diff --git a/ruoyi-api/src/main/java/org/dromara/system/api/UserService.java b/ruoyi-api/src/main/java/org/dromara/system/api/UserService.java index 09824133b..d1b8009ef 100644 --- a/ruoyi-api/src/main/java/org/dromara/system/api/UserService.java +++ b/ruoyi-api/src/main/java/org/dromara/system/api/UserService.java @@ -93,6 +93,14 @@ public interface UserService { */ List selectUsersByDeptIds(Collection deptIds); + /** + * 通过部门ID查询用户ID + * + * @param deptIds 部门ids + * @return 用户ids + */ + List selectUserIdsByDeptIds(Collection deptIds); + /** * 通过岗位ID查询用户 * @@ -101,6 +109,14 @@ public interface UserService { */ List selectUsersByPostIds(Collection postIds); + /** + * 通过岗位ID查询用户ID + * + * @param postIds 岗位ids + * @return 用户ids + */ + List selectUserIdsByPostIds(Collection postIds); + /** * 根据用户 ID 列表查询用户昵称映射关系 * diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 717c181e4..5a6fb4116 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -690,8 +690,12 @@ public class SysUserServiceImpl implements ISysUserService, UserService { if (CollUtil.isEmpty(roleIds)) { return List.of(); } - List userRoles = userRoleMapper.lambda().in(SysUserRole::getRoleId, roleIds).list(); - return StreamUtils.toList(userRoles, SysUserRole::getUserId); + List userRoles = userRoleMapper.lambda() + .select(SysUserRole::getUserId) + .in(SysUserRole::getRoleId, roleIds) + .list(); + Set userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId); + return new ArrayList<>(userIds); } /** @@ -702,17 +706,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public List selectUsersByRoleIds(Collection roleIds) { - if (CollUtil.isEmpty(roleIds)) { - return List.of(); - } - - // 通过角色ID获取用户角色信息 - List userRoles = userRoleMapper.lambda().in(SysUserRole::getRoleId, roleIds).list(); - - // 获取用户ID列表 - Set userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId); - - return this.selectListByIds(new ArrayList<>(userIds)); + List userIds = this.selectUserIdsByRoleIds(roleIds); + return this.selectListByIds(userIds); } /** @@ -726,14 +721,33 @@ public class SysUserServiceImpl implements ISysUserService, UserService { if (CollUtil.isEmpty(deptIds)) { return List.of(); } - List list = userMapper.lambda() + List list = userMapper.lambda() .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhoneNumber) .eq(SysUser::getStatus, SystemConstants.NORMAL) .in(SysUser::getDeptId, deptIds) - .voList(); + .list(); return BeanUtil.copyToList(list, UserDTO.class); } + /** + * 通过部门ID查询用户ID + * + * @param deptIds 部门ids + * @return 用户ids + */ + @Override + public List selectUserIdsByDeptIds(Collection deptIds) { + if (CollUtil.isEmpty(deptIds)) { + return List.of(); + } + List list = userMapper.lambda() + .select(SysUser::getUserId) + .eq(SysUser::getStatus, SystemConstants.NORMAL) + .in(SysUser::getDeptId, deptIds) + .list(); + return StreamUtils.toList(list, SysUser::getUserId); + } + /** * 通过岗位ID查询用户 * @@ -742,17 +756,27 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public List selectUsersByPostIds(Collection postIds) { + List userIds = this.selectUserIdsByPostIds(postIds); + return this.selectListByIds(userIds); + } + + /** + * 通过岗位ID查询用户ID + * + * @param postIds 岗位ids + * @return 用户ids + */ + @Override + public List selectUserIdsByPostIds(Collection postIds) { if (CollUtil.isEmpty(postIds)) { return List.of(); } - - // 通过岗位ID获取用户岗位信息 - List userPosts = userPostMapper.lambda().in(SysUserPost::getPostId, postIds).list(); - - // 获取用户ID列表 + List userPosts = userPostMapper.lambda() + .select(SysUserPost::getUserId) + .in(SysUserPost::getPostId, postIds) + .list(); Set userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId); - - return this.selectListByIds(new ArrayList<>(userIds)); + return new ArrayList<>(userIds); } /** diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java deleted file mode 100644 index f5e41e44a..000000000 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.dromara.workflow.handler; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.utils.StreamUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.system.api.domain.UserDTO; -import org.dromara.warm.flow.core.spi.PermissionHandler; -import org.dromara.workflow.common.ConditionalOnEnable; -import org.dromara.workflow.service.IFlwTaskAssigneeService; -import org.springframework.stereotype.Component; - -import java.util.Collections; -import java.util.List; - -/** - * 办理人权限处理器 - * - * @author AprilWind - */ -@ConditionalOnEnable -@RequiredArgsConstructor -@Component -@Slf4j -public class WorkflowPermissionHandler implements PermissionHandler { - - private final IFlwTaskAssigneeService flwTaskAssigneeService; - - /** - * 办理人权限标识,比如用户,角色,部门等,用于校验是否有权限办理任务 - * 后续在流程上下文中获取。 - * 返回当前用户权限集合 - * - * @return 当前用户权限集合 - */ - @Override - public List permissions() { - return Collections.singletonList(LoginHelper.getUserIdStr()); - } - - /** - * 获取当前办理人 - * - * @return 当前办理人 - */ - @Override - public String getHandler() { - return LoginHelper.getUserIdStr(); - } - - /** - * 将预设办理人转换为实际用户 ID 列表。 - * - * @param permissions 预设权限标识列表 - * @return 用户 ID 列表 - */ - @Override - public List convertPermissions(List permissions) { - if (CollUtil.isEmpty(permissions)) { - return permissions; - } - String storageIds = CollUtil.join(permissions, StringUtils.SEPARATOR); - List users = flwTaskAssigneeService.fetchUsersByStorageIds(storageIds); - return StreamUtils.toList(users, userDTO -> Convert.toStr(userDTO.getUserId())); - } -} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java deleted file mode 100644 index d427b546d..000000000 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dromara.workflow.service; - -import org.dromara.system.api.domain.UserDTO; - -import java.util.List; - -/** - * 流程设计器-获取办理人 - * - * @author AprilWind - */ -public interface IFlwTaskAssigneeService { - - /** - * 批量解析多个存储标识符(storageIds),按类型分类并合并查询用户列表 - * 输入格式支持多个以逗号分隔的标识(如 "user:123,role:456,789") - * 会自动去重返回结果,非法格式的标识将被忽略 - * - * @param storageIds 多个存储标识符字符串(逗号分隔) - * @return 合并后的用户列表,去重后返回,非法格式的标识将被跳过 - */ - List fetchUsersByStorageIds(String storageIds); - -} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java index 8b6d9612d..8fc5aadc9 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java @@ -10,11 +10,12 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.system.api.*; import org.dromara.system.api.domain.DeptDTO; import org.dromara.system.api.domain.TaskAssigneeDTO; -import org.dromara.system.api.domain.UserDTO; import org.dromara.system.api.model.TaskAssigneeBody; +import org.dromara.warm.flow.core.spi.PermissionHandler; import org.dromara.warm.flow.ui.dto.HandlerFunDto; import org.dromara.warm.flow.ui.dto.HandlerQuery; import org.dromara.warm.flow.ui.dto.TreeFunDto; @@ -24,7 +25,6 @@ import org.dromara.warm.flow.ui.vo.HandlerSelectVo; import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.enums.TaskAssigneeEnum; import org.dromara.workflow.service.IFlwSpelService; -import org.dromara.workflow.service.IFlwTaskAssigneeService; import org.springframework.stereotype.Service; import java.util.*; @@ -39,7 +39,7 @@ import java.util.stream.Collectors; @Slf4j @RequiredArgsConstructor @Service -public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, HandlerSelectService { +public class FlwTaskAssigneeServiceImpl implements PermissionHandler, HandlerSelectService { private static final String DEFAULT_GROUP_NAME = "默认分组"; @@ -50,6 +50,69 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand private final PostService postService; private final IFlwSpelService spelService; + /** + * 办理人权限标识,比如用户,角色,部门等,用于校验是否有权限办理任务 + * 后续在流程上下文中获取。 + * 返回当前用户权限集合 + * + * @return 当前用户权限集合 + */ + @Override + public List permissions() { + return Collections.singletonList(LoginHelper.getUserIdStr()); + } + + /** + * 获取当前办理人 + * + * @return 当前办理人 + */ + @Override + public String getHandler() { + return LoginHelper.getUserIdStr(); + } + + /** + * 将预设办理人转换为实际用户 ID 列表。 + * + * @param permissions 预设权限标识列表 + * @return 用户 ID 列表 + */ + @Override + public List convertPermissions(List permissions) { + if (CollUtil.isEmpty(permissions)) { + return permissions; + } + + Map> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class); + for (String storageId : permissions) { + Pair parsed = this.parseStorageId(storageId); + if (parsed != null) { + typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue()); + } + } + + return typeIdMap.entrySet() + .stream() + .map(entry -> { + TaskAssigneeEnum type = entry.getKey(); + List longIds = StreamUtils.toList(entry.getValue(), Convert::toLong); + return switch (type) { + case USER -> longIds; + case ROLE -> userService.selectUserIdsByRoleIds(longIds); + case DEPT -> userService.selectUserIdsByDeptIds(longIds); + case POST -> userService.selectUserIdsByPostIds(longIds); + default -> Collections.emptyList(); + }; + }) + .filter(CollUtil::isNotEmpty) + .flatMap(Collection::stream) + .filter(Objects::nonNull) + .distinct() + .map(Convert::toStr) + .toList(); + } + /** * 获取办理人权限设置列表tabs页签 * @@ -192,45 +255,6 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand .setCreateTime(assignee -> DateUtils.formatLocalDateTime(assignee.getCreateTime())); } - /** - * 批量解析多个存储标识符(storageIds),按类型分类并合并查询用户列表 - * 输入格式支持多个以逗号分隔的标识(如 "user:123,role:456,789") - * 会自动去重返回结果,非法格式的标识将被忽略 - * - * @param storageIds 多个存储标识符字符串(逗号分隔) - * @return 合并后的用户列表,去重后返回,非法格式的标识将被跳过 - */ - @Override - public List fetchUsersByStorageIds(String storageIds) { - if (StringUtils.isEmpty(storageIds)) { - return List.of(); - } - Map> typeIdMap = new EnumMap<>(TaskAssigneeEnum.class); - for (String storageId : StringUtils.str2List(storageIds, StringUtils.SEPARATOR, true, true)) { - Pair parsed = this.parseStorageId(storageId); - if (parsed != null) { - typeIdMap.computeIfAbsent(parsed.getKey(), k -> new ArrayList<>()).add(parsed.getValue()); - } - } - return this.getUsersByTypes(typeIdMap).stream() - .distinct() - .toList(); - } - - /** - * 按任务分配类型批量查询用户。 - * - * @param typeIdMap 任务分配类型与 id 列表映射 - * @return 用户列表 - */ - private List getUsersByTypes(Map> typeIdMap) { - return typeIdMap.entrySet().stream() - .map(entry -> this.getUsersByType(entry.getKey(), entry.getValue())) - .filter(CollUtil::isNotEmpty) - .flatMap(Collection::stream) - .toList(); - } - /** * 按任务分配类型批量查询名称映射。 * @@ -243,30 +267,6 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand return nameMap; } - /** - * 根据指定的任务分配类型(TaskAssigneeEnum)和 ID 列表,获取对应的用户信息列表 - * - * @param type 任务分配类型,表示用户、角色、部门或其他(TaskAssigneeEnum 枚举值) - * @param ids 与指定分配类型关联的 ID 列表(例如用户ID、角色ID、部门ID等) - * @return 返回包含用户信息的列表。如果类型为用户(USER),则通过用户ID列表查询; - * 如果类型为角色(ROLE),则通过角色ID列表查询; - * 如果类型为部门(DEPT),则通过部门ID列表查询; - * 如果类型为岗位(POST)或无法识别的类型,则返回空列表 - */ - private List getUsersByType(TaskAssigneeEnum type, List ids) { - if (type == TaskAssigneeEnum.SPEL) { - return new ArrayList<>(); - } - List longIds = StreamUtils.toList(ids, Convert::toLong); - return switch (type) { - case USER -> userService.selectListByIds(longIds); - case ROLE -> userService.selectUsersByRoleIds(longIds); - case DEPT -> userService.selectUsersByDeptIds(longIds); - case POST -> userService.selectUsersByPostIds(longIds); - default -> new ArrayList<>(); - }; - } - /** * 根据任务分配类型和对应 ID 列表,批量查询名称映射关系 * diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index bbda90ed6..686df0393 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -63,7 +63,6 @@ import org.dromara.workflow.mapper.FlwHisTaskMapper; import org.dromara.workflow.mapper.FlwTaskMapper; import org.dromara.workflow.service.IFlwCommonService; import org.dromara.workflow.service.IFlwNodeExtService; -import org.dromara.workflow.service.IFlwTaskAssigneeService; import org.dromara.workflow.service.IFlwTaskService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -105,7 +104,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService { private final FlwHisTaskMapper flwHisTaskMapper; private final FlwCategoryMapper flwCategoryMapper; private final FlowNodeMapper flowNodeMapper; - private final IFlwTaskAssigneeService flwTaskAssigneeService; private final IFlwCommonService flwCommonService; private final IFlwNodeExtService flwNodeExtService; @@ -567,25 +565,20 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (CollUtil.isEmpty(nextNodeList)) { return new ArrayList<>(); } - List nextFlowNodes = BeanUtil.copyToList(nextNodeList, FlowNode.class); // 只获取中间节点 - nextFlowNodes = StreamUtils.filter(nextFlowNodes, node -> NodeType.BETWEEN.getKey().equals(node.getNodeType())); - if (CollUtil.isNotEmpty(nextNodeList)) { - //构建以下节点数据 - List buildNextTaskList = StreamUtils.toList(nextNodeList, node -> taskService.addTask(node, instance - , definition, new WorkflowContext(), SkipType.PASS.getKey())); - //办理人变量替换 - ExpressionUtil.evalVariable(buildNextTaskList, mergeVariable, null, false); - for (FlowNode flowNode : nextFlowNodes) { - StreamUtils.findFirst(buildNextTaskList, t -> t.getNodeCode().equals(flowNode.getNodeCode())) - .ifPresent(first -> { - List users; - if (CollUtil.isNotEmpty(first.getPermissionList()) - && CollUtil.isNotEmpty(users = flwTaskAssigneeService.fetchUsersByStorageIds(StringUtils.joinComma(first.getPermissionList())))) { - flowNode.setPermissionFlag(StreamUtils.join(users, e -> Convert.toStr(e.getUserId()))); - } - }); - } + nextNodeList = StreamUtils.filter(nextNodeList, node -> NodeType.BETWEEN.getKey().equals(node.getNodeType())); + if (CollUtil.isEmpty(nextNodeList)) { + return new ArrayList<>(); + } + List nextFlowNodes = BeanUtil.copyToList(nextNodeList, FlowNode.class); + //构建以下节点数据 + List buildNextTaskList = StreamUtils.toList(nextNodeList, node -> taskService.addTask(node, instance + , definition, new WorkflowContext(), SkipType.PASS.getKey())); + //办理人变量替换 + ExpressionUtil.evalVariable(buildNextTaskList, mergeVariable, null, false); + Map> map = StreamUtils.toMap(buildNextTaskList, Task::getNodeCode, Task::getPermissionList); + for (FlowNode node : nextFlowNodes) { + node.setPermissionFlag(StringUtils.joinComma(map.get(node.getNodeCode()))); } return nextFlowNodes; }