---
title: 公式能力扩展
version: 1.0
date_created: 2026-06-12
last_updated: 2026-06-12
tags: ['formula', 'business-object', 'computation', 'core']
status: done
complexity: 🜶 复杂
背景
ForgeAdmin 已具备 BusinessObject、LowcodeModel、Runtime、动态CRUD、对象关系能力,但缺少统一公式体系,无法支持金额自动计算、主从表汇总、条件表达式计算、自动字段赋值等场景。本次变更建立字段级公式能力,使业务对象的字段可通过公式自动计算值,减少手动赋值和数据不一致风险。
1. 目标与成功标准
- 用户价值: 业务对象字段值可通过配置公式自动计算,无需手写代码
- 业务目标: 消除金额计算、主从表汇总的手工维护,降低数据不一致风险
- 成功判定:
- 字段设计器中可配置公式(类型、表达式、计算模式)
- 配置公式后保存/查询时字段值自动计算
- 从表变更时主表聚合字段自动更新
- 发布时循环依赖和嵌套深度校验通过
2. 代码现状
2.1 关键入口
| 文件 |
说明 |
| orge-plugin-generator/.../domain/entity/AiBusinessObject.java |
业务对象实体,含 objectType、options(JSON) |
| orge-plugin-generator/.../domain/entity/AiBusinessObjectRelation.java |
对象关系,支持 REFERENCE/DETAIL/CHILD_LIST |
| orge-plugin-generator/.../domain/entity/AiLowcodeModel.java |
数据模型,modelSchema 存储字段定义 JSON |
| orge-plugin-generator/.../domain/entity/GenTableColumn.java |
字段定义实体,含 javaField、columnType、validateRule |
| orge-plugin-generator/.../service/businessapp/BusinessObjectPublishService.java |
对象发布服务 |
| orge-plugin-generator/.../service/businessapp/BusinessObjectCreateService.java |
业务对象创建服务 |
2.2 已知限制
- GenTableColumn 无公式配置字段,AiLowcodeModel.modelSchema 中无公式定义
- 运行时动态CRUD 无公式计算截入点
- 金额计算、主从表汇总全靠业务代码手写
3. 变更范围
会修改
- orge-plugin-generator: 字段定义实体、发布服务、DTO/VO 扩展
- orge-plugin-generator: 新增公式服务、控制器、Aviator 表达式引擎集成
- orge-app-server / orge-admin-server: 动态CRUD 入口增加公式计算截入
- orge-admin-ui: 字段设计器中新增公式配置界面
- orge-dependencies: 新增 Aviator 表达式引擎依赖
不会修改
- 条件引擎、审批表达式、流程表达式
- AI公式生成
- forge-flow 流程引擎
- forge-report-ui、forge-h5-ui
- 跨对象公式引用(V1 不支持)
4. Requirements, Constraints & Guidelines
功能需求
- REQ-001 (计算公式): 字段值由同对象其他字段表达式计算得出,如 otal = unit_price * quantity
- REQ-002 (聚合公式): 主表字段值由从表记录聚合计算,如 otal_amount = SUM(detail.amount)
- REQ-003 (条件公式): 字段值根据条件表达式动态赋值,如 discount = IF(amount > 1000, 0.1, 0)
- REQ-004 (VIRTUAL 模式): 读取时动态计算,不存储到数据库
- REQ-005 (STORED 模式): 保存时计算并持久化,读取时返回存储值
- REQ-006 (公式配置): 字段定义中新增 ormula_config JSON,支持公式类型、表达式、计算模式、依赖字段
- REQ-007 (循环依赖检测): 发布时使用 DAG 拓扑排序检测循环引用
- REQ-008 (公式错误处理): 计算失败时记录 ERROR 日志并降级处理
- REQ-009 (公式嵌套): V1 支持最大嵌套深度 3 层,发布时 DAG 分析 + 循环检测
约束条件
- CON-001: 公式字段不支持用户直接编辑,值由系统计算
- CON-002: 金额类公式计算结果使用 long 类型(单位:分)
- CON-003: STORED 公式在 Insert/Update 时触发重算
- CON-004: VIRTUAL 公式在查询记录时实时计算,不存储
- CON-005: 聚合公式依赖于对象关系 (DETAIL/CHILD_LIST),无关系时报错
- CON-006: 聚合公式采用自动重算模式,不采用手动或定时触发
- CON-007: STORED 聚合公式采用自动维护模式,禁止脏数据
- CON-008: 公式嵌套最大深度 3 层
- CON-009: V1 不支持跨对象公式
编写约定
- GUD-001: 表达式引擎使用 Aviator,支持算术、逻辑、三元、内置函数
- GUD-002: 公式配置 JSON 格式统一:{ type, expression, mode, dependsOn, maxDepth }
- GUD-003: 公式服务注入点采用统一拦截器模式,不侵入具体 CRUD 业务代码
风险
- RISK-001 (金额一致性): STORED 聚合公式必须与从表同步更新,避免主从表金额不一致
- RISK-002 (循环依赖): 公式间循环引用必须在发布时拦截
- RISK-003 (性能): 聚合公式 N+1 查询需优化;从表批量操作时主表重算频率需控制
- RISK-004 (并发): STORED 公式并发写入时可能导致主表值过时
- RISK-005 (兼容性): 已有字段增加公式后历史数据需重算迁移
- RISK-006 (回滚): 公式配置回滚后已存储计算值需明确清理策略
5. Interfaces & Data Contracts
数据变更
| 表 |
字段 |
说明 |
| gen_table_column |
ormula_config TEXT |
新增公式配置 JSON |
| i_lowcode_model |
modelSchema JSON |
字段 schema 中新增 formula 节点 |
API 变更
| 方法 |
路径 |
说明 |
| POST |
/api/ai/business/formula/validate |
验证公式表达式语法 |
| POST |
/api/ai/business/formula/preview |
预览公式计算结果 |
| POST |
/api/ai/business/object/{objectCode}/publish |
发布时增加 DAG + 循环检测 + 深度校验 |
| POST/PUT/GET |
动态CRUD入口 |
新增/更新/查询时公式计算截入 |
| POST/PUT/DELETE |
动态CRUD入口(从表) |
从表变更后触发主表聚合重算 |
6. 测试与验证策略
- 公式解析测试: Aviator 表达式语法解析正确性
- 计算模式测试: STORED 保存持久化、VIRTUAL 查询实时计算
- 聚合重算测试: 从表 CRUD 后主表字段自动更新
- 循环依赖测试: DAG 拓扑排序拦截循环引用
- 嵌套深度测试: 超过 3 层嵌套时发布拦截
- 错误处理测试: 公式异常时日志记录 + 降级处理
- 覆盖率: 核心公式引擎 85%+,公式服务 80%+
7. 技术决策
| 决策项 |
方案 |
放弃方案 |
| 表达式引擎 |
Aviator |
MVEL(体积大)、自研(成本高) |
| 存储策略 |
字段扩展 JSON |
独立公式表(复杂度高) |
| 聚合触发 |
自动重算 |
手动触发、定时触发 |
| 循环检测 |
DAG 拓扑排序 |
— |
| 跨对象 |
V1 不支持 |
— |
| 嵌套深度 |
最大 3 层 |
— |
8. 待澄清项
全部 8 项已确认,无待澄清项。
9. 验收标准
- AC-001: Given 字段配置 STORED 计算公式 otal = price * qty, When 保存记录且 price=100, qty=3, Then total 持久化为 300
- AC-002: Given 字段配置 VIRTUAL 计算公式 otal = price * qty, When 查询记录且 price=100, qty=3, Then total 返回 300 且不存储
- AC-003: Given 主表字段配置聚合公式 SUM(detail.amount), When 从表新增一条 amount=50 的记录, Then 主表字段自动更新
- AC-004: Given 表单字段 A 引用 B, B 引用 C, C 引用 A, When 发布时, Then 检测循环依赖并禁止发布
- AC-005: Given 公式嵌套深度 4 层, When 发布时, Then 拦截并提示超限
- AC-006: Given 公式表达式语法错误, When 调用 validate 接口, Then 返回具体错误位置和原因
- AC-007: Given 配置公式的字段, When 用户在表单中编辑该字段, Then 字段不可编辑(只读)
- AC-008: Given 公式计算时抛出异常, When 查询/保存, Then 记录 ERROR 日志,公式字段保持原值或置 null
归档记录(HARD-GATE)
- 状态:done
- 归档时间:2026-06-27
- 归档人:yaomd(批量归档)
- 归档路径:code-copilot/changes/archive/2026-06-27-formula-capability-extension/
- 判定依据:任务清单全部完成,execution-log 验证通过(编译/构建/lint 闭环)。