<template>
  <el-dialog title="商品图片" :visible.sync="visible" :width="width" v-on:close="onClose">
    <div v-show="!editMode">
      <div>
        <el-button @click="editMode=true" type="primary" v-show="max===0||dataList.length<max">添加图片</el-button>
      </div>
      <div class="main-imgMaterial">
        <ul class="main-imgMaterialList">
          <li v-for="(item,index) of dataList" :class="{'isDefault':item.isDefault}">
            <img :src="item.imgUrl"/><br/>
            <span class="aLink" v-show="!item.isDefault" @click.stop="remove(item,index)">删除</span>
            <span class="aLink" v-show="!item.isDefault" @click.stop="setDefault(item,index)">设为默认</span>
          </li>
        </ul>
      </div>
    </div>
    <div v-show="editMode">
      <div>
        <el-button @click="chooseFile" type="primary">选择图片</el-button>
        <el-button @click="uploadCroppedImage" type="primary" v-show="hasImg&&percentage===0">上传</el-button>
        <el-button @click="editMode=false">取消</el-button>
      </div>
      <div class="workArea">

        <croppa v-model="myCroppa"
                :width="imgWidth"
                :height="imgHeight"
                :quality="2"
                placeholder="请选择图片"
                :placeholder-font-size="0"
                :disabled="false"
                :prevent-white-space="true"
                :show-remove-button="true"
                ref="croppa"
                v-on:new-image="hasImg=true"
                canvas-color="transparent"
                :accept="transparent?'image/png':'image/*'"
                @file-type-mismatch="onFileTypeError"
        >
        </croppa>
        <el-progress :percentage="percentage" v-show="percentage>0&&percentage<100"></el-progress>
      </div>
    </div>
  </el-dialog>
</template>

