119 lines
3.6 KiB
TypeScript
119 lines
3.6 KiB
TypeScript
import { UploadOutlined } from '@ant-design/icons';
|
||
import { ActionType } from '@ant-design/pro-components';
|
||
import { request } from '@umijs/max';
|
||
import { Button, Upload, message } from 'antd';
|
||
import React from 'react';
|
||
|
||
// 字典项导入按钮组件的属性接口
|
||
interface DictItemImportButtonProps {
|
||
// 当前选中的字典
|
||
selectedDict?: any;
|
||
// ProTable 的 actionRef,用于刷新列表
|
||
actionRef?: React.MutableRefObject<ActionType | undefined>;
|
||
// 是否禁用按钮
|
||
disabled?: boolean;
|
||
// 自定义导入函数,返回 Promise(如果不提供,则使用默认的导入逻辑)
|
||
onImport?: (file: File, dictId: number) => Promise<any>;
|
||
// 导入成功后刷新字典列表的回调函数
|
||
onRefreshDicts?: () => void;
|
||
}
|
||
|
||
// 字典项导入按钮组件
|
||
const DictItemImportButton: React.FC<DictItemImportButtonProps> = ({
|
||
selectedDict,
|
||
actionRef,
|
||
disabled = false,
|
||
onImport,
|
||
onRefreshDicts,
|
||
}) => {
|
||
// 处理导入文件上传
|
||
const handleImportUpload = async (options: any) => {
|
||
console.log(options);
|
||
const { file, onSuccess, onError } = options;
|
||
try {
|
||
// 条件判断,确保已选择字典
|
||
if (!selectedDict?.id) {
|
||
throw new Error('请先选择字典');
|
||
}
|
||
|
||
let result: any;
|
||
// 如果提供了自定义导入函数,则使用自定义函数
|
||
if (onImport) {
|
||
result = await onImport(file as File, selectedDict.id);
|
||
} else {
|
||
// 使用默认的导入逻辑,将 dictId 传入到 body 中
|
||
const formData = new FormData();
|
||
formData.append('file', file as File);
|
||
formData.append('dictId', String(selectedDict.id));
|
||
|
||
result = await request('/api/dict/item/import', {
|
||
method: 'POST',
|
||
body: formData,
|
||
});
|
||
}
|
||
|
||
// 显示导入结果详情
|
||
showImportResult(result);
|
||
|
||
// 导入成功后刷新列表
|
||
setTimeout(() => {
|
||
actionRef?.current?.reload();
|
||
onRefreshDicts?.();
|
||
}, 100);
|
||
} catch (error: any) {
|
||
onError?.(error as Error);
|
||
}
|
||
};
|
||
|
||
// 显示导入结果详情
|
||
const showImportResult = (result: any) => {
|
||
// 从 result.data 中获取实际数据(因为后端返回格式为 { success: true, data: {...} })
|
||
const data = result.data || result;
|
||
const { total, processed, updated, created, errors } = data;
|
||
|
||
// 构建结果消息
|
||
let messageContent = `总共处理 ${total} 条,成功处理 ${processed} 条,新增 ${created} 条,更新 ${updated} 条`;
|
||
|
||
if (errors && errors.length > 0) {
|
||
messageContent += `,失败 ${errors.length} 条`;
|
||
// 显示错误详情
|
||
const errorDetails = errors
|
||
.map((err: any) => `${err.identifier}: ${err.error}`)
|
||
.join('\n');
|
||
message.warning(messageContent + '\n\n错误详情: \n' + errorDetails);
|
||
} else {
|
||
message.success(messageContent);
|
||
}
|
||
};
|
||
|
||
// 处理上传状态变化
|
||
const handleUploadChange = (info: any) => {
|
||
if (info.file.status === 'done') {
|
||
message.success(`${info.file.name} 文件上传成功`);
|
||
} else if (info.file.status === 'error') {
|
||
message.error(`${info.file.name} 文件上传失败`);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Upload
|
||
name="file"
|
||
action={undefined}
|
||
customRequest={handleImportUpload}
|
||
showUploadList={false}
|
||
disabled={disabled || !selectedDict}
|
||
onChange={handleUploadChange}
|
||
>
|
||
<Button
|
||
size="small"
|
||
icon={<UploadOutlined />}
|
||
disabled={disabled || !selectedDict}
|
||
>
|
||
导入字典项
|
||
</Button>
|
||
</Upload>
|
||
);
|
||
};
|
||
|
||
export default DictItemImportButton;
|