mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 20:49:00 +08:00
feat(flow): support dynamic countersign add-sign
This commit is contained in:
1 parent
5931a5d6d7
commit
2b6a4d2e85
32 files changed
+1916
-37
No files matched your search
@@ -0,0 +1,229 @@
|
||||
# 工作流动态加签设计
|
||||
|
||||
> 状态:已实现(2026-07-16)
|
||||
|
||||
## 目标
|
||||
|
||||
为运行中的并行会签节点动态追加一名或多名独立审批人。新增审批人与原审批人并行处理,并进入同一会签完成条件。
|
||||
|
||||
首版不实现前加签、后加签、撤销加签或减签;现有 `delegateTask` 继续表示委托,不复用为加签。
|
||||
|
||||
## 业务规则
|
||||
|
||||
1. 仅配置为并行会签且开启“允许审批人加签”的节点可用。
|
||||
2. 只有仍持有未完成待办的原始审批人可以发起;加签审批人、转办接手人、已完成审批人、流程发起人和普通管理员均不可以发起。
|
||||
3. 加签不完成或暂停发起人的待办;所有待办继续并行处理。
|
||||
4. 同一轮节点执行中,每个用户最多参与一次。已有原始审批人、已有加签审批人及曾经接手过该轮任务的用户均不可再次加入。
|
||||
5. 一次可以选择多人,整批校验、整批成功或整批失败。
|
||||
6. 原始审批人在自己的待办完成前可以多次加签。
|
||||
7. 加签原因必填,长度为 2~100 字。
|
||||
8. 加签审批人可以转办,但不能继续加签;转办不改变会签实例总数。
|
||||
9. 任意新增审批人拒绝时,继续执行当前会签的拒绝规则;全部参与人同意后节点才通过。
|
||||
10. 加签与节点完成竞争时,以先提交成功的事务为准,不重新打开已完成节点。
|
||||
|
||||
## 配置模型
|
||||
|
||||
在 `Node` 增加:
|
||||
|
||||
```java
|
||||
private Boolean allowAddSign;
|
||||
```
|
||||
|
||||
- 设计器仅在多人审批模式为会签时显示开关。
|
||||
- 新节点默认 `false`;字段为空时后端也按 `false` 处理。
|
||||
- 开关直接保存在现有 `process_node_data.data` JSON 中。
|
||||
- 为保持实现简单,不提供发布版本隔离;修改节点配置可能影响正在运行的实例。
|
||||
|
||||
## 接口设计
|
||||
|
||||
### 查询任务详情
|
||||
|
||||
扩展现有 `GET /task/task/queryTask` 响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"canAddSign": true,
|
||||
"participantUserIds": [1, 2, 3]
|
||||
}
|
||||
```
|
||||
|
||||
`canAddSign` 必须由后端根据当前登录人、活动任务、原始分配关系、节点模式和开关综合计算,前端不能自行推导权限。
|
||||
|
||||
### 发起加签
|
||||
|
||||
新增 `POST /task/task/addSign`:
|
||||
|
||||
```json
|
||||
{
|
||||
"taskId": "12501",
|
||||
"targetUserIdList": [31, 32],
|
||||
"reason": "需要法务和财务共同确认"
|
||||
}
|
||||
```
|
||||
|
||||
客户端不提交操作人、流程实例或节点 ID;这些值由后端根据登录人和 `taskId` 获取,避免越权和参数篡改。
|
||||
|
||||
成功返回本次加签记录 ID 和新增任务摘要;业务校验失败时整批不产生任务。
|
||||
|
||||
## 后端处理流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["接收 taskId、目标用户、原因"] --> B["查询当前登录人的活动任务"]
|
||||
B --> C["锁定当前 ProcessNodeRecord"]
|
||||
C --> D["校验原始审批人、会签模式和允许加签开关"]
|
||||
D --> E["批量校验租户用户、输入重复和节点参与历史"]
|
||||
E --> F["创建一条批次加签审计记录"]
|
||||
F --> G["逐人调用 addMultiInstanceExecution"]
|
||||
G --> H["任务监听器写入执行人记录"]
|
||||
H --> I["保存变更后参与人快照并提交事务"]
|
||||
```
|
||||
|
||||
核心调用使用 Flowable 8 的:
|
||||
|
||||
```java
|
||||
runtimeService.addMultiInstanceExecution(nodeId, parentExecutionId, executionVariables);
|
||||
```
|
||||
|
||||
处理要点:
|
||||
|
||||
- 通过当前任务 `executionId` 找到并行多实例父执行实例。
|
||||
- `executionVariables` 写入模型已有的 `${nodeId}_assignee_temp` 执行人变量。
|
||||
- 同时写入 `assignmentOrigin=ADD_SIGN`、`initialUserId`、`addSignRecordId` 和 `addedByUserId` 等局部元数据。
|
||||
- Flowable 负责增加 `nrOfInstances`、创建任务和计算节点完成状态。
|
||||
- 不手工修改 Flowable 运行表,不在业务表中另造可完成的审批任务。
|
||||
|
||||
## 数据记录
|
||||
|
||||
### 执行人记录扩展
|
||||
|
||||
在 `process_node_record_assign_user` 增加:
|
||||
|
||||
- `node_record_id`:本轮节点执行记录 ID,用于区分退回后再次进入同一节点。
|
||||
- `assignment_origin`:`ORIGINAL` 或 `ADD_SIGN`。
|
||||
- `initial_user_id`:本份待办最初分配的用户;转办后保持不变。
|
||||
- `add_sign_record_id`:加签产生的任务关联到对应批次记录,原始任务为空。
|
||||
|
||||
为新记录建立 `(tenant_id, node_record_id, user_id)` 唯一约束,配合节点行锁保证同一轮节点内人员唯一。历史兼容和数据回填不在本次范围内。
|
||||
|
||||
权限判断同时要求:
|
||||
|
||||
- `assignment_origin = ORIGINAL`;
|
||||
- 当前登录人等于 `initial_user_id`;
|
||||
- 当前登录人仍是任务现任 `assignee`;
|
||||
- 任务和节点都处于活动状态。
|
||||
|
||||
因此原始任务转办给其他用户后,接手人不能发起加签。
|
||||
|
||||
### 加签审计记录
|
||||
|
||||
新增 `process_task_add_sign_record`,一批操作一条记录,保存:
|
||||
|
||||
- 租户、流程、流程实例、本轮节点记录、节点和来源任务;
|
||||
- 发起人、加签原因、操作时间;
|
||||
- 本次目标用户快照;
|
||||
- 操作前和操作后的参与人快照。
|
||||
|
||||
只记录事务成功的加签;失败请求记录应用日志,不生成半成品审计数据。
|
||||
|
||||
## 并发与事务
|
||||
|
||||
- `addSign` 与会签任务 `completeTask` 在操作同一节点前,锁定相同的活动 `process_node_record` 行。
|
||||
- 所有目标用户先完成校验,再创建任何多实例执行。
|
||||
- 批次记录、Flowable 多实例、任务监听记录处于同一事务;任一步失败全部回滚。
|
||||
- 两个审批人同时加签同一用户时,一个成功,另一个在获得锁后因重复参与失败。
|
||||
- 节点先完成时返回“当前审批节点已结束,无法加签”;不做节点重开或补偿任务。
|
||||
- Flowable 乐观锁异常转换为明确的并发操作提示,不向前端暴露引擎异常文本。
|
||||
|
||||
## 转办约束
|
||||
|
||||
现有转办接口应收紧为单目标用户,并增加当前节点参与人校验:
|
||||
|
||||
- 转办目标不得在本轮节点参与历史中出现。
|
||||
- 转办沿用原任务的 `assignment_origin`、`initial_user_id` 和 `add_sign_record_id`。
|
||||
- 加签任务转办后仍是加签任务;原始任务转办后,接手人不获得加签权限。
|
||||
|
||||
## 前端设计
|
||||
|
||||
### 流程设计器
|
||||
|
||||
在审批人抽屉的“多人审批方式”下增加“允许审批人加签”开关。切换到或签、依次审批或单人审批时隐藏并重置为 `false`。
|
||||
|
||||
### 桌面待办
|
||||
|
||||
- 在“提交、拒绝、转办”操作区增加“加签”。
|
||||
- 仅当后端返回 `canAddSign=true` 时显示。
|
||||
- 弹窗复用组织选择器,支持多选,过滤 `participantUserIds`。
|
||||
- 原因输入 2~100 字;提交期间禁用重复点击。
|
||||
- 成功后关闭弹窗、刷新任务详情与流程进度。
|
||||
|
||||
### 移动端待办
|
||||
|
||||
移动端使用相同接口和规则,增加“加签”入口及适配小屏的底部弹层;成功后刷新当前任务,不改变原待办的可审批状态。
|
||||
|
||||
## 审批记录展示
|
||||
|
||||
在流程进度时间线中增加独立事件:
|
||||
|
||||
> 张三加签李四、王五:需要法务和财务共同确认
|
||||
|
||||
新增审批人的任务处理记录继续按普通会签任务展示,并标注“加签”。转办时继续展示完整的处理人变化轨迹。
|
||||
|
||||
## 错误提示
|
||||
|
||||
- 当前节点未开启加签
|
||||
- 仅并行会签节点支持加签
|
||||
- 当前任务已完成或已转办
|
||||
- 只有未完成审批的原始审批人可以加签
|
||||
- 请选择加签人员
|
||||
- 加签原因需为 2~100 字
|
||||
- 用户已参与当前会签:{姓名}
|
||||
- 当前审批节点已结束,无法加签
|
||||
- 节点状态已变化,请刷新后重试
|
||||
|
||||
## 验收矩阵
|
||||
|
||||
### 后端
|
||||
|
||||
1. A、B 会签,A 加签 C 后产生三份并行待办,A 的原待办保持活动。
|
||||
2. A、B、C 全部同意后节点通过;C 拒绝时执行当前拒绝策略。
|
||||
3. A 一次加签 C、D,任一目标不合法时 C、D 都不产生任务。
|
||||
4. A 可以在完成前多次加签,完成后再次请求被拒绝。
|
||||
5. C 不能继续加签;C 可转办给未参与的 D,实例总数不变。
|
||||
6. 原始任务 A 转办给 D 后,D 不能加签。
|
||||
7. 重复用户、跨租户用户、无效用户、空原因和超长原因均被拒绝。
|
||||
8. 或签、依次审批、单人审批及未开启开关的节点均被拒绝。
|
||||
9. 并发加签同一用户只允许一个请求成功。
|
||||
10. 加签与最后审批并发时符合先提交者生效规则,不出现孤儿任务或节点重开。
|
||||
11. 审计记录、执行人记录与 Flowable 活动任务一致。
|
||||
|
||||
### 前端
|
||||
|
||||
1. 设计器开关仅在会签配置下可见并正确保存。
|
||||
2. 桌面端和移动端均按 `canAddSign` 控制入口。
|
||||
3. 已参与人员不可选择,批量选择和原因校验一致。
|
||||
4. 加签成功后流程进度、待办列表和审批记录即时刷新。
|
||||
5. 后端拒绝并发或越权请求时,页面保留输入并显示明确原因。
|
||||
|
||||
## 主要改动位置
|
||||
|
||||
后端集中在:
|
||||
|
||||
- `pigx-flow-api/.../dto/Node.java`
|
||||
- `pigx-flow-api/.../entity/ProcessNodeRecordAssignUser.java`
|
||||
- `pigx-flow-biz/.../controller/ProcessTaskController.java`
|
||||
- `pigx-flow-biz/.../service/ITaskService.java`
|
||||
- `pigx-flow-biz/.../service/impl/TaskServiceImpl.java`
|
||||
- `pigx-flow-biz/.../service/impl/FlowableEngineServiceImpl.java`
|
||||
- `pigx-flow-biz/.../support/listeners/FlowProcessEventListener.java`
|
||||
- `db/3pigxx_flow.sql` 与 `db/0pigxx_boot.sql`
|
||||
- `db/upgrade/20260716_dynamic_add_sign.sql`(存量数据库升级)
|
||||
|
||||
前端集中在:
|
||||
|
||||
- `src/views/flow/workflow/components/drawer/approverDrawer.vue`
|
||||
- `src/views/flow/workflow/components/addNode.vue`
|
||||
- `src/api/flow/task/index.ts`
|
||||
- `src/views/flow/task/pending.vue`
|
||||
- `src/views/flow/task/handler/`
|
||||
- `src/views/flow/mobile/task.vue`
|
||||
Reference in new issue
Block a user