feat(pigx-flow-api): 新增流程状态事件注册与校验功能

- 在FlowStatusEventPublisher中添加流程ID注册和校验方法,使用Redis Set存储已注册的flowId
- 更新FlowStatusEventAutoConfiguration,在启动时自动注册所有本地flowId到Redis
- 重构ProcessServiceImpl中的validateFlowId方法,改为通过Redis查询flowId注册状态
- 优化BpmOaLeaveServiceImpl中的流程参数设置逻辑,使用Dict构建root用户信息
This commit is contained in:
PIGCLOUD committed 2026-03-08 15:02:49 +08:00
1 parent 618f3ff1d5
commit 84041ed7ce
4 files changed
+42 -24

No files matched your search

@@ -40,7 +40,9 @@ public class FlowStatusEventAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnBean(IProcessInstanceStatusEventService.class)
public FlowStatusEventListener flowStatusEventListener(List<IProcessInstanceStatusEventService> eventServices,
StringRedisTemplate redisTemplate) {
StringRedisTemplate redisTemplate, FlowStatusEventPublisher publisher) {
// 启动时注册所有本地 flowId 到 Redis
eventServices.forEach(service -> publisher.registerFlowId(service.getFlowId()));
return new FlowStatusEventListener(eventServices, redisTemplate);
}
@@ -1,6 +1,7 @@
package com.pig4cloud.pigx.flow.event;
import cn.hutool.json.JSONUtil;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.flow.dto.ProcessInstanceParamDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -21,6 +22,8 @@ public class FlowStatusEventPublisher {
public static final String CHANNEL = "pigx:flow:status";
public static final String REGISTERED_FLOW_IDS_KEY = CacheConstants.GLOBALLY + "flow:registered-flow-ids";
private final StringRedisTemplate redisTemplate;
/**
@@ -34,4 +37,22 @@ public class FlowStatusEventPublisher {
paramDto.getProcessInstanceId());
}
/**
* 注册 flowId 到 Redis Set
* @param flowId 流程定义Key
*/
public void registerFlowId(String flowId) {
redisTemplate.opsForSet().add(REGISTERED_FLOW_IDS_KEY, flowId);
log.debug("注册 flowId: {}", flowId);
}
/**
* 校验 flowId 是否已注册
* @param flowId 流程定义Key
* @return true 表示已注册
*/
public boolean isFlowIdRegistered(String flowId) {
return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(REGISTERED_FLOW_IDS_KEY, flowId));
}
}
@@ -1,18 +1,22 @@
package com.pig4cloud.pigx.flow.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import com.pig4cloud.pigx.flow.api.feign.RemoteFlowApiFlowService;
import com.pig4cloud.pigx.flow.constant.NodeUserTypeEnum;
import com.pig4cloud.pigx.flow.dto.ProcessInstanceParamDto;
import com.pig4cloud.pigx.flow.entity.BpmOaLeaveEntity;
import com.pig4cloud.pigx.flow.mapper.BpmOaLeaveMapper;
import com.pig4cloud.pigx.flow.service.BpmOaLeaveService;
import com.pig4cloud.pigx.flow.support.utils.FlowableUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 请假表单
*
@@ -63,8 +67,13 @@ public class BpmOaLeaveServiceImpl extends ServiceImpl<BpmOaLeaveMapper, BpmOaLe
// 发起哪个流程 (LEAVE)
processInstanceParamDto.setFlowId(this.getFlowId());
// 设置流程审批人/发起人信息
processInstanceParamDto.setParamMap(FlowableUtils.getFlowParamMap(bpmOaLeave));
Map<String, Object> flowParamMap = bpmOaLeave.getFlowParamMap();
Dict rootUser = Dict.create()
.set("id", SecurityUtils.getUser().getId())
.set("name", SecurityUtils.getUser().getUsername())
.set("type", NodeUserTypeEnum.USER.getKey());
flowParamMap.put("root", CollUtil.newArrayList(rootUser));
processInstanceParamDto.setParamMap(flowParamMap);
R<String> stringR = flowApiFlowService.startProcessInstance(processInstanceParamDto);
bpmOaLeave.setProcessInstanceId(stringR.getData());
baseMapper.updateById(bpmOaLeave);
@@ -23,7 +23,7 @@ import com.pig4cloud.pigx.flow.dto.Node;
import com.pig4cloud.pigx.flow.dto.NodeUser;
import com.pig4cloud.pigx.flow.entity.Process;
import com.pig4cloud.pigx.flow.entity.ProcessStarter;
import com.pig4cloud.pigx.flow.event.IProcessInstanceStatusEventService;
import com.pig4cloud.pigx.flow.event.FlowStatusEventPublisher;
import com.pig4cloud.pigx.flow.mapper.ProcessMapper;
import com.pig4cloud.pigx.flow.service.IProcessService;
import com.pig4cloud.pigx.flow.service.IProcessStarterService;
@@ -43,7 +43,6 @@ import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 流程定义服务实现类
@@ -69,7 +68,7 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
private final Sequence flowSequence;
private final Optional<List<IProcessInstanceStatusEventService>> processInstanceStatusEventServicesOptional;
private final FlowStatusEventPublisher flowStatusEventPublisher;
/**
* 获取流程详细信息
@@ -301,10 +300,10 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
}
/**
* 验证流程ID是否在所有IProcessInstanceStatusEventService实现类中存在
* 验证流程ID是否已注册流程状态事件处理
* <p>
* 遍历所有实现了IProcessInstanceStatusEventService接口的服务类,检查输入的flowId
* 是否与任意一个服务的getFlowId()返回值匹配。如果匹配则返回true,否则返回false。
* 通过 Redis Set 查询 flowId 是否已被任意微服务模块注册,
* 支持跨服务校验。
* </p>
*
* @param flowId 流程定义ID
@@ -312,23 +311,10 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
*/
@Override
public R<Boolean> validateFlowId(String flowId) {
// 如果flowId为空,直接返回false
if (StrUtil.isBlank(flowId)) {
return R.ok(false);
}
// 如果没有IProcessInstanceStatusEventService实现类,返回false
if (processInstanceStatusEventServicesOptional.isEmpty()) {
log.warn("未找到任何IProcessInstanceStatusEventService实现类");
return R.ok(false);
}
// 遍历所有实现类,检查flowId是否存在
List<IProcessInstanceStatusEventService> serviceList = processInstanceStatusEventServicesOptional.get();
boolean exists = serviceList.stream()
.anyMatch(service -> flowId.equals(service.getFlowId()));
return R.ok(exists);
return R.ok(flowStatusEventPublisher.isFlowIdRegistered(flowId));
}
}