This commit is contained in:
六如
2024-12-19 18:05:59 +08:00
parent 3e06fcd799
commit f7f04c28eb
24 changed files with 517 additions and 188 deletions

View File

@@ -19,6 +19,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
/**
@@ -40,6 +41,14 @@ public class UserContext {
UserContext.tokenGetter = tokenGetter;
}
/**
* 获取当前登录用户id
* @return 返回id,没有返回-1
*/
public static Long getUserId() {
return Optional.ofNullable(getUser()).map(User::getUserId).orElse(-1L);
}
/**
* 获取当前登录用户
*

View File

@@ -0,0 +1,21 @@
package com.gitee.sop.adminbackend.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 菜单类型
* @author 六如
*/
@Getter
@AllArgsConstructor
public enum MenuTypeEnum implements IntEnum {
MENU(0, "菜单"),
IFRAME(1, "iframe"),
LINK(2, "外链"),
BUTTON(3, "按钮");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,22 @@
package com.gitee.sop.adminbackend.common.util;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @author 六如
*/
public class DateUtil {
static DateTimeFormatter FORMATTER_FRONT = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
static DateTimeFormatter FORMATTER_YMDHMS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static String formatFrontDate(LocalDateTime localDateTime) {
return FORMATTER_FRONT.format(localDateTime);
}
public static String formatYmdhms(LocalDateTime localDateTime) {
return FORMATTER_YMDHMS.format(localDateTime);
}
}

View File

@@ -60,7 +60,7 @@ public class SysResource {
private String redirect;
/**
* 路由重定向
* 菜单图标
*/
private String icon;

View File

@@ -12,5 +12,4 @@ import org.springframework.stereotype.Service;
@Service
public class SysResourceService implements LambdaService<SysResource, SysResourceMapper> {
}

View File

@@ -7,6 +7,7 @@ import com.gitee.sop.adminbackend.service.sys.dto.SysRoleResourceDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@@ -50,4 +51,10 @@ public class SysRoleResourceService implements LambdaService<SysRoleResource, Sy
.listUniqueValue(SysRoleResource::getResourceId);
}
public List<Long> listRoleResource(Collection<Long> roleIds) {
return this.query()
.in(SysRoleResource::getRoleId, roleIds)
.listUniqueValue(SysRoleResource::getResourceId);
}
}

View File

