2026-07-15-oa-condition-from-form-design.md 8.6 KB

OA 条件分支:表单字段驱动可视化配置

日期: 2026-07-15
范围: web-admin 审批设计器步骤 2(表单设计)+ 步骤 3(流程设计);backend 发布校验(引擎匹配逻辑已具备)
Demo: docs/mockups/oa-approval-condition-from-form-demo.html
关联: docs/superpowers/specs/2026-07-14-oa-approval-dingtalk-design.md § 条件分支;backend/app/services/oa_engine.py _match_condition_group

1. 背景与目标

现状问题

流程「条件分支」配置要求用户手写公式,例如 {days} > 5。普通配置者不了解表单字段 field 标识,学习成本高、易配错。

目标

  1. 在表单设计中显式勾选哪些控件「参与流程条件分支」。
  2. 勾选后该字段在发起时必填,且必填开关在勾选期间锁定不可关。
  3. 在流程设计中用可视化规则配置条件:选择字段标题 + 运算符 + 比较值;不提供自定义公式入口。
  4. 运行时仍用表单填报值做分支匹配,不引入独立的「流程实例变量」配置概念。

非目标

  • 系统变量(发起人部门等)进入条件(可二期)。
  • 条件组内 OR、跨组复杂布尔、嵌套括号。
  • 保留或新增「高级:自定义公式」折叠区(已否定,降低双模式复杂度)。
  • 改写公式求值引擎核心算法(已有 rules → 表达式路径够用)。

2. 产品约定(已确认)

项 结论
字段入池方式 表单控件属性勾选「参与流程条件分支」(方案 A)
必填联动 勾选 ⇒ 强制 required=true,必填开关禁用;取消勾选后才能改回选填
可勾选控件 仅:数字、金额、单选、下拉、日期
条件 UI 纯可视化;无高级公式
多条件 同一分支内多条规则 AND
默认分支 isDefault=true,不配 rules
取消勾选有引用 拦截,提示先到流程设计删除对该字段的条件引用
架构方案 方案 1:Schema 打标 + conditionGroups[].rules

3. 架构

[2 表单设计]                         [3 流程设计]
  FormCreate 字段属性                   FlowDesigner 条件抽屉
  · props.useInCondition              · 下拉 = 已勾选字段(展示 title)
  · 勾选 ⇒ required 锁定               · 编辑 rules[{field,op,value}]
         ↓                                    ↓
           form_schema_json              flow_tree_json
                        ↘              ↙
                     发布校验 / 运行引擎
               · 参与字段必须 required
               · rules 只引用合法参与字段
               · _match_condition_group 优先 rules

职责边界

  • 表单: 谁可以进入条件池,并保证运行时有值(必填)。
  • 流程: 如何用这些字段做比较。
  • 引擎: 基本沿用现有 rules 匹配;新配置不再依赖用户手写 when。

4. 数据契约

4.1 表单字段(form_schema_json)

在合格控件的 props(或项目统一挂载的扩展字段,与 FormCreate 属性面板约定一致)增加:

属性 类型 说明
useInCondition boolean 是否参与流程条件分支
required boolean useInCondition === true 时必须为 true

可勾选 type(实现时映射现有 FormCreate type 名):

  • 输入框:如 input(运算符仅 == / !=)
  • 数字:如 inputNumber
  • 金额:如项目内金额控件 type(若与数字共用则同一逻辑)
  • 单选:如 radio
  • 下拉:如 select
  • 日期:如 datePicker / date

附件、说明、布局、公式展示等控件不展示该开关。开关位于右侧「组件配置」Tab 的基础字段区(baseRule),非浮层。

4.2 条件分支组(flow_tree_json)

interface ConditionGroup {
  name: string
  isDefault?: boolean
  /** 新配置主存;默认分支为空数组 */
  rules: Array<{
    field: string
    op: '>' | '>=' | '<' | '<=' | '==' | '!='
    value: string | number
  }>
  /** 存量兼容:仅运行时读取;新保存应清空 */
  when?: string
  child: FlowNode | null
}

运算符策略

字段类型 可用 op
数字 / 金额 / 日期 / 输入框 > >= < <= == !=
单选 / 下拉 == !=

