Skip to content

Conversation

@RylanBot
Copy link
Collaborator

@RylanBot RylanBot commented Nov 28, 2025

🤔 这个 PR 的性质是?

  • 日常 bug 修复
  • 新特性提交
  • 文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • CI/CD 改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他

🔗 相关 Issue

💡 需求背景和解决方案

测试代码存档

(普通表头的住宿费修改后 onEdited 成功,多级表头的年龄失败...打印 onChange 也可以看到 data 没有修改)

import React, { useState } from 'react';
import { CheckCircleFilledIcon, CloseCircleFilledIcon, ErrorCircleFilledIcon } from 'tdesign-icons-react';
import { Checkbox, Input, MessagePlugin, Space, Table, Tag } from 'tdesign-react';

import type { TableProps, TableSort } from 'tdesign-react';

const statusNameListMap = {
  0: { label: '审批通过', theme: 'success', icon: <CheckCircleFilledIcon /> },
  1: { label: '审批失败', theme: 'danger', icon: <CloseCircleFilledIcon /> },
  2: { label: '审批过期', theme: 'warning', icon: <ErrorCircleFilledIcon /> },
};

const initialData: TableProps['data'] = [];
for (let i = 0; i < 20; i++) {
  initialData.push({
    index: i + 1,
    applicant: ['贾明', '张三', '王芳'][i % 3],
    status: i % 3,
    channel: ['电子签署', '纸质签署', '纸质签署'][i % 3],
    time: [3, 2, 4, 1][i % 4],
    createTime: ['2022-01-01', '2022-02-01', '2022-03-01', '2022-04-01', '2022-05-01'][i % 4],
    property: ['组长审批', '部门审批', '财务审批'][i % 3],
    default: i,
    detail: {
      email: ['[email protected]', '[email protected]', '[email protected]'][i % 3],
      position: `读取 ${i} 个数据的嵌套信息值`,
    },
    info: {
      name: ['张三', '李四', '王五'][i % 3],
      age: 20 + (i % 10),
    },
    needed: i % 4 === 0 ? '是' : '否',
    type_default: '-',
    description: '数据源',
    field1: [100, 200, 400, 500][i % 4],
    field2: [100, 200, 400, 500][i % 4],
    field3: [100, 200, 400, 500][i % 4],
    field4: [100, 200, 400, 500][i % 4],
    field5: '字段5',
    field6: '字段6',
    field7: `审批单号00${i + 1}`,
  });
}

