build / build-push (push) Successful in 28s
Spring Boot 流程引擎服务:流程定义/实例/任务、审批人解析、 回调分发、oapi 接口及单元测试。 保留远程 .gitea/workflows/build.yml 与 docker/Dockerfile, 新增 .gitignore 排除 target/ 构建产物。
63 lines
2.7 KiB
Java
63 lines
2.7 KiB
Java
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;
|
||
}
|
||
}
|