add 用户获取角色、菜单

This commit is contained in:
小李 2026-01-08 16:52:49 +08:00
parent 5a4b472126
commit 47e8f1ea5f
9 changed files with 118 additions and 48 deletions

View File

@ -0,0 +1,28 @@
package com.tacit.common.entity;
import java.util.List;
/**
* 树形结构实体接口
* 实现该接口的实体可以使用 TreeUtils 工具类进行树形结构转换
* @param <T> 实体类型
*/
public interface TreeEntity<T> {
/**
* 获取实体ID
* @return 实体ID
*/
Long getId();
/**
* 获取父实体ID
* @return 父实体ID
*/
Long getParentId();
/**
* 设置子实体列表
* @param children 子实体列表
*/
void setChildren(List<T> children);
}

View File

@ -0,0 +1,51 @@
package com.tacit.common.utils;
import com.tacit.common.entity.TreeEntity;
import java.util.List;
import java.util.stream.Collectors;
public class TreeUtils {
/**
* 将列表转换为树形结构
* @param entityList 实体列表
* @return 树形结构的实体列表
*/
public static <T extends TreeEntity<T>> List<T> buildTree(List<T> entityList) {
if (entityList == null || entityList.isEmpty()) {
return null;
}
// 找到所有根节点parentId为0或null
List<T> rootEntities = entityList.stream()
.filter(entity -> entity.getParentId() == null || entity.getParentId() == 0)
.collect(Collectors.toList());
// 为每个根节点添加子节点
rootEntities.forEach(rootEntity -> {
addChildren(rootEntity, entityList);
});
return rootEntities;
}
/**
* 递归添加子节点
* @param parentEntity 父实体
* @param entityList 所有实体列表
*/
private static <T extends TreeEntity<T>> void addChildren(T parentEntity, List<T> entityList) {
// 找到所有父节点的直接子节点
List<T> children = entityList.stream()
.filter(entity -> parentEntity.getId().equals(entity.getParentId()))
.collect(Collectors.toList());
if (!children.isEmpty()) {
// 设置子节点
parentEntity.setChildren(children);
// 递归添加子节点的子节点
children.forEach(child -> {
addChildren(child, entityList);
});
}
}
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.tacit.common.entity.Base;
import com.tacit.common.entity.TreeEntity;
import lombok.Data;
import java.io.Serializable;
@ -13,7 +14,7 @@ import java.util.stream.Collectors;
@Data
@TableName("sys_menu")
public class Menu extends Base implements Serializable {
public class Menu extends Base implements Serializable, TreeEntity<Menu> {
private static final long serialVersionUID = 1L;
// 菜单ID
@TableId(type = IdType.AUTO)
@ -69,47 +70,8 @@ public class Menu extends Base implements Serializable {
@TableField(exist = false)
private List<Menu> children;
/**
* 将菜单列表转换为树形结构
* @param menuList 菜单列表
* @return 树形结构的菜单列表
*/
public static List<Menu> buildTree(List<Menu> menuList) {
if (menuList == null || menuList.isEmpty()) {
return null;
}
// 找到所有根节点parentId为0或null
List<Menu> rootMenus = menuList.stream()
.filter(menu -> menu.getParentId() == null || menu.getParentId() == 0)
.collect(Collectors.toList());
// 为每个根节点添加子节点
rootMenus.forEach(rootMenu -> {
addChildren(rootMenu, menuList);
});
return rootMenus;
}
/**
* 递归添加子节点
* @param parentMenu 父菜单
* @param menuList 所有菜单列表
*/
private static void addChildren(Menu parentMenu, List<Menu> menuList) {
// 找到所有父节点的直接子节点
List<Menu> children = menuList.stream()
.filter(menu -> parentMenu.getMenuId().equals(menu.getParentId()))
.collect(Collectors.toList());
if (!children.isEmpty()) {
// 设置子节点
parentMenu.setChildren(children);
// 递归添加子节点的子节点
children.forEach(child -> {
addChildren(child, menuList);
});
}
@Override
public Long getId() {
return menuId;
}
}

View File

@ -9,6 +9,7 @@ import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@Data
@TableName("t_role")
@ -20,7 +21,6 @@ public class Role extends Base implements Serializable {
//角色名称
@TableField("role_name")
private String roleName;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Integer delFlag;
@TableField(exist = false)
private List<Menu> menuList;
}

View File

@ -1,5 +1,6 @@
package com.tacit.admin.entity.dto;
import com.tacit.admin.entity.Role;
import com.tacit.admin.entity.User;
import lombok.Data;
@ -21,4 +22,8 @@ public class LoginResponse implements Serializable {
* 用户信息
*/
private User user;
/**
* 角色信息
*/
private Role role;
}

View File

@ -6,6 +6,8 @@ import com.tacit.admin.entity.Role;
public interface RoleService extends IService<Role> {
//根据用户id获取角色
Role getRoleByUserId(Long userId);
//根据用户id获取角色菜单
Role getRoleMenuByUserId(Long userId);
}

View File

@ -13,6 +13,7 @@ import com.tacit.admin.mapper.UserRoleMapper;
import com.tacit.admin.service.MenuService;
import com.tacit.admin.service.RoleService;
import com.tacit.common.redis.utils.RedisUtils;
import com.tacit.common.utils.TreeUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@ -39,7 +40,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
List<Long> menuIdList = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
List<Menu> menuList = menuMapper.selectBatchIds(menuIdList);
// 需要将MenuList转换成树形结构
menuList = Menu.buildTree(menuList);
menuList = TreeUtils.buildTree(menuList);
return menuList;
}
return null;

View File

@ -2,21 +2,25 @@ package com.tacit.admin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tacit.admin.entity.Menu;
import com.tacit.admin.entity.Role;
import com.tacit.admin.entity.User;
import com.tacit.admin.entity.UserRole;
import com.tacit.admin.mapper.RoleMapper;
import com.tacit.admin.mapper.UserRoleMapper;
import com.tacit.admin.service.MenuService;
import com.tacit.admin.service.RoleService;
import com.tacit.common.redis.utils.RedisUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
@Resource
private RedisUtils redisUtils;
private MenuService menuService;
@Resource
private RoleMapper roleMapper;
@Resource
@ -35,4 +39,15 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
// 角色不存在
return null;
}
@Override
public Role getRoleMenuByUserId(Long userId) {
Role role = this.getRoleByUserId(userId);
if (role == null){
return null;
}
List<Menu> menuList = menuService.getMenuListByRoleId(role.getId());
role.setMenuList(menuList);
return role;
}
}

View File

@ -2,11 +2,13 @@ package com.tacit.admin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tacit.admin.entity.Role;
import com.tacit.admin.entity.User;
import com.tacit.admin.entity.dto.LoginRequest;
import com.tacit.admin.entity.dto.LoginResponse;
import com.tacit.admin.entity.dto.RegisterRequest;
import com.tacit.admin.mapper.UserMapper;
import com.tacit.admin.service.RoleService;
import com.tacit.admin.service.UserService;
import com.tacit.common.utils.JwtUtils;
import com.tacit.common.redis.utils.RedisUtils;
@ -32,6 +34,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
@Resource
private RedisUtils redisUtils;
@Resource
private RoleService roleService;
@Override
public User getUserByUsername(String username) {
@ -101,10 +105,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
String token = JwtUtils.generateToken(claims);
// 将生成的 JWT 令牌存储到 Redis 缓存中设置过期时间为 7 7 * 24 * 60 * 60
redisUtils.setObject(token, user.getId(),7 * 24 * 60 * 60, TimeUnit.SECONDS);
Role roleMenu = roleService.getRoleByUserId(user.getId());
// 构建登录响应
LoginResponse loginResponse = new LoginResponse();
loginResponse.setToken(token);
loginResponse.setUser(user);
loginResponse.setRole(roleMenu);
return loginResponse;
}