Commit 36165e72fc8e5ac43a2b52a02f18bfdfd69bcf46

Authored by YunaiV
2 parents bd93257a dc1c8247

Merge branch 'feature/bpm' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17

Showing 13 changed files with 99 additions and 109 deletions
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/ratelimiter/core/redis/RateLimiterRedisDAO.java
@@ -44,6 +44,7 @@ public class RateLimiterRedisDAO { @@ -44,6 +44,7 @@ public class RateLimiterRedisDAO {
44 RateLimiterConfig config = rateLimiter.getConfig(); 44 RateLimiterConfig config = rateLimiter.getConfig();
45 if (config == null) { 45 if (config == null) {
46 rateLimiter.trySetRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS); 46 rateLimiter.trySetRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS);
  47 + rateLimiter.expire(rateInterval, TimeUnit.SECONDS); // 原因参见 https://t.zsxq.com/lcR0W
47 return rateLimiter; 48 return rateLimiter;
48 } 49 }
49 // 2. 如果存在,并且配置相同,则直接返回 50 // 2. 如果存在,并且配置相同,则直接返回
@@ -54,6 +55,7 @@ public class RateLimiterRedisDAO { @@ -54,6 +55,7 @@ public class RateLimiterRedisDAO {
54 } 55 }
55 // 3. 如果存在,并且配置不同,则进行新建 56 // 3. 如果存在,并且配置不同,则进行新建
56 rateLimiter.setRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS); 57 rateLimiter.setRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS);
  58 + rateLimiter.expire(rateInterval, TimeUnit.SECONDS); // 原因参见 https://t.zsxq.com/lcR0W
57 return rateLimiter; 59 return rateLimiter;
58 } 60 }
59 61
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
@@ -82,13 +82,11 @@ public class BpmModelMetaInfoVO { @@ -82,13 +82,11 @@ public class BpmModelMetaInfoVO {
82 @Schema(description = "摘要设置", example = "{}") 82 @Schema(description = "摘要设置", example = "{}")
83 private SummarySetting summarySetting; 83 private SummarySetting summarySetting;
84 84
85 - // TODO @lesan:processBeforeTriggerSetting;要不叫这个?主要考虑,notify 留给后续的站内信、短信、邮件这种 notify 通知哈。  
86 @Schema(description = "流程前置通知设置", example = "{}") 85 @Schema(description = "流程前置通知设置", example = "{}")
87 - private HttpRequestSetting PreProcessNotifySetting; 86 + private HttpRequestSetting processBeforeTriggerSetting;
88 87
89 - // TODO @lesan:processAfterTriggerSetting  
90 @Schema(description = "流程后置通知设置", example = "{}") 88 @Schema(description = "流程后置通知设置", example = "{}")
91 - private HttpRequestSetting PostProcessNotifySetting; 89 + private HttpRequestSetting processAfterTriggerSetting;
92 90
93 @Schema(description = "流程 ID 规则") 91 @Schema(description = "流程 ID 规则")
94 @Data 92 @Data
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
@@ -188,16 +188,15 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -188,16 +188,15 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
188 @TableField(typeHandler = JacksonTypeHandler.class) 188 @TableField(typeHandler = JacksonTypeHandler.class)
189 private BpmModelMetaInfoVO.SummarySetting summarySetting; 189 private BpmModelMetaInfoVO.SummarySetting summarySetting;
190 190
191 - // TODO @lesan:processBeforeTriggerSetting;要不叫这个?主要考虑,notify 留给后续的站内信、短信、邮件这种 notify 通知哈。  
192 /** 191 /**
193 * 流程前置通知设置 192 * 流程前置通知设置
194 */ 193 */
195 - @TableField(typeHandler = JacksonTypeHandler.class, exist = false) // TODO @芋艿:临时注释 exist,因为要合并 master-jdk17  
196 - private BpmModelMetaInfoVO.HttpRequestSetting PreProcessNotifySetting; 194 + @TableField(typeHandler = JacksonTypeHandler.class)
  195 + private BpmModelMetaInfoVO.HttpRequestSetting processBeforeTriggerSetting;
197 /** 196 /**
198 * 流程后置通知设置 197 * 流程后置通知设置
199 */ 198 */
200 - @TableField(typeHandler = JacksonTypeHandler.class, exist = false) // TODO @芋艿:临时注释 exist,因为要合并 master-jdk17  
201 - private BpmModelMetaInfoVO.HttpRequestSetting PostProcessNotifySetting; 199 + @TableField(typeHandler = JacksonTypeHandler.class)
  200 + private BpmModelMetaInfoVO.HttpRequestSetting processAfterTriggerSetting;
202 201
203 } 202 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java
@@ -10,7 +10,10 @@ import org.flowable.common.engine.impl.el.ExpressionManager; @@ -10,7 +10,10 @@ import org.flowable.common.engine.impl.el.ExpressionManager;
10 import org.flowable.engine.delegate.DelegateExecution; 10 import org.flowable.engine.delegate.DelegateExecution;
11 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; 11 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
12 import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; 12 import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
  13 +import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
  14 +import org.flowable.engine.impl.util.CommandContextUtil;
13 import org.flowable.engine.impl.util.TaskHelper; 15 import org.flowable.engine.impl.util.TaskHelper;
  16 +import org.flowable.engine.interceptor.CreateUserTaskBeforeContext;
14 import org.flowable.task.service.TaskService; 17 import org.flowable.task.service.TaskService;
15 import org.flowable.task.service.impl.persistence.entity.TaskEntity; 18 import org.flowable.task.service.impl.persistence.entity.TaskEntity;
16 import org.springframework.transaction.annotation.Transactional; 19 import org.springframework.transaction.annotation.Transactional;
@@ -69,4 +72,15 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { @@ -69,4 +72,15 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
69 return CollUtil.get(candidateUserIds, index); 72 return CollUtil.get(candidateUserIds, index);
70 } 73 }
71 74
  75 + @Override
  76 + protected void handleCategory(CreateUserTaskBeforeContext beforeContext, ExpressionManager expressionManager,
  77 + TaskEntity task, DelegateExecution execution) {
  78 + ProcessDefinitionEntity processDefinitionEntity = CommandContextUtil.getProcessDefinitionEntityManager().findById(execution.getProcessDefinitionId());
  79 + if (processDefinitionEntity == null) {
  80 + log.warn("[handleCategory][任务编号({}) 找不到流程定义({})]", task.getId(), execution.getProcessDefinitionId());
  81 + return;
  82 + }
  83 + task.setCategory(processDefinitionEntity.getCategory());
  84 + }
  85 +
72 } 86 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmHttpRequestUtils.java
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil; @@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.core.KeyValue; 5 import cn.iocoder.yudao.framework.common.core.KeyValue;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  8 +import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
9 import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum; 10 import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;
10 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; 11 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
@@ -40,11 +41,9 @@ public class BpmHttpRequestUtils { @@ -40,11 +41,9 @@ public class BpmHttpRequestUtils {
40 List<BpmSimpleModelNodeVO.HttpRequestParam> headerParams, 41 List<BpmSimpleModelNodeVO.HttpRequestParam> headerParams,
41 List<BpmSimpleModelNodeVO.HttpRequestParam> bodyParams, 42 List<BpmSimpleModelNodeVO.HttpRequestParam> bodyParams,
42 Boolean handleResponse, 43 Boolean handleResponse,
43 - List<KeyValue<String, String>> response,  
44 - // TODO @lesan:RestTemplate 直接通过 springUtil 获取好咧;  
45 - RestTemplate restTemplate,  
46 - // TODO @lesan:processInstanceService 直接通过 springUtil 获取好咧;  
47 - BpmProcessInstanceService processInstanceService) { 44 + List<KeyValue<String, String>> response) {
  45 + RestTemplate restTemplate = SpringUtils.getBean(RestTemplate.class);
  46 + BpmProcessInstanceService processInstanceService = SpringUtils.getBean(BpmProcessInstanceService.class);
48 47
49 // 1.1 设置请求头 48 // 1.1 设置请求头
50 MultiValueMap<String, String> headers = buildHttpHeaders(processInstance, headerParams); 49 MultiValueMap<String, String> headers = buildHttpHeaders(processInstance, headerParams);
@@ -55,27 +54,27 @@ public class BpmHttpRequestUtils { @@ -55,27 +54,27 @@ public class BpmHttpRequestUtils {
55 ResponseEntity<String> responseEntity = sendHttpRequest(url, headers, body, restTemplate); 54 ResponseEntity<String> responseEntity = sendHttpRequest(url, headers, body, restTemplate);
56 55
57 // 3. 处理返回 56 // 3. 处理返回
58 - // TODO @lesan:可以用 if return,让括号小点  
59 - if (Boolean.TRUE.equals(handleResponse)) {  
60 - // 3.1 判断是否需要解析返回值  
61 - if (responseEntity == null  
62 - || StrUtil.isEmpty(responseEntity.getBody())  
63 - || !responseEntity.getStatusCode().is2xxSuccessful()  
64 - || CollUtil.isEmpty(response)) {  
65 - return;  
66 - }  
67 - // 3.2 解析返回值, 返回值必须符合 CommonResult 规范。  
68 - CommonResult<Map<String, Object>> respResult = JsonUtils.parseObjectQuietly(responseEntity.getBody(),  
69 - new TypeReference<>() {});  
70 - if (respResult == null || !respResult.isSuccess()) {  
71 - return;  
72 - }  
73 - // 3.3 获取需要更新的流程变量  
74 - Map<String, Object> updateVariables = getNeedUpdatedVariablesFromResponse(respResult.getData(), response);  
75 - // 3.4 更新流程变量  
76 - if (CollUtil.isNotEmpty(updateVariables)) {  
77 - processInstanceService.updateProcessInstanceVariables(processInstance.getId(), updateVariables);  
78 - } 57 + if (Boolean.FALSE.equals(handleResponse)) {
  58 + return;
  59 + }
  60 + // 3.1 判断是否需要解析返回值
  61 + if (responseEntity == null
  62 + || StrUtil.isEmpty(responseEntity.getBody())
  63 + || !responseEntity.getStatusCode().is2xxSuccessful()
  64 + || CollUtil.isEmpty(response)) {
  65 + return;
  66 + }
  67 + // 3.2 解析返回值, 返回值必须符合 CommonResult 规范。
  68 + CommonResult<Map<String, Object>> respResult = JsonUtils.parseObjectQuietly(responseEntity.getBody(),
  69 + new TypeReference<>() {});
  70 + if (respResult == null || !respResult.isSuccess()) {
  71 + return;
  72 + }
  73 + // 3.3 获取需要更新的流程变量
  74 + Map<String, Object> updateVariables = getNeedUpdatedVariablesFromResponse(respResult.getData(), response);
  75 + // 3.4 更新流程变量
  76 + if (CollUtil.isNotEmpty(updateVariables)) {
  77 + processInstanceService.updateProcessInstanceVariables(processInstance.getId(), updateVariables);
79 } 78 }
80 } 79 }
81 80
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -907,17 +907,9 @@ public class BpmnModelUtils { @@ -907,17 +907,9 @@ public class BpmnModelUtils {
907 * @return 符合条件的路径 907 * @return 符合条件的路径
908 */ 908 */
909 private static SequenceFlow findMatchSequenceFlowByExclusiveGateway(Gateway gateway, Map<String, Object> variables) { 909 private static SequenceFlow findMatchSequenceFlowByExclusiveGateway(Gateway gateway, Map<String, Object> variables) {
910 - // TODO 表单无可编辑字段时variables为空,流程走向会出现问题,比如流程审批过程中无需要修改的字段值,  
911 - // TODO @小北:是不是还是保证,编辑的时候,如果计算下一个节点,还是 variables 是完整体?而不是空的!!!(可以微信讨论下)  
912 - SequenceFlow matchSequenceFlow;  
913 - if (CollUtil.isNotEmpty(variables)) {  
914 - matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(), 910 + SequenceFlow matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
915 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId()) 911 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId())
916 && (evalConditionExpress(variables, flow.getConditionExpression()))); 912 && (evalConditionExpress(variables, flow.getConditionExpression())));
917 - } else {  
918 - matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),  
919 - flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId()));  
920 - }  
921 if (matchSequenceFlow == null) { 913 if (matchSequenceFlow == null) {
922 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(), 914 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
923 flow -> ObjUtil.equal(gateway.getDefaultFlow(), flow.getId())); 915 flow -> ObjUtil.equal(gateway.getDefaultFlow(), flow.getId()));
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -248,16 +248,14 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -248,16 +248,14 @@ public class BpmModelServiceImpl implements BpmModelService {
248 throw exception(MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS, userTask.getId()); 248 throw exception(MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS, userTask.getId());
249 } 249 }
250 }); 250 });
251 - // TODO @小北:是不是可以 UserTask firUserTask = CollUtil.get(userTasks, BpmModelTypeEnum.BPMN.getType().equals(type) ? 0 : 1);然后,最好判空。。。极端情况下,没 usertask ,哈哈哈哈。  
252 - // 3. 校验第一个用户任务节点的规则类型是否为“审批人自选”  
253 - Map<Integer, UserTask> userTaskMap = new HashMap<>();  
254 - // BPMN 设计器,校验第一个用户任务节点  
255 - userTaskMap.put(BpmModelTypeEnum.BPMN.getType(), userTasks.get(0));  
256 - // SIMPLE 设计器,第一个节点固定为发起人所以校验第二个用户任务节点  
257 - userTaskMap.put(BpmModelTypeEnum.SIMPLE.getType(), userTasks.get(1));  
258 - Integer candidateStrategy = parseCandidateStrategy(userTaskMap.get(type)); 251 + // 3. 校验第一个用户任务节点的规则类型是否为“审批人自选”,BPMN 设计器,校验第一个用户任务节点,SIMPLE 设计器,第一个节点固定为发起人所以校验第二个用户任务节点
  252 + UserTask firUserTask = CollUtil.get(userTasks, BpmModelTypeEnum.BPMN.getType().equals(type) ? 0 : 1);
  253 + if (firUserTask == null) {
  254 + return;
  255 + }
  256 + Integer candidateStrategy = parseCandidateStrategy(firUserTask);
