feat(MenuController.java): 菜单重构以及整合Spring Cache Redis

This commit is contained in:
有来技术 2021-08-22 21:59:22 +08:00
parent 766cd27740
commit 0fccad91e7
5 changed files with 132 additions and 130 deletions

View File

@ -3,6 +3,7 @@ package com.youlai.admin.pojo.vo;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List; import java.util.List;
@ -29,12 +30,12 @@ public class RouteVO {
private Meta meta; private Meta meta;
@Data @Data
@NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Meta { public static class Meta {
private String title; private String title;
private String icon; private String icon;
private List<String> roles; private List<String> roles;
} }
private List<RouteVO> children; private List<RouteVO> children;
} }

View File

@ -1,115 +1,101 @@
package com.youlai.admin.controller; package com.youlai.admin.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.youlai.admin.pojo.entity.SysMenu; import com.youlai.admin.pojo.entity.SysMenu;
import com.youlai.admin.pojo.vo.MenuVO;
import com.youlai.admin.pojo.vo.RouteVO;
import com.youlai.admin.pojo.vo.TreeVO;
import com.youlai.admin.service.ISysMenuService; import com.youlai.admin.service.ISysMenuService;
import com.youlai.admin.service.ISysRoleMenuService;
import com.youlai.common.enums.QueryModeEnum;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* @author xianrui * 菜单控制器
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2020-11-06 * @date 2020-11-06
*/ */
@Api(tags = "菜单接口") @Api(tags = "菜单接口")
@RestController @RestController
@RequestMapping("/api/v1/menus") @RequestMapping("/api/v1/menus")
@Slf4j @RequiredArgsConstructor
@AllArgsConstructor
public class MenuController { public class MenuController {
private ISysMenuService iSysMenuService; private final ISysMenuService menuService;
@ApiOperation(value = "菜单列表") @ApiOperation(value = "菜单表格Table层级列表")
@ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "String")
@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "String"), @GetMapping("/table")
@ApiImplicitParam(name = "roleId", value = "角色ID", paramType = "query", dataType = "Long"), public Result getMenuTableList(String name) {
@ApiImplicitParam(name = "queryMode", value = "查询模式", paramType = "query", dataType = "QueryModeEnum") List<MenuVO> menuList = menuService.listTable(name);
}) return Result.success(menuList);
@GetMapping }
public Result list(String queryMode, String name) {
QueryModeEnum queryModeEnum = QueryModeEnum.getByCode(queryMode);
LambdaQueryWrapper<SysMenu> baseQuery = new LambdaQueryWrapper<SysMenu>() @ApiOperation(value = "菜单下拉Select层级列表")
.orderByAsc(SysMenu::getSort) @GetMapping("/select")
.orderByDesc(SysMenu::getGmtModified) public Result getMenuSelectList() {
.orderByDesc(SysMenu::getGmtCreate); List<TreeVO> menuList = menuService.listSelect();
List list; return Result.success(menuList);
switch (queryModeEnum) { }
case LIST:
baseQuery = baseQuery.like(StrUtil.isNotBlank(name), SysMenu::getName, name); @ApiOperation(value = "菜单路由Route层级列表")
list = iSysMenuService.listMenuVO(baseQuery); @GetMapping("/route")
break; public Result getMenuRouteList() {
case TREE: List<RouteVO> menuList = menuService.listRoute();
list = iSysMenuService.listTreeVO(baseQuery); return Result.success(menuList);
break;
default:
list = iSysMenuService.list(baseQuery);
break;
}
return Result.success(list);
} }
@ApiOperation(value = "菜单详情") @ApiOperation(value = "菜单详情")
@ApiImplicitParam(name = "id", value = "菜单id", required = true, paramType = "path", dataType = "Long") @ApiImplicitParam(name = "id", value = "菜单id", required = true, paramType = "path", dataType = "Long")
@GetMapping("/{id}") @GetMapping("/{id}")
public Result detail(@PathVariable Integer id) { public Result detail(@PathVariable Integer id) {
SysMenu menu = iSysMenuService.getById(id); SysMenu menu = menuService.getById(id);
return Result.success(menu); return Result.success(menu);
} }
@ApiOperation(value = "新增菜单") @ApiOperation(value = "新增菜单")
@ApiImplicitParam(name = "menu", value = "实体JSON对象", required = true, paramType = "body", dataType = "SysMenu")
@PostMapping @PostMapping
@CacheEvict(cacheNames = "admin",key = "'routeList'")
public Result add(@RequestBody SysMenu menu) { public Result add(@RequestBody SysMenu menu) {
boolean status = iSysMenuService.save(menu); boolean status = menuService.save(menu);
return Result.judge(status); return Result.judge(status);
} }
@ApiOperation(value = "修改菜单") @ApiOperation(value = "修改菜单")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "菜单id", required = true, paramType = "path", dataType = "Long"),
@ApiImplicitParam(name = "menu", value = "实体JSON对象", required = true, paramType = "body", dataType = "SysMenu")
})
@PutMapping(value = "/{id}") @PutMapping(value = "/{id}")
@CacheEvict(cacheNames = "admin",key = "'routeList'")
public Result update( public Result update(
@PathVariable Integer id, @PathVariable Integer id,
@RequestBody SysMenu menu) { @RequestBody SysMenu menu) {
boolean status = iSysMenuService.updateById(menu); boolean status = menuService.updateById(menu);
return Result.judge(status); return Result.judge(status);
} }
@ApiOperation(value = "删除菜单") @ApiOperation(value = "删除菜单")
@ApiImplicitParam(name = "ids", value = "id集合字符串以,分割", required = true, paramType = "query", dataType = "String") @ApiImplicitParam(name = "ids", value = "id集合字符串以,分割", required = true, paramType = "query", dataType = "String")
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@CacheEvict(cacheNames = "admin",key = "'routeList'")
public Result delete(@PathVariable("ids") String ids) { public Result delete(@PathVariable("ids") String ids) {
boolean status = iSysMenuService.removeByIds(Arrays.asList(ids.split(","))); boolean status = menuService.removeByIds(Arrays.asList(ids.split(",")));
return Result.judge(status); return Result.judge(status);
} }
@ApiOperation(value = "修改菜单") @ApiOperation(value = "选择性修改菜单")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, paramType = "path", dataType = "Long"),
@ApiImplicitParam(name = "menu", value = "实体JSON对象", required = true, paramType = "body", dataType = "SysMenu")
})
@PatchMapping(value = "/{id}") @PatchMapping(value = "/{id}")
@CacheEvict(cacheNames = "admin",key = "'routeList'")
public Result patch(@PathVariable Integer id, @RequestBody SysMenu menu) { public Result patch(@PathVariable Integer id, @RequestBody SysMenu menu) {
LambdaUpdateWrapper<SysMenu> updateWrapper = new LambdaUpdateWrapper<SysMenu>().eq(SysMenu::getId, id); LambdaUpdateWrapper<SysMenu> updateWrapper = new LambdaUpdateWrapper<SysMenu>().eq(SysMenu::getId, id);
updateWrapper.set(menu.getVisible() != null, SysMenu::getVisible, menu.getVisible()); updateWrapper.set(menu.getVisible() != null, SysMenu::getVisible, menu.getVisible());
boolean result = iSysMenuService.update(updateWrapper); boolean result = menuService.update(updateWrapper);
return Result.judge(result); return Result.judge(result);
} }
} }

