npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gzkx-package

v0.1.49

Published

本文档详细介绍了项目中四个核心自定义组件的使用方法和参数说明。

Downloads

1,750

Readme

自定义组件使用文档

本文档详细介绍了项目中四个核心自定义组件的使用方法和参数说明。


目录


安装

使用 npm

npm install gzkx-package

使用 yarn

yarn add gzkx-package

使用 pnpm

pnpm add gzkx-package

快速开始

1. 安装依赖

确保项目中已安装以下依赖(peerDependencies):

npm install antd axios dayjs lodash pinyin-pro react react-dom

版本要求:

  • antd: ^5.0.0
  • axios: ^1.0.0
  • dayjs: ^1.11.0
  • lodash: ^4.17.0
  • pinyin-pro: ^3.0.0
  • react: ^18.0.0 或 ^19.0.0
  • react-dom: ^18.0.0 或 ^19.0.0

2. 引入样式

在项目入口文件(如 main.tsxApp.tsx)中引入样式:

// 引入 Ant Design 样式
import 'antd/dist/reset.css';

// 引入组件库样式
import 'gzkx-package/style';

3. 基本使用

导入并使用组件:

import { CommonPage } from 'gzkx-package';
import type { FormItemConfig } from 'gzkx-package';
import type { AddItemConfig } from 'gzkx-package';
import 'gzkx-package/dist/style.css';


const MyPage = () => {
  // 搜索表单配置
  const searchFormConfig: FormItemConfig[] = [
    {
      type: 'input',
      label: '姓名',
      name: 'name',
      colSpan: 6,
    },
  ];

  // 新增/编辑表单配置
  const addFormConfig: AddItemConfig[] = [
    {
      type: 'input',
      label: '姓名',
      name: 'name',
      rules: [{ required: true, message: '请输入姓名' }],
      colSpan: 12,
    },
  ];

  // 表格列配置
  const tableColumns = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
      width: 150,
    },
  ];

  // API 地址配置
  const URL = {
    search: '/user/list',
    add: '/user/add',
    edit: '/user/edit',
    delete: '/user/delete',
  };

  return (
    <CommonPage
      searchFormConfig={searchFormConfig}
      addFormConfig={addFormConfig}
      tableColumns={tableColumns}
      URL={URL}
      tableId="my-table"
      isReset={true}
    />
  );
};

export default MyPage;

4. 导出组件列表

本组件库主要导出以下组件:

| 组件名 | 说明 | 导入方式 | |--------|------|---------| | CommonPage | 通用页面组件 | import { CommonPage } from 'gzkx-package' | | CustomTable | 自定义表格组件 | import { CustomTable } from 'gzkx-package' | | CustomForm | 自定义表单组件 | import { CustomForm } from 'gzkx-package' | | CustomAdd | 新增/编辑弹窗组件 | import { CustomAdd } from 'gzkx-package' |

5. TypeScript 类型导出

import type { 
  FormItemConfig,      // 搜索表单配置类型
  AddItemConfig,       // 新增/编辑表单配置类型
  ValidateConfig,      // 验证配置类型
  CommonPageHandle,    // CommonPage Ref 类型
  CustomTableHandle,   // CustomTable Ref 类型
  CustomColumnType,    // 自定义表格列类型
  CustomColumnsType,   // 自定义表格列数组类型
} from 'gzkx-package';

组件列表

1. CommonPage 通用页面组件

1.1 组件概述

CommonPage 是一个集成了搜索表单、数据表格、新增/编辑弹窗的通用页面组件,适用于大部分 CRUD 操作场景。

