<template>
  <el-dialog
    modal-append-to-body
    width="70%"
    :visible="visible"
    @close="close"
  >
    <div slot="title">{{title}}</div>
    <div class="body">
      <div class="operation">
        <el-button type="primary" @click="remove">删除</el-button>
      </div>
      <div class="list">
        <el-table
          stripe
          border
          ref="fileTable"
          :data="list"
          @selection-change="selectionChange"
          @row-click="toCheck"
        >
          <table-column type="selection" fixed align="center"></table-column>
          <table-column label="文件名" prop="fileName">
            <template slot-scope="scope">
              <span class="file-name" @mouseover="e => toHover(scope.row, e)" @mouseout="isHover = false">{{scope.row.fileName}}</span>
            </template>
          </table-column>
          <table-column label="业务单号" prop="orderNo"></table-column>
          <table-column label="上传时间" prop="createTime"></table-column>
          <table-column label="操作" width="150">
            <template slot-scope="scope">
              <el-button
                title="下载"
                size="mini"
                type="primary"
                icon="el-icon-download"
                plain
                circle
                @click.stop="download(scope.row)"
              ></el-button>
              <el-button
                title="删除"
                size="mini"
                type="danger"
                icon="el-icon-delete"
                plain
                circle
                @click.stop="remove(scope.row)"
              ></el-button>
            </template>
          </table-column>
        </el-table>
        <el-pagination
          class="pagination"
          @size-change="sizeChange"
          @current-change="currentChange"
          :current-page="currentNo"
          :page-sizes="[10, 20, 30, 40, 50]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        ></el-pagination>
      </div>
      <div v-if="acceptInfo">提示: {{acceptInfo}}</div>
      <div class="upload">
        <el-upload
          v-if="config"
          ref="upload"
          list-type="picture"
          action="placeholder"
          :file-list="initList"
          :accept="config.accept"
          :multiple="config.multiple"
          :limit="config.limit"
          :http-request="upload"
          :auto-upload="false"
          :on-success="uploadSuccess"
          :on-error="uploadError"
          :on-progress="uploadProgress"
          :on-change="uploadChange"
          :before-upload="beforeUpload"
        >
          <el-button type="primary" icon="el-icon-search">浏览</el-button>
          <el-button type="primary" icon="el-icon-upload" @click.stop="toUpload" :loading="uploading">上传</el-button>
        </el-upload>
      </div>
      <a id="download" :href="dlUrl" :download="dlName"></a>
      <!--悬浮显示图片弹窗-->
      <div v-show="isHover" id="hover-img">
        <img :src="hoverUrl" :alt="`图片链接: ${hoverUrl}`" />
      </div>
    </div>
  </el-dialog>
</template>

<script>
import Aliyun from '@/config/aliyun'
import fileTypeText from './config/fileTypeText'

