<template>
  <div class="xd-upload">
    <!--启用素材库-->
    <template v-if="isInMaterial">
      <div v-if="styleType ==='one'" class="upload_one_m">
        <div class="xd-upload__one-btn flex" @click="handleDialogShow">
          <slot :image="oneItem">
            <el-button size="small" type="primary" :disabled="disabled">{{uploadName}}</el-button>
          </slot>
          <div v-if="(oneItem && (oneItem.path || oneItem.url)) && !disabled " class="xd-upload__one-btn-del" @click.stop="delOne()">
            <i v-if="item['slot'] || isShowDel" class="el-icon-delete"></i>
          </div>
          <div class="xd-upload__disabled" v-if="disabled"></div>
        </div>
        <div v-if="showtype" slot="tip" class="xd-upload__tip" style="padding-top: 0">
          <slot name="tip"><span v-html="tooltip"></span></slot>
        </div>
      </div>
      <div v-if="styleType==='list'">
        <div class="xd-upload__list">
          <div
            v-if="showList.length === 0"
            class="xd-upload__list-add"
            @click="handleToUpload"
            :style="{
              width: list_width + 'px',
              height: list_height + 'px',
              borderRadius: radius + 'px'
            }"
          >
            <i class="xd_admin_iconfont xdicon_shangchuantupian1"></i>
          </div>
          <draggable
            v-else
            :list="showList"
            :disabled="showList.length === 0 || !sort"
            class="xd-upload__list-box"
            :style="{minHeight: list_height + 'px'}"
            @start="dragging = true"
            @end="dragging = false"
          >
            <div
              class="xd-upload__list-item"
              v-for="(item,index) in showList" :key="item.path"
              :title="item.name"
              :style="{
                width: list_width + 'px',
                height: list_height + 'px',
                borderRadius: radius + 'px'
              }"
            >
              <xd-item-image
                :list="getImagesPreview(index)"
                :width="list_width"
                :height="list_height"
              >
              </xd-item-image>
              <i class="el-icon-delete-solid" @click="del(index)"></i>
              <span>{{item.name|fitersName}}</span>
            </div>
          </draggable>
          <div><el-button
            type="primary"
            :disabled="isBtnMaterialMore || disabled"
            @click="isDialogShow=true"
          >{{materialBtnName}}</el-button></div>
          <div v-if="showtype" slot="tip" class="xd-upload__tip">
            <slot name="tip"><span v-html="tooltip"></span></slot>
          </div>
        </div>
      </div>
      <dialog-material
        v-if="isDialogShow"
        :show.sync="isDialogShow"
        :setting="imageConfig"
        @select="handleMaterial"
      ></dialog-material>
    </template>
    <!--启用素材库-->
    <!--使用原上传组件-->
    <template v-else>
      <template v-if="styleType==='one'">
        <el-upload
          :disabled="disabled"
          class="xd-upload__one"
          :action="uiAction"
          :name="name"
          :headers="header"
          :show-file-list="false"
          :data="postData"
          :on-success="handleOneSuccess"
          :before-upload="beforeUpload"
          :on-progress="handleProgress"
          :on-exceed="handleExceed"
          :on-error="handleError"
        >
          <div class="xd-upload__one-btn">
            <slot :image="oneItem">
              <el-button size="small" type="primary" :disabled="disabled">{{uploadName}}</el-button>
            </slot>
            <div v-if="(oneItem && (oneItem.path || oneItem.url)) && !disabled " class="xd-upload__one-btn-del" @click.stop="delOne()">
              <i v-if="item['slot']" class="el-icon-delete"></i>
            </div>
            <div class="xd-upload__disabled" v-if="disabled"></div>
          </div>
        </el-upload>
        <div v-if="showtype" slot="tip" class="xd-upload__tip">
          <slot name="tip"><span v-html="tooltip"></span></slot>
        </div>
      </template>
      <template v-else-if="styleType==='auth'">
        <div class="xd-upload__auth">
          <div class="xd-upload__auth-warpper">
            <el-upload
              :disabled="disabled"
              class="xd-upload__auth-ele"
              :action="uiAction"
              :name="name"
              :headers="header"
              :data="postData"
              :on-success="(file,filelist)=>{authHandleSuccess(file,filelist,0)}"
              :before-upload="beforeUpload"
              :on-progress="handleProgress"
              :on-exceed="handleExceed"
              :on-error="handleError"
              :show-file-list="false"
            >
              <div class="xd-upload__auth-ele-btn">
                <div class="border top"></div>
                <div class="border left"></div>
                <div class="border bottom"></div>
                <div class="border right"></div>
                <div
                  class="xd-upload__auth-ele-btn-img"
                  style="background: #f4f4f4"
                  v-if="authList[0] && authList[0]['path']"
                >
                  <img :src="authList[0]['path']" :alt="authList[0]['name']">
                </div>
                <div
                  v-else
                  class="xd-upload__auth-ele-btn-img"
                  :style="{backgroundImage: 'url(' + authBg['z_img'] + ')'}"
                ></div>
                <div class="xd-upload__disabled" v-if="disabled"></div>
              </div>
            </el-upload>
            <el-upload
              :disabled="disabled"
              class="xd-upload__auth-ele"
              :action="uiAction"
              :name="name"
              :headers="header"
              :data="postData"
              :on-success="(file,filelist)=>{authHandleSuccess(file,filelist,1)}"
              :before-upload="beforeUpload"
              :on-progress="handleProgress"
              :on-exceed="handleExceed"
              :on-error="handleError"
              :show-file-list="false"
            >
              <div class="xd-upload__auth-ele-btn">
                <div class="border top"></div>
                <div class="border left"></div>
                <div class="border bottom"></div>
                <div class="border right"></div>
                <div
                  class="xd-upload__auth-ele-btn-img"
                  style="background: #f4f4f4"
                  v-if="authList[1] && authList[1]['path']"
                >
                  <img :src="authList[1]['path']" :alt="authList[1]['name']">
                </div>
                <div
                  v-else
                  class="xd-upload__auth-ele-btn-img"
                  :style="{backgroundImage: 'url(' + authBg['f_img'] + ')'}"
                ></div>
                <div class="xd-upload__disabled" v-if="disabled"></div>
              </div>
            </el-upload>
          </div>
          <div v-if="showtype" slot="tip" class="xd-upload__tip">
            <slot name="tip"><span v-html="tooltip"></span></slot>
          </div>
        </div>
      </template>
      <template v-else-if="styleType==='list'">
        <div class="xd-upload__list">
          <div
            v-if="showList.length === 0"
            class="xd-upload__list-add"
            @click="handleToUpload"
            :style="{
              width: list_width + 'px',
              height: list_height + 'px',
              borderRadius: radius + 'px'
            }"
          >
            <i class="xd_admin_iconfont xdicon_shangchuantupian1"></i>
          </div>
          <draggable
            v-else
            :list="showList"
            :disabled="showList.length === 0 || !sort"
            class="xd-upload__list-box"
            :style="{minHeight: list_height + 'px'}"
            @start="dragging = true"
            @end="dragging = false"
          >
            <div
              class="xd-upload__list-item"
              v-for="(item,index) in showList" :key="item.path"
              :title="item.name"
              :style="{
                width: list_width + 'px',
                height: list_height + 'px',
                borderRadius: radius + 'px'
              }"
            >
              <xd-item-image
                :list="getImagesPreview(index)"
                :width="list_width"
                :height="list_height"
              >
              </xd-item-image>
              <i class="el-icon-delete-solid" @click="del(index)"></i>
              <span>{{item.name|fitersName}}</span>
            </div>
          </draggable>
          <el-upload
            :disabled="!(showList.length < limit) || disabled"
            class="xd-upload__list-ele"
            ref="xd-upload__list"
            :action="uiAction"
            :headers="header"
            :name="name"
            :data="postData"
            :on-success="handleSuccess"
            :before-upload="beforeUpload"
            :on-progress="handleProgress"
            :on-exceed="handleExceed"
            :on-error="handleError"
            :show-file-list="false"
            :limit="limit"
            :multiple="multiple"
          >
            <div class="xd-upload__list-btn">
              <slot>
                <el-button :disabled="!(showList.length < limit ) || disabled" size="small" type="primary">{{uploadName}}</el-button>
              </slot>
              <div class="xd-upload__disabled" v-if="disabled"></div>
            </div>
          </el-upload>
          <div v-if="showtype" slot="tip" class="xd-upload__tip">
            <slot name="tip"><span v-html="tooltip"></span></slot>
          </div>
        </div>
      </template>
    </template>
    <!--使用原上传组件-->
  </div>
