npm.io
0.1.70 • Published 5d ago

gzkx-package

Licence
MIT
Version
0.1.70
Deps
14
Size
4.7 MB
Vulns
0
Weekly
1.1K

自定义组件使用文档

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


目录


安装

使用 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'
useHotkeyListener 组合键监听 Hook import { useHotkeyListener } from 'gzkx-package'
useTakeShotHotkey 截图专用组合键 Hook import { useTakeShotHotkey } from 'gzkx-package'
takeShot 截图接口 import { takeShot } from 'gzkx-package'
5. TypeScript 类型导出
import type { 
  FormItemConfig,      // 搜索表单配置类型
  AddItemConfig,       // 新增/编辑表单配置类型
  ValidateConfig,      // 验证配置类型
  CommonPageHandle,    // CommonPage Ref 类型
  CustomTableHandle,   // CustomTable Ref 类型
  CustomColumnType,    // 自定义表格列类型
  CustomColumnsType,   // 自定义表格列数组类型
  HotkeyConfig,        // 组合键配置类型
} from 'gzkx-package';

组件列表

1. 工具 Hooks

1.1 useHotkeyListener - 组合键监听 Hook

用于监听键盘组合键(如 Ctrl+SAlt+F2Ctrl+Shift+A 等)。

参数
参数名 类型 必填 默认值 说明
hotkeys HotkeyConfig[] - 监听的组合键配置数组
onTrigger (hotkey: HotkeyConfig, event: KeyboardEvent) => void - 组合键触发回调
preventDefault boolean false 是否阻止默认行为
stopPropagation boolean false 是否阻止事件冒泡
HotkeyConfig 配置
interface HotkeyConfig {
  key: string;      // 主键,如 'F2', 's', 'Enter'
  ctrl?: boolean;   // 是否按住 Ctrl
  alt?: boolean;    // 是否按住 Alt
  shift?: boolean;  // 是否按住 Shift
  meta?: boolean;   // 是否按住 Meta (Mac Command/Windows Win)
}
使用示例
import { useHotkeyListener } from 'gzkx-package';

const MyComponent = () => {
  // 监听多个组合键
  useHotkeyListener({
    hotkeys: [
      { key: 'F2' },                           // 单独 F2
      { key: 'F2', ctrl: true },               // Ctrl+F2
      { key: 's', ctrl: true, shift: true },   // Ctrl+Shift+S
      { key: 'a', alt: true },                 // Alt+A
    ],
    onTrigger: (hotkey, event) => {
      console.log('组合键触发:', hotkey);
      // 根据触发的组合键执行不同操作
    },
    preventDefault: true,  // 阻止默认行为(如 Ctrl+S 保存页面)
  });

  return <div>按 F2 或 Ctrl+F2 触发</div>;
};
1.2 useTakeShotHotkey - 截图专用组合键 Hook

专门用于截图功能的组合键监听 Hook,是 useHotkeyListener 的简化封装。

参数
参数名 类型 必填 默认值 说明
onTakeShot () => void - 截图触发回调
hotkeys HotkeyConfig[] [{ key: 'F2' }] 监听的组合键配置
使用示例
import { useTakeShotHotkey, takeShot } from 'gzkx-package';
import { message } from 'antd';

const UltrasoundWorkstation = () => {
  // 使用默认 F2 键截图
  useTakeShotHotkey(async () => {
    const result = await takeShot();
    if (result.code === 200) {
      message.success('截图成功');
      console.log('截图数据:', result.data?.imageBase64);
    } else {
      message.error(`截图失败: ${result.msg}`);
    }
  });

  // 或者自定义组合键
  useTakeShotHotkey(
    async () => {
      const result = await takeShot();
      // 处理截图结果...
    },
    [
      { key: 'F9' },                    // F9 截图
      { key: 'p', ctrl: true },         // Ctrl+P 截图
      { key: 's', ctrl: true, shift: true }, // Ctrl+Shift+S 截图
    ]
  );

  return <div>超声工作站 - 按 F9 或 Ctrl+P 截图</div>;
};
1.3 takeShot - 截图接口

调用本地截图服务进行截图。

配置方法
import { setTakeShotConfig, takeShot } from 'gzkx-package';

