word,PDF,excel、ppt等文件上传,视频上传查看等

文件上传记录:
文件上传需要后端给文件服务器的地址,前端上传之后,返回文件url的外网地址,然后可以预览,下载等操作

  • 子组件
<template>
  <div class="file-upload" style="display:flex; flex-wrap: wrap;">
    <div
      class="upload-wrap"
      @mouseenter="handleHover(index,'')"
      @mouseleave="handleHover(index,'leave')"
      v-for="(imgsrc,index) in form[photoName]"
      :key="index+imgsrc.path"
    >
      <!-- 图片鼠标滑过出现画面 -->
      <div class="review" v-if="hover&&index==index1">
        <div>{{imgsrc.name}}</div>
        <div class="btn-group" v-if="isImg(imgsrc.path)=='img'||isImg(imgsrc.path)=='video'">
          <span @click="reviewItem(imgsrc)" title="预览">
            <i class="el-icon-view"></i>
          </span>
          <span v-if="!noDeleteBtn" @click="removeItem(index)" title="删除">
            <i class="el-icon-delete"></i>
          </span>
          <span v-if="importFlag" @click="importFun(imgsrc)" title="导入">
            <i class="el-icon-thumb"></i>
          </span>
        </div>
        <div class="btn-group" v-if="isFile(imgsrc.path)=='file'">
          <span @click="reviewfileItem(imgsrc)" title="预览">
            <i class="el-icon-view"></i>
          </span>
          <span  style="margin-right: 10px">
            <a
              :href="imgsrc.path"
              type="download"
              :download="imgsrc.name"
              target="_blank"
              title="查看下载"
              style="color: #fff"
            >
              <i class="el-icon-download"></i>
            </a>
          </span>
          <span v-if="!noDeleteBtn" @click="removeItem(index)" title="删除">
            <i class="el-icon-delete"></i>
          </span>
          <span v-if="importFlag" @click="importFun(imgsrc)" title="导入">
            <i class="el-icon-thumb"></i>
          </span>
        </div>
      </div>
      <!-- <el-progress v-if="upload" class="progress" type="circle" :percentage="progress"></el-progress> -->
      <!-- 图片回显 -->
      <div
        v-if="isImg(imgsrc.path)=='img'"
        :style="'background:url('+imgsrc.path+')'"
        class="img-wrap img-view"
      ></div>
      <!-- 视频回显 -->
      <video v-else-if="isImg(imgsrc.path)=='video'" :src="imgsrc.path" class="video-wrap"></video>
      <!-- 文件回显 -->
      <div class="file-review" v-else-if="isFile(imgsrc.path)=='file'">
        <!-- <svg-icon
          class="file"
          style="width:80px; height:80px; margin-top:20px; position:absolute;left:50%;margin-left:-40px;z-index:1;"
          class-name="international-icon"
          icon-class="sign_files"
        /> -->
        <img class="file" src="@/assets/wenjian1.png" alt="" style="width:80px; height:80px; margin-top:20px; position:absolute;left:50%;margin-left:-40px;z-index:1;">
      </div>
    </div>
    <!-- 新增 -->
    <div class="upload-wrap" v-if="addFlagMore&&form[photoName].length<1">
      <input
        class="input"
        :title="title"
        type="file"
        ref="uploadInput"
        @change="handleChange($event,photoName)"
      />
      <i class="el-icon-plus uploader-icon"></i>
      <div class="title">{{title}}</div>
    </div>
    <div
      class="upload-wrap"
      v-if="!addFlagMore&&!noDeleteBtn&&(!employerFlag9||(employerFlag9&&form[photoName].length<9))"
    >
      <input
        class="input"
        :title="title"
        type="file"
        ref="uploadInput"
        @change="handleChange($event,photoName)"
      />
      <i class="el-icon-plus uploader-icon"></i>
      <div class="title">{{title}}</div>
    </div>
    <!-- v-model:visible="dialogStatus"这样绑定控制台会提示没有值,所以改为v-model -->
    <el-dialog
      :title="dialogtitle"
      v-model="dialogStatus"
      width="40%"
      top="10vh"
      :append-to-body="true"
    >
      <img style="width:100%" v-if="imgsrc &&isImg(imgsrc)=='img'" :src="imgsrc" class="img-wrap" />
      <video
        style="width:100%"
        v-if="imgsrc&&isImg(imgsrc)=='video'"
        controls
        :src="imgsrc"
        class="video-wrap"
      ></video>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="mini" @click="dialogStatus = false">关 闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