</template>

<script>
  /**
   * @description 文件上传
   * 参考网站如下：
   * https://element.eleme.cn/#/zh-CN/component/installation
   * gxd-helper参考文档：https://www.npmjs.com/package/gxd-helper
   * 七牛云参考文档 https://developer.qiniu.com/kodo/1272/form-upload
   *
   * @ntioce uploadType=qiniu上传时：参数：qiniuCdnUrl，action必选  事件：onGetParamsAndHeader 必须实现
   * @ntioce uploadType=aliyun上传时：参数：action 必选  事件：onGetParamsAndHeader 必须实现
   * @ntioce uploadType=''上传时：参数：action 必选  事件：onGetParamsAndHeader，onApiSuccessUrl 必须实现
   *
   * @property {String} defaultValue 当使用styleType=auth 和styleType=list 设置默认文本数据 {选填} 默认：[]
   * @property {String} action 文件上传上传地址 {必选}  备注：type=aliyun时 可以设置为aliyuan即可
   * @property {String} name 上传文件文件参数名  {选填}  默认：file
   * @property {String} qiniuCdnUrl 七牛云静态资源方法地址 {type=qiniu时，必填}  默认：''
   * @property {String} uploadType 支持图片上传类型 {选填}  默认：''  其值： ''=>API服务上传  qiniu=>七牛云OSS上传  aliyun=> 阿里云OSS上传
   * @property {String} styleType 上传文件模式 {选填} 默认：one  其值：one=>单文件上传 auth=>证件正反面上传 list=>多文件上传
   * @property {String} uploadName 上传按钮名称 { 选填}   默认：上传
   * @property {Number} maxlen  使用多文件上传文件支持个数 {选填} 默认：100
   * @property {String} tips 上传文件大小提示文案格式  {选填}   默认：xxxx@imageType@xxxxxxxx@size@xxxx
   * @property {Array} type 上传文件类型 {选填} 默认：['jpg', 'png', 'jpeg', 'gif', 'bmp']
   * @property {Number} size 限制单个文件上传大小  {选填}  默认：5    单位：M
   * @property {Boolean} sort 列表模式是否启动排序功能 {选填}  默认：false
   * @property {String} listSize 列表模式图片显示尺寸大小 {选填}  默认：160*120
   * @property {Number} radius 图片显示圆角值  {选填}  默认：4 单位：px
   * @property {Boolean} showtype 是否显示提示文案 {选填} 默认:true
   *
   * @event {Function} onGetParamsAndHeader 上传文件前设置请求参数 回调值：resolve({params,header})
   * @event {Function} onApiSuccessUrl 本地API服务器上传成功事件（response，resolve） (本地API上传事件) 返回值：resolve(url)
   * @event {Function} success 上传文件成功 参数：（{item}）
   *
   * @slot 默认插槽：按钮插槽（one，list）
   * @slot tip插槽：提示文案插槽（one，list，''）
   *
   */
  import dialogMaterial from "@/viewsMaterial/dialogMaterial.vue";
  import XdFontIcon from "@/components/XdFontIcon.vue";
	import {Loading} from 'element-ui';
	import draggable from 'vuedraggable';
  import {authBg} from './constant';
  import { orderBy } from 'lodash';
  import XdItemImage from "@/components/XdItemImage";
  let $vm = null;


	export default {
		name: 'XdUpload',
    components: {
      XdItemImage,
      draggable,
      dialogMaterial,
      XdFontIcon
    },
		props: {
      disabled: {type: Boolean, default: false},
			defaultValue: {type:Array|Object|null,default:null},
      uploadName: {type: String, default: '上传'},
      action: {type: String, default: 'aliyun'},
      qiniuCdn: {type: String, default: ''},
      uploadType: {type: String, default: ''},
      styleType: {type: String, default: ''}, //one|list|auth|material
      name: {type: String, default: 'file'},
      maxlen: {type: Number, default: 100},
      tips: {type: String, default: '上传文件格式：@imageType@，不超过@size@MB。'},
      type: {type: Array, default() {return ['jpg', 'png', 'jpeg', 'gif', 'bmp']}},
      size: {type: Number, default: 5},
      pixelSize:{type: String, default: ''}, //现在图片大小上传
			sort: {type: Boolean, default: false},
      isMaterial: {type: Boolean|null, default: null},
			listSize:{type: String|Object, default: '160*120'},
      item: {type:Object, default() {return {}}},
      isShowDel:{type: Boolean, default: false},

			/**
       * @description 是否显示提示语
       */
			showtype: {
				type: Boolean,
				default: false
      },

			/**
			 * @description 圆角
			 */
			radius:{
				type: [Number,String],
				default: 4
      },

      //==素材库属性==============
      materialBtnName: {
        type: String,
        default: '素材库'
      },
      materialBtnType: {
        type: String,
        default: '素材库'
      },
      /**
       * @description 是否支持一次性选择多张图片
       */
      multiple: {
				type: Boolean,
				default: true
      },
    },
    filters:{
      fitersName(value = '') {
        if ($vm.$xdHelper.cutStringLen(value, 10000, 'len') < 30) return value;
        return `${$vm.$xdHelper.cutStringLen(value, 14)}...${value.substr(-6, 6)}`
      }
    },
    computed:{
      imageConfig(){
        let num = 1;

        if(this.styleType === 'list'){
          num = this.maxlen - this.showList.length;
          this.isBtnMaterialMore = this.showList.length >= this.maxlen;
        }
        if(this.styleType === 'auth'){
          num = 2;
        }

        return {
          num:num
        }
      }
    },

		data() {
			return {
				enabled: true,
        loading: null, //loading

        dsize: 40,
        fsize: 16,
        uiAction: null,
        postData:{},//上传图片传参数
        limit: 0, //上传图片个数
        progressNumber: 0, //上传进度
        tooltip: '', //提示文案
        header: {}, //设置header
        sourceUploadList: {}, //保存上传文件原始files

        //单文件上传
        oneItem: '', //单文件绑定数据


        //证件正反面上传
        authBg, //背景图片
        authList: ['', ''], //证件正反面绑定数据

        //多文件上传
        showList: [], //展示数据
        list: [], //单次上传图片
        currentUploadLength: [],
        uploadCount: 0, //添加文件个数
        dragging: false,
        list_width: 120, //列表显示模式宽度
        list_height: 90, //列表显示模式高度

        //素材库
        isInMaterial: false,
        isDialogShow: false,
        materialNotIgnore:[ 'jpg', 'jpeg', 'gif','png','bmp'], //可以唤起图片素材库的扩展名字
        isBtnMaterialMore: false,
			};
		},

    watch:{
      currentUploadLength(val){
		    if(this.uploadCount === val.length && this.loading) {
          this.loading.close();
          this.showList = this.showList.concat(this.$xdHelper.cloneDeep(this.list));
          this.list = [];
          this.update(this.showList);
        }
      },
      tips(){
        this.setTips();
      },
      isDialogShow(value){
        console.warn('isDialogShow' + value);
      }
    },

    created(){
      this.uiAction = this.action;
      $vm = this;

      //系统设置是否启用素材库
      if(typeof this.$setting.isMaterial === 'boolean') {
         this.isInMaterial = this.$setting.isMaterial;
      }

      //组件自己启用素材库
      if(typeof this.isMaterial === 'boolean') this.isInMaterial = this.isMaterial;

      //只有特定类型可以使用素材库
      if(this.isInMaterial) {
        this.isInMaterial = this.checkMaterialNotIgnore();
      }

      //证件照上传不可使用素材库
      if(this.styleType === 'auth') {
        this.isInMaterial = false;
      }

      //设置内容
      this.setContent();
      this.setTips();


			//设置上传图片个数
			this.limit = 1;

			if(this.styleType === 'list') {
        this.limit = this.maxlen;
        let listSizeArr = this.listSize.split('*');
        this.list_width = Number(listSizeArr[0]);
        this.list_height = Number(listSizeArr[1]);
        this.dsize = this.list_width * 40 / 100;
        this.fsize = this.list_width * 16 / 100;
      }
    },

		methods: {
      handleDialogShow(){

        if(this.isInMaterial) {
          if(this.disabled === false) this.isDialogShow = true;
        }
      },
      /**
       * @description 判断将要上传文件类型是不是属于图片类型
       * @return {boolean} true => 是 false=>不是（将使用原来上传模式）
       */
      checkMaterialNotIgnore(){
        //合并系统设置唤起素材库扩展名字
        let systemArr = this.$setting.materialNotIgnore||[].map(item=>{
          return item.toLocaleLowerCase()
        });

        //组件设置唤起素材库扩展名字
        let notIgnoreArr = this.$xdHelper.repeatArray(this.materialNotIgnore.concat(systemArr)).map(item=>{
          return item.toLocaleLowerCase();
        });

        let cur = this.type.map(item=>{
           return item.toLocaleLowerCase()
        });

        //判断将要上传文件类型是不是属于图片类型
        let temp = [];
        cur.map(ext=>{
          let t = false;
          notIgnoreArr.map(item=>{
            if(ext === item) t = true
          });
          if(t === false) temp.push(ext)
        });

        return temp.length === 0;
      },

      /**
       * @description 素材选中处理
       * @param items {Array} 选中对象
       */
      handleMaterial(items=[]){
        //单张处理
        if(this.styleType === 'one') {
          let temp = items[0];
          this.oneItem = {
            url: temp['url'] || temp['file_src'],
            name: temp['name'] || temp['file_name'],
            uid: temp['uid'] || temp['file_id'],
            path: !temp.path?this.getImageFullPath(temp.url):temp.path
          };
          this.update(this.oneItem);
        }

        //列表处理
        else {
          let list = items.map(item=>{
            return {
              url: item['url'] || item['file_src'],
              name: item['name'] || item['file_name'],
              uid: item['uid'] || item['file_id'],
            }
          });
          this.showList = this.$xdHelper.cloneDeep(this.showList).concat(list).map((item)=>{
            return {
              path: !item.path?this.getImageFullPath(item.url):item.path,
              ...item
            }
          });
          this.update(this.showList);
        }

      },

      setTips(){
        //设置提示文案
        let tips = this.tips.replace('@imageType@',`<span style="color: #c00"> ${this.type.join('/').toLocaleUpperCase()} </span>`);
        tips = tips.replace('@size@', `<span style="color: #c00"> ${this.size} </span>`);
        if(this.pixelSize){
          tips = tips.replace('。', '@pixelSize@。');
          if(this.pixelSize.indexOf('*') === -1) {
            tips = tips.replace('@pixelSize@',`建议图片宽度：<span style="color: #c00"> ${this.pixelSize} </span>像素`);
          } else tips = tips.replace('@pixelSize@',`建议尺寸：<span style="color: #c00"> ${this.pixelSize} </span>像素`);
        }
        if(this.styleType === 'list') {
          tips = tips.replace('。', '@num@。');
          tips = tips.replace('@num@', `，最大上传文件数:<span style="color: #c00"> ${this.maxlen} </span>张`);
        }

        this.tooltip = tips;
      },
      delOne(){
        this.oneItem = '';
        this.$emit('input', this.oneItem);
      },
      handleToUpload() {
        this.$refs['xd-upload__list'].$children[0].$refs.input.click()
      },

      /**上传文件之前处理********==========================*/
      /**
       * @description 上传图片之前处理
       * @param file
       * @returns {Promise<unknown>}
       */
      beforeUpload(file) {
        this.$set(this.sourceUploadList, file.uid, file);
        const isLt2M = file.size / 1024 / 1024;
        return new Promise((resolve, reject) => {
          this.isImageInfo(file)
            .then((res) => {
              //判断文件大小
              if (isLt2M > this.size) {
                this.message(`上传文件大小: ${this.size} MB, 当前上传文件: ${isLt2M.toFixed(2)}MB.`);
                reject();
                return;
              }

              //判断文件格式
              if (!this.checkFile(file)) {
                this.message(`上传文件格式: ${this.type.join('/').toLocaleUpperCase()} .`);
                reject();
                return;
              }

              //尺寸限定
              if(this.pixelSize) {
                let sizeArr = this.pixelSize.split('*');
                let width, height, status = true;
                if(sizeArr.length === 1) {
                  width = Number(sizeArr[0]);
                }
                if(sizeArr.length ===2) {
                  width = Number(sizeArr[0]);
                  height = Number(sizeArr[1]);
                }

                //只需要宽度有值急需要判断
                if(width) {
                  if(width !== res.width) status = false
                  if(height && (height !== res.height)) status = false;
                }
                if(!status){
                  this.message(`上传文件尺寸不一致，上传图片尺寸为：${res.width}*${res.height}，限定尺寸为:${this.pixelSize}`);
                  return;
                }
              }

              /**
               * @description 阿里OSS使用PostObject直接上传
               * 参考：https://help.aliyun.com/document_detail/31988.htm?spm=a2c4g.11186623.0.0.26885d3fh1AjJF#reference-smp-nsw-wdb
               * @param params { Object } 阿里oss对象相关参数对象
               * @param params.OSSAccessKeyId {String} Bucket拥有者的AccessKey ID {必填}
               * @param params.action  {String} 图片上传OSS地址 {必填}
               * @param params.key {String} 上传Object的名称。如果名称包含路径 {必填}
               * @param params.cdnUrl  {String} 图片上传之后访问地址 {必填}
               * @param params.policy {String} Policy规定了请求表单域的合法性。不包含Policy表单域的请求被认为是匿名请求，并只能访问public-read-write的Bucket {必填}
               * @param params.signature  {String} 根据AccessKey Secret和Policy计算的签名信息，OSS验证该签名信息从而验证该Post请求的合法性 {必填}
               * @param params.expire {Date} 过期时间 {选填}
               * @param params.name {String} 文件名称 {选填}
               * @param params.success_action_status  {String} 未指定success_action_redirect表单域时，该表单域指定了上传成功后返回给客户端的状态码 {选填}
               */
              /**
               * @description 获取上传文件所需要参数设置
               * @param params 参数设置
               * @param header 头信息设置
               */
              this.$emit('onGetParamsAndHeader', file, ({params, header})=>{
                if (this.uploadType === 'aliyun') {
                  this.uiAction = params.action;
                  this.$set(this.sourceUploadList, file.uid, {...file, aliyun: params, ...res});
                }
                if (params) this.postData = this.$xdHelper.cloneDeep(params);
                if(header) this.header = header;
                if(this.styleType !== 'list') this.loading = Loading.service({});
                resolve()
              });
            });
        })
      },

      /***
       * @description 检测文件格式
       */
      checkFile(file) {
        let type = this.type.map(item=>{
          return item.toLocaleLowerCase()
        });
        let regName = new RegExp(`^.*\\.(${type.join('|')})$`);
        let regType = new RegExp(`(${type.join('|')})`);

        //检测name中是否有指定文件类型
        if (regName.test(file.name)) {
          return true
        }

        //检测type中是否有指定文件类型
        return regType.test(file.type);

      },

      isImageInfo(file) {

        //图片格式
        if(file.type.indexOf('image/') === 0) {
          return new Promise((resolve, reject) => {
            let reader = new FileReader();
            reader.onload = (evt) => {
              let image = new Image();
              image.onload = (e) => {
                resolve({
                  type:'image',
                  width: image.width,
                  height: image.height,
                  size: file.size,
                  typeOrg:file.type,
                  dataURL: evt.target,
                })
              };
              image.onerror = (err) => {
                reject(err)
              };
              image.src = evt.target['result'];
            };
            reader.readAsDataURL(file);
          });
        }

        //视频格式
        if(file.type.indexOf('video/') === 0) {
          return  new Promise((resolve, reject)=>{
            let reader = new FileReader();
            reader.onload = (evt) => {
              let video = document.createElement('video');
              video.onloadedmetadata = (e) => {
                resolve({
                  type:'video',
                  width: video.videoWidth,
                  height: video.videoHeight,
                  size: file.size,
                  typeOrg:file.type,
                  dataURL: evt.target,
                });
              };
              video.onerror = (err) => {
                resolve({
                  type:'video',
                  width: 0,
                  height: 0,
                  size: file.size,
                  typeOrg:file.type,
                  dataURL: evt.target,
                });
              };
              video.src = evt.target['result'];
            };
            reader.readAsDataURL(file);
          })
        }

        //文件格式
        if (!this.$xdHelper.inArray(this.imageType, [file.type])) {
          return new Promise((resolve) => {
            resolve({
              type:'file',
              size: file.size,
              typeOrg:file.type,
            });
          })
        }

      },
      /**上传文件之前处理********==========================*/


      /**文件上传成功处理*******************===============*/

      /**
       * @description 设置七牛返回数据格式
       * @param result
       * @param file
       */
      getQiniuImage(result, file) {
        if(result.key.indexOf('/') !== 0) {
          result.key = `/${result.key}`
        }
        return {
          path: this.getImageFullPath(result.key),
          url: `${result.key}`,
          name: file['name'],
          uid: file['uid'],
          hashKey: result.key
        }
      },

      stringToNumber(str) {
        let result = 0;
        let len = str.length;
        for (let i = 0; i < len; i++) {
          result = result + str.charCodeAt(i) + i;
        }
        return result;
      },

      getImageFullPath(url) {
        let reg = /^(http:\/\/|https:\/\/|\/\/)+.+$/;
        if (reg.test(url)) return url;

        if (Object.prototype.toString.call(url) !== '[object String]' || url === '') {
          console.error('传入的路径（path）非字符串类型，请确认路径是否正确');
          throw new Error('传入的路径（path）非字符串类型，请确认路径是否正确');
        }
        if(!this.$setting.cdnBaseUrl) {
          console.error('请设置静态图片访问基础路径（this.$setting.cdnBaseUrl）');
          throw new Error('请设置静态图片访问基础路径（this.$setting.cdnBaseUrl）');
        }
        let index = this.stringToNumber(url) % (this.$setting.cdnLen || 6);
        let doMain = this.$setting.cdnBaseUrl.replace('@index@', index === 0 ? '' : index);
        return `${doMain}${url}`;
      },

      /**
       * @description 设置七牛返回数据格式
       * @param file
       */
      getAliYunImage(file) {
        let item = {};
        let oss = this.sourceUploadList[file['uid']]['aliyun'];
        let url = `/${oss['key']}`;
        let path = '';
        if(this.$setting.uploadBackType && this.$setting.uploadBackType === 'old'){
          url = oss['cdnUrl'];
          path = oss['cdnUrl'];
        }else{
          path = this.getImageFullPath(url);
        }

        item['url'] = url;
        item['path'] = path + '?v=' + Date.now();
        item['name'] = oss['name'];
        item['uid'] = file['uid'];
        if (oss['id']) item['id'] = oss['id'];
        return item;
      },

      /**
       * @description 设置API上传到服务器返回数据格式
       * @param result
       * @param file
       * @param callback
       */
      getApiImage(result, file, callback){
        this.$emit('onApiSuccessUrl', result, url => {
          let item = {};
          item['url'] = url;
          item['name'] = file['name'];
          item['uid'] = file['uid'];
          callback(item)
        })

      },

      /**
       * @description 多文件上传成功处理
       * @param result
       * @param file
       */
      handleSuccess(result, file) {
        console.log('handleSuccess.file', result, file);

        //七牛相关配置
        if (this.uploadType === 'qiniu') {
          let item = this.getQiniuImage(result, file);
          this.currentUploadLength.push(item);
          this.list.push(item);
          let temp = this.$xdHelper.cloneDeep(this.list);
          this.list = orderBy(temp, ['name'], ['asc']);
        }

        //阿里OSS
        else if (this.uploadType === 'aliyun') {
          let item = this.getAliYunImage(file);
          this.currentUploadLength.push(item);
          this.list.push(item);
          let temp = this.$xdHelper.cloneDeep(this.list);
          this.list = orderBy(temp, ['name'], ['asc']);
        }

        //本地存储配置
        else {
          this.getApiImage(result, file, (item)=>{
            this.currentUploadLength.push(item);
            this.list.push(item);
            let temp = this.$xdHelper.cloneDeep(this.list);
            this.list = orderBy(temp, ['name'], ['asc']);
          });

        }
      },


      /**
       * @description 单文件上传成功处理
       * @param result 后端返回值
       * @param file 当前上传文件对象
       */
      handleOneSuccess(result, file){

        //七牛相关配置
        if (this.uploadType === 'qiniu') {
          this.update(this.getQiniuImage(result, file), []);
          this.loading.close();
        }

        //阿里OSS
        else if (this.uploadType === 'aliyun') {
          this.update(this.getAliYunImage(file), []);
          this.loading.close();
        }

        //本地存储配置
        else {
          this.getApiImage(result, file, (item) => {
            this.update(item, []);
            this.loading.close();
          })
        }
      },


      /**
       * @description 证件照片正反面上传成功处理
       * @param result 后端返回值
       * @param file 当前上传文件对象
       * @param index 上传文件位置
       */
      authHandleSuccess(result, file, index) {

        //七牛相关配置
        if (this.uploadType === 'qiniu') {
          let item = this.getQiniuImage(result, file);
          this.authList.splice(index, 1, item);
          this.update(this.authList, []);
          this.loading.close();
        }

        //阿里OSS
        else if (this.uploadType === 'aliyun') {
          let item = this.getAliYunImage(file);
          this.authList.splice(index, 1, item);
          this.update(this.authList, []);
          this.loading.close();
        }

        //本地存储配置
        else {
          this.getApiImage(result, file, (item)=>{
            this.authList.splice(index, 1, item);
            this.update(this.authList, []);
            this.loading.close();
          })
        }
      },

      getSizeInfo(item){
        if(!(item instanceof Array)) item = [item];
        item.map(it=>{
          if(this.sourceUploadList[it.uid]) {
            let temp = this.sourceUploadList[it.uid];

            //图片可以获取宽高
            //标准模式视频模式可以获取宽高，非无法获取
            if(temp.type === 'image' || temp.type === 'video') {
              it['width'] = temp['width'];
              it['height'] = temp['height'];
            }

            it['size'] = temp['size'];
            it['type'] = temp['typeOrg'];
          }
        });
        return item;
      },

      /**
       * @description 上传成功处理
       * @param item 当前上传处理结果
       * @return Object|array one=>Object list|auth = Array
       */
      update(item){
        //单个文件处理
        if(this.styleType === 'one'
          && this.$xdHelper.checkVarType(item) === 'object'
          && !this.$xdHelper.isEmpty(item)
        ) {
          let uid = item.uid;
          let name = item.name;
          if (!item.uid) uid = this.$xdHelper.randomChar(20);
          if (!item.name) {
            name = this.$xdHelper.parseURL(item.url).file;
          }
          item = this.oneItem = { ...item, path: this.getImageFullPath(item.url), name, uid};
          if(item.path && item.path.indexOf('?ver=') === -1)  {
            item.path  = item.path + '?ver=' + item.uid
          }
        }



        //设置图片尺寸
        item = this.getSizeInfo(item);
        if(this.styleType === 'one') item = this.$xdHelper.cloneDeep(item[0]);

        //列表发上变化
        if(this.styleType === 'list') {
          this.isBtnMaterialMore = this.showList.length >= this.maxlen;
        }


        this.$emit('input', item);
        this.$emit('success', {item});
      },
      /**文件上传成功处理*******************===============*/

			setContent() {
			  //单图
        if(this.styleType === 'one') {
          if(this.$xdHelper.checkVarType(this.defaultValue) === 'object') {
            if(this.$xdHelper.isEmpty(this.defaultValue))  this.update('');
            else this.update(this.$xdHelper.cloneDeep(this.defaultValue));
          }
          else {
            this.update('');
          }

        }

        //认证图
        if(this.styleType === 'auth'
          && this.defaultValue !== null
          && this.$xdHelper.checkVarType(this.defaultValue) === 'array'
          && this.defaultValue.length > 0
        ) {
          this.authList = this.$xdHelper.cloneDeep(this.defaultValue.slice(0, 2)).map(item => {
            let uid = item.uid;
            let name = item.name;
            if (!item.uid) uid = this.$xdHelper.randomChar(20);
            if (!item.name) {
              name = this.$xdHelper.parseURL(item.url).file;
            }
            return {...item, path: this.getImageFullPath(item.url), name, uid};
          });
          this.update(this.authList);
        }

        //列表
        if (this.styleType === 'list'
          && this.defaultValue !== null
          && this.$xdHelper.checkVarType(this.defaultValue) === 'array'
          && this.defaultValue.length > 0
        ) {
          this.showList = this.$xdHelper.cloneDeep(this.defaultValue).map(item=>{
            let uid = item.uid;
            let name = item.name;
            if (!item.uid) uid = this.$xdHelper.randomChar(20);
            if (!item.name) {
              name = this.$xdHelper.parseURL(item.url).file;
            }
            return {...item, path: this.getImageFullPath(item.url), name, uid};
          })

          this.update(this.showList);
        }
			},


			del(index){
				let item = this.showList.splice(index,1);

        //原上传功能处理
        if(this.isInMaterial === false) {
          let file = this.$refs['xd-upload__list'].uploadFiles.filter(it=>{
            return item[0].uid === it.uid;
          });
          this.currentUploadLength = this.currentUploadLength.filter(it=>{
            return item[0].uid !== it.uid
          });
          if(file.length > 0) {
            this.$refs['xd-upload__list'].handleRemove(file[0]);
          }
        }


				this.update(this.showList)
      },


			/**
       * @description 删除失败
			 * @param err
			 */
			handleError(err){
			  console.log('handleErrorF',err)
				let message = '上传文件失败！';
				try {
          let res = JSON.parse(err.stack.split("\n")[0].split('Error: ')[1]);
          message = res.message;
				}catch (e) {
					 message = '上传文件失败！';
				}
				this.message(message || '上传文件失败！','error');
				this.loading.close();
      },


			/**
       * @description 上传进度事件
			 * @param event
			 * @param file
			 * @param fileList
			 */
			handleProgress(event, file, fileList){

			  //列表处理
			  if(this.styleType === 'list') {
          this.uploadCount = fileList.length;
          this.loading = Loading.service({});
        }

				this.progressNumber = event.percent;
				if(event.percent === 100) {
					this.progressNumber = 0
        }
        this.$emit('progress', {event, file, fileList})
      },

			/**
       * @description 上传限制事件
			 * @param files
			 * @param fileList
			 */
			handleExceed(files, fileList) {
				this.message(`当前限制选择 ${this.maxlen} 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`)
			},

      getImagesPreview(index){

        let list = this.$xdHelper.cloneDeep(this.showList);
        let right = list.splice(0,index);
        let temp = [];
        list.concat(right).map(item=>{
          temp.push(item.path)
        });
        return temp;
      },

      message(message, type= 'error', show = true){
				this.$message({
					showClose: show,
					message: message,
					type: type,
					duration:2000,
				});
      }
		}
	}
