树形表格行合并

在这里插入图片描述
[http://www.umyui.com/umycomponent/basicEditTable]umy-ui虚拟表格

<template>
  <div class="final-accounts-view">
    <ux-grid
       class="task-table"
       ref="plxTable"
       size="mini"
       show-overflow
       widthResize
       :data="taskTemplateList"
       :span-method="objectSpanMethod"
       :highlightCurrentRow="false"
       :edit-config="{ trigger: 'click', mode: 'cell',showIcon:false}"
       border
       style="width: 100%"
     >
        <ux-table-column field="primaryNumber" title="一级编号" fixed="left"></ux-table-column>
        <ux-table-column field="firstLevelTask" title="一级名称" fixed="left"></ux-table-column>
        <ux-table-column field="secondaryNumber" title="二级编号">
          <template v-slot="{row}">
            <div class="add-position">
              <span>{{ row.secondaryNumber }}</span>
              <i v-if="showAddIcon(row,2)" class="h-icon-circle-plus-fill cp" @click.stop="addItem(row,2)"></i>
            </div>
          </template>
        </ux-table-column>
        <ux-table-column field="secondaryTask" title="二级名称" :edit-render="{ autofocus: '.el-input__inner' }">
          <template v-slot:edit="{row}">
            <el-input v-model="row.secondaryTask" maxlength="500" @change="secondaryTaskChange(row)"/>
          </template>
          <template v-slot="{row}">
            <span class="my-input-sc">{{ row.secondaryTask }}</span>
          </template>
        </ux-table-column>
        <ux-table-column field="thirdLevelNumber" title="三级编号">
          <template v-slot="{row}">
            <div class="add-position">
              <span>{{ row.thirdLevelNumber }}</span>
              <i v-if="showAddIcon(row,3)" class="h-icon-circle-plus-fill cp" @click.stop="addItem(row,3)"></i>
            </div>
          </template>
        </ux-table-column>
        <ux-table-column field="levelThirdTask" title="三级名称" :edit-render="{ autofocus: '.el-input__inner' }">
          <template v-slot:edit="{row}">
            <el-input v-model="row.levelThirdTask" maxlength="500"/>
          </template>
          <template v-slot="{row}">
            <span class="my-input-sc">{{ row.levelThirdTask }}</span>
          </template>
        </ux-table-column>
        <ux-table-column title="操作" width="60">
          <template v-slot="{row}">
            <el-button
              type="text"
              @click="delItem(row)"
              v-if="showAddIcon(row,3)"
              >删除</el-button
            >
          </template>
        </ux-table-column>
      </ux-grid>
  </div>
</template>
<script>
export default {
  data () {
    return {
      taskDefault:[
        {primaryNumber:'A',firstLevelTask:'A',secondaryNumber:'A-01',secondaryTask:'',thirdLevelNumber:'A-01-001',levelThirdTask:''},
        {primaryNumber:'B',firstLevelTask:'B',secondaryNumber:'B-01',secondaryTask:'',thirdLevelNumber:'B-01-001',levelThirdTask:''},
        {primaryNumber:'C',firstLevelTask:'C',secondaryNumber:'C-01',secondaryTask:'',thirdLevelNumber:'C-01-001',levelThirdTask:''},
      ],
      primaryNumber:[],
      firstLevelTask:[],
      secondaryNumber:[],
      secondaryTask:[],
      taskTemplateList:[],
      trigger:'manual',
    }
  },
  mounted(){
    this.taskTemplateList = JSON.parse(JSON.stringify(this.taskDefault))
    this.rowSpan(this.taskTemplateList)
  },
  methods: { 
    showAddIcon(row,lv){
      const index = this.taskTemplateList.map(item => item._XID).indexOf(row._XID); 
      if(lv==2){
        const arr =  this.taskTemplateList.filter(item => item.primaryNumber === row.primaryNumber)
        const last = arr[arr.length -1]
        const lastSameNum = arr.filter(item => item.secondaryNumber === last.secondaryNumber)
        if(arr.indexOf(row) === (arr.length - lastSameNum.length)) {
          return true
        }
      }
      if(lv==3 && (index===(this.taskTemplateList.length-1)||this.taskTemplateList[(index+1)].secondaryNumber!= row.secondaryNumber)){
        return true
      }
    },
    getContractNumber (lv,levStart) {
      let len = 1;
      if (this.taskTemplateList && this.taskTemplateList.length) {
        const arr = this.taskTemplateList.map(val => {
          let row = JSON.parse(JSON.stringify(val))
          if(lv===2 && val.primaryNumber==levStart){
            let rowArr = row.secondaryNumber.split('-')
            return rowArr[1]
          }else{
            if(lv===3 && val.secondaryNumber == levStart){
              let rowArr = row.thirdLevelNumber.split('-')
              return rowArr[2]
            }else{
              return 0
            }
          }
        });
        let max = 0;
        if (arr.length) {
          max = Math.max.apply(null, arr);
        }
        len = max + 1;
      }
      if(lv===2){
        if (len >= 100) {
          return `${levStart}-${len}`
        } else if (len >= 10) {
          return `${levStart}-${len}`
        } else {
          return `${levStart}-0${len}`
        }
      }
      if(lv===3){
        if (len >= 100) {
          return `${levStart}-${len}`
        } else if (len >= 10) {
          return `${levStart}-0${len}`
        } else {
          return `${levStart}-00${len}`
        }
      }
    },
    secondaryTaskChange(row){
      const secondaryRow =  this.taskTemplateList.filter(item => item.secondaryNumber == row.secondaryNumber)
      secondaryRow.forEach(item=>{
        item.secondaryTask = row.secondaryTask
      })
    },
    addItem (row,lv) {
      const index = this.taskTemplateList.map(item => item._XID).indexOf(row._XID);
      let addNum = index+1
      let secondaryNumber = lv==3?row.secondaryNumber:this.getContractNumber(2,row.primaryNumber)
      let secondaryTaskName = ''
      const secondaryRow =  this.taskTemplateList.filter(item => item.secondaryNumber == row.secondaryNumber)
      if(lv===2){
        addNum = index + secondaryRow.length
      }
      if(lv===3){
        secondaryTaskName = row.secondaryTask
      }
      this.taskTemplateList.splice(addNum, 0, {
        primaryNumber: row.primaryNumber,
        firstLevelTask: row.firstLevelTask,
        secondaryNumber: secondaryNumber ,
        secondaryTask: secondaryTaskName,
        thirdLevelNumber: this.getContractNumber(3,secondaryNumber),
        levelThirdTask: ''
      })
      this.rowSpan(this.taskTemplateList)
    },
    delItem (rowObj) {
      const index = this.taskTemplateList.map(item => item._XID).indexOf(rowObj._XID);
      const surplusArr = this.taskTemplateList.filter(item=>(item.primaryNumber===rowObj.primaryNumber))
      if(surplusArr.length==1){
        return this.messageInfo('warning', '该编号最后一条数据不允许删除!')
      }
      this.$confirm('确定要删除该条数据吗?', '提示', {
        confirmButtonText: '确 定',
        cancelButtonText: '取 消',
        type: 'question'
      }).then(() => {
        this.taskTemplateList.splice(index, 1)
        this.rowSpan(this.taskTemplateList)
      }).catch(() => { });
    },
    rowSpan (list) {
      this.primaryNumber = []
      this.firstLevelTask = []
      this.secondaryNumber = []
      this.secondaryTask = []
      let contactDot = 0;
      let contactDotTow = 0;
      let contactDotThree = 0;
      let contactDotFour = 0;
      list.forEach((item, index) => {
        if (index === 0) {
          this.primaryNumber.push(1)
          this.firstLevelTask.push(1)
          this.secondaryNumber.push(1)
          this.secondaryTask.push(1)
        } else {
          if (item.primaryNumber === list[index - 1].primaryNumber) {
            this.primaryNumber[contactDot] += 1;
            this.primaryNumber.push(0)
            this.firstLevelTask[contactDotTow] += 1
            this.firstLevelTask.push(0)
          } else {
            this.primaryNumber.push(1)
            contactDot = index
            this.firstLevelTask.push(1)
            contactDotTow = index
          }
          if (item.primaryNumber === list[index - 1].primaryNumber && item.secondaryNumber === list[index - 1].secondaryNumber) { //第三列合并相同
            this.secondaryNumber[contactDotThree] += 1
            this.secondaryNumber.push(0)
            this.secondaryTask[contactDotFour] += 1
            this.secondaryTask.push(0)
          } else {
            this.secondaryNumber.push(1)
            contactDotThree = index
            this.secondaryTask.push(1)
            contactDotFour = index
          }
        }
      })
    },
    objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        if (this.primaryNumber[rowIndex]) {
          return {
            rowspan: this.primaryNumber[rowIndex],
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
      if (columnIndex === 1) {
        if (this.firstLevelTask[rowIndex]) {
          return {
            rowspan: this.firstLevelTask[rowIndex],
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
      if (columnIndex === 2) {
        if (this.secondaryNumber[rowIndex]) {
          return {
            rowspan: this.secondaryNumber[rowIndex],
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
      if (columnIndex === 3) {
        if (this.secondaryTask[rowIndex]) {
          return {
            rowspan: this.secondaryTask[rowIndex],
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    },
  }
}
</script>
<style lang="scss">
.final-accounts-view {
  .my-input-sc {
    display: inline-block;
    height: 28px;
    line-height: 25px;
    -webkit-appearance: none;
    background-color: #ffffff;
    background-image: none;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    font-size: 12px;
    outline: none;
    padding: 0 8px;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .task-table {
    .el-input{
      width: 100%;
    }
    .elx-table .elx-body--column, .elx-table .elx-footer--column, .elx-table .elx-header--column{
      line-height: 26px;
    }
    .elx-cell{
      height: 28px;
      position: relative;
    }
    .elx-table--empty-block{
      height: 300px;
    }
    .add-position {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .h-icon-circle-plus-fill {
        color: #0776d8;
        padding-left: 8px;
      }
    }
    .el-form-item {
      width: 100%;
    }
    .el-table .cell {
      width: 100% !important;
    }
  }
  .elx-table--body-wrapper{
    overflow-x: hidden;
  }
  .task_template_dialog{
    .el-form{
      .el-input{
        width: 230px !important;
      }
    }
  }
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值