低代码 ERP 与 AI 结合架构整理
1. 背景与目标
这份文档整理的是一套低代码 ERP 平台的架构思路。
目标不是做一个普通的页面搭建器,也不是让 AI 直接去写大量业务代码,而是先搭出一个元数据驱动的 ERP 平台骨架。
这套平台的基本要求是:
- 可配置
- 可迁移
- 可审计
- 可长期维护
- AI 可以参与生成,但平台本身不能退化成任意脚本系统
整条路线的核心判断是:
不是“AI 到处写代码”,也不是“全部低代码一把梭”,而是“元数据驱动标准业务页 + 统一业务基础能力 + 受控扩展能力”。
2. 平台定位
这套系统的定位是:
元数据驱动的 ERP 平台
不是:
- 普通后台页面生成器
- 只会根据数据库字段生成 CRUD 页的工具
- 纯前端低代码页面系统
这套平台要覆盖的是:
- 业务对象建模
- 默认页面骨架生成
- 标准 ERP 页面低代码化
- 权限、动作、流程统一定义
- AI 生成配置
- 高度定制页面允许手写 View
同时要避开几件事:
- 字符串函数成为主路径
- 页面直接拼接原始接口地址
- 数据库结构永久绑死页面结构
- 低代码页面和手写页面裂成两套系统
3. 整体原则
3.1 标准业务页走低代码
第一批低代码重点覆盖的是标准 ERP 页面:
- 列表页
- 查询页
- 表单页
- 详情页
- 树表页
- 主子表页
- 审批页
- 基础门户页
这些页面的共同特征很明显:
- 结构相对稳定
- 交互模式重复度高
- 大多围绕表单、表格、树、工具栏、弹框、抽屉、查询区展开
3.2 高度定制页面走手写 View
驾驶舱、分析页、大屏、工作台这类页面不强行塞进低代码模板体系里,直接允许手写 View。
但手写页面也不另起一套业务系统,仍然走同一套基础能力:
- 路由元数据
- 权限模型
- Action Registry
- Service 层
- 实体元数据
- 流程接入点
- 审计日志
3.3 AI 生成的是业务意图,不是技术细节
AI 更适合产出的是:
- Schema
- 表达式
- Action 绑定
- 模板选择
- 权限配置
AI 不作为默认路径去产出这些东西:
- 原始接口 URL
- 任意副作用脚本
- 直接数据库写入逻辑
- 组件之间的隐式命令式耦合
4. 总体架构
flowchart TB
A["AI 生成层"] --> B["元数据 / Schema 层"]
B --> C["UI 层"]
B --> D["页面状态层"]
B --> E["Action 层"]
E --> F["Service 层"]
F --> G["后端元数据引擎"]
G --> H["数据库 / 存储层"]
G --> I["权限 / 流程 / 审计"]
C --> D
D --> E
4.1 AI 生成层
AI 负责生成结构化配置,不负责默认生成整套项目代码。
这一层主要产出:
- 实体定义
- 字段定义
- 页面定义
- 模板选择
- Action 绑定
- 权限表达式
4.2 元数据 / Schema 层
这一层是平台的中心。
它定义的是:
- 有哪些实体
- 有哪些字段
- 有哪些页面
- 页面里有哪些块
- 页面能调用哪些动作
- 哪些权限规则生效
4.3 UI 层
UI 层按三层组织:
- 基础组件
- 组合组件
- 页面模板
4.4 页面状态层
这里对应页面的唯一数据层。
核心点不是做一个“大对象”,而是做一个统一的页面状态模型。
4.5 Action 层
Action 层是整个平台最关键的执行层。
所有有副作用的动作都统一放到这里处理:
- 查询
- 提交
- 审批
- 同步
- 发消息
- 打开弹框
- 刷新联动区域
- 页面跳转
4.6 Service 层
Service 层保持薄,只做这些事:
- 请求封装
- 鉴权头处理
- 超时 / 重试
- 错误结构标准化
Service 不作为业务动作入口。
4.7 后端元数据引擎
后端不只是“按字段建表”,而是根据元数据产出一套后端基础能力:
- 表结构
- 默认 API
- 默认 CRUD Action
- 校验规则
- 权限校验
- 流程接入点
- 审计日志
5. UI 分层
flowchart LR
A["低代码基础组件"] --> B["表单 / 表格 / 树等组合组件"]
B --> C["页面模板"]
C --> D["标准低代码页面"]
B --> E["自定义 View 页面"]
5.1 基础组件
第一层是基础组件,例如:
- Input
- Select
- DatePicker
- Switch
- Button
- Tree
- Table Cell Renderer
5.2 组合组件
第二层是组合组件,例如:
- Form
- QueryPanel
- DataTable
- TreePanel
- DetailPanel
- Toolbar
5.3 页面模板
第三层是页面模板,例如:
- CRUD 页面模板
- 树表页面模板
- 主子表页面模板
- 审批页面模板
- 详情页面模板
页面模板先做强,不先做复杂的模板继承体系。
6. 模板和展示容器拆开
页面、弹框、抽屉不是三套模板体系,它们只是模板的展示容器。
真正需要拆开的,是这三个东西:
TemplateContainerOpen Rule
flowchart LR
A["Template"] --> B["容器约定"]
C["Page Container"] --> B
D["Dialog Container"] --> B
E["Drawer Container"] --> B
6.1 Template 负责什么
Template 负责业务内容本身:
- 布局结构
- 组件树
- 数据绑定
- 联动逻辑
- Action 绑定
- 权限声明
Template 不负责这些事:
- 页面路由含义
- 弹框层级含义
- 抽屉关闭策略
- 容器尺寸管理
6.2 展示容器负责什么
展示容器只是展示外壳,不是业务逻辑本体。
它负责:
- 呈现方式
- 生命周期管理
- 打开 / 关闭
- 尺寸、位置、层级
- 遮罩与阻塞策略
- 路由挂接方式
- 关闭结果回传
flowchart TB
A["Container"] --> B["渲染容器"]
A --> C["生命周期"]
A --> D["打开 / 关闭"]
A --> E["尺寸 / 层级"]
A --> F["路由接入"]
A --> G["结果返回"]
6.3 打开规则
Template 和展示容器之间靠统一打开规则连接。
打开规则至少要定义:
- 加载哪个模板
- 容器类型
- 上下文参数
- 初始容器配置
- 关闭结果
- 生命周期钩子
sequenceDiagram
participant C as Caller
participant H as Container Manager
participant T as Template Loader
C->>H: open(templateId, hostType, params, hostProps)
H->>T: load template
T-->>H: template meta / supportedHosts
H->>T: inject params and runtime context
T-->>H: render / submit / close request
H-->>C: return result
6.4 模板不能直接绑定页面 / 弹框 / 抽屉
如果模板和展示容器强绑定,会出现这些问题:
- 同一个业务模板无法在整页、抽屉、弹框之间复用
- AI 需要学习三套模板体系
- 容器后续扩展会污染模板定义
- 页面版、弹框版、抽屉版配置会逐渐分叉
拆开之后会清楚很多:
- 同一个模板可以被多个容器复用
- AI 只需要决定用什么模板、用什么容器打开
- 容器能力可以独立扩展
- 业务模板复用率更高
6.5 模板仍然要声明容器限制
虽然模板和容器拆开,但模板仍然要声明自己适合哪些容器。
不是所有模板都适合所有容器。比如:
- 大查询区 + 大表格的模板,不适合普通弹框
- 强依赖路由上下文的流程页,不一定适合临时抽屉
- 高密度主子表模板,可能只适合整页或超宽抽屉
所以模板里需要额外声明:
supportedHostspreferredHosthostConstraints
6.6 页面、弹框、抽屉只是展示方式
这件事可以直接定成平台原则:
页面、弹框、抽屉不是模板类型,而是模板的展示方式。
flowchart TD
A["需要打开某个业务内容"] --> B["选择 Template"]
B --> C["选择容器: page / dialog / drawer"]
C --> D["注入 params / context / hostProps"]
D --> E["运行 Template"]
E --> F["返回 result / close reason / write-back"]
6.7 对低代码页面和手写页面都成立
这套模型对两类页面都成立:
- 低代码模板可以通过统一规则被 page、dialog、drawer 打开
- 自定义 View 也可以接入同一套容器规则
这样平台不会因为容器形态不同长出三套打开逻辑。
6.8 Route、Template、Model 的关系
页面入口需要把 route、template、model 拆开看。
route决定进入哪类模板入口template决定页面表现形式model决定当前展示的是哪个业务对象
这意味着路由不需要无限增长,而是保持有限、规则化的模板型入口。
例如:
/list/:model/detail/:model/:id/form/:model/new/form/:model/:id/edit/tree-list/:model/approval/:model/:id
flowchart LR
A["Route"] --> B["Template Entry"]
A --> C["Route Params"]
C --> D["model"]
C --> E["id / mode / query"]
B --> F["Template"]
D --> G["Model Meta"]
E --> H["Runtime Context"]
F --> I["Page Builder"]
G --> I
H --> I
I --> J["Rendered Page"]
这条路的好处是:
- 路由数量有限且规则化
- 模板入口稳定
- 新业务接入更像注册一个 model
- AI 更容易生成入口配置
- 菜单、权限、缓存、埋点更容易统一
同时保留一个边界:
不要进一步收缩成一个万能路由装下所有页面,例如:
/page/:template/:model/:id
这会让权限接入点太粗,URL 表达的信息变弱,菜单、缓存、监控都不好做。
7. 统一状态 / 数据源设计
页面里所有主要状态都放在唯一数据层里,这件事已经定下来了。
但唯一数据层不是一个乱塞数据的大对象,而是一套统一状态模型。
flowchart TB
A["页面状态层"] --> B["实体数据"]
A --> C["查询状态"]
A --> D["表单草稿状态"]
A --> E["页面 UI 状态"]
A --> F["选择状态"]
A --> G["派生状态"]
这套结构里的核心原则是:
页面里的所有主要状态都放在唯一数据层里,块本身不维护各自独立的主状态。
也就是说:
- 每个块都从唯一数据层取值
- 块通过 props 绑定这层数据
- Action 改这层数据
- 页面规则层也改这层数据
- 数据变化后,块自然重新渲染
块和块之间不是直接通信,而是通过唯一数据层间接联动。
7.1 数据层按块组织,不按业务名组织
这套平台更偏页面导向,不偏业务对象仓库导向。
所以数据层优先按页面块组织,而不是按业务名字组织。
例如更适合这样的结构:
customerQueryorderTablebaseFormdetailDrawerpageMeta
不是优先长成这样:
customercustomerListcurrentOrderorderItems
7.2 模板决定块结构,模型决定块内容
这条关系已经很清楚:
- 模板决定页面里有哪些块
- 模型决定这些块里装什么内容
换句话说:
- 页面长什么样,由模板决定
- 每个块里有哪些字段、列、默认动作、默认查询,由模型决定
这句话可以直接定下来:
模板决定块结构,模型决定块内容。
7.3 每个块必须有 id 和 type
每个块都必须有两个属性:
idtype
两者作用不同:
id用来精确定位这个块是谁type用来决定这个块具备哪些通用能力
例如:
id: customerQuery,type: queryid: orderTable,type: tableid: baseForm,type: formid: itemTable,type: table
这件事也可以直接定成一句话:
块的行为由
type决定,块的身份由id决定。
7.4 type 先固定一批
第一版不开放随意扩展块类型,先固定一批常用 type。
这样做有几个直接好处:
- 平台统一
- AI 生成稳定
- 默认行为一致
- 调试更容易做
后面再逐步增加新的 type。
7.5 每种 type 预定义标准状态结构
既然 type 先固定,那么每种 type 也要带一套标准状态结构。
例如:
table默认有:data、loading、pagination、selectedRow、selectedRowsform默认有:values、errors、dirty、loading、modedialog默认有:visible、loading、params、result
这样平台才能真正提供统一能力:
- 默认行为
- 默认联动
- 默认调试视图
- AI 生成时的稳定目标
7.6 唯一数据层的建议结构
唯一数据层更适合按块实例组织。
flowchart TB
A["唯一数据层"] --> B["blocks"]
B --> C["block id: customerQuery"]
B --> D["block id: orderTable"]
B --> E["block id: baseForm"]
C --> F["type: query"]
D --> G["type: table"]
E --> H["type: form"]
也就是说:
- 页面数据层按块实例组织
id用于定位type用于识别标准能力
7.7 页面状态层里的常见内容
统一数据层里通常会包含这些部分:
7.7.1 实体数据
已加载的业务对象或记录快照。
7.7.2 查询状态
例如:
- 搜索条件
- 分页
- 排序
- 当前树节点
- 当前 Tab
7.7.3 表单草稿状态
例如:
- 草稿值
- 脏字段
- 校验结果
- 临时编辑值
7.7.4 页面 UI 状态
例如:
- 弹窗开关
- 抽屉开关
- 当前模式
- 局部加载态
7.7.5 选择状态
例如:
- 当前行
- 多选行
- 当前树节点
- 当前聚焦记录
7.7.6 派生状态
例如:
- 统计值
- 金额合计
- 展示标签
- 条件计算结果
7.8 下一步要补的三张表
前端平台继续往前走,最该补的是三张固定表:
-
块类型表
定义有哪些type,每种type的标准状态是什么。 -
块事件表
定义每种type默认会发哪些事件。 -
规则动作表
定义页面规则层允许哪些固定动作。
8. 数据清洗层
数据清洗层需要有,但不做成一个隐式大黑盒。
这一层更像是:
- adapter
- mapper
- view model transformer
这一层负责:
- 响应结构适配
- 展示数据整理
- 枚举标签转换
- 临时展示字段计算
这一层不负责:
- 隐式业务判断
- 核心业务规则处理
- 多接口副作用编排
否则 Action 层会被架空,逻辑会散落进数据层。
9. Action 中心化执行模型
这套平台以 Action 为中心,不让页面直接调接口。
无论是低代码页面还是自定义页面,统一通过 Action 触发业务动作。
sequenceDiagram
participant U as 用户
participant V as 页面 / View
participant S as 页面状态层
participant A as Action 层
participant R as Service 层
participant B as 后端
U->>V: 触发事件
V->>A: 分发 Action
A->>S: 读取上下文 / 当前状态
A->>R: 调用请求服务
R->>B: 发起请求
B-->>R: 返回结果
R-->>A: 标准化响应
A->>S: 写回状态 / 更新数据
A-->>V: 刷新 / 通知 / 收尾
9.1 Action 为什么必须成为主入口
因为只有这里能统一处理这些事情:
- 权限校验
- 审计日志
- 流程接入点
- 错误处理规则
- 重试 / 幂等等策略
- AI 生成时的可控边界
如果页面能随便拼 URL 和参数,这些保证会越来越弱。
9.2 Action 不是单纯请求函数
Action 在这里不是一个简单的“调接口函数”,而是一个可配置的动作单元。
它和 Service、唯一数据层、页面规则层一起工作:
- Service 负责请求
- Action 组织动作过程
- 结果写回唯一数据层
- 页面规则层再根据配置决定后续怎么走
10. Expression、Action、Function 的边界
这三个东西的边界必须立住。
10.1 Expression
Expression 只处理这些事:
- visible
- disabled
- required
- readonly
- 默认值
- 简单计算值
- 简单条件判断
要求也很明确:
- 声明式
- 无副作用
- 易审计
- 易静态分析
10.2 Action
Action 处理所有副作用:
- 查询数据
- 提交数据
- 调业务接口
- 发消息
- 启动流程
- 跳转页面
- 刷新联动区域
Action 先做成预注册、可约束、可审计的形式。
10.3 Function
字符串函数可以保留,但只作为受控的特殊扩展入口,不是主路径。
第一版约束直接定死:
- 仅服务端执行
- 沙箱环境
- 白名单上下文变量
- 白名单平台 API
- 有超时限制
- 有日志
- 有版本管理
10.4 优先顺序
flowchart TD
A["需要实现某段逻辑"] --> B{"Schema 能否表达?"}
B -- 能 --> C["使用 Schema / 模板 / 配置"]
B -- 不能 --> D{"Expression 能否表达?"}
D -- 能 --> E["使用纯表达式"]
D -- 不能 --> F{"现成 Action 能否表达?"}
F -- 能 --> G["绑定预置 Action"]
F -- 不能 --> H{"是否必须扩展?"}
H -- 是 --> I["使用受控 Function / 插件"]
H -- 否 --> J["扩平台或写自定义页面"]
这条顺序不是提示词要求,而是平台本身的结构顺序。
11. 联动设计
ERP 页面里的联动很多,但联动不能变成组件之间互相监听、互相改值的隐式脚本网络。
先把联动分成三类:
flowchart LR
A["联动"] --> B["属性联动"]
A --> C["数据联动"]
A --> D["行为联动"]
再额外加一层明确的页面规则层。
页面里单独放一层规则层,专门监听块事件和数据变化,再根据配置决定后续动作。
这个规则层不是块本身,也不是纯 Action 层。
flowchart LR
A["块"] --> B["发出事件"]
C["唯一数据层"] --> D["数据变化"]
B --> E["页面规则层"]
D --> E
E --> F["改唯一数据层"]
E --> G["触发 Action"]
G --> C
F --> C
11.1 块只负责显示和发事件
块本身只做这些事:
- 显示数据
- 接收 props
- 发出自己的标准事件
块本身不做这些事:
- 判断别的块要不要响应
- 决定跨块联动逻辑
- 直接操作别的块的状态
这些都交给页面规则层。
11.2 规则层同时监听两类输入
规则层同时支持两类输入:
- 块事件
例如:
orderTable.rowSelectedcustomerDialog.confirmedbaseForm.submit
- 数据变化
例如:
orderTable.selectedRow changedbaseForm.values changedcustomerQuery.filters changed
11.3 不把这层对外叫发布订阅
“发布订阅”只是底层实现方式,不作为平台对外的主要概念。
平台对外需要说清的是:
- 哪些事件会发出来
- 哪些数据变化可以监听
- 命中规则后允许做哪些固定动作
- 执行顺序是什么
- 如何避免死循环
所以平台层统一叫:
- 页面规则层
- 页面联动引擎
11.4 规则层先固定少量动作
第一版规则层先只支持少量固定动作:
setDatamergeDataclearDatarunActionopenContainercloseContainer
这样做的好处很直接:
- 平台边界清楚
- AI 更容易生成
- 配置更容易读懂
- 规则层不会过早变成脚本系统
11.5 Action 和规则层的分工
两者不是替代关系,而是分工关系:
- 规则层负责根据配置响应事件和状态变化
- Action 负责执行有副作用的业务动作
所以:
- 简单联动不必都写成 Action
- 重要业务动作仍统一走 Action
11.6 循环触发问题提前处理
因为规则层同时监听事件和数据变化,循环触发是一定会出现的问题。
后面实现时要提前定这些东西:
- 哪些状态变化会继续广播
- 同一轮是否去重
- 是否限制最大触发层级
- 是否允许“写状态但不继续触发”
11.7 属性联动
属性联动主要控制这些东西:
- visible
- disabled
- required
- readonly
- options
- 模板切换
这类统一用纯表达式处理。
11.8 数据联动
数据联动处理“一个值如何影响另一个值”。
典型场景:
- 选客户后自动带出税号和联系人
- 选组织树节点后列表自动过滤
- 选单据类型后默认值变化
这类再拆成两种:
- 派生值
- 受控写回
能算出来的直接算,不落库;需要查后端或改状态的,统一走 Action。
11.9 行为联动
行为联动处理跨块的事件流程。
典型场景:
- 树选中后刷新表格
- 行点击后打开详情抽屉
- 提交成功后刷新列表
主流程就是:
- 块发事件
- 页面规则层接收
- 调 Action
- 状态回写
- 其他块消费新状态
12. 建库即建页面的边界
“建库即建页面”这个方向成立,但边界必须写清楚。
真正的意思是:
实体元数据可以生成默认页面骨架,但数据库字段结构不能永久等于页面结构。
flowchart TB
A["实体 / 字段元数据"] --> B["存储结构"]
A --> C["默认 API"]
A --> D["默认 CRUD Action"]
A --> E["默认页面 Schema"]
E --> F["标准低代码页面"]
E --> G["二次配置扩展"]
G --> H["必要时替换为自定义 View"]
12.1 元数据能稳定生成什么
- 数据表
- 默认 CRUD API
- 默认表单页 / 列表页 / 详情页
- 字段和组件的初始对应关系
- 基础校验规则
- 基础查询区
12.2 元数据不能单独决定什么
- 聚合视图
- 多实体编排页
- 驾驶舱
- 流程重交互页面
- 高度非标交互页面
所以页面定义必须允许逐步脱离原始存储结构继续扩展。
13. 后端架构方向
后端不是“根据字段建库”的工具,而是“根据元数据生成后端能力的引擎”。
核心元数据对象至少包括:
EntitySchemaFieldSchemaPageSchemaComponentSchemaActionSchemaPermissionSchemaWorkflowSchema
flowchart TB
A["EntitySchema"] --> B["数据库表"]
A --> C["校验规则"]
A --> D["默认 CRUD Action"]
A --> E["默认页面骨架"]
F["PermissionSchema"] --> D
F --> E
G["WorkflowSchema"] --> D
H["ActionSchema"] --> E
D --> I["业务执行过程"]
E --> J["前端页面执行过程"]
14. 权限模型
权限不能只理解成“能不能看字段、能不能点按钮”。
完整 ERP 平台至少要覆盖:
- 页面访问权限
- 数据读取权限
- 字段可见权限
- 字段编辑权限
- Action 执行权限
- 组织 / 租户 / 账套范围权限
- 流程状态权限
flowchart TD
A["权限模型"] --> B["路由访问"]
A --> C["数据访问"]
A --> D["字段可见"]
A --> E["字段可编辑"]
A --> F["Action 执行"]
A --> G["组织 / 租户范围"]
A --> H["流程状态限制"]
前端可以根据权限元数据决定渲染结果,最终裁决仍然在后端 Action 层。
15. 低代码页面和手写页面共存
平台不是二选一,而是保留两种方式,但共享同一套业务基础能力。
flowchart LR
A["元数据 / 业务基础能力"] --> B["标准低代码页面"]
A --> C["自定义前端 View"]
B --> D["共享 Action / 权限 / 流程 / 审计"]
C --> D
15.1 低代码页面负责什么
- 标准业务页骨架
- 标准 ERP 交互模式
- 表单 / 表格 / 树等常规联动
- Action 绑定
- 权限声明
15.2 手写页面负责什么
- 特殊布局
- 特殊交互
- 可视化表达
- 模板体系覆盖不了的页面体验
15.3 共享基础能力负责什么
- 业务动作
- 权限
- 流程
- 路由元数据
- 实体元数据
- 审计日志
这样平台不会裂成两套产品。
16. 风险和防线
16.1 配置逐渐变成隐藏代码
表现:
- 大量字符串函数
- 越来越多页面自己拼接口
- 逻辑散落在 Expression、Action、Function 中
防线:
- Schema 第一
- Expression 第二
- Action 第三
- Function 最后
16.2 原始接口配置绕过业务含义
表现:
- 同一个业务动作在不同页面上用不同 URL 和参数结构实现
- 页面配置里直接充斥技术细节
防线:
- 页面只绑定命名 Action
- 原始接口声明收口在 Service / Integration 模块内部
16.3 数据库结构绑死 UI
表现:
- 页面被迫镜像表结构
- 聚合页和流程页越来越难扩
防线:
- 数据库元数据只生成默认页面
- 页面 Schema 可以独立继续扩展
16.4 低代码和手写体系断裂
表现:
- 低代码页面一套权限 / 动作模型
- 手写页面另一套权限 / 动作模型
防线:
- 两类页面共用同一套业务基础能力
17. 第一阶段范围
第一版先做这些:
- 实体建模
- 字段建模
- 默认字段组件对应关系
- 列表页模板
- 表单页模板
- 详情页模板
- 树表页模板
- 主子表页模板
- 统一 Action Registry
- 统一权限模型
- Expression 引擎
- 基础流程接入点
先不做这些:
- 复杂驾驶舱搭建器
- 过强的动态布局引擎
- 太宽松的字符串函数能力
- 复杂模板继承体系
18. 下一步待办
当前方向已经清楚了,下一步不再继续停留在概念层,而是把确定下来的东西压成固定表和固定规则。
优先待办如下:
-
明确第一批固定块类型
先定第一版内置哪些type,例如query、table、form、tree、dialog、drawer、toolbar、page,并确定哪些必须内置,哪些可以后置。 -
明确每种块类型的标准状态结构
例如table默认有哪些状态字段,form默认有哪些状态字段,dialog默认有哪些状态字段。 -
明确每种块类型的标准事件
例如table.rowSelected、query.search、form.submit、dialog.confirmed、drawer.closed。 -
明确页面规则层的第一批固定动作
先收敛为少量固定动作,例如setData、mergeData、clearData、runAction、openContainer、closeContainer。 -
明确规则层执行顺序和循环保护
包括规则命中后的执行顺序、状态写回后是否继续触发、同一轮是否去重、是否限制最大触发层级。 -
明确 Action 的最小定义
至少包含:名字、输入参数、调用哪个 Service、成功默认行为、失败默认行为、是否支持动作链。 -
明确模板和块之间的关系
继续细化“模板决定块结构,模型决定块内容”,补足模板定义块的方式、块如何绑定唯一数据层、块如何暴露标准事件。 -
明确唯一数据层的实际结构草案
把“按块组织”的想法写成更具体的数据结构示意,后面继续收敛 DSL。
19. 总结
这套方案的主线已经比较清楚:
- 模板决定页面结构
- 模型决定块内容
- 唯一数据层做状态中心
- 页面规则层做联动
- Action 做业务动作
- Service 做请求
整套平台要做的,不是用低代码替代一切,也不是让 AI 随便生成代码,而是先把页面结构、状态流转和动作执行压到一套有限、固定、可枚举的规则里。
AI 在这里的作用也不是自由发挥,而是在一个受约束的平台里生成:
- 模板配置
- 块配置
- 规则配置
- Action 绑定
真正往下推进时,重点已经不是继续讲大方向,而是把平台定义压成几张固定表:块类型表、块事件表、规则动作表,以及 Action 的最小定义。做到这一步,这套平台才算真正从想法进入定义。
