/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package com.vci.ubcs.system.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.vci.ubcs.system.entity.Menu; import com.vci.ubcs.system.entity.TopMenu; import com.vci.ubcs.system.service.IMenuService; import com.vci.ubcs.system.service.ITopMenuService; import com.vci.ubcs.system.vo.ButtonCloneVO; import com.vci.ubcs.system.vo.CheckedTreeVO; import com.vci.ubcs.system.vo.GrantTreeVO; import com.vci.ubcs.system.vo.MenuVO; import com.vci.ubcs.system.wrapper.MenuWrapper; import io.swagger.annotations.*; import lombok.AllArgsConstructor; import org.springblade.core.cache.utils.CacheUtil; import org.springblade.core.boot.ctrl.BladeController; import org.springblade.core.log.annotation.ApiLog; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.secure.BladeUser; import org.springblade.core.tenant.annotation.NonDS; import org.springblade.core.tool.api.R; import org.springblade.core.tool.node.TreeNode; import org.springblade.core.tool.support.Kv; import org.springblade.core.tool.utils.Func; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.validation.Valid; import java.util.List; import java.util.Map; import static org.springblade.core.cache.constant.CacheConstant.MENU_CACHE; /** * 控制器 * * @author Chill */ @NonDS @RestController @AllArgsConstructor @RequestMapping("/menu") @Api(value = "菜单", tags = "菜单") public class MenuController extends BladeController { private final IMenuService menuService; private final ITopMenuService topMenuService; /** * 详情 */ @GetMapping("/detail") //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 1) @ApiOperation(value = "详情", notes = "传入menu") public R detail(Menu menu) { Menu detail = menuService.getOne(Condition.getQueryWrapper(menu)); return R.data(MenuWrapper.build().entityVO(detail)); } /** * 列表 */ @GetMapping("/list") @ApiImplicitParams({ @ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"), @ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string") }) //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 2) @ApiOperation(value = "列表", notes = "传入menu") public R> list(@ApiIgnore @RequestParam Map menu) { List list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().orderByAsc(Menu::getSort)); return R.data(MenuWrapper.build().listNodeVO(list)); } /** * 根据父菜单的code获取,下面的按钮 * @param menu * @return */ @GetMapping("/getButtonByParentCode") @ApiImplicitParams({ @ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"), @ApiImplicitParam(name = "category", value = "菜单类型", paramType = "query", dataType = "string") }) @ApiOperationSupport(order = 3) @ApiOperation(value = "列表", notes = "传入menu") public R> getButtonByParentCode(@ApiIgnore @RequestParam Map menu){ if(Func.isBlank(menu.getOrDefault("code","").toString())){ throw new ServiceException("必填参数菜单code不能为空!"); } return R.data(MenuWrapper.build().listNodeVO(menuService.getButtonByParentCode(menu.getOrDefault("code","").toString()))); } /** * 懒加载列表 */ @GetMapping("/lazy-list") @ApiImplicitParams({ @ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"), @ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string") }) //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 3) @ApiOperation(value = "懒加载列表", notes = "传入menu") @ApiLog("菜单懒加载列表") public R> lazyList(Long parentId, @ApiIgnore @RequestParam Map menu) { List list = menuService.lazyList(parentId, menu); return R.data(MenuWrapper.build().listNodeLazyVO(list)); } /** * 菜单列表 */ @GetMapping("/menu-list") @ApiImplicitParams({ @ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"), @ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string") }) //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 4) @ApiOperation(value = "菜单列表", notes = "传入menu") public R> menuList(@ApiIgnore @RequestParam Map menu) { List list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().eq(Menu::getCategory, 1).orderByAsc(Menu::getSort)); return R.data(MenuWrapper.build().listNodeVO(list)); } /** * 懒加载菜单列表 */ @GetMapping("/lazy-menu-list") @ApiImplicitParams({ @ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"), @ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string") }) //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 5) @ApiOperation(value = "懒加载菜单列表", notes = "传入menu") public R> lazyMenuList(Long parentId, @ApiIgnore @RequestParam Map menu, Query query) { IPage menuVOIPage = menuService.lazyMenuPage(parentId, menu,query); return R.data(MenuWrapper.build().pageNodeLazyVO(menuVOIPage)); } /** * 新增或修改 */ @PostMapping("/submit") //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 6) @ApiOperation(value = "新增或修改", notes = "传入menu") public R submit(@Valid @RequestBody Menu menu) { if (menuService.submit(menu)) { CacheUtil.clear(MENU_CACHE); CacheUtil.clear(MENU_CACHE, Boolean.FALSE); // 返回懒加载树更新节点所需字段 Kv kv = Kv.create().set("id", String.valueOf(menu.getId())); return R.data(kv); } return R.fail("操作失败"); } /** * 删除 */ @PostMapping("/remove") //@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) @ApiOperationSupport(order = 7) @ApiOperation(value = "删除", notes = "传入ids") public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) { CacheUtil.clear(MENU_CACHE); CacheUtil.clear(MENU_CACHE, Boolean.FALSE); return R.status(menuService.removeMenu(ids)); } /** * 前端菜单数据 */ @GetMapping("/routes") @ApiOperationSupport(order = 8) @ApiOperation(value = "前端菜单数据", notes = "前端菜单数据") public R> routes(BladeUser user, Long topMenuId) { List lists = menuService.routes((user == null) ? null : user.getRoleId(), topMenuId); menuService.handleKeepAlive(lists); return R.data(lists); } /** * 前端按钮数据 */ @GetMapping("/buttons") @ApiOperationSupport(order = 10) @ApiOperation(value = "前端按钮数据", notes = "前端按钮数据") public R> buttons(BladeUser user) { List list = menuService.buttons(user.getRoleId()); return R.data(list); } /** * 获取菜单树形结构 */ @GetMapping("/tree") @ApiOperationSupport(order = 11) @ApiOperation(value = "树形结构", notes = "树形结构") public R> tree() { List tree = menuService.tree(); return R.data(tree); } /** * 获取权限分配树形结构 */ @GetMapping("/grant-tree") @ApiOperationSupport(order = 12) @ApiOperation(value = "权限分配树形结构", notes = "权限分配树形结构") public R grantTree(BladeUser user) { GrantTreeVO vo = new GrantTreeVO(); vo.setMenu(menuService.grantTree(user)); vo.setDataScope(menuService.grantDataScopeTree(user)); vo.setApiScope(menuService.grantApiScopeTree(user)); return R.data(vo); } /** * 获取权限分配树形结构 */ @GetMapping("/role-tree-keys") @ApiOperationSupport(order = 13) @ApiOperation(value = "角色所分配的树", notes = "角色所分配的树") public R roleTreeKeys(String roleIds) { CheckedTreeVO vo = new CheckedTreeVO(); vo.setMenu(menuService.roleTreeKeys(roleIds)); vo.setDataScope(menuService.dataScopeTreeKeys(roleIds)); vo.setApiScope(menuService.apiScopeTreeKeys(roleIds)); return R.data(vo); } /** * 获取顶部菜单树形结构 */ @GetMapping("/grant-top-tree") @ApiOperationSupport(order = 14) @ApiOperation(value = "顶部菜单树形结构", notes = "顶部菜单树形结构") public R grantTopTree(BladeUser user) { GrantTreeVO vo = new GrantTreeVO(); vo.setMenu(menuService.grantTopTree(user)); return R.data(vo); } /** * 获取顶部菜单树形结构 */ @GetMapping("/top-tree-keys") @ApiOperationSupport(order = 15) @ApiOperation(value = "顶部菜单所分配的树", notes = "顶部菜单所分配的树") public R topTreeKeys(String topMenuIds) { CheckedTreeVO vo = new CheckedTreeVO(); vo.setMenu(menuService.topTreeKeys(topMenuIds)); return R.data(vo); } /** * 顶部菜单数据 */ @GetMapping("/top-menu") @ApiOperationSupport(order = 16) @ApiOperation(value = "顶部菜单数据", notes = "顶部菜单数据") public R> topMenu(BladeUser user) { if (Func.isEmpty(user)) { return null; } List list = topMenuService.list(Wrappers.query().lambda().orderByAsc(TopMenu::getSort)); return R.data(list); } /** * 获取配置的角色权限 */ @GetMapping("/auth-routes") @ApiOperationSupport(order = 17) @ApiOperation(value = "菜单的角色权限") public R> authRoutes(BladeUser user) { if (Func.isEmpty(user)) { return null; } return R.data(menuService.authRoutes(user)); } /** * 克隆其他菜单下按钮 * @param buttonCloneVO 要克隆的菜单按钮主键 被克隆的按钮主键 * @return */ @PostMapping("/cloneMenuButton") public R cloneMenuButton(@RequestBody ButtonCloneVO buttonCloneVO) { return menuService.cloneMenuButton(buttonCloneVO.getMenuId(), buttonCloneVO.getButtonIds()); } /** * 根据角色id获取已授权的按钮信息 * @param roleId * @return */ @GetMapping("/getButtonsByRoleId") public R> getButtonsByRoleId(@Valid @RequestParam("roleId") String roleId,@Valid @RequestParam("code") String menuCode){ return R.data(menuService.getButtonsByRoleId(roleId,menuCode)); } }