---
name: new-page
为 CRM 管理后台新增页面。先选择分支并套用该分支的唯一模板,再执行公共步骤。
| 分支 | 适用场景 | 模板(整体复制) |
|---|---|---|
| 表格页 | 列表、数据表格、带搜索/筛选/分页 | 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 |
表格页额外确认:字段、列展示方式、可搜索字段、分页大小。
非表格页额外确认:表单字段与校验、详情字段、布局形式。
模板目录: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), []),再传给 request={fetchList};不要在 <ProTable /> 标签里内联箭头函数。server.ts,组件只调用导出的方法。server.ts 使用 @/api/request 提供的 request 发送请求,不要直接使用 axios;泛型顺序为 request<请求参数, 响应数据>。defaultPageSize(不要用受控的 pageSize);需要切换每页条数时设置 showSizeChanger: true。options={false}。toolBarRender 时不加 cardProps;没有 toolBarRender 时补充 cardProps={{ bodyStyle: { padding: 20 } }}。scroll={{ x: ... }} 以兼容窄屏。模板文件: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。Form + Form.Item + rules 校验。Card、Descriptions、Statistic、Tag 等 Ant Design 组件。useState,派生数据使用 useMemo。server.ts,组件只调用导出的方法。server.ts 使用 @/api/request 提供的 request 发送请求,不要直接使用 axios。server.ts,不要写在组件内部。src/api/request.ts 的 request,不要直接使用 axios。默认会合并相同并发请求、自动提示错误,并只返回响应 data。merge 控制是否合并、showError 控制是否提示错误、parse: false 返回完整 AxiosResponse、signal 用于取消。function 声明。AntdApp.useApp() 提供的 message / modal,不要用静态方法。variant="borderless")。BasicLayout 提供。.page-header),菜单和面包屑已标明页面名称,直接展示内容即可。在 src/router/routeConfig.tsx 中增加配置,并补充组件与图标的 import:
{
path: '/business/invoices',
title: '发票管理',
icon: <FileTextOutlined />,
element: <Invoices />,
},
放入现有分组时写在其 children 中;新增一级分组时保持与现有分组相同的结构。
如果新增的是演示页面,同步更新 README.md 的「演示页面」表格。不需要更新 CLAUDE.md。
npm run typecheck
涉及样式或构建配置时再执行:
npm run build
完成后简要说明:分支类型、新增文件、路由地址,以及验证结果。
columns.tsxrequest 已提取为独立的 useCallback 方法,未在标签内内联toolBarRender 时已加 cardProps={{ bodyStyle: { padding: 20 } }},有 toolBarRender 时未加columns.tsx,使用合适的 Ant Design 组件server.ts,组件内没有直接写请求ProColumns<T> / 明确接口,没有 anyAntdApp.useApp() 获取.page-header)npm run typecheck 通过