fastlion-amis
Version:
一种MIS页面生成工具
973 lines • 60.8 kB
JavaScript
"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