通过用户id查询并构建菜单树

master
GPU is all you need 4 years ago
parent 1c78633919
commit 449c979f36
  1. 315
      awardBE/src/main/java/edu/ncst/award/service/impl/system/MenuServiceImpl.java

@ -1,25 +1,14 @@
package edu.ncst.award.service.impl.system;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ncst.award.exception.BusinessException;
import edu.ncst.award.exception.CodeMsg;
import edu.ncst.award.common.util.treeUtils.TreeUtils;
import edu.ncst.award.mapper.system.MenuMapper;
import edu.ncst.award.model.system.Menu;
import edu.ncst.award.model.system.Role;
import edu.ncst.award.service.IMenuService;
import edu.ncst.award.utils.SessionUtils;
import edu.ncst.award.vo.ListResultVO;
import edu.ncst.award.vo.Query;
import edu.ncst.award.vo.param.ResetMenuDTO;
import edu.ncst.award.vo.result.UserInfoVO;
import edu.ncst.award.vo.RouterVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
@ -29,292 +18,48 @@ import java.util.stream.Collectors;
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
private final MenuMapper menuMapper;
@Autowired
private SqlSession sqlSession;
public MenuServiceImpl(MenuMapper menuMapper) {
this.menuMapper = menuMapper;
}
// 获取菜单列表
@Override
public ListResultVO<Menu> getMenuList(Query query) {
QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
Page<Menu> pageRequest = query.toPageRequest();
Page<Menu> page = menuMapper.getMenuList(pageRequest, null);
// 封装返回结果
ListResultVO<Menu> listResultVO = new ListResultVO<>();
listResultVO.setList(page.getRecords());
listResultVO.setTotal(page.getTotal());
listResultVO.setCurrent(page.getCurrent());
return listResultVO;
}
// 获取菜单详情
@Override
public Menu getMenuDetail(Integer id) {
Menu menu = menuMapper.selectById(id);
return menu;
}
// 添加菜单
@Transactional
@Override
public Menu addMenu(Menu menu) {
int insert = menuMapper.insert(menu);
Menu result = getMenuDetail(menu.getId());
if (insert == 1) {
return result;
} else {
throw new BusinessException(CodeMsg.ADD_ERROR);
}
}
// 修改菜单
@Transactional
@Override
public Menu modifyMenu(Menu menu) {
int update = menuMapper.updateById(menu);
Menu result = getMenuDetail(menu.getId());
if (update == 1) {
return result;
} else {
throw new BusinessException(CodeMsg.MODIFY_ERROR);
}
}
// 删除菜单
@Transactional
@Override
public boolean deleteMenu(Integer id) {
int delete = menuMapper.deleteById(id);
if (delete == 1) {
return true;
} else {
throw new BusinessException(CodeMsg.DELETE_ERROR);
}
}
/**
* 导入菜单
* 说明该操作会将原有的菜单元信息全部清空然后再导入新的菜单元信息
* @param resetMenuDTO 重置菜单表单
*/
@Transactional
@Override
public void resetMenuMeta(ResetMenuDTO resetMenuDTO) {
List<Menu> oldTree = getMenuTree();
List<Menu> newTree = resetMenuDTO.getMenus();
Map<String, Menu> waitDeleteMap = new HashMap<>();
findWaitDeleteMenu(oldTree, newTree, waitDeleteMap);
diffMenuMeta(oldTree, newTree, waitDeleteMap, null);
// 批量删除不存在的菜单
Collection<Menu> deleteMenus = waitDeleteMap.values();
List<Integer> menuIds = deleteMenus.stream().map(Menu::getId).collect(Collectors.toList());
if (!menuIds.isEmpty()) {
menuMapper.deleteBatchIds(menuIds);
}
}
private void findWaitDeleteMenu(List<Menu> oldTree, List<Menu> newTree, Map<String, Menu> waitDeleteMap) {
HashMap<String, Menu> newMenuMap = new HashMap<>();
for (Menu menu : newTree) {
newMenuMap.put(menu.getName(), menu);
}
// 旧菜单列表存在 但 新菜单列表不存在 加入到待删除列表(旧有新无)
for (Menu oldMenu : oldTree) {
String key = oldMenu.getName();
if (!newMenuMap.containsKey(key)) {
waitDeleteMap.put(key, oldMenu);
} else {
Menu newMenu = newMenuMap.get(key);
List<Menu> children = newMenu.getChildren();
if (children != null && children.size() > 0) {
findWaitDeleteMenu(oldMenu.getChildren(), children, waitDeleteMap);
}
}
}
}
private void diffMenuMeta(List<Menu> oldTree, List<Menu> newTree, Map<String, Menu> waitDeleteMap, Integer parentId) {
if (oldTree == null || newTree == null) return;
HashMap<String, Menu> oldMenuMap = new HashMap<>();
for (Menu menu : oldTree) {
oldMenuMap.put(menu.getName(), menu);
}
// 遍历新菜单列表
for (Menu newMenu : newTree) {
List<Menu> children = newMenu.getChildren();
List<Menu> oldChildren = new ArrayList<>();
String key = newMenu.getName();
log.info(newMenu.toString());
log.info(key);
Integer menuId;
if (newMenu.getName() == null || "".equals(newMenu.getName())) {
continue;
}
if (oldMenuMap.containsKey(key)) {
// 旧菜单列表存在 且 新菜单列表存在 执行更新操作(旧有新有)
Menu oldMenu = oldMenuMap.get(key);
oldChildren = oldMenu.getChildren();
menuId = oldMenu.getId();
// 更新旧菜单数据
BeanUtils.copyProperties(newMenu, oldMenu,"id", "children");
oldMenu.setParentId(parentId);
// 属性完全相同(除ID,新菜单没有ID可以进行比较)时没有必要进行更新操作
if (!isMenuEquals(oldMenu, newMenu)) {
menuMapper.updateById(oldMenu);
}
} else if (waitDeleteMap.containsKey(key)) {
Menu oldMenu = waitDeleteMap.remove(key);
oldChildren = oldMenu.getChildren();
menuId = oldMenu.getId();
// 更新旧菜单数据
BeanUtils.copyProperties(newMenu, oldMenu, "id", "children");
oldMenu.setParentId(parentId);
if (!isMenuEquals(oldMenu, newMenu)) {
menuMapper.updateById(oldMenu);
}
} else {
log.info(newMenu.toString());
// 旧菜单列表不存在 但 新菜单列表存在 执行插入操作(旧无新有)
newMenu.setParentId(parentId);
menuMapper.insert(newMenu);
menuId = newMenu.getId();
}
if (children != null && children.size() > 0) {
diffMenuMeta(oldChildren, children, waitDeleteMap, menuId);
}
}
}
/**
* 判断两个菜单中的字段是否相等
*/
private boolean isMenuEquals(Menu oldMenu, Menu newMenu) {
if (oldMenu == null && newMenu == null) {
return true;
} else if (oldMenu == null || newMenu == null) {
return false;
}
return Objects.equals(oldMenu.getName(), newMenu.getName()) &&
Objects.equals(oldMenu.getTitle(), newMenu.getTitle()) &&
Objects.equals(oldMenu.getIcon(), newMenu.getIcon()) &&
Objects.equals(oldMenu.getUrl(), newMenu.getUrl()) &&
Objects.equals(oldMenu.getShowInMenu(), newMenu.getShowInMenu()) &&
Objects.equals(oldMenu.getParentId(), newMenu.getParentId()) &&
Objects.equals(oldMenu.getSort(), newMenu.getSort()) &&
Objects.equals(oldMenu.getRemark(), newMenu.getRemark());
}
/**
* 获取菜单树
* @return 菜单树
*/
@Override
public List<Menu> getMenuTree() {
return menuMapper.getMenuTree(null);
}
/**
* 获取当前菜单树
* @return 菜单树
* 获取当前用户能够访问的路由菜单列表
*
* @param userId 用户id
* @return
*/
@Override
public List<Menu> getCurrentUserMenuTree() {
UserInfoVO userInfoVO = SessionUtils.getCurrentUser();
List<Role> roles = userInfoVO.getRoles();
Set<Integer> allowMenuIdSet = new HashSet<>();
if (roles != null) {
for (Role role : roles) {
List<Integer> roleMenuIds = getRoleMenuIds(role.getId(),true);
allowMenuIdSet.addAll(roleMenuIds);
}
}
List<Menu> menuTree = getMenuTree();
return filterMenuList(menuTree, allowMenuIdSet);
}
/**
* 过滤掉不允许访问的菜单
*/
private List<Menu> filterMenuList(List<Menu> menuTree, Set<Integer> allowMenuIdSet) {
List<Menu> allowMenuTree = new ArrayList<>();
if (menuTree == null || menuTree.size() == 0) {
return menuTree;
}
for (Menu menu : menuTree) {
if (allowMenuIdSet.contains(menu.getId())) {
if (menu.getChildren() != null && menu.getChildren().size() > 0) {
menu.setChildren(filterMenuList(menu.getChildren(), allowMenuIdSet));
}
allowMenuTree.add(menu);
}
}
return allowMenuTree;
public List<Menu> selectMenuTreeByUserId(Integer userId) {
return menuMapper.selectMenuTreeByUserId(userId);
}
/**
* 获取指定角色能够访问的菜单ID
* 构建前端路由所需要的菜单
*
* @param menus 菜单列表
* @return 路由列表
*/
@Override
public List<Integer> getRoleMenuIds(Integer roleId , boolean withParent) {
if(withParent){
return menuMapper.getRoleMenuIdsWithParent(roleId);
}else{
return menuMapper.getRoleMenuIds(roleId);
}
public List<RouterVo> buildMenus(List<Menu> menus) {
return TreeUtils.build(0, menus, RouterVo.class, (dataObject, routerVo) -> {
routerVo.setId(dataObject.getId());
routerVo.setParentId(dataObject.getParentId());
routerVo.setName(dataObject.getName());
routerVo.setPath(dataObject.getRoutePath());
routerVo.setHidden(!dataObject.getShowInMenu());
routerVo.setRedirect(dataObject.getUrl());
routerVo.setComponent(dataObject.getRouteComponentName());
});
}
/**
* 获取当前用户
* @return
* 通过id获得菜单的所有子节点
*
* @param menuId 菜单id
* @return 菜单的所有子节点
*/
@Override
public List<String> getCurrentUserMenuAuthority() {
UserInfoVO userInfoVO = SessionUtils.getCurrentUser();
List<Role> roles = userInfoVO.getRoles();
if (roles != null && !roles.isEmpty()) {
List<String> roleNames = roles.stream().map(Role::getName).collect(Collectors.toList());
return menuMapper.getCurrentUserMenuAuthority(roleNames);
} else {
return new ArrayList<>();
}
public List<Menu> getAllMenusById(Integer menuId) {
return menuMapper.selectMenuTreeByUserId(0);
}
}

Loading…
Cancel
Save