<template>
  <div class="by-table">
    <vxe-table
      ref="table"
      :data="value"
      :size="attrs.size?attrs.size:'small'"
      sync-resize
      auto-resize
      :edit-rules="attrs.editRules"
      :height="attrs.height"
      :max-height="attrs.maxHeight"
      :stripe="attrs.stripe"
      :border="attrs.border"
      :align="attrs.align"
      :show-footer="attrs.showFooter"
      :footer-method="attrs.footerMethod"
      :tree-config="{transform: attrs.transform, rowField: attrs.rowField, parentField: attrs.parentField}"
      :row-config="{isHover: true}"
      :tooltip-config="{showAll: true}"
      :radio-config="{trigger: attrs.triggerRowCheck}"
      :checkbox-config="{ checkMethod: attrs.checkMethod, visibleMethod: attrs.visibleMethod,trigger: attrs.triggerRowCheck}">
      style="width: 100%">
      <vxe-column v-if="attrs.checkbox" type="checkbox" width="50" fixed="left" />
      <vxe-column v-if="attrs.radio" type="radio" width="50" fixed="left" />
      <vxe-column v-if="attrs.seq" type="seq" title="序号" :width="attrs.seqWidth?attrs.seqWidth:50" fixed="left" :tree-node="attrs.treeNodeSeq" />
      <template v-for="(item,index) of columns">
        <vxe-column
          v-if="item.action"
          :key="'action_'+index"
          :title="item.title"
          :width="item.width"
          resizable
          fixed="right"
        >
          <template #default="{ row }">
            <template v-if="item.plugins">
              <template v-for="(pluginsItem,_index) of item.plugins" >
                <span class="col-action" 
                  :key="'plu'+_index" 
                  v-if="showPlugin(pluginsItem,row)"
                  @click="pluginClick(pluginsItem,row)">
                  <i v-if="pluginsItem.icon" :class="pluginsItem.icon" ></i>
                  {{ pluginsItem.name }}
                </span>
              </template>
            </template>
          </template>
        </vxe-column>
        <vxe-column
          v-if="!item.action"
          :key="item.field?item.field+getUuid():index+getUuid()"
          :field="item.field"
          :title="item.title"
          :width="item.width"
          :fixed="item.fixed"
          resizable
          :align="item.align"
          :edit-render="{}"
          :tree-node="item.treeNode"
        >
          <template #default="scope">
            <slot v-if="item.slot" :name='item.field' :row='scope.row' :rowIndex="scope.rowIndex"></slot>
            <component v-else-if="item.component" :is="item.component" :ref="item.field+'Comp'" :propConfig="item.compConfig" :parentValue="scope.row"
              :propValue="scope.row[item.field]" @onChange="onChange($event, scope,item.field)" />
            <template v-else>
              <div v-if="item.isDetail" :class="{'ellipsis':item.ellipsis}" :style="{ 'text-align': item.align }" class="tdCol detail" @click="detail(scope.row)">
                {{ item.formatField ? formatField(item,scope.row) : scope.row[item.field] }}
                <div class="copy-out" v-if="item.copy && scope.row[item.field]">
                  <div class="copy" @click="copyHandle(scope.row[item.field])">复制</div>
                </div>
              </div>
              <div class="tdCol" :class="{'ellipsis':item.ellipsis}" :style="{ 'text-align': item.align }" v-else>
                {{ item.formatField ? formatField(item,scope.row) : scope.row[item.field] }}
                <div class="copy-out" v-if="item.copy && scope.row[item.field]">
                  <div class="copy" @click="copyHandle(scope.row[item.field])">复制</div>
                </div>
              </div>
            </template>
            
          </template>
        </vxe-column>
      </template>
    </vxe-table>
    <div class="page" v-if="page.total > 0">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="page.pageNo"
        :page-sizes="attrs.pageSizes"
        :page-size="page.pageSize?page.pageSize:20"
        :layout="attrs.layoutPage?attrs.layoutPage:'total, sizes, prev, pager, next, jumper'"
        :total="page.total">
      </el-pagination>
    </div>
  </div>
</template>

