import { __awaiter, __rest } from "tslib"; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { Button, Modal, Upload, message } from "antd"; import { CloudUploadOutlined, PlusOutlined, UploadOutlined, } from "@ant-design/icons"; import { updateFileList } from "antd/es/upload/utils"; import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { requestByPost, getBaseURL } from "@dage/service"; import { DageUploadType, } from "./types"; import { AntdDragger, AntdDraggerText, AntdUpload, UploadContainer, UploadTips, } from "./style"; import { DageUploadContext } from "./context"; import { DageUploadItemActions } from "./ItemActions"; import { ACCEPT, getImageSize, validateFileType } from "./utils"; const getBase64 = (file) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = (error) => reject(error); }); export const DageUpload = (_a) => { var { action, value, dType = DageUploadType.IMG, maxCount = 9, maxSize = 5, tips, disabled, name = "file", downloadErrorMessage = "下载失败", children, className, onChange } = _a, rest = __rest(_a, ["action", "value", "dType", "maxCount", "maxSize", "tips", "disabled", "name", "downloadErrorMessage", "children", "className", "onChange"]); const [messageApi] = message.useMessage(); const context = useContext(DageUploadContext); // 内部维护 mergeFileList // 修复 reat18 受控模式下批量更新导致状态异常 const _mergedFileList = useRef([]); const [previewOpen, setPreviewOpen] = useState(false); const [previewImage, setPreviewImage] = useState(""); const [previewTitle, setPreviewTitle] = useState(""); const uploadListType = useMemo(() => { switch (dType) { case DageUploadType.IMG: return "picture-card"; default: return "text"; } }, [dType]); const isPictureCard = uploadListType === "picture-card"; // 可选文件类型 const accept = useMemo(() => ACCEPT[dType] || "*", [dType]); useEffect(() => { if (!value) return; _mergedFileList.current = value; }, [value]); const beforeUpload = (file) => { if (!validateFileType(file, accept)) { messageApi.error("选择的文件类型不正确!"); return Upload.LIST_IGNORE; } // 校验文件大小 const isLtM = file.size / 1024 / 1024 < maxSize; if (!isLtM) { messageApi.error(`最大支持 ${maxSize}M!`); return Upload.LIST_IGNORE; } context === null || context === void 0 ? void 0 : context.handleUploadingFileNum("add"); return true; }; const onUpload = (option) => { const formData = new FormData(); const headers = option.headers || {}; formData.append("type", dType); if (option.file instanceof Blob) { formData.append(name, option.file, option.file.name); } else { formData.append(name, option.file); } option.data && Object.keys(option.data).forEach((key) => { var _a; const value = (_a = option.data) === null || _a === void 0 ? void 0 : _a[key]; if (Array.isArray(value)) { value.forEach((item) => { formData.append(`${key}[]`, item); }); return; } formData.append(key, value); }); requestByPost(action, formData, { headers, }) .then((data) => { var _a; (_a = option.onSuccess) === null || _a === void 0 ? void 0 : _a.call(option, data); }) .catch((err) => { var _a; context === null || context === void 0 ? void 0 : context.handleUploadingFileNum("uploaded"); (_a = option.onError) === null || _a === void 0 ? void 0 : _a.call(option, err); }); }; const handleChange = ({ fileList: newFileList, file, }) => __awaiter(void 0, void 0, void 0, function* () { if (file.status === "done") { if (typeof file.response !== "object" || !file.response.fileName) { // 上传失败 file.status = "error"; } else if (isPictureCard && file.originFileObj) { // 如果是图片获取图片宽高 try { // @ts-ignore file.imgAttrs = yield getImageSize(file.originFileObj); // todo: 缩略图并发上传有时候会丢失 file.thumbUrl = getBaseURL() + file.response.filePath; } catch (err) { // 图片加载失败 file.status = "error"; } } context === null || context === void 0 ? void 0 : context.handleUploadingFileNum("uploaded"); } if (_mergedFileList.current.length > newFileList.length) { _mergedFileList.current = newFileList; } else { _mergedFileList.current = updateFileList(file, _mergedFileList.current); } onChange === null || onChange === void 0 ? void 0 : onChange(_mergedFileList.current.map((i) => (Object.assign(Object.assign({}, i), { dType }))), Object.assign(Object.assign({}, file), { dType })); }); const handleCancel = () => setPreviewOpen(false); const handlePreview = (file) => __awaiter(void 0, void 0, void 0, function* () { if (!isPictureCard) return; if (!file.url && !file.preview) { file.preview = yield getBase64(file.originFileObj); } setPreviewImage(file.url || file.preview); setPreviewOpen(true); setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf("/") + 1)); }); const props = Object.assign({ fileList: value, withCredentials: true, customRequest: onUpload, listType: uploadListType, maxCount, accept, disabled, itemRender: (node, file, fileList, actions) => (_jsx(DageUploadItemActions, { isPictureCard: isPictureCard, disabled: disabled, file: file, actions: actions, downloadErrorMessage: downloadErrorMessage, children: node })), showUploadList: { showPreviewIcon: false, showDownloadIcon: false, showRemoveIcon: false, }, multiple: maxCount > 1, onPreview: handlePreview, beforeUpload: beforeUpload, onChange: handleChange }, rest); return (_jsxs(UploadContainer, { className: className, children: [[DageUploadType.MODEL, DageUploadType.MOBILE_MODEL].includes(dType) ? (_jsx(AntdDragger, Object.assign({ style: { padding: "0 24px", width: "320px" } }, props, { children: children || (_jsxs(_Fragment, { children: [_jsx(CloudUploadOutlined, { style: { fontSize: "40px", color: "#1677ff" } }), _jsxs(AntdDraggerText, { children: ["\u5C06\u6587\u4EF6\u62D6\u5230\u6B64\u5904\uFF0C\u6216", _jsx("span", { children: "\u70B9\u51FB\u4E0A\u4F20" })] }), _jsx(UploadTips, { className: "dage-upload__tips", children: tips })] })) }))) : (_jsxs(_Fragment, { children: [_jsx(AntdUpload, Object.assign({}, props, { children: children || (isPictureCard ? (!disabled && (!value || value.length < maxCount) && _jsx(PlusOutlined, {})) : (_jsx(Button, { disabled: disabled, icon: _jsx(UploadOutlined, {}), children: "\u4E0A\u4F20" }))) })), !!tips && (_jsx(UploadTips, { style: { marginTop: isPictureCard ? 0 : "8px" }, className: "dage-upload__tips", children: tips }))] })), _jsx(Modal, { open: previewOpen, title: previewTitle, footer: null, onCancel: handleCancel, children: _jsx("img", { alt: "example", style: { width: "100%" }, src: previewImage }) })] })); }; export * from "./types"; export * from "./context";