1.2 Props 参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | searchFormConfig | FormItemConfig[] \| null | 是 | - | 搜索表单配置项数组 | | addFormConfig | AddItemConfig[] | 是 | - | 新增/编辑表单配置项数组 | | tableColumns | any[] | 是 | - | 表格列配置数组 | | URL | object | 是 | - | API 接口地址配置,包含 search, add, edit, delete, view | | tableId | string | 否 | - | 表格唯一 ID,用于保存用户的表格配置 | | isnopage | boolean | 否 | false | 是否不分页 | | topHeight | number | 否 | - | 顶部高度(像素) | | tableHeight | number | 否 | 150 | 表格高度调整参数 | | actionWidth | number | 否 | 150 | 操作列宽度 | | editText | string | 否 | '编辑' | 编辑按钮文本 | | viewText | string | 否 | '查看' | 查看按钮文本 | | delText | string | 否 | '删除' | 删除按钮文本 | | isaddtab | boolean | 否 | false | 新增/编辑表单是否分 Tab 显示 | | isReset | boolean | 否 | false | 是否显示重置按钮 | | addisdisabled | object | 否 | { isdisabled: false, message: '' } | 新增按钮禁用配置 | | postParams | object | 否 | - | 请求参数配置对象 | | limit | object | 否 | 全部为 true | 操作权限限制配置 | | CustomOperations | ReactNode \| Function | 否 | - | 自定义操作列内容 | | PropOtherButton | ReactNode \| Function | 否 | - | 搜索表单右侧的其他按钮 | | CustomModalFooter | Function | 否 | - | 自定义弹窗底部按钮 | | proplist | any[] | 否 | - | 假数据(用于测试) | | editdclickback | Function | 否 | - | 点击编辑/新增时的回调函数 | | oneditFormChange | Function | 否 | - | 编辑表单值变化时的回调 | | onSearchFormChange | Function | 否 | - | 搜索表单值变化时的回调 | | onRowClick | Function | 否 | - | 表格行点击回调 | | onDelete | Function | 否 | - | 删除成功后的回调 | | onSearch | Function | 否 | - | 搜索按钮点击后的回调 | | onReset | Function | 否 | - | 重置按钮点击后的回调 | | onView | Function | 否 | - | 查看按钮点击后的回调 | | validateConfig | ValidateConfig | 否 | - | 表单验证配置 | | tableConfig | any | 否 | - | 表格额外配置 |

1.2.1 详细参数说明

postParams 对象结构:

{
  addParams?: any;      // 新增时额外携带的参数
  delParams?: any;      // 删除时额外携带的参数
  editParams?: any;     // 编辑时额外携带的参数
  searchParams?: any;   // 搜索时额外携带的参数
}

limit 对象结构:

{
  addLimit?: boolean;    // 是否显示新增按钮,默认 true
  delLimit?: boolean;    // 是否显示删除按钮,默认 true
  editLimit?: boolean;   // 是否显示编辑按钮,默认 true
  searchLimit?: boolean; // 是否显示搜索功能,默认 true
}

URL 对象结构:

{
  search: string;   // 查询接口地址
  add?: string;     // 新增接口地址
  edit?: string;    // 编辑接口地址
  delete?: string;  // 删除接口地址
  view?: string;    // 查看接口地址(可选,如果没有则使用 edit)
}

1.3 Ref 暴露的方法

使用 ref 可以调用组件内部方法:

interface CommonPageHandle {
  getList: (parentParams?: any) => Promise<void>;  // 刷新列表
  setFieldsValue: (values: any) => void;           // 设置表单字段值
  getFieldsValue: () => any;                        // 获取表单字段值
  reload: () => void;                               // 重新加载列表
  getSearchFieldsValue: () => any;                  // 获取搜索表单值
  setSearchFieldsValue: (values: any) => void;      // 设置搜索表单值
  /** 打开表格配置弹窗 */
  openSettingModal: () => void;                     // 打开表格配置弹窗
  /** 关闭表格配置弹窗 */
  closeSettingModal: () => void;                    // 关闭表格配置弹窗
}

1.4 使用示例

import { useRef } from 'react';
import CommonPage, { CommonPageHandle } from '@/components/customComponents/commonPage';
import { FormItemConfig } from '@/components/customComponents/CustomForm';
import { AddItemConfig } from '@/components/customComponents/CustomAdd';

