|
|
@@ -0,0 +1,435 @@
|
|
|
+package com.lianda.backend.service;
|
|
|
+
|
|
|
+import com.lianda.backend.dto.*;
|
|
|
+import com.lianda.backend.model.*;
|
|
|
+import com.lianda.backend.repository.*;
|
|
|
+import com.lianda.backend.config.DataSource;
|
|
|
+import com.lianda.backend.config.RoutingDataSourceConfig;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.domain.*;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 角色管理Service
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class RoleService {
|
|
|
+
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(RoleService.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysRoleRepository sysRoleRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysFunctionCodeRepository sysFunctionCodeRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysRoleFunctionCodeRepository sysRoleFunctionCodeRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserRoleRepository sysUserRoleRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private UserRepository userRepository;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询角色列表
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = true)
|
|
|
+ public Page<RoleDTO> queryRoles(RoleQueryDTO queryDTO) {
|
|
|
+ logger.info("开始查询角色列表,查询条件:{}", queryDTO.getRoleName());
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<SysRole> roles;
|
|
|
+ long total = 0;
|
|
|
+
|
|
|
+ if (queryDTO.getRoleName() != null && !queryDTO.getRoleName().isEmpty()) {
|
|
|
+ roles = sysRoleRepository.findByRoleNameContaining(queryDTO.getRoleName());
|
|
|
+ } else {
|
|
|
+ roles = sysRoleRepository.findAll();
|
|
|
+ }
|
|
|
+
|
|
|
+ total = roles.size();
|
|
|
+
|
|
|
+ List<RoleDTO> roleDTOs = roles.stream()
|
|
|
+ .map(this::convertToDTO)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ int start = queryDTO.getPage() * queryDTO.getPageSize();
|
|
|
+ int end = Math.min(start + queryDTO.getPageSize(), roleDTOs.size());
|
|
|
+ List<RoleDTO> pageData = roleDTOs.subList(start, end);
|
|
|
+
|
|
|
+ logger.info("角色列表查询成功,共{}条记录", total);
|
|
|
+ return new PageImpl<>(pageData, PageRequest.of(queryDTO.getPage(), queryDTO.getPageSize()), total);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色列表查询失败", e);
|
|
|
+ throw new RuntimeException("角色列表查询失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取功能代码树
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = true)
|
|
|
+ public List<FunctionCodeTreeNodeDTO> getFunctionCodeTree() {
|
|
|
+ logger.info("开始获取功能代码树");
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<SysFunctionCode> allFunctionCodes = sysFunctionCodeRepository.findAllByOrderByOrderNoAsc();
|
|
|
+ List<FunctionCodeTreeNodeDTO> tree = buildFunctionCodeTree(allFunctionCodes, null);
|
|
|
+
|
|
|
+ logger.info("功能代码树获取成功,共{}个节点", tree.size());
|
|
|
+ return tree;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("功能代码树获取失败", e);
|
|
|
+ throw new RuntimeException("功能代码树获取失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建功能代码树
|
|
|
+ */
|
|
|
+ private List<FunctionCodeTreeNodeDTO> buildFunctionCodeTree(List<SysFunctionCode> allFunctionCodes, String parentCode) {
|
|
|
+ List<FunctionCodeTreeNodeDTO> tree = new ArrayList<>();
|
|
|
+
|
|
|
+ for (SysFunctionCode functionCode : allFunctionCodes) {
|
|
|
+ if (parentCode == null && functionCode.getParentFunctionCode() == null) {
|
|
|
+ FunctionCodeTreeNodeDTO node = convertToTreeNode(functionCode);
|
|
|
+ node.setChildren(buildFunctionCodeTree(allFunctionCodes, functionCode.getFunctionCode()));
|
|
|
+ tree.add(node);
|
|
|
+ } else if (parentCode != null && parentCode.equals(functionCode.getParentFunctionCode())) {
|
|
|
+ FunctionCodeTreeNodeDTO node = convertToTreeNode(functionCode);
|
|
|
+ node.setChildren(buildFunctionCodeTree(allFunctionCodes, functionCode.getFunctionCode()));
|
|
|
+ tree.add(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tree;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取角色的功能代码列表
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = true)
|
|
|
+ public List<String> getRoleFunctionCodes(String roleId) {
|
|
|
+ logger.info("开始获取角色功能代码列表,角色ID:{}", roleId);
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<String> functionCodes = sysRoleFunctionCodeRepository.findFunctionCodesByRoleId(roleId);
|
|
|
+ logger.info("角色功能代码列表获取成功,共{}个功能代码", functionCodes.size());
|
|
|
+ return functionCodes;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色功能代码列表获取失败", e);
|
|
|
+ throw new RuntimeException("角色功能代码列表获取失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增角色
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ public RoleDTO createRole(RoleSaveDTO roleSaveDTO) {
|
|
|
+ logger.info("开始创建角色,角色名称:{}", roleSaveDTO.getRoleName());
|
|
|
+
|
|
|
+ try {
|
|
|
+ SysRole existingRole = sysRoleRepository.findByRoleName(roleSaveDTO.getRoleName());
|
|
|
+ if (existingRole != null) {
|
|
|
+ throw new RuntimeException("角色名称已存在,请使用其他角色名称");
|
|
|
+ }
|
|
|
+
|
|
|
+ SysRole role = new SysRole();
|
|
|
+ role.setRoleId(UUID.randomUUID().toString());
|
|
|
+ role.setRoleName(roleSaveDTO.getRoleName());
|
|
|
+ role.setDescription(roleSaveDTO.getDescription());
|
|
|
+ role.setIsSystemRole(false);
|
|
|
+ role.setRecordStatus(1);
|
|
|
+
|
|
|
+ String currentUserId = getCurrentUserId();
|
|
|
+ role.setCreateUserId(currentUserId);
|
|
|
+ role.setCreateTime(new Date());
|
|
|
+ role.setModifyUserId(currentUserId);
|
|
|
+ role.setModifyTime(new Date());
|
|
|
+
|
|
|
+ role = sysRoleRepository.save(role);
|
|
|
+
|
|
|
+ if (roleSaveDTO.getFunctionCodes() != null && !roleSaveDTO.getFunctionCodes().isEmpty()) {
|
|
|
+ saveRoleFunctionCodes(role.getRoleId(), roleSaveDTO.getFunctionCodes());
|
|
|
+ }
|
|
|
+
|
|
|
+ RoleDTO roleDTO = convertToDTO(role);
|
|
|
+ roleDTO.setFunctionCodes(roleSaveDTO.getFunctionCodes());
|
|
|
+
|
|
|
+ logger.info("角色创建成功,角色ID:{}", role.getRoleId());
|
|
|
+ return roleDTO;
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ logger.error("角色创建失败:{}", e.getMessage());
|
|
|
+ throw e;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色创建失败", e);
|
|
|
+ throw new RuntimeException("角色创建失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改角色
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ public RoleDTO updateRole(RoleSaveDTO roleSaveDTO) {
|
|
|
+ logger.info("开始修改角色,角色ID:{}", roleSaveDTO.getRoleId());
|
|
|
+
|
|
|
+ try {
|
|
|
+ SysRole role = sysRoleRepository.findById(roleSaveDTO.getRoleId())
|
|
|
+ .orElseThrow(() -> new RuntimeException("角色不存在"));
|
|
|
+
|
|
|
+ SysRole existingRole = sysRoleRepository.findByRoleName(roleSaveDTO.getRoleName());
|
|
|
+ if (existingRole != null && !existingRole.getRoleId().equals(roleSaveDTO.getRoleId())) {
|
|
|
+ throw new RuntimeException("角色名称已存在,请使用其他角色名称");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (role.getIsSystemRole()) {
|
|
|
+ throw new RuntimeException("系统角色不允许修改");
|
|
|
+ }
|
|
|
+
|
|
|
+ role.setRoleName(roleSaveDTO.getRoleName());
|
|
|
+ role.setDescription(roleSaveDTO.getDescription());
|
|
|
+
|
|
|
+ String currentUserId = getCurrentUserId();
|
|
|
+ role.setModifyUserId(currentUserId);
|
|
|
+ role.setModifyTime(new Date());
|
|
|
+
|
|
|
+ role = sysRoleRepository.save(role);
|
|
|
+
|
|
|
+ sysRoleFunctionCodeRepository.deleteByRoleId(role.getRoleId());
|
|
|
+ if (roleSaveDTO.getFunctionCodes() != null && !roleSaveDTO.getFunctionCodes().isEmpty()) {
|
|
|
+ saveRoleFunctionCodes(role.getRoleId(), roleSaveDTO.getFunctionCodes());
|
|
|
+ }
|
|
|
+
|
|
|
+ RoleDTO roleDTO = convertToDTO(role);
|
|
|
+ roleDTO.setFunctionCodes(roleSaveDTO.getFunctionCodes());
|
|
|
+
|
|
|
+ logger.info("角色修改成功,角色ID:{}", role.getRoleId());
|
|
|
+ return roleDTO;
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ logger.error("角色修改失败:{}", e.getMessage());
|
|
|
+ throw e;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色修改失败", e);
|
|
|
+ throw new RuntimeException("角色修改失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除角色
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ public void deleteRole(String roleId) {
|
|
|
+ logger.info("开始删除角色,角色ID:{}", roleId);
|
|
|
+
|
|
|
+ try {
|
|
|
+ SysRole role = sysRoleRepository.findById(roleId)
|
|
|
+ .orElseThrow(() -> new RuntimeException("角色不存在"));
|
|
|
+
|
|
|
+ if (role.getIsSystemRole()) {
|
|
|
+ throw new RuntimeException("系统角色不允许删除");
|
|
|
+ }
|
|
|
+
|
|
|
+ sysUserRoleRepository.deleteByRoleId(roleId);
|
|
|
+ sysRoleFunctionCodeRepository.deleteByRoleId(roleId);
|
|
|
+ sysRoleRepository.deleteById(roleId);
|
|
|
+
|
|
|
+ logger.info("角色删除成功,角色ID:{}", roleId);
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ logger.error("角色删除失败:{}", e.getMessage());
|
|
|
+ throw e;
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色删除失败", e);
|
|
|
+ throw new RuntimeException("角色删除失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量删除角色
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ public void deleteRoles(List<String> roleIds) {
|
|
|
+ logger.info("开始批量删除角色,角色ID列表:{}", roleIds);
|
|
|
+
|
|
|
+ try {
|
|
|
+ for (String roleId : roleIds) {
|
|
|
+ deleteRole(roleId);
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("批量删除角色成功,共删除{}个角色", roleIds.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("批量删除角色失败", e);
|
|
|
+ throw new RuntimeException("批量删除角色失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存角色功能代码关联
|
|
|
+ */
|
|
|
+ private void saveRoleFunctionCodes(String roleId, List<String> functionCodes) {
|
|
|
+ for (String functionCode : functionCodes) {
|
|
|
+ SysRoleFunctionCodeId id = new SysRoleFunctionCodeId();
|
|
|
+ id.setRoleId(roleId);
|
|
|
+ id.setFunctionCode(functionCode);
|
|
|
+
|
|
|
+ SysRoleFunctionCode roleFunctionCode = new SysRoleFunctionCode();
|
|
|
+ roleFunctionCode.setId(id);
|
|
|
+
|
|
|
+ sysRoleFunctionCodeRepository.save(roleFunctionCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为DTO
|
|
|
+ */
|
|
|
+ private RoleDTO convertToDTO(SysRole role) {
|
|
|
+ RoleDTO dto = new RoleDTO();
|
|
|
+ dto.setRoleId(role.getRoleId());
|
|
|
+ dto.setRoleName(role.getRoleName());
|
|
|
+ dto.setDescription(role.getDescription());
|
|
|
+ dto.setIsSystemRole(role.getIsSystemRole());
|
|
|
+ dto.setRecordStatus(role.getRecordStatus());
|
|
|
+ dto.setRecordStatusName(role.getRecordStatus() == 1 ? "启用" : "禁用");
|
|
|
+ dto.setCreateTime(role.getCreateTime());
|
|
|
+ dto.setModifyTime(role.getModifyTime());
|
|
|
+ return dto;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为树节点DTO
|
|
|
+ */
|
|
|
+ private FunctionCodeTreeNodeDTO convertToTreeNode(SysFunctionCode functionCode) {
|
|
|
+ FunctionCodeTreeNodeDTO dto = new FunctionCodeTreeNodeDTO();
|
|
|
+ dto.setId(functionCode.getFunctionCode());
|
|
|
+ dto.setLabel(functionCode.getFunctionName());
|
|
|
+ dto.setFunctionCode(functionCode.getFunctionCode());
|
|
|
+ dto.setParentFunctionCode(functionCode.getParentFunctionCode());
|
|
|
+ dto.setOrderNo(functionCode.getOrderNo());
|
|
|
+ return dto;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取角色的用户列表
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = true)
|
|
|
+ @DataSource(value = RoutingDataSourceConfig.DataSourceType.BRANCH)
|
|
|
+ public Page<UserDTO> getRoleUsers(String roleId, UserQueryDTO queryDTO) {
|
|
|
+ logger.info("开始获取角色用户列表,角色ID:{},查询条件:{}", roleId, queryDTO.getKeyword());
|
|
|
+
|
|
|
+ try {
|
|
|
+ logger.info("开始查询角色用户关联数据");
|
|
|
+ List<SysUserRole> userRoles = sysUserRoleRepository.findByRoleId(roleId);
|
|
|
+ logger.info("查询到{}条角色用户关联数据", userRoles.size());
|
|
|
+
|
|
|
+ List<User> roleUsers = new ArrayList<>();
|
|
|
+
|
|
|
+ for (SysUserRole userRole : userRoles) {
|
|
|
+ logger.info("处理用户角色关联,用户ID:{}", userRole.getUserId());
|
|
|
+ User user = userRepository.findById(userRole.getUserId()).orElse(null);
|
|
|
+ if (user != null) {
|
|
|
+ logger.info("找到用户,用户ID:{},姓名:{},登录账号:{}", user.getId(), user.getName(), user.getLoginId());
|
|
|
+ if (queryDTO.getKeyword() == null || queryDTO.getKeyword().isEmpty() ||
|
|
|
+ user.getName().contains(queryDTO.getKeyword()) ||
|
|
|
+ user.getLoginId().contains(queryDTO.getKeyword())) {
|
|
|
+ roleUsers.add(user);
|
|
|
+ logger.info("用户符合查询条件,已添加到列表");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logger.warn("未找到用户,用户ID:{}", userRole.getUserId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ long total = roleUsers.size();
|
|
|
+ logger.info("开始转换用户DTO,共{}条记录", total);
|
|
|
+ List<UserDTO> userDTOs = roleUsers.stream()
|
|
|
+ .map(this::convertUserToDTO)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ int start = queryDTO.getPage() * queryDTO.getPageSize();
|
|
|
+ int end = Math.min(start + queryDTO.getPageSize(), userDTOs.size());
|
|
|
+ List<UserDTO> pageData = userDTOs.subList(start, end);
|
|
|
+
|
|
|
+ logger.info("角色用户列表获取成功,共{}条记录", total);
|
|
|
+ return new PageImpl<>(pageData, PageRequest.of(queryDTO.getPage(), queryDTO.getPageSize()), total);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("角色用户列表获取失败", e);
|
|
|
+ throw new RuntimeException("角色用户列表获取失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加用户到角色
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ @DataSource(value = RoutingDataSourceConfig.DataSourceType.BRANCH)
|
|
|
+ public void addUsersToRole(String roleId, List<String> userIds) {
|
|
|
+ logger.info("开始添加用户到角色,角色ID:{},用户ID列表:{}", roleId, userIds);
|
|
|
+
|
|
|
+ try {
|
|
|
+ for (String userId : userIds) {
|
|
|
+ SysUserRole userRole = new SysUserRole();
|
|
|
+ userRole.setUserId(userId);
|
|
|
+ userRole.setRoleId(roleId);
|
|
|
+
|
|
|
+ sysUserRoleRepository.save(userRole);
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("添加用户到角色成功,共添加{}个用户", userIds.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("添加用户到角色失败", e);
|
|
|
+ throw new RuntimeException("添加用户到角色失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从角色中移除用户
|
|
|
+ */
|
|
|
+ @Transactional
|
|
|
+ @DataSource(value = RoutingDataSourceConfig.DataSourceType.BRANCH)
|
|
|
+ public void removeUserFromRole(String roleId, String userId) {
|
|
|
+ logger.info("开始从角色中移除用户,角色ID:{},用户ID:{}", roleId, userId);
|
|
|
+
|
|
|
+ try {
|
|
|
+ sysUserRoleRepository.deleteByUserIdAndRoleId(userId, roleId);
|
|
|
+ logger.info("从角色中移除用户成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("从角色中移除用户失败", e);
|
|
|
+ throw new RuntimeException("从角色中移除用户失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换User为DTO
|
|
|
+ */
|
|
|
+ private UserDTO convertUserToDTO(User user) {
|
|
|
+ UserDTO dto = new UserDTO();
|
|
|
+ dto.setId(user.getId());
|
|
|
+ dto.setEmployeeId("");
|
|
|
+ dto.setName(user.getName());
|
|
|
+ dto.setLoginId(user.getLoginId());
|
|
|
+ dto.setRoleName("");
|
|
|
+ dto.setWeChatUserId(user.getWechatUserId() != null ? user.getWechatUserId() : "");
|
|
|
+ dto.setRecordStatus(user.getRecordStatus());
|
|
|
+ dto.setRecordStatusName("");
|
|
|
+ dto.setCreateTime(user.getCreateTime());
|
|
|
+ dto.setModifyTime(user.getModifyTime());
|
|
|
+ return dto;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前登录用户ID
|
|
|
+ */
|
|
|
+ private String getCurrentUserId() {
|
|
|
+ return "admin";
|
|
|
+ }
|
|
|
+}
|