2. 设计页面
默认情况下平台会为每个 model 自动生成空的页面 stub。本章将这些 stub 替换为手工设计的列表、详情与表单页面 — 全程在 Page Designer 这一基于 schema 的可视化画布中完成,block、列、字段都是可视化配置,绝不手写 .tsx。
预计耗时:30–40 分钟。

2.1 Lead 列表页
打开 Designer → Pages → crm_lead/list 并配置:
- 列:
name、email、source、score、status、created_at - 筛选:
status、source,以及在name|email上的自由文本搜索 - 行操作:Open、Qualify(调用
crm:qualify_leadCommand) - 工具栏操作:+ New Lead 打开表单

画布左侧是 block 树,中间是实时预览,右侧是属性面板。拖一个 table block,绑到 crm_lead model,再从字段调色板里挑列加进去 — 没有 JSX,不需要重新打包。

2.2 Lead 表单
表单应将 field 分成两段:
- Contact:
name、email、phone、source - Qualification:
score、status、notes
将 name、email、source、status 标记为必填。Designer 会渲染星号,并在空提交时拒绝保存。
2.3 Lead 详情
使用两列布局。左列:contact + qualification。右列:一个自定义 block recent-activity(将在第 4 章接入)。
2.4 Account 页面
对 Account,列表展示 name / tier / owner / # opportunities。最后一列是计算得到的只读汇总 —— 可以作为 model 的虚拟 field,也可以作为页面定义中的自定义列。

2.5 Opportunity 页面
Opportunity 列表是 CRM 的核心。看板风格的“按 stage 分组”与“sum amount”不在页面定义里配置,而是通过一个 saved view(已保存视图,viewType: "kanban")实现 —— 在 viewConfig 里用 groupByField 指定分组字段,用 kanbanAggregations 配置随筛选刷新的汇总:
// saved-views.json 节选
{
"name": "Pipeline Board",
"modelCode": "crm_opportunity",
"pageKey": "crm_opportunity",
"viewType": "kanban",
"viewConfig": {
"groupByField": "crm_opp_stage",
"groupByDictCode": "crm_opp_stage",
"kanbanAggregations": [
{ "field": "crm_opp_expected_amount", "function": "sum", "label": "Pipeline Value" }
]
}
}而列表页本体(crm_opportunity_list.json)是一个普通的 kind: "list" 页面,顶层用 modelCode、schemaVersion: 4 与 blocks(toolbar / tabs / table)。
2.6 验证
- 从菜单导航到 CRM → Leads / Accounts / Opportunities,确认每个页面可加载
- 尝试为每个 model 创建一条记录
- 确认必填 field 校验失败时显示字段级错误(而非泛化 toast)
- 确认原始 code(如
crm_lead、mt_crm_lead)绝不会出现在列头、label 或错误消息里 —— 这些是 页面金标闸门 的红线
下一步
