/** * BladeX Commercial License Agreement * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. *

* Use of this software is governed by the Commercial License Agreement * obtained after purchasing a license from BladeX. *

* 1. This software is for development use only under a valid license * from BladeX. *

* 2. Redistribution of this software's source code to any third party * without a commercial license is strictly prohibited. *

* 3. Licensees may copyright their own code but cannot use segments * from this software for such purposes. Copyright of this software * remains with BladeX. *

* Using this software signifies agreement to this License, and the software * must not be used for illegal purposes. *

* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is * not liable for any claims arising from secondary or illegal development. *

* Author: Chill Zhuang (bladejava@qq.com) */ package com.nov.KgLowDurable.service.Impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.nov.KgLowDurable.common.TreeNode; import com.nov.KgLowDurable.exception.ServiceException; import com.nov.KgLowDurable.mapper.MenuMapper; import com.nov.KgLowDurable.pojo.dto.MenuDTO; import com.nov.KgLowDurable.pojo.entity.*; import com.nov.KgLowDurable.pojo.vo.MenuVO; import com.nov.KgLowDurable.service.IMenuService; import com.nov.KgLowDurable.service.IRoleMenuService; import com.nov.KgLowDurable.service.IRoleService; import com.nov.KgLowDurable.service.ITopMenuSettingService; import com.nov.KgLowDurable.util.*; import com.nov.KgLowDurable.wrapper.MenuWrapper; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; import static com.nov.KgLowDurable.util.StringUtils.isEmpty; import static com.nov.KgLowDurable.util.StringUtils.isNotBlank; /** * 服务实现类 * * @author Chill */ //@Master @Service @AllArgsConstructor public class MenuServiceImpl extends ServiceImpl implements IMenuService { private final IRoleMenuService roleMenuService; //private final IRoleScopeService roleScopeService; private final ITopMenuSettingService topMenuSettingService; private final IRoleService roleService; private final static String PARENT_ID = "parentId"; private final static Integer MENU_CATEGORY = 1; @Override public List lazyList(Long parentId, Map param) { if (isEmpty(Func.toStr(param.get(PARENT_ID)))) { parentId = null; } return baseMapper.lazyList(parentId, param); } @Override public List lazyMenuList(Long parentId, Map param) { if (isEmpty(Func.toStr(param.get(PARENT_ID)))) { parentId = null; } return baseMapper.lazyMenuList(parentId, param); } @Override public List routes(String roleId, Long topMenuId) { // if (StringUtils.isBlank(roleId)) { // return null; // } List

