<template>
  <div class="ws-upload"
       v-loading="loading">
    <div v-if="!remarkWord">
      <el-button class="upload-noramark-btn"
                 style="padding: 8px 25px;"
                 size="small"
                 type="text"
                 @click="_handleUploadClick">上传附件</el-button>
    </div>
    <div class="trigger-group"
         v-if="editable && remarkWord">
      <el-button class="upload-btn"
                 size="small"
                 type="primary"
                 style="padding: 8px 20px;"
                 round
                 @click="_handleUploadClick">上传附件</el-button>
      <div class="tip">
        支持上传{{ formatTxt }}格式的文件，单个文件大小不能超过15MB
      </div>
    </div>
    <el-upload action="#"
               list-type="picture-card"
               :http-request="_handleRequest"
               :file-list="fileList"
               :before-upload="_handleBeforeUpload"
               :accept="accept"
               :multiple="!limit || parseInt(limit) > 1"
               ref="elUpload">
      <template v-slot:trigger>
        <div ref="triggerDiv">-</div>
      </template>
      <template v-slot:file="{file}">
        <div class="thumbnail-group">
          <img v-if="isPictureFile(file)"
               class="el-upload-list__item-thumbnail"
               :src="_getFileImg(file)" />
          <img v-else
               class="el-upload-list__item-thumbnail"
               :class="getFileClass(file)" />
        </div>
        <div class="fileName"
             v-if="showName"
             :title="file.name">{{ file.name }}</div>
        <span class="el-upload-list__item-actions"
              v-if="file.status == 'success' && (editable || download || preview)">
          <span v-if="isPictureFile(file) && preview"
                class="el-upload-list__item-preview"
                @click="_handlePreview(file)">
            <i class="el-icon-zoom-in"></i>
          </span>
          <span v-if="download && !isPictureFile(file)"
                class="el-upload-list__item-delete"
                @click="_handleDownload(file)">
            <i class="el-icon-view"
               v-if="isOnlineFile(file)"></i>
            <i class="el-icon-download"
               v-else></i>
          </span>
          <span v-if="onlineEdit && !isPictureFile(file)"
                class="el-upload-list__item-delete"
                @click="_handleOnline(file)">
            <i class="el-icon-edit"></i>
          </span>

          <span v-if="editable"
                class="el-upload-list__item-delete"
                @click="_handleRemove(file)">
            <i class="el-icon-delete"></i>
          </span>
        </span>
      </template>
    </el-upload>
    <el-dialog v-drag
               :modal="false"
               :visible.sync="dialogVisible"
               @closed="_handlePreviewClosed"
               :title="downloadName"
               append-to-body>
      <img :src="dialogImageUrl"
           width="100%" />
    </el-dialog>
  </div>
</template>

<script>
import Cookies from "js-cookie";
import { getFileList, saveFiles, uploadShipFiles, getOssInterimCredentials, GotOssAccessConfig } from '../../api/system/upload'
import config from "../../api/config/ossCfg";
import { formatDate } from "../../utils/formatDate";
import { uuid } from "../../utils/publicFun";
import { client } from "../../utils/alioss";
import downloadNow from "../WsDownload/download";

