需要注意

  • 启动流程时传入businessKey,因为在事件接收时用与supports方法判断
/**
 * 启动流程实例
 */
private void startProcess(ProcessDefinition procDef, Map<String, Object> variables) {
    ...
    // 发起流程实例
    String businessKey = "";
    Object businessKeyObj = variables.get(BusiConstants.BUSINESS_KEY_NAME);
    if (ObjectUtil.isNotNull(businessKeyObj)) {
        businessKey = businessKeyObj.toString();
    }
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDef.getId(), businessKey, variables);
    // 第一个用户任务为发起人,则自动完成任务
    wfTaskService.startFirstTask(processInstance, variables);
}
  • 触发事件。当流程节点发起拒绝时。
// 发布工作流拒绝事件,由业务模块监听并处理(如释放名额等)
try {
    Map<String, Object> variables = processVariables;
    
    // 如果之前获取的变量为空,尝试从历史服务获取
    if (variables == null || variables.isEmpty()) {
        try {
            HistoricProcessInstance historicProcessInstance = historyService
                    .createHistoricProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .includeProcessVariables()
                    .singleResult();
            if (historicProcessInstance != null && historicProcessInstance.getProcessVariables() != null) {
                variables = historicProcessInstance.getProcessVariables();
                log.info("从历史服务获取流程变量成功,流程实例ID: {}", task.getProcessInstanceId());
            } else {
                variables = new HashMap<>();
                log.warn("从历史服务获取流程变量为空,流程实例ID: {}", task.getProcessInstanceId());
            }
        } catch (Exception e) {
            log.warn("从历史服务获取流程变量失败,流程实例ID: {}", task.getProcessInstanceId(), e);
            variables = new HashMap<>();
        }
    }
    
    String businessKey = processInstance.getBusinessKey();

    WorkflowRejectEvent event = new WorkflowRejectEvent();
    event.setBusinessKey(businessKey);
    event.setProcessInstanceId(task.getProcessInstanceId());
    event.setVariables(variables);
    event.setTaskId(task.getId());
    event.setTaskName(task.getName());
    event.setTaskDefinitionKey(task.getTaskDefinitionKey());
    event.setRejectReason(taskBo.getComment());

    eventPublisher.publishEvent(event);
    log.info("发布工作流拒绝事件,流程实例ID: {}, 业务Key: {}", task.getProcessInstanceId(), businessKey);
} catch (Exception e) {
    // 记录日志但不影响拒绝流程
    log.warn("发布工作流拒绝事件失败", e);
}

  • 监听事件进行处理。supports方法
/**
 * 项目申请拒绝事件监听器
 * 处理工作流拒绝事件,释放项目申请名额
 *
 * @author ruoyi
 * @date 2025-01-28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ProjectApplicationRejectListener implements WorkflowEventListener {

    private final IProjectApplicationService applicationService;
    private final ProjProjectApplicationMapper applicationMapper;

    @Override
    public boolean supports(WorkflowEvent event) {
        if (!(event instanceof WorkflowRejectEvent)) {
            return false;
        }
        // 只处理项目申请相关的拒绝事件
        return BusiConstants.BUSINESS_KEY.APPLY_PROJECT.equals(event.getBusinessKey());
    }

    @Override
    public void onEvent(WorkflowEvent event) {
        if (!supports(event)) {
            return;
        }

        try {
            WorkflowRejectEvent rejectEvent = (WorkflowRejectEvent) event;
            Map<String, Object> variables = rejectEvent.getVariables();

            if (variables == null) {
                log.warn("拒绝事件中未找到流程变量,流程实例ID: {}", rejectEvent.getProcessInstanceId());
                return;
            }

            // 从流程变量中获取项目相关信息
            Object projectIdObj = variables.get(BusiConstants.PROJECT_ID);
            Object batchIdObj = variables.get(BusiConstants.BATCH_ID);
            Object idNumberObj = variables.get(BusiConstants.ID_NUMBER);

            if (projectIdObj == null || batchIdObj == null || idNumberObj == null) {
                log.debug("拒绝事件中缺少必要的流程变量,流程实例ID: {}, projectId: {}, batchId: {}, idNumber: {}",
                        rejectEvent.getProcessInstanceId(), projectIdObj, batchIdObj, idNumberObj);
                return;
            }

            Long projectId = Long.parseLong(projectIdObj.toString());
            Long batchId = Long.parseLong(batchIdObj.toString());
            String idNumber = idNumberObj.toString();

            log.info("处理项目申请拒绝事件,释放名额,流程实例ID: {}, projectId: {}, batchId: {}, idNumber: {}",
                    rejectEvent.getProcessInstanceId(), projectId, batchId, idNumber);

            // 查询对应的申请记录
            ProjProjectApplicationDO application = applicationService.selectByProjectBatchIdNumber(
                    projectId, batchId, idNumber);

            if (application != null && ApplicationStatusConstants.COMPLETED.equals(application.getStatus())) {
                // 将状态从COMPLETED改为FAILED,释放名额
                application.setStatus(ApplicationStatusConstants.FAILED);
                // 系统自动处理,设置 updateBy 为 "system",自动填充会保留已设置的值并更新 updateTime
                application.setUpdateBy("system");
                applicationMapper.updateById(application);
                log.info("表单被拒绝,释放名额成功,applicationId: {}, projectId: {}, batchId: {}",
                        application.getApplicationId(), projectId, batchId);
            } else {
                log.debug("未找到需要释放名额的申请记录或状态不是COMPLETED,application: {}, status: {}",
                        application != null ? application.getApplicationId() : null,
                        application != null ? application.getStatus() : null);
            }

        } catch (Exception e) {
            // 记录日志但不影响主流程
            log.error("处理项目申请拒绝事件失败,流程实例ID: {}", event.getProcessInstanceId(), e);
        }
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