上一篇地址:【清晨平台记录四】代码实现平台后台用户模块二(主要实现个人账号的操作功能)
本篇代码地址:Gitee 地址 注意是 project05 分支哦
接口文档地址:Apifox工具编写的接口文档
目录
2.基础框架设计思路
2.2用户模块业务功能接口(补充)
序号 | 接口 | 接口描述 |
获取登录信息 | 用户登录后获取当前登录用户的基础信息和权限等信息 | |
获取路由信息 | 获取当前登录用户能操作的路由信息 |
操作权限、数据权限的逻辑补充:
操作权限:用户通过所拥有的角色的菜单权限,会查询出哪些导航栏(目录、菜单类型的菜单)显示,哪些按钮(按钮类型的菜单)的显示;
若目录显示,则其下级也会显示;
若菜单显示,则其对应的页面能打开,并且能够进行基础的查询;
若按钮显示,则能够对数据进行操作;
数据权限:数据权限的设置针对当前操作的角色下的菜单而言,打开菜单会自动获取数据信息,数据信息是有当前用户所拥有的角色中,能够操作这个菜单的数据权限最大范围而言;
例如:
同一个用户绑定两个角色,角色A、角色B,其中用户A的菜单权限选择了菜单A,数据权限选择了全部;用户B的菜单权限选择了菜单A、菜单B,数据权限选择了仅自己;
那么该用户若打开菜单A,它能查询的数据范围是全部;若打开菜单B,它能查询的数据范围是仅自己的;
5.用户模块—研发思路
5.2子模块研发
5.2.6登录成功后用户信息及操作权限
1.获取登录信息
我们可以根据当前登录账号,在security里面拿到他的个人信息(security里的信息是从redis里面拿到的),然后再从 menu 表中获取到当前用户拥有的操作权限标识,无论是菜单、目录、按钮都是权限~
但是这里的权限标识是只针对于菜单和按钮的,例如打开某菜单后获取菜单下的数据时的操作权限,操作某菜单下的按钮的权限;
个人信息容易获取,而从获取权限信息就需要重新思考,首先持久层就需要添加 <select> 元素,关联菜单角色表来获取。
由于我们后续还要针对权限进行鉴权等操作,所以再创建一个权限service层,专门处理权限的操作~
开始码代码:
//我们在 admin 模块中写表现层
1.表现层
controller:com.qingchen.controller.system.SysLoginController extends BaseController
//我们在 framework 模块中写业务层
2.业务层
service:com.qingchen.framework.web.service.SysPermissionService
//我们在 system 模块中写持久层
3.持久层
mapper.xml:mapper/system/SysMenuMapper.xml
mbg 生成的代码里面,自动包含增删改查,我们先修改insert、update、delete为我们想要的sql操作
mapper接口:com.qingchen.system.mapper.SysMenuMapper
//业务层写完之后要和表现层的调用对上哦~
2.获取路由信息
我们根据当前登录账号,从menu表中获取到当前用户拥有的目录和菜单,然后构建成前端 vue-router 能识别的路由格式~
这里的路由信息也可以理解为权限信息,当前账号拥有的哪些目录、菜单类型的菜单权限;
构建前端识别的 router 数据时,记得和前端进行沟通~
开始码代码:
//我们在 admin 模块中写表现层
1.表现层
controller:com.qingchen.controller.system.SysLoginController extends BaseController
//我们在 framework 模块中写业务层
2.业务层
service:com.qingchen.system.service.impl.SysMenuServiceImpl implements SysMenuService
//业务层写完之后要和表现层的调用对上哦~
我们获取到当前用户拥有的菜单、目录树后,在将他们转化成 vue-router 能识别的格式。
重点代码:
@Service
public class SysMenuServiceImpl implements SysMenuService {
......
/**
* @Description: 获取到当前用户拥有的菜单、目录树后
* @param userId
* @Return: java.util.List<com.qingchen.system.domain.entity.SysMenu>
*/
@Override
public List<SysMenu> selectUserMenuTreeByUserId(Long userId) {
List<SysMenu> sysMenus = sysMenuMapper.selectMenuTreeByUserId(userId);
return buildMenuList(sysMenus);
}
/**
* @Description: 将导航列表转化成 vue-router 能识别的格式
* @param sysMenus
* @Return: java.util.List<com.qingchen.system.domain.vo.RouterVo>
*/
@Override
public List<RouterVo> buildMenusRouter(List<SysMenu> sysMenus) {
List<RouterVo> routers = new LinkedList<RouterVo>();
for (SysMenu menu : sysMenus) {
// 1.先统一赋值 name、hidden、meta、query,再判断赋值path、component (子级菜单和外链是一样的)
RouterVo router = new RouterVo();
router.setHidden("1".equals(menu.getVisible()));
router.setName(getRouteName(menu));
router.setPath(getRouterPath(menu));
router.setComponent(getRouterComponent(menu));
router.setQuery(menu.getQuery());
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
// 2.判断,如果是顶级、目录,则赋值 noRedirect ,再递归赋值 children (有子级)
if(isTopDir(menu)){
router.setRedirect("noRedirect");
List<SysMenu> cMenus = menu.getChildren();
// 递归循环子级
router.setChildren(buildMenusRouter(cMenus));
}// 3.判断,如果是顶级、菜单,则创建子级菜单节点信息 ,并赋值给 children
else if (isTopMenu(menu)){
router.setRedirect("noRedirect");
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
children.setPath(menu.getPath());
children.setComponent(menu.getComponent());
children.setName(StringUtils.capitalize(menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQuery());
childrenList.add(children);
router.setChildren(childrenList);
}
// 4.将一级路由添加到路由列表中
routers.add(router);
}
return routers;
}
}
后续的模块~~
5.2.7数据权限
5.2.8列表分页
5.2.9角色模块添加操作用户的逻辑