allMenus = baseMapper.allMenu(); List roleMenus = null; Role role=roleService.getById(roleId); // 超级管理员并且不是顶部菜单请求则返回全部菜单 if (Func.isEmpty(topMenuId)) { roleMenus = allMenus; } // 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单 else if (role!=null&&!role.getName().equals("超级管理员")&&Func.isEmpty(topMenuId)) { // 角色配置对应菜单 List roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId)); // 反向递归角色菜单所有父级 List routes = new LinkedList<>(roleIdMenus); roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu)); roleMenus = tenantPackageMenu(routes); } // 顶部菜单请求返回对应角色权限菜单 else { // 角色配置对应菜单 List roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId)); // 反向递归角色菜单所有父级 List routes = new LinkedList<>(roleIdMenus); roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu)); // 顶部配置对应菜单 List topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId); // 筛选匹配角色对应的权限菜单 roleMenus = tenantPackageMenu(topIdMenus.stream().filter(x -> routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue()) ).collect(Collectors.toList())); } return buildRoutes(allMenus, roleMenus); } @Override public List routesExt(String roleId, Long topMenuId) { if (StringUtils.isBlank(roleId)) { return null; } List allMenus = baseMapper.allMenuExt(); List roleMenus = baseMapper.roleMenuExt(Func.toLongList(roleId), topMenuId); return buildRoutes(allMenus, roleMenus); } private List buildRoutes(List allMenus, List roleMenus) { List routes = new LinkedList<>(roleMenus); roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu)); routes.sort(Comparator.comparing(Menu::getSort)); MenuWrapper menuWrapper = new MenuWrapper(); List collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList()); return menuWrapper.listNodeVO(collect); } private void recursion(List allMenus, List routes, Menu roleMenu) { Optional menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst(); if (menu.isPresent() && !routes.contains(menu.get())) { routes.add(menu.get()); recursion(allMenus, routes, menu.get()); } } @Override public List buttons(String roleId) { List buttons = StringUtils.isEmpty(roleId) ? baseMapper.allButtons() : baseMapper.buttons(Func.toLongList(roleId)); MenuWrapper menuWrapper = new MenuWrapper(); return menuWrapper.listNodeVO(buttons); } @Override public List tree() { return ForestNodeMerger.merge(baseMapper.tree()); } @Override public List grantTree(String roleId) { List menuTree = baseMapper.grantTreeByRole(Func.toLongList(roleId));//Func.toLongList(user.getRoleId()) return ForestNodeMerger.merge(menuTree); } @Override public List grantTopTree(String roleId) { List menuTree = StringUtils.isEmpty(roleId)? baseMapper.grantTopTree() : baseMapper.grantTopTreeByRole(Func.toLongList(roleId)); return ForestNodeMerger.merge(menuTree); } /** * 租户菜单权限自定义筛选 */ // private List tenantPackageTree(List menuTree, String tenantId) { // TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId); // if (isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) { // List menuIds = Func.toLongList(tenantPackage.getMenuId()); // // 筛选出两者菜单交集集合 // List collect = menuTree.stream().filter(x -> menuIds.contains(x.getId())).toList(); // // 创建递归基础集合 // List packageTree = new LinkedList<>(collect); // // 递归筛选出菜单集合所有父级 // collect.forEach(treeNode -> recursionParent(menuTree, packageTree, treeNode)); // // 递归筛选出菜单集合所有子级 // collect.forEach(treeNode -> recursionChild(menuTree, packageTree, treeNode)); // // 合并在一起返回最终集合 // return packageTree; // //} // return menuTree; // } /** * 父节点递归 */ public void recursionParent(List menuTree, List packageTree, TreeNode treeNode) { Optional node = menuTree.stream().filter(x -> Func.equals(x.getId(), treeNode.getParentId())).findFirst(); if (node.isPresent() && !packageTree.contains(node.get())) { packageTree.add(node.get()); recursionParent(menuTree, packageTree, node.get()); } } /** * 子节点递归 */ public void recursionChild(List menuTree, List packageTree, TreeNode treeNode) { List nodes = menuTree.stream().filter(x -> Func.equals(x.getParentId(), treeNode.getId())).collect(Collectors.toList()); nodes.forEach(node -> { if (!packageTree.contains(node)) { packageTree.add(node); recursionChild(menuTree, packageTree, node); } }); } /** * 租户菜单权限自定义筛选 */ private List tenantPackageMenu(List menu) { // TenantPackage tenantPackage = SysCache.getTenantPackage(AuthUtil.getTenantId()); // if (Func.isNotEmpty(tenantPackage) && Func.isNotEmpty(tenantPackage.getId()) && tenantPackage.getId() > 0L) { // List menuIds = Func.toLongList(tenantPackage.getMenuId()); // menu = menu.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList()); // } return menu; } // @Override // public List grantDataScopeTree(BladeUser user) { // return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId()))); // } // @Override // public List grantApiScopeTree(BladeUser user) { // return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId()))); // } @Override public List roleTreeKeys(String roleIds) { List roleMenus = roleMenuService.list(Wrappers.query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds))); return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList()); } @Override public List topTreeKeys(String topMenuIds) { List settings = topMenuSettingService.list(Wrappers.query().lambda().in(TopMenuSetting::getTopMenuId, Func.toLongList(topMenuIds))); return settings.stream().map(setting -> Func.toStr(setting.getMenuId())).collect(Collectors.toList()); } // @Override // public List dataScopeTreeKeys(String roleIds) { // List roleScopes = roleScopeService.list(Wrappers.query().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds))); // return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList()); // } // @Override // public List apiScopeTreeKeys(String roleIds) { // List roleScopes = roleScopeService.list(Wrappers.query().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds))); // return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList()); // } @Override public List authRoutes(String roleId) { List routes = baseMapper.authRoutes(Func.toLongList(roleId)); List list = new ArrayList<>(); routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias()))))); return list; } @Override public boolean removeMenu(String ids) { Integer cnt = baseMapper.selectCount(Wrappers.query().lambda().in(Menu::getParentId, Func.toLongList(ids))); if (cnt > 0L) { throw new ServiceException("请先删除子节点!"); } return removeByIds(Func.toLongList(ids)); } @Override public boolean submit(Menu menu) { boolean isNewMenu = menu.getId() == null; // 验证code和name唯一性 LambdaQueryWrapper menuQueryWrapper = Wrappers.lambdaQuery() .and(!isNewMenu, w -> w.ne(Menu::getId, menu.getId())) .and(w -> w.eq(Menu::getCode, menu.getCode()) .or(o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY))); if (baseMapper.selectCount(menuQueryWrapper) > 0L) { throw new ServiceException("菜单名或编号已存在!"); } // 验证path唯一性 if (isNotBlank(menu.getPath())) { LambdaQueryWrapper pathQueryWrapper = Wrappers.lambdaQuery() .eq(Menu::getPath, menu.getPath()) .ne(!isNewMenu, Menu::getId, menu.getId()); if (baseMapper.selectCount(pathQueryWrapper) > 0L) { throw new ServiceException("菜单路径已存在!"); } } // 处理父节点 if (menu.getParentId() == null) { menu.setParentId(BladeConstant.TOP_PARENT_ID); } // 验证父节点类型(新增或父节点变更时) if (isNewMenu || menu.getParentId() != null) { Menu parentMenu = baseMapper.selectById(menu.getParentId()); if (parentMenu != null && parentMenu.getCategory() != 1) { throw new ServiceException("父节点只可选择菜单类型!"); } } menu.setIsDeleted(BladeConstant.DB_NOT_DELETED); return saveOrUpdate(menu); } @Override public List grantTreeALL() { List menuTree = baseMapper.grantTreeByRoleALL();//Func.toLongList(user.getRoleId()) return ForestNodeMerger.merge(menuTree); } }