最近一直再做桌面应用开发,其中一个功能是拖拽文件上传,我突然发现一个bug,比如我上传了五个文件,可能有一个文件的type是空串(因为组件可能识别不到某个文件,比如cad文件或者文件夹的type都会是空串),但是我已经处理的空串的情况并且根据后缀名判断把该文件是否加入筛选后的数组,我发现这样还不行,我就开始打断点,发现他们每个lastDotIndex的值都一样,这肯定不对啊,就是因为lastDotIndex值导致我的摘选条件判断出错了,原来是这么写的
const lastDotIndex = ref();
const uploadOrDragUploadFile = async (files: FileList) => {
const batchId = uid();
try {
const categoryId = props.knowledge.id
if(!categoryId && !files && files.length < 1){
return;
}
// 是否含有文件夹
let folderFlag = false;
const lastDotIndexArray = [];
for (let i = 0; i < files.length; i++) {
// 为了解决有文件夹识别的名称或路径多了.fld的问题
lastDotIndex.value = files[i].path.lastIndexOf('.');
if(!files[i].type && files[i].path.endsWith("fld")){
lastDotIndex.value = -1;
}
if(files[i].type || (lastDotIndex.value !== -1 && lastDotIndex.value < files[i].path.length - 1)){
const filePath =files[i].path;
const { ext } = getFileExt(filePath);
const uniqueId = uid();
const fileItem: TransferItem = {
title: files[i].name,
key: filePath,
type: "upload",
percent: 0,
ext: ext,
fileType: toUpper(ext),
id: uniqueId,
directoryFlag: false,
remotePath: "",
localPath: files[i].path
};
fileItems.push(fileItem);
fileStore.addItem(fileItem);
const n = Math.floor(Math.random() * files.length) + 1;
startLoadingById(fileItem.id!, batchId, n);
}else{
if(!folderFlag){
folderFlag = true;
}
}
}
const fileArrays = [...files]; // 将 FileList 转换为数组
// 过滤出 type 不为空的文件(排除文件夹)
const validFiles = fileArrays.filter((file) => {
return file.type !== '' || (lastIndex.value != -1 && lastIndex.value < file.path.length - 1)
})
if(validFiles.length === 0){
message.warn({
content: "对不起,不能上传文件夹",
class: MESSAGE_CLS.WARN,
});
return;
}
const res = await bachUploadFile(categoryId, Array.from(validFiles)).catch(err => {
stopLoadingById("", batchId);
});
if(res && res.success && res.result.successList.length > 0){
const filePath = res.result.successList[0];
res.result.successList.forEach((path: string) => {
const lastSlashIndex = path.lastIndexOf('/');
if (lastSlashIndex !== -1) {
for (let i = 0; i < fileItems.length; i++){
fileItems[i].title = path.substring(lastSlashIndex + 1)
}
}
const index = path.lastIndexOf("/");
if (index > -1) {
const filename = path.substring(index + 1);
fileItems.find((item: any) => {
if (item.title === filename){
const transferItem = fileStore.getItem(item.id);
transferItem && (transferItem.percent = 100);
setTimeout(() => {
fileStore.delItem(item.id);
}, 200);
}
});
}
});
}
他把const lastDotIndex = ref();声明成响应式常量,其中关键问题在 for (let i = 0; i < files.length; i++) { // 为了解决有文件夹识别的名称或路径多了.fld的问题 lastDotIndex.value = files[i].path.lastIndexOf('.'); if(!files[i].type && files[i].path.endsWith("fld")){ lastDotIndex.value = -1; } 这,其中lastDotIndex.value = files[i].path.lastIndexOf('.');会只保存数组最后一个元素的lastDotIndex 所以我的解决办法如下:
这样就可以了,当然这个方法代码是不全的,删掉了一些,要不字数太多啦,关注问题和解决方法就好啦