From 68234a112e96a1abd73453fac6093f4f9554153b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E7=8E=89=E7=A5=A5?= Date: Tue, 29 Jun 2021 13:57:26 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=99=BB=E5=BD=95=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/error/GlobalExceptionHandler.java | 9 +-- .../auth/factory/LoginUserFactory.java | 24 ++++++- .../menu/controller/SysMenuController.java | 18 ++++- .../modular/menu/service/SysMenuService.java | 19 +++++- .../menu/service/impl/SysMenuServiceImpl.java | 65 +++++++++---------- .../role/service/impl/SysRoleServiceImpl.java | 7 +- 6 files changed, 92 insertions(+), 50 deletions(-) diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/core/error/GlobalExceptionHandler.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/core/error/GlobalExceptionHandler.java index 0ee7a3dc..05b3c5f2 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/core/error/GlobalExceptionHandler.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/core/error/GlobalExceptionHandler.java @@ -41,6 +41,7 @@ import vip.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum; import vip.xiaonuo.core.pojo.response.ErrorResponseData; import vip.xiaonuo.core.sms.modular.aliyun.exp.AliyunSmsException; import vip.xiaonuo.core.sms.modular.tencent.exp.TencentSmsException; +import vip.xiaonuo.core.util.HttpServletUtil; import vip.xiaonuo.core.util.ResponseUtil; import org.apache.ibatis.exceptions.PersistenceException; import org.mybatis.spring.MyBatisSystemException; @@ -173,8 +174,8 @@ public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) @ResponseBody public ErrorResponseData notFound(NoHandlerFoundException e) { - log.error(">>> 资源不存在异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); - return renderJson(PermissionExceptionEnum.URL_NOT_EXIST); + log.error(">>> 资源不存在异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage() +",请求地址为:" + HttpServletUtil.getRequest().getRequestURI()); + return renderJson(PermissionExceptionEnum.URL_NOT_EXIST.getCode(), PermissionExceptionEnum.URL_NOT_EXIST.getMessage() +",请求地址为:" + HttpServletUtil.getRequest().getRequestURI()); } /** @@ -227,8 +228,8 @@ public class GlobalExceptionHandler { @ExceptionHandler(PermissionException.class) @ResponseBody public ErrorResponseData noPermission(PermissionException e) { - log.error(">>> 权限异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage()); - return renderJson(e.getCode(), e.getErrorMessage()); + log.error(">>> 权限异常,请求号为:{},具体信息为:{}", RequestNoContext.get(), e.getMessage() +",请求地址为:" + HttpServletUtil.getRequest().getRequestURI()); + return renderJson(e.getCode(), e.getErrorMessage() + ",请求地址为:" + HttpServletUtil.getRequest().getRequestURI()); } /** diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java index c8ecd20a..eb29a52e 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/auth/factory/LoginUserFactory.java @@ -25,6 +25,7 @@ Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意 package vip.xiaonuo.sys.modular.auth.factory; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; @@ -36,6 +37,7 @@ import vip.xiaonuo.core.exception.ServiceException; import vip.xiaonuo.core.exception.enums.ServerExceptionEnum; import vip.xiaonuo.core.pojo.login.LoginEmpInfo; import vip.xiaonuo.core.pojo.login.SysLoginUser; +import vip.xiaonuo.core.pojo.node.LoginMenuTreeNode; import vip.xiaonuo.core.tenant.consts.TenantConstants; import vip.xiaonuo.core.tenant.context.TenantCodeHolder; import vip.xiaonuo.core.tenant.context.TenantDbNameHolder; @@ -44,12 +46,16 @@ import vip.xiaonuo.core.util.IpAddressUtil; import vip.xiaonuo.core.util.UaUtil; import vip.xiaonuo.sys.modular.app.service.SysAppService; import vip.xiaonuo.sys.modular.emp.service.SysEmpService; +import vip.xiaonuo.sys.modular.menu.entity.SysMenu; import vip.xiaonuo.sys.modular.menu.service.SysMenuService; +import vip.xiaonuo.sys.modular.role.service.SysRoleMenuService; import vip.xiaonuo.sys.modular.role.service.SysRoleService; import vip.xiaonuo.sys.modular.user.service.SysUserService; import javax.servlet.http.HttpServletRequest; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 登录用户工厂类 @@ -69,6 +75,8 @@ public class LoginUserFactory { private static final SysRoleService sysRoleService = SpringUtil.getBean(SysRoleService.class); + private static final SysRoleMenuService sysRoleMenuService = SpringUtil.getBean(SysRoleMenuService.class); + /** * 填充登录用户相关信息 * @@ -93,8 +101,14 @@ public class LoginUserFactory { List roles = sysRoleService.getLoginRoles(userId); sysLoginUser.setRoles(roles); + // 获取角色id集合 + List roleIdList = roles.stream().map(dict -> Convert.toLong(dict.get(CommonConstant.ID))).collect(Collectors.toList()); + + // 获取菜单id集合 + List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); + // 权限信息 - List permissions = sysMenuService.getLoginPermissions(userId); + List permissions = sysMenuService.getLoginPermissions(userId, menuIdList); sysLoginUser.setPermissions(permissions); // 数据范围信息 @@ -102,7 +116,7 @@ public class LoginUserFactory { sysLoginUser.setDataScopes(dataScopes); // 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统 - List apps = sysAppService.getLoginApps(userId); + List apps = sysAppService.getLoginApps(userId, roleIdList); sysLoginUser.setApps(apps); // 如果根本没有应用信息,则没有菜单信息 @@ -111,7 +125,11 @@ public class LoginUserFactory { } else { //AntDesign菜单信息,根据人获取,用于登录后展示菜单树,默认获取默认激活的系统的菜单 String defaultActiveAppCode = apps.get(0).getStr(CommonConstant.CODE); - sysLoginUser.setMenus(sysMenuService.getLoginMenusAntDesign(userId, defaultActiveAppCode)); + List loginMenus = sysMenuService.getLoginMenus(userId, defaultActiveAppCode, menuIdList); + Map> collect = loginMenus.stream().collect(Collectors.groupingBy(SysMenu::getApplication)); + List tempList = collect.get(defaultActiveAppCode); + List loginMenuTreeNodes = sysMenuService.convertSysMenuToLoginMenu(tempList); + sysLoginUser.setMenus(loginMenuTreeNodes); } //如果开启了多租户功能,则设置当前登录用户的租户标识 diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/controller/SysMenuController.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/controller/SysMenuController.java index e72e9737..9fdbf495 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/controller/SysMenuController.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/controller/SysMenuController.java @@ -28,8 +28,10 @@ import vip.xiaonuo.core.annotion.BusinessLog; import vip.xiaonuo.core.annotion.Permission; import vip.xiaonuo.core.context.login.LoginContextHolder; import vip.xiaonuo.core.enums.LogAnnotionOpTypeEnum; +import vip.xiaonuo.core.pojo.node.LoginMenuTreeNode; import vip.xiaonuo.core.pojo.response.ResponseData; import vip.xiaonuo.core.pojo.response.SuccessResponseData; +import vip.xiaonuo.sys.modular.menu.entity.SysMenu; import vip.xiaonuo.sys.modular.menu.param.SysMenuParam; import vip.xiaonuo.sys.modular.menu.service.SysMenuService; import org.springframework.validation.annotation.Validated; @@ -37,8 +39,11 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import vip.xiaonuo.sys.modular.role.service.SysRoleMenuService; +import vip.xiaonuo.sys.modular.user.service.SysUserRoleService; import javax.annotation.Resource; +import java.util.List; /** * 系统菜单控制器 @@ -52,6 +57,12 @@ public class SysMenuController { @Resource private SysMenuService sysMenuService; + @Resource + private SysRoleMenuService sysRoleMenuService; + + @Resource + private SysUserRoleService sysUserRoleService; + /** * 系统菜单列表(树) * @@ -156,6 +167,11 @@ public class SysMenuController { @BusinessLog(title = "系统菜单_切换", opType = LogAnnotionOpTypeEnum.TREE) public ResponseData change(@RequestBody @Validated(SysMenuParam.change.class) SysMenuParam sysMenuParam) { Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId(); - return new SuccessResponseData(sysMenuService.getLoginMenusAntDesign(sysLoginUserId, sysMenuParam.getApplication())); + List userRoleIdList = sysUserRoleService.getUserRoleIdList(sysLoginUserId); + List menuIdList = sysRoleMenuService.getRoleMenuIdList(userRoleIdList); + //转换成登录菜单 + List sysMenuList = sysMenuService.getLoginMenus(sysLoginUserId, sysMenuParam.getApplication(), menuIdList); + List menuTreeNodeList = sysMenuService.convertSysMenuToLoginMenu(sysMenuList); + return new SuccessResponseData(menuTreeNodeList); } } diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/SysMenuService.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/SysMenuService.java index d300a499..94c48fb6 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/SysMenuService.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/SysMenuService.java @@ -44,32 +44,35 @@ public interface SysMenuService extends IService { * 获取用户权限相关信息 * * @param userId 用户id + * @param menuIdList 菜单id集合 * @return 权限集合 * @author xuyuxiang * @date 2020/3/13 16:26 */ - List getLoginPermissions(Long userId); + List getLoginPermissions(Long userId, List menuIdList); /** * 获取用户AntDesign菜单相关信息,前端使用 * * @param userId 用户id * @param appCode 应用编码 + * @param menuIdList 菜单id集合 * @return AntDesign菜单信息结果集 * @author yubaoshan * @date 2020/4/17 17:48 */ - List getLoginMenusAntDesign(Long userId, String appCode); + List getLoginMenus(Long userId, String appCode, List menuIdList); /** * 获取用户菜单所属的应用编码集合 * * @param userId 用户id + * @param roleIdList 角色id集合 * @return 用户菜单所属的应用编码集合 * @author xuyuxiang * @date 2020/3/21 11:01 */ - List getUserMenuAppCodeList(Long userId); + List getUserMenuAppCodeList(Long userId, List roleIdList); /** * 系统菜单列表(树表) @@ -147,4 +150,14 @@ public interface SysMenuService extends IService { * @date 2020/6/28 12:14 */ boolean hasMenu(String appCode); + + /** + * 将SysMenu格式菜单转换为LoginMenuTreeNode菜单 + * + * @author xuyuxiang + * @date 2021/6/29 13:43 + * @param sysMenuList 原始菜单集合 + * @return LoginMenuTreeNode菜单集合 + */ + List convertSysMenuToLoginMenu(List sysMenuList); } diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java index 0874b089..cac69130 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/menu/service/impl/SysMenuServiceImpl.java @@ -27,6 +27,7 @@ package vip.xiaonuo.sys.modular.menu.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -59,6 +60,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * 系统菜单service接口实现类 @@ -83,26 +85,28 @@ public class SysMenuServiceImpl extends ServiceImpl impl private ResourceCache resourceCache; @Override - public List getLoginPermissions(Long userId) { + public List getLoginPermissions(Long userId, List menuIdList) { Set permissions = CollectionUtil.newHashSet(); - List roleIdList = sysUserRoleService.getUserRoleIdList(userId); - if (ObjectUtil.isNotEmpty(roleIdList)) { - List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); - if (ObjectUtil.isNotEmpty(menuIdList)) { - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (ObjectUtil.isNotEmpty(menuIdList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysMenu::getId, menuIdList).ne(SysMenu::getType, MenuTypeEnum.DIR.getCode()) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); - queryWrapper.in(SysMenu::getId, menuIdList).eq(SysMenu::getType, MenuTypeEnum.BTN.getCode()) - .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); - - this.list(queryWrapper).forEach(sysMenu -> permissions.add(sysMenu.getPermission())); - } + this.list(queryWrapper).forEach(sysMenu -> { + if(MenuTypeEnum.BTN.getCode().equals(sysMenu.getType())) { + permissions.add(sysMenu.getPermission()); + } else { + String removePrefix = StrUtil.removePrefix(sysMenu.getRouter(), SymbolConstant.LEFT_DIVIDE); + String permission = removePrefix.replaceAll(SymbolConstant.LEFT_DIVIDE, SymbolConstant.COLON); + permissions.add(permission); + } + }); } return CollectionUtil.newArrayList(permissions); } @Override - public List getLoginMenusAntDesign(Long userId, String appCode) { - List sysMenuList; + public List getLoginMenus(Long userId, String appCode, List menuIdList) { //如果是超级管理员则展示所有系统权重菜单,不能展示业务权重菜单 SysUser sysUser = sysUserService.getById(userId); Integer adminType = sysUser.getAdminType(); @@ -120,29 +124,19 @@ public class SysMenuServiceImpl extends ServiceImpl impl } else { //非超级管理员则获取自己角色所拥有的菜单集合 - List roleIdList = sysUserRoleService.getUserRoleIdList(userId); - if (ObjectUtil.isNotEmpty(roleIdList)) { - List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); - if (ObjectUtil.isNotEmpty(menuIdList)) { - queryWrapper.in(SysMenu::getId, menuIdList) - .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) - .eq(SysMenu::getApplication, appCode) - .notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) - .orderByAsc(SysMenu::getSort); - - } else { - //如果角色的菜单为空,则查不到菜单 - return CollectionUtil.newArrayList(); - } + if (ObjectUtil.isNotEmpty(menuIdList)) { + queryWrapper.in(SysMenu::getId, menuIdList) + .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) + .eq(SysMenu::getApplication, appCode) + .notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) + .orderByAsc(SysMenu::getSort); } else { - //如果角色为空,则根本没菜单 + //如果角色的菜单为空,则查不到菜单 return CollectionUtil.newArrayList(); } } //查询列表 - sysMenuList = this.list(queryWrapper); - //转换成登录菜单 - return this.convertSysMenuToLoginMenu(sysMenuList); + return this.list(queryWrapper); } /** @@ -151,7 +145,8 @@ public class SysMenuServiceImpl extends ServiceImpl impl * @author xuyuxiang * @date 2020/4/17 17:53 */ - private List convertSysMenuToLoginMenu(List sysMenuList) { + @Override + public List convertSysMenuToLoginMenu(List sysMenuList) { List antDesignMenuTreeNodeList = CollectionUtil.newArrayList(); sysMenuList.forEach(sysMenu -> { LoginMenuTreeNode loginMenuTreeNode = new LoginMenuTreeNode(); @@ -182,9 +177,8 @@ public class SysMenuServiceImpl extends ServiceImpl impl } @Override - public List getUserMenuAppCodeList(Long userId) { + public List getUserMenuAppCodeList(Long userId, List roleIdList) { Set appCodeSet = CollectionUtil.newHashSet(); - List roleIdList = sysUserRoleService.getUserRoleIdList(userId); if (ObjectUtil.isNotEmpty(roleIdList)) { List menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); @@ -193,8 +187,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(SysMenu::getId, menuIdList) .eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); - - this.list(queryWrapper).forEach(sysMenu -> appCodeSet.add(sysMenu.getApplication())); + appCodeSet = this.list(queryWrapper).stream().map(SysMenu::getApplication).collect(Collectors.toSet()); } } diff --git a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java index e960e69e..d0c16938 100644 --- a/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java +++ b/snowy-base/snowy-system/src/main/java/vip/xiaonuo/sys/modular/role/service/impl/SysRoleServiceImpl.java @@ -55,6 +55,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * 系统角色service接口实现类 @@ -86,13 +87,13 @@ public class SysRoleServiceImpl extends ServiceImpl impl LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(SysRole::getId, roleIdList).eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode()); //根据角色id集合查询并返回结果 - this.list(queryWrapper).forEach(sysRole -> { + dictList = this.list(queryWrapper).stream().map(sysRole -> { Dict dict = Dict.create(); dict.put(CommonConstant.ID, sysRole.getId()); dict.put(CommonConstant.CODE, sysRole.getCode()); dict.put(CommonConstant.NAME, sysRole.getName()); - dictList.add(dict); - }); + return dict; + }).collect(Collectors.toList()); } return dictList; }