选择审批人、发起人自选
RuoYi Office 工作流支持多种审批人指派策略,满足不同业务场景的需求。
1. 审批人配置
在 BPMN 或 Simple 设计器中,每个用户任务节点都需要配置审批人规则。
审批人规则通过 Flowable 的扩展属性存储:
candidateStrategy:审批人策略编号candidateParam:策略参数(JSON 格式)
2. 审批人策略
RuoYi Office 内置多种审批人策略,由 BpmTaskCandidateStrategy 接口的实现类完成计算;策略编号定义在 BpmTaskCandidateStrategyEnum 中:
| 策略 | 编号 | 说明 |
|---|---|---|
| 审批人为空 | 1 | 用于特殊场景(如与发起人相同时自动通过等) |
| 角色 | 10 | 指定角色的所有用户 |
| 部门成员 | 20 | 指定部门的成员(含负责人) |
| 部门负责人 | 21 | 指定部门的负责人 |
| 岗位 | 22 | 指定岗位的所有用户 |
| 连续多级部门负责人 | 23 | 按部门层级连续向上查找负责人 |
| 用户 | 30 | 直接指定具体用户 |
| 审批人自选 | 34 | 当前审批人在审批时选择下一节点审批人 |
| 发起人自选 | 35 | 发起人在发起时选择该节点审批人 |
| 发起人自己 | 36 | 流程发起人本人 |
| 发起人部门负责人 | 37 | 发起人所在部门的负责人 |
| 发起人连续多级部门负责人 | 38 | 发起人向上连续多级部门负责人 |
| 用户组 | 40 | 指定用户组的成员 |
| 表单内用户字段 | 50 | 从表单字段解析用户 |
| 表单内部门负责人 | 51 | 从表单部门字段解析负责人 |
| 流程表达式 | 60 | 通过 UEL 表达式计算审批人 |
调用链
用户任务 → BpmUserTaskActivityBehavior
→ BpmTaskCandidateInvoker#calculateUsersByTask
→ BpmTaskCandidateStrategy(具体策略)
→ 返回候选人集合;单实例任务下再随机选定唯一负责人3. 自定义审批人策略
可通过实现 BpmTaskCandidateStrategy 接口并注册为 Spring Bean 扩展策略;需先在 BpmTaskCandidateStrategyEnum 中增加新的枚举项,策略编号避免与内置值冲突。
java
@Component
public class MyCustomCandidateStrategy implements BpmTaskCandidateStrategy {
@Override
public BpmTaskCandidateStrategyEnum getStrategy() {
return BpmTaskCandidateStrategyEnum.MY_CUSTOM; // 需在枚举中定义
}
@Override
public void validateParam(String param) {
// 校验 param(如 JSON)
}
@Override
public Set<Long> calculateUsers(String param) {
// 根据 param 计算候选人
return Set.of(1L, 2L);
}
}4. 发起人自选
发起人自选允许流程发起人在发起时自行选择审批人。
流程表单
在流程表单场景下,发起流程页面会自动展示审批人选择组件。选中的审批人写入流程变量。
业务表单
在业务表单场景下,需要在业务的创建页面中集成审批人选择组件,并将选中的审批人作为流程变量提交。
实现原理
- 流程设计:将节点审批人策略设为「发起人自选」(编号 35)。
- 发起流程:前端展示审批人选择组件。
- 提交:将各节点所选审批人写入流程变量
PROCESS_START_USER_SELECT_ASSIGNEES,其值为Map<节点 activityId, List<用户 ID>>。 - 运行到节点:
BpmTaskCandidateStartUserSelectStrategy根据当前活动的activityId从该 Map 中取出审批人列表。
另:审批人自选(编号 34)使用变量
PROCESS_APPROVE_USER_SELECT_ASSIGNEES,由当前审批人在处理任务时选择后续节点处理人,原理类似。
5. 流程表达式
通过 UEL 表达式动态计算审批人(详见 流程表达式)。
例如:
${bpmTaskAssignStartUserExpression.calculateUsers(execution)}:分配给流程发起人${bpmTaskAssignLeaderExpression.calculateUsers(execution, 1)}:分配给发起人的一级领导