实战小知识-----8.27-----菜单备份工程

52 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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);
}