feat(oapi): 应用内审批 oapi——待办/办件查询 + 办理(operator 复核)+ 待办跳转 bizUrl 优先
build / build-push (push) Successful in 1m29s

- GET /oapi/flow/tasks/todo?schId&assigneeId&bizType&page&size(出参含 biz 定位/快照/版本)
- GET /oapi/flow/instances?schId&bizType&status&page&size(查询不限办理人)
- POST /oapi/flow/task/{taskId}/approve|reject?schId&operatorId&operatorName:
  operatorId 按任务办理人逐字复核(非办理人→业务码拒绝不 500),拒绝必填意见,
  opinion 经事件链透传到回调 payload;审批后回调/待办减一自动复用
- 待办通知 jumpPath:办件 bizUrl 优先(空回落 /task/{taskId})

契约 IT +3(todo 过滤分页/instances 状态过滤/办理三态+payload 断言),
单测 UserMsgNotifierBizUrlTest 两态;全量 99 单测 + 11 契约 IT 绿。
This commit is contained in:
chenxing
2026-09-22 16:54:29 +08:00
parent d2395c20ce
commit f2126cdf32
8 changed files with 519 additions and 4 deletions
@@ -2,6 +2,7 @@ package com.yunhai.flowcenter.controller.oapi;
import com.yunhai.flowcenter.model.OapiModels;
import com.yunhai.flowcenter.service.OapiFlowService;
import com.yunhai.platform.utils.model.BasePageResult;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -25,8 +26,12 @@ import java.util.List;
* - GET /oapi/flow/progress?instanceId=|bizType=&bizId=&schId= → data={status,steps:[…]}
* - GET /oapi/flow/diagram/url?instanceId=|flowGuid=&mode=&schId= → data={imgUrl,expiresIn}
* - POST /oapi/flow/callback/reg?schId= → data={secret}
* 刻意不提供审批动作(同意/拒绝/退回/移交/催办):那是"人"的决策,必须带登录身份走 CAS 用户面,
* 应用间签名不得代签——谁办理谁负责,审计链不能断在应用上。
* 应用内审批(2026-09 第三步,原"刻意不提供审批动作"立场由该方案修订:登录身份由调用方
* 应用按其 CAS 会话保证并以 operatorId 传入,本端按任务办理人逐字复核,审计链不断):
* - GET /oapi/flow/tasks/todo?schId=&assigneeId=&bizType=&page=&size= → data=分页待办
* - GET /oapi/flow/instances?schId=&bizType=&status=&page=&size= → data=分页办件
* - POST /oapi/flow/task/{taskId}/approve?schId=&operatorId=&operatorName=(body: opinion/edgeName)
* - POST /oapi/flow/task/{taskId}/reject?schId=&operatorId=&operatorName=(body: opinion 必填)
*/
@RestController
@RequestMapping("/oapi/flow")
@@ -102,4 +107,51 @@ public class OapiFlowController {
@RequestBody OapiModels.CallbackRegBody body) {
return flowService.registerCallback(schId, appKey, body);
}
// ===== 应用内审批(第三步):查询 + 办理 =====
/** 我的待办(oapi):assigneeId 维度分页,bizType 可选过滤 */
@GetMapping("/tasks/todo")
public BasePageResult<OapiModels.TodoTaskVo> todoTasks(
@RequestParam("schId") Long schId,
@RequestParam("assigneeId") Integer assigneeId,
@RequestParam(value = "bizType", required = false) String bizType,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
return flowService.pageTodoTasks(schId, assigneeId, bizType, page, size);
}
/** 办件分页(oapi):bizType/status 可选过滤 */
@GetMapping("/instances")
public BasePageResult<OapiModels.InstanceItemVo> instances(
@RequestParam("schId") Long schId,
@RequestParam(value = "bizType", required = false) String bizType,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
return flowService.pageInstances(schId, bizType, status, page, size);
}
/** 同意(oapi):operatorId 按任务办理人逐字复核,非办理人→业务码拒绝 */
@PostMapping("/task/{taskId}/approve")
public void approve(@RequestParam("schId") Long schId,
@RequestParam("operatorId") Integer operatorId,
@RequestParam("operatorName") String operatorName,
@PathVariable("taskId") Long taskId,
@RequestBody(required = false) OapiModels.HandleBody body) {
flowService.approveTask(schId, taskId, operatorId, operatorName,
body == null ? null : body.getOpinion(),
body == null ? null : body.getEdgeName());
}
/** 拒绝(oapi):opinion 必填,非办理人→业务码拒绝 */
@PostMapping("/task/{taskId}/reject")
public void reject(@RequestParam("schId") Long schId,
@RequestParam("operatorId") Integer operatorId,
@RequestParam("operatorName") String operatorName,
@PathVariable("taskId") Long taskId,
@RequestBody(required = false) OapiModels.HandleBody body) {
flowService.rejectTask(schId, taskId, operatorId, operatorName,
body == null ? null : body.getOpinion());
}
}