vue后台管理系统---上传附件

前言

最近遇到一个项目,使用vue开发后台管理系统,其中有一个需求是需要上传附件(Word、PPT、excel、图片格式、PDF、压缩包)
如图:
在这里插入图片描述

开发

接口

// 上传接口
  uploadFile: (params, onUploadProgress) => upload('/sync_api/api/v1/upload/uploadFile', params, onUploadProgress),

在这里插入图片描述

在这里插入图片描述

页面

html
		<!-- 上传附件 -->
        <div v-loading="fileUploading">
          <div class="title-box">
            <h3 style="width: 120px">
              <span class="required">*</span>
              上传附件
            </h3>
            <p>可上传Word、PPT、excel、图片格式、PDF、压缩包;总内容不超过500MB</p>

			<!-- input上传 -->
            <input
              ref="fileUpload"
              class="upload-input"
              type="file"
              title=""
              multiple="multiple"
              @change="fileChange($event, 0, 500, 0, ['word', 'ppt', 'excel', 'image', 'pdf', 'zip'], fileSuc)"
            />
            <el-button class="add-btn" @click="add('fileUpload')">
              <img alt="" class="imgIcon" src="@/assets/image/icon/addIcon1.png" />
              新增
            </el-button>
          </div>
          <div class="file-list" style="padding-left: 120px">
            <div v-for="(item, index) in fileList" :key="index" class="file-box">
              <div class="file-icon">
              	<!-- 删除icon图片 --> 
                <img
                  class="file-del"
                  src="@/assets/image/icon/icon-file-del.png"
                  alt=""
                  @click="fileList.splice(index, 1)"
                />
                
                <img
                  v-if="typeList.image.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-image.png"
                  alt=""
                  @click="download(item)"
                />
                <img
                  v-else-if="typeList.word.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-word.png"
                  alt=""
                  @click="download(item)"
                />
                <img
                  v-else-if="typeList.ppt.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-ppt.png"
                  alt=""
                  @click="download(item)"
                />
                <img
                  v-else-if="typeList.excel.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-excel.png"
                  alt=""
                  @click="download(item)"
                />
                <img
                  v-else-if="typeList.pdf.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-pdf.png"
                  alt=""
                  @click="download(item)"
                />
                <img
                  v-else-if="typeList.zip.includes(getSuffix(item.originalFileName))"
                  class="file-img"
                  src="@/assets/image/icon/icon-zip.png"
                  alt=""
                  @click="download(item)"
                />
              </div>
              //文件名称
              <p class="file-name">{{ item.originalFileName }}</p>
              
              <el-button class="file-btn" @click="add('fileUpload', index)">
                <img src="@/assets/image/icon/changeIcon.png" alt="" />
                修改
              </el-button>
            </div>
          </div>
        </div>
        
<style>
	.upload-input {
	    height: 0;
	    width: 0;
	    opacity: 0;
	  }
