实现上传文件夹功能

文章目录

  • 需求一
    • 代码实现
  • 需求二
  • 小结

需求一

实现上传文件夹功能;一级文件夹包含多个二级文件夹,一级文件夹命名随意,二级文件夹按照 【标签1-标签2-标签3】系列名-作者名 格式进行命名;手动触发上传(遍历循环上传文件);

代码实现

1、

<el-button size="small" class="uploadBtn" :disabled="loading">
 	<input ref="file" class="fileUploaderClass" type='file' name="file" webkitdirectory @change.stop="changesData" />
		{{ fileLists.length === 0 ? '选择文件夹' : '重新选择' }}
</el-button>

<el-button type="primary" v-if="this.fileLists.length > 0" @click="uploadFile" size="small" :loading="loading" :disabled="loading">
		{{ loading ? '上传中...' : '点击上传' }}
</el-button>

2、

/** 选择文件夹 */
    changesData() {
      /** 获取文件夹里面包含的图片文件对象 */
      const fileList = this.$refs.file.files;

      /** 子文件夹命名规范校验规则 */
      const folderRegex = /^\【([^\]]+)\】(.+)-(.+)$/;
      /** 子文件夹名称切割规则 */
      const regex = /【(.*?)】(.*?)-(.*)/;
      for (const i in fileList) {
        if (fileList.hasOwnProperty(i)) {
          /** 根据"/"切割文件路径 */
          const webkitRelativePath = fileList[i].webkitRelativePath;
          const parts = webkitRelativePath.split('/');
          /** 一级文件夹名称 */
          const oneFolderName = parts[0];
          /** 二级文件夹名称 */
          const secondaryFolderName = parts[1];
          if (folderRegex.test(secondaryFolderName) === false) {
            this.$message.error(`${secondaryFolderName} 文件夹命名不规范,请认真学习【命名规范】和详细检查【文件夹层级】之后重新上传`);
            /** 清空input上传的文件 */
            this.$refs.file.value = '';
            break;
          }
          const secondaryFolderNameList = secondaryFolderName.match(regex);
          /** match切割的结果为一个数组,数组第一项为字符串本身 */
          /** 标签 */
          const labels = secondaryFolderNameList[1];
          /** 系列 */
          const series = secondaryFolderNameList[2];
          /** 作者 */
          const author = secondaryFolderNameList[3];
          /** 文件名称 */
          const fileName = parts[2];
          /** 图片文件的宽高获取 */
          let _URL = window.URL || window.webkitURL;
          let image = new Image();
          image.src = _URL.createObjectURL(fileList[i]);
          image.onload = () => {
            /** 整合上传参数 */
            let item = {
              file: fileList[i],
              labels: labels,
              series: series,
              author: author,
              height: image.height,
              width: image.width,
            };
            this.fileLists.push(item);
          };
        }
      }

    },

    /** 上传文件 */
    uploadFile() {
     let successNum = 0;
     let errorNum = 0;
     let promises = [];
     this.loading = true;
      /**  遍历文件列表并创建上传请求的 Promise */
      for (let i = 0; i < this.fileLists.length; i++) {
        const uploadPromise = materialUpload({ ...this.fileLists[i] }).then((res) => {
          if (res && res.code === 0) {
            successNum += 1;
          } else {
            errorNum += 1;
          }
        }).catch((error) => {
          errorNum += 1;
          console.error('Error uploading file:', error);
        });
        promises.push(uploadPromise);
      }

      /** 使用 Promise.all 等待所有的上传请求完成 */
      Promise.all(promises)
        .finally(() => {
          this.loading = false;
          this.$message({
            message: `成功上传文件 ${successNum} 个,失败 ${errorNum} 个。`,
            duration: 30000,
            showClose: true,
            offset: 50
          })
        });
    
      },
    }

需求二

该需求与需求一的区别是,选择之后自动上传,并且文件夹名称没有格式限制,关于上传后的数据处理自由度更高,而且使用批量上传。

	<div class="fileUpload">
		<el-button class="uploadBtn" :disabled="loading">
			<input ref="file" class="fileUploaderClass" type='file' name="file" webkitdirectory
                  @change.stop="changesData()" />
	                {{ this.form.labelList.length === 0 ? '选择文件夹' : '重新选择' }}
         </el-button>
	</div>
   /** 选择文件夹 */
    changesData(event) {
      /** 文件夹里面包含的图片文件对象 */
      let fileObject = this.$refs.file.files;
      const formData = new FormData();
      /** file对象不能为空 */
      if (!(Object.keys(fileObject).length === 0 && fileObject.constructor === Object)) {
        /** 遍历检查文件类型,逻辑自行处理 */
        for (const i in fileObject) {
          /** hasOwnProperty防止i为undefined */
          if (fileObject.hasOwnProperty(i)) {
          }
        }
        const params = {
          url: 'xxx',
          formData: formData
        };
        this.loading = true;
        uploadFiles(params).then((res) => {
          if (res && res.code === 0) {
            /** 一级文件夹的文件,只能有一个斜杠,但斜杠前后字符不限 */
            const folderRegex = /^[^/]+\/[^/]+$/;
            let labelList = [];
            res.data.forEach((item, index) => {
              /** 根据"/"切割文件路径 */
              const webkitRelativePath = item.name;
              const parts = webkitRelativePath.split('/');
              /** 一级文件夹名称 */
              const oneFolderName = parts[0];
              /** 如果文件路径是二级 */
              if (folderRegex.test(item.name) === false) {
                /** 二级文件夹名称 */
                const secondaryFolderName = parts[1];
                /** 文件名称 */
                const fileName = parts[2];
				/** ... 其他逻辑 */
              } else {
                /** ... 其他逻辑 */
              }
            })
            if (labelList.length === 0) {
              this.$confirm('未识别到素材内容,请注意所选文件夹层级结构、文件格式是否符合要求。', '提示', {
                confirmButtonText: "确定",
                showCancelButton: false
              }).then(() => { }).catch(() => { });
            } else {
              this.$message.success('上传成功!');
              /** 根据二级文件夹进行分类 */
              this.form.labelList = labelList.reduce((acc, curr) => {
                /** 检查结果数组中是否已存在具有相同 labelName 的对象 */
                const existingItem = acc.find(item => item.labelName === curr.labelName);
                if (existingItem) {
                  /** 如果存在,将当前对象添加到 materialList 数组中 */
                    existingItem.materialList.push({...});
                  }
                } else {
                  /** 如果不存在,创建一个新的对象并添加到结果数组中 */
                  const item = {
                    labelName: curr.labelName,
                    materialList: [{ imageUrl: curr.imageUrl, name: curr.name, sort: 0 }]
                  };
                  acc.push(item);
                }
                return acc;
              }, []);

            };

          } else {
            /** 清空文件选择 */
            this.$refs.file.value = '';
            this.$confirm('未识别到素材内容,请注意所选文件夹层级结构、文件格式是否符合要求。', '提示', {
              confirmButtonText: "确定",
              showCancelButton: false
            }).then(() => { }).catch(() => { });
          }
        }).finally(() => { this.loading = false; })

      }
    },

小结

记录学习 +1。

你可能感兴趣的:(需求笔记,前端)