export default {
  name: "WsUpload",
  props: {
    appendixIds: String,
    editable: {
      // 是否为编辑模式
      type: Boolean,
      default: true
    },
    onlineEdit: {
      // 在线编辑
      type: Boolean,
      default: false
    },
    remarkWord: {
      // 是否有备注要求
      type: Boolean,
      default: true
    },
    preview: {
      // 是否允许预览
      type: Boolean,
      default: true
    },
    download: {
      // 是否允许下载
      type: Boolean,
      default: true
    },
    showName: {
      // 是否显示文件名
      type: Boolean,
      default: true
    },
    limit: {
      // 文件总数量限制
      type: Number,
      default: undefined
    },
    sizeLimit: {
      // 文件大小限制
      type: Number,
      default: undefined
    },
    accept: {
      // 限制文件类型
      type: String,
      default: ".jpg, .jpeg, .png, .gif, .pdf, .doc, .docx, .xls, .xlsx, .zip, .rar, .eml"
    },
    ossKey: {
      type: String,
      required: true
    },
    compId: {
      // 公司ID
      type: String,
      required: false
    },
    vesselId: {
      // 船舶ID
      type: String,
      required: false
    },
    tableName: {
      // 要保存的表的名字
      type: String,
      required: false
    }
  },
  data () {
    return {
      ossAccessConfig: {},
      vesselBankFlag: "V",
      curFileNum: 0,
      tempFileList: [],
      initFileList: [],
      loading: false, // 是否正在初始化filelsit
      fileList: [],
      removeList: [],
      dialogImageUrl: "",
      dialogVisible: false,
      downloadName: "",
      loadingView: "", // loading弹出层
      uploadParams: {
        companyId: this.compId,
        basePath: config.getUploadPath(this.ossKey, this.compId)
      },
      clientFag: localStorage.getItem('ws-pf_clientFag') || 'B'
    };
  },
  computed: {
    formatTxt () {
      return this.accept
        .replace(/\./g, "")
        .replace(/ /g, "")
        .replace(/,/g, "、 ");
    },
    thisAppendixIds () {
      return this.appendixIds;
    }
  },
  watch: {
    // 监听props.appendixIds, 变化时向服务器请求
    async thisAppendixIds (newV, oldV) {
      this.getDefaultFiles(newV);
    }
  },
  mounted () {
    this.getDefaultFiles(this.appendixIds);

    const handleChange = this.$refs.elUpload.$refs["upload-inner"].handleChange;
    this.$refs.elUpload.$refs["upload-inner"].handleChange = ev => {
      this.initFileList = [];
      this.curFileNum = ev.target.files.length;
      for (let i = 0; i < this.curFileNum; i++) {
        this.initFileList.push(ev.target.files[i]);
        this.tempFileList[i] = i;
      }
      handleChange(ev);
    };

    // this.getOssAccessConfig();
  },
  methods: {
    async getOssAccessConfig () {
      let resp = await GotOssAccessConfig();
      this.ossAccessConfig = resp.data;
    },
    // 获取图片文件
    _getFileImg (file) {
      if (!file) {
        return "";
      }
      if (this.isPictureFile(file)) {
        if (file.url.indexOf("blob") === 0 || this.vesselBankFlag === "V") {
          return file.url;
        }
        return file.url + "?x-oss-process=image/resize,w_120,h_120";
      }
      return "";
    },

    async getDefaultFiles (appendixIds) {
      this.fileList = [];
      if (appendixIds) {
        this.loading = true;
        const list = await this._getFileList(appendixIds);
        this.loading = false;

        if (list) {
          this.fileList = list.map((item, idx) => {
            return {
              appendixId: item.appendixId,
              name: item.appendixName,
              url: this.getFilePath(item.appendixPath),
              uid: uuid()
            };
          });
        }
      }
    },

    // 处理上传按钮点击
    _handleUploadClick () {
      this.$refs.triggerDiv.click();
    },
    // 处理预览
    _handlePreview (file) {
      this.dialogImageUrl = file.url;
      this.downloadName = file.name;
      this.dialogVisible = true;
    },
    // 处理预览关闭
    _handlePreviewClosed () {
      this.dialogImageUrl = "";
      this.downloadName = "";
    },

    // 处理删除
    _handleRemove (file) {
      if (file.appendixId) {
        // 这是要删除已经存在的附件
        const index = this.fileList.findIndex(itm => itm.appendixId === file.appendixId);
        this.fileList.splice(index, 1);
        this.removeList.push(file.appendixId);
      } else {
        // 这是删除已上传但还未保存的附件
        const index = this.fileList.findIndex(itm => itm.uid === file.uid);
        this.fileList.splice(index, 1);
      }
      this.$emit("onChange", this.fileList.length);
    },

    // 自定义上传过程
    _handleRequest (param) {
      if (this.vesselBankFlag === "V") {
        //船端
        this._uploadFilesShip(param);
      } else {
        //岸端
        this._uploadFiles(param);
      }
    },

    _uploadFiles (param) {
      return new Promise(async (resolve, reject) => {
        this.showLoading();
        const file = param.file;

        const dateStr = formatDate(new Date(), "yyyyMMddhhmmss");
        const dotIndex = file.name.lastIndexOf(".");
        const filePre = file.name.substring(0, dotIndex);
        const ext = file.name.substring(dotIndex + 1);
        const fileName = `${filePre}-${dateStr}.${ext}`;

        const targetPath = config.getUploadPath(this.ossKey, this.compId);
        if (!targetPath) {
          reject("配置的ossKey或compId不对");
          return;
        }
        // oss临时凭证
        const ossInter = await this.getOssInter();
        if (!ossInter) {
          reject("oss临时凭证为空!");
          return;
        }

        // 上传
        client(ossInter, this.ossAccessConfig)
          .put(targetPath + fileName, file)
          .then(response => {
            const item = {
              appendixName: file.name,
              appendixPath: "/" + response.url.substring(response.url.indexOf(targetPath)),
              appendixSize: this.toKB(file.size),
              appendixType: "B",
              fromTableName: this.tableName,
              vesselId: this.vesselId,
              uid: file.uid,
              url: this.getFilePath(response.url),
              name: file.name
            };
            let fileIndex = this.getFileIndex(item.uid);
            if (fileIndex >= 0) {
              this.tempFileList.splice(fileIndex, 1, item);
              this._handleSuccessOnce();
            }
            resolve();
          })
          .catch(err => {
            this.handleError();
            reject();
          });
      });
    },

    _uploadFilesShip (param) {
      return new Promise(async (resolve, reject) => {
        this.showLoading();
        const file = param.file;

        uploadShipFiles(file, {
          companyId: this.compId || "",
          modelId: !this.tableName ? "" : this.tableName.split("_")[0]
        })
          .then(response => {
            if (response.data) {
              const item = {
                appendixName: response.data.appendixName,
                appendixPath: response.data.appendixPath,
                appendixSize: this.toKB(file.size),
                appendixType: "V",
                fromTableName: this.tableName,
                vesselId: this.vesselId,
                uid: file.uid,
                url: this.getFilePath(response.data.appendixPath),
                name: file.name
              };
              let fileIndex = this.getFileIndex(item.uid);
              if (fileIndex >= 0) {
                this.tempFileList.splice(fileIndex, 1, item);
                this._handleSuccessOnce();
              }
              resolve();
            } else {
              this.handleError();
              reject();
            }
          })
          .catch(err => {
            this.handleError();
            reject();
          })
          .finally(() => {
            this.hideLoading();
          });
      });
    },

    // 处理单个文件上传成功
    _handleSuccessOnce () {
      this.curFileNum--;
      if (this.curFileNum === 0) {
        this.fileList.push.apply(
          this.fileList,
          this.tempFileList.filter(item => {
            if (item.uid) {
              return item.uid
            }
          })
        );
        //this.$message.success(this.$t('showMessage.saveSuccessOss'));
        this.tempFileList = [];
        this.$emit("onChange", this.fileList.length);
        this.hideLoading();
      }
    },
    // 处理在线编辑
    _handleOnline (file) {
      window.open(process.env.VUE_APP_BASE_API + "/office/file?fileId=" + file.appendixId + "&showSaveFlag=1");
    },

    // 处理下载
    _handleDownload (file) {
      downloadNow(file.url, file.name, this.vesselBankFlag);
    },

    _handleBeforeUpload (file) {
      let size = this.sizeLimit ? this.sizeLimit : 30;
      if (file.size > size * 1024 * 1024) {
        this.$message({
          message: "文件不能大于" + size + "M",
          type: "error",
          showClose: true
        });
        return false;
      }
      if (this.limit) {
        let limitFileNum = parseInt(this.limit);
        let currentFileNum = this.fileList.length + this.curFileNum;
        if (limitFileNum > 1 && currentFileNum > limitFileNum) {
          this._handleExceed();
          return false;
        }
        if (limitFileNum === 1) {
          this.fileList = [];
        }
      }
      return true;
    },
    //处理文件上传失败
    _handleError () {
      this.curFileNum--;
      // this.$message({
      //   message: this.$t('showMessage.saveErrorOss'),
      //   type: 'error',
      //   showClose: true
      // })
      this.hideLoading();
    },

    _handleExceed () {
      this.$message({
        message: `最多只能上传${this.limit}个文件`,
        type: "warning",
        showClose: true
      });
    },

    // 传入appendixIds 从服务器获取文件列表信息
    _getFileList (appendixIds) {
      return new Promise(next => {
        getFileList({ appendixIds })
          .then(res => {
            if (res.code === "200") {
              next(res.data || []);
            } else {
              next();
            }
          })
          .catch(() => {
            next();
          });
      });
    },

    handleSaveBill () {
      return new Promise((resolve, reject) => {
        const oldAppendixIds = this.removeList.join();
        const newAppendixs = this.fileList;
        const params = { newAppendixs, oldAppendixIds };
        saveFiles(params)
          .then(res => {
            resolve(res.data.join());
          })
          .catch(err => {
            this.$message({
              message: "文件保存失败",
              type: "error",
              showClose: true
            });
            reject();
          });
      });
    },

    // 获取文件样式
    getFileClass (file) {
      const ext = this.getExtName(file.name);
      return "ext " + ext;
    },
    // 是否为图片
    isPictureFile (file) {
      if (file && file.name) {
        const name = this.getExtName(file.name);
        return name === "jpg" || name === "png" || name === "jpeg" || name === "gif" || name === "webp" || name === "bmp";
      }
      return false;
    },
    // 是否为在线打开文件
    isOnlineFile (file) {
      if (file && file.name) {
        const name = this.getExtName(file.name);
        return name === "pdf" || name === "tet";
      }
      return false;
    },

    getOssInter () {
      return new Promise(next => {
        getOssInterimCredentials().then(response => {
          if (response.code === "200") {
            next(response.data);
          } else {
            next();
          }
        });
      });
    },

    getFileIndex (uid) {
      for (let i = 0; i < this.initFileList.length; i++) {
        if (this.initFileList[i].uid === uid) {
          return i;
        }
      }
      return -1;
    },

    // 显示loading
    showLoading () {
      this.loadingView = this.$loading({
        lock: true,
        text: "Loading",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
        target: document.querySelector(".div1")
      });
    },
    // 隐藏loading
    hideLoading () {
      this.loadingView.close();
    },
    // 获取后缀名
    getExtName (url) {
      if (!url) {
        return url;
      }
      url = url.substr(url.lastIndexOf(".") + 1);
      if (url.indexOf("?") >= 0) {
        url = url.substr(url.indexOf("?"));
      }
      return url;
    },

    checkUrl (path) {
      if (path.indexOf("http://") > -1 || path.indexOf("https://") > -1) {
        let pathSplit = path.split(".com/")
        if (pathSplit) {
          path = pathSplit[1]
        }
      }
      return path;
    },
    getFilePath (path) {
      // if (this.vesselBankFlag === "V") {
      // const sysUrl = "http://" + window.location.host + "/";
      const sysUrl = this.$store.getters.baseInfo.fileUrl;
      return sysUrl + this.slash(path);
    },
    // 字节转KB
    toKB (bt) {
      return (bt / 1024).toFixed(2) + "KB";
    },
    clearFiles () {
      this.fileList = [];
    },
    // 反斜杠转斜杠
    slash (str) {
      return str.replace(/\\/g, "/");
    }
  }
};
</script>

