<template>
  <div class="pl-upload-container" :id="divId">
    <el-upload drag v-loading="loading" :element-loading-text="uploadLoadingText"
               :file-list="fileList"
               :show-file-list="false"
               :action="uploadUrl"
               :on-success="onSuccess"
               :on-exceed="onExceed"
               :http-request="uploadFileMethod"
               :accept="acceptFileType"
               :limit="limit"
               multiple
               style="width:100%;white-space: pre-wrap;"
               v-if="!isDisabled && !isView">
      <div v-if="!isView">
        <i class="el-icon-upload"></i>
        <img  class="el-upload-img" src="../../assets/font/el-upload-s.png" style="display: none"/>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      </div>
    </el-upload>
    <div v-for="item in stretchNum" style="height: 50px"></div>
    <div v-if="isView && fileList.length == 0" class="el-upload__text">
      <el-tag type="info">未上传附件</el-tag>
    </div>

    <div class="pl-flie-list" id="viewer-selection" v-viewer>
      <div class="pl-file-list-item" v-for="file in fileList" :title="file.name">
        <div class="pl-file-list-item-img">
          <img :src="file.url" :id="file.id" :onerror="defaultImg"/>
        </div>
        <div class="pl-file-list-item-text">
          {{ file.name }}
        </div>
        <div class="pl-file-list-item-btn pos-abs-full">
          <div class="top-btn" @click.stop="tempRemove(file)" v-if="!isDisabled && !isView">
            <i class="el-icon-close btn-close" title="删除"></i>
          </div>
          <div class="center-btn">
            <span v-if="file.isPreview">
                <el-button :type="type" round v-if="file.isPlay" size="small"
                           :icon="icon"
                           :title="`点击播放 ${file.name}`"
                           @click="previewFile(file, file.imgIndex)">{{ clickText }}</el-button>
                <el-button type="primary" round v-else size="small"
                           icon="el-icon-view"
                           :title="`点击预览 ${file.name}`"
                           @click="previewFile(file, file.imgIndex)">预览</el-button>
            </span>
            <el-button type="info" size="small" v-if="candownload" round icon="el-icon-download"
                       :title="`点击下载 ${file.name}`"
                       @click="downloadFile(file.downloadUrl,file)">下载
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <el-dialog class="pl-upload-temp-dialog" :visible.sync="tempDialogVisible"
               append-to-body :close-on-press-escape="false"
               :close-on-click-modal="false" v-if="tempDialogVisible"></el-dialog>

    <!-- 音频视频预览 -->
    <el-dialog custom-class="pl-audiovisual-dialog"
               top="10vh"
               :visible.sync="preview.audiovisualDialogVisible"
               append-to-body
               :before-close="audiovisualBeforeClose">
      <d-player :options="{video: {url: preview.audiovisualSrc}, autoplay: false}"
                style="width: 1000px; height: 800px;"
                ref="videoRef"/>
    </el-dialog>
    <!--  音频播放      -->
    <div ref="aplayer" style="display: none"></div>
    <el-dialog
              title="水印选择" append-to-body
              :visible.sync="waterdialogVisible"
              width="300px">
          <el-select v-model="checkWaterMarkText" placeholder="请选择" >
              <el-option
                      v-for="item in (waterMakeConfig.waterArr||[])"
                      :key="item"
                      :label="item"
                      :value="item">
              </el-option>
          </el-select>
          <span slot="footer" class="dialog-footer">
            <el-button @click="waterdialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="downLoadWaterMarkFile">确 定</el-button>
          </span>
    </el-dialog>
  </div>
</template>

<script>
import Vue from 'vue';
import Viewer from 'v-viewer';
import 'viewerjs/dist/viewer.css';
import VueDPlayer from 'vue-dplayer';
import 'vue-dplayer/dist/vue-dplayer.css';
import APlayer from 'aplayer';
import 'aplayer/dist/APlayer.min.css';

import uploadImg from "./uploadImg";
import uploadMinxins from "./mixin/uploadMixin";

Vue.use(Viewer, {
  defaultOptions: {
    zIndex: 9999
  }
});