export default {
  data () {
    return {
      aliyun: {}, // 阿里云操作对象, 需要主动new初始化
      visible: false, // 显示弹窗
      title: '附件管理', // 标题
      // 默认配置
      defaultConfig: {
        businessType: 'DEFAULT',
        orderNo: '',
        accept: '',
        limit: 0,
        multiple: true,
      },
      config: {}, // 合并配置
      acceptInfo: '', // 接受类型提示
      list: [], // 查询列表
      currentNo: 1,
      pageSize: 10,
      total: 0,
      selection: [], // 勾选的行
      initList: [], // 初始空列表
      files: [], // 上传的文件列表
      cacheFiles: [], // 上传前缓存的文件列表
      dlUrl: '', // 下载链接
      dlName: '', // 下载文件名
      isHover: false, // 显示悬浮预览图片
      hoverUrl: '', // 预览图片链接
      uploading: false, // 上传中防止重复提交
      USER_INFO: JSON.parse(window.localStorage.getItem('userInfo') || '{}')
    }
  },
  methods: {

    // 传入参数展示上传弹窗
    /**
     * @param {Object} config 的可选值:
     *   @property {String} orderNo 必填, 业务单号, 多个单号用 ',' 拼接
     *   @property {String} accept 接受的上传文件类型, 默认 '' 不限制
     *   @property {Number} limit 上传数量限制, 默认 0 不限制
     *   @property {Boolean} multiple 是否允许多选, 默认 true 允许
     * */
    getConfig (config) {
      this.aliyun = new Aliyun() // 初始化阿里云操作对象
      this.config = {
        ...this.defaultConfig,
        ...config,
      }
      this.acceptInfo = this.config.accept ? `仅支持上传 ${fileTypeText(this.config.accept)} 格式的文件` : ''
      this.visible = true
      this.uploading = false
      this.getFileList()
    },
    // 查询文件列表
    getFileList () {
      const url = this.$API.public.upload.getFileList
      this.USER_INFO = JSON.parse(window.localStorage.getItem('userInfo') || '{}')
      const param = {
        orgId: this.USER_INFO.orgId,
        projectId: this.USER_INFO.projectId,
        orderNos: this.config.orderNo,
        businessType: this.config.businessType, // 带业务类型查询
        'page.currentPage': this.currentNo,
        'page.limitCount': this.pageSize,
      }
      this.$https.post(url, param)
        .then(data => {
          this.total = data.total
          this.list = data.rows
        })
    },
    // 删除服务端图片
    remove (row) {
      let fileIds
      let param = {}
      const url = this.$API.public.upload.delete
      if (row.fileId) {
        // 单独操作
        fileIds = [row.fileId]
        param = { files: JSON.stringify([row]) }
        this.delList(url, param, fileIds)
      } else {
        // 批量操作
        if (!this.selection.length) return this.$message.warning('请选择记录')
        fileIds = this.selection.map(item => item.fileId)
        param = {
          files: JSON.stringify(this.selection)
          // orderNo: this.config.orderNo, // 唯一单号
          // fileIds: JSON.stringify(fileIds),
        }
        this.delList(url, param, fileIds)
      }
    },
    delList (url, param, fileIds) {
      this.$https.post(url, param)
        .then(data => {
          this.$message.success('操作成功')
          // 删除阿里云图片
          this.aliyun.delete(fileIds)
          this.getFileList()
          this.$store.commit('framework/changeUploadSuccess') // 改变上传成功标识, 使页面监听到并刷新
        })
    },
    // 下载
    download (row) {
      // 使用阿里云链接下载
      // this.dlUrl = 'https://logistics-pic.oss-cn-shenzhen.aliyuncs.com/a23c3ce5cb22dde5fc55445bf9d8a2c8.xlsx'
      // this.dlName = '出库列表'
      this.dlUrl = this.aliyun.download(row) // 阿里云下载
      window.open(this.dlUrl) // 暂时先用这个
      // this.dlUrl = row.fileAddress // 直接使用url
      // this.dlName = row.fileName
      // setTimeout(() => {
      //   // ##待验证兼容性
      //   document.querySelector('#download').click()
      // }, 500)
    },
    // 上传前操作
    beforeUpload (file) {
      const accept = this.config.accept
      let fileType = file.type
      if (accept.includes('image/*')) {
        // 不限制图片格式时
        fileType.includes('image/') && (fileType = 'image/*')
      }
      if (accept && !accept.includes(fileType)) {
        this.$message.error(`${this.acceptInfo}, 请重新选择`)
        this.uploading = false
        return false
      }
      this.USER_INFO = JSON.parse(window.localStorage.getItem('userInfo') || '{}')
    },
    // 上传状态变化
    uploadChange (file, fileList) {
      this.cacheFiles = fileList
    },
    // 上传按钮
    toUpload () {
      if (!this.cacheFiles.length) {
        this.$message.warning('请先点击 浏览 选择文件~')
        return
      }
      this.uploading = true
      this.files = []
      this.$refs.upload.submit()
    },
    // 上传到阿里云
    async upload (param) {
      // eslint-disable-next-line
      await this.aliyun.upload(param.file)
        .then(data => {
          const { fileId, fileName, fileType, fileAddress, ...otherData } = data
          this.files.push({
            fileId,
            fileName,
            fileType,
            fileAddress,
            orderNos: this.config.orderNo.split(','), // 唯一单号
            projectId: this.USER_INFO.projectId, // 仓库(项目)id
            businessType: this.config.businessType, // 标识业务类型, 默认用DEFAULT
          })
        })
        .catch(err => {
          this.$message.error(`文件 ${err.name} 上传失败了, 再试试吧~`)
          this.uploading = false
          console.log('上传到阿里云错误', err)
        })
    },
    // 阿里云上传完成
    uploadSuccess (res, file, fileList) {
      if (fileList.every(item => item.status === 'success')) {
        this.uploadToServer()
      }
    },
    // 上传到服务器
    uploadToServer () {
      const url = this.$API.public.upload.create
      const param = {
        files: JSON.stringify(this.files)
      }
      this.$https.post(url, param)
        .then(data => {
          if (data.succeed) {
            this.$message.success('操作成功')
            this.getFileList()
            // 清空缓存
            this.files = []
            this.cacheFiles = []
            this.initList = []
            this.$store.commit('framework/changeUploadSuccess') // 改变上传成功标识, 使页面监听到并刷新
          } else {
            this.$message.error(data.errorMsg)
          }
          this.uploading = false
        })
        .catch(err => {
          this.uploading = false
          console.log('上传到服务器错误', err)
        })
    },
    // 上传出错, ##无效?
    uploadError (err, file, fileList) {
      console.log('uploadError', err, file, fileList)
    },
    // 移除组件上传列表中的图片, 暂时不用
    removeFile (file, fileList) {
      const removedIndex = this.cacheFiles.findIndex(item => item.name === file.name)
      this.cacheFiles.splice(removedIndex, 1)
    },
    // 上传过程监听, ##无效?
    uploadProgress (e, file, fileList) {
      console.log('progress', e, file, fileList)
    },
    // 勾选变化
    selectionChange (selection) {
      this.selection = selection
    },
    // 点击表格行执行勾选或反选
    toCheck (row) {
      this.$refs.fileTable.toggleRowSelection(row)
    },
    // 页码变化
    currentChange (currentNo) {
      this.currentNo = currentNo
      this.getFileList()
    },
    // 每页条数变化
    sizeChange (pageSize) {
      this.pageSize = pageSize
      this.getFileList()
    },
    // 关闭
    close () {
      this.visible = false
    },
    // 预览图片
    // 悬浮图片显示大图
    toHover (row, e) {
      if (row.fileType.includes('image')) {
        this.hoverUrl = row.fileAddress
        this.isHover = true
        let hoverImg = document.querySelector('#hover-img')
        hoverImg.style.left = (e.clientX + document.getElementById('content').scrollLeft - 50) + 'px'
        hoverImg.style.top = (e.clientY - 250) + 'px' // 因为获取不到元素的高度，所以先写死-250
        // console.log(event.clientX, event.clientY, document.body.clientWidth, document.body.clientHeight, document.getElementById('content').scrollTop, document.getElementById('content').scrollLeft, img, img.style.height)
      }
    },
  },

}
</script>

<style lang="scss">
  .body {
    > div {
      margin-bottom: 20px;
    }
    #download {
      display: none;
    }
    #hover-img {
      position: absolute;
      z-index: 1;
      padding: 10px;
      background-color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
      img {
        width: 300px;
        height: 300px;
      }
    }
  }
  .file-name {
    color: #0682ea;
    &:hover {
      cursor: pointer;
    }
  }
  ul.el-upload-list {
    max-height: 300px;
    overflow: auto;
    margin-top: 10px;
    padding: 1px;
    li:first-child {
      margin-top: 0;
    }
  }
</style>
