/** * @file 照片上传弹窗组件 * @author luozhengxuan <51071534@qq.com> * */ import React, { useCallback, useMemo, useState } from 'react'; import Axios from 'axios'; import { FormOutlined, DeleteOutlined } from '@ant-design/icons'; import { message, Modal, Upload } from 'antd'; import { RcFile } from 'antd/es/upload'; import 'antd/es/modal/style/index'; import { compressImage } from '@jy-fe/utils'; import modalOpen from '../common/modal-open'; import PNGPhotoUpload from '../assets/photo-upload.png'; import PNGPhotoCase1 from '../assets/photo-case-1.png'; import PNGPhotoCase2 from '../assets/photo-case-2.png'; import PNGPhotoCase3 from '../assets/photo-case-3.png'; import PNGShowcaseSuccess from '../assets/showcase-success.png'; import PNGShowcaseFail from '../assets/showcase-fail.png'; import { OpenConfig, XuiModalPhotoProps } from './xui-modal-photo.d'; interface FileData { url: string; list: RcFile[]; } export const XuiModalPhoto: React.FC & { open: (c: OpenConfig) => Record; } = ({ uploadURL, uploadExtraConf = {}, success, fail, ...props }) => { const classname = 'xui-ant__modal-photo'; const imgSize = 3; const accept = useMemo( () => ({ type: ['jpg', 'png', 'jpeg'], mime: ['image/jpeg', 'image/png'], }), [], ); const [fileList, setFileList] = useState({ url: '', list: [] }); const [loading, setLoading] = useState(false); const internalBeforeUpload = file => { if (!accept.mime.includes(file.type)) { message.error(`只支持${accept.type.join('、')}格式`); return false; } if (file.size / 1024 / 1024 > imgSize) { message.error(`图片大于${imgSize}M`); return false; } setFileList({ url: URL.createObjectURL(file), list: [file], }); return false; }; const handleDelete = useCallback(() => { setFileList({ url: '', list: [] }); }, []); // eslint-disable-next-line consistent-return const fetchCreate = async (e: React.MouseEvent) => { try { if (!fileList.list.length) { return message.warn('请上传生活照'); } const { data: extraData, ...otherExtraConf } = uploadExtraConf; const formData = new FormData(); if (extraData instanceof Object) { Object.entries(extraData).forEach(entry => { formData.append(entry[0], entry[1]); }); } const maxSize = 2000000; let compressFilePhoto; if (fileList.list[0].size > maxSize) { compressFilePhoto = await compressImage(fileList.url, 0.5); } const file = compressFilePhoto || fileList.list[0]; formData.append('file', file); setLoading(true); const { data } = await Axios({ url: uploadURL, method: 'POST', data: formData, ...(otherExtraConf || {}), }); // 这里如果使用 return Promise.reject 会进入到 axios 的捕获里 // TODO: 待优化 if (data.status) throw data; message.success('上传成功'); if (props.onCancel) { props.onCancel(e); } if (success) success(data.data); return data; } catch (err) { if (err.msg) { message.warn(err.msg); } else { message.error('网络异常'); } if (fail) fail(err); } finally { setLoading(false); handleDelete(); } }; return (
{fileList.list.length ? ( [ ,
  
, ] ) : ( )}
拍摄要求
照片高清、完整,{imgSize}M以内的jpg/png/jpeg格式
标准拍摄
照片模糊
成像错误
); }; XuiModalPhoto.open = (config: OpenConfig) => modalOpen(config, XuiModalPhoto); export default XuiModalPhoto;