feat: dispatch NamedAction and NamedCondition by key
Hosts register one bean per action/condition; Spring wires the dispatcher when no facade is defined, and REST catalog projects from those beans. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
- 到期升级 `processDue` / `TASK_ESCALATED`
|
||||
- 管理员/系统取消 `cancel` / `CANCELLED`
|
||||
- 可选 REST(autoconfigure 条件装配)+ 目录 SPI `OrdoCatalog`
|
||||
- `NamedAction` / `NamedCondition` 注册与官方 key 分发;默认 Catalog 从具名 Bean 投影
|
||||
|
||||
## 开发计划(确定要做)
|
||||
|
||||
|
||||
+21
-14
@@ -76,12 +76,16 @@ ordo:
|
||||
| Bean | 默认 |
|
||||
|---|---|
|
||||
| `AssigneeResolver` | 候选人字符串即办理人 |
|
||||
| `RoutingCondition` | `ref` 边默认恒 true;无 `when` 的边不经过该 Bean |
|
||||
| `ActionHandler` | 空操作 |
|
||||
| `NamedCondition` | 可有多个;无 `RoutingCondition` 门面且列表非空时装配 `DispatchingRoutingCondition` |
|
||||
| `NamedAction` | 可有多个;无 `ActionHandler` 门面且列表非空时装配 `DispatchingActionHandler` |
|
||||
| `RoutingCondition` | 无 `NamedCondition` 时 `ref` 边恒 true;有则按 key 分发,未知 `ref` 为 false |
|
||||
| `ActionHandler` | 无 `NamedAction` 时空操作;有则按 key 分发,未知 key 抛 `IllegalArgumentException` |
|
||||
| `OrdoEventListener` | 可有多个,提交后按 Spring 顺序调用 |
|
||||
| `OrdoCatalog` | 空列表(仅 REST 打开时装配) |
|
||||
| `OrdoCatalog` | REST 打开时:从 `NamedCondition` / `NamedAction` 投影;皆空则为空列表。`assignees` 仍空 |
|
||||
|
||||
未提供自定义 Bean 时,ACTION 步骤仍会推进流程,但 handler 什么都不做。
|
||||
未提供 `NamedAction` 且未覆盖 `ActionHandler` 时,ACTION 步骤仍会推进流程,但 handler 什么都不做。不要同时提供门面 Bean 与对应 `Named*`(门面优先,具名 Bean 不参与运行时)。
|
||||
|
||||
内存引擎把 `DispatchingRoutingCondition.of(...)` / `DispatchingActionHandler.of(...)` 传入 `InMemoryOrdoEngine` 即可。
|
||||
|
||||
### 2.3 可选 REST
|
||||
|
||||
@@ -294,9 +298,9 @@ v1:至少 2 条分支;禁止套娃 PARALLEL;join 固定 ALL;任一分支
|
||||
|
||||
无条件边是默认分支;`priority` 只在同类边之间比较(多条条件边之间,或多条无条件边之间)。
|
||||
|
||||
`RoutingCondition.matches` 看到 `args` 与 `ProcessRuntime`(含业务 `context`、发起人、定义与当前步)。看不到任务意见。上下文在 `start` 时写入,运行中引擎不会改 context。未知 `ref` 由宿主返回 `false`,该边不匹配。内置谓词仍只读 `ProcessContext` 变量。
|
||||
`RoutingCondition.matches` 看到 `args` 与 `ProcessRuntime`(含业务 `context`、发起人、定义与当前步)。看不到任务意见。上下文在 `start` 时写入,运行中引擎不会改 context。内置谓词仍只读 `ProcessContext` 变量。
|
||||
|
||||
引擎只注入**一个** `RoutingCondition`。Spring 下多个该类型 Bean 会冲突。宿主用一个门面按 `ref` 分发;不要指望引擎按定义拆 bean。
|
||||
引擎仍只注入**一个** `RoutingCondition`。Spring 下注册多个 `NamedCondition` Bean(`key()` 对应 `when.ref`);无门面且列表非空时装配官方分发器。未知 `ref` 为 false,该边不匹配。重复 `key` 启动失败。也可继续提供单个 `RoutingCondition` 门面自行分发(不要与 `NamedCondition` 混用)。无 `NamedCondition` 时默认仍是恒 true。
|
||||
|
||||
## 7. ACTION 步骤
|
||||
|
||||
@@ -307,22 +311,25 @@ v1:至少 2 条分支;禁止套娃 PARALLEL;join 固定 ALL;任一分支
|
||||
3. 事务提交后调用 `ActionHandler.execute(actionKey, runtime)`。
|
||||
4. 成功 → `SUCCESS` + 事件 `ACTION_SUCCEEDED`;失败 → `FAILED`(`errorMessage`)+ `ACTION_FAILED` + 日志 WARNING。
|
||||
|
||||
**失败不回滚已提交的审批,不阻塞后续步骤,引擎不做重试。** 宿主用 `queryActionExecutions` 或 listener 自行补发。
|
||||
**失败不回滚已提交的审批,不阻塞后续步骤,引擎不做重试。** 宿主用 `queryActionExecutions` 或 listener 自行补发。分发器遇到未知 `actionKey` 会抛 `IllegalArgumentException`,记为该次 ACTION `FAILED`。
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class MailActions implements ActionHandler {
|
||||
public class LeaveApprovedMail implements NamedAction {
|
||||
@Override
|
||||
public void execute(String actionKey, ProcessRuntime runtime) {
|
||||
switch (actionKey) {
|
||||
case "leave-submitted-mail" -> { /* ... */ }
|
||||
case "leave-approved-mail" -> { /* ... */ }
|
||||
default -> throw new IllegalStateException("unknown action: " + actionKey);
|
||||
}
|
||||
public String key() {
|
||||
return "leave-approved-mail";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ProcessRuntime runtime) {
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
仍可提供单个 `ActionHandler` 按 key 自行分发;不要与 `NamedAction` 混用。
|
||||
|
||||
## 8. 审计与监听
|
||||
|
||||
`queryHistory(instanceId, page)`:该实例事件,**发生时间升序**。
|
||||
|
||||
Reference in New Issue
Block a user