export default {
  name: "pl-upload",
  mixins:[uploadMinxins],
  components: {
    'd-player': VueDPlayer,
  },
  props: {

  },
  data() {
    return {
      uploadLoadingText:"正在上传，请稍等...",
      stretchNum:0,
    }
  },

  watch: {

  },

  methods: {
    /*
    ** 初始化上传文件信息列表
    */
    initFiles() {
      let vm = this;
      let fileListDom = window.document.querySelector("#" + this.divId + ".el-upload-list");
      if (fileListDom) {
        fileListDom.innerHTML = "";
      }
      vm.axios.post(vm.api.baseUploadUrl + "viewFile", {"fkId": vm.fileFkId}).then(function (response) {
        let resultFile = [];
        let arrFile = response.data;
        let imgIndex = 0;
        arrFile.forEach(function (file) {
          if (vm.tempRemoveFile.indexOf(file.id) > -1) {
            return;
          }
          file.downloadUrl = vm.api.baseUploadUrl + "downloadFile?id=" + file.id;
          file.viewUrl = vm.api.baseUploadUrl + "previewFile?id=" + file.id;
          // file.downloadUrl = file.downloadUrl.replace("uploadController/downloadFile?id", "wepUploadAction!downloadFile?fjid");
          // 获取小写文件扩展名
          let extension = (file.extension || "").toLowerCase();
          if (extension === "jpg" || extension === "jpeg" || extension === "png") {
            file.url = file.viewUrl;
            file.isPreview = true;
          } else if (vm.objExtensionToImgType[extension]) {
            file.url = uploadImg[vm.objExtensionToImgType[extension] + ".png"];
            const dtype = vm.objExtensionToImgType[extension].toLowerCase();
            if (dtype === 'word' || dtype === 'excel' ||
                dtype === 'powerpoint' || dtype === 'pdf' ||
                dtype === 'video'
            ) {
              file.isPreview = true;
            } else if (dtype === 'sound') {
              file.isPreview = true;
              file.isPlay = true;
            }
          } else {
            file.url = uploadImg["file.png"];
          }
          file.imgIndex = imgIndex++;

          resultFile.push(file);
        });
        vm.fileList = resultFile;
        vm.fileList.forEach(file => {
              let extension = (file.extension || "").toLowerCase();
              if (vm.hasWater && (extension === "jpg" || extension === "jpeg" || extension === "png")) {
                  vm.getImageFileFromUrl(file.downloadUrl, file.name)
                      .then((response) => {
                          // 返回的是文件对象，使用变量接收即可
                          try {
                              vm.getBase64(response).then((imgResult) => {
                                  let waterMake = {
                                      waterMakeText: vm.waterMakeConfig.defaultWaterMake,
                                      fileName:file.name,
                                      fileType:extension
                                  }
                                  vm.base64AddWaterMaker(imgResult, waterMake,"view").then((res) => {
                                      // 这里可以把添加水印后的文件传给后端，我这里只是举例并没有做
                                      // console.log("res", imgResult);
                                      file.url = res;
                                  });
                              })
                          } catch (error) {
                              console.log('error:', error);
                          }
                      })
                      .catch((e) => {
                          console.error(e);
                      })
              }
        })
      });
    },
      /**
       * 根据图片url转为png文件对象
       * @param url
       * @param imageName
       * @returns {Promise<unknown>}
       */
      getImageFileFromUrl(url, imageName) {
          return new Promise((resolve, reject) => {
              var blob = null;
              var xhr = new XMLHttpRequest();
              xhr.open("GET", url);
              xhr.setRequestHeader('Accept', 'image/png');
              xhr.responseType = "blob";
              // 加载时处理
              xhr.onload = () => {
                  // 获取返回结果
                  blob = xhr.response;
                  let imgFile = new File([blob], imageName, {type: 'image/png'});
                  // 返回结果
                  resolve(imgFile);
              };
              xhr.onerror = (e) => {
                  reject(e)
              };
              // 发送
              xhr.send();
          });
      },
      // 图片 转base64
      getBase64(file) {
          return new Promise(function (resolve, reject) {
              let reader = new FileReader();
              let imgResult = "";
              reader.readAsDataURL(file);
              reader.onload = function () {
                  imgResult = reader.result;
              };
              reader.onerror = function (error) {
                  reject(error);
              };
              reader.onloadend = function () {
                  resolve(imgResult);
              };
          });
      },
      // 给图片添加水印
      base64AddWaterMaker(base64Img, waterMakeConfig,type) {

          // 保留this指向 后面会用到的
          let vm = this;
          return new Promise((resolve, reject) => {
              let waterMaketext = waterMakeConfig.waterMakeText || "我是水印";
              // let waterMaketext = "仅限投标使用，盖章有效"
              let repeat = waterMakeConfig.repeat || true;
              let fontSize = 30;
              const canvas = document.createElement('canvas');
              const ctx = canvas.getContext('2d');
              const img = new Image();
              img.crossOrigin = 'Anonymous'; // 图片加载的过程中允许出现跨域
              // 先有src属性才会触发 onload函数
              img.src = base64Img;
              // 异步加载
              img.onload = function () {
                  // 注意img.onload方法是异步的
                  canvas.width = img.width;
                  canvas.height = img.height;
                  vm.width = img.width;
                  vm.height = img.height;
                  // 以左上角为坐标原点 进行绘制图像
                  ctx.drawImage(img, 0, 0, img.width, img.height);
                  ctx.save();

                  let strWidth = 50;
                  let strHeight = 40;
                  strWidth = ctx.measureText(waterMaketext).width + 40;
                  strHeight = strHeight + 30;
                  ctx.fillStyle = "rgba(232,232,238,.8)";//设置文字颜色及透明度
                  ctx.translate(img.width * -0.2, 0);//设置偏转点位
                  ctx.rotate(-0.5); // 水印初始偏转角度
                  if (repeat) {
                      let moveX = strWidth * 8;
                      let moveY = 400;
                      fontSize = 60;
                      ctx.font = fontSize + 'px 黑体';
                      for (let i = strWidth * 0.65 * -1; i < img.width; i += moveX) {
                          for (let j = strHeight; j < img.height * 2; j += moveY) {
                              ctx.fillText(waterMaketext, i, j);
                              ctx.save();
                          }
                      }
                  } else {
                      ctx.font = fontSize * 2 + 'px 黑体';
                      ctx.fillText(waterMaketext, img.width * 0.1, img.height * 0.85); //在图片上添加字体
                      ctx.save();
                  }
                  if(type=="view"){
                      let resultBase64 = canvas.toDataURL('image/png'); // 也是生成的base64格式的
                      if (!resultBase64) {
                          reject();
                      } else {
                          resolve(resultBase64);
                      }
                  }else if(type=="download"){
                      let imgType = "image/jpeg";
                      if(waterMakeConfig.fileType){
                          imgType = "image/"+waterMakeConfig.fileType;
                      }
                      canvas.toBlob((blob) => {
                          let link = document.createElement('a');
                          link.href = window.URL.createObjectURL(blob);
                          link.download = waterMakeConfig.fileName||'水印下载';
                          link.click();
                          link.remove();
                          resolve();
                      }, imgType);
                  }
              };
          });
      },
    /*
    ** 复写原来的上传方法，去除原生的OPTIONS预检请求，
    ** 系统不支持OPTIONS请求
    */
    uploadFileMethod(item) {
      let vm = this;
      let num = 0;
                let uploadFileName = '\n'+item.file.name;
                vm.stretchNum++;
                vm.uploadLoadingText = vm.uploadLoadingText + uploadFileName + '( ' + num + '% )';
      if (!vm.beforeUpload(item.file)) {
        return;
      }
      let formData = new FormData();
      formData.append("file", item.file);
      formData.append("fkId", vm.fileFkId);
      formData.append("extraPath", this.extraPath);
      //创建axios实例
      vm.axios.defaults.headers = null;
      const axiosInstance = vm.axios.create({
        baseURL: vm.uploadUrl,
        headers: {
          Authorization: (localStorage["Authorization" + (window.projectSuffix || "")] || ""),
          'Content-Type': 'multipart/form-data',
        },
        transformRequest: [
          function (data) {
            return data;
          }
        ],
      });

      vm.loading = true;
      //上传文件
      axiosInstance.post(vm.uploadUrl, formData ,{
          onUploadProgress:(progressEvent)=>{
              num = Number(((progressEvent.loaded / progressEvent.total) * 100).toFixed(0));
              if(!vm.loading){
                  vm.loading = true;
              }
              let newUploadLoadArr = [];
              vm.uploadLoadingText.split('\n').forEach(key => {
                  if(key.includes(item.file.name)){
                      key =  item.file.name + '( ' + num + '% )';
                  }
              newUploadLoadArr.push(key);
            })
            vm.uploadLoadingText = newUploadLoadArr.join('\n');
            // vm.uploadLoadingText = '正在上传，请稍等...( ' + num + '% )'
          }
        }).then(function (res) {
            vm.axios.defaults.headers = {
              'Content-Type': 'application/x-www-form-urlencoded',
              Authorization: (localStorage["Authorization" + (window.projectSuffix || "")] || ""),
              common: {
                a: 1,
                b: 2,
                abc: 123
              }
        };

        if (res.data && typeof res.data == "object" && !res.data.operateSuccess && !res.data.upload) {
          vm.$message.error(res.data.message);
        } else {
          vm.uploadFileRecord && vm.uploadFileRecord(vm.field, "add", item.file.name,res.data.upload.id);
        }
        let updateUploadLoadArr = [];
            vm.uploadLoadingText.split('\n').forEach(key => {
                if(!key.includes(item.file.name)){
                    updateUploadLoadArr.push(key);
                }
            })
            vm.uploadLoadingText = updateUploadLoadArr.join('\n');
            if(vm.stretchNum > 0){
                vm.stretchNum--;
            }
        vm.loading = false;
        vm.initFiles();
      }).catch(function (thrown) {
        vm.axios.defaults.headers = {
          'Content-Type': 'application/x-www-form-urlencoded',
          Authorization: (localStorage["Authorization" + (window.projectSuffix || "")] || ""),
          common: {
            a: 1,
            b: 2,
            abc: 123
          }
        };
      });
    },

    /**
     * 临时删除
     */
    tempRemove(file) {
      if (!this.fileTypeValid) {
        this.fileTypeValid = true;
        return;
      }
      if (!this.ifTempRemove) {
        this.remove(file);
      } else {
        this.$confirm('是否确定删除此附件?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
        }).then(() => {
          this.tempRemoveFile.push(file.id);
          this.$emit('onFileRemoved', this.tempRemoveFile);
          this.uploadFileRecord && this.uploadFileRecord(this.field, "delete", file.name,file.id);
          this.initFiles();
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      }
    },

    /*
    ** 文件删除
    */
    remove(file) {
      let vm = this;
      // beforeUpload上传时验证失败不触发这里的删除方法
      if (!vm.fileTypeValid) {
        vm.fileTypeValid = true;
        return;
      }
      vm.$confirm('是否确定删除此附件?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      }).then(function () {
        vm.axios.post(vm.api.baseUploadUrl + "delete", {"ids": file.id}).then(function () {
          vm.$message("附件删除成功！");
          vm.initFiles();
        });
      }).catch(function () {
        vm.$message({
          type: 'info',
          message: '已取消删除'
        });
        vm.initFiles();
      });
    }
  }
}
</script>

