-
批量处理优化:
- 使用
Promise.all
并行处理文件读取和上传 - 添加了专门的
batchUploadToMinio
函数处理批量上传 - 移除了之前的分批处理逻辑,改为一次性并行上传所有文件
- 基于文件大小计算总体上传进度,而不是简单的文件数量
- 进度条显示更准确的整体上传进度
- 使用
页面引入插件
import { initMinio, putObject } from 'minio-js'
// 组件挂载时初始化MinIO
onMounted(() => {
initMinioClient();
});
/**
* 处理文件上传
* @param event 上传事件
*/
async function changeFile(event: any) {
if (isUploading.value) {
ElMessage.warning('有文件正在上传中,请等待完成');
return;
}
const files = Array.from(event.target.files || []);
if (files.length === 0) return;
isUploading.value = true;
const Forward = 'image/';
try {
// 批量读取所有文件内容
const fileDataPromises = files.map(file => ({
file,
name: file.webkitRelativePath || file.name,
size: file.size,
dataPromise: readFileAsArrayBuffer(file)
}));
// 读取所有文件内容
const fileData = await Promise.all(fileDataPromises.map(async item => {
const content = await item.dataPromise;
return {
content,
path: Forward + item.name,
size: item.size,
name: item.name
};
}));
// 批量上传到MinIO
await batchUploadToMinio('src', fileData, progressRef);
// 批量更新服务器状态
await Promise.all(fileData.map(item =>
pushUplaodnews(getFileTypeNumber(fileType), item.name, item.size.toString())
));
ElMessage.success(`所有文件上传完成! 共 ${files.length} 个文件`);
} catch (error) {
console.error('批量上传失败:', error);
ElMessage.error('批量上传失败: ' + (error.message || '未知错误'));
} finally {
resetProgress();
isUploading.value = false;
// 清空文件输入框的值,确保下次可以选择相同文件
event.target.value = '';
}
}
/**
* 读取文件为ArrayBuffer
*/
function readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target?.result as ArrayBuffer);
reader.onerror = (e) => reject(new Error('文件读取失败'));
reader.readAsArrayBuffer(file);
});
}
/**
* 上传文件到MinIO
*/
function uploadToMinio(bucket: string, content: any, path: string): Promise<void> {
return new Promise((resolve, reject) => {
putObject(bucket, content, path, (err) => {
if (err) reject(err);
else resolve();
});
});
}
/**
* 批量上传文件到MinIO并显示总体进度
* @param bucket MinIO桶名称
* @param files 文件对象数组,包含内容和路径
* @param progressRef 进度条引用
*/
async function batchUploadToMinio(bucket: string, files: Array<{content: any, path: string, size: number}>, progressRef: any): Promise<void> {
const totalSize = files.reduce((acc, file) => acc + file.size, 0);
let uploadedSize = 0;
// 使用Promise.all并行上传多个文件
const uploadPromises = files.map(async (file, index) => {
try {
await uploadToMinio(bucket, file.content, file.path);
// 更新总进度
uploadedSize += file.size;
progressRef.value = Math.round((uploadedSize / totalSize) * 100);
return { success: true, path: file.path };
} catch (error) {
console.error(`上传失败: ${file.path}`, error);
return { success: false, path: file.path, error };
}
});
return Promise.all(uploadPromises).then(() => {});
}
最后注意上传组件ID重复使用问题,可能导致第二次上传失败的问题
-
修复了ID重复问题:
- 为每个文件输入框分配了唯一的ID,如
imageFileInput
,posFileInput
,cameraFileInput
等 - 确保每个
label
的for
属性与对应的输入框ID匹配
- 为每个文件输入框分配了唯一的ID,如