<template>
  <div class="cy-upload">
    <el-upload
      ref="upload"
      :class="{
        'cy-upload-content': disabled,
        'upload-form': uploadFromStatus,
        'upload-file-length': !fileLists.length,
        'is-preview-file': !isPreviewFile,
        'upload-from-orange-status': uploadFromOrangeStatus
      }"
      :file-list="fileLists"
      :action="actionUrl"
      :disabled="disabled"
      :before-upload="validateFileType"
      multiple
      :on-success="(response, file, fileList) => {
        uploadMoreSuccess(fileList, 'fileLists')
      }"
      :data="uploadData"
      :before-remove="(file, fileList) => {
        return handleRemove(file, fileList, 'fileLists')
      }"
      :on-error="fileError"
      :on-progress="uploadProgress"
      :on-preview="previewFile"
      :limit="limit"
      :accept="accept"
      :headers="headers"
    >
      <template v-if="isUploadBtn">
        <svg-icon v-if="uploadFromOrangeStatus" icon-class="upload" class="upload-svg" />
        <div v-else class="upload-default">
          <span style="line-height: 30px;">{{ defaultDesc }}</span>
          <svg-icon icon-class="upload" class="upload-svg" />
        </div>
        <!-- <el-button v-else type="primary" :size="size">上传附件</el-button> -->
      </template>
    </el-upload>
    <template v-if="fileLists.length && canDownload">
      <div
        v-power="downloadPower"
        :class="{
          'upload-download': !uploadFromStatus,
          'upload-form-download': uploadFromStatus,
          'disabled-download': !uploadFromStatus && disabled,
          'disabled-form-download': uploadFromStatus && disabled
        }"
        :style="downloadStyle"
      >
        <div v-for="(item, index) in fileLists" :key="index">
          <i class="el-icon-download" @click="downloadClick(item)" />
        </div>
      </div>
    </template>
    <template v-if="disabled && !fileLists.length">
      <div class="cy-upload-placeholder">暂无附件</div>
    </template>
    <template v-if="!fileLists.length && placeholder && !disabled">
      <div class="cy-upload-placeholder">{{ placeholder }}</div>
    </template>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import { getFilePerview } from '@/api/dictionary'
import { exportFile } from '@/utils'

