edit | blame | history | raw

---
name: new-page

description: 当用户要创建新页面、新建新页面、新建页面、新增页面、加一个页面或搭建页面脚手架时使用。先选择分支:表格/列表页使用 ProTable 模板,表单/详情/仪表盘等非表格页使用 Ant Design 模板;两个分支都会生成 server.ts 维护接口调用,并统一执行代码规范、路由注册、文档更新与类型检查。

新增页面

为 CRM 管理后台新增页面。先选择分支并套用该分支的唯一模板,再执行公共步骤。

1. 选择分支

分支 适用场景 模板(整体复制)
表格页 列表、数据表格、带搜索/筛选/分页 templates/table-page/
非表格页 表单、详情、仪表盘、设置页、纯展示页 templates/non-table-page/

无法从需求判断时向用户确认。两个分支都不重复维护路由等公共逻辑,完成后统一执行第 4 节。

同时确认:

项目 说明 示例
业务域 决定目录 src/pages/<domain>/ system、business
页面名 目录名与组件名 invoices / Invoices
路由 完整路径,同时作为菜单 key /business/invoices
菜单标题 / 图标 中文标题 + @ant-design/icons 发票管理 / FileTextOutlined
数据来源 接口调用放在同目录 server.ts;演示阶段可先用本地 mock server.ts
是否分组 是否放入现有的「系统管理 / 业务管理」分组 children

表格页额外确认:字段、列展示方式、可搜索字段、分页大小。
非表格页额外确认:表单字段与校验、详情字段、布局形式。

2. 分支 A:表格页

模板目录:templates/table-page/,整体复制到 src/pages/<domain>/<page>/:

src/pages/<domain>/<page>/
├── index.tsx       # 页面组件(默认导出)
├── columns.tsx     # ProColumns<T>[] 列定义
├── types.ts        # 记录类型与查询参数
├── server.ts       # 接口调用(列表查询、删除等)
└── <Page>.scss     # 页面级样式(按需新增)

替换占位符:Xxx → 实体名(大驼峰),xxx → 目录/样式名(小写)。

该分支要求:

  • 使用 ProTable,不要手写「筛选表单 + Table」。
  • columns 必须放在独立 columns.tsx,类型为 ProColumns<T>[];需要回调时导出 createXxxColumns(options) 工厂函数。
  • 页面中用 useMemo 缓存 columns,用 useCallback 包裹事件处理函数。
  • request 单独定义:在组件内声明 const fetchList = useCallback((params: XxxListParams) => getXxxList(params).then((result) => ({ data: result.data, total: result.total, success: result.success })), []),再传给 request={fetchList};不要在 <ProTable /> 标签里内联箭头函数,也不要用 await + try/catch。
  • 页面组件不直接写请求:列表查询、删除等接口调用统一放在同目录的 server.ts,组件只调用导出的方法。
  • server.ts 使用 @/api/request 提供的 request 发送请求,不要直接使用 axios;泛型顺序为 request<请求参数, 响应数据>。
  • 分页使用 defaultPageSize(不要用受控的 pageSize);需要切换每页条数时设置 showSizeChanger: true。
  • 不需要右侧工具栏图标时用 options={false}。
  • 表格样式:有 toolBarRender 时不加 cardProps;没有 toolBarRender 时补充 cardProps={{ bodyStyle: { padding: 20 } }}。
  • 表格补充 scroll={{ x: ... }} 以兼容窄屏。

3. 分支 B:非表格页

模板文件:templates/non-table-page/index.tsx,复制到 src/pages/<domain>/<page>/index.tsx:

src/pages/<domain>/<page>/
├── index.tsx       # 页面组件(默认导出)
├── types.ts        # 表单 / 详情类型
├── server.ts       # 接口调用(保存、详情查询等)
└── <Page>.scss     # 页面级样式(按需新增)

表单页直接使用模板;详情页把 Form 换成 Descriptions,仪表盘使用 Card + Statistic + Row/Col。

该分支要求:

  • 不要创建 columns.tsx,不要使用 ProTable。
  • 表单使用 Ant Design Form + Form.Item + rules 校验。
  • 数据展示优先使用 Card、Descriptions、Statistic、Tag 等 Ant Design 组件。
  • 页面局部状态使用 useState,派生数据使用 useMemo。
  • 保存、详情查询等接口调用统一放在同目录的 server.ts,组件只调用导出的方法。
  • server.ts 使用 @/api/request 提供的 request 发送请求,不要直接使用 axios。

4. 公共步骤(两个分支都执行)

4.1 代码规范

  • 页面级接口调用统一放在页面目录的 server.ts,不要写在组件内部。
  • 统一使用 src/api/request.ts 的 request,不要直接使用 axios。默认会合并相同并发请求、自动提示错误,并只返回响应 data。
  • 接口请求使用 .then / .catch / .finally 链式处理,不要使用 await + try/catch。
  • 请求选项:merge 控制是否合并、showError 控制是否提示错误、parse: false 返回完整 AxiosResponse、signal 用于取消。
  • 全部使用箭头函数,不新增 function 声明。
  • 提示与确认框使用 AntdApp.useApp() 提供的 message / modal,不要用静态方法。
  • 使用 Ant Design 5 API,不使用已废弃属性(如 Card 用 variant="borderless")。
  • 页面只负责内容区域,外层布局由 BasicLayout 提供。
  • 不要在页面内添加标题 / 说明区块(如 .page-header),菜单和面包屑已标明页面名称,直接展示内容即可。
  • 页面级样式与页面同目录,使用 BEM 类名。
  • 不添加权限相关代码:本项目已移除权限体系。

4.2 注册路由

在 src/router/routeConfig.tsx 中增加配置,并补充组件与图标的 import:

{
  path: '/business/invoices',
  title: '发票管理',
  icon: <FileTextOutlined />,
  element: <Invoices />,
},

放入现有分组时写在其 children 中;新增一级分组时保持与现有分组相同的结构。

4.3 更新文档

如果新增的是演示页面,同步更新 README.md 的「演示页面」表格。不需要更新 CLAUDE.md。

4.4 验证

npm run typecheck

涉及样式或构建配置时再执行:

npm run build

完成后简要说明:分支类型、新增文件、路由地址,以及验证结果。

4.5 完成检查清单

  • [ ] 已选择正确分支并整体使用对应模板
  • [ ] 表格页使用 ProTable,columns 独立在 columns.tsx
  • [ ] request 已提取为独立的 useCallback 方法,未在标签内内联
  • [ ] 接口请求使用 .then 链式处理,没有 await + try/catch
  • [ ] 表格页无 toolBarRender 时已加 cardProps={{ bodyStyle: { padding: 20 } }},有 toolBarRender 时未加
  • [ ] 非表格页未创建 columns.tsx,使用合适的 Ant Design 组件
  • [ ] 两个分支均已创建 server.ts,组件内没有直接写请求
  • [ ] 类型使用 ProColumns<T> / 明确接口,没有 any
  • [ ] 全部使用箭头函数
  • [ ] 提示与确认框通过 AntdApp.useApp() 获取
  • [ ] 路由已注册,菜单与面包屑可正常显示
  • [ ] 页面没有重复的标题 / 说明区块(不使用 .page-header)
  • [ ] npm run typecheck 通过