@@ -2,11 +2,17 @@ package com.gitee.sop.adminbackend.service.sys;
import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.sop.adminbackend.common.user.User;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.SysRole;
import com.gitee.sop.adminbackend.dao.entity.SysUserRole;
import com.gitee.sop.adminbackend.dao.mapper.SysRoleMapper;
import com.gitee.sop.adminbackend.dao.mapper.SysUserRoleMapper;
import com.gitee.sop.adminbackend.service.sys.dto.SysRoleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;
@@ -18,6 +24,9 @@ import java.util.stream.Collectors;
@Service
public class SysUserRoleService implements LambdaService<SysUserRole, SysUserRoleMapper> {
@Autowired
private SysRoleMapper sysRoleMapper;
/**
* 设置用户角色
*
@@ -52,4 +61,14 @@ public class SysUserRoleService implements LambdaService<SysUserRole, SysUserRol
.listUniqueValue(SysUserRole::getRoleId);
}
public List<SysRoleDTO> listUserRoles(Long userId) {
List<Long> roleIds = this.listUserRoleIds(userId);
if (roleIds.isEmpty()) {
return new ArrayList<>(0);
}
return sysRoleMapper.query()
.in(SysRole::getId, roleIds)
.list(sysRole -> CopyUtil.copyBean(sysRole, SysRoleDTO::new));
}
}

View File

@@ -0,0 +1,99 @@
package com.gitee.sop.adminbackend.service.sys;
import com.gitee.fastmybatis.core.util.TreeUtil;
import com.gitee.sop.adminbackend.common.enums.MenuTypeEnum;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.dao.entity.SysResource;
import com.gitee.sop.adminbackend.dao.entity.SysRoleResource;
import com.gitee.sop.adminbackend.service.sys.dto.MenuTreeDTO;
import com.gitee.sop.adminbackend.service.sys.dto.MenuTreeDTO.Meta;
import com.gitee.sop.adminbackend.service.sys.dto.SysRoleDTO;
import com.gitee.sop.adminbackend.service.sys.dto.UserPermissionDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author 六如
*/
@Service
public class UserPermissionService {
@Autowired
private SysResourceService sysResourceService;
@Autowired
private SysRoleResourceService sysRoleResourceService;
@Autowired
private SysUserRoleService sysUserRoleService;
public UserPermissionDTO getUserPermission(Long userId) {
List<SysRoleDTO> sysRoleDTOS = sysUserRoleService.listUserRoles(userId);
if (sysRoleDTOS.isEmpty()) {
return UserPermissionDTO.empty();
}
Set<Long> roleIds = sysRoleDTOS.stream().map(SysRoleDTO::getId).collect(Collectors.toSet());
List<String> roleCodes = sysRoleDTOS.stream().map(SysRoleDTO::getCode).distinct().collect(Collectors.toList());
// 角色对应的资源
List<Long> resourceIds = sysRoleResourceService.query()
.in(SysRoleResource::getRoleId, roleIds)
.listUniqueValue(SysRoleResource::getResourceId);
// 获取按钮权限
List<String> permissions = sysResourceService.query()
.eq(SysResource::getMenuType, MenuTypeEnum.BUTTON.getValue())
.in(SysResource::getId, resourceIds)
.listUniqueValue(SysResource::getAuths);
UserPermissionDTO userPermissionDTO = new UserPermissionDTO();
userPermissionDTO.setRoles(roleCodes);
userPermissionDTO.setPermissions(permissions);
return userPermissionDTO;
}
/**
* 获取用户菜单
*
* @param userId 用户id
* @return 返回菜单树
*/
public List<MenuTreeDTO> listUserMenuTree(Long userId) {
List<Long> roleIds = sysUserRoleService.listUserRoleIds(userId);
if (roleIds.isEmpty()) {
return Collections.emptyList();
}
List<Long> resourceIds = sysRoleResourceService.listRoleResource(roleIds);
if (resourceIds.isEmpty()) {
return Collections.emptyList();
}
List<SysResource> list = sysResourceService.query()
.in(SysResource::getId, resourceIds)
.eq(SysResource::getMenuType, MenuTypeEnum.MENU)
.list();
return convert(list);
}
private List<MenuTreeDTO> convert(List<SysResource> list) {
List<MenuTreeDTO> menuTreeDTOS = list.stream()
.map(sysResource -> {
MenuTreeDTO menuTreeDTO = CopyUtil.copyBean(sysResource, MenuTreeDTO::new);
Meta meta = CopyUtil.copyBean(sysResource, Meta::new);
menuTreeDTO.setMeta(meta);
return menuTreeDTO;
})
.collect(Collectors.toList());
return TreeUtil.convertTree(menuTreeDTOS, 0L);
}
}

View File

@@ -0,0 +1,131 @@
package com.gitee.sop.adminbackend.service.sys.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gitee.fastmybatis.core.support.TreeNode;
import com.gitee.sop.adminbackend.common.jackson.convert.annotation.Bool;
import com.google.common.collect.Lists;
import lombok.Data;
import java.util.List;
/**
* 菜单资源
*
* @author 六如
* @see <a href="https://pure-admin.cn/pages/routerMenu/#%E8%B7%AF%E7%94%B1%E5%92%8C%E8%8F%9C%E5%8D%95%E9%85%8D%E7%BD%AE">...</a>
*/
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MenuTreeDTO implements TreeNode<MenuTreeDTO, Long> {
/**
* id
*/
private Long id;
/**
* 路由路径
*/
private String path;
/**
* 路由名称(必须保持唯一)
*/
private String name;
/**
* 路由重定向(默认跳转地址)
*/
private String redirect;
/**
* 父级id
*/
private Long parentId;
/**
* 路由元信息
*/
private Meta meta;
private List<MenuTreeDTO> children;
@Override
public Long takeId() {
return id;
}
@Override
public Long takeParentId() {
return parentId;
}
/**
* 路由元信息,通俗来说就是路由上的额外信息 https://router.vuejs.org/zh/guide/advanced/meta.html#%E8%B7%AF%E7%94%B1%E5%85%83%E4%BF%A1%E6%81%AF
*/
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public static class Meta {
/**
* 菜单名称兼容国际化、非国际化如果用国际化的写法就必须在根目录的locales文件夹下对应添加
*/
private String title;
/**
* 菜单图标
*/
private String icon;
/**
* 右侧图标
*/
private String extraIcon;
/**
* 菜单(是否显示该菜单)
*/
@Bool
private Integer showLink;
/**
* 父级菜单(是否显示父级菜单
*/
@Bool
private Integer showParent;
/**
* 链接地址(需要内嵌的`iframe`链接地址)
*/
private String frameSrc;
/**
* 加载动画(内嵌的`iframe`页面是否开启首次加载动画)
*/
@Bool
private Integer frameLoading;
/**
* 缓存页面
*/
@Bool
private Integer keepAlive;
/**
* 标签页(当前菜单名称或自定义信息禁止添加到标签页)
*/
@Bool
private Integer hiddenTag;
/**
* 菜单激活
*/
private String activePath;
/**
* 排序
*/
private Integer rank;
}
}

View File

@@ -0,0 +1,29 @@
package com.gitee.sop.adminbackend.service.sys.dto;
import lombok.Data;
/**
* @author 六如
*/
@Data
public class SysRoleDTO {
/**
* id
*/
private Long id;
/**
* 角色名称
*/
private String name;
/**
* 角色code
*/
private String code;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,31 @@
package com.gitee.sop.adminbackend.service.sys.dto;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
/**
* @author 六如
*/
@Data
public class UserPermissionDTO {
/**
* 用户角色code
*/
private List<String> roles;
/**
* 用户按钮级别code
*/
private List<String> permissions;
public static UserPermissionDTO empty() {
UserPermissionDTO userPermissionDTO = new UserPermissionDTO();
userPermissionDTO.setRoles(new ArrayList<>());
userPermissionDTO.setPermissions(new ArrayList<>());
return userPermissionDTO;
}
}

View File

@@ -0,0 +1,20 @@
package com.gitee.sop.adminbackend.service.sys.dto;
import lombok.Data;
import java.util.List;
/**
* 用户角色信息
* @author 六如
*/
@Data
public class UserRoleInfoDTO {
private Long userId;
private List<Long> roleIds;
private List<String> roleCodes;
}

View File

@@ -6,16 +6,18 @@ import com.gitee.sop.adminbackend.common.enums.StatusEnum;
import com.gitee.sop.adminbackend.common.exception.BizException;
import com.gitee.sop.adminbackend.common.manager.UserCacheManager;
import com.gitee.sop.adminbackend.common.util.CopyUtil;
import com.gitee.sop.adminbackend.common.util.DateUtil;
import com.gitee.sop.adminbackend.common.util.GenerateUtil;
import com.gitee.sop.adminbackend.common.util.JwtUtil;
import com.gitee.sop.adminbackend.dao.entity.SysUser;
import com.gitee.sop.adminbackend.service.sys.SysUserService;
import com.gitee.sop.adminbackend.service.sys.UserPermissionService;
import com.gitee.sop.adminbackend.service.sys.dto.UserPermissionDTO;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginDTO;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginForm;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginResult;
import com.gitee.sop.adminbackend.service.sys.login.dto.LoginUser;
import com.gitee.sop.adminbackend.service.sys.login.enums.RegTypeEnum;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,7 +27,6 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -39,9 +40,10 @@ public class LoginService {
@Autowired
private SysUserService sysUserService;
@Autowired
private UserCacheManager userCacheManager;
@Autowired
private UserPermissionService userPermissionService;
public LoginUser login(LoginDTO loginDTO) {
@@ -74,20 +76,14 @@ public class LoginService {
// 创建token
String token = this.createToken(sysUser.getId());
loginUser.setAccessToken(token);
if ("admin".equals(sysUser.getUsername())) {
// ROLE
loginUser.setRoles(Sets.newHashSet("admin"));
// *:*:* 表示所有权限
loginUser.setPermissions(Sets.newHashSet("*:*:*"));
} else {
// TODO:其它角色权限
loginUser.setRoles(Sets.newHashSet());
loginUser.setPermissions(Sets.newHashSet());
}
UserPermissionDTO userPermission = userPermissionService.getUserPermission(loginUser.getUserId());
// 角色权限
loginUser.setRoles(userPermission.getRoles());
loginUser.setPermissions(userPermission.getPermissions());
// 设置token过期时间
String value = Configs.getValue(ConfigKeyEnum.JWT_TIMEOUT_DAYS);
LocalDateTime expireDate = LocalDateTime.now().plusDays(NumberUtils.toInt(value));
loginUser.setExpires(expireDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")));
loginUser.setExpires(DateUtil.formatFrontDate(expireDate));
return loginUser;
}

View File

@@ -3,7 +3,7 @@ package com.gitee.sop.adminbackend.service.sys.login.dto;
import com.gitee.sop.adminbackend.common.user.User;
import lombok.Data;
import java.util.Set;
import java.util.List;
/**
* @author 六如
@@ -56,9 +56,9 @@ public class LoginUser implements User {
*/
private Integer status;
private Set<String> roles;
private List<String> roles;
private Set<String> permissions;
private List<String> permissions;
private String accessToken;

View File

@@ -36,13 +36,25 @@ public class SysResourceController {
@Autowired
private SysRoleResourceService sysRoleResourceService;
/**
* 获取菜单树
*
* @return 返回分页结果
*/
@GetMapping("/tree")
public Result<List<SysResourceVO>> tree() {
List<SysResource> list = sysResourceService.listAll();
List<SysResourceVO> retList = CopyUtil.copyList(list, SysResourceVO::new);
return Result.ok(retList);
}
/**
* 查询全部资源
*
* @return 返回分页结果
*/
@GetMapping("/listAll")
public Result<List<SysResourceVO>> tree() {
public Result<List<SysResourceVO>> listAll() {
List<SysResource> list = sysResourceService.listAll();
List<SysResourceVO> retList = CopyUtil.copyList(list, SysResourceVO::new);
return Result.ok(retList);

View File

@@ -0,0 +1,35 @@
package com.gitee.sop.adminbackend.controller.sys;
import com.gitee.sop.adminbackend.common.context.UserContext;
import com.gitee.sop.adminbackend.common.resp.Result;
import com.gitee.sop.adminbackend.service.sys.UserPermissionService;
import com.gitee.sop.adminbackend.service.sys.dto.MenuTreeDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author 六如
*/
@RestController
@RequestMapping("sys/userperm")
public class UserPermissionController {
@Autowired
private UserPermissionService userPermissionService;
/**
* 获取当前登录用户菜单
*
* @return 返回菜单树
*/
@GetMapping("listCurrentUserMenu")
public Result<List<MenuTreeDTO>> listCurrentUserMenu() {
List<MenuTreeDTO> menuTreeDTOS = userPermissionService.listUserMenuTree(UserContext.getUserId());
return Result.ok(menuTreeDTOS);
}
}

View File

@@ -1,12 +1,10 @@
package com.gitee.sop.adminbackend.controller.sys.param;
import java.time.LocalDateTime;
import com.gitee.sop.adminbackend.common.jackson.convert.annotation.Bool;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
@@ -19,29 +17,26 @@ public class SysResourceAddParam {
/**
* 菜单类型0代表菜单、1代表iframe、2代表外链、3代表按钮
*/
@NotNull
@NotNull(message = "菜单类型必填")
private Integer menuType;
/**
* 菜单名称
* 菜单名称, menuType=0时必填
*/
@NotBlank
private String title;
/**
* 路由名称
* 路由名称, menuType=0时必填
*/
@NotBlank
private String name;
/**
* 路由路径
* 路由路径, menuType=0时必填
*/
@NotBlank
private String path;
/**
* 路由路径
* 组件路径
*/
private String component;

View File

@@ -2,6 +2,7 @@ package com.gitee.sop.adminbackend.controller.sys.vo;
import lombok.Data;
import java.util.List;
import java.util.Set;
/**
@@ -41,9 +42,9 @@ public class LoginResultVO {
*/
private Integer status;
private Set<String> roles;
private List<String> roles;
private Set<String> permissions;
private List<String> permissions;
private String accessToken;