UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

973 lines 60.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageControlRenderer = void 0; var tslib_1 = require("tslib"); var react_1 = tslib_1.__importStar(require("react")); var Item_1 = require("./Item"); // import 'cropperjs/dist/cropper.css'; var Cropper = react_1.default.lazy(function () { return Promise.resolve().then(function () { return new Promise(function(resolve){require(['react-cropper'], function(ret) {resolve(tslib_1.__importStar(ret));})}); }); }); var react_dropzone_1 = (0, tslib_1.__importDefault)(require("react-dropzone")); require("blueimp-canvastoblob"); var find_1 = (0, tslib_1.__importDefault)(require("lodash/find")); var api_1 = require("../../utils/api"); var helper_1 = require("../../utils/helper"); var icons_1 = require("../../components/icons"); var Button_1 = (0, tslib_1.__importDefault)(require("../../components/Button")); var attr_accept_1 = (0, tslib_1.__importDefault)(require("attr-accept")); var InputFile_1 = require("./InputFile"); var Image_1 = (0, tslib_1.__importDefault)(require("../Image")); var tpl_builtin_1 = require("../../utils/tpl-builtin"); var tpl_1 = require("../../utils/tpl"); var isPlainObject_1 = (0, tslib_1.__importDefault)(require("lodash/isPlainObject")); var merge_1 = (0, tslib_1.__importDefault)(require("lodash/merge")); var popover_1 = (0, tslib_1.__importDefault)(require("antd/lib/popover")); var input_1 = (0, tslib_1.__importDefault)(require("antd/lib/input")); var spark_md5_1 = (0, tslib_1.__importDefault)(require("spark-md5")); var preventEvent = function (e) { return e.stopPropagation(); }; var ImageControl = /** @class */ (function (_super) { (0, tslib_1.__extends)(ImageControl, _super); function ImageControl(props) { var _this_1 = _super.call(this, props) || this; _this_1.state = { uploading: false, locked: false, files: [], pictureUrl: '', uploadParams: {}, arrayBufferData: [], chunksSize: 0, upload_cmd: 'check_exist', upload_name: '', file_type: '', fileSize: 0 }; _this_1.files = []; _this_1.fileUploadCancelExecutors = []; _this_1.dropzone = react_1.default.createRef(); _this_1.frameImageRef = react_1.default.createRef(); _this_1.current = null; _this_1.unmounted = false; _this_1.handleFile = function (config) { return new Promise(function (resolve, reject) { return (0, tslib_1.__awaiter)(_this_1, void 0, void 0, function () { function loadNext() { var start = currentChunk * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); } var fileSize, file, blobSlice, _this, chunkSize, chunks, currentChunk, file_type, file_name, spark, chunkFileReader, params, arrayBufferData, md5; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: fileSize = config === null || config === void 0 ? void 0 : config.size; file = config; blobSlice = File.prototype.slice; _this = this; chunkSize = 1024 * 1024 * 1; chunks = Math.ceil(file.size / chunkSize); currentChunk = 0; file_type = config === null || config === void 0 ? void 0 : config.type; file_name = config === null || config === void 0 ? void 0 : config.name; spark = new spark_md5_1.default.ArrayBuffer(); chunkFileReader = new FileReader(); params = { chunks: [], file: {} }; arrayBufferData = []; params.file.fileName = file.name || this.state.cropFileName; params.file.fileSize = file.size; return [4 /*yield*/, this.getFileMd5(file)]; case 1: md5 = _a.sent(); params.file.fileMd5 = md5; params.file.id = config.id; chunkFileReader.onload = function (e) { // 对每一片分片进行md5加密 spark.append(e.target.result); // 每一个分片需要包含的信息 var obj = { chunk: currentChunk + 1, start: currentChunk * chunkSize, end: ((currentChunk * chunkSize + chunkSize) >= file.size) ? file.size : currentChunk * chunkSize + chunkSize, chunkMd5: spark.end(), chunks: chunks }; // 每一次分片onload,currentChunk都需要增加,以便来计算分片的次数 currentChunk++; params.chunks.push(obj); // 将每一块分片的arrayBuffer存储起来,用来partUpload var tmp = { chunk: obj.chunk, currentBuffer: e.target.result }; arrayBufferData.push(tmp); if (currentChunk < chunks) { // 当前切片总数没有达到总数时 loadNext(); } else { //记录所有chunks的长度 params.file.fileChunks = params.chunks.length; // 表示预处理结束,将上传的参数,arrayBuffer的数据存储起来 _this.setState({ // preUploading: false, uploadParams: params, arrayBufferData: arrayBufferData, chunksSize: chunks, // preUploadPercent: 100, file_type: file_type, upload_name: params.file.fileName, fileSize: fileSize }, function () { resolve(); }); } }; chunkFileReader.onerror = function () { console.warn('oops, something went wrong.'); }; loadNext(); return [2 /*return*/]; } }); }); }); }; _this_1.handlePartUpload = function (originalFile, cb, onProgress) { var _a = _this_1.state, upload_cmd = _a.upload_cmd, upload_name = _a.upload_name, chunksSize = _a.chunksSize, file_type = _a.file_type, uploadParams = _a.uploadParams; var uploadList = uploadParams.chunks, file = uploadParams.file; var fileMd5 = file.fileMd5; var _b = _this_1.props, url = _b.url, receiver = _b.receiver, env = _b.env, name = _b.name; var count = 0; // 遍历uploadList try { // @ts-ignore Promise.allSettled(uploadList.map(function (_uploadItem) { return new Promise(function (resolve, reject) { var chunkMd5 = _uploadItem.chunkMd5, chunk = _uploadItem.chunk, start = _uploadItem.start, end = _uploadItem.end; var formData = new FormData(), //新建一个Blob对象,将对应分片的arrayBuffer加入Blob中 blob = new Blob([_this_1.state.arrayBufferData[chunk - 1].currentBuffer], { type: 'application/octet-stream' }); // 上传的参数 var params = "fileMd5=" + fileMd5 + "&chunkMd5=" + chunkMd5 + "&chunk=" + chunk + "&start=" + start + "&end=" + end + "&chunks=" + _this_1.state.arrayBufferData.length; // 通过formData将上传参数传入 formData.append('upload_cmd', upload_cmd); formData.append('upload_field', String(name)); formData.append('file_name', upload_name); formData.append('file_md5', fileMd5); formData.append('chunk_index', chunk); formData.append('chunk_total', String(chunksSize)); formData.append('chunk_size', String(end - start)); formData.append('type', file_type); formData.append('chunk_file', blob); // 搞不懂为什么,这样在壳上可以解密 // Shell.hasShell() && Shell.uploadFile({ path: url || receiver, url: url || receiver, formData: formData, }, () => { }, () => { }) env.fetcher({ url: url || receiver, data: formData, method: 'post' }).then(function (res) { if (res.status === 0) { count++; onProgress(count / chunksSize); resolve(res === null || res === void 0 ? void 0 : res.data); } else { reject({ _err: res === null || res === void 0 ? void 0 : res.msg, _data: formData }); } }).catch(function (e) { return reject(e); }); }); })).then(function (_res) { var _chunk_success_count = 0; var _chunk_error_arr = []; _res.map(function (_upload_res) { if ((_upload_res === null || _upload_res === void 0 ? void 0 : _upload_res.status) === 'fulfilled') { _chunk_success_count++; } else { _chunk_error_arr.push(_upload_res.reason._data); } }); if (_chunk_success_count === chunksSize) { var formData = new FormData(); // 通过formData将上传参数传入,发起文件分片合并通知 formData.append('upload_cmd', 'chunk_merge'); formData.append('upload_field', String(name)); formData.append('file_name', upload_name); formData.append('file_md5', fileMd5); // 搞不懂为什么,这样在壳上可以解密 // Shell.hasShell() && Shell.uploadFile({ path: url || receiver, url: url || receiver, formData: formData, }, () => { }, () => { }) env.fetcher({ url: url || receiver, data: formData, method: 'post' }).then(function (_merge_res) { if ((_merge_res === null || _merge_res === void 0 ? void 0 : _merge_res.status) === 0) { var obj = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, _merge_res === null || _merge_res === void 0 ? void 0 : _merge_res.data), { state: 'uploaded' }); obj.value = obj.value || obj.url; cb(null, originalFile, obj); } else { cb(_merge_res === null || _merge_res === void 0 ? void 0 : _merge_res.msg, originalFile); } }).catch(function (_file_merge_res) { cb('上传失败', originalFile); return; }); } else { _chunk_error_arr.map(function (_chunk_error_item) { env.fetcher({ url: url, data: _chunk_error_item, method: 'post' }).then(function (_error_res) { }); }); throw new Error('chunk file upload error!'); } }).catch(function (_err) { cb(_err, originalFile); return; }); } catch (error) { cb(error, originalFile); return; } }; _this_1.addContent = function () { return (react_1.default.createElement("div", { className: 'add-content-container' }, react_1.default.createElement("div", { className: 'add-content-body' }, react_1.default.createElement("div", { className: 'add-content-body-show' }, "\u5C06\u56FE\u7247\u62D6\u62FD\u6216\u590D\u5236\u81F3\u6B64\u5373\u53EF\u6DFB\u52A0"), react_1.default.createElement("div", { className: 'add-content-divider' }), react_1.default.createElement("div", { className: 'add-content-body-input' }, react_1.default.createElement("div", { className: 'add-content-url' }, react_1.default.createElement(input_1.default, { value: _this_1.state.pictureUrl, onChange: function (e) { _this_1.setState({ pictureUrl: e.target.value }); }, placeholder: '\u8F93\u5165\u56FE\u7247\u5730\u5740' })), react_1.default.createElement("div", { className: 'add-content-commit' }, react_1.default.createElement(Button_1.default, { onClick: function () { return (0, tslib_1.__awaiter)(_this_1, void 0, void 0, function () { var newFiles; var _this_1 = this; return (0, tslib_1.__generator)(this, function (_a) { newFiles = this.state.files.concat(); newFiles.push(this.state.pictureUrl); this.setState({ files: newFiles }, function () { _this_1.files = newFiles; _this_1.onChange(); _this_1.setState({ pictureUrl: '' }); }); return [2 /*return*/]; }); }); }, disabled: !_this_1.state.pictureUrl }, "\u786E\u8BA4")), react_1.default.createElement("div", { className: 'add-content-add' }, react_1.default.createElement(Button_1.default, { onClick: _this_1.handleSelect }, "\u6DFB\u52A0\u672C\u5730\u56FE\u7247")))))); }; var value = props.value; var multiple = props.multiple; var joinValues = props.joinValues; var delimiter = props.delimiter; var files = []; if (value) { // files = (multiple && Array.isArray(value) ? value : joinValues ? (value as string).split(delimiter) : [value]) files = (Array.isArray(value) ? value : joinValues && typeof value === 'string' && multiple ? value.split(delimiter) : [value]) .map(function (item) { return ImageControl.valueToFile(item); }) .filter(function (item) { return item; }); } _this_1.state = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, _this_1.state), { files: (_this_1.files = files), crop: _this_1.buildCrop(props), frameImageWidth: 0 }); _this_1.sendFile = _this_1.sendFile.bind(_this_1); _this_1.removeFile = _this_1.removeFile.bind(_this_1); _this_1.handleDrop = _this_1.handleDrop.bind(_this_1); _this_1.handleClick = _this_1.handleClick.bind(_this_1); _this_1.handleClick = _this_1.handleClick.bind(_this_1); _this_1.handleCrop = _this_1.handleCrop.bind(_this_1); _this_1.handleDropRejected = _this_1.handleDropRejected.bind(_this_1); _this_1.cancelCrop = _this_1.cancelCrop.bind(_this_1); _this_1.rotatableCrop = _this_1.rotatableCrop.bind(_this_1); _this_1.handleImageLoaded = _this_1.handleImageLoaded.bind(_this_1); _this_1.handleFrameImageLoaded = _this_1.handleFrameImageLoaded.bind(_this_1); _this_1.startUpload = _this_1.startUpload.bind(_this_1); _this_1.stopUpload = _this_1.stopUpload.bind(_this_1); _this_1.toggleUpload = _this_1.toggleUpload.bind(_this_1); _this_1.tick = _this_1.tick.bind(_this_1); _this_1.onChange = _this_1.onChange.bind(_this_1); _this_1.addFiles = _this_1.addFiles.bind(_this_1); _this_1.handleSelect = _this_1.handleSelect.bind(_this_1); _this_1.handlePaste = _this_1.handlePaste.bind(_this_1); _this_1.syncAutoFill = _this_1.syncAutoFill.bind(_this_1); return _this_1; } ImageControl.formatFileSize = function (size, units) { if (units === void 0) { units = [' B', ' KB', ' M', ' G']; } size = parseInt(size, 10) || 0; while (size > 1024 && units.length > 1) { size /= 1024; units.shift(); } return size.toFixed(2) + units[0]; }; ImageControl.valueToFile = function (value, props) { return value ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (typeof value === 'string' ? { value: value, url: value, id: (0, helper_1.guid)() } : value)), { state: 'init' }) : undefined; }; ImageControl.sizeInfo = function (width, height, __) { if (!width) { return __('Image.height', { height: height }); } else if (!height) { return __('Image.width', { width: width }); } return __('Image.size', { width: width, height: height }); }; ImageControl.prototype.componentDidMount = function () { this.syncAutoFill(); }; ImageControl.prototype.componentDidUpdate = function (prevProps) { var _this_1 = this; var props = this.props; if (prevProps.value !== props.value && this.emitValue !== props.value) { var value = props.value; var multiple = props.multiple; var joinValues = props.joinValues; var delimiter = props.delimiter; var files = []; if (value) { files = (Array.isArray(value) ? value : joinValues && typeof value === 'string' && multiple ? value.split(delimiter) : [value]) .map(function (item) { var obj = ImageControl.valueToFile(item, props); var org; if (obj && (org = (0, find_1.default)(_this_1.files, function (item) { return item.value === obj.value; }))) { obj = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, org), obj), { id: org.id || obj.id }); } return obj; }) .filter(function (item) { return item; }); } this.setState({ files: (this.files = files) }, this.syncAutoFill); } if (prevProps.crop !== props.crop) { this.setState({ crop: this.buildCrop(props) }); } }; ImageControl.prototype.componentWillUnmount = function () { this.unmounted = true; }; ImageControl.prototype.buildCrop = function (props) { var crop = props.crop; var __ = this.props.translate; if (crop && props.multiple) { props.env && props.env.alert && props.env.alert(__('Image.configError')); return null; } if (crop === true) { crop = {}; } if (crop) { crop = (0, tslib_1.__assign)({ aspectRatio: undefined, guides: true, dragMode: 'move', viewMode: 1, rotatable: true, scalable: true }, crop); } return crop; }; ImageControl.prototype.handleDropRejected = function (rejectedFiles, evt) { if (evt.type !== 'change' && evt.type !== 'drop') { return; } var _a = this.props, multiple = _a.multiple, env = _a.env, accept = _a.accept, __ = _a.translate; var files = rejectedFiles.map(function (fileRejection) { return ((0, tslib_1.__assign)((0, tslib_1.__assign)({}, fileRejection.file), { state: 'invalid', id: (0, helper_1.guid)(), name: fileRejection.file.name })); }); // this.setState({ // files: this.files = multiple // ? this.files.concat(files) // : this.files.length // ? this.files // : files.slice(0, 1) // }); env.alert(__('File.invalidType', { files: files.map(function (file) { return "\u300C" + file.name + "\u300D"; }).join(' '), accept: accept })); }; ImageControl.prototype.startUpload = function (retry) { if (retry === void 0) { retry = false; } if (this.state.uploading) { return; } this.setState({ uploading: true, locked: true, files: (this.files = this.files.map(function (file) { if (retry && file.state === 'error') { file.state = 'pending'; file.progress = 0; } return file; })) }, this.tick); }; ImageControl.prototype.toggleUpload = function () { return this.state.uploading ? this.stopUpload() : this.startUpload(); }; ImageControl.prototype.stopUpload = function () { if (!this.state.uploading) { return; } this.setState({ uploading: false }); }; ImageControl.prototype.tick = function () { var _this_1 = this; if (this.current || !this.state.uploading) { return; } var env = this.props.env; var __ = this.props.translate; var file = (0, find_1.default)(this.files, function (item) { return item.state === 'pending'; }); if (file) { this.current = file; file.state = 'uploading'; this.setState({ files: (this.files = this.files.concat()) }, function () { return _this_1.sendFile(file, function (error, file, obj) { var files = _this_1.files.concat(); var idx = files.indexOf(file); if (!~idx) { return; } var newFile = file; if (error) { newFile.state = file.state !== 'uploading' ? file.state : 'error'; newFile.error = error; if (!_this_1.props.multiple && newFile.state === 'invalid') { files.splice(idx, 1); _this_1.current = null; return _this_1.setState({ files: (_this_1.files = files), error: error }, _this_1.tick); } env.notify('error', error || __('File.errorRetry')); } else { newFile = (0, tslib_1.__assign)((0, tslib_1.__assign)({ name: file.name || _this_1.state.cropFileName }, obj), { preview: file.preview }); } files.splice(idx, 1, newFile); _this_1.current = null; _this_1.setState({ files: (_this_1.files = files) }, _this_1.tick); }, function (progress) { var files = _this_1.files.concat(); var idx = files.indexOf(file); if (!~idx) { return; } // file 是个非 File 对象,先不copy了直接改。 file.progress = progress; _this_1.setState({ files: (_this_1.files = files) }); }); }); } else { this.setState({ uploading: false, locked: false }, function () { _this_1.onChange(!!_this_1.resolve); if (_this_1.resolve) { _this_1.resolve(_this_1.files.some(function (file) { return file.state === 'error'; }) ? __('File.errorRetry') : null); _this_1.resolve = undefined; } }); } }; ImageControl.prototype.removeFile = function (file, index) { var files = this.files.concat(); this.removeFileCanelExecutor(file, true); files.splice(index, 1); var isUploading = this.current === file; if (isUploading) { this.current = null; } this.setState({ files: (this.files = files) }, isUploading ? this.tick : this.onChange); }; ImageControl.prototype.previewImage = function (file, index, e) { var onImageEnlarge = this.props.onImageEnlarge; if (onImageEnlarge) { var files = this.files; e.preventDefault(); onImageEnlarge({ src: (file.preview || file.url || file), originalSrc: (file.preview || file.url || file), index: index, list: files.map(function (file) { return ({ src: (file.preview || file.url || file), originalSrc: (file.preview || file.url || file), title: file.name || (0, InputFile_1.getNameFromUrl)(file.value || file.url || file) }); }) }); } }; ImageControl.prototype.editImage = function (index) { var files = this.files; this.setState({ cropFile: { preview: files[index].preview || files[index].url, name: files[index].name, state: 'init' }, cropFileName: files[index].name }); }; ImageControl.prototype.onChange = function (changeImmediately) { var _a = this.props, multiple = _a.multiple, onChange = _a.onChange, joinValues = _a.joinValues, extractValue = _a.extractValue, delimiter = _a.delimiter, valueField = _a.valueField, isUrl = _a.isUrl, env = _a.env; var files = isUrl ? this.files : this.files.filter(function (file) { return file.state == 'uploaded' || file.state == 'init'; }); var newValue = files.length ? joinValues ? files[0].value : files[0] : ''; if (multiple) { newValue = joinValues ? files.map(function (item) { return item.value; }).join(delimiter) : extractValue ? files.map(function (item) { return item.value; }) : files; } else { newValue = joinValues ? newValue.value || newValue : extractValue ? newValue[valueField || 'value'] : newValue; } if (isUrl) { newValue = files.map(function (item) { var _a, _b, _c; if (typeof item === 'string') { return item; } if ((_a = (item.addr || item.url)) === null || _a === void 0 ? void 0 : _a.includes('http')) { return item.addr || item.url; } return (((_c = (_b = env.axiosInstance) === null || _b === void 0 ? void 0 : _b.defaults) === null || _c === void 0 ? void 0 : _c.baseURL) || (env === null || env === void 0 ? void 0 : env.ajaxApi) || '') + (item.addr || item.url); }).join(delimiter); } onChange((this.emitValue = newValue || ''), undefined, changeImmediately); this.syncAutoFill(); }; ImageControl.prototype.syncAutoFill = function () { var _a = this.props, autoFill = _a.autoFill, multiple = _a.multiple, onBulkChange = _a.onBulkChange, data = _a.data; if (!(0, helper_1.isEmpty)(autoFill) && onBulkChange) { var files = this.state.files.filter(function (file) { return ~['uploaded', 'init', 'ready'].indexOf(file.state); }); var toSync_1 = (0, tpl_builtin_1.dataMapping)(autoFill, multiple ? { items: files } : files[0]); Object.keys(toSync_1).forEach(function (key) { if ((0, isPlainObject_1.default)(toSync_1[key]) && (0, isPlainObject_1.default)(data[key])) { toSync_1[key] = (0, merge_1.default)({}, data[key], toSync_1[key]); } }); onBulkChange(toSync_1); } }; ImageControl.prototype.handleSelect = function () { this.dropzone.current && this.dropzone.current.open(); }; ImageControl.prototype.handleRetry = function (index) { var files = this.files.concat(); var file = files[index]; if (file.state !== 'invalid' && file.state !== 'error') { return; } file.state = 'pending'; file.progress = 0; this.setState({ files: files }, this.startUpload); }; ImageControl.prototype.handleDrop = function (files) { var _a = this.props, multiple = _a.multiple, crop = _a.crop; if (crop && !multiple) { var file = files[0]; if (!file.preview || !file.url) { file.preview = window.URL.createObjectURL(file); } return this.setState({ cropFile: file, cropFileName: file.name }); } this.addFiles(files); }; ImageControl.prototype.handlePaste = function (e) { var event = e.nativeEvent; var files = []; var items = event.clipboardData.items; var accept = this.props.accept || '*'; [].slice.call(items).forEach(function (item) { var blob; if (item.kind !== 'file' || !(blob = item.getAsFile()) || !(0, attr_accept_1.default)(blob, accept)) { return; } blob.id = (0, helper_1.guid)(); files.push(blob); }); this.handleDrop(files); }; ImageControl.prototype.handleCrop = function () { var _this_1 = this; var _a = this.props, cropFormat = _a.cropFormat, cropQuality = _a.cropQuality; this.cropper.getCroppedCanvas().toBlob(function (file) { _this_1.addFiles([file]); _this_1.setState({ cropFile: undefined, locked: false, lockedReason: '' }); }, cropFormat || 'image/png', cropQuality || 1); }; ImageControl.prototype.cancelCrop = function () { this.setState({ cropFile: undefined, cropFileName: undefined, locked: false, lockedReason: '' }, this.onChange); }; ImageControl.prototype.rotatableCrop = function () { this.cropper.rotate(45); }; ImageControl.prototype.addFiles = function (files) { var _this_1 = this; if (!files.length) { return; } var _a = this.props, multiple = _a.multiple, maxLength = _a.maxLength, maxSize = _a.maxSize, accept = _a.accept, __ = _a.translate; var currentFiles = this.files; if (!multiple && currentFiles.length) { currentFiles = []; } var allowed = (multiple ? maxLength ? maxLength : files.length + currentFiles.length : 1) - currentFiles.length; var inputFiles = []; [].slice.call(files, 0, allowed).forEach(function (file) { if (maxSize && file.size > maxSize) { _this_1.props.env.alert(__('File.maxSize', { filename: file.name, actualSize: ImageControl.formatFileSize(file.size), maxSize: ImageControl.formatFileSize(maxSize) })); return; } file.state = 'pending'; file.id = (0, helper_1.guid)(); if (!file.preview || !file.url) { file.preview = URL.createObjectURL(file); } inputFiles.push(file); }); if (!inputFiles.length) { return; } this.setState({ error: undefined, files: (this.files = currentFiles.concat(inputFiles)), locked: true }, function () { var autoUpload = _this_1.props.autoUpload; if (autoUpload) { _this_1.startUpload(); } }); }; ImageControl.prototype.sendFile = function (file, cb, onProgress) { var _this_1 = this; var _a = this.props, limit = _a.limit, __ = _a.translate; if (!limit) { return this._upload(file, cb, onProgress); } var image = new Image(); image.onload = function () { var width = image.width; var height = image.height; var error = ''; if ((limit.width && limit.width != width) || (limit.height && limit.height != height)) { error = __('Image.sizeNotEqual', { info: ImageControl.sizeInfo(limit.width, limit.height, __) }); } else if ((limit.maxWidth && limit.maxWidth < width) || (limit.maxHeight && limit.maxHeight < height)) { error = __('Image.limitMax', { info: ImageControl.sizeInfo(limit.maxWidth, limit.maxHeight, __) }); } else if ((limit.minWidth && limit.minWidth > width) || (limit.minHeight && limit.minHeight > height)) { error = __('Image.limitMin', { info: ImageControl.sizeInfo(limit.minWidth, limit.minHeight, __) }); } else if (limit.aspectRatio && Math.abs(width / height - limit.aspectRatio) > 0.01) { error = __(limit.aspectRatioLabel || 'Image.limitRatio', { ratio: (+limit.aspectRatio).toFixed(2) }); } if (error) { file.state = 'invalid'; cb(error, file); } else { _this_1._upload(file, cb, onProgress); } }; image.src = (file.preview || file.url); }; ImageControl.prototype.getFileMd5 = function (file) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { return (0, tslib_1.__generator)(this, function (_a) { return [2 /*return*/, new Promise(function (resolve) { var spark = new spark_md5_1.default.ArrayBuffer(); var totalFileReader = new FileReader(); totalFileReader.readAsArrayBuffer(file); totalFileReader.onload = function (e) { // 对整个totalFile生成md5 spark.append(e.target.result); resolve(spark.end()); // 计算整个文件的fileMd5 }; })]; }); }); }; ImageControl.prototype._upload = function (file, cb, onProgress) { var _this_1 = this; var _a = this.props, url = _a.url, receiver = _a.receiver, env = _a.env, name = _a.name, __ = _a.translate; var formData = new FormData(); this.handleFile(file).then(function () { var uploadParams = _this_1.state.uploadParams; formData.append('upload_cmd', 'check_exist'); formData.append('upload_field', String(name)); formData.append('file_name', uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.file.fileName); formData.append('file_md5', uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.file.fileMd5); // 搞不懂为什么,这样在壳上可以解密 // Shell.hasShell() && Shell.uploadFile({ path: url || receiver, url: url || receiver, formData: formData, }, () => { }, () => { }) env.fetcher({ url: url || receiver, data: formData, method: 'post', dataType: 'form-data' }).then(function (res) { if ((res === null || res === void 0 ? void 0 : res.status) === 0 && (res === null || res === void 0 ? void 0 : res.data)) { var exist = (res === null || res === void 0 ? void 0 : res.data).exist; switch (exist) { case true: onProgress(1); var obj = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, res.data), { state: 'uploaded' }); obj.value = obj.value || obj.url; cb(null, file, obj); break; case false: _this_1.setState({ upload_cmd: 'chunk_upload' }, function () { // 上传分片文件 _this_1.handlePartUpload(file, cb, onProgress); }); break; default: break; } } else { throw new Error(res.msg || __('File.errorRetry')); } }).catch(function (error) { return cb(error.message || __('File.errorRetry'), file); }); }); }; ImageControl.prototype._send = function (file, receiver, params, onProgress) { return (0, tslib_1.__awaiter)(this, void 0, Promise, function () { var fd, data, api, fileField, idx, env; var _this_1 = this; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: fd = new FormData(); data = this.props.data; api = (0, api_1.buildApi)(this.props.url || receiver, (0, helper_1.createObject)(data, params), { method: 'post' }); fileField = this.props.fileField || 'file'; idx = api.url.indexOf('?'); if (~idx && params) { params = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (0, helper_1.qsparse)(api.url.substring(idx + 1))), params); api.url = api.url.substring(0, idx) + '?' + (0, helper_1.qsstringify)(params); } else if (params) { api.url += '?' + (0, helper_1.qsstringify)(params); } if (api.data) { (0, helper_1.qsstringify)(api.data) .split('&') .filter(function (item) { return item !== ''; }) .forEach(function (item) { var parts = item.split('='); fd.append(parts[0], decodeURIComponent(parts[1])); }); } // Note: File类型字段放在后面,可以支持第三方云存储鉴权 fd.append(fileField, file, file.name || this.state.cropFileName); env = this.props.env; if (!env || !env.fetcher) { throw new Error('fetcher is required'); } _a.label = 1; case 1: _a.trys.push([1, , 3, 4]); return [4 /*yield*/, env.fetcher(api, fd, { method: 'post', cancelExecutor: function (cancelExecutor) { // 记录取消器,取消的时候要调用 _this_1.fileUploadCancelExecutors.push({ file: file, executor: cancelExecutor }); }, onUploadProgress: function (event) { return onProgress(event.loaded / event.total); } })]; case 2: return [2 /*return*/, _a.sent()]; case 3: this.removeFileCanelExecutor(file); return [7 /*endfinally*/]; case 4: return [2 /*return*/]; } }); }); }; ImageControl.prototype.removeFileCanelExecutor = function (file, execute) { if (execute === void 0) { execute = false; } this.fileUploadCancelExecutors = this.fileUploadCancelExecutors.filter(function (item) { if (execute && item.file === file) { item.executor(); } return item.file !== file; }); }; ImageControl.prototype.handleClick = function () { this.refs.dropzone.open(); }; ImageControl.prototype.handleImageLoaded = function (index, e) { var _this_1 = this; var imgDom = e.currentTarget; var img = new Image(); img.onload = function () { delete img.onload; var files = _this_1.files.concat(); var file = files[index]; if (!file) { return; } file.info = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, file.info), { width: img.width, height: img.height }); files.splice(index, 1, file); var needUploading = !!(_this_1.current || (0, find_1.default)(files, function (file) { return file.state === 'pending'; })); _this_1.unmounted || _this_1.setState({ files: (_this_1.files = files) }, !needUploading ? _this_1.onChange : undefined); }; img.src = imgDom.src; }; ImageControl.prototype.handleFrameImageLoaded = function (e) { var imgDom = e.currentTarget; var img = new Image(); var clientHeight = this.frameImageRef.current.clientHeight; var _this = this; img.onload = function () { var ratio = this.width / this.height; var finalWidth = (ratio * (clientHeight - 2)).toFixed(2); _this.setState({ frameImageWidth: +finalWidth }); }; img.src = imgDom.src; }; ImageControl.prototype.validate = function () { var _this_1 = this; var __ = this.props.translate; if (this.state.locked && this.state.lockedReason) { return this.state.lockedReason; } else if (this.state.cropFile) { return new Promise(function (resolve) { _this_1.resolve = resolve; _this_1.handleCrop(); }); } else if (this.state.uploading || this.files.some(function (item) { return item.state === 'pending'; })) { return new Promise(function (resolve) { _this_1.resolve = resolve; _this_1.startUpload(); }); } else if (this.files.some(function (item) { return item.state === 'error'; })) { return __('File.errorRetry'); } }; ImageControl.prototype.render = function () { var _this_1 = this; var _a = this.props, className = _a.className, cx = _a.classnames, placeholder = _a.placeholder, disabled = _a.disabled, multiple = _a.multiple, accept = _a.accept, maxLength = _a.maxLength, autoUpload = _a.autoUpload, hideUploadButton = _a.hideUploadButton, thumbMode = _a.thumbMode, thumbRatio = _a.thumbRatio, reCropable = _a.reCropable, frameImage = _a.frameImage, fixedSize = _a.fixedSize, fixedSizeClassName = _a.fixedSizeClassName, __ = _a.translate, isUrl = _a.isUrl; var _b = this.state, files = _b.files, error = _b.error, crop = _b.crop, uploading = _b.uploading, cropFile = _b.cropFile, frameImageWidth = _b.frameImageWidth; var frameImageStyle = {}; if (fixedSizeClassName && frameImageWidth && fixedSize) { frameImageStyle.width = frameImageWidth; } var filterFrameImage = (0, tpl_1.filter)(frameImage, this.props.data, '| raw'); var hasPending = files.some(function (file) { return file.state == 'pending'; }); return (react_1.default.createElement("div", { className: cx("ImageControl", className) }, cropFile ? (react_1.default.createElement("div", { className: cx('ImageControl-cropperWrapper') }, react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "...") }, react_1.default.createElement(Cropper, (0, tslib_1.__assign)({}, crop, { onInitialized: function (instance) { _this_1.cropper = instance; }, src: cropFile.preview }))), react_1.default.createElement("div", { className: cx('ImageControl-croperToolbar') }, crop.rotatable && (react_1.default.createElement("a", { className: cx('ImageControl-cropRotatable'), onClick: this.rotatableCrop, "data-tooltip": __('rotate'), "data-position": "left" }, react_1.default.createElement(icons_1.Icon, { icon: "retry", className: "icon" }))), react_1.default.createElement("a", { className: cx('ImageControl-cropCancel'), onClick: this.cancelCrop, "data-tooltip": __('cancel'), "data-position": "left" }, react_1.default.createElement(icons_1.Icon, { icon: "close", className: "icon" })), react_1.default.createElement("a", { className: cx('ImageControl-cropConfirm'), onClick: this.handleCrop, "data-tooltip": __('confirm'), "data-position": "left" }, react_1.default.createElement(icons_1.Icon, { icon: "check", className: "icon" }))))) : (react_1.default.createElement(react_dropzone_1.default, { key: "drop-zone", ref: this.dropzone, onDrop: this.handleDrop, onDropRejected: this.handleDropRejected, accept: accept, multiple: multiple, disabled: disabled }, function (_a) { var getRootProps = _a.getRootProps, getInputProps = _a.getInputProps, isDragActive = _a.isDragActive, isDragAccept = _a.isDragAccept, isDragReject = _a.isDragReject, isFocused = _a.isFocused; var addCon = react_1.default.createElement("label", { className: cx('ImageControl-addBtn', { 'is-disabled': disabled }, fixedSize ? 'ImageControl-fixed-size' : '', fixedSize ? fixedSizeClassName : ''), style: frameImageStyle, onClick: isUrl ? null : _this_1.handleSelect, "data-tooltip": __(placeholder), "data-position": "right", ref: _this_1.frameImageRef }, filterFrameImage ? (react_1.default.createElement(Image_1.default, { key: "upload-default-image", src: filterFrameImage, classN