<style lang="scss" scoped>
$picture-size: 110px;
$ctrl-margin-left: 10px;

.ws-upload {
  /*.upload-noramark-btn{*/
  /*  padding: 0px;*/
  /*  border: none;*/
  /*}*/
  .trigger-group {
    margin-bottom: 10px;

    .upload-btn {
      display: inline-block;
      border-radius: 4px;
    }
    .tip {
      display: inline-block;
      margin: 0;
      padding: 0;
      font-size: 12px;
      line-height: 17px;
      color: #999;
      margin-bottom: 4px;
      margin-top: 4px;
      vertical-align: middle;
    }
  }

  /deep/ .thumbnail-group {
    width: $picture-size;
    height: $picture-size;

    .el-upload-list__item-thumbnail {
      display: block;
      border-radius: 6px;
      border: 1px solid #ccd6e3;
      background-color: #fff;
    }
  }

  /deep/ .el-upload-list__item-actions {
    height: $picture-size;
    overflow: hidden;
    border-radius: 6px;
    align-items: center;
    display: flex;
    justify-content: center;
  }

  .fileName {
    font-size: 12px;
    color: #666;
    margin: 0;
    text-align: center;
    margin-top: 4px;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /deep/
    .el-upload-list--picture-card
    .el-upload-list__item-actions
    span
    + span {
    margin-left: $ctrl-margin-left;
  }

  /deep/ .el-upload.el-upload--picture-card {
    display: none;
  }

  /deep/ .el-upload-list__item {
    width: $picture-size;
    height: auto;
    border: 0;
    background: none;
  }

  .ws-upload-progress {
    width: 84%;
    top: 88px;
  }

  .ext {
    background-size: $picture-size * 0.7;
    background-repeat: no-repeat;
    background-position: center;
  }
  .doc {
    background-image: url("../../assets/images/common/upload/doc.png");
  }
  .docx {
    background-image: url("../../assets/images/common/upload/docx.png");
  }
  .eml {
    background-image: url("../../assets/images/common/upload/eml.png");
  }
  .pdf {
    background-image: url("../../assets/images/common/upload/pdf.png");
  }
  .mp4,
  .avi,
  .mov,
  .rmvb,
  .rm,
  .flv {
    background-image: url("../../assets/images/common/upload/video.jpg");
    background-size: $picture-size;
  }
  .rar {
    background-image: url("../../assets/images/common/upload/rar.png");
  }
  .xls {
    background-image: url("../../assets/images/common/upload/xls.png");
  }
  .xlsx {
    background-image: url("../../assets/images/common/upload/xlsx.png");
  }
  .zip {
    background-image: url("../../assets/images/common/upload/zip.png");
  }
}

// 取消ele动画
/deep/ .el-list-leave-active {
  transition: all 0s;
}
/deep/ .el-list-enter-active {
  transition: all 0s;
}
/*.el-button--text{*/
/*  color: #666666;*/
/*}*/
/*.el-button--text:hover{*/
/*  color: #4a89f1;*/
/*}*/
/*.el-button--text:focus{*/
/*  color: #ffffff;*/
/*}*/
</style>