259 if (Objects.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) { 257 if (Objects.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) {
260 - throw exception(MODEL_DEPLOY_FAIL_FIRST_USER_TASK_CANDIDATE_STRATEGY_ERROR, userTaskMap.get(type).getName()); 258 + throw exception(MODEL_DEPLOY_FAIL_FIRST_USER_TASK_CANDIDATE_STRATEGY_ERROR, firUserTask.getName());
261 } 259 }
262 } 260 }
263 261
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -122,9 +122,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -122,9 +122,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
122 @Resource 122 @Resource
123 private BpmProcessIdRedisDAO processIdRedisDAO; 123 private BpmProcessIdRedisDAO processIdRedisDAO;
124 124
125 - @Resource  
126 - private RestTemplate restTemplate;  
127 -  
128 // ========== Query 查询相关方法 ========== 125 // ========== Query 查询相关方法 ==========
129 126
130 @Override 127 @Override
@@ -914,16 +911,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -914,16 +911,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
914 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService. 911 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
915 getProcessDefinitionInfo(instance.getProcessDefinitionId()); 912 getProcessDefinitionInfo(instance.getProcessDefinitionId());
916 if (ObjUtil.isNotNull(processDefinitionInfo) && 913 if (ObjUtil.isNotNull(processDefinitionInfo) &&
917 - ObjUtil.isNotNull(processDefinitionInfo.getPostProcessNotifySetting())) {  
918 - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getPostProcessNotifySetting(); 914 + ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
  915 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
919 916
920 BpmHttpRequestUtils.executeBpmHttpRequest(instance, 917 BpmHttpRequestUtils.executeBpmHttpRequest(instance,
921 setting.getUrl(), 918 setting.getUrl(),
922 setting.getHeader(), 919 setting.getHeader(),
923 setting.getBody(), 920 setting.getBody(),
924 - true, setting.getResponse(),  
925 - restTemplate,  
926 - this); 921 + true, setting.getResponse());
927 } 922 }
928 } 923 }
929 }); 924 });
@@ -936,18 +931,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -936,18 +931,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
936 // 流程前置通知 931 // 流程前置通知
937 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService. 932 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
938 getProcessDefinitionInfo(instance.getProcessDefinitionId()); 933 getProcessDefinitionInfo(instance.getProcessDefinitionId());
939 - // TODO @lesan:if return 哈。减少括号。  
940 - if (ObjUtil.isNotNull(processDefinitionInfo) &&  
941 - ObjUtil.isNotNull(processDefinitionInfo.getPreProcessNotifySetting())) {  
942 - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getPreProcessNotifySetting();  
943 - BpmHttpRequestUtils.executeBpmHttpRequest(instance,  
944 - setting.getUrl(),  
945 - setting.getHeader(),  
946 - setting.getBody(),  
947 - true, setting.getResponse(),  
948 - restTemplate,  
949 - this); 934 + if (ObjUtil.isNull(processDefinitionInfo) ||
  935 + ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
  936 + return;
950 } 937 }
  938 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
  939 + BpmHttpRequestUtils.executeBpmHttpRequest(instance,
  940 + setting.getUrl(),
  941 + setting.getHeader(),
  942 + setting.getBody(),
  943 + true, setting.getResponse());
