yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
@@ -122,8 +122,10 @@ ProcessDefinition processDefinition = id != null ? processDefinitionService.getProcessDefinition(id) : processDefinitionService.getActiveProcessDefinition(key); if (processDefinition == null) { // ç¼å·ä¸å卿¶è¿å nullï¼ä¸ãkey æ¥ä¸å°ãä¿æä¸è´ï¼é¿å Flowable æå¼å¸¸åæ 500 return success(null); } // ç¼å·ä¸å卿¶ä¸é¢çæ¥è¯¢ä¼è¿å nullï¼è¿éç´æ¥è¿å nullï¼é¿å NPE åæ 500 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(processDefinition.getId()); BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId()); return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinition( yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
@@ -107,9 +107,13 @@ BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class); respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance)) .setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance)); // definition respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); copyTo(processDefinitionInfo, respVO.getProcessDefinition()); // definitionï¼æµç¨å®ä¹å¯è½å·²è¢«å é¤ï¼éè¦å®¹éï¼å¦åå端æ¿å° 500ï¼ if (processDefinition != null) { respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); if (respVO.getProcessDefinition() != null && processDefinitionInfo != null) { copyTo(processDefinitionInfo, respVO.getProcessDefinition()); } } // user if (startUser != null) { respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java
@@ -15,8 +15,18 @@ return selectList(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionIds); } /** * æ¥è¯¢æµç¨å®ä¹çæ©å±ä¿¡æ¯ * * åå²åå åä¸ processDefinitionId å¯è½åå¨å¤æ¡è®°å½ï¼ä¾å¦éå¤é¨ç½²/éå¤ä¿å模åï¼ï¼ * ç´æ¥ç¨ selectOne 伿 TooManyResultsException å¯¼è´æ¥å£ 500ï¼ * è¿éæ¹ä¸ºåææ°ç䏿¡ï¼ä¿è¯æ¥å£å¯ç¨ã */ default BpmProcessDefinitionInfoDO selectByProcessDefinitionId(String processDefinitionId) { return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId); List<BpmProcessDefinitionInfoDO> list = selectList(new LambdaQueryWrapperX<BpmProcessDefinitionInfoDO>() .eq(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId) .orderByDesc(BpmProcessDefinitionInfoDO::getId)); return list.isEmpty() ? null : list.get(0); } default void updateByModelId(String modelId, BpmProcessDefinitionInfoDO updateObj) { yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmProcessDefinitionIdUtils.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,57 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; import cn.hutool.core.util.StrUtil; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; /** * Flowable æµç¨å®ä¹ç¼å·å·¥å · * * <p>æµç¨å®ä¹ç¼å·å½¢å¦ {@code qingjia:2:553a7ac9-...}ï¼å å«åå·ã * åç«¯å¦æå¯¹è¯¥å¼åäº URL ç¼ç ååä½ä¸ºæ¥è¯¢åæ°ä¼ éï¼åéç¼ç ï¼ï¼ * Spring åªè§£ç ä¸å±ï¼æç»æ¿å°ç仿¯ {@code qingjia%3A2%3A...}ï¼ * Flowable æè¯¥ç¼å·æ¥ä¸å°æµç¨å®ä¹ï¼ç´æ¥æ FlowableObjectNotFoundException å¯¼è´ 500ã * * <p>è¿éå¨å ¥å£å¤å䏿¬¡å¹ççå½ä¸åï¼åªå¨ç¡®å®æ®ç % è½¬ä¹æ¶æè§£ç ï¼ * åæ³çæµç¨å®ä¹ç¼å·ä¸å¯è½å å« %ï¼å æ¤ä¸ä¼è¯¯ä¼¤ã * * @author è¶ çº§ç®¡çå */ public class BpmProcessDefinitionIdUtils { /** æå¤è§£ç 屿°ï¼é²æ¢å¼å¸¸è¾å ¥æ éå¾ªç¯ */ private static final int MAX_DECODE_TIMES = 5; private BpmProcessDefinitionIdUtils() { } /** * å½ä¸åæµç¨å®ä¹ç¼å·ï¼æå¤è§£ç ä¸å±æ®çç URL è½¬ä¹ * * @param id æµç¨å®ä¹ç¼å· * @return å½ä¸ååçç¼å·ï¼å ¥å为空æ¶åæ ·è¿å */ public static String normalize(String id) { if (StrUtil.isBlank(id) || id.indexOf('%') < 0) { return id; } // å端å¯è½ç¼ç 夿¬¡ï¼1~3 å±é½è§è¿ï¼ï¼éå±è§£ç ç´å°ä¸åå« % è½¬ä¹ String current = id; for (int i = 0; i < MAX_DECODE_TIMES && current.indexOf('%') >= 0; i++) { String decoded; try { decoded = URLDecoder.decode(current, StandardCharsets.UTF_8); } catch (Exception ignored) { // è§£ç 失败说æä¸æ¯ URL 转ä¹ï¼ä¿æåå¼ break; } if (decoded.equals(current)) { break; } current = decoded; } return current; } } yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
@@ -11,12 +11,14 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionInfoMapper; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmProcessDefinitionIdUtils; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.BpmnModel; import org.flowable.common.engine.api.FlowableObjectNotFoundException; import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.engine.RepositoryService; import org.flowable.engine.repository.Deployment; @@ -57,7 +59,18 @@ @Override public ProcessDefinition getProcessDefinition(String id) { return repositoryService.getProcessDefinition(id); String definitionId = BpmProcessDefinitionIdUtils.normalize(id); if (StrUtil.isBlank(definitionId)) { return null; } // ç¼å·ä¸å卿¶ Flowable 伿 FlowableObjectNotFoundExceptionï¼è¿éç»ä¸è½¬æ null ç±è°ç¨æ¹å¤çï¼ // é¿å å端æ¿å° 500ãç³»ç»å¼å¸¸ã try { return repositoryService.getProcessDefinition(definitionId); } catch (FlowableObjectNotFoundException ex) { log.warn("[getProcessDefinition][æµç¨å®ä¹({}) ä¸åå¨]", definitionId); return null; } } @Override @@ -65,7 +78,8 @@ if (CollUtil.isEmpty(ids)) { return emptyList(); } return repositoryService.createProcessDefinitionQuery().processDefinitionIds(ids).list(); return repositoryService.createProcessDefinitionQuery().processDefinitionIds( ids.stream().map(BpmProcessDefinitionIdUtils::normalize).collect(java.util.stream.Collectors.toSet())).list(); } @Override @@ -88,7 +102,7 @@ public ProcessDefinition getActiveProcessDefinition(String key) { return repositoryService.createProcessDefinitionQuery() .processDefinitionTenantId(FlowableUtils.getTenantId()) .processDefinitionKey(key).active().singleResult(); .processDefinitionKey(BpmProcessDefinitionIdUtils.normalize(key)).active().singleResult(); } @Override @@ -203,17 +217,30 @@ @Override public BpmnModel getProcessDefinitionBpmnModel(String id) { return repositoryService.getBpmnModel(id); String definitionId = BpmProcessDefinitionIdUtils.normalize(id); if (StrUtil.isBlank(definitionId)) { return null; } try { return repositoryService.getBpmnModel(definitionId); } catch (FlowableObjectNotFoundException ex) { log.warn("[getProcessDefinitionBpmnModel][æµç¨å®ä¹({}) ä¸åå¨]", definitionId); return null; } } @Override public BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id) { return processDefinitionMapper.selectByProcessDefinitionId(id); return processDefinitionMapper.selectByProcessDefinitionId(BpmProcessDefinitionIdUtils.normalize(id)); } @Override public List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids) { return processDefinitionMapper.selectListByProcessDefinitionIds(ids); if (CollUtil.isEmpty(ids)) { return emptyList(); } return processDefinitionMapper.selectListByProcessDefinitionIds( ids.stream().map(BpmProcessDefinitionIdUtils::normalize).collect(java.util.stream.Collectors.toSet())); } @Override yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -198,9 +198,13 @@ processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, loginUserId); } // 1.3 读åå ¶å®ç¸å ³æ°æ® ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition( historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() : reqVO.getProcessDefinitionId()); String processDefinitionId = historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() : reqVO.getProcessDefinitionId(); ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(processDefinitionId); if (processDefinition == null) { // æµç¨å®ä¹ä¸å卿¶ï¼è¿åæç¡®çä¸å¡é误ï¼é¿å æåº 500ãç³»ç»å¼å¸¸ã throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS); } BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService .getProcessDefinitionInfo(processDefinition.getId()); BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId()); @@ -772,6 +776,9 @@ // è·å¾æµç¨å®ä¹ ProcessDefinition definition = processDefinitionService .getProcessDefinition(createReqVO.getProcessDefinitionId()); if (definition == null) { throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS); } // åèµ·æµç¨ return createProcessInstance0(userId, definition, createReqVO.getVariables(), null, createReqVO.getStartUserSelectAssignees());