const DemoPage = () => {
  const pageRef = useRef<CommonPageHandle>(null);

  // 搜索表单配置
  const searchFormConfig: FormItemConfig[] = [
    {
      type: 'input',
      label: '姓名',
      name: 'name',
      placeholder: '请输入姓名',
      colSpan: 6,
    },
    {
      type: 'select',
      label: '状态',
      name: 'status',
      options: [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 },
      ],
      colSpan: 6,
    },
    {
      type: 'rangePicker',
      label: '日期范围',
      name: 'createTime/endTime',
      colSpan: 6,
    },
  ];

  // 新增/编辑表单配置
  const addFormConfig: AddItemConfig[] = [
    {
      type: 'input',
      label: '姓名',
      name: 'name',
      rules: [{ required: true, message: '请输入姓名' }],
      colSpan: 12,
    },
    {
      type: 'InputNumber',
      label: '年龄',
      name: 'age',
      colSpan: 12,
    },
    {
      type: 'Radio',
      label: '性别',
      name: 'gender',
      options: [
        { label: '男', value: 1 },
        { label: '女', value: 0 },
      ],
      colSpan: 12,
    },
    {
      type: 'textarea',
      label: '备注',
      name: 'remark',
      colSpan: 24,
    },
  ];

  // 表格列配置
  const tableColumns = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
      width: 150,
    },
    {
      title: '年龄',
      dataIndex: 'age',
      key: 'age',
      width: 100,
    },
    {
      title: '性别',
      dataIndex: 'gender',
      key: 'gender',
      width: 100,
      render: (text: number) => (text === 1 ? '男' : '女'),
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
      width: 180,
    },
  ];

  // API 地址配置
  const URL = {
    search: '/api/user/list',
    add: '/api/user/add',
    edit: '/api/user/edit',
    delete: '/api/user/delete',
  };

  return (
    <CommonPage
      ref={pageRef}
      searchFormConfig={searchFormConfig}
      addFormConfig={addFormConfig}
      tableColumns={tableColumns}
      URL={URL}
      tableId="user-table"
      isReset={true}
      postParams={{
        searchParams: { orgId: '123' },
      }}
      onRowClick={(record) => {
        console.log('点击了行:', record);
      }}
      onDelete={(record) => {
        console.log('删除了:', record);
      }}
      onSearch={() => {
        console.log('搜索触发');
      }}
      onReset={() => {
        console.log('重置触发');
      }}
      onView={(record) => {
        console.log('查看了:', record);
      }}
    />
  );
};

export default DemoPage;

2. CustomTable 自定义表格组件

2.1 组件概述

CustomTable 是对 Ant Design Table 组件的增强封装,支持用户自定义表格列配置、保存配置到后端、序号列、树形数据等功能。

2.2 Props 参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | columns | ColumnsType<any> | 是 | - | 表格列配置 | | dataSource | any[] | 是 | - | 表格数据源 | | loading | boolean | 否 | false | 加载状态 | | pagination | object \| false | 否 | - | 分页配置 | | handleTableChange | Function | 否 | - | 表格变化回调 | | size | 'small' \| 'middle' \| 'large' | 否 | 'middle' | 表格尺寸 | | tableId | string | 否 | - | 表格唯一 ID,用于保存列配置 | | onRowClick | Function | 否 | - | 行点击回调 | | page | object | 否 | - | 分页信息(用于序号计算) | | showTableConfig | boolean | 否 | true | 是否显示表格配置按钮和序号列 | | ...rest | any | 否 | - | 其他 Ant Design Table 原生属性 |

2.3 特色功能

  1. 表格配置功能:用户可以自定义列的显示、宽度、对齐方式、排序等,配置会保存到后端。
  2. 自动序号列:自动添加序号列(可通过 showTableConfig 控制)。
  3. 树形数据支持:支持展开/收起树形数据。
  4. Tooltip 支持:单元格内容过长时自动显示 Tooltip。

2.4 Ref 暴露的方法

使用 ref 可以调用组件内部方法:

interface CustomTableHandle {
  openSettingModal: () => void;   // 打开表格配置弹窗
  closeSettingModal: () => void;  // 关闭表格配置弹窗
}

使用示例:

