diff --git a/src/main/java/com/yunhai/svchall/controller/api/SvcApprovalController.java b/src/main/java/com/yunhai/svchall/controller/api/SvcApprovalController.java index b038e9d..1f85dba 100644 --- a/src/main/java/com/yunhai/svchall/controller/api/SvcApprovalController.java +++ b/src/main/java/com/yunhai/svchall/controller/api/SvcApprovalController.java @@ -62,6 +62,28 @@ public class SvcApprovalController { return approvalClient.todoTasks(op.schId, op.userId, page, size); } + /** 我已审批(P3.5):中心 done,过滤=签名方应用身份(中心侧接缝),信封透传 */ + @GetMapping("Done") + public Map done(BoaUser user, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + @RequestParam(required = false) Map rawParams) { + Operator op = requireOperator(user); + rejectIdentityParams(rawParams); + return approvalClient.doneTasks(op.schId, op.userId, page, size); + } + + /** 抄送我的(P3.5):中心 cc,过滤=签名方应用身份(中心侧接缝),信封透传 */ + @GetMapping("Cc") + public Map cc(BoaUser user, + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "size", required = false) Integer size, + @RequestParam(required = false) Map rawParams) { + Operator op = requireOperator(user); + rejectIdentityParams(rawParams); + return approvalClient.ccMine(op.schId, op.userId, page, size); + } + /** * 当前人在该办件上的待办(详情卡片数据源,0/1/N 均 200 空 tasks)。 * 先按会话学校定位办件行再过 Guard——跨校行在此即"办件不存在"。 diff --git a/src/main/java/com/yunhai/svchall/service/impl/SvcApprovalClient.java b/src/main/java/com/yunhai/svchall/service/impl/SvcApprovalClient.java index f042e69..683a582 100644 --- a/src/main/java/com/yunhai/svchall/service/impl/SvcApprovalClient.java +++ b/src/main/java/com/yunhai/svchall/service/impl/SvcApprovalClient.java @@ -93,6 +93,42 @@ public class SvcApprovalClient { return first; } + /** + * 我的已办(P3.5):{@code /oapi/flow/tasks/done}。中心按签名方应用身份过滤 + * (d.appKey=本应用 appKey,由 oapi 端从验签层取),出站不传 bizType——天然覆盖新旧 + * bizType 存量(P2-02 接缝),双值双查在此端点不适用(过滤键不是 bizType)。 + */ + public Map doneTasks(Integer schId, Integer assigneeId, Integer page, Integer size) { + requireEnabled(); + Map query = new LinkedHashMap<>(); + query.put("schId", String.valueOf(schId)); + query.put("assigneeId", String.valueOf(assigneeId)); + if (page != null) { + query.put("page", String.valueOf(page)); + } + if (size != null) { + query.put("size", String.valueOf(size)); + } + return openCall.get(TARGET, "/oapi/flow/tasks/done", query, Map.class); + } + + /** + * 抄送我的(P3.5):{@code /oapi/flow/cc}。过滤接缝同 {@link #doneTasks}(签名 appKey)。 + */ + public Map ccMine(Integer schId, Integer userId, Integer page, Integer size) { + requireEnabled(); + Map query = new LinkedHashMap<>(); + query.put("schId", String.valueOf(schId)); + query.put("userId", String.valueOf(userId)); + if (page != null) { + query.put("page", String.valueOf(page)); + } + if (size != null) { + query.put("size", String.valueOf(size)); + } + return openCall.get(TARGET, "/oapi/flow/cc", query, Map.class); + } + /** 同意(opinion 可空;多出口 edgeName 透传) */ public void approve(Long taskId, Integer schId, Integer operatorId, String operatorName, String opinion, String edgeName) { diff --git a/src/test/java/com/yunhai/svchall/controller/api/SvcApprovalControllerTest.java b/src/test/java/com/yunhai/svchall/controller/api/SvcApprovalControllerTest.java index 48bdfbb..e84f637 100644 --- a/src/test/java/com/yunhai/svchall/controller/api/SvcApprovalControllerTest.java +++ b/src/test/java/com/yunhai/svchall/controller/api/SvcApprovalControllerTest.java @@ -195,6 +195,26 @@ class SvcApprovalControllerTest { .andExpect(jsonPath("$.data.total").value(0)); } + @Test + @DisplayName("Done/Cc(P3.5):会话身份出站,信封透传,身份字段入参拒绝") + void doneAndCcEndpoints() throws Exception { + BoaUserContext.set(user(10006, 3)); + Map data = new LinkedHashMap<>(); + data.put("total", 0); + data.put("content", new java.util.ArrayList<>()); + when(approvalClient.doneTasks(3, 10006, 1, 10)).thenReturn(data); + when(approvalClient.ccMine(3, 10006, 1, 10)).thenReturn(data); + mockMvc.perform(get("/api/apply/approval/Done")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(0)); + mockMvc.perform(get("/api/apply/approval/Cc")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(0)); + mockMvc.perform(get("/api/apply/approval/Done").param("assigneeId", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(2)); + } + @Test @DisplayName("My:{total,list} → FlowPage{total,content,pageIndex,pageSize,totalPages,hasNext} 显式映射") void myEnvelopeMapping() throws Exception { diff --git a/src/test/java/com/yunhai/svchall/service/impl/SvcApprovalClientTest.java b/src/test/java/com/yunhai/svchall/service/impl/SvcApprovalClientTest.java index 15d4dd1..07c8afa 100644 --- a/src/test/java/com/yunhai/svchall/service/impl/SvcApprovalClientTest.java +++ b/src/test/java/com/yunhai/svchall/service/impl/SvcApprovalClientTest.java @@ -170,6 +170,31 @@ class SvcApprovalClientTest { assertTrue(((List) out.get("tasks")).isEmpty()); } + @Test + @DisplayName("doneTasks:/oapi/flow/tasks/done,无 bizType 参数(中心按签名 appKey 过滤)") + void doneTasksAssembly() { + client.doneTasks(3, 10006, 2, 10); + @SuppressWarnings("unchecked") + ArgumentCaptor> q = ArgumentCaptor.forClass(Map.class); + verify(openCall).get(eq(TARGET), eq("/oapi/flow/tasks/done"), q.capture(), eq(Map.class)); + assertEquals("3", q.getValue().get("schId")); + assertEquals("10006", q.getValue().get("assigneeId")); + assertEquals("2", q.getValue().get("page")); + assertEquals("10", q.getValue().get("size")); + assertTrue(!q.getValue().containsKey("bizType"), "P2-02 接缝:不传 bizType"); + } + + @Test + @DisplayName("ccMine:/oapi/flow/cc,userId 维度,无 bizType 参数") + void ccMineAssembly() { + client.ccMine(3, 10006, 1, 10); + @SuppressWarnings("unchecked") + ArgumentCaptor> q = ArgumentCaptor.forClass(Map.class); + verify(openCall).get(eq(TARGET), eq("/oapi/flow/cc"), q.capture(), eq(Map.class)); + assertEquals("10006", q.getValue().get("userId")); + assertTrue(!q.getValue().containsKey("bizType")); + } + @Test @DisplayName("approve:taskId 入路径、身份入查询串、opinion/edgeName 入 body 且 trim") void approveAssembly() {