UNPKG

react-admin-kit

Version:

A react based UI components for admin system

158 lines (152 loc) 6.26 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.FormUploadType = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _antd = require("antd"); var _react = require("react"); var _reactDom = require("react-dom"); var _context = require("../SettingProvider/context"); var _utils = require("../utils"); var _omit = _interopRequireDefault(require("omit.js")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["multiple", "children", "onFinish", "errorHandle", "responseToFileList", "nameKey", "urlKey"]; /** * 给 file 对象赋上默认的 status: done * initialValues 和 setFieldsValue 两种情况下的 file 对象需要带上 status, 否则表单收集不到. * beforeUpload 为 false 的 file 对象也会进到 fileList, 它的 status 为空, 所以表单不收集 * @param files */ 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 = (0, _react.useContext)(_context.FormUploadContext) || {}; var safeProps = (0, _omit.default)(props, ['value', 'onChange']); var mergedProps = (0, _utils.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 = (0, _objectWithoutProperties2.default)(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 (0, _objectSpread2.default)((0, _objectSpread2.default)({}, val), {}, { name: val[nameKey], url: val[urlKey] }); }) : value; // 是否有调用父组件的 onChange 函数 var emitChangeRef = (0, _react.useRef)(null); var firstTimeRef = (0, _react.useRef)(true); var _useState = (0, _react.useState)(withDefaultStatus($value)), _useState2 = (0, _slicedToArray2.default)(_useState, 2), innerFileList = _useState2[0], setInnerFileList = _useState2[1]; var _useState3 = (0, _react.useState)(false), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), uploading = _useState4[0], setUploading = _useState4[1]; /** * FormUpload 组件的设计是内部维护自己的文件列表, 然后监听外部 value 属性的变化, 来达到近似受控组件的效果. * 为什么说近似, 是因为有一个例外, 当上传的文件列表中有上传错误的文件时, 通过 props.onChnage 传给外面的文件与内部的文件不一致. * 传给外面的文件都是上传成功的, 而内部上包含错误文件的. * 就是这个例外需要两边不同步, 通过一个 emitChangeRef 来标记并阻止他们同步. */ (0, _react.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 = (0, _toConsumableArray2.default)(info.fileList); var $fileList = fileList.map(function (file) { /** * 将后端的返回合并进file对象 */ if (file.response) { var res = file.response; var resObj = responseToFileList ? responseToFileList(res) : {}; return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, file), resObj); } return file; }); if (info.file.status === 'error') { if (errorHandle) { errorHandle(info.file.response || {}); } } (0, _reactDom.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__*/(0, _jsxRuntime.jsx)(_antd.Upload, (0, _objectSpread2.default)((0, _objectSpread2.default)({ multiple: multiple, fileList: innerFileList, onChange: handleOnChange }, rest), {}, { children: renderChildren() })); } var _default = exports.default = FormUpload; // 用于生成api文档 /* istanbul ignore next */ var FormUploadType = exports.FormUploadType = function FormUploadType() { return null; };