同组多条 rules:引擎现有逻辑拼为 AND(与 oa_engine._match_condition_group 一致)。

4.3 引擎行为(保持兼容)

_match_condition_group 已支持:

  1. isDefault 或空规则 → 记为默认分支候选
  2. when 字符串公式
  3. rules 列表 → 生成临时公式再 eval_formula

本需求约定: 设计器新写入以 rules 为准;保存可视化配置后清空同组 when,避免双源不一致。存量仅有 when 的实例版本仍可运行。

5. 交互

5.1 表单设计

  1. 选中合格控件:属性面板显示「参与流程条件分支」。
  2. 打开开关:设置 useInCondition=true、required=true,禁用必填控件。
  3. 关闭开关:若任意条件节点 rules[].field 仍引用当前 field → 拦截并提示去流程设计处理;无引用则允许关闭并恢复必填开关可编辑(关闭后不强制把 required 改回 false,仅解锁)。
  4. 可选:画布角标「用于分支」(Demo 已示意,实现按需)。

5.2 流程设计

  1. 条件节点抽屉:去掉「条件公式」输入框。
  2. 规则行:字段下拉(label=标题,value=field)+ 运算符 + 值;单选/下拉值用选项列表。
  3. 空池:提示先到步骤 2 勾选;禁用添加规则。
  4. 默认分支:禁用规则编辑,rules=[]。
  5. 非默认:至少一行完整规则;支持「+ 且条件」。
  6. 树上分支标签:人话预览(如「请假天数 大于 3」),不展示 {field}。

5.3 设计器数据流

  • designer/index.vue 将当前 formSchema(或从中解析的条件候选字段列表)传入 FlowDesigner。
  • 候选列表过滤:useInCondition === true 且 type 在白名单。

6. 校验

6.1 前端(保存草稿 / 切步)

  • 建议:切换到流程步或保存草稿时做软提示;发布做硬拦截。

6.2 发布(oa_publish + 前端发布前)

检查 处理
useInCondition 但 required 不为真 发布前自动纠正为 required,或拦截(推荐自动纠正并写入 schema)
非默认分支 rules 为空或 field/op/value 缺失 拦截:「请完善条件分支」
rules.field 在 schema 中不存在或未 useInCondition 拦截:「条件引用了无效字段」
分支仅有存量 when、无有效 rules 不允许发布;提示用可视化重新配置
默认分支缺失或不唯一 沿用现有发布规则

6.3 运行时

  • 发起校验:必填字段由动态表单 required 保障。
  • 分支匹配:form_data[field] + rules;不另建变量表。

7. 存量与迁移

场景 行为
已发布版本仅含 when 运行时继续按公式走;不影响在途实例
打开草稿/新版本编辑 条件抽屉:若无 rules 仅有 when,展示提示「请用可视化重新配置」;保存后写入 rules 并清空 when
V1 不做自动公式→rules 解析 避免半吊子解析;配置者重配一次即可

8. 改动面(实现指引)

层 内容
前端表单 FormCreate 属性面板扩展 useInCondition + 必填锁定
前端流程 FlowDesigner.vue 条件 UI;types.ts 明确 rules 形状
前端设计器壳 designer/index.vue 传递 form 候选字段给流程步
后端 oa_publish 校验补强;引擎优先不改或仅单测覆盖 rules 路径
文档/Demo 本 spec + 已有 mockup

9. 验收标准

  1. 配置者无需知道 field 变量名即可配置「天数大于 3」类分支。
  2. 未勾选参与的字段不会出现在条件字段下拉中。
  3. 勾选参与后发起页该字段必填且属性上无法关掉必填。
  4. 发布应用后:满足条件走对应分支,否则走默认分支。
  5. UI 上不再出现条件公式输入框。
  6. 试图取消仍被引用的「参与分支」勾选时被拦截并有中文提示。

10. 测试要点

  • 单元:rules 匹配(数字比较、字符串等于、默认分支回落)— 扩展现有 test_oa_engine / test_oa_publish。
  • 发布:引用未勾选字段应失败;仅有 when 无 rules 应失败。
  • 前端手测:勾选锁定必填、取消有引用拦截、下拉只含勾选字段、人话标签、端到端请假式流程。