feat: upload组件支持计算md5(通过组件参数开启)
This commit is contained in:
parent
d8d78edde1
commit
f57dacfe5d
|
|
@ -33,6 +33,7 @@
|
|||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dnd-touch-backend": "^16.0.1",
|
||||
"sha1": "^1.1.1",
|
||||
"spark-md5": "^3.0.2",
|
||||
"tslib": "^2.4.0",
|
||||
"uuid": "^8.3.2",
|
||||
"weixin-js-sdk": "^1.6.3",
|
||||
|
|
@ -66,8 +67,9 @@
|
|||
"@types/react-dom": "^18.2.14",
|
||||
"@types/react-native": "^0.72.8",
|
||||
"@types/sha1": "^1.1.3",
|
||||
"@types/spark-md5": "^3.0.5",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"@types/wechat-miniprogram": "^3.4.5",
|
||||
"@types/wechat-miniprogram": "^3.4.9",
|
||||
"antd": "5.13.3",
|
||||
"antd-mobile": "5.33.0",
|
||||
"antd-mobile-icons": "0.3.0",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
|||
import { ReactComponentProps } from 'oak-frontend-base/lib/types/Page';
|
||||
import { generateNewId } from 'oak-domain/lib/utils/uuid';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { calculateFileMd5 } from '../../../utils/files/md5';
|
||||
|
||||
type ExtraFile = EntityDict['extraFile']['OpSchema'];
|
||||
export interface EnhancedExtraFile extends ExtraFile {
|
||||
|
|
@ -90,6 +91,7 @@ export default OakComponent({
|
|||
size: 3, // 每行可显示的个数 小程序独有
|
||||
showUploadList: true, //web独有
|
||||
showUploadProgress: false, // web独有
|
||||
calcMd5: false, // 是否计算文件md5值
|
||||
accept: 'image/*', // web独有
|
||||
disablePreview: false, // 图片是否可预览
|
||||
disableDelete: false, // 图片是否可删除
|
||||
|
|
@ -180,6 +182,7 @@ export default OakComponent({
|
|||
fileType: string;
|
||||
size: number;
|
||||
sort: number;
|
||||
md5: string;
|
||||
},
|
||||
file: File | string
|
||||
) {
|
||||
|
|
@ -193,7 +196,7 @@ export default OakComponent({
|
|||
bucket,
|
||||
autoUpload,
|
||||
} = this.props;
|
||||
const { name, fileType, size, sort } = options;
|
||||
const { name, fileType, size, sort, md5 } = options;
|
||||
const extension = name.substring(name.lastIndexOf('.') + 1);
|
||||
const filename = name.substring(0, name.lastIndexOf('.'));
|
||||
const { files } = this.state;
|
||||
|
|
@ -210,6 +213,7 @@ export default OakComponent({
|
|||
entity,
|
||||
filename,
|
||||
size,
|
||||
md5,
|
||||
extension,
|
||||
fileType,
|
||||
entityId,
|
||||
|
|
@ -228,13 +232,26 @@ export default OakComponent({
|
|||
this.features.extraFile.addLocalFile(id, file);
|
||||
}
|
||||
},
|
||||
addFileByWeb(file: File) {
|
||||
async addFileByWeb(file: File) {
|
||||
const { size, type, name } = file;
|
||||
this.addExtraFileInner(
|
||||
let md5 = null;
|
||||
if (this.props.calcMd5) {
|
||||
try {
|
||||
// 计算文件md5值
|
||||
md5 = await calculateFileMd5(file)
|
||||
} catch (error) {
|
||||
this.triggerEvent('onError', {
|
||||
level: 'error',
|
||||
msg: '计算文件MD5失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
await this.addExtraFileInner(
|
||||
{
|
||||
name,
|
||||
fileType: type,
|
||||
size,
|
||||
md5,
|
||||
sort: this.getSort(),
|
||||
},
|
||||
file
|
||||
|
|
@ -256,7 +273,7 @@ export default OakComponent({
|
|||
msg: errMsg,
|
||||
});
|
||||
} else {
|
||||
tempFiles.map((tempExtraFile, index) => {
|
||||
await Promise.all(tempFiles.map(async (tempExtraFile, index) => {
|
||||
const {
|
||||
tempFilePath,
|
||||
thumbTempFilePath,
|
||||
|
|
@ -266,16 +283,28 @@ export default OakComponent({
|
|||
const filePath = tempFilePath || thumbTempFilePath;
|
||||
const fileFullName =
|
||||
filePath.match(/[^/]+(?!.*\/)/g)![0];
|
||||
this.addExtraFileInner(
|
||||
let md5 = null;
|
||||
if (this.props.calcMd5) {
|
||||
try {
|
||||
md5 = await calculateFileMd5(filePath);
|
||||
} catch (error) {
|
||||
this.triggerEvent('onError', {
|
||||
level: 'error',
|
||||
msg: '计算文件MD5失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
await this.addExtraFileInner(
|
||||
{
|
||||
name: fileFullName,
|
||||
fileType,
|
||||
size,
|
||||
md5,
|
||||
sort: this.getSort(index),
|
||||
},
|
||||
filePath
|
||||
);
|
||||
});
|
||||
}));
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.errMsg !== 'chooseMedia:fail cancel') {
|
||||
|
|
@ -520,6 +549,8 @@ export default OakComponent({
|
|||
size: number;
|
||||
showUploadList: boolean;
|
||||
showUploadProgress: boolean;
|
||||
// 是否计算文件md5值
|
||||
calcMd5: boolean;
|
||||
accept: string;
|
||||
// 图片是否可预览
|
||||
disablePreview: boolean;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
export async function calculateFileMd5(
|
||||
filePath: string
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fs = wx.getFileSystemManager();
|
||||
(fs as any).getFileInfo({
|
||||
filePath: filePath,
|
||||
digestAlgorithm: 'md5',
|
||||
success(res: any) {
|
||||
resolve(res.digest as string);
|
||||
},
|
||||
fail(err: any) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import SparkMd5 from 'spark-md5';
|
||||
|
||||
export function calculateFileMd5(
|
||||
file: File
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunkSize = 2097152;
|
||||
const chunks = Math.ceil(file.size / chunkSize);
|
||||
let currentChunk = 0;
|
||||
const spark = new SparkMd5.ArrayBuffer();
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = function (e) {
|
||||
spark.append(e.target?.result as ArrayBuffer);
|
||||
currentChunk++;
|
||||
if (currentChunk < chunks) {
|
||||
loadNext();
|
||||
} else {
|
||||
resolve(spark.end());
|
||||
}
|
||||
};
|
||||
fileReader.onerror = function () {
|
||||
reject(new Error('Failed to read file'));
|
||||
};
|
||||
function loadNext() {
|
||||
const start = currentChunk * chunkSize;
|
||||
const end = Math.min(start + chunkSize, file.size);
|
||||
fileReader.readAsArrayBuffer(file.slice(start, end));
|
||||
}
|
||||
loadNext();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export function calculateFileMd5(
|
||||
file: File | string
|
||||
): Promise<string> {
|
||||
return new Promise((revlove) => {
|
||||
revlove('dummy-md5-hash-for-index');
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import SparkMd5 from 'spark-md5';
|
||||
|
||||
export function calculateFileMd5(
|
||||
file: File
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunkSize = 2097152;
|
||||
const chunks = Math.ceil(file.size / chunkSize);
|
||||
let currentChunk = 0;
|
||||
const spark = new SparkMd5.ArrayBuffer();
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = function (e) {
|
||||
spark.append(e.target?.result as ArrayBuffer);
|
||||
currentChunk++;
|
||||
if (currentChunk < chunks) {
|
||||
loadNext();
|
||||
} else {
|
||||
resolve(spark.end());
|
||||
}
|
||||
};
|
||||
fileReader.onerror = function () {
|
||||
reject(new Error('Failed to read file'));
|
||||
};
|
||||
function loadNext() {
|
||||
const start = currentChunk * chunkSize;
|
||||
const end = Math.min(start + chunkSize, file.size);
|
||||
fileReader.readAsArrayBuffer(file.slice(start, end));
|
||||
}
|
||||
loadNext();
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue