Source: packages/UpLoadFile/PUpLoadFile.vue

<!--  -->
<template>
  <div class="upload-file-con">
    <div v-if="action[config_.model].indexOf(1) >= 0" class="card-item">
      <ImgGroup
        :vhas="vhas"
        v-if="ImgGroupConfig.card1.show && ImgGroupConfig.card1.url"
        class="img-group"
        :value="[ImgGroupConfig.card1.url]"
        :showDeleBtn="!config_.readonly"
        :deleteEvent="
          (item, index) => {
            ImgGroupEvent('card1', item, index);
          }
        "
      ></ImgGroup>
      <img v-if="getShowBG" src="./svg/身份证正面.svg" class="card-item-bg" />
      <a-upload
        v-bind="uploadAttr"
        ref="card1"
        class="upload"
        :multiple="false"
        :disabled="config_.readonly"
        :customRequest="(action) => customRequestEvent_(action, 'card1')"
        :beforeUpload="
          (...args) => {
            beforeUploadEvent('card1', ...args);
          }
        "
        :defaultFileList="config_.defaultFileList['card1']"
      >
        <a-button> <a-icon type="upload" /> </a-button>
      </a-upload>
      <div
        v-if="tipConfig.card1.show"
        :class="[
          'tip-msg animate__animated',
          tipConfig.card1.show && 'animate__shakeX',
        ]"
      >
        {{ tipConfig.card1.msg }}
      </div>
      <!-- 提示信息 -->
      <!-- v-if="!ImgGroupConfig.card1.show&&!tipConfig.card1.show && !ImgGroupConfig.card1.url && config_.tips.card1" -->
      <div  v-if=" !tipConfig.card1.show && !ImgGroupConfig.card1.url && config_.tips.card1" class="tip-msg msg" v-html="config_.tips.card1"></div>
    </div>
    <div v-if="action[config_.model].indexOf(2) >= 0" class="card-item">
      <ImgGroup
        :vhas="vhas"
        v-if="ImgGroupConfig.card2.show && ImgGroupConfig.card2.url"
        class="img-group"
        :value="[ImgGroupConfig.card2.url]"
        :showDeleBtn="!config_.readonly"
        :deleteEvent="
          (item, index) => {
            ImgGroupEvent('card2', item, index);
          }
        "
      ></ImgGroup>
      <img v-if="getShowBG" src="./svg/身份证背面.svg" class="card-item-bg" />
      <a-upload
        v-bind="uploadAttr"
        ref="card2"
        class="upload"
        :multiple="false"
        :disabled="config_.readonly"
        :customRequest="(action) => customRequestEvent_(action, 'card2')"
        :beforeUpload="
          (...args) => {
            beforeUploadEvent('card2', ...args);
          }
        "
        :defaultFileList="config_.defaultFileList['card2']"
      >
        <a-button> <a-icon type="upload" /> </a-button>
      </a-upload>
      <div
        v-if="tipConfig.card2.show"
        :class="[
          'tip-msg animate__animated',
          tipConfig.card2.show && 'animate__shakeX',
        ]"
      >
        {{ tipConfig.card2.msg }}
      </div>
       <!-- 提示信息 -->
       <div  v-if="!tipConfig.card2.show && !ImgGroupConfig.card2.url && config_.tips.card2" class="tip-msg msg" v-html="config_.tips.card2"></div>
    </div>

    <div
      v-if="action[config_.model].indexOf(3) >= 0"
      class="card-item card-item-list"
    >
      <div class="card-item-upload">
        <img v-if="getShowBG" src="./svg/身份证背面.svg" class="card-item-bg" />
        <a-upload
          v-bind="uploadAttr"
          ref="card3"
          class="upload"
          :multiple="true"
          :disabled="config_.readonly"
          :customRequest="(action) => customRequestEvent_(action, 'card3')"
          :beforeUpload="
            (...args) => {
              beforeUploadEvent('card3', ...args);
            }
          "
          :defaultFileList="config_.defaultFileList['card3']"
        >
          <a-button> <a-icon type="upload" /> </a-button>
        </a-upload>
        <div
          v-if="tipConfig.card3.show"
          :class="[
            'tip-msg animate__animated',
            tipConfig.card3.show && 'animate__shakeX',
          ]"
        >
          {{ tipConfig.card3.msg }}
        </div>
         <!-- 提示信息 -->
         <!-- !tipConfig.card3.show && !ImgGroupConfig.card3.url && config_.tips.card3 -->
      <div  v-if=" !tipConfig.card3.show && config_.tips.card3" class="tip-msg msg" v-html="config_.tips.card3"></div>
      </div>
      <div class="card-item-list-con">
        <ImgGroup
          :vhas="vhas"
          v-if="ImgGroupConfig.card3.show"
          :value="[...ImgGroupConfig.card3.url]"
          :showDeleBtn="!config_.readonly"
          :deleteEvent="
            (item, index) => {
              ImgGroupEvent('card3', item, index);
            }
          "
        ></ImgGroup>
      </div>
    </div>
  </div>
</template>

<script>
import ImgGroup from "../ImgGroup";
import FileType from "./utils/fileTypeNew";
import IS from "../utils/is";
import UUID from "../utils/uuid";
import { getCaptionFileName, getFileOldName } from "../utils/util";

 /**
   * PUpLoadFile 附件上传  使用方法  <p-UpLoadFile  :config="{}" v-model="{}" :customRequestEvent="PUpLoadFileCustomRequestEvent"></p-UpLoadFile>
   * 
   * @vue-prop {Object} config - 此项必传;上传组件的配置 eg:{dir:'', model:'', showBG:false, readonly:false, tips:{}, required:false, defaultFileList:{card1:{},card2:{},card3:[]}, fielConfig:{type:'',size:1,singleFileSize:1}} <br/> dir  此参数必填  上传路径;
   * @vue-prop {Object} value - 用于vModel 会根据【model】的值来确定此值的内容,如: 身份证=>{card1:{url:'',name:''},card2:{url:'',name:''}}   单文件=>{card1:{url:'',name:''}}  多文件 => {card3:{url:'',name:''}}
   * @vue-prop {Function} customRequestEvent -  此参数必填  自定义事件  有公共方法可以调用(PUpLoadFileCustomRequestEvent, 此方法为全局混入方法),不必自己写,直接照抄
   * @vue-prop {Object} uploadAttr -   此参数选填 此属性表示 upload 组件原本属性集合  具体使用可查询官网 
   * @vue-prop {Array<Object>} extendedFileVerification -    此参数选填 扩展文件校验 eg:  [{ 'groupName':'文档', suffixArr:['xlsx', 'xls', 'pptx', 'ppt', 'pdf', 'doc', 'docx', 'txt'],errorMsg:'只允许上传 PDF,DOC,DOCX,XLS,XLSX 类型文件' }]
   * @vue-prop {String} vhas -    用于授权
   * @vue-prop {Boolean} [isShowWatermark=true] -    表示是否在上传会显得时候显示水印  默认显示
   */
