# git.fsdpf.net/go/condflow 条件流引擎:把一串"条件 -> 动作"的分支(`CondCase`)按优先级串成一个决策流(`CondFlow`), 输入一份数据,按顺序求值每个分支的条件(复用 `git.fsdpf.net/go/condition` 的 `Condition` DSL),命中的分支执行对应动作,支持分支之间链式跳转到下一个流。典型场景:审批流程(金额分档 审批、信用分拒绝)、营销规则(分群发券)等需要"按条件走不同处理逻辑"的业务。 ## 核心概念 - **`CondFlow`**:一个决策流,`New(name string)` 创建,`AddCase(c *CondCase)` 按优先级加入 分支,`Run(app do.Injector, input reflux.R, user req.User) error` 执行——按 `getSortedCases()` 排好的顺序对每个分支求值,命中就执行 `Action`,`WithNextCaseOnSuccess(true)` 控制命中后要不 要继续尝试后面的分支(默认命中一个就停)。 - **`CondCase`**:单个分支,`NewCondCase(name, cond *condition.Condition, action string)` 构造,绑定一个 `condition.Condition` 和一个 action 的名字(通过 `ActionInvoker` 按名字查 实际实现)。`WithPriority`/`WithActionParams`/`WithActionConfig` 配置优先级和动作参数; `WithNextFlowOnSuccess(flow *CondFlow, params fieldx.Schema)` 支持分支命中后跳转到另一个 `CondFlow` 继续执行,串成更复杂的决策树。 - **`Action`/`ActionInvoker`**:实际执行的业务逻辑,`type Action func(ctx Context, cfg valuex.Accessor) (reflux.R, error)`,`ActionInvoker` 按名字查找、调用具体的 `Action` 实现(`Executor` 接口 + 反射,`NewActionInvokerWithValue` 支持从一个结构体值上按方法名找 对应的 action)。 - **`Context`/`FlowContext`**:执行上下文,带当前用户(`req.User`)、输入数据的按路径取值 (`Get`/`GetParam`,基于 `valuex.Accessor`)、`Fork(input)` 派生一个新上下文(分支跳转时 用)、`Res() req.Resource` 拿到动作关联的资源。 - **条件求值**:`CondFlow.makeTable`/`makeCTE` 把输入数据(`reflux.R`)包装成一张虚拟的 `Flow` 表(用 `db-v2` 的 `CTE`),每个分支的 `condition.Condition.ToSql(...)` 渲染成 `IF(条件, 1, 0)` 列,一次查询同时算出所有分支是否命中,不用逐个分支单独跑判断逻辑。 ## 已知问题 `tests/example_test.go` 里的 `Example_userApprovalFlow` 目前会失败(预期输出跟实际生成的 SQL 对不上,具体差异待排查),其它测试和例子都正常。