<script lang="ts">
/**
  config:{
    attr:{
      copy:true/false //复制
      triggerRowCheck:'row'  //点击行选中
      size: medium / small / mini  //尺寸
      height: ''  //高度
      maxHeight:''  //最大高度
      stripe: true/false  //是否为斑马纹
      border: true/false  //是否带有纵向边框
      seq:true/false  //显示序号
      seqWidth:''  //序号宽度
      checkbox: true/false  //显示复选框
      radio:true/false  //显示单选框
      align: left/center/right  //对齐方式
      transform: true/false  //开启自动将列表转成树结构
      rowField:''  row对应id
      parentField:''  row父id
      pageSize:''  //分页条数
      pageSizes:[]  //每页显示个数选择器的选项设置
      layoutPage:''  //分页组件布局
      checkMethod:()=>{}  //禁用复选框方法
      visibleMethod：()=>{} //显示复选框方法
      editRules:{}//表格验证
    },
    columns:[{
      ellipsis:true/false //超出省略号表示
      title:''  //标题
      field：''  //字段名
      align: left/center/right   //对齐方式
      width:''  //列宽
      fixed: true, left, right  // 固定列
      action： true/false 是否操作列
      plugins:操作列执行
      component:''  //组件
      compConfig:{} //组件配置
      slot: true/false  //是否插槽
      isDetail:true/false  //点击详情
      tree-node: true/false  //展开节点
      formatField:(item)=>{}  //格式化内容
    }],
    request:{}
  }

 */
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import VueViews from '@/benyun/compVue/VueViews'

interface Page{
  pageNo?:number,
  pageSize?:number,
  total?:number
}

@Component
export default class ByTable extends VueViews {
  value:Array<any>=[];
  key_id="_X_ROW_KEY"
  page = {
    pageNo: 1, //当前页
    pageSize: 20, //每页条数
    total: 0 //总条数
  }
  get columns(){
    return this.config?.columns ? this.config.columns : [];
  }

  created(){
    this.initConfig()
  }
  getUuid(){
    return (((1 + Math.random()) * 0x10000) | 0).toString(3).substring(1);
  }
  initConfig(){
    if(this.propConfig){
      this.setConfig(this.propConfig)
    }
  }
  mounted(){
    this.$nextTick(()=>{
      if(this.requestConfig){
        this.request();
      }
    })
  }
  validate(){
    let res = true
    const $table:any = this.$refs.table
    const data = $table.getTableData()
    $table.validate(data.tableData).catch(() => {})
    if(this.attrs.editRules && data.tableData && data.tableData.length > 0){
      for(const item of data.tableData) {
        for(const key in this.attrs.editRules){
          if(this.attrs.editRules[key] && this.attrs.editRules[key].length > 0) {
            for(const ruleItem of this.attrs.editRules[key]){
              if(ruleItem.required) {
                if(!item[key]){
                  res = false;
                  break
                }
              }
              if(ruleItem.validatorHandle && item[key] || item[key] === 0){
                res = ruleItem.validatorHandle(item[key])
              }
              if(!res) break
            }
          }
          if(!res) break
        }
      }
    }else{
      res = true
    }
    return res
    // console.log(errMap)
    // if (errMap) {
    //   this.$message({message:'校验不通过！',type:'warning'})
    // } else {
    //   this.$message({message:'校验成功！',type:'warning'})
    
    // }
  }
  recalculate(){
    if(this.$refs.table){
      (this.$refs.table as any).recalculate(true);
      this.$forceUpdate();
    }
  }
  loadTableData(data:Array<any>){
    if(this.$refs.table){
      (this.$refs.table as any).loadData(data);
    }
  }
  //点击详情
  detail(row:any){
    let data = (this as any).$lodash.cloneDeep(row);
    delete data[this.key_id];
    this.$emit('detail',data)
  }

  setConfigAfter(){
    if(this.attrs.pageSize){
      this.page.pageSize = this.attrs.pageSize;
    }
    this.recalculate();
    
  }
  copyHandle(text:string){
    let textarea:any = document.createElement('textarea');
    textarea.style.position = 'fixed';
    textarea.style.opacity = 0;
    textarea.value = text;
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand('copy');
    document.body.removeChild(textarea);
    this.$message({
      message:'复制成功！',
      type:'success'
    })
  }
  //设置分页
  setPage(page:Page){
    if(page.pageNo){
      this.page.pageNo = page.pageNo;
    }
    if(page.pageSize){
      this.page.pageSize = page.pageSize;
    }
    this.page.total = page.total?page.total:0;
    
  }