// 配置截图服务(通常在应用初始化时)
setTakeShotConfig({
  host: 'localhost',    // 截图服务主机
  port: 28081,          // 截图服务端口
  timeout: 10000,       // 请求超时时间(ms)
});
使用示例
const handleCapture = async () => {
  const result = await takeShot({
    format: 'png',      // 图片格式
    quality: 100,       // 图片质量
  });

  if (result.code === 200) {
    // result.data.imageBase64 - Base64 图片数据
    // result.data.imagePath - 图片保存路径
    console.log('截图成功:', result.data);
  } else {
    console.error('截图失败:', result.msg);
  }
};

3. CommonPage 通用页面组件

3.1 组件概述

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

3.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 - 表格额外配置
3.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)
}
3.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;                    // 关闭表格配置弹窗
}
3.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;

4. CustomTable 自定义表格组件

4.1 组件概述

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

4.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 原生属性
4.3 特色功能
  1. 表格配置功能:用户可以自定义列的显示、宽度、对齐方式、排序等,配置会保存到后端。
  2. 自动序号列:自动添加序号列(可通过 showTableConfig 控制)。
  3. 树形数据支持:支持展开/收起树形数据。
  4. Tooltip 支持:单元格内容过长时自动显示 Tooltip。
4.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);
      }}
    />
  );
};
4.6 列配置弹窗说明

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

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

5. CustomForm 自定义表单组件

5.1 组件概述

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

5.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 原生属性
5.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;
}
5.4 支持的表单类型
type 值 说明 额外属性
input 普通输入框 -
password 密码输入框 -
select 下拉选择 options
radio 单选框 options
rangePicker 日期范围选择 -
datePicker 日期选择 -
treeSelect 树形选择 options (treeData 格式)
deptSelect 科室选择(自动加载数据) -
orgSelect 机构选择(自动加载数据) -
5.5 Ref 暴露的方法
interface CustomFormHandle {
  setFieldsValue: (values: any) => void;  // 设置表单值
  getFieldsValue: () => any;              // 获取表单值
}
5.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>
      }
    />
  );
};

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

6.1 组件概述

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

6.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 - 验证配置
6.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;           // 其他属性
}
6.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
6.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[][];               // 分组验证配置
}
6.6 Ref 暴露的方法
interface CustomAddHandle {
  setFieldsValue: (values: any) => void;  // 设置表单值
  getFieldsValue: () => any;              // 获取表单值
}
6.7 使用示例
6.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)}
/>
6.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)}
/>
6.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,
}

7. 常见使用场景

7.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}
    />
  );
};
7.2 自定义操作列
<CommonPage
  searchFormConfig={searchFormConfig}
  addFormConfig={addFormConfig}
  tableColumns={tableColumns}
  URL={URL}
  CustomOperations={(record) => (
    <>
      <a onClick={() => handleResetPassword(record)}>重置密码</a>
      <a onClick={() => handleAssignRole(record)}>分配角色</a>
    </>
  )}
/>
7.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,
  }}
/>

8. 注意事项

8.1 表单字段命名
  1. 日期范围字段:使用 / 分隔,如 startDate/endDate,组件会自动拆分为两个字段。
  2. 输入框+下拉框组合:使用 nameoptionname 分别定义两个字段。
  3. 双输入框:使用 firstLabelsecondLabel 定义两个字段名。
8.2 数据格式
  1. 日期数据:后端返回的日期字符串会自动转换为 dayjs 对象,提交时根据 dateFormat 格式化。
  2. 树形选择多选:多选时,后端返回逗号分隔的字符串(如 "1,2,3"),组件会自动转换为数组。
8.3 性能优化
  1. tableId:为表格设置唯一 ID,用户的列配置会保存到后端,避免每次都重新配置。
  2. 防抖:组件内部已对列表刷新、实时验证等操作做了防抖处理。
8.4 样式定制

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

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

9. 常见问题

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 实现。


10. 更新日志

  • 2026-04-14: 新增组合键监听 Hooks (useHotkeyListener, useTakeShotHotkey) 和截图接口 (takeShot)
  • 2025-11-24: CustomTable 添加了表格配置保存功能
  • 2025-04-27: CommonPage 组件创建
  • 2025-04-23: CustomTable 组件创建

11. 技术支持

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

Keywords