</style>
js
<script>
import { Message } from 'element-ui'
export default {
  components: {},
  data: () => ({
    // 对应类型的名称(上传提示时需要)
    typeName: {
      image: '图片',
      word: 'Word',
      ppt: 'PPT',
      excel: 'Excel',
      zip: '压缩包',
      pdf: 'PDF',
      video: '视频'
    },
    typeList: {
      // 支持上传的后缀名
      image: ['png', 'jpg', 'jpeg', 'gif', 'bmp'], // 图片
      word: ['doc', 'docx'], // Word
      ppt: ['ppt', 'pptx'], // PPT
      excel: ['xls', 'xlsx'], // Excel
      zip: ['zip', 'rar', '7z'], // 压缩包
      pdf: ['pdf'], // PDF
      video: ['mp4', 'mov']
    },
    fileList: [], // 附件列表
    fileUploading: false, // 上传附件Loading
    editIndex: null, // 编辑中的Index
  }),
  watch: { },
  created() {  },
  mounted() {},
  methods: {
    /**
     * 下载
     * @param file 下载的文件
     */
    download(file) {
      this.$download(file.filePath, file.originalFileName)
    },
    /**
     * 上传点击事件
     * @param ref
     * @param editIndex
     */
    add(ref, editIndex) {
      this.editIndex = editIndex
      this.$refs[ref].value = ''
      this.$refs[ref].dispatchEvent(new MouseEvent('click'))
    },
    /**
     * 上传附件文件回调
     * @param fileArr
     * @returns {Promise<void>}
     */
    async fileSuc(fileArr) {
      this.fileUploading = true
      const data = await this.uploadFile(fileArr, 'system').catch(() => {
        this.fileUploading = false
      })
      this.fileUploading = false
      if (this.editIndex != null) {
        this.fileList.splice(this.editIndex, 1, ...data)
      } else {
        this.fileList.push(...data)
      }
    },
    /**
     * input获取文件事件
     * @param e event
     * @param fileSize 限制大小,单位MB
     * @param totalSize 限制总大小,单位MB
     * @param limit 限制数量
     * @param typeList 支持的格式列表
     * @param sucFun 成功回调
     */
    fileChange(e, fileSize, totalSize, limit, typeList, sucFun) {
      const files = e.target.files
      const fileArr = []
      let hasFile = false // 是否有可上传的文件
      const msgList = [] // 消息队列
      let total = 0
      for (const file of files) {
        if (fileArr.length >= limit && limit !== 0) {
          msgList.push(`超过${limit}个文件,剩余文件跳过上传`)
          break
        }
        if (file.size / 1024 / 1024 > fileSize && fileSize !== 0) {
          if (fileSize > 1024) {
            msgList.push(`${file.name}大于${fileSize / 1024}GB,跳过上传`)
          } else {
            msgList.push(`${file.name}大于${fileSize}MB,跳过上传`)
          }
          continue
        }
        total += file.size / 1024 / 1024
        if (total > totalSize && totalSize !== 0) {
          msgList.push(`超过${totalSize}MB,剩余文件跳过上传`)
          break
        }
        let has = false
        // 循环遍历支持下载后缀,不支持的文件则跳过
        for (const k of typeList) {
          const list = this.typeList[k]
          if (list.includes(this.getSuffix(file.name))) {
            has = true
            break
          }
        }
        if (!has) {
          const msgTypeList = []
          for (const k of typeList) {
            msgTypeList.push(this.typeName[k])
          }
          msgList.push(`${file.name}不是${msgTypeList.join('、')},跳过上传`)
          continue
        }
        fileArr.push(file)
        hasFile = true
      }
      // 文件都被跳过,取消上传
      if (!hasFile) {
        msgList.push('没有可上传的文件')
        this.msgTick(msgList)
        return
      }
      this.msgTick(msgList) // 处理消息队列
      sucFun(fileArr)
    },
    /**
     * 多消息事件处理,避免同时弹出覆盖显示
     * @param list 消息列表
     * @param index 当前进行显示的下标
     */
    msgTick(list, index = 0) {
      if (!list[index]) {
        return
      }
      setTimeout(
        function() {
          Message.error(list[index])
          this.msgTick(list, index + 1)
        }.bind(this),
        300
      )
    },
    /**
     * 获取后缀名
     * @param name 文件名
     * @returns {string} 后缀名
     */
    getSuffix(name) {
      return name.substring(name.lastIndexOf('.') + 1).toLowerCase()
    },
    /**
     * 上传
     * @param fileList 文件列表
     * @param type 类型
     * @returns {Promise<*>}
     */
    async uploadFile(fileList, type = 'system') {
      const formData = new FormData()
      formData.append('type', type)
      fileList.forEach(item => formData.append('files', item))
      const { data } = await this.$http.uploadFile(formData)
      return data
    }
  }
}
</script>

至此,附件上传分享完毕

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值