# 会签配置详解 会签(多实例任务):一个审批节点同时由多人处理,根据完成比例决定是否通过。 **重要前提:** 不启动多实例(不加 `multiInstanceLoopCharacteristics`),则只会创建一个任务,默认不启动。不启动多实例时,会签相关配置都无效。 ## 1. 会签通用结构 ```xml ${COMPLETION_CONDITION} ``` ## 2. 会签规则(countersignRule) | 规则值 | 说明 | completionCondition | |--------|------|---------------------| | `countersign_all` | 全部通过 | `${nrOfCompletedInstances/nrOfInstances==1}` | | `countersign_one` | 一人通过即可 | `${nrOfCompletedInstances/nrOfInstances>0}` | | `countersign_half` | 半数通过 | `${nrOfCompletedInstances/nrOfInstances>=0.5}` | | `countersign_proportion` | 按比例通过(自定义比例) | `${nrOfCompletedInstances/nrOfInstances>=0.N}` | | `countersign_custom` | 自定义选人 | 自定义 | > **注意:** XML 中 `>=` 需要写成 `>=`,如 `${nrOfCompletedInstances/nrOfInstances>=0.6}` ## 3. 顺序会签 vs 并行会签 | 对比项 | 并行会签(isSequential="false") | 顺序会签(isSequential="true") | |--------|-------------------------------|-------------------------------| | 任务创建 | 同时为所有审批人创建任务 | 按顺序逐个创建,前一个完成才创建下一个 | | nrOfActiveInstances | 等于尚未完成的审批人数 | 始终为 1 | | 适用场景 | 多人同时审批,互不影响 | 按层级逐级审批 | | 完成条件触发 | 每完成一个就检查条件 | 每完成一个就检查条件 | ```xml ``` ## 4. 多实例内置流程变量 多实例自动创建以下 3 个流程变量,用于 `completionCondition` 表达式: | 变量名 | 类型 | 说明 | |--------|------|------| | `nrOfInstances` | int | 实例总数(审批人总数) | | `nrOfActiveInstances` | int | 当前活跃的(未完成的)实例数。**顺序会签时此值始终为 1** | | `nrOfCompletedInstances` | int | 已完成的实例个数 | **完成条件示例:** ``` ${nrOfCompletedInstances/nrOfInstances==1} → 全部完成 ${nrOfCompletedInstances/nrOfInstances>0} → 至少一人完成 ${nrOfCompletedInstances/nrOfInstances>=0.5} → 50%完成 ${nrOfCompletedInstances/nrOfInstances>=0.6} → 60%完成时,删除其他未完成任务,继续下一步 ``` ## 5. 会签工具 Bean — flowUtil `flowUtil` 是系统暴露的 Spring Bean,提供会签人员集合获取方法: | 方法 | 说明 | 用于 | |------|------|------| | `${flowUtil.stringToList('user1,user2')}` | 将逗号分隔字符串转为 List 集合 | 固定人员会签(candidateUsers) | | `${flowUtil.getAssigneeUsers(execution,'BASE64配置')}` | 根据 Base64 编码的配置动态获取审批人列表 | 部门/岗位/表单字段会签 | **`stringToList` 的变量写法:** ```xml flowable:collection="${flowUtil.stringToList('admin,jeecg,zhangsan')}" flowable:collection="${flowUtil.stringToList(assigneeUserIdList)}" ``` **`getAssigneeUsers` 的 Base64 配置:** 将 taskCountersignExtendJson 的 JSON(去掉 timestamp 和 countersignProportion)进行 Base64 编码后作为参数传入。 ## 4. 会签审批人类型(auditorUserType) taskCountersignExtendJson 是 Base64 编码的 JSON,解码后结构如下: ### 人员会签(candidateUsers) ```json { "auditorUserType": "candidateUsers", "auditorUserIds": ["jeecg", "admin"], "countersignProportion": "0.2", "timestamp": 1758257673121 } ``` 对应 XML collection: ```xml flowable:collection="${flowUtil.stringToList('jeecg,admin')}" ``` ### 部门会签(candidateDepts) ```json { "auditorUserType": "candidateDepts", "auditorDeptIds": ["部门ID1", "部门ID2"], "timestamp": 1758257664644 } ``` 对应 XML collection: ```xml flowable:collection="${flowUtil.getAssigneeUsers(execution,'BASE64编码的配置')}" ``` ### 职务会签(candidatePosts) ```json { "auditorUserType": "candidatePosts", "auditorPostIds": ["职务ID1", "职务ID2"], "timestamp": 1758202368122 } ``` 对应 XML collection: ```xml flowable:collection="${flowUtil.getAssigneeUsers(execution,'BASE64编码的配置')}" ``` ### 表单字段会签(formData) 从表单中的用户选择控件动态获取会签人: ```json { "auditorUserType": "formData", "auditorCountersignFormField": "select_user_xxx", "auditorCountersignFormFieldType": "select-user", "timestamp": 1758257668105 } ``` 对应 XML collection: ```xml flowable:collection="${flowUtil.getAssigneeUsers(execution,'BASE64编码的配置')}" ``` ## 7. 完整会签示例 — 人员会签(并行,全部通过) ```xml ${nrOfCompletedInstances/nrOfInstances==1} ``` ## 8. 完整会签示例 — 人员比例通过(并行,20%) ```xml ${nrOfCompletedInstances/nrOfInstances>=0.2} ``` ## 9. 完整会签示例 — 岗位会签(顺序,比例20%) 来自生产环境的岗位(candidatePosts)顺序会签示例,使用 `flowUtil.getAssigneeUsers` 动态获取审批人: **taskCountersignExtendJson Base64 解码后:** ```json { "countersignProportion": "0.2", "auditorUserType": "candidatePosts", "auditorPostIds": ["2032387176954642433", "1958471111989067778"], "timestamp": 1773418938149 } ``` **getAssigneeUsers 参数 Base64 解码后(不含 timestamp 和 countersignProportion):** ```json { "auditorUserType": "candidatePosts", "auditorPostIds": ["2032387176954642433", "1958471111989067778"] } ``` ```xml ``` **关键差异:** - `isSequential="true"` — 顺序逐个审批 - 没有 `completionCondition` — 当 countersignRule 为 proportion 但未写 completionCondition 时,系统通过 countersignProportion 属性和 taskCountersignExtendJson 中的 countersignProportion 值自动处理 - `flowUtil.getAssigneeUsers(execution, 'BASE64')` — 运行时根据岗位ID动态获取用户列表