179 lines
5.9 KiB
JavaScript
179 lines
5.9 KiB
JavaScript
import Compressor from 'compressorjs';
|
||
;
|
||
export default OakComponent({
|
||
entity: 'extraFile',
|
||
isList: true,
|
||
projection: {
|
||
id: 1,
|
||
tag1: 1,
|
||
tag2: 1,
|
||
origin: 1,
|
||
bucket: 1,
|
||
objectId: 1,
|
||
filename: 1,
|
||
extra1: 1,
|
||
extra2: 1,
|
||
extension: 1,
|
||
type: 1,
|
||
entity: 1,
|
||
entityId: 1,
|
||
fileType: 1,
|
||
sort: 1,
|
||
isBridge: 1,
|
||
uploadState: 1,
|
||
size: 1,
|
||
applicationId: 1,
|
||
},
|
||
data: {
|
||
// 根据 size 不同,计算的图片显示大小不同
|
||
itemSizePercentage: '',
|
||
},
|
||
wechatMp: {
|
||
externalClasses: ['oak-class', 'oak-item-class', 'oak-item-add-class'],
|
||
},
|
||
filters: [
|
||
{
|
||
filter() {
|
||
const { tag1, tag2 } = this.props;
|
||
const filter1 = {};
|
||
if (tag1) {
|
||
Object.assign(filter1, { tag1 });
|
||
}
|
||
if (tag2) {
|
||
Object.assign(filter1, { tag2 });
|
||
}
|
||
return filter1;
|
||
},
|
||
},
|
||
],
|
||
properties: {
|
||
bucket: '',
|
||
autoUpload: false,
|
||
maxNumber: 20,
|
||
extension: [],
|
||
selectCount: 1,
|
||
sourceType: ['album', 'camera'],
|
||
mediaType: ['image'],
|
||
mode: 'aspectFit',
|
||
size: 3,
|
||
showUploadList: true,
|
||
showUploadProgress: false,
|
||
accept: 'image/*',
|
||
disablePreview: false,
|
||
disableDelete: false,
|
||
disableAdd: false,
|
||
disableDownload: false,
|
||
type: 'image',
|
||
origin: null,
|
||
tag1: '',
|
||
tag2: '',
|
||
entity: '',
|
||
entityId: '',
|
||
theme: 'image',
|
||
enableCrop: false,
|
||
enableCompross: false,
|
||
//图片裁剪
|
||
cropQuality: 1,
|
||
showRest: false,
|
||
showGrid: false,
|
||
fillColor: 'white',
|
||
rotationSlider: false,
|
||
aspectSlider: false,
|
||
zoomSlider: true,
|
||
resetText: '重置',
|
||
aspect: 1 / 1,
|
||
minZoom: 1,
|
||
maxZoom: 3,
|
||
cropShape: 'rect',
|
||
cropperProps: {},
|
||
modalTitle: '编辑图片',
|
||
modalWidth: '40vw',
|
||
modalOk: '确定',
|
||
modalCancel: '取消',
|
||
//图片压缩
|
||
strict: true,
|
||
checkOrientation: true,
|
||
retainExif: false,
|
||
maxWidth: Infinity,
|
||
maxHeight: Infinity,
|
||
minWidth: 0,
|
||
minHeight: 0,
|
||
compressWidth: undefined,
|
||
compressHeight: undefined,
|
||
resize: 'none',
|
||
compressQuality: 0.8,
|
||
mimeType: 'auto',
|
||
convertTypes: ['image/png'],
|
||
convertSize: Infinity, //文件类型包含在convertTypes中且文件大小超过此值的文件将转换为 JPEG,Infinity表示禁用该功能
|
||
},
|
||
features: ['extraFile'],
|
||
formData({ data, features }) {
|
||
let files = data
|
||
?.filter((ele) => !ele.$$deleteAt$$)
|
||
.sort((ele1, ele2) => ele1.sort - ele2.sort);
|
||
if (this.props.tag1) {
|
||
files = files?.filter((ele) => ele?.tag1 === this.props.tag1);
|
||
}
|
||
if (this.props.tag2) {
|
||
files = files?.filter((ele) => ele?.tag2 === this.props.tag2);
|
||
}
|
||
const files2 = files.map((ele) => {
|
||
const url = features.extraFile.getUrl(ele);
|
||
const thumbUrl = features.extraFile.getUrl(ele, 'thumbnail');
|
||
const fileState = features.extraFile.getFileState(ele.id);
|
||
const fileName = features.extraFile.getFileName(ele);
|
||
return {
|
||
url,
|
||
thumbUrl,
|
||
fileName,
|
||
fileState: fileState?.state,
|
||
percentage: fileState?.percentage,
|
||
...ele,
|
||
};
|
||
});
|
||
return {
|
||
files: files2,
|
||
};
|
||
},
|
||
methods: {
|
||
async compressFile(file) {
|
||
//https://github.com/fengyuanchen/compressorjs/blob/main/README.md
|
||
const { strict, checkOrientation, retainExif, maxWidth, maxHeight, minWidth, minHeight, compressWidth: width, compressHeight: height, resize, compressQuality: quality, mimeType, convertTypes, convertSize } = this.props;
|
||
// 构建压缩选项
|
||
const options = Object.fromEntries(Object.entries({
|
||
strict, checkOrientation, retainExif, maxWidth, maxHeight, minWidth, minHeight,
|
||
width, height, resize, quality, mimeType, convertTypes, convertSize
|
||
}).filter(([key, value]) => value !== undefined));
|
||
const fileSize = (file.size / 1024 / 1024).toFixed(1);
|
||
console.log("压缩前:", fileSize, "MB");
|
||
console.log("压缩比例:", quality);
|
||
console.log("压缩选项:", options);
|
||
try {
|
||
// 封装 Compressor 实例的 Promise
|
||
const result = await new Promise((resolve, reject) => {
|
||
new Compressor(file, {
|
||
...options,
|
||
success: (compressedFile) => {
|
||
console.log("压缩后:", (compressedFile.size / 1024 / 1024).toFixed(1), "MB");
|
||
if (compressedFile instanceof Blob) {
|
||
//@ts-ignore
|
||
compressedFile = new File([compressedFile], "f" + (compressedFile?.name).slice(-8), { type: compressedFile.type });
|
||
}
|
||
resolve(compressedFile);
|
||
},
|
||
error: (err) => {
|
||
console.error("压缩错误:", err);
|
||
reject(err);
|
||
}
|
||
});
|
||
});
|
||
return result;
|
||
}
|
||
catch (error) {
|
||
console.error('处理文件压缩时出错:', error);
|
||
return file; // 返回原始文件以防压缩失败
|
||
}
|
||
}
|
||
},
|
||
});
|