1、业务需求

可以控制文件上传数量、格式,支持图片、pdf的预览、下载、删除,支持其他文件格式的下载删除。

2、效果截图

3、组件代码

<!--  -->
<template>
  <div class="mainContainer">
    <el-form @submit.native.prevent>
      <el-upload
        class="upload-demo"
        :action="apiPath"
        :accept="acceptType"
        :limit="fileLimit"
        :file-list="fileList"
        :http-request="handleUploadFile"
      >
        <img
          src="@/assets/mainPage/uploadFile.png"
          alt="uploadFile"
          v-if="isChangeFiles"
        />
        <div slot="tip" class="el-upload__tip" v-if="isChangeFiles">
          支持 {{ acceptType }} 格式,最多{{ fileLimit }}个
        </div>
      </el-upload>
      <ul class="uploadView clearfix">
        <li v-for="item in fileList" :key="item.id">
          <div class="fileView" :title="item.name">
            <img :src="getFileIconByName(item.name)" />
            {{ item.name }}
          </div>
          <div class="uploadBtn">
            <a
              href="javascript:void(0)"
              @click="handleRemove(item.id)"
              v-if="isChangeFiles"
              >删除</a
            >
            <a
              href="javascript:void(0)"
              v-if="isHasViewFunc(item.name)"
              @click="handleView(item.url)"
              >查看</a
            >
            <a
              href="javascript:void(0)"
              @click="handleDownload(item.name, item.url)"
              >下载</a
            >
          </div>
        </li>
      </ul>
      <!-- <el-upload class="upload-demo" :action="apiPath" :on-preview="handlePreview" :before-remove="beforeRemove"
        :headers="headers"
        :on-remove="handleRemove"
        :accept="acceptType" :before-upload="beforeUpload" :limit="fileLimit" :on-exceed="handleExceed"
        :file-list="fileList" :on-success="handleFileAdd">
        <img src="@/assets/mainPage/uploadFile.png" alt="uploadFile" />
        <div slot="tip" class="el-upload__tip">支持 {{ acceptType }} 格式,最多{{ fileLimit }}个</div>
      </el-upload> -->
    </el-form>
  </div>
</template>

