feat(component): 增加组件发布功能弹窗

master
钟良源 2 months ago
parent f3295f25d7
commit 2dabe0fa88

@ -0,0 +1,197 @@
import React, { useState } from 'react';
import { Modal, Form, Input, Upload, Button, Message } from '@arco-design/web-react';
import { IconUpload, IconDelete } from '@arco-design/web-react/icon';
import styles from './style/publishComponentModal.module.less';
import { publishComponent, uploadComponentFile } from '@/api/componentMarket';
import { PublishComponentParams } from '@/api/interface';
const FormItem = Form.Item;
interface PublishComponentModalProps {
visible: boolean;
componentInfo: any;
onCancel: () => void;
onSuccess: () => void;
}
const PublishComponentModal: React.FC<PublishComponentModalProps> = ({
visible,
componentInfo,
onCancel,
onSuccess
}) => {
const [form] = Form.useForm();
const [fileList, setFileList] = useState([]);
const [uploading, setUploading] = useState(false);
const [uploadedFiles, setUploadedFiles] = useState<any[]>([]); // 保存上传成功后的文件信息
// 处理文件选择
const handleFileChange = (fileList) => {
// 验证每个文件大小
const invalidFiles = fileList.filter(file => file.originFile && file.originFile.size > 10 * 1024 * 1024);
if (invalidFiles.length > 0) {
Message.error('上传文件大小不能超过10MB!');
return;
}
setFileList(fileList);
};
// 文件上传
const uploadFile = async () => {
if (fileList.length === 0) {
Message.warning('请选择要上传的文件');
return;
}
try {
setUploading(true);
const formData = new FormData();
fileList.forEach((file) => {
formData.append('files', file.originFile);
});
const result: any = await uploadComponentFile(formData);
if (result.code === 200) {
Message.success(`成功上传 ${fileList.length} 个文件`);
// 保存上传成功后的文件信息
setUploadedFiles(result.data || []);
}
else {
Message.error(result.msg || '上传失败');
}
} catch (error) {
console.error('上传失败:', error);
Message.error('上传失败');
} finally {
setUploading(false);
}
};
// 删除单个文件
const handleRemoveFile = (index: number) => {
const newFileList = fileList.filter((_, i) => i !== index);
setFileList(newFileList);
};
// 处理提交
const handleSubmit = async () => {
try {
const values = await form.validate();
// 调用发布接口
const publishParams: PublishComponentParams = {
id: componentInfo?.id || '',
recommend: values.recommend
};
if (uploadedFiles.length > 0) {
// 拼接 files 和 filesName
const files = uploadedFiles.map(file => file.link).join(',');
const filesName = uploadedFiles.map(file => file.originalName).join(',');
publishParams.files = files;
publishParams.filesName = filesName;
}
setUploading(true);
const result: any = await publishComponent(publishParams);
if (result.code === 200) {
Message.success('组件发布成功');
handleCancel();
onSuccess();
}
else {
Message.error(result.msg || '组件发布失败');
}
} catch (error) {
console.error('发布组件失败:', error);
Message.error('组件发布失败');
} finally {
setUploading(false);
}
};
// 处理取消
const handleCancel = () => {
form.resetFields();
setFileList([]);
setUploadedFiles([]);
setUploading(false);
onCancel();
};
return (
<Modal
title="组件发布"
visible={visible}
onCancel={handleCancel}
footer={
<div className={styles['modal-footer']}>
<Button onClick={handleCancel}></Button>
<Button type="primary" onClick={handleSubmit} loading={uploading}>
</Button>
</div>
}
style={{ width: 600 }}
>
<Form
form={form}
layout="vertical"
>
<FormItem
label="组件描述:"
field="recommend"
rules={[{ required: true, message: '请输入组件描述' }]}
>
<Input placeholder="请输入组件描述" />
</FormItem>
<FormItem label="上传附件:">
<div className={styles['upload-section']}>
<Upload
fileList={fileList}
onChange={handleFileChange}
accept="*"
multiple
autoUpload={false}
showUploadList={false}
>
<Button type="outline" icon={<IconUpload />}>
</Button>
</Upload>
<Button type="primary" style={{ marginLeft: 12 }} onClick={uploadFile} loading={uploading}>
</Button>
</div>
<div className={styles['upload-tip']}>
10MB
</div>
{fileList.length > 0 && (
<div className={styles['file-list']}>
{fileList.map((file, index) => (
<div key={index} className={styles['file-item']}>
<span className={styles['file-name']}>
{index + 1}. {file.name}
</span>
<IconDelete
className={styles['delete-icon']}
onClick={() => handleRemoveFile(index)}
/>
</div>
))}
</div>
)}
</FormItem>
</Form>
</Modal>
);
};
export default PublishComponentModal;

@ -0,0 +1,63 @@
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
.upload-section {
display: flex;
align-items: center;
}
.upload-tip {
margin-top: 8px;
font-size: 12px;
color: #86909c;
}
.file-list {
margin-top: 12px;
max-height: 200px;
overflow-y: auto;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: #f2f3f5;
border-radius: 4px;
font-size: 13px;
color: #4e5969;
margin-bottom: 8px;
transition: background 0.2s;
&:last-child {
margin-bottom: 0;
}
&:hover {
background: #e8e9eb;
}
}
.file-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 12px;
}
.delete-icon {
font-size: 16px;
color: #86909c;
cursor: pointer;
transition: color 0.2s;
flex-shrink: 0;
&:hover {
color: #f53f3f;
}
}
Loading…
Cancel
Save