上一章我们讲解了资源设计的思路,通过自定义注解的形式自动生成。这章开始我们正式开始用户rbac模块的资源模块管理功能开发。因为资源是通过自定义注解在启动时候自动加载的,所以不会不需要手动新增,所以资源管理只涉及到 查询和修改的开发。具体的启动初始化会在后面在讲解。
1. 创建工程目录
我在admin-user工程下创建controller、service、dao、mapper、pojo目录
pojo目录为实体目录,下面我又细分了3个目录为db(和数据库连接的实体)、req(请求实体)、resp(响应实体)
2. 资源管理开发
创建资源实体 id、modelCode、modelDesc、funCode、funDesc、operCode、operDesc、path、isMenu、sort、level、icon、dispylayFlag、updateFlag
package com.swh.admin.pojo.db;
import com.baomidou.mybatisplus.annotation.TableName;
import com.swh.admin.pojo.req.ReqUpdateResInfoVo;
import com.swh.common.vo.BaseVo;
import com.swh.common.vo.ReqMqMenuResourcesVo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import static com.swh.common.constant.AdminUserConst.MenuLevle.LEVLE_ONE;
import static com.swh.common.constant.AdminUserConst.MenuLevle.LEVLE_TWO;
/**
* @ClassName: DbMenuResVo
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:34
*/
@Setter
@Getter
@NoArgsConstructor
@TableName("admin_resources")
public class DbAdminResVo extends BaseVo {
private String id;
private String modelCode;
private String modelDesc;
private String funCode;
private String funDesc;
private String operCode;
private String operDesc;
private String path;
private String isMenu;
private int sort;
private int level;
private String icon;
private String dispylayFlag;
private String updateFlag;
public DbAdminResVo(ReqMqMenuResourcesVo req) {
this.id = req.getId();
this.modelCode = req.getModelCode();
this.modelDesc = req.getModelDesc();
this.funCode = req.getFunCode();
this.funDesc = req.getFunDesc();
this.operCode = req.getOperCode();
this.operDesc = req.getOperDesc();
this.path = req.getPath();
this.isMenu = req.getIsMenu();
this.sort = req.getSort();
this.level = req.getLevel();
this.icon = req.getIcon();
this.dispylayFlag = req.getDisplayFlag();
this.updateFlag = "N";
}
public DbAdminResVo(ReqUpdateResInfoVo req, DbAdminResVo vo) {
this.id = req.getId();
if (vo.getLevel() == LEVLE_ONE) {
this.modelDesc = req.getDesc();
this.level = 1;
}
if (vo.getLevel() == LEVLE_TWO) {
this.funDesc = req.getDesc();
this.level = 2;
}
this.sort = req.getSort();
this.icon = req.getIcon();
this.dispylayFlag = req.getShowFlag();
}
}
创建资源管理controller
AdminResController
package com.swh.admin.controller;
import com.swh.admin.pojo.req.ReqBatchAllAdminResVo;
import com.swh.admin.pojo.req.ReqUpdateResInfoVo;
import com.swh.admin.pojo.resp.RespAdminResTreeVo;
import com.swh.admin.service.AdminResService;
import com.swh.common.annotation.ApiCode;
import com.swh.common.annotation.ApiCodes;
import com.swh.common.annotation.Menu;
import com.swh.common.menu.LevelThreeMenuEnum;
import com.swh.common.result.AjaxResult;
import com.swh.common.utils.Assert;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.swh.common.constant.AdminUserConst.Url.*;
import static com.swh.common.result.ResultCode.ROLE_ID_NOT_NULL;
/**
* @ClassName: AdminResController
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:20
*/
@Slf4j
@Api(tags = "资源菜单管理")
@RestController
public class AdminResController {
@Autowired
private AdminResService adminResService;
@ApiCodes(value = {
@ApiCode(menuName = "MENU_ADMIN_RES_ALL", menuClass = LevelThreeMenuEnum.class)
})
@ApiOperation(value = "资源树")
@Menu(menuName = "MENU_ADMIN_RES_ALL", menuClass = LevelThreeMenuEnum.class)
@GetMapping(ADMIN_RES_GET_ALL)
public AjaxResult<List<RespAdminResTreeVo>> getAllAdminRes(@RequestBody ReqBatchAllAdminResVo req) {
Assert.isNotBlank(req.getRoleId(), ROLE_ID_NOT_NULL.getMsg());
return AjaxResult.ok(adminResService.batchGetAllAdminRes(req));
}
@ApiCodes(value = {
@ApiCode(menuName = "MENU_ADMIN_MENU_ALL", menuClass = LevelThreeMenuEnum.class)
})
@ApiOperation(value = "菜单树")
@Menu(menuName = "MENU_ADMIN_MENU_ALL", menuClass = LevelThreeMenuEnum.class)
@GetMapping(ADMIN_MENU_GET_ALL)
public AjaxResult<List<RespAdminResTreeVo>> getAllMenuTree() {
return AjaxResult.ok(adminResService.getAllMenuTree());
}
@ApiCodes(value = {
@ApiCode(menuName = "MENU_ADMIN_MENU_UPDATE", menuClass = LevelThreeMenuEnum.class)
})
@ApiOperation(value = "菜单项更新")
@Menu(menuName = "MENU_ADMIN_MENU_UPDATE", menuClass = LevelThreeMenuEnum.class)
@PostMapping(ADMIN_MENU_INFO_UPDATE)
public AjaxResult<String> updateMenuInfo(@RequestBody ReqUpdateResInfoVo req) {
Assert.isNotBlank(req.getId(), "不能为空");
Assert.isNotBlank(req.getDesc(), "不能为空");
Assert.isNotBlank(req.getShowFlag(), "不能为空");
Assert.isNotBlank(req.getShowFlag(), "不能为空");
adminResService.updateMenuInfo(req);
return AjaxResult.ok();
}
}
创建资源管理service 和 serviceImpl
AdminResService
package com.swh.admin.service;
import com.swh.admin.pojo.db.DbAdminResVo;
import com.swh.admin.pojo.req.ReqBatchAllAdminResVo;
import com.swh.admin.pojo.req.ReqUpdateResInfoVo;
import com.swh.admin.pojo.resp.RespAdminResTreeVo;
import java.util.List;
/**
* @ClassName: AdminResService
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:22
*/
public interface AdminResService {
/**
* 资源树
*
* @param req
* @return
*/
List<RespAdminResTreeVo> batchGetAllAdminRes(ReqBatchAllAdminResVo req);
/**
* 菜单树
*
* @return
*/
List<RespAdminResTreeVo> getAllMenuTree();
/**
* 菜单数据更新
*
* @param req
*/
void updateMenuInfo(ReqUpdateResInfoVo req);
/**
* 插入菜单资源信息
*
* @param adminResVos
*/
void addAllMenuResource(List<DbAdminResVo> adminResVos);
/**
* 获取用户的菜单
*
* @param resultRes
* @return
*/
List<RespAdminResTreeVo> getUserMenuTree(List<DbAdminResVo> resultRes);
}
AdminResServiceImpl
package com.swh.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.swh.admin.dao.AdminResDao;
import com.swh.admin.dao.RoleResMpDao;
import com.swh.admin.pojo.db.DbAdminResVo;
import com.swh.admin.pojo.req.ReqBatchAllAdminResVo;
import com.swh.admin.pojo.req.ReqUpdateResInfoVo;
import com.swh.admin.pojo.resp.RespAdminResTreeVo;
import com.swh.admin.service.AdminResService;
import com.swh.common.exception.RequestException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import static com.swh.common.constant.AdminUserConst.MenuLevle.LEVLE_ONE;
import static com.swh.common.constant.AdminUserConst.MenuLevle.LEVLE_TWO;
import static com.swh.common.result.ResultCode.MENU_NOT_EXISTS;
/**
* @ClassName: AdminResServiceImpl
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:22
*/
@Slf4j
@Service
public class AdminResServiceImpl implements AdminResService {
@Autowired
private RoleResMpDao roleResMpDao;
@Autowired
private AdminResDao adminResDao;
@Override
public List<RespAdminResTreeVo> batchGetAllAdminRes(ReqBatchAllAdminResVo req) {
List<String> resIds = roleResMpDao.getResIdsByRoleId(req.getRoleId());
List<RespAdminResTreeVo> listLevel1 = adminResDao.getResourceByLevel(1).stream().map(menu -> new RespAdminResTreeVo(menu, resIds)).sorted().collect(Collectors.toList());
List<RespAdminResTreeVo> listLevel2 = adminResDao.getResourceByLevel(2).parallelStream().map(menu -> new RespAdminResTreeVo(menu, resIds)).collect(Collectors.toList());
Map<String, List<RespAdminResTreeVo>> mapLevel3 = adminResDao.getResourceByLevel(3).parallelStream().map(menu -> new RespAdminResTreeVo(menu, resIds)).collect(Collectors.toList()).parallelStream().collect(Collectors.groupingBy(RespAdminResTreeVo::getParentCode));
List<RespAdminResTreeVo> tmp;
//将三级菜单的数据二级菜单中
for (RespAdminResTreeVo resp : listLevel2) {
tmp = mapLevel3.get(resp.getCode());
if (CollUtil.isNotEmpty(tmp)) {
resp.setList(tmp);
} else {
resp.setList(new ArrayList<>());
}
}
Map<String, List<RespAdminResTreeVo>> mapLevel2 = listLevel2.parallelStream().collect(Collectors.groupingBy(RespAdminResTreeVo::getParentCode, toSortedList(Comparator.comparing(RespAdminResTreeVo::getSort))));
for (RespAdminResTreeVo resp : listLevel1) {
tmp = mapLevel2.get(resp.getCode());
if (CollUtil.isNotEmpty(tmp)) {
resp.setList(tmp);
} else {
resp.setList(new ArrayList<>());
}
}
return listLevel1;
}
@Override
public List<RespAdminResTreeVo> getAllMenuTree() {
List<RespAdminResTreeVo> listLevel1 = adminResDao.getResourceByLevel(1).stream().map(RespAdminResTreeVo::new).sorted().collect(Collectors.toList());
List<RespAdminResTreeVo> listLevel2 = adminResDao.getResourceByLevel(2).parallelStream().map(RespAdminResTreeVo::new).collect(Collectors.toList());
Map<String, List<RespAdminResTreeVo>> mapLevel2 = listLevel2.parallelStream().collect(Collectors.groupingBy(RespAdminResTreeVo::getParentCode, toSortedList(Comparator.comparing(RespAdminResTreeVo::getSort))));
for (RespAdminResTreeVo resp : listLevel1) {
List<RespAdminResTreeVo> tmp = mapLevel2.get(resp.getCode());
if (CollUtil.isNotEmpty(tmp)) {
resp.setList(tmp);
} else {
resp.setList(new ArrayList<>());
}
}
return listLevel1;
}
@Override
public void updateMenuInfo(ReqUpdateResInfoVo req) {
DbAdminResVo vo = adminResDao.getResourceById(req.getId());
if (ObjectUtil.isNull(vo)) {
throw new RequestException(MENU_NOT_EXISTS);
}
adminResDao.updateMenuInfo(new DbAdminResVo(req, vo));
}
@Override
public void addAllMenuResource(List<DbAdminResVo> adminResVos) {
//删除本应用的数据
adminResDao.delMenuResources();
//替换插入数据
adminResDao.addMenuResources(adminResVos);
}
@Override
public List<RespAdminResTreeVo> getUserMenuTree(List<DbAdminResVo> resultRes) {
List<RespAdminResTreeVo> listLevel1 = adminResDao.getResourceByLevel(1).parallelStream().map(m -> {
if (ObjectUtil.isNotNull(m) && m.getLevel() == LEVLE_ONE && StrUtil.equals(m.getDispylayFlag(), "Y")) {
return new RespAdminResTreeVo(m);
}
return null;
}
).filter(Objects::nonNull).sorted().collect(Collectors.toList());
Map<String, List<RespAdminResTreeVo>> mapLevel3 = resultRes.parallelStream().map(RespAdminResTreeVo::new).collect(Collectors.groupingBy(RespAdminResTreeVo::getParentCode, toSortedList(Comparator.comparing(RespAdminResTreeVo::getSort))));
List<RespAdminResTreeVo> listLevel2 = adminResDao.getResourceByLevel(2).parallelStream().map(m -> {
if (ObjectUtil.isNotNull(m) && m.getLevel() == LEVLE_TWO && StrUtil.equals(m.getDispylayFlag(), "Y") && CollUtil.isNotEmpty(mapLevel3.get(m.getModelCode() + m.getFunCode()))) {
return new RespAdminResTreeVo(m);
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
Map<String, List<RespAdminResTreeVo>> mapLevel2 = listLevel2.parallelStream().collect(Collectors.groupingBy(RespAdminResTreeVo::getParentCode, toSortedList(Comparator.comparing(RespAdminResTreeVo::getSort))));
//获取所有已关联的一级菜单
for (RespAdminResTreeVo resp : listLevel1) {
List<RespAdminResTreeVo> tmp = mapLevel2.get(resp.getCode());
if (CollUtil.isNotEmpty(tmp)) {
resp.setList(tmp);
} else {
resp.setList(new ArrayList<>());
}
}
return listLevel1.stream().map(d -> {
if (CollUtil.isNotEmpty(d.getList())) {
return d;
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
}
private <T> Collector<T, ?, List<T>> toSortedList(Comparator<? super T> c) {
return Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(c)), ArrayList::new);
}
}
创建资源管理的dao层和mapper层
AdminResDao
package com.swh.admin.dao;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.swh.admin.mapper.AdminResMapper;
import com.swh.admin.pojo.db.DbAdminResVo;
import com.swh.common.vo.BaseDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName: AdminResDao
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:41
*/
@Repository
public class AdminResDao extends BaseDao<DbAdminResVo> {
@Autowired
private AdminResMapper adminResMapper;
/**
* 根据level获取对应资源
*
* @param level
* @return
*/
public List<DbAdminResVo> getResourceByLevel(int level) {
return adminResMapper.selectList(new QueryWrapper<DbAdminResVo>().eq("level", level));
}
/**
* 根据Id获取菜单数据
*
* @param id
* @return
*/
public DbAdminResVo getResourceById(String id) {
return adminResMapper.selectById(id);
}
/**
* 更新菜单数据
*
* @param dbAdminResVo
*/
public void updateMenuInfo(DbAdminResVo dbAdminResVo) {
adminResMapper.updateById(dbAdminResVo);
}
/**
* 删除菜单信息
*/
public void delMenuResources() {
adminResMapper.delete(new QueryWrapper<>());
}
/**
* 根据Id获取菜单资源信息
*
* @param resIds
* @return
*/
public List<DbAdminResVo> getResourceByIds(List<String> resIds) {
if (CollUtil.isNotEmpty(resIds)) {
return adminResMapper.selectBatchIds(resIds);
}
return new ArrayList<>();
}
}
AdminResMapper
package com.swh.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.swh.admin.pojo.db.DbAdminResVo;
import org.apache.ibatis.annotations.Insert;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @ClassName: AdminResMapper
* @Description:
* @Author: songWenHao
* @Date: 2022/6/16 16:42
*/
@Component
public interface AdminResMapper extends BaseMapper<DbAdminResVo> {
}