<script>

  import ossUpload from '../math/oss_upload';
  import Ajax from '../math/ajax';
  import Croppa from 'vue-croppa';
  import Vue from 'vue';
  import 'vue-croppa/dist/vue-croppa.css';
  import {layer} from '../math/layer';

  Vue.use(Croppa);

  export default {
    name: "img-manger",
    props: {
      transparent: {
        type: Boolean,
        default: false
      },
      /**
       * 上传模式 默认启用OSS
       */
      mode: {
        type: String,
        default: 'oss'
      },
      /**
       * OSS模式下必传（获取OSS令牌的接口地址）
       */
      ossTokenUrl: {
        type: String
      },
      /**
       * OSS模式下必传 图片上传成功后的域名
       */
      ossWebPath: {
        type: String
      },
      /**
       * OSS模式下 图片放到哪个目录下面（可选）
       */
      ossDir: {
        type: String,
        default: ''
      },
      opt: {
        type: Object,
        default: {
          listApi: '',      //数据列表接口
          addApi: '',       //添加数据接口
          delApi: '',       //删除数据接口
          defApi: '',       //设置默认接口
          uploadApi: '',    //文件上传接口
          useDef: true      //是否启用默认图片功能
        }
      },
      width: {
        type: String,
        default: '700px'
      },
      //输出图片宽度
      imgWidth: {
        type: Number,
        default: 300
      },
      //输出图片高度
      imgHeight: {
        type: Number,
        default: 300
      },
      quality: {
        type: Number,
        default: 2
      },
      max: {
        type: Number,
        default: 0
      },
      /**
       * 图片压缩比
       */
      ratio: {
        type: Number,
        default: .8
      }

    },
    data() {
      return {
        editMode: false,
        visible: false,
        dataList: [],
        paras: {},
        myCroppa: {},
        hasImg: false,
        percentage: 0
      }
    },
    methods: {
      onFileTypeError() {
        if (this.transparent) {
          layer.error('只允许选择png图片');
        } else {
          layer.error('只允许选择图片');
        }
      },
      /**
       * 显示图片管理器
       * @param paras - 必传
       */
      show(paras) {
        this.paras = paras;
        this.visible = true;
        this.dataList = [];
        this.loadList();
        this.clear();

      },
      /**
       * 加载图片列表
       */
      loadList() {
        Ajax.get(this.opt.listApi, this.paras).then(data => {
          this.dataList = data;
        });
      },

      /**
       * 清空工作区
       */
      clear() {
        if (this.hasImg) {
          this.$refs.croppa.remove();
          this.hasImg = false;
        }
      },
      /**
       * 选择图片
       */
      chooseFile() {
        this.$refs.croppa.chooseFile();
      },
      /**
       * 上传图片
       */
      uploadCroppedImage() {
        if (!this.hasImg) {
          this.$message({
            message: '请选择图片',
            type: 'error'
          });
          return;
        }
        this.myCroppa.generateBlob((blob) => {
          switch (this.mode) {
            case 'oss':
              this.uploadByOss(blob);
              break;
            case 'api':
              this.uploadByApi(blob);
              break;
          }
        }, this.transparent ? 'image/png' : 'image/jpeg', this.ratio)
      },

      /**
       *阿里OSS上传
       */
      uploadByOss(blob) {
        const xhr = new XMLHttpRequest();
        let fileName;
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4 && xhr.status === 200) {
            this.onUploadSuccess({
              imgUrl: this.ossWebPath + fileName,
              imgId: 0
            });
          }
        };
        xhr.upload.addEventListener('progress', (e) => {
          this.percentage = ~~(100 * e.loaded / e.total) / 2;
        }, false);

        ossUpload(this.ossTokenUrl, blob, this.ossDir, false).then((res) => {
          fileName = res.fileName;
          xhr.open('post', res.host);
          xhr.send(res.formData);
        });
      },
      /**
       * Api直接上传
       */
      uploadByApi(blob) {
        const xhr = new XMLHttpRequest();
        const formData = new FormData();
        formData.append('file', blob, this.transparent?'图片.png':'图片.jpg');
        xhr.open('post', this.opt.uploadApi);
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4 && xhr.status === 200) {
            this.onUploadSuccess(JSON.parse(xhr.responseText));
          }
        };
        xhr.upload.addEventListener('progress', (e) => {
          this.percentage = ~~(100 * e.loaded / e.total) / 2;
        }, false);
        xhr.send(formData);
      },
      /**
       * 图片上传后触发
       * @param res
       */
      onUploadSuccess(res) {
        this.percentage = 0;

        Ajax.post(this.opt.addApi, Object.assign({
          imgUrl: res.imgUrl,
          imgId: res.imgId
        }, this.paras)).then(data => {
          this.$message({
            message: '上传成功',
            type: 'success'
          });
          this.dataList.push({
            id: data.id,
            imgUrl: res.imgUrl,
            imgId: res.imgId,
            isDefault: false
          });
          this.editMode = false;
          this.clear();
        });

      },
      /**
       * 删除图片
       * @param item
       * @param index
       */
      remove(item, index) {
        this.$confirm('删除后不可恢复', '确实要删除该图片吗？', {
          type: 'warning'
        }).then(() => {
          Ajax.get(this.opt.delApi, Object.assign({
            id: item.id
          }, this.paras)).then(() => {
            this.dataList.splice(index, 1);
            this.$message({
              message: '图片已删除',
              type: 'warning'
            });
          });
        }).catch(() => {
        });
      },
      /**
       * 删除图片
       * @param item
       * @param index
       */
      setDefault(item, index) {
        this.$confirm('是否将该图片设置为默认图片', '操作确认？', {
          type: 'warning'
        }).then(() => {
          Ajax.get(this.opt.delApi, Object.assign({
            id: item.id
          }, this.paras)).then(() => {
            this.dataList.forEach((item) => {
              item.isDefault = false;
            });
            item.isDefault = true;
            this.$message({
              message: '操作成功',
              type: 'success'
            });
            this.$emit('on-set-default', this.paras, item.imgUrl);
          });
        }).catch(() => {
        });
      },
      /**
       * 关闭时抛出事件
       */
      onClose() {
        this.$emit('on-close');
      }
    }
  }
</script>

<style scoped>
  .workArea {
    text-align: center;
    padding-top: 20px;
  }

  .workArea div {
    line-height: 0px;
  }

  .isDefault {
    border: red 1px solid;
  }
</style>