import { useRef } from 'react';
import CustomTable, { CustomTableHandle } from '@/components/customComponents/CustomTable';

const Demo = () => {
  const tableRef = useRef<CustomTableHandle>(null);

  const handleOpenConfig = () => {
    tableRef.current?.openSettingModal();
  };

  return (
    <>
      <Button onClick={handleOpenConfig}>打开表格配置</Button>
      <CustomTable
        ref={tableRef}
        columns={columns}
        dataSource={dataSource}
        tableId="my-table"
      />
    </>
  );
};

2.5 使用示例

import CustomTable from '@/components/customComponents/CustomTable';

const DemoTable = () => {
  const [dataSource, setDataSource] = useState([]);
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: 10,
    total: 0,
  });

  const columns = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
      width: 150,
    },
    {
      title: '年龄',
      dataIndex: 'age',
      key: 'age',
      width: 100,
    },
    {
      title: '地址',
      dataIndex: 'address',
      key: 'address',
      width: 300,
    },
  ];

  return (
    <CustomTable
      columns={columns}
      dataSource={dataSource}
      loading={loading}
      pagination={pagination}
      tableId="demo-table"
      page={pagination}
      showTableConfig={true}
      onRowClick={(record) => {
        console.log('点击行:', record);
      }}
      handleTableChange={(newPagination) => {
        setPagination(newPagination);
      }}
    />
  );
};

2.6 列配置弹窗说明

showTableConfig={true} 时,序号列旁边会显示设置图标,点击后打开配置弹窗,可以配置:

  • 显示名称:列的显示标题
  • 表头对齐:左/中/右对齐
  • 内容对齐:左/中/右对齐
  • 数据格式:字符串/数字/日期
  • 宽度:列宽
  • 是否启用:是否显示该列
  • 允许排序:是否允许排序
  • 排序:列的显示顺序

3. CustomForm 自定义表单组件

3.1 组件概述

CustomForm 是一个基于配置的表单组件,通过传入配置数组即可快速生成表单,支持多种表单项类型。

3.2 Props 参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | config | FormItemConfig[] | 是 | - | 表单项配置数组 | | onFinish | Function | 否 | - | 表单提交回调 | | onSearch | Function | 否 | - | 搜索按钮点击回调 | | onReset | Function | 否 | - | 重置按钮点击回调 | | initialValues | object | 否 | - | 表单初始值 | | layout | 'horizontal' \| 'vertical' \| 'inline' | 否 | 'horizontal' | 表单布局 | | labelCol | object | 否 | { span: 5 } | label 栅格布局 | | wrapperCol | object | 否 | { span: 19 } | 控件栅格布局 | | submitButtonText | string | 否 | '搜索' | 提交按钮文本 | | resetButtonText | string | 否 | '重置' | 重置按钮文本 | | isReset | boolean | 否 | false | 是否显示重置按钮 | | OtherButton | ReactNode \| Function | 否 | - | 其他按钮 | | onSearchFormChange | Function | 否 | - | 表单值变化回调 | | ...restFormProps | any | 否 | - | 其他 Ant Design Form 原生属性 |

3.3 FormItemConfig 配置项

interface FormItemConfig {
  type: 'input' | 'select' | 'rangePicker' | 'datePicker' | 'password' | 
        'treeSelect' | 'radio' | 'deptSelect' | 'orgSelect';
  label: string;              // 标签文本
  name: string;               // 字段名
  placeholder?: string;       // 占位符
  options?: FormItemOption[]; // 选项(用于 select、radio 等)
  rules?: any[];              // 验证规则
  colSpan?: number;           // 栅格占位(默认 6,即一行 4 个)
  labelCol?: number;          // label 栅格占位(默认 5)
  wrapperCol?: number;        // 控件栅格占位(默认 19)
  initialValue?: any;         // 初始值
  defaultValue?: any;         // 默认值
  [key: string]: any;         // 其他属性
}

interface FormItemOption {
  label: React.ReactNode;
  value: string | number;
}

3.4 支持的表单类型

