在飞工作合入:FlowEvent 增操作人字段(可空),引擎/推进监听/回调派发全程透传, 对齐 SDK FlowCallbackEvent 的 taskId/operator 字段(规范 §6.4)。
82 lines
3.8 KiB
Java
82 lines
3.8 KiB
Java
package com.yunhai.flowcenter.engine;
|
||
|
||
import com.yunhai.flowcenter.entity.FlwDef;
|
||
import com.yunhai.flowcenter.entity.FlwInstance;
|
||
import com.yunhai.flowcenter.entity.FlwTask;
|
||
import com.yunhai.flowcenter.enums.FlwEnums;
|
||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||
import com.yunhai.flowcenter.repository.FlwTaskRepository;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Propagation;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
/**
|
||
* 节点放行推进(AFTER_COMMIT 监听器经代理调用本 bean,REQUIRES_NEW 生效——
|
||
* 事务已提交后的同步监听阶段没有活动事务,@Modifying 批量语句必须有新事务承载):
|
||
* 该节点待办清零且办件在途才推进;并发冲突由 flw_instance.version 乐观锁暴露,监听器层负责重试。
|
||
*/
|
||
@Slf4j
|
||
@Service
|
||
@RequiredArgsConstructor
|
||
public class FlowAdvanceService {
|
||
|
||
private final FlwInstanceRepository instanceRepository;
|
||
private final FlwDefRepository defRepository;
|
||
private final FlwTaskRepository taskRepository;
|
||
private final FlowEngine flowEngine;
|
||
|
||
/**
|
||
* @param nodeId 待放行节点
|
||
* @param edgeName 多出口节点所选出口(办理事件携带);可空——兜底从该节点
|
||
* 最近一条已同意任务的 edge_name 列重放(推进在 AFTER_COMMIT 新事务重查,
|
||
* 事件传参只是快路径,落库的值才是权威)
|
||
* @param operator 本节点办理人(TASK_HANDLED 事件 data 穿透;推进产生的
|
||
* TASK_CREATED/COMPLETED 操作人信封字段来源),可空
|
||
* @return 是否实际推进了
|
||
*/
|
||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||
public boolean tryAdvance(Long instanceId, String nodeId, String edgeName, FlowOperator operator) {
|
||
FlwInstance instance = instanceRepository.findById(instanceId).orElse(null);
|
||
if (instance == null
|
||
|| instance.getStatus() != FlwEnums.InstanceStatus.APPROVING.getCode()) {
|
||
return false;
|
||
}
|
||
// 已推进过的节点不再放行(currentNodes 由引擎在放行时移除,乐观锁保证互斥)
|
||
String current = instance.getCurrentNodes();
|
||
boolean active = current != null && java.util.Arrays.stream(current.split(","))
|
||
.anyMatch(nodeId::equals);
|
||
if (!active) {
|
||
return false;
|
||
}
|
||
long pending = taskRepository.findByInstanceIdAndStatus(instanceId,
|
||
FlwEnums.TaskStatus.PENDING.getCode()).stream()
|
||
.filter(t -> nodeId.equals(t.getNodeId()))
|
||
.count();
|
||
if (pending > 0) {
|
||
return false;
|
||
}
|
||
FlwDef def = defRepository.findById(instance.getDefId()).orElse(null);
|
||
if (def == null) {
|
||
log.error("[flow-center] 办件定义缺失,推进中止:instance={} defId={}",
|
||
instanceId, instance.getDefId());
|
||
return false;
|
||
}
|
||
String chosen = edgeName;
|
||
if (chosen == null) {
|
||
chosen = taskRepository.findByInstanceIdAndStatus(instanceId,
|
||
FlwEnums.TaskStatus.APPROVED.getCode()).stream()
|
||
.filter(t -> nodeId.equals(t.getNodeId()) && t.getEdgeName() != null)
|
||
.max(java.util.Comparator.comparing(
|
||
FlwTask::getHandleTime, java.util.Comparator.nullsFirst(java.util.Comparator.naturalOrder())))
|
||
.map(FlwTask::getEdgeName)
|
||
.orElse(null);
|
||
}
|
||
flowEngine.continueAdvance(instance, def, nodeId, chosen, operator);
|
||
instanceRepository.save(instance);
|
||
return true;
|
||
}
|
||
}
|