fix
This commit is contained in:
@@ -40,6 +40,7 @@ public class SaTokenMvcConfiguration implements WebMvcConfigurer {
|
||||
public SaServletFilter getGlobleSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
.addInclude("/**").addExclude("/favicon.ico")
|
||||
.addExclude("/auth/getConfig", "/captcha/code")
|
||||
.setAuth(obj -> {
|
||||
SaRouter.match("/**", "/auth/login", StpUtil::checkLogin);
|
||||
})
|
||||
|
||||
@@ -135,6 +135,11 @@ public class LoginUser implements Serializable {
|
||||
*/
|
||||
private String deviceType;
|
||||
|
||||
/**
|
||||
* 是否是超级管理员
|
||||
*/
|
||||
private Integer isAdmin;
|
||||
|
||||
/**
|
||||
* 获取登录id
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.agileboot.system.menu.service;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.agileboot.common.satoken.pojo.LoginUser;
|
||||
import com.agileboot.system.menu.dto.*;
|
||||
import com.agileboot.system.menu.vo.RouterVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -20,4 +21,6 @@ public interface ISysMenuService {
|
||||
void remove(Long menuId);
|
||||
|
||||
List<Long> getMenuIdsByRoleId(Long roleId);
|
||||
|
||||
List<RouterVO> getRouterTree(LoginUser loginUser);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.agileboot.system.menu.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import com.agileboot.common.core.enums.common.MenuTypeEnum;
|
||||
import com.agileboot.common.core.enums.common.StatusEnum;
|
||||
import com.agileboot.common.core.exception.BizException;
|
||||
import com.agileboot.common.core.exception.error.ErrorCode;
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
@@ -12,12 +14,14 @@ import com.agileboot.system.menu.dto.*;
|
||||
import com.agileboot.system.menu.entity.SysMenu;
|
||||
import com.agileboot.system.menu.mapper.SysMenuMapper;
|
||||
import com.agileboot.system.menu.service.ISysMenuService;
|
||||
import com.agileboot.system.menu.vo.RouterVO;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -114,13 +118,68 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
||||
return this.baseMapper.selectMenuIdsByRoleId(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RouterVO> getRouterTree(LoginUser loginUser) {
|
||||
List<Tree<Long>> trees = buildMenuEntityTree(loginUser);
|
||||
return buildRouterTree(trees);
|
||||
}
|
||||
|
||||
public List<Tree<Long>> buildMenuEntityTree(LoginUser loginUser) {
|
||||
List<SysMenu> allMenus;
|
||||
if (loginUser.getIsAdmin() == 1) {
|
||||
allMenus = super.list();
|
||||
} else {
|
||||
allMenus = this.baseMapper.selectMenuListByUserId(loginUser.getUserId());
|
||||
}
|
||||
|
||||
// 传给前端的路由排除掉按钮和停用的菜单
|
||||
List<SysMenu> noButtonMenus = allMenus.stream()
|
||||
.filter(menu -> !menu.getIsButton())
|
||||
.filter(menu-> StatusEnum.ENABLE.getValue().equals(menu.getStatus()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
TreeNodeConfig config = new TreeNodeConfig();
|
||||
// 默认为id 可以不设置
|
||||
config.setIdKey("menuId");
|
||||
|
||||
return TreeUtil.build(noButtonMenus, 0L, config, (menu, tree) -> {
|
||||
// 也可以使用 tree.setId(dept.getId());等一些默认值
|
||||
tree.setId(menu.getMenuId());
|
||||
tree.setParentId(menu.getParentId());
|
||||
// TODO 可以取meta中的rank来排序
|
||||
// tree.setWeight(menu.getRank());
|
||||
tree.putExtra("entity", menu);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public List<RouterVO> buildRouterTree(List<Tree<Long>> trees) {
|
||||
List<RouterVO> routers = new LinkedList<>();
|
||||
if (CollUtil.isNotEmpty(trees)) {
|
||||
for (Tree<Long> tree : trees) {
|
||||
Object entity = tree.get("entity");
|
||||
if (entity != null) {
|
||||
RouterVO routerDTO = new RouterVO((SysMenu) entity);
|
||||
List<Tree<Long>> children = tree.getChildren();
|
||||
if (CollUtil.isNotEmpty(children)) {
|
||||
routerDTO.setChildren(buildRouterTree(children));
|
||||
}
|
||||
routers.add(routerDTO);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return routers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建前端所需要树结构
|
||||
*
|
||||
* @param menus 菜单列表
|
||||
* @return 树结构列表
|
||||
*/
|
||||
public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
|
||||
private List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
|
||||
TreeNodeConfig config = new TreeNodeConfig();
|
||||
//默认为id可以不设置
|
||||
config.setIdKey("menuId");
|
||||
|
||||
@@ -44,6 +44,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
loginUser.setUsername(sysUser.getUsername());
|
||||
loginUser.setNickname(sysUser.getNickname());
|
||||
loginUser.setPassword(sysUser.getPassword());
|
||||
loginUser.setIsAdmin(sysUser.getIsAdmin());
|
||||
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
@@ -2,25 +2,30 @@ package com.agileboot.auth.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.agileboot.auth.pojo.dto.LoginBody;
|
||||
import com.agileboot.auth.pojo.dto.RegisterBody;
|
||||
import com.agileboot.auth.pojo.vo.ConfigVO;
|
||||
import com.agileboot.auth.pojo.vo.LoginVO;
|
||||
import com.agileboot.auth.service.IAuthStrategy;
|
||||
import com.agileboot.auth.service.SysLoginService;
|
||||
import com.agileboot.common.core.constant.Constants;
|
||||
import com.agileboot.common.core.core.R;
|
||||
import com.agileboot.common.core.utils.ValidatorUtils;
|
||||
import com.agileboot.common.satoken.pojo.LoginUser;
|
||||
import com.agileboot.common.satoken.utils.LoginHelper;
|
||||
import com.agileboot.system.client.service.ISysClientService;
|
||||
import com.agileboot.system.client.vo.SysClientVO;
|
||||
import com.agileboot.system.menu.service.ISysMenuService;
|
||||
import com.agileboot.system.menu.vo.RouterVO;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 认证
|
||||
@@ -36,6 +41,7 @@ public class AuthController {
|
||||
|
||||
private final SysLoginService loginService;
|
||||
private final ISysClientService sysClientService;
|
||||
private final ISysMenuService sysMenuService;
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
@@ -63,6 +69,20 @@ public class AuthController {
|
||||
return R.ok(loginVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统的内置配置
|
||||
*
|
||||
* @return 配置信息
|
||||
*/
|
||||
@GetMapping("/getConfig")
|
||||
public R<ConfigVO> getConfig() {
|
||||
// ConfigVO vo = loginService.getConfig();
|
||||
ConfigVO configVO = new ConfigVO();
|
||||
String property = SpringUtil.getProperty("security.captcha.enabled");
|
||||
configVO.setIsCaptchaOn(Boolean.parseBoolean(property));
|
||||
return R.ok(configVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
@@ -80,4 +100,16 @@ public class AuthController {
|
||||
loginService.register(user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户对应的菜单路由 用于动态生成路由
|
||||
* TODO 如果要在前端开启路由缓存的话 需要在ServerConfig.json 中 设置CachingAsyncRoutes=true 避免一直重复请求路由接口
|
||||
* @return 路由信息
|
||||
*/
|
||||
@GetMapping("/getRouters")
|
||||
public R<List<RouterVO>> getRouters() {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
List<RouterVO> routerTree = sysMenuService.getRouterTree(loginUser);
|
||||
return R.ok(routerTree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.agileboot.auth.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.hutool.captcha.AbstractCaptcha;
|
||||
import cn.hutool.captcha.generator.CodeGenerator;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
@@ -21,6 +22,7 @@ import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -32,8 +34,10 @@ import java.time.Duration;
|
||||
*/
|
||||
@Slf4j
|
||||
@Validated
|
||||
@SaIgnore
|
||||
@RequiredArgsConstructor
|
||||
@RestController("/captcha")
|
||||
@RestController
|
||||
@RequestMapping("/captcha")
|
||||
public class CaptchaController {
|
||||
|
||||
private final CaptchaProperties captchaProperties;
|
||||
@@ -47,11 +51,11 @@ public class CaptchaController {
|
||||
CaptchaVO captchaVo = new CaptchaVO();
|
||||
boolean captchaEnabled = captchaProperties.getEnabled();
|
||||
if (!captchaEnabled) {
|
||||
captchaVo.setCaptchaEnabled(false);
|
||||
captchaVo.setIsCaptchaOn(false);
|
||||
return R.ok(captchaVo);
|
||||
}
|
||||
CaptchaController proxy = (CaptchaController) AopContext.currentProxy();
|
||||
return R.ok(proxy.getCodeImpl());
|
||||
// CaptchaController proxy = (CaptchaController) AopContext.currentProxy();
|
||||
return R.ok(this.getCodeImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ public class PasswordLoginBody extends LoginBody {
|
||||
* 用户密码
|
||||
*/
|
||||
@NotBlank(message = "Password cannot be empty")
|
||||
@Length(min = 5, max = 30, message = "user.password.length.valid")
|
||||
// @Length(min = 5, max = 30, message = "user.password.length.valid")
|
||||
private String password;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class CaptchaVO {
|
||||
/**
|
||||
* 是否开启验证码
|
||||
*/
|
||||
private Boolean captchaEnabled = true;
|
||||
private Boolean isCaptchaOn = true;
|
||||
|
||||
private String uuid;
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.agileboot.auth.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigVO {
|
||||
private Boolean isCaptchaOn;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.agileboot.system.menu.vo;
|
||||
|
||||
import com.agileboot.common.core.utils.jackson.JacksonUtil;
|
||||
import com.agileboot.system.menu.dto.MetaDTO;
|
||||
import com.agileboot.system.menu.entity.SysMenu;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 动态路由信息
|
||||
* 必须加上@JsonInclude(Include.NON_NULL)的注解 否则传null值给Vue动态路由渲染时会出错
|
||||
*
|
||||
* @author valarchie
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RouterVO {
|
||||
|
||||
public RouterVO(SysMenu entity) {
|
||||
if (entity != null) {
|
||||
this.name = entity.getRouterName();
|
||||
this.path = entity.getPath();
|
||||
// 暂时不需要component
|
||||
// this.component = entity.getComponent();
|
||||
// this.rank = entity.getRank();
|
||||
// this.redirect = entity.getRedirect();
|
||||
if (JacksonUtil.isJson(entity.getMetaInfo())) {
|
||||
this.meta = JacksonUtil.from(entity.getMetaInfo(), MetaDTO.class);
|
||||
} else {
|
||||
this.meta = new MetaDTO();
|
||||
}
|
||||
this.meta.setAuths(Lists.newArrayList(entity.getPermission()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由名字 根据前端的要求 必须唯一
|
||||
* 并按照前端项目的推荐 这个Name最好和组件的Name一样 使用菜单表中的router_name
|
||||
* TODO 这里后端需要加校验
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 路由路径地址
|
||||
*/
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 路由重定向
|
||||
*/
|
||||
private String redirect;
|
||||
|
||||
/**
|
||||
* 组件地址
|
||||
*/
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 一级菜单排序值(排序仅支持一级菜单)
|
||||
*/
|
||||
private Integer rank;
|
||||
|
||||
|
||||
/**
|
||||
* 其他元素
|
||||
*/
|
||||
private MetaDTO meta;
|
||||
|
||||
/**
|
||||
* 子路由
|
||||
*/
|
||||
private List<RouterVO> children;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user