| type 值 | 说明 | 额外属性 | |---------|------|---------| | input | 普通输入框 | - | | password | 密码输入框 | - | | select | 下拉选择 | options | | radio | 单选框 | options | | rangePicker | 日期范围选择 | - | | datePicker | 日期选择 | - | | treeSelect | 树形选择 | options (treeData 格式) | | deptSelect | 科室选择(自动加载数据) | - | | orgSelect | 机构选择(自动加载数据) | - |

3.5 Ref 暴露的方法

interface CustomFormHandle {
  setFieldsValue: (values: any) => void;  // 设置表单值
  getFieldsValue: () => any;              // 获取表单值
}

3.6 使用示例

import { useRef } from 'react';
import CustomForm, { FormItemConfig } from '@/components/customComponents/CustomForm';

const DemoForm = () => {
  const formRef = useRef<any>(null);

  const formConfig: FormItemConfig[] = [
    {
      type: 'input',
      label: '用户名',
      name: 'username',
      placeholder: '请输入用户名',
      colSpan: 6,
      rules: [{ required: true, message: '请输入用户名' }],
    },
    {
      type: 'select',
      label: '角色',
      name: 'role',
      options: [
        { label: '管理员', value: 'admin' },
        { label: '普通用户', value: 'user' },
      ],
      colSpan: 6,
    },
    {
      type: 'rangePicker',
      label: '日期范围',
      name: 'dateRange',
      colSpan: 6,
    },
    {
      type: 'orgSelect',
      label: '机构',
      name: 'orgId',
      colSpan: 6,
    },
  ];

  const handleSearch = (values: any) => {
    console.log('搜索参数:', values);
  };

  const handleReset = (form: any) => {
    console.log('重置表单');
  };

  return (
    <CustomForm
      ref={formRef}
      config={formConfig}
      onSearch={handleSearch}
      onReset={handleReset}
      isReset={true}
      submitButtonText="查询"
      resetButtonText="重置"
      OtherButton={
        <Button onClick={() => console.log(formRef.current?.getFieldsValue())}>
          获取表单值
        </Button>
      }
    />
  );
};

4. CustomAdd 新增/编辑弹窗组件

4.1 组件概述

CustomAdd 是一个功能强大的弹窗表单组件,支持新增、编辑、查看三种模式,支持多种表单项类型、表单验证、Tab 分组等。

4.2 Props 参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | visible | boolean | 是 | - | 弹窗是否可见 | | mode | 'add' \| 'edit' \| 'view' | 是 | - | 模式:新增/编辑/查看 | | config | AddItemConfig[] | 是 | - | 表单项配置数组 | | initialValues | object | 否 | - | 初始值(编辑/查看模式) | | onOk | Function | 是 | - | 确定按钮回调 | | onCancel | Function | 是 | - | 取消按钮回调 | | title | string | 否 | 自动生成 | 弹窗标题 | | loading | boolean | 否 | false | 确定按钮加载状态 | | tab | boolean | 否 | false | 是否分 Tab 显示 | | modalProps | object | 否 | - | Modal 额外属性 | | oneditFormChange | Function | 否 | - | 表单值变化回调 | | CustomModalFooter | Function | 否 | - | 自定义底部按钮 | | validateConfig | ValidateConfig | 否 | - | 验证配置 |

4.3 AddItemConfig 配置项

interface AddItemConfig {
  type: 'input' | 'inputoption' | 'inputnumberoption' | 'select' | 
        'rangePicker' | 'datePicker' | 'password' | 'InputNumber' | 
        'Radio' | 'upload' | 'textarea' | 'area' | 'treeSelect' | 
        'richText' | 'doubleValue' | 'file' | 'deptSelect' | 
        'orgSelect' | 'uploadByte';
  label: string;                // 标签文本
  name: string;                 // 字段名
  placeholder?: string;         // 占位符
  options?: FormItemOption[];   // 选项
  rules?: any[];                // 验证规则
  colSpan?: number;             // 栅格占位(默认 6)
  defaultValue?: any;           // 默认值
  