  getPage(){
    return this.page
  }
  //每页条数发生变化
  handleSizeChange(val:number) {
    this.page.pageSize = val;
    if (this.page.pageSize * val > this.page.total) {
      this.page.pageNo = 1
    }
    this.$emit('pagination',{pageNum:this.page.pageNo,pageSize:this.page.pageSize})
  }
  //当前页发生变化
  handleCurrentChange(val:number) {
    this.page.pageNo = val;
    this.$emit('pagination',{pageNum:this.page.pageNo,pageSize:this.page.pageSize})
  }

  //操作列点击操作
  pluginClick(config:any,row:any){
    if(config?.event?.click){
      // let data = (this as any).$lodash.cloneDeep(row)
      // delete data[this.key_id];
      config.event.click(row)
    }
  }
  //操作按钮是否显示
  showPlugin(config:any,row:any){
    if(config?.event?.show){
      let data = (this as any).$lodash.cloneDeep(row)
      delete data[this.key_id];
      return config.event.show(data)
    }

    return true
  }

  //格式化内容
  formatField(config:any,row:any){
    if(config.formatField){
      return config.formatField(row)
    }
  }

  //组件值的变化
  onChange(val:any,item:any,code:string){
    (this.$refs.table as any).updateStatus(item);
    let row = item.row;
    if(val && (val as any).constructor == Object){
      for (const key in val) {
        if (!row[key]) {
          Vue.set(row, key, val[key])
        } else {
          row[key] = val[key]
        }
      }
    }else{
      if(!row[code]){
        Vue.set(row, code, val)
      }else{
        row[code] = val
      }
    }
    this.$emit('onChangeRow',row);
  }

  //获取表格选中的数据
  getSelectData() {
    let data: Array<any> = []
    if (this.$refs.table) {
      if (this.attrs.radio && (this.$refs.table as any).getRadioRecord()) {
        data = (this as any).$lodash.cloneDeep([(this.$refs.table as any).getRadioRecord()]);
      } 
      if(this.attrs.checkbox && (this.$refs.table as any).getCheckboxRecords()){
        data = (this as any).$lodash.cloneDeep((this.$refs.table as any).getCheckboxRecords());
      }
    }
    for(let item of data){
      delete item[this.key_id];
    }
    return data
  }
  //清除选中
  clearCheckboxRow(){
    if(this.attrs.checkbox){
      (this.$refs.table as any).clearCheckboxRow();
    }
    if(this.attrs.radio){
      (this.$refs.table as any).clearRadioRow();
    }
  }
  setValue(data:Array<any>){
    // setTimeout(()=>{
      this.value = data ? data : [];
    // },100)
    (this.$refs.table as any).clearValidate()
    this.$forceUpdate()
  }

  getValue(){
    let d = (this as any).$lodash.cloneDeep(this.value);
    for(let item of d){
      delete item[this.key_id];
    }
    return d;
  }
  request(){
    if(!this.requestConfig || !this.requestConfig.url){
      return
    }

    let parame = (this as any).$lodash.cloneDeep(this.requestConfig);
    parame.success = (res:any) => {
      if(res.data){
        this.setValue(res.data);
      }
    }
    parame.fail = (err:any) => {}
    this.requestHandle(parame);
  }
}
</script>

<style lang="scss" scoped>
.by-table{
  width: 100%;
  .page{
    width: 100%;
    display: flex;
    padding-top: 16px;
    justify-content: flex-end;
  }
  .tdCol{
    width: 100%;
    .copy-out{
      display: flex;
      justify-content: flex-end;
    }
    .copy{
      // position: absolute;
      // bottom: 0;
      // right: 0;
      border: solid 1px #0089ff;
      font-size: 12px;
      width: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 20px;
      border-radius: 3px;
      cursor: pointer;
      color: #0089ff;
      background-color: #f1f7fc;
    }
  }
  .ellipsis{
    width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}
.col-action{
  color: #0089ff;
  cursor: pointer;
  padding: 0 4px;
}
.detail{
  color: #0089ff;
  cursor: pointer;
}
</style>