package cn.exrick.xboot.base.controller.manage; import cn.exrick.xboot.base.utils.VoUtil; import cn.exrick.xboot.base.vo.MenuVo; import cn.exrick.xboot.core.common.constant.CommonConstant; import cn.exrick.xboot.core.common.exception.XbootException; import cn.exrick.xboot.core.common.redis.RedisTemplateHelper; import cn.exrick.xboot.core.common.utils.CommonUtil; import cn.exrick.xboot.core.common.utils.ResultUtil; import cn.exrick.xboot.core.common.utils.SecurityUtil; import cn.exrick.xboot.core.common.vo.Result; import cn.exrick.xboot.core.config.security.permission.MySecurityMetadataSource; import cn.exrick.xboot.core.entity.Permission; import cn.exrick.xboot.core.entity.RolePermission; import cn.exrick.xboot.core.entity.User; import cn.exrick.xboot.core.service.PermissionService; import cn.exrick.xboot.core.service.RolePermissionService; import cn.exrick.xboot.core.service.mybatis.IPermissionService; import cn.hutool.core.util.StrUtil; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.Comparator; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * @author Exrick */ @Slf4j @RestController @Api(tags = "菜单权限管理接口") @RequestMapping("/xboot/permission") @CacheConfig(cacheNames = "permission") @Transactional public class PermissionController { @Autowired private PermissionService permissionService; @Autowired private RolePermissionService rolePermissionService; @Autowired private IPermissionService iPermissionService; @Autowired private RedisTemplateHelper redisTemplate; @Autowired private SecurityUtil securityUtil; @Autowired private MySecurityMetadataSource mySecurityMetadataSource; @RequestMapping(value = "/getMenuList", method = RequestMethod.GET) @ApiOperation(value = "获取用户页面菜单数据") public Result> getAllMenuList() { List menuList; // 读取缓存 User u = securityUtil.getCurrUser(); String key = "permission::userMenuList:" + u.getId(); String v = redisTemplate.get(key); if (StrUtil.isNotBlank(v)) { menuList = new Gson().fromJson(v, new TypeToken>() { }.getType()); return new ResultUtil>().setData(menuList); } // 用户所有权限 已排序去重 List list = iPermissionService.findByUserId(u.getId()); // 筛选0级页面 menuList = list.stream().filter(p -> CommonConstant.PERMISSION_NAV.equals(p.getType())) .sorted(Comparator.comparing(Permission::getSortOrder)) .map(VoUtil::permissionToMenuVo).collect(Collectors.toList()); getMenuByRecursion(menuList, list); // 缓存 redisTemplate.set(key, new Gson().toJson(menuList), 15L, TimeUnit.DAYS); return new ResultUtil>().setData(menuList); } private void getMenuByRecursion(List curr, List list) { curr.forEach(e -> { if (CommonConstant.LEVEL_TWO.equals(e.getLevel())) { List buttonPermissions = list.stream() .filter(p -> (e.getId()).equals(p.getParentId()) && CommonConstant.PERMISSION_OPERATION.equals(p.getType())) .sorted(Comparator.comparing(Permission::getSortOrder)) .map(Permission::getButtonType).collect(Collectors.toList()); e.setPermTypes(buttonPermissions); } else { List children = list.stream() .filter(p -> (e.getId()).equals(p.getParentId()) && CommonConstant.PERMISSION_PAGE.equals(p.getType())) .sorted(Comparator.comparing(Permission::getSortOrder)) .map(VoUtil::permissionToMenuVo).collect(Collectors.toList()); e.setChildren(children); if (e.getLevel() < 3) { getMenuByRecursion(children, list); } } }); } @RequestMapping(value = "/getAllList", method = RequestMethod.GET) @ApiOperation(value = "获取权限菜单树") @Cacheable(key = "'allList'") public Result> getAllList() { List list = permissionService.getAll(); // 0级 List list0 = list.stream().filter(e -> (CommonConstant.LEVEL_ZERO).equals(e.getLevel())) .sorted(Comparator.comparing(Permission::getSortOrder)).collect(Collectors.toList()); getAllByRecursion(list0, list); return new ResultUtil>().setData(list0); } private void getAllByRecursion(List curr, List list) { curr.forEach(e -> { List children = list.stream().filter(p -> (e.getId()).equals(p.getParentId())) .sorted(Comparator.comparing(Permission::getSortOrder)).collect(Collectors.toList()); e.setChildren(children); setInfo(e); if (e.getLevel() < 3) { getAllByRecursion(children, list); } }); } @RequestMapping(value = "/getByParentId/{parentId}", method = RequestMethod.GET) @ApiOperation(value = "通过id获取") @Cacheable(key = "#parentId") public Result> getByParentId(@PathVariable String parentId) { List list = permissionService.findByParentIdOrderBySortOrder(parentId); list.forEach(e -> setInfo(e)); return ResultUtil.data(list); } @RequestMapping(value = "/add", method = RequestMethod.POST) @ApiOperation(value = "添加") @CacheEvict(key = "'menuList'") public Result add(Permission permission) { if (permission.getId().equals(permission.getParentId())) { return ResultUtil.error("上级节点不能为自己"); } // 判断拦截请求的操作权限按钮名是否已存在 if (CommonConstant.PERMISSION_OPERATION.equals(permission.getType())) { List list = permissionService.findByTitle(permission.getTitle()); if (list != null && list.size() > 0) { return new ResultUtil().setErrorMsg("名称已存在"); } } // 如果不是添加的一级 判断设置上级为父节点标识 if (!CommonConstant.PARENT_ID.equals(permission.getParentId())) { Permission parent = permissionService.get(permission.getParentId()); if (parent.getIsParent() == null || !parent.getIsParent()) { parent.setIsParent(true); permissionService.update(parent); } } Permission u = permissionService.save(permission); // 重新加载权限 mySecurityMetadataSource.loadResourceDefine(); // 手动删除缓存 redisTemplate.deleteByPattern("permission:*"); return new ResultUtil().setData(u); } @RequestMapping(value = "/edit", method = RequestMethod.POST) @ApiOperation(value = "编辑") public Result edit(Permission permission) { if (permission.getId().equals(permission.getParentId())) { return ResultUtil.error("上级节点不能为自己"); } // 判断拦截请求的操作权限按钮名是否已存在 if (CommonConstant.PERMISSION_OPERATION.equals(permission.getType())) { // 若名称修改 Permission p = permissionService.get(permission.getId()); if (!p.getTitle().equals(permission.getTitle())) { List list = permissionService.findByTitle(permission.getTitle()); if (list != null && list.size() > 0) { return ResultUtil.error("名称已存在"); } } } Permission old = permissionService.get(permission.getId()); String oldParentId = old.getParentId(); Permission u = permissionService.update(permission); // 如果该节点不是一级节点 且修改了级别 判断上级还有无子节点 if (!CommonConstant.PARENT_ID.equals(oldParentId) && !oldParentId.equals(permission.getParentId())) { Permission parent = permissionService.get(oldParentId); List children = permissionService.findByParentIdOrderBySortOrder(parent.getId()); if (parent != null && (children == null || children.isEmpty())) { parent.setIsParent(false); permissionService.update(parent); } } // 重新加载权限 mySecurityMetadataSource.loadResourceDefine(); // 手动批量删除缓存 redisTemplate.deleteByPattern("user:*"); redisTemplate.deleteByPattern("permission:*"); return ResultUtil.data(u); } @RequestMapping(value = "/delByIds", method = RequestMethod.POST) @ApiOperation(value = "批量通过id删除") @CacheEvict(key = "'menuList'") public Result delByIds(@RequestParam String[] ids) { for (String id : ids) { deleteRecursion(id, ids); } // 重新加载权限 mySecurityMetadataSource.loadResourceDefine(); // 手动删除缓存 redisTemplate.deleteByPattern("permission:*"); return ResultUtil.success("批量通过id删除数据成功"); } public void deleteRecursion(String id, String[] ids) { List list = rolePermissionService.findByPermissionId(id); if (list != null && list.size() > 0) { throw new XbootException("删除失败,包含正被用户使用关联的菜单"); } // 获得其父节点 Permission p = permissionService.get(id); Permission parent = null; if (p != null && StrUtil.isNotBlank(p.getParentId())) { parent = permissionService.get(p.getParentId()); } permissionService.delete(id); // 判断父节点是否还有子节点 if (parent != null) { List children = permissionService.findByParentIdOrderBySortOrder(parent.getId()); if (children == null || children.isEmpty()) { parent.setIsParent(false); permissionService.update(parent); } } // 递归删除 List permissions = permissionService.findByParentIdOrderBySortOrder(id); for (Permission pe : permissions) { if (!CommonUtil.judgeIds(pe.getId(), ids)) { deleteRecursion(pe.getId(), ids); } } } @RequestMapping(value = "/search", method = RequestMethod.GET) @ApiOperation(value = "搜索菜单") public Result> searchPermissionList(@RequestParam String title) { List list = permissionService.findByTitleLikeOrderBySortOrder("%" + title + "%"); list.forEach(e -> setInfo(e)); return new ResultUtil>().setData(list); } public void setInfo(Permission permission) { if (!CommonConstant.PARENT_ID.equals(permission.getParentId())) { Permission parent = permissionService.get(permission.getParentId()); permission.setParentTitle(parent.getTitle()); } else { permission.setParentTitle("一级菜单"); } } }