Files
flow-center-service/src/main/java/com/yunhai/flowcenter/engine/FlowAdvanceService.java
T
chenxing c1103aeb29
build / build-push (push) Successful in 28s
feat: 提交流程中心后端代码
Spring Boot 流程引擎服务:流程定义/实例/任务、审批人解析、
回调分发、oapi 接口及单元测试。
保留远程 .gitea/workflows/build.yml 与 docker/Dockerfile,
新增 .gitignore 排除 target/ 构建产物。
2026-09-15 10:42:56 +08:00

63 lines
2.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.flowcenter.engine;
import com.yunhai.flowcenter.entity.FlwDef;
import com.yunhai.flowcenter.entity.FlwInstance;
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;
/** @return 是否实际推进了 */
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean tryAdvance(Long instanceId, String nodeId) {
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;
}
flowEngine.continueAdvance(instance, def, nodeId);
instanceRepository.save(instance);
return true;
}
}