From 22cd701d94db3f071cb7da913e079e79e2a3cf64 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 7 Nov 2024 10:02:15 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9E=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=8A=9E=E7=90=86=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/domain/dto/TaskAssigneeDTO.java | 102 ++++++++++++++ .../core/domain/model/TaskAssigneeBody.java | 56 ++++++++ .../common/core/service/UserService.java | 10 ++ .../service/impl/SysUserServiceImpl.java | 33 +++++ .../common/enums/TaskAssigneeEnum.java | 109 +++++++++++++++ .../impl/WfTaskAssigneeServiceImpl.java | 125 ++++++++++++++++++ .../dromara/workflow/utils/WorkflowUtils.java | 18 +-- 7 files changed, 444 insertions(+), 9 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java new file mode 100644 index 000000000..4465c0457 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java @@ -0,0 +1,102 @@ +package org.dromara.common.core.domain.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 任务受让人 + * + * @author AprilWind + */ +@Data +@NoArgsConstructor +public class TaskAssigneeDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 总大小 + */ + private Long total = 0L; + + /** + * + */ + private List list; + + public TaskAssigneeDTO(Long total, List list) { + this.total = total; + this.list = list; + } + + /** + * 将源列表转换为 TaskHandler 列表 + * + * @param 通用类型 + * @param sourceList 待转换的源列表 + * @param storageId 提取 storageId 的函数 + * @param handlerCode 提取 handlerCode 的函数 + * @param handlerName 提取 handlerName 的函数 + * @param groupName 提取 groupName 的函数 + * @param createTimeMapper 提取 createTime 的函数 + * @return 转换后的 TaskHandler 列表 + */ + public static List convertToHandlerList( + List sourceList, + Function storageId, + Function handlerCode, + Function handlerName, + Function groupName, + Function createTimeMapper) { + return sourceList.stream() + .map(item -> new TaskHandler( + String.valueOf(storageId.apply(item)), + handlerCode != null ? handlerCode.apply(item) : "无", + handlerName != null ? handlerName.apply(item) : "无", + groupName != null ? groupName.apply(item) : "默认分组", + createTimeMapper != null ? createTimeMapper.apply(item) : null + )) + .collect(Collectors.toList()); + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class TaskHandler { + + /** + * 主键 + */ + private String storageId; + + /** + * 权限编码 + */ + private String handlerCode = "无"; + + /** + * 权限名称 + */ + private String handlerName = "无"; + + /** + * 权限分组 + */ + private String groupName = "默认分组"; + + /** + * 创建时间 + */ + private Date createTime; + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java new file mode 100644 index 000000000..0cbed2f18 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java @@ -0,0 +1,56 @@ +package org.dromara.common.core.domain.model; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 任务受让人 + * + * @author AprilWind + */ +@Data +@NoArgsConstructor +public class TaskAssigneeBody implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 权限编码 + */ + private String handlerCode; + + /** + * 权限名称 + */ + private String handlerName; + + /** + * 权限分组 + */ + private String groupId; + + /** + * 开始时间 + */ + private String beginTime; + + /** + * 结束时间 + */ + private String endTime; + + /** + * 当前页 + */ + private Integer pageNum = 1; + + /** + * 每页显示条数 + */ + private Integer pageSize = 10; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java index 43aef28cb..92fb967e7 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java @@ -1,6 +1,8 @@ package org.dromara.common.core.service; +import org.dromara.common.core.domain.dto.TaskAssigneeDTO; import org.dromara.common.core.domain.dto.UserDTO; +import org.dromara.common.core.domain.model.TaskAssigneeBody; import java.util.List; @@ -82,4 +84,12 @@ public interface UserService { * @return 用户 */ List selectUsersByDeptIds(List deptIds); + + /** + * 查询角色信息 + * + * @return 角色信息列表 + */ + TaskAssigneeDTO selectUsersByRoleList(TaskAssigneeBody taskQuery); + } 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 8c6d1d5f5..aefb0b532 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 @@ -15,7 +15,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.UserConstants; +import org.dromara.common.core.domain.dto.TaskAssigneeDTO; import org.dromara.common.core.domain.dto.UserDTO; +import org.dromara.common.core.domain.model.TaskAssigneeBody; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.UserService; import org.dromara.common.core.utils.MapstructUtils; @@ -702,4 +704,35 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .in(SysUser::getDeptId, deptIds)); return BeanUtil.copyToList(list, UserDTO.class); } + + /** + * 根据角色列表查询用户信息。 + * + * @param taskQuery 包含查询条件的请求体对象,包含分页参数、权限编码、权限名称、时间范围等信息。 + * @return 返回包含查询结果的 `TaskAssigneeDTO` 对象,其中包含符合条件的总记录数和处理人列表。 + */ + @Override + public TaskAssigneeDTO selectUsersByRoleList(TaskAssigneeBody taskQuery) { + // 创建分页查询对象,并设置分页大小和页码 + PageQuery pageQuery = new PageQuery(); + pageQuery.setPageSize(taskQuery.getPageSize()); + pageQuery.setPageNum(taskQuery.getPageNum()); + + // 使用 LambdaQueryWrapper 构建查询条件 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysRole::getRoleKey, taskQuery.getHandlerCode()) + .like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysRole::getRoleName, taskQuery.getHandlerName()) + .between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()), + SysRole::getCreateTime, taskQuery.getBeginTime(), taskQuery.getEndTime()); + + // 执行分页查询,并将查询结果封装为 SysRoleVo 对象的 Page + Page page = roleMapper.selectVoPage(pageQuery.build(), wrapper); + + // 使用封装的字段映射方法进行转换 + List handlers = TaskAssigneeDTO.convertToHandlerList(page.getRecords(), + SysRoleVo::getRoleId, SysRoleVo::getRoleKey, SysRoleVo::getRoleName, null, SysRoleVo::getCreateTime); + + return new TaskAssigneeDTO(page.getTotal(), handlers); + } + } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java new file mode 100644 index 000000000..42971c624 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java @@ -0,0 +1,109 @@ +package org.dromara.workflow.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.dromara.common.core.exception.ServiceException; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 任务分配人枚举 + * + * @author AprilWind + */ +@Getter +@AllArgsConstructor +public enum TaskAssigneeEnum { + + /** + * 用户 + */ + USER("用户", "user:"), + + /** + * 角色 + */ + ROLE("角色", "role:"), + + /** + * 部门 + */ + DEPT("部门", "dept:"), + + /** + * 岗位 + */ + POST("岗位", "post:"); + + private final String desc; + private final String code; + + /** + * 根据描述获取对应的枚举类型 + *

+ * 通过传入描述,查找并返回匹配的枚举项。如果未找到匹配项,会抛出 {@link ServiceException}。 + *

+ * + * @param desc 描述,用于匹配对应的枚举项 + * @return TaskAssigneeEnum 返回对应的枚举类型 + * @throws ServiceException 如果未找到匹配的枚举项 + */ + public static TaskAssigneeEnum fromDesc(String desc) { + for (TaskAssigneeEnum type : values()) { + if (type.getDesc().equals(desc)) { + return type; + } + } + throw new ServiceException("未知的办理人类型: " + desc); + } + + /** + * 根据代码获取对应的枚举类型 + *

+ * 通过传入代码,查找并返回匹配的枚举项。如果未找到匹配项,会抛出 {@link ServiceException}。 + *

+ * + * @param code 代码,用于匹配对应的枚举项 + * @return TaskAssigneeEnum 返回对应的枚举类型 + * @throws IllegalArgumentException 如果未找到匹配的枚举项 + */ + public static TaskAssigneeEnum fromCode(String code) { + for (TaskAssigneeEnum type : values()) { + if (type.getCode().equals(code)) { + return type; + } + } + throw new ServiceException("未知的办理人类型代码: " + code); + } + + /** + * 获取所有办理人类型的描述列表 + *

+ * 获取当前枚举类所有项的描述字段列表,通常用于展示选择项。 + *

+ * + * @return List 返回所有办理人类型的描述列表 + */ + public static List getAssigneeTypeList() { + return Arrays.stream(values()) + .map(TaskAssigneeEnum::getDesc) + .collect(Collectors.toList()); + } + + /** + * 获取所有办理人类型的代码列表 + *

+ * 获取当前枚举类所有项的代码字段列表,通常用于程序内部逻辑的判断。 + *

+ * + * @return List 返回所有办理人类型的代码列表 + */ + public static List getAssigneeCodeList() { + return Arrays.stream(values()) + .map(TaskAssigneeEnum::getCode) + .collect(Collectors.toList()); + } +} + diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java new file mode 100644 index 000000000..9e607d902 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java @@ -0,0 +1,125 @@ +package org.dromara.workflow.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.warm.flow.ui.dto.HandlerFunDto; +import com.warm.flow.ui.dto.HandlerQuery; +import com.warm.flow.ui.service.HandlerSelectService; +import com.warm.flow.ui.vo.HandlerSelectVo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.dto.TaskAssigneeDTO; +import org.dromara.common.core.domain.model.TaskAssigneeBody; +import org.dromara.common.core.service.UserService; +import org.dromara.common.core.utils.DateUtils; +import org.dromara.workflow.common.enums.TaskAssigneeEnum; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static org.dromara.workflow.common.enums.TaskAssigneeEnum.ROLE; + +/** + * 流程设计器-获取办理人权限设置列表 + * + * @author AprilWind + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class WfTaskAssigneeServiceImpl implements HandlerSelectService { + private final UserService userService; + + /** + * 获取办理人权限设置列表tabs页签 + * + * @return tabs页签 + */ + @Override + public List getHandlerType() { + return TaskAssigneeEnum.getAssigneeTypeList(); + } + + /** + * 获取用户列表, 同时构建左侧部门树状结构 + * + * @param query 查询条件 + * @return HandlerSelectVo + */ + @Override + public HandlerSelectVo getHandlerSelect(HandlerQuery query) { + TaskAssigneeEnum type = TaskAssigneeEnum.fromDesc(query.getHandlerType()); + TaskAssigneeBody taskQuery = BeanUtil.toBean(query, TaskAssigneeBody.class); + TaskAssigneeDTO dto = new TaskAssigneeDTO(); + if (TaskAssigneeEnum.USER == type) { + // 处理用户相关的业务逻辑 + } else if (ROLE == type) { + // 处理角色相关的业务逻辑 + dto = userService.selectUsersByRoleList(taskQuery); + } else if (TaskAssigneeEnum.DEPT == type) { + // 处理部门相关的业务逻辑 + } else if (TaskAssigneeEnum.POST == type) { + // 处理岗位相关的业务逻辑 + } + // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 + HandlerFunDto handlerFunDto = new HandlerFunDto<>(dto.getList(), dto.getTotal()) + .setStorageId(assignee -> ROLE.getCode() + assignee.getStorageId()) + .setHandlerCode(TaskAssigneeDTO.TaskHandler::getHandlerCode) + .setHandlerName(TaskAssigneeDTO.TaskHandler::getHandlerName) + .setGroupName(TaskAssigneeDTO.TaskHandler::getGroupName) + .setCreateTime(assignee -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime())); + return getHandlerSelectVo(handlerFunDto); + } + +// /** +// * 获取用户列表 +// * +// * @param query 查询条件 +// * @return HandlerSelectVo +// */ +// private HandlerSelectVo getDept(HandlerQuery query) { +// // 查询部门列表 +// List deptList = userService.selectDeptList(sysDept); +// long total = new PageInfo<>(deptList).getTotal(); +// +// // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 +// HandlerFunDto handlerFunDto = new HandlerFunDto<>(deptList, total) +// .setStorageId(dept -> "dept:" + dept.getDeptId()) // 前面拼接dept: 是为了防止用户、部门的主键重复 +// .setHandlerName(SysDept::getDeptName) // 权限名称 +// .setCreateTime(dept -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, dept.getCreateTime())); +// +// return getHandlerSelectVo(handlerFunDto); +// +// } +// +// /** +// * 获取用户列表, 同时构建左侧部门树状结构 +// * +// * @param query 查询条件 +// * @return HandlerSelectVo +// */ +// private HandlerSelectVo getUser(HandlerQuery query) { +// ...... +// // 查询用户列表 +// List userList = userService.selectUserList(sysUser); +// long total = new PageInfo<>(userList).getTotal(); +// // 查询部门列表,构建树状结构 +// List deptList = deptMapper.selectDeptList(new SysDept()); +// +// // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 +// HandlerFunDto handlerFunDto = new HandlerFunDto<>(userList, total) +// .setStorageId(user -> user.getUserId().toString()) +// .setHandlerCode(SysUser::getUserName) // 权限编码 +// .setHandlerName(SysUser::getNickName) // 权限名称 +// .setCreateTime(user -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, user.getCreateTime())) +// .setGroupName(user -> user.getDept() != null ? user.getDept().getDeptName() : ""); +// +// // 业务系统机构,转成组件内部左侧树列表能够显示的数据 +// TreeFunDto treeFunDto = new TreeFunDto<>(deptList) +// .setId(dept -> dept.getDeptId().toString()) // 左侧树ID +// .setName(SysDept::getDeptName) // 左侧树名称 +// .setParentId(dept -> dept.getParentId().toString()); // 左侧树父级ID +// +// return getHandlerSelectVo(handlerFunDto, treeFunDto); +// } + +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java index 4977a66bb..9dcb2b6da 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java @@ -13,6 +13,7 @@ import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.workflow.common.enums.TaskAssigneeEnum; import java.util.*; @@ -32,9 +33,9 @@ public class WorkflowUtils { public static List permissionList() { List roles = LoginHelper.getLoginUser().getRoles(); Long deptId = LoginHelper.getDeptId(); - List permissionList = StreamUtils.toList(roles, role -> "role:" + role.getRoleId()); + List permissionList = StreamUtils.toList(roles, role -> TaskAssigneeEnum.ROLE.getCode() + role.getRoleId()); permissionList.add(LoginHelper.getUserIdStr()); - permissionList.add("dept:" + deptId); + permissionList.add(TaskAssigneeEnum.DEPT.getCode() + deptId); return permissionList; } @@ -55,11 +56,11 @@ public class WorkflowUtils { for (User user : userList) { String processedBy = user.getProcessedBy(); Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON)); - if (processedBy.startsWith("user:")) { + if (processedBy.startsWith(TaskAssigneeEnum.USER.getCode())) { userIds.add(id); - } else if (processedBy.startsWith("role:")) { + } else if (processedBy.startsWith(TaskAssigneeEnum.ROLE.getCode())) { roleIds.add(id); - } else if (processedBy.startsWith("dept:")) { + } else if (processedBy.startsWith(TaskAssigneeEnum.DEPT.getCode())) { deptIds.add(id); } else { userIds.add(Long.valueOf(processedBy)); @@ -111,14 +112,13 @@ public class WorkflowUtils { String processedBy = user.getProcessedBy(); // 提取 processedBy 字段中 ":" 后的部分作为ID Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON)); - - if (processedBy.startsWith("user:")) { + if (processedBy.startsWith(TaskAssigneeEnum.USER.getCode())) { // 如果前缀为 "user:",根据用户ID查询 return userService.selectListByIds(List.of(id)); - } else if (processedBy.startsWith("role:")) { + } else if (processedBy.startsWith(TaskAssigneeEnum.ROLE.getCode())) { // 如果前缀为 "role:",根据角色ID查询用户 return userService.selectUsersByRoleIds(List.of(id)); - } else if (processedBy.startsWith("dept:")) { + } else if (processedBy.startsWith(TaskAssigneeEnum.DEPT.getCode())) { // 如果前缀为 "dept:",根据部门ID查询用户 return userService.selectUsersByDeptIds(List.of(id)); }