  // 特殊字段(根据 type 使用)
  optionname?: string;          // inputoption 类型的下拉框字段名
  labelName?: string;           // select 类型保存 label 的字段名
  firstLabel?: string;          // doubleValue 第一个输入框字段名
  secondLabel?: string;         // doubleValue 第二个输入框字段名
  separator?: string;           // doubleValue 分隔符
  dateFormat?: string;          // 日期格式化字符串
  
  [key: string]: any;           // 其他属性
}

4.4 支持的表单类型

| type 值 | 说明 | 额外配置 | |---------|------|---------| | input | 普通输入框 | 支持拼音码自动生成 | | password | 密码输入框 | - | | textarea | 多行文本 | - | | InputNumber | 数字输入框 | - | | select | 下拉选择 | options, labelName | | Radio | 单选框 | options | | datePicker | 日期选择 | dateFormat | | rangePicker | 日期范围 | dateFormat,name 格式:"startDate/endDate" | | treeSelect | 树形选择 | options, multiple | | upload | 图片上传 | - | | file | 文件上传 | - | | uploadByte | 字节流上传 | - | | area | 地址选择器 | - | | richText | 富文本编辑器 | - | | deptSelect | 科室选择 | - | | orgSelect | 机构选择 | - | | inputoption | 输入框+下拉框组合 | optionname, options | | inputnumberoption | 数字输入框+下拉框组合 | optionname, options | | doubleValue | 双输入框(如范围) | firstLabel, secondLabel, separator |

4.5 ValidateConfig 验证配置

interface ValidateConfig {
  validateApi: string;              // 验证接口地址
  validateFields: string[];         // 需要验证的字段名数组
  validateMethod?: 'GET' | 'POST';  // 请求方法,默认 POST
  validateParams?: (values: any) => any; // 自定义验证参数处理函数
  validateMessage?: string;         // 验证失败提示,默认 "验证失败"
  union?: boolean;                  // 是否联合验证,默认 true
  realtime?: boolean;               // 是否实时验证,默认 false
  realtimeDelay?: number;           // 实时验证防抖延迟(毫秒),默认 500
  group?: string[][];               // 分组验证配置
}

4.6 Ref 暴露的方法

interface CustomAddHandle {
  setFieldsValue: (values: any) => void;  // 设置表单值
  getFieldsValue: () => any;              // 获取表单值
}

4.7 使用示例

4.7.1 基础使用

import { useState, useRef } from 'react';
import CustomAdd, { AddItemConfig } from '@/components/customComponents/CustomAdd';

const Demo = () => {
  const [visible, setVisible] = useState(false);
  const [mode, setMode] = useState<'add' | 'edit' | 'view'>('add');
  const [initialValues, setInitialValues] = useState<any>(null);
  const addRef = useRef<any>(null);

  const addFormConfig: AddItemConfig[] = [
    {
      type: 'input',
      label: '姓名',
      name: 'name',
      rules: [{ required: true, message: '请输入姓名' }],
      colSpan: 12,
    },
    {
      type: 'InputNumber',
      label: '年龄',
      name: 'age',
      colSpan: 12,
    },
    {
      type: 'Radio',
      label: '性别',
      name: 'gender',
      options: [
        { label: '男', value: 1 },
        { label: '女', value: 0 },
      ],
      colSpan: 12,
      defaultValue: 1,
    },
    {
      type: 'datePicker',
      label: '出生日期',
      name: 'birthDate',
      dateFormat: 'YYYY-MM-DD',
      colSpan: 12,
    },
    {
      type: 'orgSelect',
      label: '所属机构',
      name: 'orgId',
      rules: [{ required: true, message: '请选择机构' }],
      colSpan: 12,
    },
    {
      type: 'deptSelect',
      label: '所属科室',
      name: 'deptId',
      colSpan: 12,
    },
    {
      type: 'textarea',
      label: '备注',
      name: 'remark',
      colSpan: 24,
    },
  ];

  const handleOk = async (values: any) => {
    console.log('提交的值:', values);
    // 调用接口...
    setVisible(false);
  };

  return (
    <>
      <Button onClick={() => { setMode('add'); setVisible(true); }}>
        新增
      </Button>

      <CustomAdd
        ref={addRef}
        visible={visible}
        mode={mode}
        config={addFormConfig}
        initialValues={initialValues}
        onOk={handleOk}
        onCancel={() => setVisible(false)}
        loading={false}
      />
    </>
  );
};