<style scoped lang="scss">
.pl-upload-container {

  .pl-flie-list {
    text-align: left;

    .pl-file-list-item {
      vertical-align: top;
      display: inline-block;
      width: 135px;
      height: 135px;
      margin-right: 8px;
      margin-top: 8px;
      border-radius: 2px;
      border: 1px solid #c0ccda;
      cursor: pointer;
      transition: all 0.3s;
      position: relative;

      .pl-file-list-item-btn {
        display: none;
        transition: all 0.3s;
        background: rgba(0, 0, 0, 0.2);

        .top-btn {
          position: absolute;
          top: 0;
          right: 5px;
          text-align: right;

          .btn-close {
            color: black;

            &:hover {
              color: red;
            }
          }
        }

        .center-btn {
          display: inline-block;
          text-align: center;
          width: 100%;
          vertical-align: middle;

          ::v-deep {
            .el-button {
              margin: 5px;
            }
          }
        }

        &:after {
          content: "";
          display: inline-block;
          height: 100%;
          vertical-align: middle;
        }
      }

      &:hover {
        .pl-file-list-item-btn {
          display: block;
        }
      }

      .pl-file-list-item-img {
        /*width: 70px;*/
        height: 70px;
        margin: 14px 31.5px 0 31.5px;

        img {
          width: 70px;
          height: 70px;
        }
      }

      .pl-file-list-item-text {
        margin: 8px 4px;
        text-align: center;
        text-overflow: ellipsis;
        width: 125px;
        white-space: nowrap;
        overflow: hidden;
      }
    }
  }

  .upload-menu {
    position: absolute;
    display: inline-block;

    .menu-li {
      float: left;
      height: 25px;
      line-height: 25px;
      text-align: center;
      font-size: 12px;
      padding-right: 3px;
      cursor: pointer;

      &:hover {
        color: #00AFE4;
      }
    }
  }
}

