<template>
  <div class="el-image-uploader">
    <el-upload
      ref="upload"
      action
      :headers="headers"
      list-type="picture-card"
      :multiple="true"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-error="handleError"
      :before-upload="beforeUpload"
      :http-request="uploadMulFile"
      :file-list="fileList"
      :data="uploadData"
    >
      <i class="el-icon-plus"></i>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件，且不超过5MB</div>
    </el-upload>

    <!-- 图片预览对话框 -->
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt="Preview">
    </el-dialog>
  </div>
</template>

<script>
import ossClient from "@/utils/ossClient";
import md5 from "md5";
export default {
  name: 'ImageUploader',
  props: {
    // 上传时附带的额外参数
    uploadData: {
      type: Object,
      default: () => ({})
    },
    // 上传的请求头
    headers: {
      type: Object,
      default: () => ({})
    },
    // 最大文件大小（MB）
    maxSize: {
      type: Number,
      default: 5
    }
  },
  data() {
    return {
      fileList: [], // 文件列表
      dialogImageUrl: '', // 预览图片URL
      dialogVisible: false, // 预览对话框显示状态
      uploadConf: {
        region: null,
        accessKeyId: null,
        accessKeySecret: null,
        bucket: null,
        // stsToken: null,
      },
    }
  },
  created() {
    this.initOssInfo();
  },
  methods: {
    // 处理图片预览
    handlePreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    //初始化从后端获取到 TST账户对OSS进行操作  在created初始化
    initOssInfo() {
      //获取阿里云token  这里是后台返回来的数据 暂时使用死数据
      const aliyun = {
        // "你的Region  注意 这个只要 空间名 不要 http:// 和 .aliyunoss.com !!",
        Region: "oss-cn-beijing",
        AccessKeyId: "LTAI5tJzo2DiQxQqh9EipDNh",
        AccessKeySecret: "JnduhWY5Tr5VfuFHgDOv9XjqYx1mDg",
        Bucket: "zx-material-new",
        //"你的SecurityToken"
        // SecurityToken: null,
      };
      const {
        Region,
        AccessKeyId,
        AccessKeySecret,
        Bucket,
        // SecurityToken,
      } = aliyun;
      //初始化连接oss参数
      this.uploadConf.region = Region;
      this.uploadConf.accessKeyId = AccessKeyId;
      this.uploadConf.accessKeySecret = AccessKeySecret;
      this.uploadConf.bucket = Bucket;
      // this.uploadConf.stsToken = SecurityToken;
    },


    // 处理图片删除
    handleRemove(file, fileList) {
      this.fileList = fileList
      this.$emit('change', this.getFiles())
    },

    // 处理上传失败
    handleError(err, file) {
      this.$message.error('上传失败：' + (err.message || '未知错误'))
    },

    // 上传前的验证
    beforeUpload(file) {
      // 验证文件类型
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        this.$message.error('只能上传图片文件！')
        return false
      }

      // 验证文件大小
      const isLtMaxSize = file.size / 1024 / 1024 < this.maxSize
      if (!isLtMaxSize) {
        this.$message.error(`图片大小不能超过 ${this.maxSize}MB！`)
        return false
      }

      return true
    },

    // 获取文件列表
    getFiles() {
      return this.fileList.map(file => ({
        name: file.name,
        url: file.url,
        size: file.size,
        raw: file.raw
      }))
    },

    // 清空上传列表
    clearFiles() {
      this.$refs.upload.clearFiles()
      this.fileList = []
      this.$emit('change', [])
    },

    // 手动上传
    submit() {
      this.$refs.upload.submit()
    },
    //上传到阿里云OSS
    uploadMulFile(uploader) {
      console.log("文件信息", uploader);
      //获取到文件的信息内容
      let file = uploader.file;
      //获取文件类型 和 上传文件的日期
      let fileType = file.name.split(".").pop();
      if (file.name.split(".").length === 1) {
        fileType = "jpg";
      }
      let curTime = new Date();
      //定义上传到云端的路径和文件名字
      let fileName = md5(file.name + Date.now()) +
        "." +
        fileType;

      let upFilePath =
        "ad_putin_materials" +
        "/" +
        curTime.getFullYear() +
        "/" +
        (curTime.getMonth() + 1) +
        "/" +
        curTime.getDate() +
        "/" + fileName
      //分片上传配置，回显进度以及上传总进度重置，分片大小，超时设置
      let optionsFile = {
        progress: function (p) {
          uploader.onProgress({ percent: Math.floor(p * 10000) / 100 });
        },
        partSize: 1000 * 1024, //设置分片大小 小于1m 1024*1024
        timeout: 36000000, //设置超时时间 - 10小时
      };
      //实例化上传对象
      let client = ossClient(this.uploadConf);
      /* 分片上传 显示上传进度 */
      const that = this;
      //测试地址替换为 "test/" +upFilePath
      client
        .multipartUpload(upFilePath, file, optionsFile)
        .then((res) => {
          //解析url并替换前缀可访问
          let strUrl = res.res.requestUrls[0].split("?")[0];
          strUrl = strUrl.replace(
            "http://zx-material-new.oss-cn-beijing.aliyuncs.com",
            "https://cdn.zhangxingames.com"
          );
          that.fileList = [...that.fileList, { uid: file.uid, url: strUrl, name: fileName }];
          uploader.onSuccess(); //上传成功(打钩的小图标)
          client = null;
          this.$emit('change', this.getFiles())
        })
        .catch((err) => {
          that.$message.warning(`上传终止，提示：${err}`);
          console.log(err);
          if (client.isCancel()) {
            uploader.onError();
          }
        });
    },
  }
}
</script>

<style>
.el-image-uploader {
  padding: 20px;
}

.el-upload__tip {
  margin-top: 10px;
  color: #909399;
}
</style>