// TODO: 文件Word,Excel,PDF上传
import fileUpload from '@/api/fileUpload.js'
export default {
  props: {
    employerFlag9: Boolean, // 用于添加九张图的标记
    form: Object, // 上传的对应表单名称
    photoName: String, // 上传的对应字段名称
    title: String, // 标题
    noDeleteBtn: Boolean, // true为没有删除按钮
    importFlag: Boolean, // 导入标记
    fileTypeFlag: String, // 传入文件的类型
    addFlagMore: Boolean // 只能上传一张标记
  },
  data () {
    return {
      folderName: 'other', // 文件夹命上传路径 工人 custemer 雇主 employer 中介 agent 默认 other
      upload: false, // 是否出现上传进度
      progress: 0, // 进度条
      dialogStatus: false, // 弹出框
      hover: false, // 是否鼠标滑过
      canShow: false,
      fileShow: false,
      fileType: 'img', // 文件类型
      index1: null,
      imgsrc: '',
      switchConfig: {
        imgSize: 20
      },
      dialogtitle: ''
    }
  },
  computed: {

  },
  filters: {
    filterType (type) {
      if (
        type === 'jpg' ||
        type === 'jpeg' ||
        type === 'png' ||
        type === 'GIF' ||
        type === 'JPG' ||
        type === 'PNG' ||
        type === 'gif'
      ) {
        return 'img'
      }
      if (type === 'mp4') {
        return 'video'
      }
      if (
        type === 'docx' ||
        type === 'doc' ||
        type === 'pptx' ||
        type === 'ppt' ||
        type === 'xlsx' ||
        type === 'xls' ||
        type === 'pdf' ||
        type === 'PDF' ||
        type === 'zip' ||
        type === 'sql' ||
        type === 'html' ||
        type === 'json' ||
        type === 'jar' ||
        type === 'js' ||
        type === 'rar' ||
        type === 'txt'
      ) {
        return 'file'
      }
    }
  },
  methods: {
    isImg (val) {
      // 判断是图片
      if (val) {
        const miniTpye = val.split('.')[val.split('.').length - 1]
        if (
          miniTpye === 'jpeg' ||
          miniTpye === 'jpg' ||
          miniTpye === 'png' ||
          miniTpye === 'GIF' ||
          miniTpye === 'JPG' ||
          miniTpye === 'PNG' ||
          miniTpye === 'gif'
        ) {
          this.fileType = 'img'
          this.canShow = true
          return 'img'
        } else if (miniTpye === 'mp4') {
          this.fileType = 'video'
          this.canShow = true
          return 'video'
        } else {
          this.canShow = false
          return ''
        }
      } else {
        this.canShow = false
        return ''
      }
      // }
    },
    isFile (val) {
      // 判断是文件
      if (val) {
        const fileType = val.split('.')[val.split('.').length - 1]
        if (
          fileType === 'pdf' ||
          fileType === 'xls' ||
          fileType === 'ppt' ||
          fileType === 'pptx' ||
          fileType === 'xlsx' ||
          fileType === 'doc' ||
          fileType === 'docx' ||
          fileType === 'zip' ||
          fileType === 'PDF' ||
          fileType === 'sql' ||
          fileType === 'html' ||
          fileType === 'json' ||
          fileType === 'jar' ||
          fileType === 'js' ||
          fileType === 'rar' ||
          fileType === 'txt' ||
          fileType === 'rtf'
        ) {
          this.fileType = 'file'
          this.fileShow = true
          return 'file'
        } else {
          this.fileShow = false
          return ''
        }
      } else {
        this.fileShow = false
        return ''
      }
      // }
    },
    handleChange (file, wrap) {
      const uploadFile = file.target.files[0]
      console.log(uploadFile, '文件')
      const fileSize = uploadFile.size / 1024 / 1024
      const fileName = file.target.files[0].name
      const fileExtendName = fileName.split('.')[
        fileName.split('.').length - 1
      ]
      const filter = this.$options.filters.filterType
      this.fileType = filter(fileExtendName)
      if (uploadFile) {
        if (
          !/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(fileName) &&
          this.fileType === 'img'
        ) {
          this.$message({
            message:
              '上传的文件类型不正确!可为( gif | jpg | jpeg | png | GIF | JPG | PNG)文件',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
          return false
        }
        if (
          !/\.(docx|doc|pptx|ppt|xlsx|xls|pdf|PDF|zip|sql|html|json|jar|js|rar|txt)$/.test(
            fileName
          ) &&
          this.fileType === 'file'
        ) {
          this.$message({
            message:
              '上传的文件类型不正确!可为( docx | doc | pptx | ppt | xlsx | xls | pdf | PDF | zip | sql | html | json | jar | js | rar|txt )文件',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
          return false
        }
        if (!/\.(mp4)$/.test(fileName) && this.fileType === 'video') {
          this.$message({
            message: '上传的文件类型不正确!只能上传MP4文件',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
          return false
        }
        if (fileSize >= this.switchConfig.imgSize && this.fileType === 'img') {
          this.$message({
            message: '图片上传大小不能超过' + this.switchConfig.imgSize + 'MB',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
        } else if (
          fileSize >= this.switchConfig.videoSize &&
          this.fileType === 'video'
        ) {
          this.$message({
            message:
              '视频上传大小不能超过' + this.switchConfig.videoSize + 'MB',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
        } else if (
          fileSize >= this.switchConfig.fileSize &&
          this.fileType === 'file'
        ) {
          this.$message({
            message: '文件上传大小不能超过' + this.switchConfig.fileSize + 'MB',
            type: 'error',
            showClose: true
          })
          this.$refs.uploadInput.value = ''
        } else {
          const formData = new FormData()
          formData.append('file', uploadFile)
          var config = {
            onUploadProgress: (progressEvent) => {
              this.upload = true
              var complete =
                ((progressEvent.loaded / progressEvent.total) * 100) | 0
              this.progress = complete
            }
          }
          // http://api.gosingapore.com/hiring-communal/upload/uploadFile?folderName=other
          fileUpload
            .post(
              '/upload/uploadFile?folderName=other' + this.folderName,
              formData,
              config
            )
            .then((res) => {
              this.upload = false
              if (res.code === 2000000) {
                setTimeout(() => {
                  this.$message({
                    message: '上传成功',
                    type: 'success'
                  })
                  if (
                    this.photoName === 'img' ||
                    this.photoName === 'annexList' ||
                    this.photoName === 'pics' ||
                    this.photoName === 'customerPictures' ||
                    this.photoName === 'resumeAnnexList'
                  ) {
                    // eslint-disable-next-line vue/no-mutating-props
                    this.form[this.photoName].push({
                      name: fileName,
                      path: res.data.ossUrl,
                      annexId: null
                    })
                  } else {
                    // eslint-disable-next-line vue/no-mutating-props
                    this.form[this.photoName] = [
                      { name: fileName, path: res.data.ossUrl, annexId: null }
                    ]
                  }
                  this.$refs.uploadInput.value = ''
                }, 1000)
              } else {
                this.$refs.uploadInput.value = ''
              }
            })
            .catch(() => {
              this.$refs.uploadInput.value = ''
            })
        }
      }
    },
    // 删除
    removeItem (item) {
      // eslint-disable-next-line vue/no-mutating-props
      this.form[this.photoName].splice(item, 1)
    },
    // 预览图片
    reviewItem (item) {
      this.dialogStatus = true
      this.imgsrc = item.path
      this.dialogtitle = item.name
    },
    // 预览文件
    reviewfileItem (item) {
      window.open(`https://view.officeapps.live.com/op/view.aspx?src=${item.path}`)
    },
    // 鼠标移入移出
    handleHover (index, type) {
      this.index1 = index
      // 鼠标经过事件 显示预览和删除按钮
      if (type === 'leave') {
        this.hover = false
      } else {
        this.hover = true
      }
    },
    // 图片导入
    importFun (val) {
      this.$emit('importImgFun', {
        obj: { annexId: null, path: val.path },
        photoName: this.photoName
      })
    }
  }
}
</script>

<style scoped lang="scss">
.file-upload {
  display: inline-block;
  .title {
    text-align: center;
    width: 120px;
    bottom: 10px;
    position: absolute;
    //width: 100%;
    left: 0;
  }

  transition: all 0.5s ease-in-out;
}

.file-upload:hover {
  .upload-wrap {
    border-color: #fff;
  }
}

.review {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 102;
  background-color: rgba(0, 0, 0, 0.55);
  color: #fff;
  // @include flex(column, space-evenly, center);
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;

  transition: all 0.5s ease-in-out;
  animation: fadeIn 0.5s ease-in-out;

  span {
    cursor: pointer;
  }

  span:first-child {
    margin-right: 15px;

    i {
      font-size: 16px;
    }
  }
}
.img-view {
  background-repeat: no-repeat !important;
  background-size: cover !important;
  background-position: center !important;
}
.upload-wrap {
  width: 120px;
  height: 120px;
  position: relative;
  border-radius: 5px;
  overflow: hidden;
  border: 1px dashed #dcdcdc;
  background-color: #f5f4f7;
  transition: all 0.5s ease-in-out;
  margin: 0 5px 5px 0;

  .input,
  .progress,
  .img-wrap,
  .video-wrap,
  .uploader-icon {
    position: absolute;
    left: 0;
    z-index: 99;
    width: 100%;
    height: 100%;
  }

  .uploader-icon {
    font-size: 24px;
    text-align: center;
    line-height: 110px;
    color: #666;
    z-index: 2;
  }

  .input {
    opacity: 0;
    cursor: pointer;
  }

  .progress {
    z-index: 100;
    width: 110px;
    height: 100px;
    left: 5px;
    top: 5px;
    background-color: #f5f4f7;

    /deep/ .el-progress-circle {
      width: 100% !important;
      height: 100% !important;
    }
  }

  .img-wrap,
  .video-wrap {
    background-color: #000;
    z-index: 98;
  }
  .file-review {
    display: block;
    font-size: 36px;
    text-align: center;
    line-height: 100px;
  }
}
</style>
  • 父组件
  • 引用:import fileUpload from '@/components/fileUpload/fileUpload.vue'
<!-- 第二种上传附件 -->
          <div style="display: flex; flex-wrap: wrap;">
            <file-upload :type="'file'" :form="form" :title="'文件上传'" :photoName="'annexList'"></file-upload>
          </div>
          <el-button @click="fileformclick">提交</el-button>
  • 效果图:

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 预览

  • 在这里插入图片描述

  • 下载

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值