</script>

<style scoped lang="scss">
  .xd-upload {
    position: relative;

    .flex {
      display: inline-block;
      position: relative;

    }

    &__auth {
      &-ele {
        height: 120px;
        &-btn {
          position: relative;
          width: 180px;
          height: 120px;
          background: #f4f4f4;

          & > .border {
            position: absolute;
            width: 20px;
            height: 20px;
            border: 2px dashed #00a9e1;
            z-index: 4;
          }

          & > .border.right {
            top: -1px;
            right: -2px;
          }

          & > .border.left {
            top: -1px;
            left: -2px;
          }

          & > .border.bottom {
            bottom: -1px;
            right: -2px;
          }

          & > .border.top {
            bottom: -1px;
            left: -2px;
          }

          &-img {
            width: 100%;
            height: 100%;
            background-size: 100%;
            background-position: center;
            background-repeat: no-repeat;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 5;

            & > img {
              max-height: 100%;
              max-width: 100%;
            }
          }
        }
      }

      &-warpper {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        margin-bottom: 10px;

        & > * {
          margin-right: 20px;
        }
        & > *:last-child {
          margin-right: 0;
        }
      }

    }

    &__list {

      &-add {
        background: #efefef;
        border: 1px dashed #ccc;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        margin-bottom: 25px;

        & i {
          font-size: 50px;
          color: #999;
        }
      }

      &-box {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: wrap;
        margin-bottom: 15px;
      }

      &-item {
        margin-right: 10px;
        margin-bottom: 10px;
        position: relative;
        overflow: hidden;

        & > i {
          position: absolute;
          right: 5px;
          top: 5px;
          opacity: .2;
          color: #999;
        }

        &:hover i {
          transition: opacity .5s;
          opacity: 1;
        }

        & > span {
          position: absolute;
          left: 0;
          right: 0;
          bottom: 0;
          background: rgba(0,0,0,.5);
          color: #fff;
          font-size: 12px;
          line-height: 16px;
          padding: 5px 5px;
          word-break: break-all;
          word-wrap: break-word;
          white-space: pre-line;
        }
      }
    }

    &__tip {
      font-size: 14px;
      padding-top: 10px;
      line-height: 24px;
    }

    &__one {
      &-btn {
        position: relative;
        overflow: hidden;
        cursor: pointer;
        &-del {
          position: absolute;
          top: 0;
          right: 0;
          width: 30px;
          height: 30px;
          display: flex;
          justify-content: center;
          align-items: center;
          opacity: 0;
        }
        &:hover{
          & > .xd-upload__one-btn-del {
            opacity: 0.8;
            & i.el-icon-delete {
              color: #000;
            }
          }
        }

      }
    }

    &__disabled {
      position: absolute;
      top:0;
      left:0;
      bottom: 0;
      right: 0;
      background: rgba(220, 220, 220, 0.1);
      z-index: 10000;
      cursor: not-allowed;
    }
  }

  @media screen and (max-width: 768px) {
    .xd-upload {
      &__list {
        &-add {
          margin-bottom: 15px;
        }
        &-box {
          margin-bottom: 5px;
        }
      }
    }
  }

  .upload_one_m {


  }

</style>
