UNPKG

linkmore-design

Version:

🌈 🚀lm组件库。🚀

508 lines (488 loc) 19.5 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import { useMemoizedFn } from 'ahooks'; import OSS from 'ali-oss'; import { useCallback, useRef } from 'react'; import message from "../../message"; var useCoreOptions = function useCoreOptions(_ref) { var state = _ref.state, dispatch = _ref.dispatch, props = _ref.props; var uid = props.uid, onChange = props.onChange, type = props.type, fileSize = props.fileSize, fileSizeType = props.fileSizeType, fileAreaSize = props.fileAreaSize, enabledOss = props.enabledOss, enableCrop = props.enableCrop, ossConfig = props.ossConfig, multiple = props.multiple, locale = props.locale; var fileUploadLen = useRef(null); // 上传的文件数量 var doneFileUploadLen = useRef([]); // 已完成上传的文件 /* 获取两个对象是否存在指定值相等 * 取用户定义的列字段,如果读取不到则取'fileName'对比 */ var getHasEqual = useCallback(function (obj1, obj2) { var extend = [uid, 'fileName']; var flag = false; extend.forEach(function (v) { if (!flag && obj1[v] && obj2[v]) { flag = obj1[v] === obj2[v]; } }); return flag; }, [uid]); // 从对象中读取存在的指定属性 var getFileHasValue = useCallback(function (obj) { if (!obj) return ''; var extend = [uid, 'fileName']; var val = ''; extend.forEach(function (v) { if (!val && obj[v]) val = obj[v]; }); return val; }, [uid]); // 获取当前的文件列表 var getFileList = useCallback(function () { return props.fileList || state.fileList; }, [props.fileList, state.fileList]); // 获取上传状态 var getUploadStatus = useCallback(function () { var uploading = typeof state.percent === 'number'; return { uploading: uploading }; }, [state.percent]); // 获取文件字段值 var getFileFields = useCallback(function (fileParams) { var fileNames = props.fileNames; var obj = {}; Object.entries(fileNames).forEach(function (v) { var itemKey = v[0]; var itemValue = v[1]; if (fileParams[itemKey]) { obj[itemKey] = fileParams[itemValue]; } }); return obj; }, [props]); // 获取是否达到最大上传数量 var getIsMaxCount = useCallback(function () { var maxCount = props.maxCount, limit = props.limit; var flag = false; var num = maxCount || limit; if (num && typeof num === 'number') { flag = !(getFileList().length < num); } return flag; }, [getFileList, props]); // 上传成功事件: File, fileParams var uploadSuccess = useCallback( /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(file, params, ossCallBack) { var _props$onSuccess, _props$onCallBack; var fileList, res; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: fileList = Array.isArray(params) ? [].concat(_toConsumableArray(getFileList()), _toConsumableArray(params)) : [].concat(_toConsumableArray(getFileList()), [params]); dispatch({ type: 'changeFileList', fileList: fileList }); dispatch({ type: 'changePercent', percent: null }); // 上传事件:抛出 file: 文件 filelist: 文件列表 event: 上传进度信息 (_props$onSuccess = props.onSuccess) === null || _props$onSuccess === void 0 ? void 0 : _props$onSuccess.call(props, { file: file, fileList: fileList }); onChange === null || onChange === void 0 ? void 0 : onChange({ file: file, fileList: fileList }); doneFileUploadLen.current = []; _context.next = 8; return ossCallBack === null || ossCallBack === void 0 ? void 0 : ossCallBack(Array.isArray(params) ? params : [params]); case 8: res = _context.sent; (_props$onCallBack = props.onCallBack) === null || _props$onCallBack === void 0 ? void 0 : _props$onCallBack.call(props, res, { file: file, fileList: fileList }); case 10: case "end": return _context.stop(); } }, _callee); })); return function (_x, _x2, _x3) { return _ref2.apply(this, arguments); }; }(), [getFileList, props.onSuccess, props.onCallBack, onChange, dispatch, doneFileUploadLen.current]); // 上传进度事件 var uploadProgress = useCallback(function (file, _ref3) { var _props$onProgress; var progress = _ref3.progress, checkPoint = _ref3.checkPoint, result = _ref3.result; var params = { file: file, fileList: getFileList(), event: { progress: progress, checkPoint: checkPoint, result: result, status: typeof progress !== 'number' ? 'done' : 'uploading' } }; (_props$onProgress = props.onProgress) === null || _props$onProgress === void 0 ? void 0 : _props$onProgress.call(props, params); onChange === null || onChange === void 0 ? void 0 : onChange(params); dispatch({ type: 'changePercent', percent: Number((progress * 100).toFixed(2)) }); }, [getFileList, props.onProgress, onChange, dispatch]); // 上传失败事件 var uploadError = useCallback(function (_ref4) { var error = _ref4.error, file = _ref4.file; props.onError ? props.onError({ error: error, file: file, fileList: getFileList() }) : message.warning(locale.fileUploadError, 1.5); onChange === null || onChange === void 0 ? void 0 : onChange({ file: file, fileList: getFileList(), event: { status: 'error' } }); doneFileUploadLen.current = []; }, [props.onError, getFileList, onChange, doneFileUploadLen.current, locale]); // 上传至ali-oss var uploadOss = useCallback( /*#__PURE__*/function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(file) { var _ossConfig, _ossConfig$dir, filePath, shortlink, _ossConfig$region, region, accessKeyId, accessKeySecret, stsToken, _ossConfig$bucket, bucket, ossCallBack, client, timestamp, pattern, tripFileName, suffixIndex, realFileName, fileName, pathName, url, params; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; _ossConfig = ossConfig(), _ossConfig$dir = _ossConfig.dir, filePath = _ossConfig$dir === void 0 ? '/BizFile/4595/Supplier/' : _ossConfig$dir, shortlink = _ossConfig.shortlink, _ossConfig$region = _ossConfig.region, region = _ossConfig$region === void 0 ? 'oss-cn-hangzhou' : _ossConfig$region, accessKeyId = _ossConfig.accessKeyId, accessKeySecret = _ossConfig.accessKeySecret, stsToken = _ossConfig.stsToken, _ossConfig$bucket = _ossConfig.bucket, bucket = _ossConfig$bucket === void 0 ? 'linkmore-scm-test' : _ossConfig$bucket, ossCallBack = _ossConfig.ossCallBack; client = new OSS({ region: region, accessKeyId: accessKeyId, accessKeySecret: accessKeySecret, stsToken: stsToken, bucket: bucket }); timestamp = Date.now(); pattern = /[!@#$%^&*()_+{}:“<>?,;'[\]\\|`~]+/g; // 删除特殊字符 tripFileName = file.name.replace(pattern, ''); suffixIndex = tripFileName.lastIndexOf('.'); realFileName = tripFileName.slice(0, Math.min(100, suffixIndex)) + tripFileName.slice(suffixIndex); fileName = "".concat(timestamp, "-").concat(realFileName); pathName = filePath.slice(-1) === '/' ? "".concat(filePath).concat(fileName) : "".concat(filePath, "/").concat(fileName); url = "".concat(shortlink).concat(pathName) || ''; _context2.next = 13; return client.multipartUpload(pathName, file, { // 获取分片上传进度、断点和返回值。 progress: function progress(_progress, checkPoint, result) { return !multiple && uploadProgress(file, { progress: _progress, checkPoint: checkPoint, result: result }); }, parallel: 4, // 并发上传分片数量 partSize: 1024 * 1024 // 分片大小 // 会导致部分图片无法上传 // headers: { 'Content-Disposition': `attachment; filename=${realFileName}` }, }); case 13: params = props.fileConfig({ file: file, timestamp: timestamp, fileName: fileName, filePath: filePath, shortlink: shortlink, url: url, realFileName: realFileName }); if (!multiple) { uploadSuccess(file, params, ossCallBack); } if (multiple) { doneFileUploadLen.current = [].concat(_toConsumableArray(doneFileUploadLen.current), [params]); if (fileUploadLen.current === doneFileUploadLen.current.length) { uploadSuccess(null, doneFileUploadLen.current, ossCallBack); } } _context2.next = 21; break; case 18: _context2.prev = 18; _context2.t0 = _context2["catch"](0); uploadError({ error: _context2.t0, file: file }); case 21: case "end": return _context2.stop(); } }, _callee2, null, [[0, 18]]); })); return function (_x4) { return _ref5.apply(this, arguments); }; }(), [multiple, ossConfig, uploadProgress, props.fileConfig, uploadSuccess, uploadError, fileUploadLen.current, doneFileUploadLen.current]); // 自定义使用外部上传 var customUpload = useCallback(function (file) { var _props$fileUpload; (_props$fileUpload = props.fileUpload) === null || _props$fileUpload === void 0 ? void 0 : _props$fileUpload.call(props, { file: file, value: getFileList(), onChange: uploadSuccess }); }, [props.fileUpload, getFileList, uploadSuccess]); // 调用上传方法: 执行 uploadOss && customUpload事件 var uploadFile = useCallback(function (file) { enabledOss && uploadOss(file); customUpload(file); }, [enabledOss, uploadOss, customUpload]); // 检测完成, 执行外部 `beforeUpload` 事件 var checkOver = useCallback( /*#__PURE__*/function () { var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(file) { var res, newFile; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: if (props !== null && props !== void 0 && props.beforeUpload) { _context3.next = 3; break; } uploadFile(file); return _context3.abrupt("return"); case 3: res = props.beforeUpload(file, getFileList()); // Promise if (!(res !== null && res !== void 0 && res.then)) { _context3.next = 16; break; } _context3.prev = 5; _context3.next = 8; return res; case 8: newFile = _context3.sent; uploadFile(newFile); _context3.next = 15; break; case 12: _context3.prev = 12; _context3.t0 = _context3["catch"](5); console.log('上传失败!'); case 15: return _context3.abrupt("return"); case 16: if (res) { _context3.next = 18; break; } return _context3.abrupt("return"); case 18: // () => true uploadFile(file); case 19: case "end": return _context3.stop(); } }, _callee3, null, [[5, 12]]); })); return function (_x5) { return _ref6.apply(this, arguments); }; }(), [props.beforeUpload, getFileList, uploadFile]); // 单个文件异步校验 var fileCheckAsync = useCallback(function (file) { return new Promise(function (resolve, reject) { // 文件类型校验是否通过 | 存在通配符或符合规定类型 var isCheckType = type.includes('*') || type.includes(file.name.replace(/.*\./, '').toLowerCase()); // 大小校验是否通过 var isCheckSize = file.size / 1024 / (fileSizeType.toLowerCase().includes('m') ? 1024 : 1) <= fileSize; if (!isCheckType) { var content = type.join('、'); reject(new Error("".concat(locale.fileTypeMessageBefore).concat(content).concat(locale.fileTypeMessageAfter))); } if (!isCheckSize) { reject(new Error("".concat(locale.fileSizeMessage).concat(fileSize).concat(fileSizeType, "\uFF01"))); } // 是否需要校验图片宽高 if (fileAreaSize) { var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (evt) { var res = evt.target.result; var imageObj = new Image(); imageObj.src = res; imageObj.onload = function () { var maxWidth = fileAreaSize.maxWidth, maxHeight = fileAreaSize.maxHeight; var isCheckAreaSizeMaxWidth = !maxWidth || imageObj.width <= maxWidth; var isCheckAreaSizeMaxHeight = !maxHeight || imageObj.height <= maxHeight; if (!isCheckAreaSizeMaxWidth || !isCheckAreaSizeMaxHeight) { reject(new Error(locale.fileSizeLimitMessage)); } else { resolve(file); } }; }; } else { resolve(file); } }); }, [type, fileSize, fileSizeType, fileAreaSize, locale]); // 文件循环校验,返回校验后的文件数组 var filesLoopCheck = useCallback(function (files) { return Promise.all(files === null || files === void 0 ? void 0 : files.map(fileCheckAsync)); }, [fileCheckAsync]); /* * 上传前: 先校验 => 全部校验通过后开始上传 * 事件执行顺序: * beforeUpload => filesLoopCheck => checkOver * => uploadFile => uploadOss && customUpload * => uploadProgress => uploadSuccess || uploadError * => Props.onChange && (Props.onSuccess || Props.onError) */ var beforeUpload = useCallback( /*#__PURE__*/function () { var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(e) { var files, res; return _regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: files = Array.from(e.target ? e.target.files : e); _context4.prev = 1; _context4.next = 4; return filesLoopCheck(files); case 4: res = _context4.sent; fileUploadLen.current = res.length; // 仅单文件上传时可剪裁 if (enableCrop) { dispatch({ type: 'changeCropFile', cropFile: res[0] }); } else { // 校验完成开始执行上传 res.forEach(checkOver); } _context4.next = 13; break; case 9: _context4.prev = 9; _context4.t0 = _context4["catch"](1); console.log('文件校验未通过!', _context4.t0.message); message.warning(_context4.t0.message, 1.5); case 13: case "end": return _context4.stop(); } }, _callee4, null, [[1, 9]]); })); return function (_x6) { return _ref7.apply(this, arguments); }; }(), [filesLoopCheck, enableCrop, checkOver, fileUploadLen.current]); // 删除事件 var remove = useCallback( /*#__PURE__*/function () { var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(file) { var _props$onRemove; var res, _getFileList, fileList; return _regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: _context5.next = 2; return (_props$onRemove = props.onRemove) === null || _props$onRemove === void 0 ? void 0 : _props$onRemove.call(props, file); case 2: res = _context5.sent; if (res) { fileList = (_getFileList = getFileList()) === null || _getFileList === void 0 ? void 0 : _getFileList.filter(function (v) { return !getHasEqual(v, file); }); dispatch({ type: 'changeFileList', fileList: fileList }); onChange === null || onChange === void 0 ? void 0 : onChange({ file: file, fileList: fileList }); } case 4: case "end": return _context5.stop(); } }, _callee5); })); return function (_x7) { return _ref8.apply(this, arguments); }; }(), [props.onRemove, getFileList, onChange, dispatch, getHasEqual]); // 点击文件链接或预览图标时的回调 var preview = useMemoizedFn(function (file) { var _props$onPreview; (_props$onPreview = props.onPreview) === null || _props$onPreview === void 0 ? void 0 : _props$onPreview.call(props, file, getFileList()); }); // 点击下载文件时的回调 var download = useCallback(function (file) { var _props$onDownload; (_props$onDownload = props.onDownload) === null || _props$onDownload === void 0 ? void 0 : _props$onDownload.call(props, file); }, [props.onDownload]); // 拖拽移动事件 var move = useCallback(function (active, over, fileList) { var _props$onMove; (_props$onMove = props.onMove) === null || _props$onMove === void 0 ? void 0 : _props$onMove.call(props, active, over, fileList); onChange === null || onChange === void 0 ? void 0 : onChange({ file: active, fileList: fileList }); dispatch({ type: 'changeFileList', fileList: fileList }); }, [props.onMove, onChange, dispatch]); var CoreMethods = { getIsMaxCount: getIsMaxCount, // 获取是否达到最大上传数量 getFileHasValue: getFileHasValue, getFileFields: getFileFields, beforeUpload: beforeUpload, checkOver: checkOver, getUploadStatus: getUploadStatus, remove: remove, preview: preview, download: download, move: move }; var RefMethods = { getState: function getState() { return state; }, getFileList: getFileList, // 获取文件列表 uploadFile: uploadFile }; return { CoreMethods: CoreMethods, RefMethods: RefMethods }; }; export default useCoreOptions;