index.vue 8.63 KB
<template>
  <el-row class="el-upload-self">
    <el-upload
      ref="upload"
      :multiple="multiple"
      :class="[
        'avatar-uploader',
        value.length > 0 ? 'textUpload' : '',
        accept == 'application/pdf' ? 'pdfUpload' : '',
      ]"
      :action="action"
      :headers="headers"
      :list-type="listType"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      :on-change="handleSelectFile"
      :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="value.length">
        <el-button size="middle" type="text">点击更换</el-button>
      </template>

      <template v-else-if="listType === 'picture-card' && !value.length">
        <el-button size="middle" type="text">点击上传</el-button>
      </template>

      <template v-else>
        <!-- <el-button size="middle" :type="btnType">点击上传</el-button> -->
        <!-- <img v-if="imageUrl" :src="imageUrl" class="avatar" /> -->
        <el-button size="middle" type="text">点击上传</el-button>
      </template>
      <div slot="file" slot-scope="{ file }">
        <img
          v-if="accept == 'image/*'"
          class="el-upload-list__item-thumbnail"
          :src="file.url"
          alt=""
        />
        <span v-if="accept == 'image/*'" class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePreview(file)"
          >
            <i class="el-icon-download"></i>
          </span>
        </span>
        <el-tooltip
          class="item"
          effect="dark"
          :content="file.name"
          placement="top"
        >
          <div
            v-if="accept != 'image/*'"
            style="cursor: pointer"
            class="fileNameText"
            @click="handlePreview(file)"
          >
            {{ file.name }}
          </div>
        </el-tooltip>
      </div>
      <!-- <div slot="tip" class="el-upload__tip">{{ tip }}</div> -->
    </el-upload>

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

<script>
import { getAccessToken } from "@/utils/accessToken"
import { delFile } from "@/api/file"
export default {
  name: "ElUploadSelf",
  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: { type: Number, default: 10 * 1024 * 1024 },
    loadText: String,
    showFileList: {
      type: Boolean,
      default: true,
    },
    drag: {
      type: Boolean,
      default: false,
    },
    btnType: {
      type: String,
      default: "primary",
    },
    value: {
      type: Array,
      default: () => [],
    }, //上传文件数组 绑定数组
  },
  data() {
    return {
      imgUrl: "",
      title: "",
      httpPrefix:
        process.env.NODE_ENV === "development"
          ? "/api"
          : process.env.VUE_APP_BASE_API,
      fileList: [],
    }
  },
  computed: {
    headers() {
      return {
        Authorization: `Bearer ${getAccessToken()}`,
      }
    },
    action() {
      return this.httpPrefix + `/cloud-upms/file/upload`
    },
    // 预览list
    previewList() {
      console.log(this.value)
      if (!this.value.length || this.accept != "image/*") return []
      return this.value.map((_) => {
        return (
          _.url ||
          `https://ds.cixincloud.com/geca-api/disease-data/file/info/${_.bucketName}/${_.uuidName}`
        )
      })
    },
  },
  watch: {
    value: {
      handler(newValue, oldValue) {
        if (newValue === oldValue) return
        this.fileList = newValue.map((_) => {
          return {
            name: _.fileName,
            url: `https://ds.cixincloud.com/geca-api/disease-data/file/info/${_.bucketName}/${_.uuidName}`,
          }
        })
      },
      immediate: true,
    },
  },
  methods: {
    handleSelectFile(file, fileList) {
      if (fileList.length > 1) {
        this.value.shift()
        fileList.shift()
      }
    },
    // 上传前回调
    beforeUpload(file) {
      return new Promise((resolve, reject) => {
        const size = this.fileSize
        console.log(file.size)
        if (size && file.size > size) {
          this.$message.error("文件大小超出限制,请上传10M以下的文件")
          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 })
        // 上传成功
        this.$emit("input", this.value)
        this.$emit("fileSuccess")
      } else {
        this.$message.warning(res.msg)
        this.$refs.upload.clearFiles()
      }
    },

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

    // 移除
    handleRemove({ url }, fileList) {
      if (fileList.length > 1) {
        fileList.shift()
      }
      this.value = []
      this.$emit("input", this.value)
      // 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 = `https://ds.cixincloud.com/geca-api/disease-data/file/info/${_.bucketName}/${_.uuidName}`
      }
      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;
}
::v-deep .avatar-uploader {
  display: flex;
  align-items: center;
  .el-upload--picture-card {
    height: 20px;
    transform: translateY(-4px);
  }
}
::v-deep .pdfUpload {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  .el-upload--text {
    height: 20px;
    transform: translateY(-4px);
  }

  .el-upload-list__item {
    transform: translateY(-6px);
    // width: 158px;
    height: 20px;
  }
}
::v-deep .avatar-uploader .el-upload {
  border: none;
  width: 80px;
  height: 30px;
  line-height: 0px;
}
::v-deep .textUpload {
  align-items: flex-start;
  .el-upload {
    border: none;
    width: 80px;
    height: 30px;
    line-height: 0px;
  }
  .el-upload--text {
    height: 20px;
    transform: translateY(-4px);
  }
}
::v-deep .avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
::v-deep .el-upload-list__item {
  width: 88px;
  height: 88px;
  &:hover {
    background-color: #fff;
  }
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 88px;
  height: 88px;
  line-height: 88px;
  text-align: center;
}
.avatar {
  width: 88px;
  height: 88px;
  display: block;
}
.fileNameText {
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
// ::v-deep .el-upload--picture-card {
//   width: none;
//   height: none;
//   line-height: 0px;
//   border: none;
// }
</style>