/* * Copyright (c) 2018. paascloud.net All Rights Reserved. * 项目名称:paascloud快速搭建企业级分布式微服务平台 * 类名称:UacMenuServiceImpl.java * 创建人:刘兆明 * 联系方式:[email protected] * 开源地址: https://github.com/paascloud * 博客地址: http://blog.paascloud.net * 项目官网: http://paascloud.net */ package com.paascloud.provider.service.impl; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.paascloud.PublicUtil; import com.paascloud.base.constant.GlobalConstant; import com.paascloud.base.dto.LoginAuthDto; import com.paascloud.base.enums.ErrorCodeEnum; import com.paascloud.core.support.BaseService; import com.paascloud.provider.mapper.UacMenuMapper; import com.paascloud.provider.model.constant.MenuConstant; import com.paascloud.provider.model.domain.UacMenu; import com.paascloud.provider.model.domain.UacRoleMenu; import com.paascloud.provider.model.dto.menu.UacMenuStatusDto; import com.paascloud.provider.model.enums.UacMenuStatusEnum; import com.paascloud.provider.model.exceptions.UacBizException; import com.paascloud.provider.model.vo.MenuVo; import com.paascloud.provider.model.vo.ViewMenuVo; import com.paascloud.provider.service.UacActionService; import com.paascloud.provider.service.UacMenuService; import com.paascloud.provider.service.UacRoleMenuService; import com.paascloud.provider.utils.TreeUtil; import org.apache.commons.lang3.StringUtils; import org.modelmapper.ModelMapper; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; /** * The class Uac menu service. * * @author [email protected] */ @Service @Transactional(rollbackFor = Exception.class) public class UacMenuServiceImpl extends BaseService<UacMenu> implements UacMenuService { @Resource private UacMenuMapper uacMenuMapper; @Resource private UacRoleMenuService uacRoleMenuService; @Resource private UacActionService uacActionService; @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public List<MenuVo> getMenuVoList(Long userId, Long applicationId) { // 1.查询该用户下所有的菜单列表 List<MenuVo> menuVoList = Lists.newArrayList(); List<UacMenu> menuList; Set<UacMenu> menuSet = Sets.newHashSet(); // 如果是admin则返回所有的菜单 if (userId == 1L) { // 1.1 查询该用户下所有的菜单列表 UacMenu uacMenuQuery = new UacMenu(); uacMenuQuery.setStatus(UacMenuStatusEnum.ENABLE.getType()); uacMenuQuery.setApplicationId(applicationId); uacMenuQuery.setOrderBy(" level asc,number asc"); menuList = uacMenuMapper.selectMenuList(uacMenuQuery); } else { // 1.2查询该用户下所有的菜单列表 menuVoList = uacMenuMapper.findMenuVoListByUserId(userId); if (PublicUtil.isEmpty(menuVoList)) { return null; } Set<Long> ids = Sets.newHashSet(); for (final MenuVo menuVo : menuVoList) { ids.add(menuVo.getId()); } List<UacMenu> ownMenuList = this.getMenuList(ids); // 查出所有含有菜单的菜单信息 UacMenu uacMenu = new UacMenu(); uacMenu.setStatus(UacMenuStatusEnum.ENABLE.getType()); List<UacMenu> allMenuList = this.selectMenuList(uacMenu); Map<Long, UacMenu> map = Maps.newHashMap(); for (final UacMenu menu : allMenuList) { map.put(menu.getId(), menu); } for (final UacMenu menu : ownMenuList) { getPid(menuSet, menu, map); } menuList = new ArrayList<>(menuSet); } List<MenuVo> list = getMenuVo(menuList); if (PublicUtil.isNotEmpty(menuVoList)) { list.addAll(menuVoList); } // 2.递归成树 return TreeUtil.getChildMenuVos(list, 0L); } private void getPid(Set<UacMenu> menuSet, UacMenu menu, Map<Long, UacMenu> map) { UacMenu parent = map.get(menu.getPid()); if (parent != null && parent.getId() != 0L) { menuSet.add(parent); getPid(menuSet, parent, map); } } private List<MenuVo> getMenuVo(List<UacMenu> list) { List<MenuVo> menuVoList = Lists.newArrayList(); for (UacMenu uacMenu : list) { MenuVo menuVo = new MenuVo(); BeanUtils.copyProperties(uacMenu, menuVo); menuVo.setUrl(uacMenu.getUrl()); menuVo.setMenuName(uacMenu.getMenuName()); menuVoList.add(menuVo); } return menuVoList; } @Override public int saveUacMenu(UacMenu menu, LoginAuthDto loginAuthDto) { Long pid = menu.getPid(); menu.setUpdateInfo(loginAuthDto); UacMenu parentMenu = mapper.selectByPrimaryKey(pid); if (PublicUtil.isEmpty(parentMenu)) { throw new UacBizException(ErrorCodeEnum.UAC10013001, pid); } if (menu.isNew()) { UacMenu updateMenu = new UacMenu(); menu.setLevel(parentMenu.getLevel() + 1); updateMenu.setLeaf(MenuConstant.MENU_LEAF_NO); updateMenu.setId(pid); Long menuId = super.generateId(); menu.setId(menuId); int result = mapper.updateByPrimaryKeySelective(updateMenu); if (result < 1) { throw new UacBizException(ErrorCodeEnum.UAC10013002, menuId); } menu.setStatus(UacMenuStatusEnum.ENABLE.getType()); menu.setCreatorId(loginAuthDto.getUserId()); menu.setCreator(loginAuthDto.getUserName()); menu.setLastOperatorId(loginAuthDto.getUserId()); menu.setLastOperator(loginAuthDto.getUserName()); // 新增的菜单是叶子节点 menu.setLeaf(MenuConstant.MENU_LEAF_YES); return uacMenuMapper.insertSelective(menu); } else { return uacMenuMapper.updateByPrimaryKeySelective(menu); } } @Override public int deleteUacMenuById(Long id, LoginAuthDto loginAuthDto) { Preconditions.checkArgument(id != null, "菜单id不能为空"); int result; // 获取当前菜单信息 UacMenu uacMenuQuery = new UacMenu(); uacMenuQuery.setId(id); uacMenuQuery = mapper.selectOne(uacMenuQuery); if (PublicUtil.isEmpty(uacMenuQuery)) { throw new UacBizException(ErrorCodeEnum.UAC10013003, id); } // 删除菜单与角色的关联关系 UacRoleMenu uacRoleMenu = new UacRoleMenu(); uacRoleMenu.setMenuId(id); uacRoleMenuService.delete(uacRoleMenu); // 删除菜单 result = uacMenuMapper.deleteByPrimaryKey(id); if (result < 1) { logger.error("删除菜单失败 menuId={}", id); throw new UacBizException(ErrorCodeEnum.UAC10013008, id); } // 删除权限 // TODO 应该先查询再删除 uacActionService.deleteByMenuId(id); // 修改当前删除菜单的父菜单是否是叶子节点 UacMenu updateParentUacMenu = new UacMenu(); updateParentUacMenu.setId(uacMenuQuery.getPid()); updateParentUacMenu.setLeaf(MenuConstant.MENU_LEAF_YES); // 是二三级 if (Objects.equals(MenuConstant.MENU_LEVEL_TWO, uacMenuQuery.getLevel()) || Objects.equals(MenuConstant.MENU_LEVEL_THREE, uacMenuQuery.getLevel())) { // 查询是否是叶子节点 int count = uacMenuMapper.selectMenuChildCountByPid(uacMenuQuery.getPid()); if (count == 0) { uacMenuMapper.updateByPrimaryKeySelective(updateParentUacMenu); } } return result; } @Override public int enableMenuList(List<UacMenu> menuList, LoginAuthDto loginAuthDto) { UacMenu uacMenuUpdate = new UacMenu(); int sum = 0; for (UacMenu menu : menuList) { uacMenuUpdate.setId(menu.getId()); uacMenuUpdate.setVersion(menu.getVersion() + 1); uacMenuUpdate.setStatus(UacMenuStatusEnum.ENABLE.getType()); uacMenuUpdate.setLastOperator(loginAuthDto.getLoginName()); uacMenuUpdate.setLastOperatorId(loginAuthDto.getUserId()); uacMenuUpdate.setUpdateTime(new Date()); int result = mapper.updateByPrimaryKeySelective(uacMenuUpdate); if (result > 0) { sum += 1; } else { throw new UacBizException(ErrorCodeEnum.UAC10013004, menu.getId()); } } return sum; } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public List<UacMenu> getAllParentMenuByMenuId(Long menuId) { UacMenu uacMenuQuery = new UacMenu(); uacMenuQuery.setId(menuId); uacMenuQuery = mapper.selectOne(uacMenuQuery); List<UacMenu> uacMenuList = Lists.newArrayList(); uacMenuList = buildParentNote(uacMenuList, uacMenuQuery); return uacMenuList; } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public List<UacMenu> getAllChildMenuByMenuId(Long menuId, String menuStatus) { UacMenu uacMenuQuery = new UacMenu(); uacMenuQuery.setId(menuId); uacMenuQuery = mapper.selectOne(uacMenuQuery); List<UacMenu> uacMenuList = Lists.newArrayList(); uacMenuList = buildNode(uacMenuList, uacMenuQuery, menuStatus); return uacMenuList; } @Override public int disableMenuList(List<UacMenu> menuList, LoginAuthDto loginAuthDto) { UacMenu uacMenuUpdate = new UacMenu(); int sum = 0; for (UacMenu menu : menuList) { uacMenuUpdate.setId(menu.getId()); uacMenuUpdate.setVersion(menu.getVersion() + 1); uacMenuUpdate.setStatus(UacMenuStatusEnum.DISABLE.getType()); uacMenuUpdate.setLastOperator(loginAuthDto.getLoginName()); uacMenuUpdate.setLastOperatorId(loginAuthDto.getUserId()); uacMenuUpdate.setUpdateTime(new Date()); int result = mapper.updateByPrimaryKeySelective(uacMenuUpdate); if (result > 0) { sum += 1; } else { throw new UacBizException(ErrorCodeEnum.UAC10013005, menu.getId()); } } return sum; } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public List<UacMenu> selectMenuList(UacMenu uacMenu) { return uacMenuMapper.selectMenuList(uacMenu); } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public List<MenuVo> findAllMenuListByAuthResDto(LoginAuthDto authResDto) { List<MenuVo> voList = Lists.newArrayList(); Preconditions.checkArgument(authResDto != null, "无权访问"); if (!GlobalConstant.Sys.SUPER_MANAGER_LOGIN_NAME.equals(authResDto.getLoginName())) { voList = uacMenuMapper.findMenuVoListByUserId(authResDto.getUserId()); } else { UacMenu uacMenuQuery = new UacMenu(); // 查询启用的菜单 uacMenuQuery.setStatus(UacMenuStatusEnum.ENABLE.getType()); uacMenuQuery.setOrderBy(" level asc,number asc"); List<UacMenu> list = uacMenuMapper.select(uacMenuQuery); for (UacMenu uacMenu : list) { MenuVo menuVo = new MenuVo(); BeanUtils.copyProperties(uacMenu, menuVo); voList.add(menuVo); } } return voList; } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public ViewMenuVo getViewVoById(Long id) { Preconditions.checkArgument(id != null, "菜单ID不能为空"); UacMenu menu = uacMenuMapper.selectByPrimaryKey(id); if (menu == null) { logger.error("找不到菜单信息id={}", id); throw new UacBizException(ErrorCodeEnum.UAC10013003, id); } // 获取父级菜单信息 UacMenu parentMenu = uacMenuMapper.selectByPrimaryKey(menu.getPid()); ModelMapper modelMapper = new ModelMapper(); ViewMenuVo menuVo = modelMapper.map(menu, ViewMenuVo.class); if (parentMenu != null) { menuVo.setParentMenuName(parentMenu.getMenuName()); } return menuVo; } @Override public void updateUacMenuStatusById(UacMenuStatusDto uacMenuStatusDto, LoginAuthDto loginAuthDto) { Long id = uacMenuStatusDto.getId(); String status = uacMenuStatusDto.getStatus(); Preconditions.checkArgument(id != null, "菜单ID不能为空"); Preconditions.checkArgument(StringUtils.isNotEmpty(status), "菜单状态不能为空"); UacMenu uacMenuQuery = this.selectByKey(id); if (MenuConstant.MENU_LEVEL_ROOT.equals(uacMenuQuery.getLevel())) { throw new UacBizException(ErrorCodeEnum.UAC10013007); } // 要处理的菜单集合 List<UacMenu> menuList = Lists.newArrayList(); int result; if (status.equals(UacMenuStatusEnum.DISABLE.getType())) { // 获取菜单以及子菜单 menuList = this.getAllChildMenuByMenuId(id, UacMenuStatusEnum.ENABLE.getType()); // 禁用菜单以及子菜单 result = this.disableMenuList(menuList, loginAuthDto); } else { // 获取菜单、其子菜单以及父菜单 UacMenu uacMenu = new UacMenu(); uacMenu.setPid(id); result = this.selectCount(uacMenu); // 此菜单含有子菜单 if (result > 0) { menuList = this.getAllChildMenuByMenuId(id, UacMenuStatusEnum.DISABLE.getType()); } List<UacMenu> menuListTemp = this.getAllParentMenuByMenuId(id); for (UacMenu menu : menuListTemp) { if (!menuList.contains(menu)) { menuList.add(menu); } } // 启用菜单、其子菜单以及父菜单 result = this.enableMenuList(menuList, loginAuthDto); } if (result < 1) { throw new UacBizException(ErrorCodeEnum.UAC10013006, id); } } @Override @Transactional(readOnly = true, rollbackFor = Exception.class) public boolean checkMenuHasChildMenu(Long pid) { Preconditions.checkArgument(pid != null, "菜单pid不能为空"); UacMenu uacMenu = new UacMenu(); uacMenu.setStatus(UacMenuStatusEnum.ENABLE.getType()); uacMenu.setPid(pid); return mapper.selectCount(uacMenu) > 0; } @Override public List<UacMenu> listMenuListByRoleId(Long roleId) { List<UacMenu> menuList = uacMenuMapper.listMenuListByRoleId(roleId); List<UacMenu> addMenuList = Lists.newArrayList(); if (PublicUtil.isNotEmpty(menuList)) { for (UacMenu uacMenu : menuList) { getMenuList(addMenuList, uacMenu.getPid()); } } menuList.addAll(addMenuList); return new ArrayList<>(new HashSet<>(menuList)); } @Override public List<UacMenu> getMenuList(final Set<Long> menuIdList) { return uacMenuMapper.listMenu(menuIdList); } private List<UacMenu> getMenuList(List<UacMenu> uacMenuList, Long menuId) { UacMenu uacMenu = uacMenuMapper.selectByPrimaryKey(menuId); if (uacMenu != null) { Long pid = uacMenu.getPid(); if (pid != null) { uacMenuList.add(uacMenu); getMenuList(uacMenuList, pid); } } return uacMenuList; } /** * 递归获取菜单的子菜单 */ private List<UacMenu> buildNode(List<UacMenu> uacMenuList, UacMenu uacMenu, String menuStatus) { List<UacMenu> uacMenuQueryList = mapper.select(uacMenu); UacMenu uacMenuQuery; for (UacMenu menu : uacMenuQueryList) { // 启用状态 if (menuStatus.equals(menu.getStatus()) && !MenuConstant.MENU_LEVEL_ROOT.equals(menu.getLevel())) { uacMenuList.add(menu); } uacMenuQuery = new UacMenu(); uacMenuQuery.setPid(menu.getId()); buildNode(uacMenuList, uacMenuQuery, menuStatus); } return uacMenuList; } /** * 递归获取菜单的父菜单 */ private List<UacMenu> buildParentNote(List<UacMenu> uacMenuList, UacMenu uacMenu) { List<UacMenu> uacMenuQueryList = mapper.select(uacMenu); UacMenu uacMenuQuery; for (UacMenu menu : uacMenuQueryList) { if (UacMenuStatusEnum.DISABLE.getType().equals(menu.getStatus()) && !MenuConstant.MENU_LEVEL_ROOT.equals(menu.getLevel())) { // 禁用状态 uacMenuList.add(menu); } uacMenuQuery = new UacMenu(); uacMenuQuery.setId(menu.getPid()); buildParentNote(uacMenuList, uacMenuQuery); } return uacMenuList; } }