菜单表设计
- resource_code 给前端用,唯一标识 (不设计的话,就需要自己维护,难度比较大)
2.permissionCode 权限编码,接口功能,后端url放到这里,给后端做接口权限的校验 - params 给前端存储参数,json格式。 json kye的组成:icon, desc, show, options;options 里是其他json的格式
resource_code唯一标识的设计
- 组成内容:应用 + 模块 + 菜单 + 功能
- 如果当前资源就是应用类型,则只有前4位,同理,如果只是模块类型,则只有前8位
- 菜单允许嵌套,通过表中parentId来标识菜单的父子关系,通过resourceCode看不出父子关系
- 不同页面存在公共的接口,可以将其设计到公共的模块或则公共的菜单中,在给这个角色赋权限的时候,这些公共的接口不需要赋值,默认拥有这些公共的模块(公共的模块不包括不需要token的接口,比如登录,图形验证码)
核心代码
生成resource_code,怎么去计算resource_code才不能重复呢?并且resource_code可以读取这个菜单就是属于这个模块的数据;菜单的嵌套问题;公共功能的设计
比如:需要生成模块1下新的菜单,则需要先读取这个应用这个模块1下的最大菜单数 +1;菜单的嵌套(因菜单只有4位标识,则嵌套的菜单只能挂载这个模块下,并不能通过resource_code显示的挂在这个菜单下;菜单的嵌套还需要搭配parent_id来标识)
大体核心思想:
- 新计算出各种场景下的最大值,比如这个模块1的菜单最大值,菜单1下的功能最大值
- 新增新的菜单2,则向功能场景下,插入这个菜单2对应功能的最大值
- 嵌套的菜单不能根据parentId去获取这个场景下的最大值,而应该获取父模块id去获取对应场景的最大值
生成resource_code的核心代码:
/**
* 填充resourceImportInner, 映射parentId, 计算resourceCode
*
* @param resourceImportInners List<ResourceImportInner>
* @return List<Resource>
*/
private void populateResourceImportInner(List<ResourceImportInner> resourceImportInners) {
// 查出对应模块最大的resourceCode
Map<Long, Long> applicationMaxResource = getMaxResourceCodeByType(ResourceTypeEnum.APPLICATION.getValue());
Map<Long, Long> moduleMaxResource = getMaxResourceCodeByType(ResourceTypeEnum.MODULE.getValue());
Map<Long, Long> menuMaxResource = getMaxResourceCodeByType(ResourceTypeEnum.MENU.getValue());
Map<Long, Long> functionMaxResource = getMaxResourceCodeByType(ResourceTypeEnum.FUNCTION.getValue());
// 获取除功能模块,resourceName和id的映射关系
Map<String, Long> resourceNameMap = resourceName2IdMap(resourceImportInners);
// 组装resourceCode 和 parentId
for (ResourceImportInner importVo : resourceImportInners) {
importVo.setParentId