UNPKG

@jay.kou/rak-ssr

Version:

A react based UI components for admin system

156 lines (150 loc) 5.82 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 = ["value", "onChange", "multiple", "children", "onFinish", "errorHandle", "responseToFileList", "nameKey", "urlKey"], _excluded2 = ["urlKey", "nameKey", "responseToFileList", "errorHandle"]; import { Upload } from 'antd'; import { cloneElement, useContext, useEffect, useRef, useState } from 'react'; import { flushSync } from 'react-dom'; import { FormUploadContext } from "../SettingProvider/context"; import { jsx as _jsx } from "react/jsx-runtime"; /** * 给 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 value = props.value, onChange = props.onChange, _props$multiple = props.multiple, multiple = _props$multiple === void 0 ? true : _props$multiple, children = props.children, onFinish = props.onFinish, errorHandle = props.errorHandle, responseToFileList = props.responseToFileList, nameKey = props.nameKey, urlKey = props.urlKey, rest = _objectWithoutProperties(props, _excluded); var _ref = useContext(FormUploadContext) || {}, urlKeyContext = _ref.urlKey, nameKeyContext = _ref.nameKey, responseToFileListContext = _ref.responseToFileList, errorHandleContext = _ref.errorHandle, restUploadProps = _objectWithoutProperties(_ref, _excluded2); var $nameKey = nameKey || nameKeyContext || 'name'; var $urlKey = urlKey || urlKeyContext || 'url'; /** * 如果先前的 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]; /**x * 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 resToFileList = responseToFileList || responseToFileListContext; var resObj = resToFileList ? resToFileList(res) : {}; return _objectSpread(_objectSpread({}, file), resObj); } return file; }); if (info.file.status === 'error') { var $errorHandle = errorHandle || errorHandleContext; if ($errorHandle) { $errorHandle(info.file.response || {}); } } flushSync(function () { return setInnerFileList($fileList); }); // beforeUpload为false的文件也会进到onChange里 if ($fileList.every(function (file) { return file.status !== 'uploading'; })) { var successFiles = $fileList.filter(function (file) { return ['done', 'success'].includes(file.status); }); if (onChange) { onChange(successFiles); emitChangeRef.current = true; } if (onFinish) onFinish(successFiles); setUploading(false); } }; var renderChildren = function renderChildren() { if (children) { return typeof children === 'function' ? children({ loading: uploading }) : /*#__PURE__*/cloneElement(children, { loading: uploading }); } return children; }; return /*#__PURE__*/_jsx(Upload, _objectSpread(_objectSpread(_objectSpread({ multiple: multiple }, restUploadProps), {}, { fileList: innerFileList, onChange: handleOnChange }, rest), {}, { children: renderChildren() })); } export default FormUpload; // 用于生成api文档 export var FormUploadType = function FormUploadType() { return null; };