diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/ProcessConstants.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/ProcessConstants.java new file mode 100644 index 0000000000..f3dd4077ff --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/ProcessConstants.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.framework.flowable.core.enums; + +/** + * 流程常量信息 + */ +public interface ProcessConstants { + + String BPMN_FILE_SUFFIX = ".bpmn"; + + /** + * nameapace + * bpmn中的命名空间 + * 这个东西有可能导致无法切换工作流程的实现 + */ + String NAMESPASE = "http://flowable.org/bpmn"; + + /** + * 自定义属性 dataType + */ + String PROCESS_CUSTOM_DATA_TYPE = "dataType"; + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java new file mode 100644 index 0000000000..15b1c6660e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.flowable.core.enums.ProcessConstants; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +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.AllArgsConstructor; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.UserTask; +import org.flowable.engine.delegate.DelegateExecution; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; + +/** + * 多实例处理类 + */ +@AllArgsConstructor +@Component("multiInstanceHandler") +public class MultiInstanceHandler { + + @Resource + private AdminUserApi userApi; + + @Resource + private PermissionApi permissionApi; + + public Set getUserIds(DelegateExecution execution) { + Set candidateUserIds = new LinkedHashSet<>(); + FlowElement flowElement = execution.getCurrentFlowElement(); + if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) { + String dataType = userTask.getAttributeValue(ProcessConstants.NAMESPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); + if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) { + // 添加候选用户id + candidateUserIds.addAll(userTask.getCandidateUsers()); + } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) { + // 获取组的ID,角色ID集合或部门ID集合 + List groups = userTask.getCandidateGroups().stream() + // 例如部门DEPT100,100才是部门id + .map(item -> Long.parseLong(item.substring(4))) + .collect(Collectors.toList()); + List userIds = new ArrayList<>(); + if ("ROLES".equals(dataType)) { + // 通过角色id,获取所有用户id集合 + Set userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups); + userIds = new ArrayList<>(userRoleIdListByRoleIds); + } else if ("DEPTS".equals(dataType)) { + // 通过部门id,获取所有用户id集合 + List userListByDeptIds = userApi.getUserListByDeptIds(groups); + userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId); + } + // 添加候选用户id + userIds.forEach(id -> candidateUserIds.add(String.valueOf(id))); + } + } + return candidateUserIds; + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java index 28487b5629..1be0432a09 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java @@ -5,8 +5,8 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.framework.flowable.core.enums.ProcessConstants; import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; @@ -17,6 +17,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.converter.BpmnXMLConverter; import org.flowable.bpmn.model.BpmnModel; @@ -29,13 +31,10 @@ import org.flowable.engine.repository.ProcessDefinitionQuery; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; import static java.util.Collections.emptyList; @@ -53,8 +52,6 @@ import static java.util.Collections.emptyList; @Slf4j public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService { - private static final String BPMN_FILE_SUFFIX = ".bpmn"; - @Resource private RepositoryService repositoryService; @@ -125,7 +122,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ // 创建 Deployment 部署 Deployment deploy = repositoryService.createDeployment() .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) - .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) + .addBytes(createReqDTO.getKey() + ProcessConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) .tenantId(TenantContextHolder.getTenantIdStr()) .deploy();