package com.ruoyi.system.service.impl;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.vo.MetaVo;
import com.ruoyi.system.domain.vo.RouterVo;
import com.ruoyi.system.mapper.SysMenuMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* èœå• 业务层处ç†
*
* @author Lion Li
*/
@Service
public class SysMenuServiceImpl extends ServicePlusImpl<SysMenuMapper, SysMenu, SysMenu> implements ISysMenuService {
@Autowired
private SysRoleMapper roleMapper;
@Autowired
private SysRoleMenuMapper roleMenuMapper;
/**
* æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
*
* @param userId 用户ID
* @return èœå•列表
*/
@Override
public List<SysMenu> selectMenuList(Long userId) {
return selectMenuList(new SysMenu(), userId);
}
/**
* 查询系统èœå•列表
*
* @param menu èœå•ä¿¡æ¯
* @return èœå•列表
*/
@Override
public List<SysMenu> selectMenuList(SysMenu menu, Long userId) {
List<SysMenu> menuList = null;
// 管ç†å‘˜æ˜¾ç¤ºæ‰€æœ‰èœå•ä¿¡æ¯
if (SysUser.isAdmin(userId)) {
menuList = list(new LambdaQueryWrapper<SysMenu>()
.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum));
} else {
menu.getParams().put("userId", userId);
menuList = baseMapper.selectMenuListByUserId(menu);
}
return menuList;
}
/**
* æ ¹æ®ç”¨æˆ·ID查询æƒé™
*
* @param userId 用户ID
* @return æƒé™åˆ—表
*/
@Override
public Set<String> selectMenuPermsByUserId(Long userId) {
List<String> perms = baseMapper.selectMenuPermsByUserId(userId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/**
* æ ¹æ®ç”¨æˆ·ID查询èœå•
*
* @param userId 用户åç§°
* @return èœå•列表
*/
@Override
public List<SysMenu> selectMenuTreeByUserId(Long userId) {
List<SysMenu> menus = null;
if (SecurityUtils.isAdmin(userId)) {
menus = baseMapper.selectMenuTreeAll();
} else {
menus = baseMapper.selectMenuTreeByUserId(userId);
}
return getChildPerms(menus, 0);
}
/**
* æ ¹æ®è§’色ID查询èœå•æ ‘ä¿¡æ¯
*
* @param roleId 角色ID
* @return 选ä¸èœå•列表
*/
@Override
public List<Long> selectMenuListByRoleId(Long roleId) {
SysRole role = roleMapper.selectById(roleId);
return baseMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly());
}
/**
* 构建å‰ç«¯è·¯ç”±æ‰€éœ€è¦çš„èœå•
*
* @param menus èœå•列表
* @return 路由列表
*/
@Override
public List<RouterVo> buildMenus(List<SysMenu> menus) {
List<RouterVo> routers = new LinkedList<RouterVo>();
for (SysMenu menu : menus) {
RouterVo router = new RouterVo();
router.setHidden("1".equals(menu.getVisible()));
router.setName(getRouteName(menu));
router.setPath(getRouterPath(menu));
router.setComponent(getComponent(menu));
router.setQuery(menu.getQuery());
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
List<SysMenu> cMenus = (List<SysMenu>) menu.getChildren();
if (!cMenus.isEmpty() && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
router.setAlwaysShow(true);
router.setRedirect("noRedirect");
router.setChildren(buildMenus(cMenus));
} else if (isMenuFrame(menu)) {
router.setMeta(null);
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
children.setPath(menu.getPath());
children.setComponent(menu.getComponent());
children.setName(StringUtils.capitalize(menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQuery());
childrenList.add(children);
router.setChildren(childrenList);
} else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/inner");
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
String routerPath = StringUtils.replaceEach(menu.getPath(), new String[]{Constants.HTTP, Constants.HTTPS}, new String[]{"", ""});
children.setPath(routerPath);
children.setComponent(UserConstants.INNER_LINK);
children.setName(StringUtils.capitalize(routerPath));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
childrenList.add(children);
router.setChildren(childrenList);
}
routers.add(router);
}
return routers;
}
/**
* 构建å‰ç«¯æ‰€éœ€è¦ä¸‹æ‹‰æ ‘结构
*
* @param menus èœå•列表
* @return ä¸‹æ‹‰æ ‘ç»“æž„åˆ—è¡¨
*/
@Override
public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
return TreeBuildUtils.build(menus, (menu, tree) ->
tree.setId(menu.getMenuId())
.setParentId(menu.getParentId())
.setName(menu.getMenuName())
.setWeight(menu.getOrderNum()));
}
/**
* æ ¹æ®èœå•ID查询信æ¯
*
* @param menuId èœå•ID
* @return èœå•ä¿¡æ¯
*/
@Override
public SysMenu selectMenuById(Long menuId) {
return getById(menuId);
}
/**
* 是å¦å˜åœ¨èœå•å节点
*
* @param menuId èœå•ID
* @return 结果
*/
@Override
public boolean hasChildByMenuId(Long menuId) {
long result = count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
return result > 0;
}
/**
* 查询èœå•使用数é‡
*
* @param menuId èœå•ID
* @return 结果
*/
@Override
public boolean checkMenuExistRole(Long menuId) {
long result = roleMenuMapper.selectCount(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
return result > 0;
}
/**
* 新增ä¿å˜èœå•ä¿¡æ¯
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
@Override
public int insertMenu(SysMenu menu) {
return baseMapper.insert(menu);
}
/**
* 修改ä¿å˜èœå•ä¿¡æ¯
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
@Override
public int updateMenu(SysMenu menu) {
return baseMapper.updateById(menu);
}
/**
* åˆ é™¤èœå•管ç†ä¿¡æ¯
*
* @param menuId èœå•ID
* @return 结果
*/
@Override
public int deleteMenuById(Long menuId) {
return baseMapper.deleteById(menuId);
}
/**
* æ ¡éªŒèœå•å称是å¦å”¯ä¸€
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
@Override
public String checkMenuNameUnique(SysMenu menu) {
Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
long count = count(new LambdaQueryWrapper<SysMenu>()
.eq(SysMenu::getMenuName, menu.getMenuName())
.eq(SysMenu::getParentId, menu.getParentId())
.ne(SysMenu::getMenuId, menuId));
if (count > 0) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
}
/**
* 获å–路由åç§°
*
* @param menu èœå•ä¿¡æ¯
* @return 路由åç§°
*/
public String getRouteName(SysMenu menu) {
String routerName = StringUtils.capitalize(menu.getPath());
// éžå¤–链并且是一级目录(类型为目录)
if (isMenuFrame(menu)) {
routerName = StringUtils.EMPTY;
}
return routerName;
}
/**
* 获å–路由地å€
*
* @param menu èœå•ä¿¡æ¯
* @return 路由地å€
*/
public String getRouterPath(SysMenu menu) {
String routerPath = menu.getPath();
// 内链打开外网方å¼
if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
routerPath = StringUtils.replaceEach(routerPath, new String[]{Constants.HTTP, Constants.HTTPS}, new String[]{"", ""});
}
// éžå¤–链并且是一级目录(类型为目录)
if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
&& UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
routerPath = "/" + menu.getPath();
}
// éžå¤–链并且是一级目录(类型为èœå•)
else if (isMenuFrame(menu)) {
routerPath = "/";
}
return routerPath;
}
/**
* 获å–组件信æ¯
*
* @param menu èœå•ä¿¡æ¯
* @return 组件信æ¯
*/
public String getComponent(SysMenu menu) {
String component = UserConstants.LAYOUT;
if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
component = menu.getComponent();
} else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
component = UserConstants.INNER_LINK;
} else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
component = UserConstants.PARENT_VIEW;
}
return component;
}
/**
* 是å¦ä¸ºèœå•内部跳转
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
public boolean isMenuFrame(SysMenu menu) {
return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
}
/**
* 是å¦ä¸ºå†…链组件
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
public boolean isInnerLink(SysMenu menu) {
return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
}
/**
* 是å¦ä¸ºparent_view组件
*
* @param menu èœå•ä¿¡æ¯
* @return 结果
*/
public boolean isParentView(SysMenu menu) {
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
}
/**
* æ ¹æ®çˆ¶èŠ‚ç‚¹çš„IDèŽ·å–æ‰€æœ‰å节点
*
* @param list 分类表
* @param parentId ä¼ å…¥çš„çˆ¶èŠ‚ç‚¹ID
* @return String
*/
public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
List<SysMenu> returnList = new ArrayList<SysMenu>();
for (SysMenu t : list) {
// ä¸€ã€æ ¹æ®ä¼ 入的æŸä¸ªçˆ¶èŠ‚ç‚¹ID,é历该父节点的所有å节点
if (t.getParentId() == parentId) {
recursionFn(list, t);
returnList.add(t);
}
}
return returnList;
}
/**
* 递归列表
*
* @param list
* @param t
*/
private void recursionFn(List<SysMenu> list, SysMenu t) {
// 得到å节点列表
List<SysMenu> childList = getChildList(list, t);
t.setChildren(childList);
for (SysMenu tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 得到å节点列表
*/
private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
List<SysMenu> tlist = new ArrayList<SysMenu>();
for (SysMenu n : list) {
if (n.getParentId().longValue() == t.getMenuId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
/**
* åˆ¤æ–æ˜¯å¦æœ‰å节点
*/
private boolean hasChild(List<SysMenu> list, SysMenu t) {
return getChildList(list, t).size() > 0;
}
}