951 }); 944 });
952 } 945 }
953 946
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils; @@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
11 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 11 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
12 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 12 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  13 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
13 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; 14 import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
14 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; 15 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
15 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert; 16 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
@@ -557,18 +558,31 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -557,18 +558,31 @@ public class BpmTaskServiceImpl implements BpmTaskService {
557 // 2.2 添加评论 558 // 2.2 添加评论
558 taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(), 559 taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
559 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason())); 560 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
560 - // 2.3 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑  
561 - Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), reqVO.getVariables(), 561 +
  562 + // 3. 设置流程变量。如果流程变量前端传空,需要从历史实例中获取,原因:前端表单如果在当前节点无可编辑的字段时 variables 一定会为空
  563 + // 场景一:A 节点发起,B 节点表单无可编辑字段,审批通过时,C 节点需要流程变量获取下一个执行节点,但因为 B 节点无可编辑的字段,variables 为空,流程可能出现问题。
  564 + // 场景二:A 节点发起,B 节点只有某一个字段可编辑(比如 day),但 C 节点需要多个节点。
  565 + // (比如 work + day 变量,在发起时填写,因为 B 节点只有 day 的编辑权限,在审批后,variables 会缺少 work 的值)
  566 + Map<String, Object> processVariables = new HashMap<>();
  567 + if (CollUtil.isNotEmpty(instance.getProcessVariables())) { // 获取历史中流程变量
  568 + processVariables.putAll(instance.getProcessVariables());
  569 + }
  570 + if (CollUtil.isNotEmpty(reqVO.getVariables())) { // 合并前端传递的流程变量,以前端为准
  571 + processVariables.putAll(reqVO.getVariables());
  572 + }
  573 +
  574 + // 4. 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑
  575 + Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), processVariables,
