spec.md 8.1 KB

--- 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 闭环)。