关于<a-upload-dragger>实现选择文件夹,上传文件夹中符合要求的文件,并在所有符合要求文件上传完成后统一进行提示。这里面文件是直接上传到七牛云
这里要实现这样一个功能,就是批量上传图片的功能,在上传的时候,选择要上传的文件夹,这个组件会自动取读取这个文件夹中所有的文件,并挨个进行上传,我们需要再上传的时候添加个过滤条件,只有符合我们规定的文件才会调用接口完成真正的上传功能。这里面还有个直接上传到七牛云的
组件代码:
<a-upload-dragger
name="file"
:fileList="filesList"
directory
:show-upload-list="false"
:auto-upload="false"
@change="handleFiles"
>
<div class="upload-area">
<upload-one theme="filled" size="24" fill="#383838" :strokeWidth="3"/>
<div class="text">
上传文件夹
</div>
</div>
</a-upload-dragger>
/**
*directory:允许上传文件夹
*show-upload-list:是否显示上传的文件列表
*auto-upload:是否开启自动上传
*change:文件状态改变的回调
**/
/**
*change
*文件状态改变的回调,返回为:
*{
* file: { /* ... */ },
* fileList: [ /* ... */ ],当前的文件列表。
* event: { /* ... */ },
*}
**/
这个具体上传的方法,用了一个防抖,主要是因为,这个 <a-upload-dragger>组件只要查到一个文件就会调用一次,不是等加载完所有的文件后,才取一次性调用完成上传。但其实我们在第一次就能拿到文件夹中所有的文件,所以需要加一个防抖,防止重复上传。
async function handleFiles({ fileList }) {
clearTimeout(debounceTimeout.value);
loading.value = true;
debounceTimeout.value = setTimeout(async () => {
// console.log('fileList', fileList);
const files = Array.isArray(fileList) ? fileList : [fileList];
const uploadPromises = files.map(item => {
// 进行规则校验
if (validateFile(item)) {
return uploadFileFn(item.originFileObj);
}
// return Promise.reject(new Error(`文件 ${item.name} 不符合上传条件`));
return Promise.resolve();
});
try {
// 等待所有符合条件的文件上传完成
const re = await Promise.all(uploadPromises);
const successCount = re.filter(it => it && it.data.success).length;
const errorCount = re.filter(it => it && !it.data.success).map(item => item.data.message);
is.value = true;
backData.value = {
successCount,
errorCount: errorCount.length,
errorContent: errorCount,
};
} catch (error) {
// message.error('文件部分不符合上传条件');
} finally {
loading.value = false;
emits('importSuccess');
// closeDialog();
}
}, 300); // 300 毫秒的防抖延迟
}
自定义校验,检查文件是否符合上传的规则。
function validateFile(file) {
// 自定义规则校验,返回 true 或 false
const allowedTypes = ['image/jpeg', 'image/png'];
return allowedTypes.includes(file.type);
}
自定义文件上传方法:这里用到的是直接上传到七牛云,但这个方法没写全,上传之前,还需要拿到七牛云的token,这个需要自己写。
async function uploadFileFn(file) {
try {
const tokenData = await uploadFileGetToken({
file_upload_business_type: 'product_library',
});
if (!tokenData) {
throw new Error('获取上传 token 失败');
}
const fileFormData = new FormData();
fileFormData.set('file', file);
fileFormData.set('key', `${tokenData.data.key}${file.name.slice(file.name.lastIndexOf('.') + 1)}`);
fileFormData.set('token', tokenData.data.token);
fileFormData.set('business_type', 'attachment');
const res = await axios.post('https://up.qiniup.com/', fileFormData, {
headers: {
Authorization: `UpToken ${tokenData.data.token}`,
'Content-Type': 'multipart/form-data',
},
});
if (res.data.success === false) {
throw new Error(res.data.msg || '上传失败');
}
const backUrlItem = `${tokenData.data.domain}${res.data.key}`;
const uploadImgObj = {
cover_image: backUrlItem,
name: file.name.replace(/\.[^/.]+$/, ''),
};
return Promise.resolve();
} catch (error) {
// console.error('上传文件时发生错误:', error);
return Promise.reject(error); // 返回错误
}
}