export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    isAdd: {
      type: Boolean,
      default: true
    },
    limit: {
      type: null,
      default: null
    },
    size: {
      type: String,
      default: 'small'
    },
    fileData: {
      type: Array,
      default: () => []
    },
    uploadParams: {
      type: Object,
      default: () => {}
    },
    // 表单主题
    uploadFromStatus: {
      type: Boolean,
      default: false
    },
    // 橘色主题
    uploadFromOrangeStatus: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: ''
    },
    isCallBack: {
      type: Boolean,
      default: false
    },
    power: {
      type: String,
      default: ''
    },
    downloadStyle: {
      type: String,
      default: ''
    },
    accept: {
      type: String,
      default: ''
    },
    canDownload: {
      type: Boolean,
      default: false
    },
    isPreviewFile: {
      type: Boolean,
      default: true
    },
    defaultDesc: {
      type: String,
      default: '上传附件'
    },
    /**
     * @type String 校验上传文件类型 file-type="bmp,png,jpg,jpeg"
     * */
    fileType: {
      type: String,
      default: ''
    },
    // 下载按钮权限
    downloadPower: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      actionUrl: `${process.env.VUE_APP_BASE_API}/fileStorage/doUploadFiles`,
      fileLists: [],
      uploadLoading: null,
      uploadData: {},
      headers: {
        token: getToken()
      }
    }
  },
  computed: {
    getFileLists() {
      const list = this.fileLists.map(item => {
        if (item.response) {
          const { response: { data }} = item
          return {
            id: data[0].id,
            name: data[0].originalName,
            url: data[0].path,
            originalName: data[0].originalName,
            path: data[0].path
          }
        } else {
          return item
        }
      })
      return list
    },
    isUploadBtn() {
      return !this.disabled && !this.limit || (!this.disabled && this.limit && this.fileLists.length < this.limit)
    }
  },
  watch: {
    fileData: {
      handler(newV) {
        if (newV.length) {
          this.fileLists = newV.map(item => {
            const { id, path, originalName, absolutePath } = item
            return {
              id,
              url: path,
              name: originalName,
              originalName,
              path,
              absolutePath
            }
          })
        } else {
          this.fileLists = []
        }
      },
      immediate: true,
      deep: true
    },
    uploadParams: {
      handler(newV) {
        this.uploadData = {
          ...newV
        }
      },
      immediate: true,
      deep: true
    },
    isUploadBtn: {
      handler(newV) {
        this.$nextTick(() => {
          this.$refs.upload.$el.querySelector('.el-upload').style.display = newV ? 'block' : 'none'
        })
      },
      immediate: true
    }
  },
  destroyed() {
    this.fileLists = []
  },
  methods: {
    fetchFile() {
      this.uploadData = {
      }
      this.getFileLoad().then(data => {
        this.fileLists = data.map(item => {
          item.name = item.fileName
          item.url = item.fileUrl
          return item
        })
      })
    },

    // 设置上传限制大小 在文件上传之前进行的操作
    beforeUploadM(file) {
      var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
      const testMsgM = testmsg === 'jpg'
      const isLtM = file.size / 1024 / 20 >= 1 && file.size / 1024 / 750 <= 1

      if (!testMsgM) {
        this.$message.warning('请上传jpg格式的图片')
      }
      if (!isLtM) {
        this.$message.warning('上传文件大小不得小于20KB,不得大于750kB!')
      }
      if (testMsgM && isLtM) {
        this.uploadLoading = this.handlerUploadMark()
      }
      return testMsgM && isLtM
    },

    // 限制1M
    beforeUpload1M(file) {
      const testMsg1M = /^image\/(jpeg|png|jpg)$/.test(file.type)
      const isLt1M = file.size / 1024 / 1024 < 1
      if (!testMsg1M) {
        this.$message.warning('请上传jpeg/png/jpg格式的图片')
      }
      if (!isLt1M) {
        this.$message.warning('上传文件大小不能超过 1M!')
      }
      if (testMsg1M && isLt1M) {
        this.uploadLoading = this.handlerUploadMark()
      }
      return isLt1M && testMsg1M
    },

    beforeUpload2M(file) {
      const testMsg2M = /^image\/(jpeg|png|jpg)$/.test(file.type)
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!testMsg2M) {
        this.$message.warning('请上传jpeg/png/jpg格式的图片')
      }
      if (!isLt2M) {
        this.$message.warning('上传文件大小不能超过 2M!')
      }
      if (testMsg2M && isLt2M) {
        this.uploadLoading = this.handlerUploadMark()
      }
      return isLt2M && testMsg2M
    },

    // 限制10M
    beforeUpload10M(file) {
      const isLt10M = file.size / 1024 / 1024 < 10
      if (!isLt10M) {
        this.$message.warning('上传文件大小不能超过 10M!')
      } else {
        this.uploadLoading = this.handlerUploadMark()
      }
      return isLt10M
    },

    beforeUpload50M(file, limitName = '') {
      if (limitName) {
        this[limitName](file)
      }
      const isLt50M = file.size / 1024 / 1024 < 50
      if (!isLt50M) {
        this.$message.warning('上传文件大小不能超过 50M!')
      } else {
        this.uploadLoading = this.handlerUploadMark()
      }
      return isLt50M
    },

    // 格式限制
    docxAndDoc(file) {
      const last = file.name.lastIndexOf('.')
      const type = file.name.slice(last)
      const typeList = ['.docx', '.doc']
      const isType = typeList.includes(type)
      if (!isType) {
        this.$message.error('上传文件图片只能是 docx 或 doc 格式!')
        this.uploadLoading.close()
      } else {
        this.uploadLoading = this.handlerUploadMark()
      }
      return isType
    },

    // 格式限制-现在zip和RAR
    exceptZipAndRar(file) {
      // const last = file.name.lastIndexOf('.')
      // const type = file.name.slice(last)
      // const typeList = ['.zip', '.rar']
      // const isType = typeList.includes(type.toLowerCase())
      // if (isType) {
      //   this.$message.error('上传文件格式不能是 zip 或 rar 格式!')
      //   // this.uploadLoading.close()
      // } else {
      //   // this.uploadLoading = this.handlerUploadMark()
      // }
      // return !isType
      return true
    },

    // 上传前上传文件类型校验
    validateFileType(file) {
      if (!this.fileType) return true
      const validType = file.name.substring(file.name.lastIndexOf('.') + 1)
      const fileTypeStatus = this.fileType.includes(validType)
      if (!fileTypeStatus) {
        this.$message.warning(`请上传${this.fileType}文件`)
      }
      return fileTypeStatus
    },

    getWarnMsg(msg) {
      return `请上传${msg}文件`
    },

    // 文件个数限制
    handleExceed(files, fileList) {
      console.log(files)
    },

    // 上传遮罩的问题
    handlerUploadMark() {
      const loading = this.$loading({
        lock: true,
        text: '正在上传中，请稍等...',
        color: '#fff',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      return loading
    },

    // 上传报错的问题
    fileError(err, file, fileList) {
      console.log(err)
      this.uploadLoading.close()
      this.$message.warning('附件上传失败')
    },

    // 文件上传时的钩子
    uploadProgress(event, file, fileList) {

    },

    // 文件移除
    handleRemove(file, fileList, fileListName = 'fileList') {
      if ((file.response && file.response.data[0].id) || file.id) {
        return this.$confirm('确认删除该附件么？', '删除', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          setTimeout(() => {
            this[fileListName] = fileList
            if (this.isCallBack) {
              this.$emit('call-back', ...arguments)
              this.$emit('remove', file.id || (file.response && file.response.data && file.response.data[0].id))
            }
            return Promise.resolve()
          }, 0)
        }).catch(() => {
          return Promise.reject()
        })
      }
    },

    // 文件上传成功
    uploadMoreSuccess(fileList, fileListName = 'fileList') {
      this[fileListName] = fileList
      if (this.isCallBack) {
        this.$emit('call-back', ...arguments)
        this.$emit('upload', ...arguments)
      }
      this.uploadLoading && this.uploadLoading.close()
    },

    // 点击文件列表中已上传的文件时的钩子
    previewFile(file) {
      if (!this.isPreviewFile) {
        return
      }
      var idNum = ''; var name = ''
      var absolutePath = ''
      if (file.response) {
        const { response: { data }} = file
        idNum = data[0].id
        name = data[0].name
        absolutePath = data[0].absolutePath
      } else {
        idNum = file.id
        name = file.name
        absolutePath = file.absolutePath
      }
      window.open(`#/perview?fileId=${idNum}&name=${name}&absolutePath=${absolutePath}`)
    },
    downloadClick(row) {
      let absolutePath = ''
      if (row.absolutePath) {
        absolutePath = row.absolutePath
      } else {
        absolutePath = row.response.data[0].absolutePath
      }
      getFilePerview({ absolutePath }).then((res) => {
        exportFile(res)
      })
    }
  }
}
</script>