562 bpmnModel, reqVO.getNextAssignees(), instance); 576 bpmnModel, reqVO.getNextAssignees(), instance);
563 runtimeService.setVariables(task.getProcessInstanceId(), variables); 577 runtimeService.setVariables(task.getProcessInstanceId(), variables);
564 - // 2.4 调用 BPM complete 去完成任务 578 +
  579 + // 5. 调用 BPM complete 去完成任务
565 taskService.complete(task.getId(), variables, true); 580 taskService.complete(task.getId(), variables, true);
566 581
567 // 【加签专属】处理加签任务 582 // 【加签专属】处理加签任务
568 handleParentTaskIfSign(task.getParentTaskId()); 583 handleParentTaskIfSign(task.getParentTaskId());
569 } 584 }
570 585
571 -  
572 /** 586 /**
573 * 校验选择的下一个节点的审批人,是否合法 587 * 校验选择的下一个节点的审批人,是否合法
574 * 588 *
@@ -600,9 +614,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -600,9 +614,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
600 } 614 }
601 processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables()); 615 processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables());
602 // 特殊:如果当前节点已经存在审批人,则不允许覆盖 616 // 特殊:如果当前节点已经存在审批人,则不允许覆盖
603 - // TODO @小北:【不用改】通过 if return,让逻辑更简洁一点;虽然会多判断一次 processVariables,但是 if else 层级更少。  
604 - if (processVariables != null  
605 - && CollUtil.isNotEmpty(processVariables.get(nextFlowNode.getId()))) { 617 + if (processVariables != null && CollUtil.isNotEmpty(processVariables.get(nextFlowNode.getId()))) {
606 continue; 618 continue;
607 } 619 }
608 // 设置 PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES 620 // 设置 PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES
@@ -622,13 +634,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -622,13 +634,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
622 processVariables = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables()); 634 processVariables = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables());
623 if (processVariables == null) { 635 if (processVariables == null) {
624 processVariables = new HashMap<>(); 636 processVariables = new HashMap<>();
625 - } else {  
626 - List<Long> approveUserSelectAssignee = processVariables.get(nextFlowNode.getId());  
627 - // 特殊:如果当前节点已经存在审批人,则不允许覆盖  
628 - // TODO @小北:这种,应该可以覆盖呢。  
629 - if (CollUtil.isNotEmpty(approveUserSelectAssignee)) {  
630 - continue;  
631 - }  
632 } 637 }
633 // 设置 PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES 638 // 设置 PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES
634 processVariables.put(nextFlowNode.getId(), assignees); 639 processVariables.put(nextFlowNode.getId(), assignees);
@@ -1251,6 +1256,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -1251,6 +1256,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
1251 } 1256 }
1252 1257
1253 @Override 1258 @Override
  1259 + @DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人
1254 public void processTaskAssigned(Task task) { 1260 public void processTaskAssigned(Task task) {
1255 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 1261 // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
1256 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 1262 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java
@@ -33,9 +33,6 @@ public class BpmUserTaskListener implements TaskListener { @@ -33,9 +33,6 @@ public class BpmUserTaskListener implements TaskListener {
33 @Resource 33 @Resource
34 private BpmProcessInstanceService processInstanceService; 34 private BpmProcessInstanceService processInstanceService;
35 35
36 - @Resource  
37 - private RestTemplate restTemplate;  
38 -  
39 @Setter 36 @Setter
40 private FixedValue listenerConfig; 37 private FixedValue listenerConfig;
41 38
@@ -59,9 +56,7 @@ public class BpmUserTaskListener implements TaskListener { @@ -59,9 +56,7 @@ public class BpmUserTaskListener implements TaskListener {
59 listenerHandler.getPath(), 56 listenerHandler.getPath(),
60 listenerHandler.getHeader(), 57 listenerHandler.getHeader(),
61 listenerHandler.getBody(), 58 listenerHandler.getBody(),
62 - false, null,  
63 - restTemplate,  
64 - processInstanceService); 59 + false, null);
65 60
66 // 3. 是否需要后续操作?TODO 芋艿:待定! 61 // 3. 是否需要后续操作?TODO 芋艿:待定!
67 } 62 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmHttpCallbackTrigger.java
@@ -22,9 +22,6 @@ import org.springframework.web.client.RestTemplate; @@ -22,9 +22,6 @@ import org.springframework.web.client.RestTemplate;
22 public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger { 22 public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger {
23 23
24 @Resource 24 @Resource
25 - private RestTemplate restTemplate;  
26 -  
27 - @Resource  
28 private BpmProcessInstanceService processInstanceService; 25 private BpmProcessInstanceService processInstanceService;
29 26
30 @Override 27 @Override
@@ -51,9 +48,7 @@ public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger { @@ -51,9 +48,7 @@ public class BpmHttpCallbackTrigger extends BpmAbstractHttpRequestTrigger {
51 setting.getUrl(), 48 setting.getUrl(),
52 setting.getHeader(), 49 setting.getHeader(),
53 setting.getBody(), 50 setting.getBody(),
54 - false, null,  
55 - restTemplate,  
56 - processInstanceService); 51 + false, null);
57 } 52 }
58 53
59 } 54 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/http/BpmSyncHttpRequestTrigger.java
@@ -21,9 +21,6 @@ import org.springframework.web.client.RestTemplate; @@ -21,9 +21,6 @@ import org.springframework.web.client.RestTemplate;
21 public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger { 21 public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {
22 22
23 @Resource 23 @Resource
24 - private RestTemplate restTemplate;  
25 -  
26 - @Resource  
27 private BpmProcessInstanceService processInstanceService; 24 private BpmProcessInstanceService processInstanceService;
28 25
29 @Override 26 @Override
@@ -46,9 +43,7 @@ public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger { @@ -46,9 +43,7 @@ public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {
46 setting.getUrl(), 43 setting.getUrl(),
47 setting.getHeader(), 44 setting.getHeader(),
48 setting.getBody(), 45 setting.getBody(),
49 - true, setting.getResponse(),  
50 - restTemplate,  
51 - processInstanceService); 46 + true, setting.getResponse());
52 } 47 }
53 48
54 } 49 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.api.user; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.api.user;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; 6 +import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
7 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 7 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
8 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; 8 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
9 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 9 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@@ -12,7 +12,10 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; @@ -12,7 +12,10 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService;
12 import jakarta.annotation.Resource; 12 import jakarta.annotation.Resource;
13 import org.springframework.stereotype.Service; 13 import org.springframework.stereotype.Service;
14 14
15 -import java.util.*; 15 +import java.util.Collection;
  16 +import java.util.Collections;
  17 +import java.util.List;
  18 +import java.util.Set;
16 19
17 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 20 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
18 21
@@ -56,10 +59,11 @@ public class AdminUserApiImpl implements AdminUserApi { @@ -56,10 +59,11 @@ public class AdminUserApiImpl implements AdminUserApi {
56 } 59 }
57 60
58 @Override 61 @Override
59 - @DataPermission(enable = false) // 禁用数据权限。原因是,一般基于指定 id 的 API 查询,都是数据拼接为主  
60 public List<AdminUserRespDTO> getUserList(Collection<Long> ids) { 62 public List<AdminUserRespDTO> getUserList(Collection<Long> ids) {
61 - List<AdminUserDO> users = userService.getUserList(ids);  
62 - return BeanUtils.toBean(users, AdminUserRespDTO.class); 63 + return DataPermissionUtils.executeIgnore(() -> { // 禁用数据权限。原因是,一般基于指定 id 的 API 查询,都是数据拼接为主
  64 + List<AdminUserDO> users = userService.getUserList(ids);
  65 + return BeanUtils.toBean(users, AdminUserRespDTO.class);
  66 + });
63 } 67 }
64 68
65 @Override 69 @Override