<script>
import axios from "axios";
import { downloadIamge, downFile } from "@/utils";
export default {
  components: {},
  props: {
    isChangeFiles: {
      type: Boolean,
      default: true,
    },
    fileLimit: {
      type: Number,
    },
    bizType: {
      type: Number,
    },
    offlineflag: {
      type: String,
    },
    fileList: {
      type: Array,
      default: [],
    },
    fileBelongId: {
      type: Number,
    },
    acceptType: {
      type: String,
      default:
        ".xlsx,.xls,.png,.jpeg,.jpg,.gif,.ppt,pptx,.doc,.docx,.zip,.rar,.txt,.bmp,.tif,.pdf,.avi,.mp4,.mov", // 默认文件类型
    },
  },
  data() {
    return {
      // apiPath: "/api/Attachment/UploadFile?bizType=" + this.bizType,
      apiPath: "",
      // headers: { "AuthorizationToken": localStorage.getItem("token") },
      httpRequestUrl: "/api/Attachment/UploadFile?bizType=" + this.bizType,
    };
  },
  computed: {},
  watch: {},
  methods: {
    // 上传文件
    handleUploadFile(params) {
      let files = params.file;
      // 文件上传前处理
      this.beforeUploadFunc(files);
      this.uploadFlieFunc(files);
    },
    // 文件上传方法
    uploadFlieFunc(files) {
      let self = this,
        formData = new FormData();
      formData.append("file", files);
      try {
        axios
          .post(self.httpRequestUrl, formData, {
            headers: {
              AuthorizationToken: localStorage.getItem("token"),
              "Content-Type": "multipart/form-data",
            },
          })
          .then((res) => {
            if (res.data && res.data.returnData) {
              let response = res.data.returnData;
              let obj = {
                name: files.name,
                url: response.AttachmentPath,
                id: response.AttachmentID,
              };
              if (!self.fileBelongId) {
                // 当文件存储位置不是数组对象时
                self.$emit("AddAttachment", response.AttachmentID, obj);
              } else {
                // 当文件存储位置为数组对象时
                self.$emit(
                  "AddAttachment",
                  response.AttachmentID,
                  obj,
                  self.fileBelongId
                );
              }
            } else {
              self.$message.error("文件保存失败");
            }
          });
      } catch (e) {
        self.$message.error("文件保存失败");
      }
    },
    // 文件上传成功时
    // handleFileAdd(response, file, fileList) {
    //   let self = this;
    //   let obj = { name: file.name, url: response.returnData.AttachmentPath, id: response.returnData.AttachmentID }
    //   if(!this.fileBelongId) {
    //     // 当文件存储位置不是数组对象时
    //     self.$emit('AddAttachment', response.returnData.AttachmentID, obj);
    //   } else {
    //     // 当文件存储位置为数组对象时
    //     self.$emit("AddAttachment", response.returnData.AttachmentID, obj, this.fileBelongId);
    //   }
    // },
    // 文件删除
    handleRemove(id) {
      this.$confirm("文件删除后无法恢复,确定要删除文件?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        let file = { id: id };
        if (!this.fileBelongId) {
          this.$emit("removeFile", file);
        } else {
          this.$emit("removeFile", file, this.fileBelongId);
        }
      });
    },
    // 文件上传前处理
    beforeUploadFunc(files) {
      // 判断是否超过最大上传数量
      if (this.fileList.length + 1 > this.fileLimit) {
        this.$message.warning("已超过最大上传数量限制");
        return;
      }
      let fileName = files.name;
      // 获取文件类型
      let typeArr = fileName.split(".");
      let type = typeArr[typeArr.length - 1];
      if (this.acceptType != "任意数据") {
        let standFileTypeArr = this.acceptType.split(",");
        // 判断是否符合上传文件类型
        let arr = standFileTypeArr.filter((item) => item.substr(1) == type);
        if (arr.length == 0) {
          this.$message.error(`仅支持上传${this.acceptType}格式!`);
          return false;
        }
      }
      // let size = files.size;
      // if(size / 1024 / 1024 > 10) {
      //   this.$message.error('单个文件大小上限10M');
      //   return false;
      // }
      // 如果是图片,这里要对图片进行压缩
      // if(type == "png" || type == "jpeg" || type == "jpg" ) {
      //   this.compressPic(files)
      // }
      if (this.offlineflag == "1") {
        this.$confirm("离线上传过程中不能关闭当前页面", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          let newpage = this.$router.resolve({
            name: "offlineDataUpload",
          });
          window.open(newpage.href, "_blank");
        });
      }
    },
    // 压缩图片
    compressPic(file) {},
    // 根据文件名称显示图标
    getFileIconByName(fileName) {
      let iconType = fileName.split(".")[1];
      let iconPic;
      switch (iconType) {
        case "xlsx":
        case "xls":
          iconPic = require("@/assets/mainPage/ico-xlsx.png");
          break;
        case "png":
        case "jpeg":
        case "jpg":
        case "gif":
        case "tif":
          iconPic = require("@/assets/mainPage/ico-png.png");
          break;
        case "ppt":
        case "pptx":
          iconPic = require("@/assets/mainPage/ico-ppt.png");
          break;
        case "doc":
        case "docx":
          iconPic = require("@/assets/mainPage/ico-docx.png");
          break;
        case "rar":
        case "zip":
          iconPic = require("@/assets/mainPage/ico-zip.png");
          break;
        case "txt":
        case "bmp":
          iconPic = require("@/assets/mainPage/ico-txt.png");
          break;
      }
      return iconPic;
    },
    // 是否显示查看按钮,仅当文件是图片或者ppt时可以查看
    isHasViewFunc(fileName) {
      let flag = false;
      let iconType = fileName.split(".")[1];
      if (
        iconType == "png" ||
        iconType == "jpeg" ||
        iconType == "jpg" ||
        iconType == "gif" ||
        iconType == "ppt" ||
        iconType == "pptx"
      ) {
        flag = true;
      }
      return flag;
    },
    // 查看图片
    handleView(url) {
      let baseUrl = process.env.VUE_APP_DOWNLOAD_IP + url;
      window.open(baseUrl, "_blank");
    },
    // 文件下载
    handleDownload(name, url) {
      let iconType = name.split(".")[1];
      let baseUrl = process.env.VUE_APP_DOWNLOAD_IP + url;
      if (iconType == "png" || iconType == "jpeg" || iconType == "jpg") {
        downloadIamge(baseUrl, name);
      } else {
        downFile(baseUrl, name);
      }
    },
  },
  created() {},
  mounted() {},
};
</script>
<style lang='scss'>
.el-upload-list {
  display: none;
}
.uploadView {
  width: 100%;
  height: auto;
  li {
    width: 100%;
    float: left;
    padding: 0px 50px 0px 0px;
    div {
      float: left;
    }
    .fileView {
      width: calc(100% - 150px);
      height: 30px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .uploadBtn {
      padding-left: 15px;
      float: right;
      a {
        color: #5b6cea;
        text-decoration: underline;
        padding-left: 10px;
      }
    }
  }
}
.upload-demo {
  margin-bottom: 20px;
}
</style>
// 图片下载,只能在非跨域情况下使用
export function downloadIamge(imgsrc, name) {//下载图片地址和图片名
  let image = new Image();
  // 解决跨域 Canvas 污染问题
  image.setAttribute("crossOrigin", "anonymous");
  image.onload = function () {
    let canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0, image.width, image.height);
    let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
    let a = document.createElement("a"); // 生成一个a元素
    let event = new MouseEvent("click"); // 创建一个单击事件
    a.download = name || "photo"; // 设置图片名称
    a.href = url; // 将生成的URL设置为a.href属性
    a.dispatchEvent(event); // 触发a的单击事件
  };
  image.src = imgsrc;
}