View File

@ -1,37 +0,0 @@
package com.youlai.admin.controller;
import com.youlai.admin.pojo.vo.RouteVO;
import com.youlai.admin.service.ISysMenuService;
import com.youlai.common.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author xianrui
* @date 2021/6/1 22:40
*/
@Api(tags = "路由接口")
@RestController
@RequestMapping("/api/v1/routes")
@Slf4j
@AllArgsConstructor
public class RouteController {
private ISysMenuService iSysMenuService;
@ApiOperation(value = "路由列表")
@GetMapping
public Result list() {
List<RouteVO> list = iSysMenuService.listRoute();
return Result.success(list);
}
}

View File

@ -1,7 +1,6 @@
package com.youlai.admin.service; package com.youlai.admin.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.youlai.admin.pojo.entity.SysMenu; import com.youlai.admin.pojo.entity.SysMenu;
import com.youlai.admin.pojo.vo.MenuVO; import com.youlai.admin.pojo.vo.MenuVO;
@ -9,15 +8,35 @@ import com.youlai.admin.pojo.vo.RouteVO;
import com.youlai.admin.pojo.vo.TreeVO; import com.youlai.admin.pojo.vo.TreeVO;
import java.util.List; import java.util.List;
/** /**
* @author haoxr * @author haoxr
* @date 2020-11-06 * @date 2020-11-06
*/ */
public interface ISysMenuService extends IService<SysMenu> { public interface ISysMenuService extends IService<SysMenu> {
List<MenuVO> listMenuVO(LambdaQueryWrapper<SysMenu> baseQuery);
List<TreeVO> listTreeVO(LambdaQueryWrapper<SysMenu> baseQuery); /**
* 菜单表格Table层级列表
*
* @param name 菜单名称
* @return
*/
List<MenuVO> listTable(String name);
/**
* 菜单下拉Select层级列表
*
* @return
*/
List<TreeVO> listSelect();
/**
* 菜单路由Route层级列表
*
* @return
*/
List<RouteVO> listRoute(); List<RouteVO> listRoute();
} }

View File

@ -2,6 +2,7 @@ package com.youlai.admin.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.admin.common.constant.SystemConstants; import com.youlai.admin.common.constant.SystemConstants;
@ -12,6 +13,7 @@ import com.youlai.admin.mapper.SysMenuMapper;
import com.youlai.admin.pojo.vo.TreeVO; import com.youlai.admin.pojo.vo.TreeVO;
import com.youlai.admin.service.ISysMenuService; import com.youlai.admin.service.ISysMenuService;
import com.youlai.common.constant.GlobalConstants; import com.youlai.common.constant.GlobalConstants;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,61 +22,80 @@ import java.util.Optional;
/** /**
* @author xianrui * 菜单业务类
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2020-11-06 * @date 2020-11-06
*/ */
@Service @Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService { public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
/**
* 菜单表格Table层级列表
*
* @param name 菜单名称
* @return
*/
@Override @Override
public List<MenuVO> listMenuVO(LambdaQueryWrapper<SysMenu> baseQuery) { public List<MenuVO> listTable(String name) {
List<SysMenu> menuList = this.baseMapper.selectList(baseQuery); List<SysMenu> menuList = this.list(
List<MenuVO> list = recursionForTree(SystemConstants.ROOT_MENU_ID, menuList); new LambdaQueryWrapper<SysMenu>()
return list; .like(StrUtil.isNotBlank(name), SysMenu::getName, name)
} .orderByAsc(SysMenu::getSort)
);
@Override List<MenuVO> tableList = recursionTableList(SystemConstants.ROOT_MENU_ID, menuList);
public List<TreeVO> listTreeVO(LambdaQueryWrapper<SysMenu> baseQuery) { return tableList;
List<SysMenu> menuList = this.list(baseQuery);
List<TreeVO> list = recursionForTreeSelect(SystemConstants.ROOT_MENU_ID, menuList);
return list;
} }
/** /**
* 递归生成表格数据 * 递归生成菜单表格层级列表
* *
* @param parentId * @param parentId 父级ID
* @param menuList * @param menuList 菜单列表
* @return * @return
*/ */
public static List<MenuVO> recursionForTree(Long parentId, List<SysMenu> menuList) { private static List<MenuVO> recursionTableList(Long parentId, List<SysMenu> menuList) {
List<MenuVO> list = new ArrayList<>(); List<MenuVO> menuTableList = new ArrayList<>();
Optional.ofNullable(menuList).orElse(new ArrayList<>()) Optional.ofNullable(menuList).orElse(new ArrayList<>())
.stream() .stream()
.filter(menu -> menu.getParentId().equals(parentId)) .filter(menu -> menu.getParentId().equals(parentId))
.forEach(menu -> { .forEach(menu -> {
MenuVO menuVO = new MenuVO(); MenuVO menuVO = new MenuVO();
BeanUtil.copyProperties(menu, menuVO); BeanUtil.copyProperties(menu, menuVO);
List<MenuVO> children = recursionForTree(menu.getId(), menuList); List<MenuVO> children = recursionTableList(menu.getId(), menuList);
if (CollectionUtil.isNotEmpty(children)) { if (CollectionUtil.isNotEmpty(children)) {
menuVO.setChildren(children); menuVO.setChildren(children);
} }
list.add(menuVO); menuTableList.add(menuVO);
}); });
return list; return menuTableList;
} }
/** /**
* 递归生成部门树形下拉数据 * 菜单下拉Select层级列表
* *
* @param parentId
* @param menuList
* @return * @return
*/ */
public static List<TreeVO> recursionForTreeSelect(Long parentId, List<SysMenu> menuList) { @Override
List<TreeVO> list = new ArrayList<>(); public List<TreeVO> listSelect() {
List<SysMenu> menuList = this.list(new LambdaQueryWrapper<SysMenu>().orderByAsc(SysMenu::getSort));
List<TreeVO> menuSelectList = recursionSelectList(SystemConstants.ROOT_MENU_ID, menuList);
return menuSelectList;
}
/**
* 递归生成菜单下拉层级列表
*
* @param parentId 父级ID
* @param menuList 菜单列表
* @return
*/
private static List<TreeVO> recursionSelectList(Long parentId, List<SysMenu> menuList) {
List<TreeVO> menuSelectList = new ArrayList<>();
Optional.ofNullable(menuList).orElse(new ArrayList<>()) Optional.ofNullable(menuList).orElse(new ArrayList<>())
.stream() .stream()
.filter(menu -> menu.getParentId().equals(parentId)) .filter(menu -> menu.getParentId().equals(parentId))
@ -82,40 +103,52 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
TreeVO treeVO = new TreeVO(); TreeVO treeVO = new TreeVO();
treeVO.setId(menu.getId()); treeVO.setId(menu.getId());
treeVO.setLabel(menu.getName()); treeVO.setLabel(menu.getName());
List<TreeVO> children = recursionForTreeSelect(menu.getId(), menuList); List<TreeVO> children = recursionSelectList(menu.getId(), menuList);
if (CollectionUtil.isNotEmpty(children)) { if (CollectionUtil.isNotEmpty(children)) {
treeVO.setChildren(children); treeVO.setChildren(children);
} }
list.add(treeVO); menuSelectList.add(treeVO);
}); });
return list; return menuSelectList;
} }
/**
* 菜单路由Route层级列表
* <p>
* 读多写少缓存至Redis
*
* @return
* @Cacheable cacheNames:缓存名称不同缓存的数据是彼此隔离 key: 缓存Key
*/
@Override @Override
@Cacheable(cacheNames = "admin", key = "'routeList'")
public List<RouteVO> listRoute() { public List<RouteVO> listRoute() {
List<SysMenu> menuList = this.baseMapper.listRoute(); List<SysMenu> menuList = this.baseMapper.listRoute();
List<RouteVO> list = recursionRoute(SystemConstants.ROOT_MENU_ID, menuList); List<RouteVO> list = recursionRoute(SystemConstants.ROOT_MENU_ID, menuList);
return list; return list;
} }
// 递归生成路由
/**
* 递归生成菜单路由层级列表
*
* @param parentId 父级ID
* @param menuList 菜单列表
* @return
*/
private List<RouteVO> recursionRoute(Long parentId, List<SysMenu> menuList) { private List<RouteVO> recursionRoute(Long parentId, List<SysMenu> menuList) {
List<RouteVO> list = new ArrayList<>(); List<RouteVO> list = new ArrayList<>();
Optional.ofNullable(menuList).ifPresent(menus -> menus.stream().filter(menu -> menu.getParentId().equals(parentId)) Optional.ofNullable(menuList).ifPresent(menus -> menus.stream().filter(menu -> menu.getParentId().equals(parentId))
.forEach(menu -> { .forEach(menu -> {
RouteVO routeVO = new RouteVO(); RouteVO routeVO = new RouteVO();
routeVO.setName(menu.getId() + ""); // 根据name路由跳转 this.$router.push({path:xxx}) routeVO.setName(menu.getId() + ""); // 根据name路由跳转 this.$router.push({path:xxx})
routeVO.setPath(menu.getPath()); // 根据path路由跳转 this.$router.push({name:xxx}) routeVO.setPath(menu.getPath()); // 根据path路由跳转 this.$router.push({name:xxx})
routeVO.setRedirect(menu.getRedirect()); routeVO.setRedirect(menu.getRedirect());
routeVO.setComponent(menu.getComponent()); routeVO.setComponent(menu.getComponent());
routeVO.setRedirect(menu.getRedirect()); routeVO.setRedirect(menu.getRedirect());
routeVO.setMeta(routeVO.new Meta( RouteVO.Meta meta = new RouteVO.Meta(menu.getName(), menu.getIcon(), menu.getRoles());
menu.getName(), routeVO.setMeta(meta);
menu.getIcon(),
menu.getRoles()
));
// 菜单显示隐藏 // 菜单显示隐藏
routeVO.setHidden(!GlobalConstants.STATUS_YES.equals(menu.getVisible())); routeVO.setHidden(!GlobalConstants.STATUS_YES.equals(menu.getVisible()));
List<RouteVO> children = recursionRoute(menu.getId(), menuList); List<RouteVO> children = recursionRoute(menu.getId(), menuList);