场景说明
流程 A-B-C-D(A 开始、D 结束),B 任意审批(b1/b2/b3 三人),C 任意审批(c1/c2 两人)。验证 B、C 节点审批通过时产生的流程事件,确认两个真实问题。
补充说明:原 issue 中记录的"B 节点 Done 事件 2 个""C 走完未抛完成事件"经事件级验证并非缺陷——B(或签 3 人)通过产生 3 个 Done(1 实际办理 + 2 自动办结),C(或签 2 人)通过产生 2 个 Done 并抛 1 个 Finish 事件;"无完成事件 + 一条 C 记录未完成"对应的是 C 配置为并签时的正常行为。
发现的问题
1. 自动办结(autoDone)的流程记录携带了历史审批签名 signKey
现象:B 节点 b1 带签名通过后,C 节点新生成的 c1/c2 待办记录即携带 b1 的签名;c1 带签名通过后,c2 被或签自动办结(autoDone),仍携带 b1 的签名展示。
根因:FlowRecord 构造时从会话 advice 继承 signKey,而 newRecord() 只清空 advice/actionId,漏清 signKey,导致新记录及自动办结记录继承上一审批人的签名(StartNode 中已有 setSignKey(null) 补偿印证该遗漏)。
期望:与审批意见一致,新记录与自动办结记录均不应携带任何签名。
2. 流程完成结束时抛出结束节点虚拟记录的待办事件
现象:C 节点通过到达结束节点时,引擎推送了一个 FlowRecordTodoEvent,引用的是结束节点(END)的虚拟记录(nodeType=END、recordState=已办、flowState=已完成、operatorId=-1)。该记录不持久化,却被当作"待办"事件推送,业务订阅方会收到一条指向已完成流程的"待办"。
处理方式:事件在引擎内仍会生成,但推送业务订阅方前进行拦截,不推送给下游。
期望实现
FlowRecord.newRecord() 补清 signKey(根因);FlowRecord.autoDone() 防御性清空 advice 与 signKey;移除 StartNode 中因此冗余的 setSignKey(null)。
PassAction.run() 推送事件前,过滤结束节点虚拟记录的 Todo 事件,不推送给业务下游(事件仍生成,仅不对外推送)。
验证场景
FlowDoneEventCountTest:
- B(或签 3 人)通过:Done=3、Todo=2、Finish=0;
- C(或签 2 人)通过:Done=2、Finish=1、Todo=0(拦截生效);
- 自动办结记录
isAutoDone() 为真且 signKey/advice 均为 null;
- 对照:B 或签 2 人通过 Done=2;C 并签仅一人办理不抛 Finish(定位原 issue 现象)。
- 框架模块全量测试与
./mvnw clean install 通过。
场景说明
流程 A-B-C-D(A 开始、D 结束),B 任意审批(b1/b2/b3 三人),C 任意审批(c1/c2 两人)。验证 B、C 节点审批通过时产生的流程事件,确认两个真实问题。
补充说明:原 issue 中记录的"B 节点 Done 事件 2 个""C 走完未抛完成事件"经事件级验证并非缺陷——B(或签 3 人)通过产生 3 个 Done(1 实际办理 + 2 自动办结),C(或签 2 人)通过产生 2 个 Done 并抛 1 个 Finish 事件;"无完成事件 + 一条 C 记录未完成"对应的是 C 配置为并签时的正常行为。
发现的问题
1. 自动办结(autoDone)的流程记录携带了历史审批签名 signKey
现象:B 节点 b1 带签名通过后,C 节点新生成的 c1/c2 待办记录即携带 b1 的签名;c1 带签名通过后,c2 被或签自动办结(autoDone),仍携带 b1 的签名展示。
根因:
FlowRecord构造时从会话 advice 继承signKey,而newRecord()只清空advice/actionId,漏清signKey,导致新记录及自动办结记录继承上一审批人的签名(StartNode中已有setSignKey(null)补偿印证该遗漏)。期望:与审批意见一致,新记录与自动办结记录均不应携带任何签名。
2. 流程完成结束时抛出结束节点虚拟记录的待办事件
现象:C 节点通过到达结束节点时,引擎推送了一个
FlowRecordTodoEvent,引用的是结束节点(END)的虚拟记录(nodeType=END、recordState=已办、flowState=已完成、operatorId=-1)。该记录不持久化,却被当作"待办"事件推送,业务订阅方会收到一条指向已完成流程的"待办"。处理方式:事件在引擎内仍会生成,但推送业务订阅方前进行拦截,不推送给下游。
期望实现
FlowRecord.newRecord()补清signKey(根因);FlowRecord.autoDone()防御性清空advice与signKey;移除StartNode中因此冗余的setSignKey(null)。PassAction.run()推送事件前,过滤结束节点虚拟记录的 Todo 事件,不推送给业务下游(事件仍生成,仅不对外推送)。验证场景
FlowDoneEventCountTest:isAutoDone()为真且signKey/advice均为 null;./mvnw clean install通过。