import { RESPONSE_CODE } from '@/constants/enum'; import { postServiceOrderConfirmReceipt } from '@/services'; import { PlusOutlined } from '@ant-design/icons'; import { Button, Modal, Upload, message } from 'antd'; import { RcFile, UploadFile, UploadProps } from 'antd/es/upload'; import { cloneDeep } from 'lodash'; import { useEffect, useRef, useState } from 'react'; import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant'; export default ({ data, onClose }) => { const subIds = data?.map((item) => { return item.id; }); // const [form] = Form.useForm<{ name: string; company: string }>(); const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(''); const [previewTitle, setPreviewTitle] = useState(''); const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致 const getBase64 = (file: RcFile): Promise<string> => new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result as string); reader.onerror = (error) => reject(error); }); const [fileList, setFileList] = useState<UploadFile[]>([]); const [uploading, setUploading] = useState(false); const handleCancel = () => setPreviewOpen(false); const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { //fileListObj得在change里变化,change的参数是已经处理过的file数组 //beforeUpload中的参数file是未处理过,还需要Base64拿到文件数据处理 fileListObj.current = newFileList; setFileList(newFileList); }; /** 粘贴快捷键的回调 */ const onPaste = async (e: any) => { /** 获取剪切板的数据clipboardData */ let clipboardData = e.clipboardData, i = 0, items, item, types; /** 为空判断 */ if (clipboardData) { items = clipboardData.items; if (!items) { message.info('您的剪贴板中没有照片'); return; } item = items[0]; types = clipboardData.types || []; /** 遍历剪切板的数据 */ for (; i < types.length; i++) { if (types[i] === 'Files') { item = items[i]; break; } } /** 判断文件是否为图片 */ if (item && item.kind === 'file' && item.type.match(/^image\//i)) { const imgItem = item.getAsFile(); const newFileList = cloneDeep(fileListObj.current); let filteredArray = newFileList.filter( (obj) => obj.status !== 'removed', ); //过滤掉状态为已删除的照片 const listItem = { ...imgItem, status: 'done', url: await getBase64(imgItem), originFileObj: imgItem, }; if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) { message.info('发货凭证照片数量不能超过3'); return; } fileListObj.current = filteredArray; filteredArray.push(listItem); setFileList(filteredArray); return; } } message.info('您的剪贴板中没有照片'); }; useEffect(() => { document.addEventListener('paste', onPaste); return () => { document.removeEventListener('paste', onPaste); }; }, []); const uploadButton = ( <div> <PlusOutlined /> <div style={{ marginTop: 8 }}>上传凭证</div> </div> ); const handlePreview = async (file: UploadFile) => { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj as RcFile); } setPreviewImage(file.url || (file.preview as string)); setPreviewOpen(true); setPreviewTitle( file.name || file.originFileObj?.name || file.url!.substring(file.url!.lastIndexOf('/') + 1), ); }; const handleUpload = async () => { const formData = new FormData(); fileList.forEach((file) => { //originFileObj二进制文件 formData.append('files', file.originFileObj as RcFile); }); // console.log(fileList[0] as RcFile) // formData.append('file', fileList[0] as RcFile); formData.append('subIds', subIds); setUploading(true); // You can use any AJAX library you like const res = await postServiceOrderConfirmReceipt({ data: formData, headers: { 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', }, }); if (res.result === RESPONSE_CODE.SUCCESS) { message.success(res.message); onClose(); } setUploading(false); }; const props: UploadProps = { onRemove: (file) => { const index = fileList.indexOf(file); const newFileList = fileList.slice(); newFileList.splice(index, 1); setFileList(newFileList); }, beforeUpload: (file) => { setFileList([...fileList, file]); return false; }, listType: 'picture-card', onPreview: handlePreview, fileList, onChange: handleChange, accept: 'image/png, image/jpeg, image/png', }; return ( <> <Modal width={500} open title="确认收货" footer={[ <Button key="cancel" onClick={onClose}> 取消 </Button>, <Button type="primary" key="ok" onClick={handleUpload} disabled={fileList.length === 0} loading={uploading} > {uploading ? '上传中' : '提交'} </Button>, ]} onCancel={async () => { onClose(); }} > <div className="pt-4 font-semibold">请将买家确认收货的凭证照片上传</div> <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div> <Upload {...props}> {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''} </Upload> </Modal> <Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel} > <img alt="图片预览" style={{ width: '100%' }} src={previewImage} /> </Modal> </> ); };