The table component in element merges row data according to attributes

When writing a project recently, there is a requirement like this: when
buying a project, you have selected more than two employees (here, assuming that Zhang San and Li Si are two employees), then when the performance or commission is calculated, Zhang Sanhe Li Si needs to divide the performance of the project and the commission amount equally. When displaying, it is necessary to count Zhang San and Li Si together, so that when one of the employees' performance is modified, the other will also change. The design diagram is as follows:
Insert picture description here
It can be seen from the design diagram that when modifying the sales performance or commission amount of mb006 employees, it is necessary to change the sales performance or total commission of other employees under the same project (gt_test and mb005). And here is based on the project name (tire repair and waxing 2223) to merge employee data. The data returned in the background is like this:
Insert picture description here
you can see that there are actually 5 data returned in the background. Due to the storage restrictions of the background data table, the background developers cannot integrate the performance of the employees of the same project. For this reason, I only These 5 pieces of data can be converted into the similar 2 pieces of data shown above.
This project is on the PC side, and the front-end framework used is vue, so the el-table component of ElementUI is used directly to implement the layout. But the merging of el-table components can only be merged based on the row number. Let's take a look at the official case first:
Insert picture description here
Insert picture description here
you can see that the official case is to merge the data of two rows every two rows, which does not fully meet the requirement that we want to merge according to a certain attribute but do not know how many data. Let's see how to use this first:

Official introduction:

You can merge rows or columns by passing in the span-method method to the table. The parameter of the method is an object, which contains four attributes of the current row row, the current column column, the current row number rowIndex, and the current column number columnIndex. This function can return an array containing two elements, the first element represents rowspan, and the second element represents colspan.
You can also return an object with keys named rowspan and colspan.

If you are a bit convoluted, please look at the following chestnuts:

if (columnIndex === 0) {
    
    
    if (rowIndex === 0) {
    
      // 合并第一行到第四行,从第一行开始,共4行
      return {
    
    
        rowspan: 4,
        colspan: 1
      }
    } else if (rowIndex === 4) {
    
     // 合并第五行到第九行,从第五行开始,共5行
      return {
    
    
        rowspan: 5,
        colspan: 1
      }
    } else if (rowIndex === 9) {
    
     //  合并第10行到第14行,从第10行开始,共5行
      return {
    
    
        rowspan: 5,
        colspan: 1
      }
    } else {
    
     // 其余被合并的行,诸如1、2、3、5、6、7、8、10、11、12、13全都设为0
      return {
    
    
        rowspan: 0,
        colspan: 0
      }
   }
}

You can see that rowspan means how many rows of data are merged.
Let's start with the help of :span-method to achieve the requirements. Before merging the data, you need to process the data and directly upload the code:

// 核算业绩提成合并员工
// 生成一个与行数相同的数组,记录每一行设置的合并数
setMergeArr(data) {
    
    
  for (var i = 0; i < data.length; i++) {
    
    
    if (i === 0) {
    
    
      this.mergeSpanArr.push(1)
      this.mergeSpanArrIndex = 0
    } else {
    
    
      // 判断当前元素与上一个元素是否相同
      if (data[i].itemInfo === data[i - 1].itemInfo) {
    
    //itemInfo代表根据哪个相同的属性去合并
        this.mergeSpanArr[this.mergeSpanArrIndex] += 1
        this.mergeSpanArr.push(0)
      } else {
    
    
        this.mergeSpanArr.push(1)
        this.mergeSpanArrIndex = i
      }
    }
  }
  // 如果第一条记录索引为0,向数组中push 1,设置索引值
  // 如果不是第一条记录,判断与前一条记录是否相等,相等则向mergeSpanArr添加元素0
  // 且将前一条记录+1,即需要合并的行数+1,直到得到所有需要合并的行数
}

Final use:

<el-table :data="recordList" :span-method="activementTable" border></tl-table>
 //核算业绩表合并
 activementTable({
    
     row, column, rowIndex, columnIndex }) {
    
    
   if (columnIndex === 0 || columnIndex === 1) {
    
    
     const _row = this.mergeSpanArr[rowIndex]
     const _col = _row > 0 ? 1 : 0
     return {
    
    
       rowspan: _row,
       colspan: _col
     }
   }
 }

In this way, when merging data, it can be merged according to a certain attribute of the data, rather than only according to the line number like the official.

Let's talk about how to modify the amount of one of the employees and other employees of the same project following the change. First look at the design drawing:
Insert picture description here
input box:

<el-input v-model.trim="scope.row.performance" @keyup.native="totalPayTypeMoney(scope.row,1)"></el-input>

The requirement here is to modify the sales amount or commission amount of mb006, and immediately change the sales performance and commission performance of mb005 and gt_test (the value is (project sales amount-mb006 sales performance) / (number of employees-1), which means that the remaining employees are equally divided The remaining amount). Directly on the code:

//销售业绩-自动计算
 totalPayTypeMoney(item, type) {
    
    
   let singePrice       //单个员工的业绩|提成
   let totalPrice  //总业绩|总提成
   if (type == 1) {
    
    //业绩
     totalPrice = item.itemTotal
     singePrice = item.performance
   } else {
    
    //提成
     totalPrice = item.totalAmount
     singePrice = item.commission
   }
   if (
     isNaN(singePrice) ||
     parseFloat(singePrice) > parseFloat(totalPrice)
   ) {
    
    
     this.$message({
    
    
       message: "请输入小于" + totalPrice + "的数字!",
       type: "error"
     })
     //将当前修改的员工业绩|提成置为总业绩|总提成
     if (type == 1) {
    
    
       item.performance = totalPrice
     } else {
    
    
       item.commission = totalPrice
     }
   }
   //算出剩下的业绩金额|提成金额并根据几个员工均分
   let surplusTotal = (parseFloat(totalPrice) - parseFloat(type == 1 ? item.performance || 0 : item.commission || 0)) / (this.getRealNum(item.index) - 1)  //分配剩余的业绩或提成
   this.recordList.forEach(val => {
    
    
     if (val != item && val.itemInfo == item.itemInfo) {
    
    //除去本身编辑的员工 val.itemInfo == item.itemInfo控制是均分金额的是同个项目的员工
       if (type == 1) {
    
    
         val.performance = parseFloat(surplusTotal).toFixed(2)
       } else {
    
    
         val.commission = parseFloat(surplusTotal).toFixed(2)
       }
     }
   })
 }

This method is to find out how many shares of the remaining amount are divided into when finding changes to employee performance:

//如果得到的是0 就一直往上找 直到找到有合并数
getRealNum(index) {
    
    
   let num
   if (this.mergeSpanArr[index] < 1) {
    
    
     for (let i = index; i < this.mergeSpanArr.length; i--) {
    
    
       if (i > -1 && this.mergeSpanArr[i] > 0) {
    
    
         num = i
         return this.mergeSpanArr[num]
       }
     }
   } else {
    
    
     return this.mergeSpanArr[index]
   }
 }

Well, this sharing ends here. If you see this article and have to solve the problem you want to solve, please give a little star to support it. If you don't understand or can't solve your problem, you are always welcome to find and discuss together!
My WeChat: huang009516

Guess you like

Origin blog.csdn.net/Smell_rookie/article/details/106079140