UNPKG

react-admin-kit

Version:

A react based UI components for admin system

154 lines (147 loc) 5.65 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; var _excluded = ["multiple", "children", "onFinish", "errorHandle", "responseToFileList", "nameKey", "urlKey"]; import { Upload } from 'antd'; import { useContext, useEffect, useRef, useState } from 'react'; import { flushSync } from 'react-dom'; import { FormUploadContext } from "../SettingProvider/context"; import { myMergeOptions } from "../utils"; import Omit from 'omit.js'; /** * 给 file 对象赋上默认的 status: done * initialValues 和 setFieldsValue 两种情况下的 file 对象需要带上 status, 否则表单收集不到. * beforeUpload 为 false 的 file 对象也会进到 fileList, 它的 status 为空, 所以表单不收集 * @param files */ import { jsx as _jsx } from "react/jsx-runtime"; function withDefaultStatus() { var files = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var $files = files || []; return $files.map(function (file) { if (!file.status) { file.status = 'done'; } return file; }); } function FormUpload(props) { // 全局默认设置 var setting = useContext(FormUploadContext) || {}; var safeProps = Omit(props, ['value', 'onChange']); var mergedProps = myMergeOptions(setting, safeProps || {}, // 默认值放在这里,能合并对象类属性 {}); var _mergedProps$multiple = mergedProps.multiple, multiple = _mergedProps$multiple === void 0 ? true : _mergedProps$multiple, children = mergedProps.children, onFinish = mergedProps.onFinish, errorHandle = mergedProps.errorHandle, responseToFileList = mergedProps.responseToFileList, _mergedProps$nameKey = mergedProps.nameKey, nameKey = _mergedProps$nameKey === void 0 ? 'name' : _mergedProps$nameKey, _mergedProps$urlKey = mergedProps.urlKey, urlKey = _mergedProps$urlKey === void 0 ? 'url' : _mergedProps$urlKey, rest = _objectWithoutProperties(mergedProps, _excluded); var value = props.value, onChange = props.onChange; /** * 如果先前的 value 有值 [{name: '', url: ''}], 通过 setFieldsValue 设成空数组[]后, value 会变成 [undefined] */ var $value = value ? value.filter(Boolean).map(function (val) { return _objectSpread(_objectSpread({}, val), {}, { name: val[nameKey], url: val[urlKey] }); }) : value; // 是否有调用父组件的 onChange 函数 var emitChangeRef = useRef(null); var firstTimeRef = useRef(true); var _useState = useState(withDefaultStatus($value)), _useState2 = _slicedToArray(_useState, 2), innerFileList = _useState2[0], setInnerFileList = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), uploading = _useState4[0], setUploading = _useState4[1]; /** * FormUpload 组件的设计是内部维护自己的文件列表, 然后监听外部 value 属性的变化, 来达到近似受控组件的效果. * 为什么说近似, 是因为有一个例外, 当上传的文件列表中有上传错误的文件时, 通过 props.onChnage 传给外面的文件与内部的文件不一致. * 传给外面的文件都是上传成功的, 而内部上包含错误文件的. * 就是这个例外需要两边不同步, 通过一个 emitChangeRef 来标记并阻止他们同步. */ useEffect(function () { // 忽略第一次 if (firstTimeRef.current) { firstTimeRef.current = false; return; } /** * 监听 value, 外部和内部同步. (emitChange 阻止的除外) */ if (!emitChangeRef.current) { setInnerFileList(withDefaultStatus($value)); } emitChangeRef.current = false; }, [value]); var handleOnChange = function handleOnChange(info) { setUploading(true); var fileList = _toConsumableArray(info.fileList); var $fileList = fileList.map(function (file) { /** * 将后端的返回合并进file对象 */ if (file.response) { var res = file.response; var resObj = responseToFileList ? responseToFileList(res) : {}; return _objectSpread(_objectSpread({}, file), resObj); } return file; }); if (info.file.status === 'error') { if (errorHandle) { errorHandle(info.file.response || {}); } } flushSync(function () { return setInnerFileList($fileList); }); // beforeUpload为false的文件也会进到onChange里 if ($fileList.every(function (file) { return file.status !== 'uploading'; })) { setUploading(false); emitChangeRef.current = true; var successFiles = $fileList.filter(function (file) { return ['done', 'success'].includes(file.status); }); if (onChange) { onChange(successFiles); } if (onFinish) onFinish(successFiles); } }; var renderChildren = function renderChildren() { if (children && typeof children === 'function') { return children({ loading: uploading }); } return children; }; return /*#__PURE__*/_jsx(Upload, _objectSpread(_objectSpread({ multiple: multiple, fileList: innerFileList, onChange: handleOnChange }, rest), {}, { children: renderChildren() })); } export default FormUpload; // 用于生成api文档 /* istanbul ignore next */ export var FormUploadType = function FormUploadType() { return null; };