在做流量平台后台管理产品分流策略的需求的时候,遇到一个表格单元格合并的页面展示需求.页面展示的效果实现其实并不难,但是自己在实现的过程中还是遇到一些坑,记录一下:

页面效果

首先拿到后端接口返回的数据,然后进行重新处理.

{
  "code" : "0",
  "message" : "成功",
  "result" : {
    "records" : [ {
      "id" : 6348,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "jdkshfd",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 1,
      "versionName" : "华海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 20,
      "effectiveTime" : "2020-12-18 15:23:18",
      "available" : "Y",
      "modifier" : "za-dingwanyue",
      "gmtModified" : null
    }, {
      "id" : 6349,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "jdkshfd",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 2,
      "versionName" : "前海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 80,
      "effectiveTime" : "2020-12-18 15:23:18",
      "available" : "Y",
      "modifier" : "za-dingwanyue",
      "gmtModified" : null
    }, {
      "id" : 6343,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "test",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 1,
      "versionName" : "华海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 0,
      "effectiveTime" : "2020-12-18 12:14:05",
      "available" : "Y",
      "modifier" : "za-dingwanyue",
      "gmtModified" : null
    }, {
      "id" : 6344,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "test",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 5,
      "versionName" : "现代财投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 0,
      "effectiveTime" : "2020-12-18 12:14:05",
      "available" : "Y",
      "modifier" : "za-dingwanyue",
      "gmtModified" : null
    }, {
      "id" : 6342,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "test",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 2,
      "versionName" : "前海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 100,
      "effectiveTime" : "2020-12-18 12:14:05",
      "available" : "Y",
      "modifier" : "za-dingwanyue",
      "gmtModified" : null
    }, {
      "id" : 6341,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "hhzx_zt24_002",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 5,
      "versionName" : "现代财投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 0,
      "effectiveTime" : "2020-12-18 11:11:00",
      "available" : "Y",
      "modifier" : "za-tongjianyang",
      "gmtModified" : null
    }, {
      "id" : 6340,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "hhzx_zt24_002",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 1,
      "versionName" : "华海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 0,
      "effectiveTime" : "2020-12-18 11:11:00",
      "available" : "Y",
      "modifier" : "za-tongjianyang",
      "gmtModified" : null
    }, {
      "id" : 6339,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "hhzx_zt24_002",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 3,
      "versionName" : "众安投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 100,
      "effectiveTime" : "2020-12-18 11:11:00",
      "available" : "Y",
      "modifier" : "za-tongjianyang",
      "gmtModified" : null
    }, {
      "id" : 6322,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "hhzx_kt18_035",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 5,
      "versionName" : "现代财投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 100,
      "effectiveTime" : "2020-12-18 10:28:14",
      "available" : "Y",
      "modifier" : "za-tongjianyang",
      "gmtModified" : null
    }, {
      "id" : 6321,
      "channelCode" : "DY",
      "channelName" : "抖音",
      "channelSource" : "hhzx_kt18_035",
      "channelSourceName" : null,
      "onlineProductShuntConfigId" : 1,
      "versionName" : "华海投保",
      "insurerName" : null,
      "insurerCode" : null,
      "shuntPercent" : 0,
      "effectiveTime" : "2020-12-18 10:28:14",
      "available" : "Y",
      "modifier" : "za-tongjianyang",
      "gmtModified" : null
    } ],
    "total" : 378,
    "size" : 10,
    "current" : 1,
    "orders" : [ ],
    "searchCount" : true,
    "pages" : 38
  }
}

channelName和channelSource一致的时候我们才进行合并单元格


// 合并数组单元格
  const createNewArr = (data) => {
    return data.reduce((result, item, index) => {
      // 首先将name字段作为新数组result取出
      if (result.indexOf(item.channelSource) < 0 && result.indexOf(item.channelName) < 0) {
        let flag = false;
        if (index > 0 && (item.channelSource === result[index - 1].channelSource && item.channelName === result[index - 1].channelName)) {
          flag = true;
        }
        result.push({
          channelName: item.channelName,
          channelSource: item.channelSource,
          flag,
        })
      }
      return result
    }, []).reduce((result, name, index, arr) => {
      // 将name相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
      const children = data.filter(item => (item.channelSource === name.channelSource && item.channelName === name.channelName));
      if (name.flag) return result; //直接返回,否则进行concat链接
      result = result.concat(
        children.map((item, index) => ({
          ...item,
          rowSpan: index === 0 ? children.length : 0,// 将第一行数据添加rowSpan字段
        }))
      )
      return result;
    }, [])
  }
  

最后在要合并的字段中添加rowSpan属性即可: (定义列的数组中)

 const columns = [
  {
      title: '一级渠道名称',
      dataIndex: 'channelName',
      align: 'center',
      render(_, row) {
        return {
          children: row.channelName,
          props: {
            rowSpan: row.rowSpan,
          }
        }
      }
    },
 ]

最后表格调用的地方,调用这个函数处理好data在传入Table组件即可: dataSource={createNewArr(insurerList)}

参考笔记:react antd Table动态合并单元格