携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
今天整理了一下需要完成的功能,虽然是周六,但还是不想懈怠
背景交代
公司的菜单权限是使用的RBAC,角色权限管理,那么菜单表除了有一个ID主键外,还有一个code值作为编码唯一。 3千多行的菜单维护管理,就显得很繁琐很麻烦;每次新增一个新的功能,对应的菜单维护,需要在开发环境、测试环境、线上生产环境一一添加;迎刃而生的需求,就是开发一个菜单脚本
- 无论如何,维护人员都需要在一个环境下添加一次,才能作为脚本的数据储备
- 作为Mysql,之前是使用过 猪齿鱼的脚本导入;确实也好用,但是由于手动操作过几次线上库,脚本会对手动的操作不兼容,因此无法统一环境使用
脚本
脚本的理念就是
- 利用json作为数据支撑,维护人员在其中一个环境手动维护新的功能菜单后,导出来
- 导出后对json作为参数传入脚本,脚本把json业务处理后,校验code是否重复,并入库
- json存在两种方式维护
- 增量:仅作当前功能的菜单
- 全量:较少概率,就是对全局的菜单进行维护
- 利用了二叉树的层序遍历理念,因为json内会嵌套无限的json,因此需要对每次json做处理后,再次入栈出栈做出黎
实现
@Override
public ScriptVO checkAndInsert(Menu menu) {
ScriptVO scriptVO = new ScriptVO();
int total = 0,success = 0;
queue.offer(menu);
while (!queue.isEmpty()){
int size = queue.size();
for (int i = 0; i < size; i++) {
Menu parent = Menu.init(queue.poll());
// 业务处理
if (!check(parent)){
//重复+结束
scriptVO.setFailMenu(parent);
scriptVO.setTotal(++total);
scriptVO.setSuccess(++success);
return scriptVO;
}
//插入 父系
Long parentId = create(menu).getId();
++total;
++success;
if (parent.getSubMenus() != null){
parent.getSubMenus().forEach(e->{
e.setParentId(parentId);
queue.offer(e);
});
}
}
}
scriptVO.setTotal(++total);
scriptVO.setSuccess(++success);
return scriptVO;
}
@Override
public Boolean check(Menu menu) {
try {
ResponseUtils.getResponse(feign.checkPermissions(menu),Boolean.class);
}catch (CommonException e){
return Boolean.FALSE;
}
return Boolean.TRUE;
}
@Override
public Menu create(Menu menu) {
return ResponseUtils.getResponse(feign.create(menu), Menu.class);
}