- 已办去重: 同一办件一行 + doneCount 累计次数(FlwTaskRepository 查询去重)
- 发起/撤回/重提留痕事件行(状态码 6/7, 无需 DDL); /oapi/flow/progress steps 含撤回/重提步骤
- 管理端新增启用回路: POST /admin/map/enable/{id}、POST /admin/def/enable/{id}; GET /api/flow/def/source 源码查询
- 修复 findEnabledByOrdId 未过滤 status 的隐性缺陷; 新增 DeptLabelSupport 科室标签支撑
- 测试: FlowEngineIT 撤回留痕/已办去重断言、OapiFlowContractIT 撤回步骤断言(94 tests 全过)
- 本地验签修复: 本地 UserBase 无 context-path, yh.open.services 显式覆盖服务目录枚举兜底的 /userbase basePath, 否则出站签名与服务端剥离不对齐 → GetUserInfo 等全部「验签失败」; 生产经 Caddy 挂 /userbase 时删除 services 覆盖
This commit is contained in:
@@ -217,7 +217,54 @@ public class OapiFlowService {
|
||||
if (instance.getCurrentNodes() != null && !instance.getCurrentNodes().isEmpty()) {
|
||||
activeNodes.addAll(Arrays.asList(instance.getCurrentNodes().split(",")));
|
||||
}
|
||||
// 第 0 步固定"发起申请"(对外时间线图3/图4口径)
|
||||
List<FlwTask> rows = taskRepository.findByInstanceIdOrderByIdAsc(instance.getId());
|
||||
boolean hasSubmitRow = rows.stream()
|
||||
.anyMatch(t -> FlwEnums.TaskStatus.NODE_SUBMIT.equals(t.getNodeId()));
|
||||
List<OapiModels.ProgressStepVo> steps = new ArrayList<>();
|
||||
// 第 0 步"发起申请"(对外时间线图3/图4口径):2026-09-18 起发起会留痕成真实任务行,
|
||||
// 有真实行时由下面的循环出这一步(可见内容与这里的合成步一致);老办件没有真实行,
|
||||
// 仍按办件快照合成,存量数据对外表现不变。
|
||||
if (!hasSubmitRow) {
|
||||
steps.add(submitStep(instance));
|
||||
}
|
||||
// 轨迹留痕事件行(6 发起/重新提交、7 撤回)单独成步;步骤 label 直接用事件语义,
|
||||
// 不参与下面的"任一拒绝>任一同意>全失效"汇总(否则会被判成"失效")。
|
||||
Set<OapiModels.ProgressStepVo> eventSteps =
|
||||
java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>());
|
||||
|
||||
// 步骤聚合:nodeId 保序;同节点多任务行(会签/退回重到/失效清理)并入同一多人步骤
|
||||
Map<String, OapiModels.ProgressStepVo> stepsByNode = new HashMap<>();
|
||||
for (FlwTask t : rows) {
|
||||
if (FlwEnums.TaskStatus.eventCodes().contains(t.getStatus())) {
|
||||
OapiModels.ProgressStepVo es = eventStep(t);
|
||||
eventSteps.add(es);
|
||||
steps.add(es);
|
||||
continue;
|
||||
}
|
||||
OapiModels.ProgressStepVo step = stepsByNode.computeIfAbsent(t.getNodeId(), k -> {
|
||||
OapiModels.ProgressStepVo s = new OapiModels.ProgressStepVo();
|
||||
s.setNodeId(t.getNodeId());
|
||||
s.setNodeName(t.getNodeName());
|
||||
s.setAssignees(new ArrayList<>());
|
||||
steps.add(s);
|
||||
return s;
|
||||
});
|
||||
step.getAssignees().add(taskVo(t));
|
||||
}
|
||||
// 步骤 label:在办节点=待审核,其余取办理人行的汇总(任一拒绝=已拒绝 > 任一同意=已同意 > 全失效=失效)
|
||||
for (OapiModels.ProgressStepVo s : steps) {
|
||||
if (eventSteps.contains(s)) {
|
||||
continue;
|
||||
}
|
||||
s.setActive(activeNodes.contains(s.getNodeId()));
|
||||
s.setLabel(s.isActive() ? "待审核" : stepLabel(s.getAssignees()));
|
||||
}
|
||||
vo.setSteps(steps);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/** 合成"发起申请"步(老办件:无真实留痕行,取办件快照的提交人/提交时间) */
|
||||
private OapiModels.ProgressStepVo submitStep(FlwInstance instance) {
|
||||
OapiModels.ProgressStepVo submit = new OapiModels.ProgressStepVo();
|
||||
submit.setNodeId("submit");
|
||||
submit.setNodeName("发起申请");
|
||||
@@ -228,44 +275,49 @@ public class OapiFlowService {
|
||||
submitter.setUserName(instance.getSubmitterName());
|
||||
submitter.setStatus(1);
|
||||
submitter.setStatusLabel("已提交");
|
||||
submitter.setArriveTime(vo.getSubmitTime());
|
||||
submitter.setArriveTime(instance.getSubmitTime() == null ? null : instance.getSubmitTime().toString());
|
||||
submit.setAssignees(new ArrayList<>(java.util.Collections.singletonList(submitter)));
|
||||
List<OapiModels.ProgressStepVo> steps = new ArrayList<>();
|
||||
steps.add(submit);
|
||||
return submit;
|
||||
}
|
||||
|
||||
// 步骤聚合:nodeId 保序;同节点多任务行(会签/退回重到/失效清理)并入同一多人步骤
|
||||
Map<String, OapiModels.ProgressStepVo> stepsByNode = new HashMap<>();
|
||||
for (FlwTask t : taskRepository.findByInstanceIdOrderByIdAsc(instance.getId())) {
|
||||
OapiModels.ProgressStepVo step = stepsByNode.computeIfAbsent(t.getNodeId(), k -> {
|
||||
OapiModels.ProgressStepVo s = new OapiModels.ProgressStepVo();
|
||||
s.setNodeId(t.getNodeId());
|
||||
s.setNodeName(t.getNodeName());
|
||||
s.setAssignees(new ArrayList<>());
|
||||
steps.add(s);
|
||||
return s;
|
||||
});
|
||||
OapiModels.ProgressTaskVo row = new OapiModels.ProgressTaskVo();
|
||||
row.setTaskId(t.getId());
|
||||
row.setUserId(t.getAssigneeId());
|
||||
row.setUserName(t.getAssigneeName());
|
||||
row.setStatus(t.getStatus());
|
||||
row.setStatusLabel(taskLabel(t.getStatus()));
|
||||
row.setOpinion(t.getOpinion());
|
||||
row.setArriveTime(t.getArriveTime() == null ? null : t.getArriveTime().toString());
|
||||
row.setHandleTime(t.getHandleTime() == null ? null : t.getHandleTime().toString());
|
||||
row.setEdgeName(t.getEdgeName());
|
||||
step.getAssignees().add(row);
|
||||
/**
|
||||
* 留痕事件步(发起/重新提交/撤回):nodeId 用保留值 submit/resubmit/withdraw。
|
||||
* 发起步保留原合成步的口径(nodeName/label=发起申请、参与行 status=1/已提交),
|
||||
* 使新老办件对外输出一致;撤回与重新提交是本轮新增的对外可见动作。
|
||||
*/
|
||||
private OapiModels.ProgressStepVo eventStep(FlwTask t) {
|
||||
boolean submitted = FlwEnums.TaskStatus.SUBMITTED.getCode() == t.getStatus();
|
||||
OapiModels.ProgressStepVo step = new OapiModels.ProgressStepVo();
|
||||
step.setNodeId(t.getNodeId());
|
||||
step.setNodeName(t.getNodeName());
|
||||
step.setActive(false);
|
||||
step.setLabel(!submitted ? "已撤回"
|
||||
: (FlwEnums.TaskStatus.NODE_SUBMIT.equals(t.getNodeId()) ? "发起申请" : "已提交"));
|
||||
OapiModels.ProgressTaskVo vo = taskVo(t);
|
||||
if (submitted) {
|
||||
// 发起/重新提交沿用"已提交"文案(status=1 与老合成步一致,消费方无需适配)
|
||||
vo.setStatus(1);
|
||||
vo.setStatusLabel("已提交");
|
||||
} else {
|
||||
vo.setStatusLabel("已撤回");
|
||||
}
|
||||
// 步骤 label:在办节点=待审核,其余取办理人行的汇总(任一拒绝=已拒绝 > 任一同意=已同意 > 全失效=失效)
|
||||
for (OapiModels.ProgressStepVo s : steps) {
|
||||
if (s == submit) {
|
||||
continue;
|
||||
}
|
||||
s.setActive(activeNodes.contains(s.getNodeId()));
|
||||
s.setLabel(s.isActive() ? "待审核" : stepLabel(s.getAssignees()));
|
||||
}
|
||||
vo.setSteps(steps);
|
||||
return vo;
|
||||
step.setAssignees(new ArrayList<>(java.util.Collections.singletonList(vo)));
|
||||
return step;
|
||||
}
|
||||
|
||||
/** 任务行 → 对外步骤里的办理人行 */
|
||||
private OapiModels.ProgressTaskVo taskVo(FlwTask t) {
|
||||
OapiModels.ProgressTaskVo row = new OapiModels.ProgressTaskVo();
|
||||
row.setTaskId(t.getId());
|
||||
row.setUserId(t.getAssigneeId());
|
||||
row.setUserName(t.getAssigneeName());
|
||||
row.setStatus(t.getStatus());
|
||||
row.setStatusLabel(taskLabel(t.getStatus()));
|
||||
row.setOpinion(t.getOpinion());
|
||||
row.setArriveTime(t.getArriveTime() == null ? null : t.getArriveTime().toString());
|
||||
row.setHandleTime(t.getHandleTime() == null ? null : t.getHandleTime().toString());
|
||||
row.setEdgeName(t.getEdgeName());
|
||||
return row;
|
||||
}
|
||||
|
||||
private String taskLabel(Integer status) {
|
||||
@@ -279,6 +331,8 @@ public class OapiFlowService {
|
||||
case 3: return "失效";
|
||||
case 4: return "已退回";
|
||||
case 5: return "已移交";
|
||||
case 6: return "已提交";
|
||||
case 7: return "已撤回";
|
||||
default: return String.valueOf(status);
|
||||
}
|
||||
}
|
||||
@@ -408,7 +462,13 @@ public class OapiFlowService {
|
||||
return vo;
|
||||
}
|
||||
|
||||
/** 办件出参:轨迹(含 assigneeId,拍板项#3 办理人放行判定依赖) */
|
||||
/**
|
||||
* 办件出参:轨迹(含 assigneeId,拍板项#3 办理人放行判定依赖)。
|
||||
*
|
||||
* <p>2026-09-18:留痕事件行(6 发起/重新提交、7 撤回)<b>不进</b>本出参——它是"办理人与进度"
|
||||
* 的对账口径(assigneeIds 明确是"办理人集合",提交人另有 submitterId 字段,混进来会让
|
||||
* 消费方把提交人当办理人)。撤回/重提的对外可见性走 /oapi/flow/progress 的 steps(人读轨迹)。
|
||||
*/
|
||||
public OapiModels.InstanceVo toInstanceVo(FlwInstance instance) {
|
||||
OapiModels.InstanceVo vo = new OapiModels.InstanceVo();
|
||||
vo.setInstanceId(instance.getId());
|
||||
@@ -425,6 +485,9 @@ public class OapiFlowService {
|
||||
List<Map<String, Object>> trace = new ArrayList<>();
|
||||
Set<Integer> assigneeIds = new LinkedHashSet<>();
|
||||
for (com.yunhai.flowcenter.entity.FlwTask t : tasks) {
|
||||
if (FlwEnums.TaskStatus.eventCodes().contains(t.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
assigneeIds.add(t.getAssigneeId());
|
||||
Map<String, Object> row = new HashMap<>();
|
||||
row.put("taskId", t.getId());
|
||||
|
||||
Reference in New Issue
Block a user