按《FL最终代码审计与上线阻断清单》194 项已审计工作树形成候选,基座 = origin/main 11e0778。
- 源码/测试/资源:沿用已审计工作树内容(96 项相对远端为新增或更新),含未跟踪实现
CallbackFactStore、CallbackSourcePolicy、VariableContract、FormalApplyCommandService、
FlowActorContextGate 等;C01 续验夹具修正一并入内。
- CI:保留远端 11e0778 的门禁强化(CI_SOURCE_SHA 核对、容器回收验证、空 schema 反向门禁、
main ref 才推镜像);ci/flow-test-schema.sql 按当前实体重新生成(14→20 表,补 6 新表与
6 新列,回调日志复合唯一键 uk_flw_log_event_reg),workflow 表数断言同步 14→20。
- 依据:docs/tasks/evidence/FL-final-audit-20261027(194 项哈希/版本核对)。
319 lines
12 KiB
Java
319 lines
12 KiB
Java
package com.yunhai.flowcenter.model;
|
||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||
import lombok.Data;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* /oapi/flow/** 契约模型(出入参字段与 svc-hall FlowCenterClient 逐字对齐,
|
||
* 契约锚点:《流程中心M1开工说明.md》§5——两侧已编码,改动须双向同步)。
|
||
*/
|
||
public final class OapiModels {
|
||
|
||
private OapiModels() {
|
||
}
|
||
|
||
/** 流程摘要(list 元素 / {flowGuid} 详情) */
|
||
@Data
|
||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||
public static class FlowSummaryVo {
|
||
private String flowGuid;
|
||
private String name;
|
||
private Integer version;
|
||
private String nodeSummary;
|
||
}
|
||
|
||
/** 代发起请求体(POST /oapi/flow/apply;formData 为 JSON 对象透传) */
|
||
@Data
|
||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||
public static class ApplyBody {
|
||
private String flowGuid;
|
||
private String bizType;
|
||
private String bizId;
|
||
private String bizTitle;
|
||
private String bizUrl;
|
||
/** 业务摘要 JSON 快照(字符串或对象均可,统一落字符串) */
|
||
private Object bizSnapshot;
|
||
private Integer submitterId;
|
||
private String submitterName;
|
||
/** 表单数据对象(业务方编辑页产出,无表单模式不传) */
|
||
private Map<String, Object> formData;
|
||
/** 发起时指派(可选,2026-10-13):[{nodeId, userIds}],校验失败业务码拒绝发起 */
|
||
private List<AssignItem> assigns;
|
||
/**
|
||
* 期望的定义版本(可选,2026-10-17 S2.7 版本竞态):调用方拿 apply/preview 时回带的
|
||
* {@code defVersion} 原样传回。不匹配即业务码拒绝,报「流程已更新,请刷新后重新选择审批人」,
|
||
* 不再让选人结果落到改版后的线上而报「指派节点不存在」。不传=现状行为逐字不变(存量零影响)。
|
||
*/
|
||
private Integer expectedDefVersion;
|
||
}
|
||
|
||
/** 发起时指派项(apply 可选字段) */
|
||
@Data
|
||
public static class AssignItem {
|
||
private String nodeId;
|
||
private List<Integer> userIds;
|
||
}
|
||
|
||
/** 发起预览响应(GET /oapi/flow/apply/preview):只含开启指派的节点 */
|
||
@Data
|
||
public static class ApplyPreviewVo {
|
||
private String flowGuid;
|
||
/**
|
||
* 本次预览依据的已发布定义版本(2026-10-17 S2.7):调用方在 apply 时以
|
||
* {@code expectedDefVersion} 原样回带,改版即人类可读拒绝而非「指派节点不存在」。
|
||
*/
|
||
private Integer defVersion;
|
||
private List<PreviewNodeVo> nodes;
|
||
}
|
||
|
||
@Data
|
||
public static class PreviewNodeVo {
|
||
private String nodeId;
|
||
private String nodeName;
|
||
/** ANY|ALL(后端缺省补 ALL) */
|
||
private String countersign;
|
||
private PreviewSelectionVo selection;
|
||
private List<PreviewUserVo> candidates;
|
||
}
|
||
|
||
@Data
|
||
public static class PreviewSelectionVo {
|
||
/** SINGLE|MULTI */
|
||
private String mode;
|
||
private Integer min;
|
||
private Integer max;
|
||
/** 仅子应用 UI 必选提示;引擎不消费 */
|
||
private Boolean required;
|
||
}
|
||
|
||
@Data
|
||
public static class PreviewUserVo {
|
||
private Integer userId;
|
||
private String userName;
|
||
}
|
||
|
||
/** 代发起响应(biz uk 幂等:重复代发起 HTTP 200 + duplicated:true 返回既有办件) */
|
||
@Data
|
||
public static class ApplyResultVo {
|
||
private Long instanceId;
|
||
private boolean duplicated;
|
||
}
|
||
|
||
/** 按业务键查办件响应(对账兜底;traceJson 含 assigneeId 轨迹供办理人放行判定) */
|
||
@Data
|
||
public static class InstanceVo {
|
||
private Long instanceId;
|
||
private Integer applyRound;
|
||
private String requestToken;
|
||
/**
|
||
* 来源应用快照(2026-10-25 T04):UNKNOWN 恢复链按"稳定来源+requestToken"核验命令归属的
|
||
* 依据——查得实例但 applyAppKey 与本应用不符=他人办件,不得认领(P0-4 关闭点)。
|
||
*/
|
||
private String applyAppKey;
|
||
private Integer status;
|
||
private Integer version;
|
||
private String nodeSummary;
|
||
private String traceJson;
|
||
private List<Integer> assigneeIds;
|
||
private String currentNodes;
|
||
private String bizTitle;
|
||
private Integer submitterId;
|
||
private String submitterName;
|
||
private String submitTime;
|
||
private String finishTime;
|
||
}
|
||
|
||
/** 回调注册请求体(POST /oapi/flow/callback/reg) */
|
||
@Data
|
||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||
public static class CallbackRegBody {
|
||
private String flowGuid;
|
||
private String callbackUrl;
|
||
/** 订阅事件逗号分隔,空=全部 */
|
||
private String eventTypes;
|
||
/**
|
||
* 接收方 context-path / 网关前缀(可选,形如 /notice;无则空)。
|
||
* 推送时按 AppSignInterceptor 的既有约定从 URL path 中剥离后再签 X-Signature,
|
||
* 与接收方 AppAuthFilter 用 request.contextPath 剥离后的 path 对齐——配置错会 401。
|
||
*/
|
||
private String basePath;
|
||
}
|
||
|
||
/** 回调注册响应(secret 注册时生成下发) */
|
||
@Data
|
||
public static class CallbackRegResultVo {
|
||
private String secret;
|
||
}
|
||
|
||
/**
|
||
* 判断服务登记请求体(POST /oapi/flow/router/reg,2026-10-12 SERVICE 收口):
|
||
* 由 yh-flow-callback-spring-boot-starter 启动时自动提交,字段与 SDK
|
||
* {@code com.yunhai.platform.openapi.flow.model.FlowRouterRegBody} 逐字对齐。
|
||
*/
|
||
@Data
|
||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||
public static class RouterRegBody {
|
||
private String routerKey;
|
||
private String name;
|
||
/** 判断端点路径(如 /oapi/flow/route/judge) */
|
||
private String judgePath;
|
||
/** 直连基址 scheme://authority[/ctx] */
|
||
private String directHost;
|
||
}
|
||
|
||
/**
|
||
* 办件进度(结构化轨迹,2026-09-16 用户拍板:SDK 对外提供图3/图4时间线数据源)。
|
||
* steps 按 nodeId 任务到达顺序聚合(同人多任务行保留原始顺序),发起申请固定为第 0 步。
|
||
* SDK DTO com.yunhai.platform.openapi.flow.model.FlowProgress 与本契约逐字对齐。
|
||
*/
|
||
@Data
|
||
public static class ProgressVo {
|
||
private Long instanceId;
|
||
private String bizType;
|
||
private String bizId;
|
||
private String bizTitle;
|
||
/** 办件状态:10 审批中 / 20 已完成 / 30 已拒绝 / 40 已撤回 */
|
||
private Integer status;
|
||
private String currentNodes;
|
||
private Integer submitterId;
|
||
private String submitterName;
|
||
private String submitTime;
|
||
private String finishTime;
|
||
private List<ProgressStepVo> steps;
|
||
}
|
||
|
||
/** 进度步骤(同一节点全部任务行聚合为一步,b 会签时 assignees 多行) */
|
||
@Data
|
||
public static class ProgressStepVo {
|
||
private String nodeId;
|
||
private String nodeName;
|
||
/** 步骤标签:发起申请/待审核/已同意/已拒绝/已退回/已移交/失效(任务状态汇总口径见 FlowProgress.stage) */
|
||
private String label;
|
||
/** 节点当前是否在办 */
|
||
private boolean active;
|
||
private List<ProgressTaskVo> assignees;
|
||
}
|
||
|
||
/** 进度步骤内的办理人行(多人步骤每人一条;状态取自该行任务真实状态) */
|
||
@Data
|
||
public static class ProgressTaskVo {
|
||
private Long taskId;
|
||
private Integer userId;
|
||
private String userName;
|
||
/** 任务状态:0 待办 / 1 同意 / 2 拒绝 / 3 失效 / 4 已退回 / 5 已移交 */
|
||
private Integer status;
|
||
private String statusLabel;
|
||
private String opinion;
|
||
private String arriveTime;
|
||
private String handleTime;
|
||
/** 多出口节点办理时所选出口名 */
|
||
private String edgeName;
|
||
}
|
||
|
||
/** 流程图图片流换图响应(token 换图模式:imgUrl 可直接放 <img src>,免 app-sign) */
|
||
@Data
|
||
public static class DiagramUrlVo {
|
||
/** 免签图片端点相对路径(?token=xxx),消费方可拼到本服务的对外网关地址后 */
|
||
private String imgUrl;
|
||
/** 相对 token 有效期(秒) */
|
||
private long expiresIn;
|
||
}
|
||
|
||
/** 办件进度嵌入页换址响应(pageUrl 可直接放 <iframe src>,SDK FlowEmbedUrl 同构) */
|
||
@Data
|
||
public static class EmbedUrlVo {
|
||
/** 嵌入页绝对地址(flow-center 前端基址 + hash 路由 + 短时 token) */
|
||
private String pageUrl;
|
||
/** 相对 token 有效期(秒) */
|
||
private long expiresIn;
|
||
}
|
||
|
||
/** 待办任务行(tasks/todo 元素):审批列表页数据源,带办件定位与快照 */
|
||
@Data
|
||
public static class TodoTaskVo {
|
||
private Long taskId;
|
||
private Long instanceId;
|
||
/** 办件当前版本(办理前对账用) */
|
||
private Integer instanceVersion;
|
||
private String bizType;
|
||
private String bizId;
|
||
private String bizTitle;
|
||
/** 办件快照原文(JSON 字符串,发起时未传则 null) */
|
||
private String bizSnapshot;
|
||
private String nodeId;
|
||
private String nodeName;
|
||
private Integer assigneeId;
|
||
private String assigneeName;
|
||
private String arriveTime;
|
||
}
|
||
|
||
/** 办件行(instances 元素):应用侧列表/对账数据源 */
|
||
@Data
|
||
public static class InstanceItemVo {
|
||
private Long instanceId;
|
||
private Integer status;
|
||
private Integer version;
|
||
private String bizType;
|
||
private String bizId;
|
||
private String bizTitle;
|
||
private String bizUrl;
|
||
private String submitterName;
|
||
private String submitTime;
|
||
private String finishTime;
|
||
private String currentNodes;
|
||
}
|
||
|
||
/** 办理入参(approve/reject 请求体;opinion 可空,拒绝侧服务层强制必填) */
|
||
@Data
|
||
public static class HandleBody {
|
||
private String opinion;
|
||
/** 多出口节点办理时所选出口名(单出口可省) */
|
||
private String edgeName;
|
||
}
|
||
|
||
/**
|
||
* 按业务单据定位的当前人待办(tasks/by-biz 出参,v2.1 应用内审批卡片数据源)。
|
||
* 无办件与"有办件但本人无待办"同为 tasks=[] + HTTP 200,出参不区分二者(防探测)。
|
||
*/
|
||
@Data
|
||
public static class ByBizTasksVo {
|
||
/** 办件 id;无办件时 null */
|
||
private Long instanceId;
|
||
private String bizType;
|
||
private String bizId;
|
||
/** 办件状态;无办件时 null */
|
||
private Integer status;
|
||
/**
|
||
* 办件当前活跃节点——**节点 id** 逗号串,原文照抄 {@code flw_instance.current_nodes},
|
||
* 与 {@code instances}/{@code progress} 同口径(不是节点名,渲染人读名称请取
|
||
* {@code tasks[].nodeName})。无办件时 null。
|
||
*/
|
||
private String currentNodes;
|
||
/** 当前人 PENDING 任务,按 taskId 升序;无待办为空数组 */
|
||
private List<ByBizTaskVo> tasks = new ArrayList<>();
|
||
}
|
||
|
||
/** by-biz 单条待办:只含办理该任务必需的定位信息,不透出他人办理人/意见 */
|
||
@Data
|
||
public static class ByBizTaskVo {
|
||
private Long taskId;
|
||
private String nodeId;
|
||
private String nodeName;
|
||
private String arriveTime;
|
||
/** 出口列表;单出口节点为空数组(与 FlowQueryService.detail 的 outlets 口径一致) */
|
||
private List<ByBizOutletVo> outlets = new ArrayList<>();
|
||
}
|
||
|
||
/** by-biz 出口(多出口节点办理时须选其一,透传给 approve 的 edgeName) */
|
||
@Data
|
||
public static class ByBizOutletVo {
|
||
private String name;
|
||
private String toNodeId;
|
||
private String toNodeName;
|
||
}
|
||
}
|