4.7.2 分 Tab 使用

const tabFormConfig = [
  {
    label: '基本信息',
    children: [
      {
        type: 'input',
        label: '姓名',
        name: 'name',
        rules: [{ required: true, message: '请输入姓名' }],
        colSpan: 12,
      },
      {
        type: 'InputNumber',
        label: '年龄',
        name: 'age',
        colSpan: 12,
      },
    ],
  },
  {
    label: '详细信息',
    children: [
      {
        type: 'textarea',
        label: '个人简介',
        name: 'bio',
        colSpan: 24,
      },
    ],
  },
];

<CustomAdd
  visible={visible}
  mode={mode}
  config={tabFormConfig}
  tab={true}  // 启用 Tab
  onOk={handleOk}
  onCancel={() => setVisible(false)}
/>

4.7.3 带验证配置

const validateConfig: ValidateConfig = {
  validateApi: '/api/user/validate',
  validateFields: ['username', 'email'],
  validateMethod: 'POST',
  union: true,              // 联合验证
  realtime: true,           // 实时验证
  realtimeDelay: 500,       // 500ms 防抖
  validateMessage: '字段重复',
};

<CustomAdd
  visible={visible}
  mode={mode}
  config={addFormConfig}
  validateConfig={validateConfig}
  onOk={handleOk}
  onCancel={() => setVisible(false)}
/>

4.7.4 特殊类型示例

// 双输入框(范围)
{
  type: 'doubleValue',
  label: '价格范围',
  name: 'priceRange',
  firstLabel: 'minPrice',
  secondLabel: 'maxPrice',
  firstPlaceholder: '最低价',
  secondPlaceholder: '最高价',
  separator: '至',
  lastUnit: '元',
  colSpan: 24,
}

// 输入框+下拉框组合
{
  type: 'inputoption',
  label: '剂量',
  name: 'dosage',
  optionname: 'dosageUnit',
  options: [
    { label: 'mg', value: 'mg' },
    { label: 'g', value: 'g' },
  ],
  colSpan: 12,
}

// 日期范围(自动拆分为两个字段)
{
  type: 'rangePicker',
  label: '有效期',
  name: 'startDate/endDate',  // 会自动拆分为 startDate 和 endDate
  dateFormat: 'YYYY-MM-DD',
  colSpan: 12,
}

5. 常见使用场景

5.1 完整的 CRUD 页面

import { useRef } from 'react';
import CommonPage from '@/components/customComponents/commonPage';

const UserManagePage = () => {
  const pageRef = useRef<any>(null);

  const searchFormConfig = [
    { type: 'input', label: '用户名', name: 'username', colSpan: 6 },
    { type: 'input', label: '手机号', name: 'phone', colSpan: 6 },
    { 
      type: 'select', 
      label: '状态', 
      name: 'status', 
      options: [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 },
      ],
      colSpan: 6,
    },
  ];

  const addFormConfig = [
    { 
      type: 'input', 
      label: '用户名', 
      name: 'username', 
      rules: [{ required: true, message: '请输入用户名' }],
      colSpan: 12,
    },
    { 
      type: 'password', 
      label: '密码', 
      name: 'password', 
      rules: [{ required: true, message: '请输入密码' }],
      colSpan: 12,
    },
    { type: 'input', label: '手机号', name: 'phone', colSpan: 12 },
    { type: 'input', label: '邮箱', name: 'email', colSpan: 12 },
    { 
      type: 'Radio', 
      label: '状态', 
      name: 'status', 
      options: [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 },
      ],
      defaultValue: 1,
      colSpan: 12,
    },
  ];

  const tableColumns = [
    { title: '用户名', dataIndex: 'username', key: 'username', width: 150 },
    { title: '手机号', dataIndex: 'phone', key: 'phone', width: 150 },
    { title: '邮箱', dataIndex: 'email', key: 'email', width: 200 },
    { 
      title: '状态', 
      dataIndex: 'status', 
      key: 'status', 
      width: 100,
      render: (text: number) => text === 1 ? '启用' : '禁用',
    },
    { title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
  ];

  const URL = {
    search: '/api/user/list',
    add: '/api/user/add',
    edit: '/api/user/edit',
    delete: '/api/user/delete',
  };

  return (
    <CommonPage
      ref={pageRef}
      searchFormConfig={searchFormConfig}
      addFormConfig={addFormConfig}
      tableColumns={tableColumns}
      URL={URL}
      tableId="user-management-table"
      isReset={true}
    />
  );
};