// 普通文件下载
export function downFile(imgsrc, name) {
  var a = document.createElement("a");
  a.download = name;
  a.href = imgsrc;
  a.target="_blank";
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}

4、组件使用

<upload-multiple :bizType="bizType" :fileLimit="fileLimit" ref="addProjectUpload" :fileList="addProjectForm.FileList" :isChangeFiles="isChangeFiles" @AddAttachment="AddAttachment" @removeFile="removeFile" ></upload-multiple>

import { deleteFile } from "@/api/commonDoc"
import UploadMultiple from '@/components/UploadFileMultiple' // 多附件上传
export default {
	components: { UploadMultiple },
	data() {
        return {
        	bizType: 0, //区分文件上传模块
        	fileLimit: 20, // 文件上传最大上限
        	addProjectForm: {
        		FileList: [] ,// 展示数组
        		FileAttachmentList: [], // 参数上传数组
        	},
        	isChangeFiles: true , // 是否需要新增、修改文件,控制内部按钮显示。true是 false否
        }
    },
    methods: {
    	// 保存文件
        AddAttachment(attachmentId, obj) {
            this.addProjectForm.FileAttachmentList.push({ AttachmentID: attachmentId }); // 这里根据后台要求拼装数据格式
            this.addProjectForm.FileList.push(obj);
            this.addProjectForm = JSON.parse(JSON.stringify(this.addProjectForm)); // 做一次深拷贝,防止对象数据监听不到变化
        },
         // 文件删除
        removeFile(file) {
            let id = file.id;
            let obj = { id: id };
            deleteFile(obj).then(res => {
                if (res.returnData) {
                    let index1 = 0;
                    this.addProjectForm.FileAttachmentList.some(res => {
                        if (res.AttachmentID == id) {
                            this.addProjectForm.FileAttachmentList.splice(index1, 1)
                            return true;
                        }
                        index1++;
                    })
                    let index2 = 0
                    this.addProjectForm.FileList.some(res => {
                        if (res.id == id) {
                            this.addProjectForm.FileList.splice(index2, 1);
                            return true;
                        }
                        index2++;
                    })
                    this.$message({
                        type: "success",
                        message: "删除成功"
                    })
                    return;
                } else {
                    this.$message({
                        type: "error",
                        message: "删除失败"
                    })
                    return;
                }
            })
        }
    }
}

// 文件删除方法
export function deleteFile(id) {
    return request({
        url: "/Attachment/DeleteFile",
        method: 'get',
        params: id
    })
}

5、备注

图标: