|
|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|