From 555bac151d20cd003e7e79e7bdfc03eeac5dc1c6 Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 9 Jan 2024 18:39:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E6=8A=84=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ateVO.java => BpmTaskCandidateRuleVO.java} | 2 +- .../task/vo/task/BpmTaskApproveReqVO.java | 4 + .../cc/BpmProcessInstanceCopyConvert.java | 25 + .../cc/BpmProcessInstanceCopyDO.java | 52 +++ .../cc/BpmProcessInstanceCopyMapper.java | 9 + .../BpmCandidateProcessorConfiguration.java | 2 +- .../candidate/BpmCandidateSourceInfo.java | 17 +- .../BpmCandidateSourceInfoProcessor.java | 17 +- .../BpmCandidateSourceInfoProcessorChain.java | 16 +- ...didateAdminUserApiSourceInfoProcessor.java | 5 +- ...pmCandidateDeptApiSourceInfoProcessor.java | 5 +- ...pmCandidatePostApiSourceInfoProcessor.java | 5 +- ...pmCandidateRoleApiSourceInfoProcessor.java | 5 +- ...CandidateScriptApiSourceInfoProcessor.java | 6 +- ...didateUserGroupApiSourceInfoProcessor.java | 5 +- .../cc/BpmProcessInstanceCopyService.java | 26 ++ .../cc/BpmProcessInstanceCopyServiceImpl.java | 89 ++++ .../service/cc/BpmProcessInstanceCopyVO.java | 51 ++ .../cc/dto/BpmDelegateExecutionDTO.java | 439 ++++++++++++++++++ .../bpm/service/task/BpmTaskServiceImpl.java | 16 + .../yudao/module/bpm/util/FlowableUtils.java | 78 ++++ ...CandidateSourceInfoProcessorChainTest.java | 21 +- .../cc/BpmProcessInstanceCopyServiceTest.java | 17 + 23 files changed, 859 insertions(+), 53 deletions(-) rename yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/{BpmTaskCandidateVO.java => BpmTaskCandidateRuleVO.java} (96%) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java similarity index 96% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java rename to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java index 37e877c54..86ee2d596 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java @@ -14,7 +14,7 @@ import java.util.Set; * @see BpmTaskAssignRuleBaseVO */ @Data -public class BpmTaskCandidateVO { +public class BpmTaskCandidateRuleVO { @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "bpm_task_assign_rule_type") @NotNull(message = "规则类型不能为空") diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java index 14dca13ea..c9b0e9121 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -17,4 +18,7 @@ public class BpmTaskApproveReqVO { @NotEmpty(message = "审批意见不能为空") private String reason; + @Schema(description = "审批时流程抄送人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BpmTaskCandidateRuleVO ccCandidateRule; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java new file mode 100644 index 000000000..3e0a3cd45 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.bpm.convert.cc; + +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 动态表单 Convert + * + * @author 芋艿 + */ +@Mapper +public interface BpmProcessInstanceCopyConvert { + + BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class); + BpmProcessInstanceCopyDO copy(BpmProcessInstanceCopyDO bean); + + BpmProcessInstanceCopyVO convert(BpmProcessInstanceCopyDO bean); + + List convertList2(List list); + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java new file mode 100644 index 000000000..4583bc7a7 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.bpm.dal.dataobject.cc; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 流程抄送对象 + * + * @author kyle + * @date 2022-05-19 + */ +@TableName(value = "bpm_process_instance_copy", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BpmProcessInstanceCopyDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + + /** + * 发起人Id + */ + private Long startUserId; + /** + * 表单名 + */ + private String name; + /** + * 流程主键 + */ + private String processInstanceId; + + /** + * 任务主键 + */ + private String taskId; + /** + * 用户主键 + */ + private Long userId; + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java new file mode 100644 index 000000000..c911aa9c5 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.bpm.dal.mysql.cc; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface BpmProcessInstanceCopyMapper extends BaseMapperX { +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java index b9fde2436..293a935d6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java @@ -41,7 +41,7 @@ public class BpmCandidateProcessorConfiguration { /** * 可以自己定制脚本,然后通过这里设置到处理器里面去 - * @param scriptsOp + * @param scriptsOp 脚本包装对象 * @return */ @Bean diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java index 1280a53e5..5970a012e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.flowable.engine.delegate.DelegateExecution; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; import java.util.HashSet; import java.util.Set; @@ -20,21 +20,20 @@ import java.util.Set; public class BpmCandidateSourceInfo { @Schema(description = "流程id") + @NotNull private String processInstanceId; @Schema(description = "当前任务ID") + @NotNull private String taskId; - /** * 通过这些规则,生成最终需要生成的用户 */ @Schema(description = "当前任务预选规则") - private Set rules; + @NotEmpty(message = "不允许空规则") + private Set rules; - @Schema(description = "源执行流程") - private DelegateExecution execution; - - public void addRule(BpmTaskCandidateVO vo) { + public void addRule(BpmTaskCandidateRuleVO vo) { assert vo != null; if (rules == null) { rules = new HashSet<>(); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java index 52a8adaaf..0fe741c20 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.candidate; import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import org.flowable.engine.delegate.DelegateExecution; import java.util.Collections; import java.util.HashSet; @@ -29,24 +30,24 @@ public interface BpmCandidateSourceInfoProcessor { * 默认的处理 * 如果想去操作所有的规则,则可以覆盖此方法 * - * @param request - * @param chain + * @param request 原始请求 + * @param delegateExecution 审批过程中的对象 * @return 必须包含的是用户ID,而不是其他的ID * @throws Exception */ - default Set process(BpmCandidateSourceInfo request, BpmCandidateSourceInfoProcessorChain chain) throws Exception { - Set rules = request.getRules(); + default Set process(BpmCandidateSourceInfo request, DelegateExecution delegateExecution) throws Exception { + Set rules = request.getRules(); Set results = new HashSet<>(); - for (BpmTaskCandidateVO rule : rules) { + for (BpmTaskCandidateRuleVO rule : rules) { // 每个处理器都有机会处理自己支持的事件 if (CollUtil.contains(getSupportedTypes(), rule.getType())) { - results.addAll(doProcess(request, rule)); + results.addAll(doProcess(request, rule, delegateExecution)); } } return results; } - default Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + default Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return Collections.emptySet(); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java index b33fd7356..d486b96b3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.candidate; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; @@ -11,7 +12,6 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; -import java.util.stream.Collectors; @Service public class BpmCandidateSourceInfoProcessorChain { @@ -31,7 +31,7 @@ public class BpmCandidateSourceInfoProcessorChain { @Resource // 动态扩展处理节点 public BpmCandidateSourceInfoProcessorChain addProcessor(ObjectProvider processorOp) { - List processor = processorOp.orderedStream().collect(Collectors.toList()); + List processor = ListUtil.toList(processorOp.iterator()); if (null == processorList) { processorList = new ArrayList<>(processor.size()); } @@ -40,14 +40,14 @@ public class BpmCandidateSourceInfoProcessorChain { } // 获取处理器处理 - public Set process(BpmCandidateSourceInfo sourceInfo) throws Exception { + public Set process(BpmCandidateSourceInfo sourceInfo, DelegateExecution execution) throws Exception { // Verify our parameters if (sourceInfo == null) { throw new IllegalArgumentException(); } for (BpmCandidateSourceInfoProcessor processor : processorList) { try { - for (BpmTaskCandidateVO vo : sourceInfo.getRules()) { + for (BpmTaskCandidateRuleVO vo : sourceInfo.getRules()) { processor.validRuleOptions(vo.getType(), vo.getOptions()); } } catch (Exception e) { @@ -59,7 +59,7 @@ public class BpmCandidateSourceInfoProcessorChain { Exception saveException = null; for (BpmCandidateSourceInfoProcessor processor : processorList) { try { - saveResult = processor.process(sourceInfo, this); + saveResult = processor.process(sourceInfo, execution); if (CollUtil.isNotEmpty(saveResult)) { removeDisableUsers(saveResult); break; @@ -78,10 +78,9 @@ public class BpmCandidateSourceInfoProcessorChain { } public Set calculateTaskCandidateUsers(DelegateExecution execution, BpmCandidateSourceInfo sourceInfo) { - sourceInfo.setExecution(execution); Set results = Collections.emptySet(); try { - results = process(sourceInfo); + results = process(sourceInfo, execution); } catch (Exception e) { e.printStackTrace(); } @@ -90,6 +89,7 @@ public class BpmCandidateSourceInfoProcessorChain { /** * 移除禁用用户 + * * @param assigneeUserIds */ public void removeDisableUsers(Set assigneeUserIds) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java index 5be8fd291..15c89176a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java @@ -1,11 +1,12 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Set; @@ -25,7 +26,7 @@ public class BpmCandidateAdminUserApiSourceInfoProcessor implements BpmCandidate } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return rule.getOptions(); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java index 73c79b524..71a7fc87e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Collections; @@ -36,7 +37,7 @@ public class BpmCandidateDeptApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { List users = adminUserApi.getUserListByDeptIds(rule.getOptions()); return convertSet(users, AdminUserRespDTO::getId); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java index 15abe86bc..f4a885960 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.dept.PostApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.List; @@ -32,7 +33,7 @@ public class BpmCandidatePostApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { List users = adminUserApi.getUserListByPostIds(rule.getOptions()); return convertSet(users, AdminUserRespDTO::getId); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java index 0e0ef6903..92cda1fd6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java @@ -1,12 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Set; @@ -29,7 +30,7 @@ public class BpmCandidateRoleApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java index b14ca2a1b..acfcc9844 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; @@ -51,8 +51,8 @@ public class BpmCandidateScriptApiSourceInfoProcessor implements BpmCandidateSou } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { - return calculateTaskCandidateUsersByScript(request.getExecution(), rule.getOptions()); + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { + return calculateTaskCandidateUsersByScript(delegateExecution, rule.getOptions()); } private Set calculateTaskCandidateUsersByScript(DelegateExecution execution, Set options) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java index 076d1693d..42929b413 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java @@ -1,12 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.HashSet; @@ -30,7 +31,7 @@ public class BpmCandidateUserGroupApiSourceInfoProcessor implements BpmCandidate } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { List userGroups = userGroupService.getUserGroupList(rule.getOptions()); Set userIds = new HashSet<>(); userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java new file mode 100644 index 000000000..58ee02b8e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; + +/** + * 流程抄送Service接口 + * + * 现在是在审批的时候进行流程抄送 + */ +public interface BpmProcessInstanceCopyService { + + /** + * 查询流程抄送 + * + * @param copyId 流程抄送主键 + * @return 流程抄送 + */ + BpmProcessInstanceCopyVO queryById(Long copyId); + + /** + * 抄送 + * @param sourceInfo 抄送源信息,方便抄送处理 + * @return + */ + boolean makeCopy(BpmCandidateSourceInfo sourceInfo); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java new file mode 100644 index 000000000..b285d6189 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; +import cn.iocoder.yudao.module.bpm.service.cc.dto.BpmDelegateExecutionDTO; +import cn.iocoder.yudao.module.bpm.util.FlowableUtils; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Slf4j +@Service +@Validated +public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService { + @Resource + private BpmProcessInstanceCopyMapper processInstanceCopyMapper; + + /** + * 和flowable有关的,查询流程名用的 + */ + @Resource + private RuntimeService runtimeService; + + /** + * 找抄送人用的 + */ + @Resource + private BpmCandidateSourceInfoProcessorChain processorChain; + + @Override + public BpmProcessInstanceCopyVO queryById(Long copyId) { + BpmProcessInstanceCopyDO bpmProcessInstanceCopyDO = processInstanceCopyMapper.selectById(copyId); + return BpmProcessInstanceCopyConvert.INSTANCE.convert(bpmProcessInstanceCopyDO); + } + + @Override + public boolean makeCopy(BpmCandidateSourceInfo sourceInfo) { + if (null == sourceInfo) { + return false; + } + + DelegateExecution executionEntity = new BpmDelegateExecutionDTO(sourceInfo.getProcessInstanceId()); + Set ccCandidates = processorChain.calculateTaskCandidateUsers(executionEntity, sourceInfo); + if (CollUtil.isEmpty(ccCandidates)) { + log.warn("相关抄送人不存在 {}", sourceInfo.getTaskId()); + return false; + } else { + BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO(); + // 调用 + //设置任务id + copyDO.setTaskId(sourceInfo.getTaskId()); + copyDO.setProcessInstanceId(sourceInfo.getProcessInstanceId()); + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() + .processInstanceId(sourceInfo.getProcessInstanceId()) + .singleResult(); + if (null == processInstance) { + log.warn("相关流程实例不存在 {}", sourceInfo.getTaskId()); + return false; + } + copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance)); + copyDO.setName(FlowableUtils.getFlowName(processInstance.getProcessDefinitionId())); + List copyList = new ArrayList<>(ccCandidates.size()); + for (Long userId : ccCandidates) { + BpmProcessInstanceCopyDO copy = BpmProcessInstanceCopyConvert.INSTANCE.copy(copyDO); + copy.setUserId(userId); + copyList.add(copy); + } + return processInstanceCopyMapper.insertBatch(copyList); + } + } + + public List queryByProcessId() { + return null; + } + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java new file mode 100644 index 000000000..f99d92f89 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + + +/** + * 流程抄送视图对象 wf_copy + * + * @author ruoyi + * @date 2022-05-19 + */ +@Data +public class BpmProcessInstanceCopyVO { + + /** + * 编号 + */ + @Schema(description = "抄送主键") + private Long id; + + /** + * 发起人Id + */ + @Schema(description = "发起人Id") + private Long startUserId; + /** + * 表单名 + */ + @Schema(description = "流程实例的名字") + private String name; + /** + * 流程主键 + */ + @Schema(description = "流程实例的主键") + private String processInstanceId; + + /** + * 任务主键 + */ + @Schema(description = "发起抄送的任务编号") + private String taskId; + /** + * 用户主键 + */ + @Schema(description = "用户编号") + private Long userId; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java new file mode 100644 index 000000000..47213ae52 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java @@ -0,0 +1,439 @@ +package cn.iocoder.yudao.module.bpm.service.cc.dto; + +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowableListener; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ReadOnlyDelegateExecution; +import org.flowable.variable.api.persistence.entity.VariableInstance; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 仅为了传输processInstanceId + */ +public class BpmDelegateExecutionDTO implements DelegateExecution { + + public BpmDelegateExecutionDTO(String getProcessInstanceId) { + this.getProcessInstanceId = getProcessInstanceId; + } + + private final String getProcessInstanceId; + + @Override + public String getId() { + return null; + } + + @Override + public String getProcessInstanceId() { + return null; + } + + @Override + public String getRootProcessInstanceId() { + return null; + } + + @Override + public String getEventName() { + return null; + } + + @Override + public void setEventName(String eventName) { + + } + + @Override + public String getProcessInstanceBusinessKey() { + return null; + } + + @Override + public String getProcessInstanceBusinessStatus() { + return null; + } + + @Override + public String getProcessDefinitionId() { + return null; + } + + @Override + public String getPropagatedStageInstanceId() { + return null; + } + + @Override + public String getParentId() { + return null; + } + + @Override + public String getSuperExecutionId() { + return null; + } + + @Override + public String getCurrentActivityId() { + return null; + } + + @Override + public String getTenantId() { + return null; + } + + @Override + public FlowElement getCurrentFlowElement() { + return null; + } + + @Override + public void setCurrentFlowElement(FlowElement flowElement) { + + } + + @Override + public FlowableListener getCurrentFlowableListener() { + return null; + } + + @Override + public void setCurrentFlowableListener(FlowableListener currentListener) { + + } + + @Override + public ReadOnlyDelegateExecution snapshotReadOnly() { + return null; + } + + @Override + public DelegateExecution getParent() { + return null; + } + + @Override + public List getExecutions() { + return null; + } + + @Override + public void setActive(boolean isActive) { + + } + + @Override + public boolean isActive() { + return false; + } + + @Override + public boolean isEnded() { + return false; + } + + @Override + public void setConcurrent(boolean isConcurrent) { + + } + + @Override + public boolean isConcurrent() { + return false; + } + + @Override + public boolean isProcessInstanceType() { + return false; + } + + @Override + public void inactivate() { + + } + + @Override + public boolean isScope() { + return false; + } + + @Override + public void setScope(boolean isScope) { + + } + + @Override + public boolean isMultiInstanceRoot() { + return false; + } + + @Override + public void setMultiInstanceRoot(boolean isMultiInstanceRoot) { + + } + + @Override + public Map getVariables() { + return null; + } + + @Override + public Map getVariableInstances() { + return null; + } + + @Override + public Map getVariables(Collection collection) { + return null; + } + + @Override + public Map getVariableInstances(Collection collection) { + return null; + } + + @Override + public Map getVariables(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariableInstances(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariablesLocal() { + return null; + } + + @Override + public Map getVariableInstancesLocal() { + return null; + } + + @Override + public Map getVariablesLocal(Collection collection) { + return null; + } + + @Override + public Map getVariableInstancesLocal(Collection collection) { + return null; + } + + @Override + public Map getVariablesLocal(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariableInstancesLocal(Collection collection, boolean b) { + return null; + } + + @Override + public Object getVariable(String s) { + return null; + } + + @Override + public VariableInstance getVariableInstance(String s) { + return null; + } + + @Override + public Object getVariable(String s, boolean b) { + return null; + } + + @Override + public VariableInstance getVariableInstance(String s, boolean b) { + return null; + } + + @Override + public Object getVariableLocal(String s) { + return null; + } + + @Override + public VariableInstance getVariableInstanceLocal(String s) { + return null; + } + + @Override + public Object getVariableLocal(String s, boolean b) { + return null; + } + + @Override + public VariableInstance getVariableInstanceLocal(String s, boolean b) { + return null; + } + + @Override + public T getVariable(String s, Class aClass) { + return null; + } + + @Override + public T getVariableLocal(String s, Class aClass) { + return null; + } + + @Override + public Set getVariableNames() { + return null; + } + + @Override + public Set getVariableNamesLocal() { + return null; + } + + @Override + public void setVariable(String s, Object o) { + + } + + @Override + public void setVariable(String s, Object o, boolean b) { + + } + + @Override + public Object setVariableLocal(String s, Object o) { + return null; + } + + @Override + public Object setVariableLocal(String s, Object o, boolean b) { + return null; + } + + @Override + public void setVariables(Map map) { + + } + + @Override + public void setVariablesLocal(Map map) { + + } + + @Override + public boolean hasVariables() { + return false; + } + + @Override + public boolean hasVariablesLocal() { + return false; + } + + @Override + public boolean hasVariable(String s) { + return false; + } + + @Override + public boolean hasVariableLocal(String s) { + return false; + } + + @Override + public void removeVariable(String s) { + + } + + @Override + public void removeVariableLocal(String s) { + + } + + @Override + public void removeVariables(Collection collection) { + + } + + @Override + public void removeVariablesLocal(Collection collection) { + + } + + @Override + public void removeVariables() { + + } + + @Override + public void removeVariablesLocal() { + + } + + @Override + public void setTransientVariable(String s, Object o) { + + } + + @Override + public void setTransientVariableLocal(String s, Object o) { + + } + + @Override + public void setTransientVariables(Map map) { + + } + + @Override + public Object getTransientVariable(String s) { + return null; + } + + @Override + public Map getTransientVariables() { + return null; + } + + @Override + public void setTransientVariablesLocal(Map map) { + + } + + @Override + public Object getTransientVariableLocal(String s) { + return null; + } + + @Override + public Map getTransientVariablesLocal() { + return null; + } + + @Override + public void removeTransientVariableLocal(String s) { + + } + + @Override + public void removeTransientVariable(String s) { + + } + + @Override + public void removeTransientVariables() { + + } + + @Override + public void removeTransientVariablesLocal() { + + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index a0f938e67..f58679317 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -19,6 +19,8 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskAddSignTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService; import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -94,6 +96,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Resource private ManagementService managementService; + @Resource + private BpmProcessInstanceCopyService processInstanceCopyService; + @Override public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { // 查询待办任务 @@ -237,6 +242,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { .setReason(reqVO.getReason())); // 处理加签任务 handleParentTask(task); + + // 在能正常审批的情况下抄送流程 + if (null != reqVO.getCcCandidateRule()) { + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.setTaskId(reqVO.getId()); + sourceInfo.setProcessInstanceId(instance.getId()); + sourceInfo.addRule(reqVO.getCcCandidateRule()); + if (!processInstanceCopyService.makeCopy(sourceInfo)) { + throw new RuntimeException("抄送任务失败"); + } + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java new file mode 100644 index 000000000..8e8764faa --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.bpm.util; + + +import cn.hutool.extra.spring.SpringUtil; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.ExtensionElement; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.ProcessInstance; + +import java.util.List; +import java.util.Map; + +/** + * 流程引擎工具类封装 + * + * @author: linjinp + * @create: 2019-12-24 13:51 + **/ +public class FlowableUtils { + + /** + * 获取流程名称 + * + * @param processDefinitionId + * @return + */ + public static String getFlowName(String processDefinitionId) { + RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); + ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId); + return processDefinition.getName(); + } + + /** + * 获取节点数据 + * + * @param processInstanceId + * @param nodeId + * @return + */ + public static FlowNode getFlowNode(String processInstanceId, String nodeId) { + + RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); + RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); + + String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); //获取bpm(模型)对象 + BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld); + //传节点定义key获取当前节点 + FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(nodeId); + return flowNode; + } + + public static ExtensionElement generateFlowNodeIdExtension(String nodeId) { + ExtensionElement extensionElement = new ExtensionElement(); + extensionElement.setElementText(nodeId); + extensionElement.setName("nodeId"); + extensionElement.setNamespacePrefix("flowable"); + extensionElement.setNamespace("nodeId"); + return extensionElement; + } + + public static String getNodeIdFromExtension(FlowElement flowElement) { + Map> extensionElements = flowElement.getExtensionElements(); + return extensionElements.get("nodeId").get(0).getElementText(); + } + + public static Long getStartUserIdFromProcessInstance(ProcessInstance instance) { + if (null == instance) { + return null; + } + return NumberUtils.parseLong(instance.getStartUserId()); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java index 1af972d56..5c326fc0f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java @@ -4,8 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; @@ -13,10 +12,7 @@ import cn.iocoder.yudao.module.bpm.framework.bpm.config.BpmCandidateProcessorCon import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX1Script; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX2Script; -import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; -import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.BpmCandidateScriptApiSourceInfoProcessor; -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleServiceImpl; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.PostApi; @@ -28,7 +24,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -72,7 +67,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Role() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.ROLE.getType()); // mock 方法 when(permissionApi.getUserRoleIdListByRoleIds(eq(rule.getOptions()))) @@ -90,7 +85,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_DeptMember() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType()); // mock 方法 List users = CollectionUtils.convertList(asSet(11L, 22L), @@ -109,7 +104,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_DeptLeader() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); // mock 方法 DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L)); @@ -128,7 +123,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Post() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.POST.getType()); // mock 方法 List users = CollectionUtils.convertList(asSet(11L, 22L), @@ -147,7 +142,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_User() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.USER.getType()); // mock 方法 mockGetUserMap(asSet(1L, 2L)); @@ -163,7 +158,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_UserGroup() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); // mock 方法 BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(11L, 12L))); @@ -188,7 +183,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Script() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(20L, 21L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(20L, 21L)) .setType(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); // mock 方法 BpmTaskAssignScript script1 = new BpmTaskAssignScript() { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java new file mode 100644 index 000000000..42a1d46e8 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +@Import({BpmProcessInstanceCopyServiceImpl.class}) +class BpmProcessInstanceCopyServiceTest extends BaseDbUnitTest { + @Resource + private BpmProcessInstanceCopyServiceImpl service; + + @Test + void queryById() { + } +} \ No newline at end of file