<style lang="scss">
// .cy-upload-content .el-upload-list  {
//   margin-top: -42px;
// }

.cy-upload {
  width: 100%;
  position: relative;
  .el-icon-close-tip {
    display: none !important;
  }
  .upload-form {
    border: 1px solid #E8F0F3;
    position: relative;
    border-left: 0px;
    > div {
      float: right;
      position: absolute;
      right: 0px;
      height: 100%;
      background: #F0F9FC;
      display: flex;
    }
    > ul {
      margin-top: -12px;
      width: calc(100% - 88px);
      min-height: 32px;
    }
    > ul.is-disabled {
      width: 100%;
    }
  }

  .upload-from-orange-status {
    border: 1px solid #E8F0F3;
    position: relative;
    border-radius: 5px;
    min-height: 34px;
    > div {
      float: right;
      position: absolute;
      right: 0px;
      height: 100%;
      // background: #F0F9FC;
      display: flex;
    }
    > ul {
      margin-top: -10px;
      width: calc(100% - 50px);
      min-height: 32px;
    }
    > ul.is-disabled {
      width: 100%;
    }
  }
  .upload-svg {
    min-width: 20px;
    min-height: 20px;
    margin-top: 6px;
    margin-right: 5px;
  }
  .upload-default {
    display: flex;
    align-items: center;
    & > span {
      &:first-child {
        font-size: 14px;
        color: #A3A8AC;
        margin-right: 10px;
      }
    }
    .upload-svg {
      margin-top: 0px;
      margin-right: 0px;
    }
  }
  .upload-file-length > ul {
    margin-top: 0px !important;
  }
  .el-upload-list__item {
    line-height: 32px;
  }
  .el-upload-list__item .el-icon-close {
    line-height: 26px;
  }
  .upload-download {
    position: absolute;
    top: 44px;
    right: 11%;
    line-height: 32px;
    color: #67C23A;
    cursor: pointer;
  }
  .upload-download > div {
    margin-bottom: 5px;
  }

  .upload-form-download {
    position: absolute;
    top: 0px;
    right: 120px;
    line-height: 32px;
    color: #67C23A;
    cursor: pointer;
  }

  .upload-form-download > div {
    margin-bottom: 5px;
  }
  .disabled-form-download {
    position: absolute;
    top: 0px;
    right: 30px;
    line-height: 32px;
    color: #67C23A;
    cursor: pointer;
  }
  .disabled-form-download > div {
    margin-bottom: 5px;
  }
  .disabled-download {
    position: absolute;
    top: 0px;
    right: 33px;
    line-height: 34px;
    color: #67C23A;
    cursor: pointer;
  }
  .disabled-download > div {
    margin-bottom: 5px;
  }
  .upload-form .el-button--primary {
    background-color: #F0F9FC !important;
    border-color: #F0F9FC !important;
    color: #606266 !important;
  }
  .upload-form .el-button--primary:focus, .cy-upload .upload-form .el-button--primary:hover {
    color: #606266 !important;
  }
}
.cy-upload-placeholder {
  font-size: 13px;
  color: #C0C4CC;
  line-height: 35px;
  position: absolute;
  top: 0px;
  left: 16px;
}

.is-preview-file .el-upload-list__item.is-success .el-upload-list__item-name:focus, .is-preview-file .el-upload-list__item.is-success .el-upload-list__item-name:hover {
  color: #606266;
  cursor: default
}
</style>
