210 lines
12 KiB
Java
210 lines
12 KiB
Java
package com.yunhai.flowcenter.controller.oapi;
|
||
|
||
import com.yunhai.flowcenter.model.OapiModels;
|
||
import com.yunhai.flowcenter.service.FlowRouterAdminService;
|
||
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;
|
||
import org.springframework.web.bind.annotation.PostMapping;
|
||
import org.springframework.web.bind.annotation.RequestBody;
|
||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||
import org.springframework.web.bind.annotation.RequestMapping;
|
||
import org.springframework.web.bind.annotation.RequestParam;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 托管接入件(/oapi/flow/**,appKey 签名强制,V2.0 Part D #5 前置 M1)。
|
||
* 出入参逐字对齐 svc-hall FlowCenterClient(《流程中心M1开工说明.md》§5 契约锚点):
|
||
* - GET /oapi/flow/list?schId= → data=[{flowGuid,name,version,nodeSummary}]
|
||
* - GET /oapi/flow/{flowGuid}?schId= → data={flowGuid,name,version,nodeSummary}
|
||
* - POST /oapi/flow/apply → data={instanceId,duplicated}
|
||
* - GET /oapi/flow/instance?bizType=&bizId=&schId= → data={status,version,instanceId,nodeSummary,traceJson,…}
|
||
* - POST /oapi/flow/instance/{instanceId}/withdraw?schId=&submitterId= → data=null(提交人复核后撤回)
|
||
* - GET /oapi/flow/progress?instanceId=|bizType=&bizId=&schId= → data={status,steps:[…]}
|
||
* - GET /oapi/flow/diagram/url?instanceId=|flowGuid=&mode=&schId= → data={imgUrl,expiresIn}
|
||
* - GET /oapi/flow/embed/url?instanceId=|bizType=&bizId=&mode=&schId= → data={pageUrl,expiresIn}
|
||
* - POST /oapi/flow/callback/reg?schId= → data={secret}
|
||
* - POST /oapi/flow/router/reg → data=null(判断服务自注册,归属=appKey)
|
||
* 应用内审批(2026-09 第三步,原"刻意不提供审批动作"立场由该方案修订:登录身份由调用方
|
||
* 应用按其 CAS 会话保证并以 operatorId 传入,本端按任务办理人逐字复核,审计链不断):
|
||
* - GET /oapi/flow/tasks/todo?schId=&assigneeId=&bizType=&page=&size= → data=分页待办
|
||
* - GET /oapi/flow/tasks/by-biz?schId=&bizType=&bizId=&operatorId= → data=当前人在该单据的待办(0/1/N)
|
||
* - 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")
|
||
@RequiredArgsConstructor
|
||
public class OapiFlowController {
|
||
|
||
private final OapiFlowService flowService;
|
||
private final FlowRouterAdminService routerAdminService;
|
||
|
||
@GetMapping("/list")
|
||
public List<OapiModels.FlowSummaryVo> list(@RequestParam("schId") Long schId) {
|
||
return flowService.listFlows(schId);
|
||
}
|
||
|
||
@GetMapping("/{flowGuid}")
|
||
public OapiModels.FlowSummaryVo getFlow(@PathVariable("flowGuid") String flowGuid,
|
||
@RequestParam("schId") Long schId) {
|
||
return flowService.getFlow(schId, flowGuid);
|
||
}
|
||
|
||
@PostMapping("/apply")
|
||
public OapiModels.ApplyResultVo apply(@RequestParam("schId") Long schId,
|
||
@RequestAttribute(value = "yh.app.auth", required = false) String appKey,
|
||
@RequestBody OapiModels.ApplyBody body) {
|
||
return flowService.apply(schId, appKey, body);
|
||
}
|
||
|
||
/** 发起预览:返回开启发起时指派的节点与候选人(已剔除发起人本人),供子应用提交页选人 */
|
||
@GetMapping("/apply/preview")
|
||
public OapiModels.ApplyPreviewVo applyPreview(@RequestParam("schId") Long schId,
|
||
@RequestParam("flowGuid") String flowGuid, @RequestParam("submitterId") Integer submitterId) {
|
||
return flowService.applyPreview(schId, flowGuid, submitterId);
|
||
}
|
||
|
||
@GetMapping("/instance")
|
||
public OapiModels.InstanceVo instance(@RequestParam("bizType") String bizType,
|
||
@RequestParam("bizId") String bizId,
|
||
@RequestParam("schId") Long schId) {
|
||
return flowService.instanceByBiz(schId, bizType, bizId);
|
||
}
|
||
|
||
/**
|
||
* 办件进度(结构化轨迹,SDK FlowProgress 契约):instanceId 或 bizType/bizId 定位。
|
||
* 消费方渲染时间线(发起申请→各节点办理人行),SDK com.yunhai.platform.openapi.flow.model 同构。
|
||
*/
|
||
@GetMapping("/progress")
|
||
public OapiModels.ProgressVo progress(@RequestParam(value = "instanceId", required = false) Long instanceId,
|
||
@RequestParam(value = "bizType", required = false) String bizType,
|
||
@RequestParam(value = "bizId", required = false) String bizId,
|
||
@RequestParam("schId") Long schId) {
|
||
return flowService.progress(schId, instanceId, bizType, bizId);
|
||
}
|
||
|
||
/**
|
||
* 流程图换图(token 模式,"CAS 验证码式嵌入"):img 标签带不了签名,本端点在 app-sign 保护下
|
||
* 签发短时 token,返回可直接放 {@code <img src>} 的免签路径 {@code /open/flow/diagram/img?token=}。
|
||
* 口径:instanceId=办件运行时状态图;flowGuid=最高已发布版定义图。
|
||
*/
|
||
@GetMapping("/diagram/url")
|
||
public OapiModels.DiagramUrlVo diagramUrl(@RequestParam(value = "instanceId", required = false) Long instanceId,
|
||
@RequestParam(value = "flowGuid", required = false) String flowGuid,
|
||
@RequestParam(value = "mode", required = false) String mode,
|
||
@RequestParam("schId") Long schId) {
|
||
return flowService.diagramUrl(schId, instanceId, flowGuid, mode);
|
||
}
|
||
|
||
/**
|
||
* 办件进度嵌入页换址(iframe 场景,token 模式与换图同构):pageUrl 为 flow-center 前端
|
||
* 绝对地址,子应用直接放 {@code <iframe src>}。用户级可见性(本人/办理人/管理员)由
|
||
* 子应用后端在调本端点前完成——oapi 层只认 schId,应用签名不替代"谁能看"。
|
||
*/
|
||
@GetMapping("/embed/url")
|
||
public OapiModels.EmbedUrlVo embedUrl(@RequestParam(value = "instanceId", required = false) Long instanceId,
|
||
@RequestParam(value = "bizType", required = false) String bizType,
|
||
@RequestParam(value = "bizId", required = false) String bizId,
|
||
@RequestParam(value = "mode", required = false) String mode,
|
||
@RequestParam(value = "taskId", required = false) Long taskId,
|
||
@RequestParam("schId") Long schId) {
|
||
return flowService.embedUrl(schId, instanceId, bizType, bizId, mode, taskId);
|
||
}
|
||
|
||
/**
|
||
* 撤回(提交人本人;仅尚无任务被办理时)。submitterId 由业务应用按其办件归属传入,
|
||
* 本端与办件提交人复核——应用签名不替代"谁在撤"的身份证明。
|
||
*/
|
||
@PostMapping("/instance/{instanceId}/withdraw")
|
||
public void withdraw(@RequestParam("schId") Long schId,
|
||
@RequestParam("submitterId") Integer submitterId,
|
||
@PathVariable("instanceId") Long instanceId) {
|
||
flowService.withdraw(schId, instanceId, submitterId);
|
||
}
|
||
|
||
@PostMapping("/callback/reg")
|
||
public OapiModels.CallbackRegResultVo registerCallback(
|
||
@RequestParam("schId") Long schId,
|
||
@RequestAttribute(value = "yh.app.auth", required = false) String appKey,
|
||
@RequestBody OapiModels.CallbackRegBody body) {
|
||
return flowService.registerCallback(schId, appKey, body);
|
||
}
|
||
|
||
/**
|
||
* 判断服务登记(2026-10-12 SERVICE 收口):由 {@code yh-flow-callback-spring-boot-starter} 启动自注册调用。
|
||
* 无 schId——{@code flw_router} 是全局表;归属即验签后的 appKey(登记即持有,跨应用覆盖拒绝)。
|
||
*/
|
||
@PostMapping("/router/reg")
|
||
public void registerRouter(@RequestAttribute(value = "yh.app.auth", required = false) String appKey,
|
||
@RequestBody OapiModels.RouterRegBody body) {
|
||
routerAdminService.registerByApp(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);
|
||
}
|
||
|
||
/**
|
||
* 按业务单据查当前人待办(v2.1 业务详情卡片数据源):与 tasks/todo 互补——那个是"人→单据",
|
||
* 这个是"单据→我的待办"。0/1/N 三种计数都由 HTTP 200 + tasks 数组表达,办件不存在与
|
||
* 他人待办同样出空(不用于探测)。operatorId 由子应用后端从 CAS 会话取,前端不可传。
|
||
*/
|
||
@GetMapping("/tasks/by-biz")
|
||
public OapiModels.ByBizTasksVo tasksByBiz(
|
||
@RequestParam("schId") Long schId,
|
||
@RequestParam("bizType") String bizType,
|
||
@RequestParam("bizId") String bizId,
|
||
@RequestParam("operatorId") Integer operatorId) {
|
||
return flowService.tasksByBiz(schId, bizType, bizId, operatorId);
|
||
}
|
||
|
||
/** 办件分页(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());
|
||
}
|
||
}
|