export default function TableExample() {
  const [data, setData] = useState([...initialData]);
  const [bordered, setBordered] = useState(true);
  const [fixedHeader, setFixedHeader] = useState(true);
  const [fixedLeftCol, setFixedLeftCol] = useState(false);
  const [fixedRightCol, setFixedRightCol] = useState(false);
  const [headerAffixedTop, setHeaderAffixedTop] = useState(false);
  const [sort, setSort] = useState<TableSort>({ sortBy: 'default', descending: false });

  const onSortChange: TableProps['onSortChange'] = (sortInfo, context) => {
    setSort(sortInfo);
    setData([...context.currentDataSource]);
    console.log(context);
  };

  const columns: TableProps['columns'] = [
    {
      title: '申请人',
      colKey: 'applicant',
      fixed: fixedLeftCol ? ('left' as const) : undefined,
      width: 100,
    },
    {
      title: '申请汇总',
      fixed: fixedLeftCol ? 'left' : undefined,
      width: 100,
      colKey: 'total_info',
      children: [
        {
          align: 'left',
          colKey: 'platform',
          title: '申请状态',
          fixed: fixedLeftCol ? 'left' : undefined,
          width: 120,
          sorter: (a, b) => a.default - b.default,
          cell: ({ rowIndex }) => {
            const status = rowIndex % 3;
            return (
              <Tag
                shape="round"
                theme={statusNameListMap[status].theme}
                variant="light-outline"
                icon={statusNameListMap[status].icon}
              >
                {statusNameListMap[status].label}
              </Tag>
            );
          },
        },
        {
          title: '申请渠道和金额',
          colKey: 'type_default',
          fixed: fixedLeftCol ? 'left' : undefined,
          width: 100,
          children: [
            {
              align: 'left',
              colKey: 'channel',
              title: '类型',
              fixed: fixedLeftCol ? 'left' : undefined,
              width: 110,
            },
            {
              align: 'center',
              colKey: 'time',
              title: '申请耗时(天)',
              fixed: fixedLeftCol ? 'left' : undefined,
              width: 150,
            },
          ],
        },
      ],
    },
    {
      title: '用户信息',
      colKey: 'info',
      children: [
        {
          title: '姓名',
          colKey: 'info.name',
          width: 100,
        },
        {
          title: '年龄',
          colKey: 'info.age',
          width: 120,
          edit: {
            component: Input,
            onEdited: (context) => {
              console.log('onEdited triggered:', context);
              data.splice(context.rowIndex, 1, context.newRowData);
              setData([...data]);
              MessagePlugin.success('编辑成功');
              console.log('年龄', context.col);
            },
          },
        },
      ],
    },
    {
      colKey: 'field1',
      title: '住宿费',
      width: 100,
      edit: {
        component: Input,
        onEdited: (context) => {
          console.log('onEdited triggered:', context);
          data.splice(context.rowIndex, 1, context.newRowData);
          setData([...data]);
          MessagePlugin.success('编辑成功');
          console.log('住宿费', context.col);
        },
      },
    },
    {
      colKey: 'field3',
      title: '交通费',
      width: 100,
    },
    {
      colKey: 'field4',
      title: '物料费',
      width: 100,
    },
    {
      colKey: 'field2',
      title: '奖品激励费',
      width: 120,
    },
    {
      title: '审批汇总',
      colKey: 'instruction',
      fixed: fixedRightCol ? 'right' : undefined,
      width: 100,
      children: [
        {
          align: 'left',
          colKey: 'property',
          title: '审批状态',
          fixed: fixedRightCol ? 'right' : undefined,
          width: 120,
          filter: {
            type: 'single',
            list: [
              { label: '所有状态', value: '' },
              { label: '组长审批', value: '组长审批' },
              { label: '部门审批', value: '部门审批' },
              { label: '财务审批', value: '财务审批' },
            ],
          },
        },
        {
          align: 'left',
          ellipsis: true,
          colKey: 'description',
          title: '说明',
          fixed: fixedRightCol ? 'right' : undefined,
          width: 100,
          children: [
            {
              colKey: 'field7',
              title: '审批单号',
              fixed: fixedRightCol ? 'right' : undefined,
              width: 120,
            },
            {
              colKey: 'detail.email',
              title: '邮箱地址',
              fixed: fixedRightCol ? 'right' : undefined,
              ellipsis: true,
              width: 150,
            },
          ],
        },
      ],
    },
    {
      colKey: 'createTime',
      title: '申请时间',
      fixed: fixedRightCol ? 'right' : undefined,
      width: '120',
    },
  ];
  return (
    <Space direction="vertical" size="large" style={{ width: '100%' }}>
      {/* <!-- 按钮操作区域 --> */}
      <Space>
        <Checkbox checked={bordered} onChange={setBordered}>
          显示表格边框
        </Checkbox>
        <Checkbox checked={fixedHeader} onChange={setFixedHeader}>
          显示固定表头
        </Checkbox>
        <Checkbox checked={fixedLeftCol} onChange={setFixedLeftCol}>
          固定左侧列
        </Checkbox>
        <Checkbox checked={fixedRightCol} onChange={setFixedRightCol}>
          固定右侧列
        </Checkbox>
        <Checkbox checked={headerAffixedTop} onChange={setHeaderAffixedTop}>
          表头吸顶
        </Checkbox>
      </Space>

      <Table
        data={data}
        bordered={bordered}
        columns={columns}
        rowKey="index"
        maxHeight={fixedHeader ? 380 : undefined}
        headerAffixProps={{ offsetTop: 0 }}
        headerAffixedTop={headerAffixedTop}
        columnController={{ displayType: 'auto-width' }}
        sort={sort}
        onSortChange={onSortChange}
        lazyLoad
        onChange={(data, context) => {
          console.log('change', data, context);
        }}
      />
    </Space>
  );
}

📝 更新日志

  • fix(Table): 修复多级表头场景下,editable 单元格编辑后数据没有同步的问题

  • fix(Table): 修复 onChangecontext.currentData 在过滤场景下缺失的问题

  • 本条 PR 不需要纳入 Changelog

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • Changelog 已提供或无须提供

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 28, 2025

tdesign-react-demo

npm i https://pkg.pr.new/tdesign-react@3982

commit: 2adfb26

@github-actions
Copy link
Contributor

完成

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants