import React from 'react';
import Invoice from '../../..';
import { IGoodPassenger } from '../../../InvoiceController';
import {
Drawer,
Button,
Upload,
Table,
Alert,
Tag,
Space,
Typography,
message,
Input,
Progress,
} from 'kts-components-antd-x4';
import { DownloadOutlined, InboxOutlined } from '@ant-design/icons';
import type { UploadProps } from 'kts-components-antd-x4'; // 引入 UploadProps 用于类型提取
import { CheckCircleFilled } from '@ant-design/icons';
import idGenerator from '@/Invoice/tools/idGenerator';
const { Dragger } = Upload;
const { Text } = Typography;
export default () => {
const controller = Invoice.useInvoiceController();
const visible = controller.useMemo(s => s.passengerListState.isVisibleDrawer, []);
const dataSource = controller.useMemo(s => s.passengerListState.dataSource, []);
const onClose = React.useCallback(() => {
controller.pipeline(async s => {
s.passengerListState.isVisibleDrawer = false;
s.passengerListState.dataSource = [];
})();
}, [controller]);
const onConfirm = React.useCallback(async () => {
if (dataSource.length) {
await controller.pipeline(async s => {
const data = dataSource.map(item => {
return {
$index: idGenerator(),
...item
}
})
s.passengerListState.goodsList = [...s.passengerListState.goodsList, ...data];
s.passengerListState.dataSource = [];
})();
await controller.wait()
}
onClose();
}, [controller, dataSource]);
return (
}
>
);
};
const DrawerBody = () => {
const controller = Invoice.useInvoiceController();
const [fileName, setFileName] = React.useState('');
const [status, setStatus] = React.useState<'idle' | 'uploading' | 'done' | 'error'>('idle');
const [percent, setPercent] = React.useState(0);
const columns = controller.useMemo(s => s.passengerListState.columns, []);
const dataSource = controller.useMemo(s => s.passengerListState.dataSource, []);
const pagination = controller.useMemo(s => s.passengerListState.pagination, []);
const handleDownloadTemplate = React.useCallback(() => {
if (controller.downloadPassengerTpt) {
controller.downloadPassengerTpt();
}
}, [controller])
// 1. 前置校验:限制文件类型为 .xls, .xlsx
const beforeUpload = React.useCallback((file: any) => {
const isExcel = file.type === 'application/vnd.ms-excel' ||
file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
/\.(xls|xlsx)$/.test(file.name); // 兜底判断文件名后缀
if (!isExcel) {
message.error('只能上传 .xls 或 .xlsx 格式的Excel文件!');
return Upload.LIST_IGNORE; // 阻止上传
}
setFileName(file.name);
setStatus('uploading');
setPercent(0);
return true;
}, []);
// 2. 正确类型定义的 customRequest
// 直接使用 UploadProps['customRequest'] 可以完美推导出 options 内所有的类型!
const customRequest: UploadProps['customRequest'] = async (options) => {
const { file, onSuccess, onError, onProgress } = options;
if (controller.uploadPassenger) {
const res = await controller.uploadPassenger(file as any);
if (res) {
setStatus('done');
setPercent(100);
}
}
};
// 3. 处理文件选择状态(更新左侧 Input 显示的文件名)
const handleChange = (info: any) => {
if (info.file.status === 'done') {
// 上传成功后可以获取后端返回的信息
console.log('上传成功返回的数据:', info.file.response);
}
// 更新文件名
if (info.file.name) {
setFileName(info.file.name);
}
};
React.useEffect(() => {
controller.getBuyerList &&
controller.getBuyerList({ pagination: { current: 1 } });
}, [controller]);
return (
{dataSource && dataSource.length > 0 &&
文件导入成功,处理旅客运输服务特定信息记录{dataSource.length}条,处理成功{dataSource.length}条。
} />
}
);
};