5.2 自定义操作列

<CommonPage
  searchFormConfig={searchFormConfig}
  addFormConfig={addFormConfig}
  tableColumns={tableColumns}
  URL={URL}
  CustomOperations={(record) => (
    <>
      <a onClick={() => handleResetPassword(record)}>重置密码</a>
      <a onClick={() => handleAssignRole(record)}>分配角色</a>
    </>
  )}
/>

5.3 带权限控制

<CommonPage
  searchFormConfig={searchFormConfig}
  addFormConfig={addFormConfig}
  tableColumns={tableColumns}
  URL={URL}
  limit={{
    addLimit: hasPermission('user:add'),
    editLimit: hasPermission('user:edit'),
    delLimit: hasPermission('user:delete'),
    searchLimit: true,
  }}
/>

6. 注意事项

6.1 表单字段命名

  1. 日期范围字段:使用 / 分隔,如 startDate/endDate,组件会自动拆分为两个字段。
  2. 输入框+下拉框组合:使用 nameoptionname 分别定义两个字段。
  3. 双输入框:使用 firstLabelsecondLabel 定义两个字段名。

6.2 数据格式

  1. 日期数据:后端返回的日期字符串会自动转换为 dayjs 对象,提交时根据 dateFormat 格式化。
  2. 树形选择多选:多选时,后端返回逗号分隔的字符串(如 "1,2,3"),组件会自动转换为数组。

6.3 性能优化

  1. tableId:为表格设置唯一 ID,用户的列配置会保存到后端,避免每次都重新配置。
  2. 防抖:组件内部已对列表刷新、实时验证等操作做了防抖处理。

6.4 样式定制

组件使用了 CSS Modules,如需定制样式,可以:

  1. 通过 className 传入自定义类名
  2. 通过 style 传入内联样式
  3. 修改组件的 .less 文件

7. 常见问题

Q1: 如何在表单提交前进行自定义验证?

使用 validateConfig 配置,指定验证接口和字段:

const validateConfig = {
  validateApi: '/api/validate',
  validateFields: ['username'],
  realtime: true,
};

Q2: 如何实现联动选择(如省市区)?

  1. CustomForm 中使用 onSearchFormChange 监听字段变化
  2. CustomAdd 中使用 oneditFormChange 监听字段变化
<CustomAdd
  oneditFormChange={(changedValues, allValues) => {
    if (changedValues.provinceId) {
      // 加载对应的城市列表
      loadCities(changedValues.provinceId);
    }
  }}
/>

Q3: 如何获取/设置表单值?

使用 ref 调用组件方法:

const formRef = useRef<any>(null);

// 获取值
const values = formRef.current?.getFieldsValue();

// 设置值
formRef.current?.setFieldsValue({ name: '张三' });

Q4: 查看模式如何支持双击复制?

CustomAdd 组件在 view 模式下,大部分字段支持双击复制功能,会自动将字段值复制到剪贴板。

Q5: 如何实现表格行高亮选中?

CommonPage 中,点击的行会自动高亮,通过 currentRecord 状态和 rowClassName 实现。


8. 更新日志

  • 2025-11-24: CustomTable 添加了表格配置保存功能
  • 2025-04-27: CommonPage 组件创建
  • 2025-04-23: CustomTable 组件创建

9. 技术支持

如有问题,请联系开发团队或查看源代码注释。