export default {
  name: "PUpLoadFile",
  components: { ImgGroup },
  props: {
    /**
     * 用于按钮权限控制
     * @prop {string} vhas - 用于按钮权限控制
     */
    vhas:{type:String},
    /**
     * 用于上传文件的配置
     * @prop {Object} config - 用于上传文件的配置
     */
    config: {
      type: Object,
      required: true,
      default: () => {
        return {
          dir: "",
          model: "单文件",
          showBG: false, // 此属性只在 model= 身份证 时 启用
          readonly: false,
          required: false, // 文件上传必填校验 默认为false 不校验   当值为true时进行强制校验
        };
      },
    },
    // 表示是否在上传会显得时候显示水印  默认显示
    isShowWatermark:{type:Boolean, default: () => { return true }},
    // 用于vModel 
    value: { type: Object },
    // 自定义事件
    customRequestEvent: { type: Function },
    // 此属性表示 upload 组件原本属性集合
    uploadAttr: {
      type: Object,
      default: () => {
        return {
          // accept:'',
          // action: "string|(file) => Promise",
          method: "post",
          directory: false,
          // beforeUpload:'(file, fileList) => boolean | Promise',
          // customRequest:'Function',
          // data:'object|(file) => object',
          // defaultFileList:'object[]',
          disabled: false,
          // fileList:'',
          // headers:'',
          listType: "text",
          // multiple:false,
          name: "file",
          // previewFile:'',
          showUploadList: false,
          supportServerRender: false,
          withCredentials: false,
          openFileDialogOnClick: true,
          // remove:'Function(file): boolean | Promise',
          // transformFile:'Function(file): string | Blob | File | Promise<string | Blob | File>',
        };
      },
    },
    // 扩展文件校验 eg:  [{ 'groupName':'文档', suffixArr:['xlsx', 'xls', 'pptx', 'ppt', 'pdf', 'doc', 'docx', 'txt'],errorMsg:'只允许上传 PDF,DOC,DOCX,XLS,XLSX 类型文件' }]
    extendedFileVerification: { type: Array },
    showHelp:{type:Boolean, default: () => { return false }}
  },
  data() {
    // 这里存放数据
    // https://zxcloud-test.oss-cn-hangzhou.aliyuncs.com/user/license/1688540243642_%E5%8A%9E%E5%85%AC.png
    // https://zxcloud-test.oss-cn-hangzhou.aliyuncs.com/user/license/1688540248058_%E5%8C%97%E4%BA%AC2.png
    // https://zxcloud-test.oss-cn-hangzhou.aliyuncs.com/user/task/settlementDocument/1687748548983_1234567890.xlsx
    return {
      tipConfig: {
        card1: {
          show: false,
          msg: "",
        },
        card2: {
          show: false,
          msg: "",
        },
        card3: {
          show: false,
          msg: "",
        },
      },
      ImgGroupConfig: {
        card1: {
          show: false,
          url: "",
          showDeleBtn: false,
        },
        card2: {
          show: false,
          url: "",
          showDeleBtn: false,
        },
        card3: {
          show: false,
          url: [],
          showDeleBtn: false,
        },
      },
      config_: {
        dir: "",
        tips:{
          card1: '这是提示信息',
          card2: '这是提示信息',
          card3: '这是提示信息',
        },
        model: "", // 单文件  多文件 身份证 all
        // 表示是否显示card的背景图; true 表示显示;false 表示不显示; 在 model 的值为 【身份证】 时 此属性会被启用
        showBG: false,
        required: false, // 文件上传必填校验 默认为false 不校验   当值为true时进行强制校验
        // 表示是否允许上传
        readonly: false,
        // 要回显的数据 card1 card2 的值的格式为:{name:'',url:''} ;  card3 的值的格式为 [{name:'',url:''},{name:'',url:''}]
        defaultFileList: {
          card1: [],
          card2: [],
          card3: [],
        },
        fielConfig: {
          type: "", // 允许上传的文件类型 当为空时表示不限制  默认为空   可供选择类型: 图片  文档  压缩包  发票  eg: 当值为string类型时,对所有(card1,card2,card3)的有效; 当值为对象({"card1":'图片',"card2":'文档', "card3":'PDF'})时,可指定每个(card1/card2/card3)所对应的类型
          size: 1, // 允许上传的文件个数  默认值为1    eg: 1 表示只允许上传1个文件;  当值为对象({"card1":1,"card2":2, "card3":3})时,可指定每个(card1/card2/card3)所对应的类型
          singleFileSize: 1, //上传的单个文件大小 单位为 MB  默认值为1 eg: 当值为 number 时,对所有(card1,card2,card3)的有效; 当值为对象({"pdf":5,"xlsx":10, "zip":100})时,可指定对应的文件类型的大小(单位:MB)
        },
      },
      action: {
        单文件: [1],
        多文件: [3],
        身份证: [1, 2],
        all: [1, 2, 3],
      },
      fileCheckRes: {
        card1: false,
        card2: false,
        card3: false,
      },
      tempFileInfo: [],
    };
  },
  computed: {
    getShowBG() {
      let res = false;
      const model_ = this.config_.model;
      if (model_ === "身份证") {
        res = true;
        if (this.config_.showBG === false) {
          res = false;
        }
      }
      return res;
    },
  },
  watch: {
    config: {
      handler(val) {
        if (IS.isObject(val)) {
          const tempObj = Object.assign({}, this.config_, val);
          this.setdefaultFileList(tempObj.defaultFileList, tempObj.model);
          tempObj.defaultFileList = this.setConfigDefaultFileList(tempObj.defaultFileList);
          this.config_ = tempObj;
        }
      },
      deep: true,
      immediate: true,
    },
    ImgGroupConfig: {
      handler(val) {
        this.getFilesForUploadChange(val);
      },
      deep: true,
      immediate: true,
    },
  },
  created() {},
  mounted() {
    if(this.$isShowHelp == true &&  this.showHelp === true){
        console.log(`
        组件名称:
          PUpLoadFile
        使用方法:
            <p-UpLoadFile  :config="{}" v-model="{}" :customRequestEvent="PUpLoadFileCustomRequestEvent"></p-UpLoadFile>
        props参数说明:
            props: {
              config: {
                type: Object,
                required: true,
                default: () => {
                  return {
                    // 此参数必填  上传路径
                    dir: "",
                    // 身份证  all   ;  单文件 对应 card1 ;   多文件 对应  card3 ; 身份证  对应  card1(身份证正面)、card2(身份证反面)
                    model: "单文件",
                    // 此参数选填   此属性只在 model= 身份证 时 启用   默认值文false
                    showBG: false, 
                    // 此参数选填  表示是否可编辑 
                    readonly: false,
                    // 提示信息
                    tips:{
                      card1: '这是提示信息',
                      card2: '这是提示信息',
                      card3: '这是提示信息',
                    },
                    // 此参数选填   文件上传必填校验 默认为false 不校验   当值为true时进行强制校验  需要配合【getDataCheckRes】方法使用;  
                    // 方法【getDataCheckRes】的具体用法如: this.$refs.UpLoadFile.getDataCheckRes({ card1: "请上传身份证正面",card2: "请上传身份证反面", card3: "请上传附件"});
                    // 其中 【getDataCheckRes】的参数辨识检验不通过时对应的提示信息;card1、card2、card3均可缺省,也可选填对应的字段    此参数可空 
                    required: false, 
                    // 此参数选填   要回显的数据 card1 card2 的值的格式为:{name:'',url:''} ;  card3 的值的格式为 [{name:'',url:''},{name:'',url:''}]
                    defaultFileList: {
                      card1: {},
                      card2: {},
                      card3: [],
                    },
                    // 此参数集必填  
                    fielConfig: {
                      // 允许上传的文件类型 当为空时表示不限制  默认为空   
                      //    可供选择类型: 
                      //          图片('jpg', 'png', 'jpeg')  
                      //          文档('xlsx', 'xls', 'pptx', 'ppt', 'pdf', 'doc', 'docx', 'txt')  
                      //          压缩包('zip', 'rar')  发票('pdf', 'jpg', 'png', 'jpeg', 'doc', 'docx', 'zip', 'rar') 
                      //          PDF(pdf) 
                      //          委托代征协议('pdf','jpg', 'png', 'jpeg') 
                      //          我的任务('jpg', 'png', 'jpeg','pdf','xlsx', 'xls', 'pdf', 'doc', 'docx','zip', 'rar' )
                      // eg: 
                      //    当值为string类型时,对所有(card1,card2,card3)的有效; 
                      //    当值为对象({"card1":'图片',"card2":'文档', "card3":'PDF'})时,可指定每个(card1/card2/card3)所对应的类型
                      type: "",
                      // 允许上传的文件个数  默认值为1    
                      // eg: 1 表示只允许上传1个文件;  
                      //      当值为对象({"card1":1,"card2":2, "card3":3})时,可指定每个(card1/card2/card3)所对应的类型 
                      size: 1, 
                      // 上传的单个文件大小 单位为 MB  默认值为1 
                      //  eg: 当值为 number 时,对所有(card1,card2,card3)的有效; 
                      //        当值为对象({"pdf":5,"xlsx":10, "zip":100})时,可指定对应的文件类型的大小(单位:MB)
                      singleFileSize: 1,
                    },
                  };
                },
              },
              // 用于vModel 会根据【model】的值来确定此值的内容,如: 身份证=>{card1:{url:'',name:''},card2:{url:'',name:''}}   单文件=>{card1:{url:'',name:''}}  多文件 => {card3:{url:'',name:''}}
              value: { type: Object },
              // 此参数必填  自定义事件  有公共方法可以调用(PUpLoadFileCustomRequestEvent, 此方法为全局混入方法),不必自己写,直接照抄
              customRequestEvent: { type: Function },
              // 此参数选填 此属性表示 upload 组件原本属性集合  具体使用可查询官网 
              uploadAttr: {
                type: Object,
                default: () => {
                  return {
                    // accept:'',
                    // action: "string|(file) => Promise",
                    method: "post",
                    directory: false,
                    // beforeUpload:'(file, fileList) => boolean | Promise',
                    // customRequest:'Function',
                    // data:'object|(file) => object',
                    // defaultFileList:'object[]',
                    disabled: false,
                    // fileList:'',
                    // headers:'',
                    listType: "text",
                    // multiple:false,
                    name: "file",
                    // previewFile:'',
                    showUploadList: false,
                    supportServerRender: false,
                    withCredentials: false,
                    openFileDialogOnClick: true,
                    // remove:'Function(file): boolean | Promise',
                    // transformFile:'Function(file): string | Blob | File | Promise<string | Blob | File>',
                  };
                },
              },
              // 此参数选填 扩展文件校验   
              //        groupName 的值要和 fielConfig.type 使用的值一致,表示校验的类型名称 ;  
              //        suffixArr  表示需要校验的文件后缀 字符串数组 
              //        errorMsg   表示相应的错误提示
              //        eg:  [{ 'groupName':'文档', suffixArr:['xlsx', 'xls', 'pptx', 'ppt', 'pdf', 'doc', 'docx', 'txt'],errorMsg:'只允许上传 PDF,DOC,DOCX,XLS,XLSX 类型文件' }]
              extendedFileVerification: { type: Array },
              // 用于授权
              vhas:{type:string},
              // 表示是否在上传会显得时候显示水印  默认显示
              isShowWatermark:{type:Boolean, default: () => { return true }},
            },
        校验事件的使用
          方法名称: getDataCheckRes
          参数: @param {Object} tipsOption     {card1:'请上传身份证正面',card2:'请上传身份证反面',card3:'请上传附件'}
          返回值:@return {Object} res    {card1:true,card2:false,card3:true}   true 表示校验通过  false 表示检验不通过
          使用方式: this.$refs[''].getDataCheckRes(tipsOption)  或  this.$refs[''].getDataCheckRes()
        `);
      }
  },
  methods: {
    setConfigDefaultFileList(defaultFileList) {
      const defaultFileList_ = {
        card1: {},
        card2: {},
        card3: [],
      };
      Object.keys(defaultFileList).forEach((key) => {
        const ll = { uid: UUID(), name: "", status: "done" };
        if (key == "card3") {
          defaultFileList[key].forEach((item) => {
            let tempName = "";
            // console.log(item.name,IS.isEmpty(item.name),item);
            if (IS.isEmpty(item.name)) {
              tempName = this.getFileName(item.url); // getFileOldName(getCaptionFileName(item.url));
            } else {
              tempName = item.name;
            }
            ll.uid = UUID();
            const item_ = { ...ll, ...item, name: tempName };
            // console.log('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',item_);
            defaultFileList_[key].push(item_);
          });
        } else {
          let tempName = "";
          if (IS.isEmpty(defaultFileList[key].name)) {
            tempName = this.getFileName(defaultFileList[key].url);
          } else {
            tempName = defaultFileList[key].name;
          }
          if (
            defaultFileList[key].url &&
            !IS.isEmpty(defaultFileList[key].url)
          ) {
            // defaultFileList_[key] =  { ...ll, ...defaultFileList[key], name: tempName };
            defaultFileList_[key] = [
              { ...ll, ...defaultFileList[key], name: tempName },
            ];
          } else {
            defaultFileList_[key] = [];
          }
        }
      });
      // console.log('默认设置===》',defaultFileList_);
      return defaultFileList_;
    },

    getImgGroupConfigCardItemVal(url){
      if(IS.isNullOrUnDef(url) || IS.isEmpty(url)){
          return null
        }
        return {url, isShowWatermark: this.isShowWatermark}
    },

    setdefaultFileList(defaultFileList, model) {
      const { card1, card2, card3 } = defaultFileList;
     

      const modelAction = {
        单文件: () => {
          this.ImgGroupConfig["card1"].url = this.getImgGroupConfigCardItemVal(card1.url) 
          this.ImgGroupConfig["card1"].show = true;
          // console.log('***********************1',model,this.ImgGroupConfig, defaultFileList);
        },
        多文件: () => {
          this.ImgGroupConfig["card3"].url = card3.map((item) => {return this.getImgGroupConfigCardItemVal(item.url) });
          this.ImgGroupConfig["card3"].show = true;
          // console.log('***********************4',model,this.ImgGroupConfig);
        },
        身份证: () => {
          const temp = { ...this.ImgGroupConfig };
          temp["card1"].url = this.getImgGroupConfigCardItemVal(card1.url)
          temp["card2"].url = this.getImgGroupConfigCardItemVal(card2.url) 
          temp["card1"].show = true;
          temp["card2"].show = true;
          // console.log('***********************2',model,temp);
          this.ImgGroupConfig = temp;
        },
        all: () => {
          const temp = { ...this.ImgGroupConfig };
          temp["card1"].url = this.getImgGroupConfigCardItemVal(card1.url) 
          temp["card2"].url = this.getImgGroupConfigCardItemVal(card2.url) 
          temp["card3"].url = card3.map((item) => {return this.getImgGroupConfigCardItemVal(item.url) }); 
          temp["card1"].show = true;
          temp["card2"].show = true;
          temp["card3"].show = true;
          // console.log('***********************3',model,temp);

          this.ImgGroupConfig = temp;
        },
      };
      modelAction[model] && modelAction[model]();
    },
    getFileName(url){
      return getFileOldName(getCaptionFileName(url));
    },
    getFilesForUploadChange(val) {
      const res = {};
      const getItemData = (url)=>{
        const res=  {url:'',name:''}
        if(IS.isString(url)){
          res.url = url
          res.name = this.getFileName(url)
        }
        if(IS.isObject(url)){
          res.url = url.url
          res.name = this.getFileName(url.url)
        }
        return res
      }
      const modelList = {
        单文件: () => {
          res["card1"] = {...getItemData(val.card1.url)};
        },
        多文件: () => {
          res["card3"] = val.card3.url.map(item=>{ return {...getItemData(item)}});
        },
        身份证: () => {
          res["card1"] = {...getItemData(val.card1.url)};
          res["card2"] = {...getItemData(val.card2.url)};
        },
        all: () => {
          res["card1"] = {...getItemData(val.card1.url)};
          res["card2"] = {...getItemData(val.card2.url)};
          res["card3"] = val.card3.url.map(item=>{ return {...getItemData(item)}});
          // console.log('getFilesForUploadChange===>',val.card3.url,val.card3.url.map(item=>{ return {url:item,name:this.getFileName(item)}}));
        },
      };
      modelList[this.config_.model] && modelList[this.config_.model]();
      this.onChange(res);
    },
    onChange(value) {
      console.log('UpLoadFile   onChange == >', value);
      this.$emit("change.value", value);
      this.$emit("change", value);
      this.$emit("input", value);
    },
    async customRequestEvent_(action, cardName) {
      // console.log(
      //   "customRequestEvent===>",
      //   action,
      //   cardName,
      //   this.fileCheckRes
      // );
      if (
        this.fileCheckRes[cardName] == true &&
        IS.isFunction(this.customRequestEvent)
      ) {
        const res1 = await this.customRequestEvent(
          action,
          this.config_.dir,
          this
        );
        // console.log("结果=============》", res1);
        if (cardName == "card3") {
          // this.ImgGroupConfig[cardName].url.push({ uid: UUID(), name: res1.name, status: 'done',url:res1.url })
          this.ImgGroupConfig[cardName].url.push({
            name: res1.name,
            // url: res1.url
            ...this.getImgGroupConfigCardItemVal(res1.url)
          });
        } else {
          // this.ImgGroupConfig[cardName].url = { uid: UUID(), name: res1.name, status: 'done',url:res1.url }
          this.ImgGroupConfig[cardName].url = {
            name: res1.name,
            // url: es1.url
            ...this.getImgGroupConfigCardItemVal(res1.url)
          };
        }
        this.ImgGroupConfig[cardName].show = true;
      }

      // console.log(action, cardName);
    },
    async beforeUploadEvent(cardName, file) {
      const res = this.fileCheck(cardName, file);
      this.$nextTick(()=>{
        // console.log("beforeUploadEvent ====>", res);
        if(cardName=="card3"){
          const cFileCount = this.ImgGroupConfig[cardName].url.length
          if (cFileCount == 0 && this.tempFileInfo.length > 0) {
            if(res===false) {
              this.tempFileInfo = []
            }
          }
        }
      })
      return res;
    },
    fileCheck(cardName, file) {
      this.tipConfig[cardName].msg = "";
      this.tipConfig[cardName].show = false;
      // this.fileCheckRes[cardName] = true
      // console.log("文件类型校验  fileCheck ===>", cardName, file, file.type);
      // 允许上传的文件类型  允许上传的文件个数   允许上传的文件大小
      const { type, size, singleFileSize } = this.config_.fielConfig;
      let res = false;
      const getFileSuffix = (fileName) => {
        const sreSuffixData = fileName.split(".");
        return sreSuffixData[sreSuffixData.length - 1];
      };
      // 扩展文件校验
      const getEFVData = () => {
        // 扩展文件校验 [{ 'groupName':'文档', suffixArr:['xlsx'],errorMsg:'只允许上传 PDF,DOC,DOCX,XLS,XLSX 类型文件' }]
        const efvArr = this.extendedFileVerification;
        const res = {
          fileTypeList: { ...FileType.fileTypeList },
          fileTypeErrList: { ...FileType.fileTypeErrList },
        };
        if (IS.isArray(efvArr)) {
          efvArr.forEach((item) => {
            const { groupName, suffixArr, errorMsg } = item;
            res.fileTypeList[groupName] = suffixArr;
            res.fileTypeErrList[groupName] = errorMsg;
          });
        }
        return res;
      };

      const tempFileType = getEFVData();

      const fileSuffix = getFileSuffix(file.name);
      // console.log("文件类型校验  fileSuffix ===>", fileSuffix);
      // 文件类型检测
      const checkFileType = () => {
        let resErrStr = "";

        if (IS.isObject(type)) {
          // {"card1":'图片',"card2":'文档', "card3":'PDF'}
          if (type[cardName] !== "") {
            const fileTypeList_ =
              type[cardName] &&
              tempFileType.fileTypeList[type[cardName]] &&
              tempFileType.fileTypeList[type[cardName]];
            if (
              fileTypeList_ != "all" &&
              fileTypeList_.indexOf(fileSuffix) < 0
            ) {
              resErrStr = tempFileType.fileTypeErrList[type[cardName]];
            }
          }
        }
        if (IS.isString(type)) {
          // '图片'
          const fileTypeList_ =
            tempFileType.fileTypeList[type] && tempFileType.fileTypeList[type];
          if (fileTypeList_ != "all" && fileTypeList_ && fileTypeList_.indexOf(fileSuffix) < 0) {
            resErrStr = tempFileType.fileTypeErrList[type];
          }
        }

        return resErrStr;
      };

      // 统计每种文件类型的个数
      const getFileTypeNum = () => {
        const temp = {}
        let zCount = 0
        this.tempFileInfo.forEach(item => {
          const ttArr = item.name.split('.')
          const hz = ttArr[ttArr.length-1]
          if (temp[hz]) {
            temp[hz] += 1
          } else {
            temp[hz] = 1
          }
          zCount += 1
        })
        console.log("统计每种文件类型的个数=====>", temp);
        return {...temp, zs: zCount}
      }

      // 文件数量检测
      const chechFileNum = () => {
        let resErrStr = "";
        const cFileCount = this.tempFileInfo.length+1;
        const tempFileSuffixCount = getFileTypeNum()
        if (IS.isObject(size)) {
          // { "pdf":2, "png":1 }
          let tempFileCount_zs = 0
          for (const key in size) {
            tempFileCount_zs += size[key]
          }
          const count = size[fileSuffix] || 0;
          if (cardName == "card3") {
            const cFileCount_ = tempFileSuffixCount[fileSuffix] + 1;
            const zs = tempFileSuffixCount['zs'] + 1
            if (count < cFileCount_) {
              resErrStr = `${fileSuffix} 类型文件只能上传${count}个文件`;
            }
            if (tempFileCount_zs < zs) {
              resErrStr = `只能上传${tempFileCount_zs}个文件`;
            }
          }
          // console.log("@@@@@@@@@@@@@@@@@@@@@", this.tempFileInfo);
        }
        if (IS.isNumber(size)) {
          // '图片'
          const count = size;
          if (cardName == "card3") {
            // const cFileCount = this.ImgGroupConfig[cardName].url.length + 1;
            // console.log("文件数量检查 2==》", count, cFileCount, count < cFileCount);
            if (count < cFileCount) {
              resErrStr = `只能上传${count}个文件`;
            }
          }
        }
        // sFileList
        // console.log("文件数量检查 1==》",size, cardName, cFileCount);
        return resErrStr;
      };
      // 文件大小检测
      const chechFileSize = () => {
        // `当前文件【${file.name}】大小限制在${tempFileSize}MB以内`
        const currentFileSize = file.size / 1024 / 1024; // MB  singleFileSize
        let resErrStr = "";
        if (IS.isObject(singleFileSize)) {
          // {"card1":1,"card2":1, "card3":3}
          const fileSuffix_ = singleFileSize[fileSuffix];
          if (fileSuffix_ < currentFileSize) {
            resErrStr = `选择的文件大小限制在${fileSuffix_}MB以内`;
          }
        }
        if (IS.isNumber(singleFileSize)) {
          // '图片'
          const fileSuffix_ = singleFileSize;
          if (fileSuffix_ < currentFileSize) {
            resErrStr = `选择的文件大小限制在${fileSuffix_}MB以内`;
          }
        }
        return resErrStr;
      };

      let resErr = checkFileType();
      // console.log("文件类型检查 1==》", resErr);
      if (IS.isEmpty(resErr)) {
        // 文件类型校验通过
        this.tipConfig[cardName].msg = "";
        this.tipConfig[cardName].show = false;
        res = true;
        this.fileCheckRes[cardName] = res;
      } else {
        // 打开提示信息
        res = false;
        this.tipConfig[cardName].msg = resErr;
        this.tipConfig[cardName].show = true;
        this.fileCheckRes[cardName] = res;
        return res;
      }
      resErr = chechFileNum();
      // console.log("文件数量检查 1==》", resErr);
      if (IS.isEmpty(resErr)) {
        // 文件类型校验通过
        this.tipConfig[cardName].msg = "";
        this.tipConfig[cardName].show = false;
        res = true;
        this.fileCheckRes[cardName] = res;
      } else {
        // 打开提示信息
        res = false;
        this.tipConfig[cardName].msg = resErr;
        this.tipConfig[cardName].show = true;
        this.fileCheckRes[cardName] = res;
        return res;
      }
      resErr = chechFileSize();
      // console.log("文件大小检查 1==》", resErr);
      if (IS.isEmpty(resErr)) {
        // 文件类型校验通过
        this.tipConfig[cardName].msg = "";
        this.tipConfig[cardName].show = false;
        res = true;
        this.fileCheckRes[cardName] = res;
      } else {
        // 打开提示信息
        res = false;
        this.tipConfig[cardName].msg = resErr;
        this.tipConfig[cardName].show = true;
        this.fileCheckRes[cardName] = res;
        return res;
      }
      // console.log("checkFileType  888888888====>", resErr);
      if (res===true) {
        this.tempFileInfo.push(file)
      }
      return res;
    },
    ImgGroupEvent(cardName, item, index) {
      // console.log(cardName, item, index);
      if (cardName == "card3") {
        const tempArr = [...this.ImgGroupConfig[cardName].url];
        tempArr.splice(index, 1);
        const tttArr = this.tempFileInfo
        tttArr.splice(index, 1);
        this.tempFileInfo = tttArr
        // this.ImgGroupConfig[cardName].show = false;
        this.ImgGroupConfig[cardName].url = tempArr;
      } else {
        this.ImgGroupConfig[cardName].show = false;
        this.ImgGroupConfig[cardName].url = "";
      }
    },
    /**
     * 获取校验结果  使用方式: this.$refs[''].getDataCheckRes(tipsOption)  或  this.$refs[''].getDataCheckRes()
     * @param {*} tipsOption {card1:'请上传身份证正面',card2:'请上传身份证反面',card3:'请上传附件'}
     * @returns {Object} {card1:true,card2:false,card3:true} 
     */
    getDataCheckRes(tipsOption) {
      const { required, model ,fielConfig} = this.config_;
      const { card1, card2, card3 } = this.ImgGroupConfig;
      const getTipMsg = (cardName) => {
        return (
          (IS.isObject(tipsOption) && tipsOption[cardName]) || "请上传文件"
        );
      };
      const res = {}; // card1:false,card2:false,card3:false
      const modelAction = {
        单文件: () => {
          if (IS.isObject(card1.url) && !IS.isEmpty(card1.url.url)) {
            res["card1"] = true;
            this.tipConfig.card1.msg = "";
            this.tipConfig.card1.show = false;
          } else {
            if(IS.isString(card1.url) && !IS.isEmpty(card1.url)){
              res["card1"] = true;
              this.tipConfig.card1.msg = "";
              this.tipConfig.card1.show = false;
            }else{
              res["card1"] = false;
              this.tipConfig.card1.msg = getTipMsg("card1");
              this.tipConfig.card1.show = true;
            }
          }
        },
        多文件: () => {
          // console.log('身份证 ====>',card3);
          const fileCount = card3.url.length
          if (IS.isArray(card3.url) && fileCount > 0) {
            res["card3"] = true;
            this.tipConfig.card3.msg = "";
            this.tipConfig.card3.show = false;
          } else {
            res["card3"] = false;
            this.tipConfig.card3.msg = getTipMsg("card3");
            this.tipConfig.card3.show = true;
          }
        },
        身份证: () => {
          if (IS.isObject(card1.url) && !IS.isEmpty(card1.url.url)) {
            res["card1"] = true;
            this.tipConfig.card1.msg = "";
            this.tipConfig.card1.show = false;
          } else {
            if(IS.isString(card1.url) && !IS.isEmpty(card1.url)){
              res["card1"] = true;
              this.tipConfig.card1.msg = "";
              this.tipConfig.card1.show = false;
            }else{
              res["card1"] = false;
              this.tipConfig.card1.msg = getTipMsg("card1");
              this.tipConfig.card1.show = true;
            }
          }
          if (IS.isObject(card2.url) && !IS.isEmpty(card2.url.url)) {
            res["card2"] = true;
            this.tipConfig.card2.msg = "";
            this.tipConfig.card2.show = false;
          } else {
            if(IS.isString(card2.url) && !IS.isEmpty(card2.url)){
              res["card2"] = true;
            this.tipConfig.card2.msg = "";
            this.tipConfig.card2.show = false;
            }else{
              res["card2"] = false;
              this.tipConfig.card2.msg = getTipMsg("card2");
              this.tipConfig.card2.show = true;
            }
          }
        },
        all: () => {
          if (IS.isObject(card1.url) && !IS.isEmpty(card1.url.url)) {
            res["card1"] = true;
            this.tipConfig.card1.msg = "";
            this.tipConfig.card1.show = false;
          } else {
            if(IS.isString(card1.url) && !IS.isEmpty(card1.url)){
              res["card1"] = true;
              this.tipConfig.card1.msg = "";
              this.tipConfig.card1.show = false;
            }else{
              res["card1"] = false;
              this.tipConfig.card1.msg = getTipMsg("card1");
              this.tipConfig.card1.show = true;
            }
          }
          if (IS.isObject(card2.url) && !IS.isEmpty(card2.url.url)) {
            res["card2"] = true;
            this.tipConfig.card2.msg = "";
            this.tipConfig.card2.show = false;
          } else {
            if(IS.isString(card2.url) && !IS.isEmpty(card2.url)){
              res["card2"] = true;
            this.tipConfig.card2.msg = "";
            this.tipConfig.card2.show = false;
            }else{
              res["card2"] = false;
              this.tipConfig.card2.msg = getTipMsg("card2");
              this.tipConfig.card2.show = true;
            }
          }
          const fileCount = card3.url.length
          if (IS.isArray(card3.url) && fileCount > 0) {
            res["card3"] = true;
            this.tipConfig.card3.msg = "";
            this.tipConfig.card3.show = false;
          } else {
            res["card3"] = false;
            this.tipConfig.card3.msg = getTipMsg("card3");
            this.tipConfig.card3.show = true;
          }
        },
      };
      required === true && modelAction[model] && modelAction[model]();
      return res;
    },
  },
};
</script>
<style lang="less" scoped>
.upload-file-con {
  box-sizing: border-box;
  height: 250px;
  // width: 400px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-flow: row wrap;
  overflow: auto;
  .card-item {
    position: relative;
    width: 400px;
    height: calc(100% - 12px);
    border-radius: 8px;
    border: 1px solid #cdcdcd;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 5px 5px;
    // padding: 10px;
    .upload {
      position: absolute;
    }
    .card-item-bg {
      width: 80%;
      height: 80%;
      border: 1px dashed #cdcdcd;
      // border-radius: 8px;
    }

    // /deep/.ant-upload-list {
    //   display: none;
    // }
    .img-group {
      position: absolute;
      z-index: 101;
      width: 99%;
      height: 99%;
      justify-content: center;
    }
    /deep/.img-group-con {
      background-color: #ffffff;
      .img-box {
        flex: 1;
        height: 95%;
        border: 0px dashed #022ea04d;
      }
    }

    &.card-item-list {
      width: 660px;
      border: 0px solid #cdcdcd;
      justify-content: flex-start;
      .card-item-upload {
        width: 400px;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 8px;
        border: 1px solid #cdcdcd;
      }
      .card-item-list-con {
        flex: 1;
        height: 100%;
        margin-left: 5px;
        border: 1px solid #cdcdcd;
        overflow: hidden;
        /deep/.img-group-con {
          flex-flow: row wrap;
          overflow: auto;
          align-items: flex-start;
          // width: 95%;
          .img-box {
            width: 200px;
            height: 120px;
            flex: none;
            padding: 0px;
            border: 1px dashed #022ea04d;
            img {
              flex: none;
              width: 196px;
              height: 116px;
            }
            .img-box-icon {
              font-size: 90px;
            }
            .img-box-close {
              // color: #f10606;
            }
          }
        }
      }
    }

    .tip-msg {
      position: absolute;
      color: #dd0c0c;
      // font-weight: 600;
      z-index: 102;
      width: 100%;
      height: 25px;
      bottom: 0px;
      display: flex;
      justify-content: center;
      align-items: center;
      &.msg{
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #C2C2C2;
        line-height: 17px;
      }
    }
  }
}
</style>
<style>
/*定义滚动条高宽及背景
 高宽分别对应横竖滚动条的尺寸*/
.card-item-list-con::-webkit-scrollbar {
  width: 8px;
  height: 8px;
  background-color: rgba(0, 0, 0, 0.2);
}

/*定义滚动条轨道
 内阴影+圆角*/
.card-item-list-con::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  background-color: #f5f5f5;
}
/*定义滑块
     内阴影+圆角*/
.card-item-list-con::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  background-color: #b3b3b3;
}



::-webkit-scrollbar-corner {
    background: #f6f6f6;
}
::-webkit-scrollbar-thumb {
    background: #cdcdcd;
}
::-webkit-scrollbar-track {
    background: #f6f6f6;
}

div::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

div::-webkit-scrollbar-track {
  /* background: rgb(179, 177, 177); */
  border-radius: 10px;
}

div::-webkit-scrollbar-thumb {
  /* background: rgb(136, 136, 136); */
  border-radius: 10px;
}

div::-webkit-scrollbar-thumb:hover {
  background: rgb(100, 100, 100);
  border-radius: 10px;
}

div::-webkit-scrollbar-thumb:active {
  /* background: rgb(68, 68, 68); */
  border-radius: 10px;
}
</style>