index.vue 5.49 KB
<template>
  <el-row class="el-upload-self">
    <el-upload
      :multiple="multiple"
      ref="upload"
      :action="action"
      :headers="headers"
      :list-type="listType"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :before-remove="beforeRemove"
      :file-list="fileList"
      :show-file-list="showFileList"
      :accept="accept"
      :limit="limit"
      :drag="drag"
      :disabled="disabled"
    >
      <template v-if="drag">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      </template>
      <template v-else-if="listType === 'picture-card'">
        <i class="el-icon-plus"></i>
      </template>

      <template v-else>
        <el-button size="middle" :type="btnType">点击上传</el-button>
      </template>
      <div slot="tip" class="el-upload__tip">{{ tip }}</div>
    </el-upload>

    <el-image
      style="display: none"
      :src="imgUrl"
      :preview-src-list="previewList"
      ref="image"
    >
    </el-image>
  </el-row>
</template>

<script>
import { getAccessToken } from "@/utils/accessToken"
import { delFile } from "@/api/file"
export default {
  name: "el-upload-self",
  props: {
    accept: { type: String, default: "image/*" },
    disabled: {
      type: Boolean,
      default: false,
    },
    uploadQuery: {
      type: Object,
      default: () => {
        return {}
      },
    }, //后端上传文件路径(参数)
    listType: String,
    tip: String,
    multiple: Boolean,
    limit: {
      type: Number,
      default: 9,
    },
    fileSize: Number,
    loadText: String,
    showFileList: {
      type: Boolean,
      default: true,
    },
    drag: {
      type: Boolean,
      default: false,
    },
    btnType: {
      type: String,
      default: "primary",
    },
    value: Array, //上传文件数组 绑定数组
  },
  data() {
    return {
      imgUrl: "",
      title: "",
      httpPrefix:
        process.env.NODE_ENV === "development"
          ? "/api"
          : process.env.VUE_APP_BASE_API,
      fileList: [],
    }
  },
  watch: {
    value: {
      handler(newValue, oldValue) {
        if (newValue === oldValue) return
        this.fileList = newValue.map((_) => {
          return {
            name: _.file_name,
            url: `${this.httpPrefix}/disease-data/file/info/${_.bucket_name}/${_.prefix}-${_.uuid_name}`,
          }
        })
      },
      immediate: true,
    },
  },
  computed: {
    headers() {
      return {
        Authorization: `Bearer ${getAccessToken()}`,
      }
    },
    action() {
      return (
        this.httpPrefix +
        `/disease-data/file/upload?formId=${this.uploadQuery.formId}&patientId=${this.uploadQuery.patientId}&prefix=${this.uploadQuery.prefix}`
      )
    },
    // 预览list
    previewList() {
      if (!this.value) return []
      return this.value.map((_) => {
        return (
          _.url ||
          `${this.httpPrefix}/disease-data/file/info/${_.bucket_name}/${_.prefix}-${_.uuid_name}`
        )
      })
    },
  },
  methods: {
    // 上传前回调
    beforeUpload(file) {
      return new Promise((resolve, reject) => {
        const size = this.fileSize
        if (size && file.size > size) {
          this.$message.error("大小超出限制" + this.tip)
          reject()
        }
        resolve()
      })
    },

    // 超出限制
    handleExceed(files, fileList) {
      this.$message.error(`最多可上传${this.limit}个文件!`)
    },

    // 上传成功
    handleSuccess(res, file, fileList) {
      const { data } = res
      if (data) {
        this.value.push({ ...data, url: file.url })
      } else {
        this.$message.warning(res.msg)
        this.$refs.upload.clearFiles()
      }
    },

    // 移除提醒
    beforeRemove(file, fileList) {
      return this.$confirm(`确定移除 ${file.file_name || file.name}?`)
    },

    // 移除
    handleRemove({ url }, fileList) {
      const i = this.value.findIndex((_) => url.endsWith(_.uuid_name))
      if (i > -1) this.value.splice(i, 1) // 静态移除
    },

    // 查看
    handlePreview(file) {
      const name = file.fileName || file.name
      this.title = name
      let responseUrl
      if (file.response) {
        const _ = file.response.data
        responseUrl = `${this.httpPrefix}/disease-data/file/info/${_.bucket_name}/${_.prefix}-${_.uuid_name}`
      }
      try {
        if (name.match(/\.(png|jpg|jpeg)/)) {
          this.imgUrl = file.url || responseUrl
          this.$refs.image.clickHandler()
        } else {
          const elink = document.createElement("a")
          elink.download = name
          elink.style.display = "none"
          elink.href = file.url || responseUrl
          document.body.appendChild(elink)
          elink.click()
          URL.revokeObjectURL(elink.href) // 释放URL 对象
          document.body.removeChild(elink)
        }
      } catch {
        const elink = document.createElement("a")
        elink.download = name
        elink.style.display = "none"
        elink.href = file.url || responseUrl
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) // 释放URL 对象
        document.body.removeChild(elink)
      }
    },
  },
}
</script>
<style lang="scss">
.el-upload-self {
  .el-upload {
    position: relative;
  }
}
</style>

<style lang="scss" scoped>
.el-upload-self {
  font-size: 14px;
}
</style>