From f83eabd84a5d373128dfea449b58b1f27226b2e4 Mon Sep 17 00:00:00 2001 From: weicw <594098497@qq.com> Date: Sat, 31 Oct 2026 11:20:13 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E4=BC=9A=E7=AD=BE=E9=80=90=E4=B8=AA?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=89=8D=E5=A4=8D=E6=9F=A5=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 共享库成员可能同属多个会签组,一次通过会连带完成其余组待办并推进节点, 按快照直接点通过会撞上「任务已处理」。改为每轮先确认节点仍在会签, 且批准前复查任务仍为 PENDING。 --- .../approval/ApprovalSettlementIT.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/gxwebsoft/approval/ApprovalSettlementIT.java b/src/test/java/com/gxwebsoft/approval/ApprovalSettlementIT.java index 152b3b4..e517fe0 100644 --- a/src/test/java/com/gxwebsoft/approval/ApprovalSettlementIT.java +++ b/src/test/java/com/gxwebsoft/approval/ApprovalSettlementIT.java @@ -515,9 +515,18 @@ class ApprovalSettlementIT { .andExpect(jsonPath("$.code").value(0)); } - /** 按组把剩余待办逐个通过(会签组内成员来自共享库角色,逐个处理最稳)。 */ + /** + * 按组把剩余待办逐个通过(会签组内成员来自共享库角色,逐个处理最稳)。 + * + *

共享库里同一个人可能同时属于多个会签组,按 ADR 0003 他一次通过就会完成本节点本轮 + * 全部待办,节点随即推进、其余组的待办被取消。因此每轮都要先看节点是否还在会签, + * 且批准前复查该任务是否仍为 PENDING——读到的是快照,不能用它直接点通过。

+ */ private void approveAllByGroup(long instanceId, String groupKey) throws Exception { for (int guard = 0; guard < 20; guard++) { + if (!"countersign".equals(currentNodeKey(instanceId))) { + return; + } List> tasks = data.master().queryForList( "SELECT id, assignee_id, assignee_name FROM approval_task WHERE instance_id = ? " + "AND node_key = 'countersign' AND group_key = ? AND status = 'PENDING' ORDER BY id", @@ -533,6 +542,12 @@ class ApprovalSettlementIT { private void approveTask(Map task, Integer org) throws Exception { long taskId = ((Number) task.get("id")).longValue(); + // 快照里的待办可能已被同一次通过连带完成或取消,批准前必须复查 + Integer pending = data.queryMaster("SELECT COUNT(*) FROM approval_task WHERE id = ? AND status = 'PENDING'", + Integer.class, taskId); + if (pending == null || pending == 0) { + return; + } String name = (String) task.get("assignee_name"); ApprovalTestData.TestUser assignee = new ApprovalTestData.TestUser(((Number) task.get("assignee_id")).intValue(), name, name);