.upload-info-message {
  color: red;
}

.pl-upload-temp-dialog {
  width: 0;
  height: 0;
}

/* 修改音/视频dialog样式 */
::v-deep .pl-audiovisual-dialog {
  background-color: #000;

  .el-dialog__headerbtn {
    font-size: 25px;
    top: 0;
    right: 0;
    width: 30px;
    height: 30px;
    z-index: 99;
    .el-dialog__close{
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      &:hover{
        color: red;
      }
    }
  }

  .el-dialog__header {
    padding: 0;
    border-bottom:none;
  }

  .el-dialog__body {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0;
    background-color: #000;
  }
}

::v-deep .el-upload-list--picture a.el-upload-list__item-name {
  width: 125px;
  display: inline-block;
  margin: 10px 4px;
  padding: 0px;
  text-align: center;
  vertical-align: middle;
  line-height: 19px;
  cursor: pointer;
}

::v-deep .el-upload-list--picture li.el-upload-list__item {
  height: 135px;
  width: 135px;
  padding: 0px;
  float: left;
  margin-right: 10px;
}

::v-deep .el-upload-list--picture .el-upload-list__item-name i {
  display: none;
}

::v-deep .el-upload-list--picture .el-upload-list__item-thumbnail {
  position: inherit;
  margin: 14px 31.5px 0 31.5px;
  cursor: pointer;
}

::v-deep li.el-list-enter-to, ::v-deep li.el-list-leave-to, ::v-deep li.el-list-enter-active, ::v-deep li.el-list-leave-active {
  transition: none;
}
</style>

<style>
.pl-upload-container .el-upload, .pl-upload-container .el-upload-dragger {
  width: 100%;
}
</style>
