拉勾教育后台管理系统(SSM)(权限管理模块)【学习笔记】

权限模块

1、权限概念介绍

  • 权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做
  • 认证: 验证用户名密码是否正确的过程
  • 授权: 对用户所能访问的资源进行控制(动态显示菜单、url级别的权限控制)

为什么要实现权限系统
      首先系统需要进行登陆才能访问,其次不同登陆用户要有不同的权利,而且要有不同的菜单(例如财务经理针对系统中财务相关模块进行操作,人事经理针对系统中人事模块进行操作)

权限控制基本原理

  1. ACL(Access Control Lists,缩写ACL)
          ACL是最早也是最基本的一种访问控制机制,它的原理非常简单:每一项资源,都配有一个列表,这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图访问这项资源时,会首先检查这个列表中是否有关于当前用户的访问权限,从而确定当前用户可否执行相应的操作。总得来说,ACL是一种面向资源的访问控制模型,它的机制是围绕“资源”展开的。
  2. 基于角色的访问控制RBAC(Role-Based Access Control)
         RBAC是把用户按角色进行归类,通过用户的角色来确定用户能否针对某项资源进行某项操作。RBAC相对于ACL最大的优势就是它简化了用户与权限的管理,通过对用户进行分类,使得角色与权限关联起来,而用户与权限变成了间接关联。RBAC模型使得访问控制,特别是对用户的授权管理变得非常简单和易于维护,因此有广泛的应用

在这里插入图片描述
规则一:每个登陆的用户,可以有多个角色;
规则二:每个角色又可以拥有多个权限(包含菜单和资源);

2、权限模块功能分析

      权限模块主要细分为角色模块、菜单模块、资源模块,将针对细分的三个模块进行具体功能实现,同时会完成用户登陆、用户关联角色及动态菜单显示

  • 实现以下功能:
    • 角色列表&条件查询(角色模块)
    • 分配菜单(角色模块)
    • 删除角色(角色模块)
    • 菜单列表查询(菜单模块)
    • 查询菜单信息回显(菜单模块)
    • 资源分页&多条件查询(资源模块)
    • 用户登陆(用户模块)
    • 动态菜单展示(权限模块)
    • 用户关联角色(用户模块)

3、权限管理模块表设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、权限管理(角色模块)接口实现

4.1、角色列表查询&条件查询

  • 名称: findAllRole
  • 描述: 查询菜单列表
  • URL: http://localhost:8080/ssm-web/role/findAllRole
  • 请求方式: POST
  • 请求参数
{name:"角色名称"}
  • 响应结果示例
{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": [{
		"id": 1,
		"code": "ADMIN",
		"name": "超级管理员",
		"description": "后台管理员,初始拥有权限管理功能",
		"createdTime": 1595230889000,
		"updatedTime": 1595230889000,
		"createdBy": "system",
		"updatedBy": "system"
	}
	......
}

dao层

 <select id="findAllRole" resultType="role" parameterType="role">
        SELECT
            id,
            CODE,
            NAME,
            description,
            created_time,
            updated_time,
            created_by,
            updated_by
            FROM roles
        <where>
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
        </where>
    </select>

service层

@Service
@Transactional
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;

    @Override
    public List<Role> findAllRole(Role role) {
        return roleMapper.findAllRole(role);
    }
}

web层

@RestController
@RequestMapping("/role")
public class RoleController {

    @Autowired
    private RoleService roleService;

    /*查询角色列表信息*/
    @RequestMapping("/findAllRole")
    public ResponseResult findAllRole(@RequestBody Role role){
        List<Role> allRole = roleService.findAllRole(role);
        return new ResponseResult(true, 200, "角色列表查询成功", allRole);
    }
}

4.2、分配菜单

4.2.1、查询所有菜单列表
  • 名称: findAllMenu
  • 描述: 为角色分配菜单
  • URL: http://localhost:8080/ssm-web/menu/findAllMenu
  • 请求方式: GET
  • 请求参数示例:
http://localhost:8080/ssm-web/menu/findAllMenu
  • 响应结果示例

content内容为 前端所需的JSON格式菜单数据, 方便在树形空间中展示

{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": {
		"parentMenuList": [{
			"id": 1,
			"parentId": -1,
			"href": "",
			"icon": "lock",
			"name": "权限管理",
			"description": "管理系统角色、菜单、资源",
			"orderNum": 1,
			"shown": 1,
			"level": 0,
			"createdTime": 1595230898000,
			"updatedTime": 1595230898000,
			"createdBy": "system",
			"updatedBy": "system",
			"subMenuList": [{
				"id": 2,
				"parentId": 1,
				"href": "Role",
				"icon": "lock",
				"name": "角色列表",
				"description": "管理系统角色",
				"orderNum": 1,
				"shown": 1,
				"level": 1,
				"createdTime": 1595230898000,
				"updatedTime": 1595230898000,
				"createdBy": "system",
				"updatedBy": "system",
				"subMenuList": []
			}]
}]

dao层(自连接查询)

<select id="findSubMenuListByPid" resultMap="MenuResult">
        select * from menu where parent_id = #{pid}
    </select>
    <resultMap id="MenuResult" type="menu">
        <id column="id" property="id"></id>
        <result column="href" property="href"></result>
        <result column="icon" property="icon"></result>
        <result column="name" property="name"></result>
        <result column="parent_id" property="parentId"></result>
        <result column="description" property="description"></result>
        <result column="orderNum" property="order_num"></result>
        <result column="shown" property="shown"></result>
        <result column="created_time" property="createdTime"></result>
        <result column="updated_time" property="updatedTime"></result>
        <result column="created_by" property="createdBy"></result>
        <result column="updated_by" property="updatedBy"></result>
        <collection property="subMenuList" ofType="menu" select="com.lzy.dao.MenuMapper.findSubMenuListByPid" column="id"/>
    </resultMap>

service层

@Service
@Transactional
public class MenuMapperImpl implements MenuService {
    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List<Menu> findSubMenuListByPid(Integer pid) {
        return menuMapper.findSubMenuListByPid(pid);
    }
}

web层

@RestController
@RequestMapping("/menu")
public class MenuController {
    @Autowired
    private MenuService menuService;
    /*查询所有菜单信息*/
    @RequestMapping("/findAllMenu")
    public ResponseResult findAllMenu(){
        List<Menu> menuList = menuService.findSubMenuListByPid(-1);
        HashMap<String, Object> map = new HashMap<>();
        map.put("parentMenuList", menuList);
        return new ResponseResult(true, 200, "查询所有菜单信息成功", map);
    }
}

postman测试
在这里插入图片描述

4.2.2、根据角色ID查询关联菜单ID
  • 名称: findMenuByRoleId
  • 描述: 根据角色信息查询关联菜单
  • URL: http://localhost:8080/ssm-web/role/findMenuByRoleId?roleId=4
  • 请求方式: GET
  • 请求示例:
http://10.1.194.181:8080/ssm-web/role/findMenuByRoleId?roleId=1
  • 响应结果示例

content中的内容为: 当前角色关联的菜单ID

{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": ["1","2","3","4","10"]
}

dao层

<select id="findMenuByRoleId" resultType="Integer" parameterType="Integer">
   select m.id from roles r INNER JOIN role_menu_relation rm on r.id = rm.role_id
                            INNER JOIN menu m on rm.menu_id = m.id where r.id = #{id}
</select>

service层

@Override
public List<Integer> findMenuByRoleId(Integer roleId) {
    return roleMapper.findMenuByRoleId(roleId);
}

web层

 @RequestMapping("/findMenuByRoleId")
public ResponseResult findMenuByRoleId(@RequestParam Integer roleId){
    List<Integer> menuByRoleId = roleService.findMenuByRoleId(roleId);
    return new ResponseResult(true, 200, "根据角色iD查询关联菜单id成功", menuByRoleId);
}

postman测试
在这里插入图片描述

4.2.3、为角色分配菜单列表
  • 名称: RoleContextMenu
  • 描述: 为角色分配菜单
  • URL: http://localhost:8080/ssm-web/role/RoleContextMenu
  • 请求方式: POST
  • 请求参数:
参数名称参数说明是否必须数据类型备注
roleId角色idtrueint
menuIdList所选的菜单列表idtrueList
  • 请求参数示例:
{
	"roleId": 4, 
	"menuIdList": [7, 8, 9, 15, 16, 17, 18]
}
  • 响应参数示例:
{"success":true,"state":200,"message":"响应成功","content":""}

dao层

<delete id="deleteRoleContextMenu" parameterType="integer">
     delete from role_menu_relation where role_id = #{id}
 </delete>

 <insert id="RoleContextMenu" parameterType="Role_menu_relation">
     insert into role_menu_relation values(null,#{menuId},#{roleId},#{createdTime},#{updatedTime},#{createdBy},#{updatedby})
 </insert>

service层

@Override
public void RoleContextMenu(RoleMenuVo roleMenuVo) {
    // 清空中间件
    roleMapper.deleteRoleContextMenu(roleMenuVo.getRoleId());

    for (Integer integer : roleMenuVo.getMenuIdList()) {
        Role_menu_relation roleMenuRelation = new Role_menu_relation();
        roleMenuRelation.setRoleId(roleMenuVo.getRoleId());
        roleMenuRelation.setMenuId(integer);
        roleMenuRelation.setCreatedTime(new Date());
        roleMenuRelation.setUpdatedTime(new Date());
        roleMenuRelation.setCreatedBy("system");
        roleMenuRelation.setUpdatedby("system");
        roleMapper.RoleContextMenu(roleMenuRelation);
    }
}

web层

@RequestMapping("/RoleContextMenu")
 public ResponseResult RoleContextMenu(@RequestBody RoleMenuVo roleMenuVo){
     roleService.RoleContextMenu(roleMenuVo);
     return new ResponseResult(true, 200, "分配菜单成功", null);
 }

postman层
在这里插入图片描述

4.2.4、删除角色
http://localhost:8080/ssm-web/role/deleteRole?id=5
  • 响应示例:
{"success":true,"state":200,"message":"响应成功","content":""}

dao层

<delete id="deleteRole" parameterType="integer">
    delete from roles where id = #{id}
</delete>

service层

 @Override
public void deleteRole(Integer id) {
    // 清空中间表
    roleMapper.deleteRoleContextMenu(id);
    roleMapper.deleteRole(id);
}

web层

 @RequestMapping("/deleteRole")
public ResponseResult deleteRole(Integer id){
    roleService.deleteRole(id);
    return new ResponseResult(true, 200, "删除角色成功", null);
}

postman层
在这里插入图片描述

4.2.5、添加&修改角色
  • 名称: saveOrUpdateRole
  • 描述: 根据菜单ID 查询菜单信息
  • URL: http://localhost:8080/ssm-web/role/saveOrUpdateRole
  • 请求方式: POST
  • 请求参数
参数名称参数说明in是否必须数据类型备注
id角色IDfalseint修改操作携带ID
name角色名称trueString
code角色编码trueString
description角色描述trueString
  • 请求参数示例
// 添加
{
	"name":"资源管理员",
	"code": "RE_MANAGER",
	"description": "管理资源"
}

// 更新
{
	"id":"6"
	"name":"资源管理员",
	"code": "RE_MANAGER",
	"description": "管理资源"
}
  • 响应参数:
参数名称参数说明类型schema
successboolean
stateinteger(int32)integer(int32)
messagestring
contentobject
  • 响应示例:
{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": ""
}

dao层

 <insert id="saveRole" parameterType="role">
    insert into roles values (null, #{code}, #{name}, #{description}, #{
    createdTime}, #{updatedTime},#{createdBy},#{updatedBy})
</insert>

<update id="updateRole" parameterType="role">
    update roles
    <trim prefix="set" suffixOverrides=",">
        <if test="code != null and code != ''">
            code = #{code},
        </if>
        <if test="name != null and name != ''">
            name = #{name},
        </if>
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="updatedTime != null ">
            updated_time = #{updatedTime},
        </if>
    </trim>
    <where>
        <if test="id != null and id != ''">
            id = #{id}
        </if>
    </where>
</update>

service层

@Override
public void saveRole(Role role) {
    // 补全信息
    Date date = new Date();
    role.setCreatedTime(date);
    role.setUpdatedTime(date);
    role.setCreatedBy("system");
    role.setUpdatedBy("system");

    roleMapper.saveRole(role);

}

@Override
public void updateRole(Role role) {
    // 补全信息
    role.setUpdatedTime(new Date());
    roleMapper.updateRole(role);
}

web层

@RequestMapping("/saveOrUpdateRole")
public ResponseResult saveOrUpdateRole(@RequestBody Role role){
    if(role.getId() == null){
        roleService.saveRole(role);
        return new ResponseResult(true, 200, "添加角色", null);
    }else{
        roleService.updateRole(role);
        return new ResponseResult(true, 200, "修改角色", null);
    }
}

4.3、菜单模块

4.3.1、菜单列表查询
http://10.1.194.181:8080/ssm-web/menu/findAllMenu
  • 响应结果示例
{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": {
		"pageNum": 1,
		"pageSize": 10,
		"size": 10,
		"orderBy": null,
		"startRow": 1,
		"endRow": 10,
		"total": 26,
		"pages": 3,
		"list": [{
			"id": 1,
			"parentId": -1,
			"href": "",
			"icon": "lock",
			"name": "权限管理",
			"description": "管理系统角色、菜单、资源",
			"orderNum": 1,
			"shown": 1,
			"level": 0,
			"createdTime": 1595230898000,
			"updatedTime": 1595230898000,
			"createdBy": "system",
			"updatedBy": "system",
			"subMenuList": []
		},
		{
			"id": 2,
			"parentId": 1,
			"href": "Role",
			"icon": "lock",
			"name": "角色列表",
			"description": "管理系统角色",
			"orderNum": 1,
			"shown": 1,
			"level": 1,
			"createdTime": 1595230898000,
			"updatedTime": 1595230898000,
			"createdBy": "system",
			"updatedBy": "system",
			"subMenuList": []
		}......]
	}
}

dao层

<select id="findAllMenu" resultType="Menu">
    SELECT
        id,
        parent_id,
        href,
        icon,
        NAME,
        description,
        order_num,
        shown,
        LEVEL,
        created_time,
        updated_time,
        created_by,
        updated_by
    FROM menu
</select>

service层

@Override
public List<Menu> findAllMenu() {
    return menuMapper.findAllMenu();
}

web层

@RequestMapping("/findAllMenu")
public ResponseResult findAllMenu(){
    List<Menu> allMenu = menuService.findAllMenu();
    return new ResponseResult(true, 200, "查询菜单列表成功", allMenu);
}

postman测试
在这里插入图片描述

4.3.2、查询菜单信息(回显)
  • 名称: findMenuInfoById
  • 描述: 根据菜单ID 查询菜单信息
  • URL: http://localhost:8080/ssm-web/menu/findMenuInfoById
  • 请求方式: GET
  • 请求参数
参数名称参数说明in是否必须数据类型备注
id菜单idtrueint如果是新增菜单,则id值为 -1,
修改菜单 则为当前选择的id值
  • 响应结果
参数名称参数说明类型备注
successboolean
stateinteger(int32)
messagestring
contentobject
menuInfo菜单信息Menu修改操作需要回显的菜单信息
parentMenuList菜单列表信息List<Menu所有的父子菜单列表信息

dao层

<select id="findSubMenuListByPid" resultMap="MenuResult">
  select * from menu where parent_id = #{pid}
</select>
<resultMap id="MenuResult" type="menu">
    <id column="id" property="id"></id>
    <result column="href" property="href"></result>
    <result column="icon" property="icon"></result>
    <result column="name" property="name"></result>
    <result column="parent_id" property="parentId"></result>
    <result column="description" property="description"></result>
    <result column="orderNum" property="order_num"></result>
    <result column="shown" property="shown"></result>
    <result column="created_time" property="createdTime"></result>
    <result column="updated_time" property="updatedTime"></result>
    <result column="created_by" property="createdBy"></result>
    <result column="updated_by" property="updatedBy"></result>
    <collection property="subMenuList" ofType="menu" select="com.lzy.dao.MenuMapper.findSubMenuListByPid" column="id"/>
</resultMap>

<select id="findMenuById" resultType="menu">
    select * from menu where id = #{id}
</select>

service层

@Override
public Menu findMenuById(Integer id) {
    return menuMapper.findMenuById(id);
}

@Override
public List<Menu> findSubMenuListByPid(Integer id) {
    return menuMapper.findSubMenuListByPid(id);
}

web层

@RequestMapping("/findMenuInfoById")
public ResponseResult findMenuInfoById(@RequestParam Integer id){
    if(id == -1){
        /*添加操作*/
        List<Menu> subMenuListByPid = menuService.findSubMenuListByPid(-1);

        // 封装数据
        Map<String, Object> map = new HashMap<>();
        map.put("menuInfo", null);
        map.put("parentMenuList", subMenuListByPid);

        return new ResponseResult(true, 200, "菜单信息回显成功", map);
    }else{
        Menu menu = menuService.findMenuById(id);
        List<Menu> subMenuListByPid = menuService.findSubMenuListByPid(-1);

        // 封装数据
        Map<String, Object> map = new HashMap<>();
        map.put("menuInfo", menu);
        map.put("parentMenuList", subMenuListByPid);
        return new ResponseResult(true, 200, "菜单信息回显成功", map);
    }
}

postman测试
在这里插入图片描述

4.3.3、添加&修改菜单
参数名称参数说明是否必须数据类型备注
id菜单列表idint修改操作必须携带id,插入不需要携带
name菜单名称string
href菜单路径string
parentId父菜单idint
description描述string
icon菜单图标string
shown是否展示int
orderNum排序号int
level菜单层级,从0开始int
createdTime创建时间date
updatedTime更新时间date
createdBy创建人string
updatedBy更新人string
  • 请求示例
//新增
{
	"description": "设置课程状态",
	"href": "updateStatus",
	"icon": "lock",
	"name": "课程管理状态",
	"orderNum": 3,
	"parentId": 5,
	"shown": 0,
	"level":0,
	"createdTime":"2020-08-10 20:32:41",
	"updatedTime":"2020-08-10 20:32:41",
	"createdBy":"system",
	"updatedBy":"system"
}

//修改
{
	"id":23,
	"description": "设置课程状态修改",
	"href": "updateStatus修改",
	"icon": "lock",
	"name": "课程管理状态修改",
	"orderNum": 3,
	"parentId": 5,
	"shown": 1,
	"level":1,
	"createdTime":"2020-08-10 20:32:41",
	"updatedTime":"2020-08-10 20:32:41",
	"createdBy":"system",
	"updatedBy":"system"
}

dao层

<insert id="saveMenu" parameterType="menu">
  insert into menu values(null, #{parentId}, #{href}, #{icon}, #{name}, #{description}, #{orderNum},
                       #{shown}, #{level}, #{createdTime}, #{updatedTime}, #{createdBy}, #{updatedBy})
</insert>
<update id="updateMenu" parameterType="menu">
    update menu
    <trim prefix="set" suffixOverrides=",">
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="href != null and href != ''">
            href = #{href},
        </if>
        <if test="icon != null and icon != ''">
            icon = #{icon},
        </if>
        <if test="name != null and name != ''">
            name = #{name},
        </if>
        <if test="orderNum != null and orderNum != ''">
            order_num = #{orderNum},
        </if>
        <if test="parentId != null and parentId != ''">
            parent_id = #{parentId},
        </if>
        <if test="updatedTime != null">
            updated_time = #{updatedTime}
        </if>
    </trim>
    <where>
        <if test="id != null and id != ''">
            id = #{id}
        </if>
    </where>
</update>

service层

@Override
public void saveMenu(Menu menu) {
    // 补全信息
    Date date = new Date();
    menu.setCreatedTime(date);
    menu.setUpdatedTime(date);
    menu.setCreatedBy("system");
    menu.setUpdatedBy("system");

    menuMapper.saveMenu(menu);
}

@Override
public void updateMenu(Menu menu) {
    // 补全信息
    Date date = new Date();
    menu.setUpdatedTime(new Date());
    menuMapper.updateMenu(menu);
}

web层

@RequestMapping("/saveOrUpdateMenu")
public ResponseResult saveOrUpdateMenu(@RequestBody Menu menu){
    if(menu.getId() == null){
        menuService.saveMenu(menu);
        return new ResponseResult(true, 200, "保存菜单成功", null);
    }else{
        menuService.updateMenu(menu);
        return new ResponseResult(true, 200, "修改菜单成功", null);
    }
}

postman测试
在这里插入图片描述

4.4、资源模块

4.4.1、查询资源分类信息
  • 名称: findAllResourceCategory
  • 描述: 查询资源分类信息列表
  • URL: http://localhost:8080/ssm-web/ResourceCategory/findAllResourceCategory
  • 请求方式: GET
  • 请求参数
  • 响应结果示例
{
    "success": true,
    "state": 200,
    "message": "响应成功",
    "content": [
        {
            "id": 1,
            "code": "ADMIN",
            "name": "超级管理员",
            "description": "后台管理员,初始拥有权限管理功能",
            "createdTime": 1595230889000,
            "updatedTime": 1595230889000,
            "createdBy": "system",
            "updatedBy": "system"
        },
        {
            "id": 2,
            "code": "AUTHORITY_MANAGER",
            "name": "权限管理员",
            "description": "管理权限相关数据,如角色、菜单、资源。可以给用户分配角色。",
            "createdTime": 1595202475000,
            "updatedTime": 1595202475000,
            "createdBy": "15510792994",
            "updatedBy": "15510792994"
        },
        {
            "id": 3,
            "code": "COURSE_MANAGER",
            "name": "课程管理员",
            "description": "管理课程信息,对课程、课时、章节进行管理。",
            "createdTime": 1595202724000,
            "updatedTime": 1595202724000,
            "createdBy": "15510792994",
            "updatedBy": "15510792994"
        },
        {
            "id": 4,
            "code": "AD_MANAGER",
            "name": "广告管理员",
            "description": "管理广告、广告位信息",
            "createdTime": 1595202956000,
            "updatedTime": 1595202956000,
            "createdBy": "15510792994",
            "updatedBy": "15510792994"
        }
    ]
}

dao层

<select id="findAllResourceCategory" resultType="ResourceCategory">
    select * from resource_category
</select>

service层

@Service
@Transactional
public class ResourceCategoryServiceImpl implements ResourceCategoryService {
    @Autowired
    private ResourceCategoryMapper resourceCategoryMapper;

    @Override
    public List<ResourceCategory> findAllResourceCategory() {
        return resourceCategoryMapper.findAllResourceCategory();
    }
}

web层

@RestController
@RequestMapping("/ResourceCategory")
public class ResourceCategoryController {
    @Autowired
    private ResourceCategoryService resourceCategoryService;

    @RequestMapping("/findAllResourceCategory")
    public ResponseResult findAllResourceCategory(){
        List<ResourceCategory> allResourceCategory = resourceCategoryService.findAllResourceCategory();
        return new ResponseResult(true, 200, "查询资源分类成功", allResourceCategory);
    }
}

postman测试
在这里插入图片描述

4.4.2、资源信息分页&条件查询
  • 名称: findAllResource
  • 描述: 资源信息分页&条件查询
  • URL: http://localhost:8080/ssm-web/resource/findAllResource
  • 请求方式: POST
  • 请求参数
参数名称参数说明类型备注
currentPage当前页int
pageSize每页显示条数int
name资源名称string
categoryId资源分类idint
url资源路径string
  • 请求参数示例
{
	categoryId: 1,
	currentPage: 1,
	name: "获取所有角色",
	pageSize: 5,
	url: "/boss/role/all"
}
  • 响应结果示例
{
	"success": true,
	"state": 200,
	"message": "响应成功",
	"content": {
		"pageNum": 1,
		"pageSize": 5,
		"size": 1,
		"orderBy": null,
		"startRow": 1,
		"endRow": 1,
		"total": 1,
		"pages": 1,
		"list": [{
			"id": 1,
			"name": "获取所有角色",
			"url": "/boss/role/all",
			"categoryId": 1,
			"description": "获取所有角色",
			"createdTime": 1595230917000,
			"updatedTime": 1595230917000,
			"createdBy": "system",
			"updatedBy": "system"
		}]
	}
}

dao层

<select id="findAllResource" parameterType="resourseVo" resultType="Resource">
 select * from resource
    <where>
        <if test="name != null">
            and name like concat('%',#{name},'%')
        </if>
        <if test="url != null">
            and url = url
        </if>
        <if test="categoryId != null">
            and category_id = #{categoryId}
        </if>
    </where>
</select>

service层

@Service
@Transactional
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;

    @Override
    public PageInfo<Resource> findAllResource(ResourseVo resourceVo) {
        PageHelper.startPage(resourceVo.getCurrentPage(), resourceVo.getPageSize());
        List<Resource> allResource = resourceMapper.findAllResource(resourceVo);
        PageInfo<Resource> resourcePageInfo = new PageInfo<>(allResource);
        return resourcePageInfo;
    }
}

web层

@RestController
@RequestMapping("/resource")
public class ResourceController {
    @Autowired
    private ResourceService resourceService;

    @RequestMapping("/findAllResource")
    public ResponseResult findAllResource(@RequestBody ResourseVo resourseVo){
        PageInfo<Resource> allResource = resourceService.findAllResource(resourseVo);
        return new ResponseResult(true, 200, "资源查询成功", allResource);
    }
}

postaman测试
在这里插入图片描述

4.4.3、添加&更新资源信息
  • 名称: saveOrUpdateResource
  • 描述: 添加&更新资源信息
  • URL: http://localhost:8080/ssm-web/resource/saveOrUpdateResource
  • 请求方式: POST
  • 请求参数
参数名称参数说明in是否必须数据类型备注
id资源idfalse修改操作需要携带ID
name资源名称trueString
url资源路径trueString
categoryId所属资源分类trueInteger
description资源描述trueString

请求示例:

// 添加
{
	"name":"获取所有角色2",
	"url": "/boss/role/all",
	"categoryId":"1",
	"description":"获取所有角色1"
}

// 更新
{
	"id":"53",
	"name":"获取所有角色2",
	"url": "/boss/role/all",
	"categoryId":"1",
	"description":"获取所有角色1"

}

响应参数:

参数名称参数说明类型schema
successboolean
stateinteger(int32)integer(int32)
messagestring
contentobject

dao层

<insert id="saveResource" parameterType="resource">
    insert into resource values(null, #{name}, #{url}, #{categoryId}, #{description},
    #{createdTime}, #{updatedTime}, #{createdBy}, #{updatedBy})
</insert>
<update id="updateResource" parameterType="resource">
    update resource
    <trim prefix="set" suffixOverrides=",">
        <if test="name != null and name != ''">
            name = #{name},
        </if>
        <if test="url != null and url != ''">
            url = #{url},
        </if>
        <if test="categoryId != null and categoryId != ''">
            category_id = #{categoryId},
        </if>
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="updatedTime != null">
            updated_time = #{updatedTime},
        </if>
    </trim>
    <where>
        <if test="id != null and id != ''">
            id = #{id}
        </if>
    </where>
</update>

service层

@Override
public void saveResource(Resource resource) {
    // 补全信息
    Date date = new Date();
    resource.setCreatedTime(date);
    resource.setUpdatedTime(date);
    resource.setCreatedBy("system");
    resource.setUpdatedBy("system");

    resourceMapper.saveResource(resource);
}

@Override
public void updateResource(Resource resource) {
    Date date = new Date();
    resource.setUpdatedTime(date);

    resourceMapper.updateResource(resource);
}

web层

@RequestMapping("/saveOrUpdateResource")
public ResponseResult saveOrUpdateResource(@RequestBody Resource resource){
    if(resource.getId()== null){
        resourceService.saveResource(resource);
        return new ResponseResult(true, 200, "添加资源信息成功", null);
    }else{
        resourceService.updateResource(resource);
        return new ResponseResult(true, 200, "更新资源信息成功", null);
    }
}

postman测试
在这里插入图片描述

4.4.4、删除资源信息
  • 名称: deleteResource

  • 描述: 删除角色

  • URL: http://localhost:8080/ssm-web/resource/deleteResource?id=5

  • 请求方式: GET

  • 请求示例

http://localhost:8080/ssm-web/resource/deleteResource?id=5

响应参数:

参数名称参数说明类型schema
successboolean
stateinteger(int32)integer(int32)
messagestring
contentobject

dao层

<delete id="deleteResource" parameterType="Integer">
 delete from resource where id = #{id}
</delete>

service层

 @Override
public void deleteResource(Integer id) {
    resourceMapper.deleteResource(id);
}

web层

@RequestMapping("/deleteResource")
public ResponseResult deleteResource(Integer id){
    resourceService.deleteResource(id);
    return new ResponseResult(true, 200, "删除资源成功", null);
}

postman测试
在这里插入图片描述

5、登录授权

5.1、用户登录
  • 名称: login
  • 描述: 用户登录
  • URL: http://localhost:8080/ssm-web/user/login
  • 请求方式: GET
  • 请求示例
 http://localhost:8080/ssm-web/user/login?phone=18512341234&password=123456
  • 响应结果示例
{
	state: 1,
	message: "success",
	content: '{
		"access_token": "",
		"user_id": "100030016"
	}',
	success: true
}

dao层

<select id="login" parameterType="user" resultType="user">
    select * from user where phone = #{phone}
</select>

service层

@Override
public User login(User user) throws Exception {
    User login = userMapper.login(user);
    if(login != null && Md5.verify(user.getPassword(), "lagou", user.getPassword())){
        return user;
    }else{
        return null;
    }
}

web层

/*用户登录*/
@RequestMapping("/login")
public ResponseResult login(User user, HttpServletRequest request) throws Exception {
     User login = userService.login(user);
     ResponseResult result = null;
     if(login != null){
         // 保存access_token
         Map<String, Object> map = new HashMap<>();
         String access_token = UUID.randomUUID().toString();
         map.put("access_token", access_token);
         map.put("user_id", login.getId());

         HttpSession session = request.getSession();
         session.setAttribute("user_id", login.getId());
         session.setAttribute("access_token", access_token);

         result = new ResponseResult(true, 1, "响应成功", map);
     }else{
         result = new ResponseResult(true, 1, "用户名密码错误", null);
     }
     return result;
 }
5.2、分配角色(回显)
  • 名称: findUserRoleById
  • 描述: 获取用户拥有的菜单权限
  • URL: http://localhost:8080/ssm-web/user/findUserRoleById
  • 请求方式: GET
  • 请求示例
http://localhost:8080/ssm-web/user/findUserRoleById?id=4
  • 响应结果
参数名称参数说明类型备注
successboolean
stateinteger(int32)
messagestring
contentobject
  • 响应结果示例
{
	"success": true,
	"state": 200,
	"message": "分配角色成功",
	"content": [{
		"id": 2,
		"code": "AUTHORITY_MANAGER",
		"name": "权限管理员",
		"description": "管理权限相关数据,如角色、菜单、资源。可以给用户分配角色。",
		"createdTime": null,
		"updatedTime": null,
		"createdBy": null,
		"updatedBy": null
	},
	{
		"id": 3,
		"code": "COURSE_MANAGER",
		"name": "课程管理员",
		"description": "管理课程信息,对课程、课时、章节进行管理。",
		"createdTime": null,
		"updatedTime": null,
		"createdBy": null,
		"updatedBy": null
	}]
}

dao层

<select id="findUserRelationRoleById" resultType="role" parameterType="int">
  SELECT
        r.id,
        r.code,
        r.name,
        r.description
    FROM roles r INNER JOIN user_role_relation ur
    ON r.`id` = ur.`role_id` INNER JOIN USER u ON ur.`user_id` = u.`id`
    WHERE u.`id` = #{id}
</select>

service层

@Override
public List<Role> findUserRelationRoleById(Integer id) {
    return userMapper.findUserRelationRoleById(id);
}

web层

@RequestMapping("/findUserRoleById")
public ResponseResult findUserRoleById(Integer id){
    List<Role> userRelationRoleById = userService.findUserRelationRoleById(id);
    return new ResponseResult(true, 200, "分配角色回显成功", userRelationRoleById);
}

postman测试
在这里插入图片描述

5.3、分配角色
  • 名称: userContextRole
  • 描述: 获取用户拥有的菜单权限
  • URL: http://localhost:8080/ssm-web/user/userContextRole
  • 请求方式: POST
  • 请求示例
{
	"userId": 4, 
	"roleIdList": [4,5,6]
}
  • 响应结果
参数名称参数说明类型备注
successboolean
stateinteger(int32)
messagestring
contentobject

dao层

<delete id="deleteUserContextRole" parameterType="int">
   delete from user_role_relation where user_id = #{userId}
</delete>

<insert id="userContextRole" parameterType="user_role_relation">
    insert into user_role_relation values(null, #{userId}, #{roleId}, #{createdTime},
            #{updatedTime}, #{createdBy}, #{updatedby})
</insert>

service层

@Override
public List<Role> findUserRelationRoleById(Integer id) {
    return userMapper.findUserRelationRoleById(id);
}

@Override
public void userContextRole(UserVo userVo) {
    // 根据用户id清空中间表的关联关系
    userMapper.deleteUserContextRole(userVo.getUserId());
    
    // 想中间表添加记录
    for (Integer integer : userVo.getRoleIdList()) {
        User_Role_relation userRoleRelation = new User_Role_relation();
        userRoleRelation.setUserId(userVo.getUserId());
        userRoleRelation.setRoleId(integer);
        Date date = new Date();
        userRoleRelation.setCreatedTime(date);
        userRoleRelation.setUpdatedTime(date);

        userRoleRelation.setCreatedBy("system");
        userRoleRelation.setUpdatedby("system");

        userMapper.userContextRole(userRoleRelation);
    }
}

web层

@RequestMapping("/userContextRole")
public ResponseResult userContextRole(@RequestBody UserVo userVo){
    userService.userContextRole(userVo);
    return new ResponseResult(true, 200, "分配角色成功", null);
}

postman测试
在这里插入图片描述

5.4、获取用户拥有的权限
  • 名称: getUserPermissions

  • 描述: 获取用户拥有的菜单权限

  • URL: http://localhost:8080/ssm-web/user/getUserPermissions

  • 请求方式: GET

  • 请求示例

  • 响应结果

参数名称参数说明类型备注
successboolean
stateinteger(int32)
messagestring
contentobject
  • 响应结果示例
{
	"state": 1,
	"message": "success",
	"content": {
		"menuList": [{
			"id": 1,
			"parentId": -1,
			"name": "权限管理",
			"subMenuList": [{
				"id": 2,
				"name": "角色列表"
			},
			{
				"id": 3,
				"name": "菜单列表",
				
			}]
		}],
		"resourceList": [{
			"id": 1,
			"name": "获取所有角色"
		},
		{
			"id": 2,
			"name": "给用户分配角色",
			
		}]
	},
	"success": true
}

dao层

<select id="findParentMenuByRoleId" parameterType="java.util.List"
        resultType="Menu">
    SELECT
    DISTINCT m.*
    FROM roles r INNER JOIN role_menu_relation rm ON r.`id` = rm.role_id
    INNER JOIN menu m ON rm.menu_id = m.id
    WHERE m.parent_id = -1 AND r.id IN
    <foreach collection="list" item="item" open="(" separator=","
             close=")">
        #{item}
    </foreach>
    GROUP BY m.id
</select>

<select id="findSubMenuByPid" resultType="Menu">
    select * from menu where parent_id = #{pid}
</select>

<select id="findResourceByRoleId" parameterType="java.util.List"
        resultType="Resource">
    SELECT
    DISTINCT rc.*
    FROM roles r INNER JOIN role_resource_relation rrr ON r.`id` =
    rrr.`role_id`
    INNER JOIN resource rc ON rrr.`resource_id` = rc.`id` WHERE r.id IN
    <foreach item="item" index="index" collection="list" open="("
             separator="," close=")">
        #{item}
    </foreach>
    GROUP BY rc.id;
</select>

service层

@Override
public ResponseResult getUserPermissions(Integer id) {
    //1.获取当前用户拥有的角色
    List<Role> roleList = userMapper.findUserRelationRoleById(id);
    //2.获取角色ID,保存到 list
    List<Integer> list = new ArrayList<>();
    for (Role role : roleList) {
        list.add(role.getId());
    }
    //3.根据角色id查询 父菜单
    List<Menu> parentMenu = userMapper.findParentMenuByRoleId(list);
    //4.封装父菜单下的子菜单
    for (Menu menu : parentMenu) {
        List<Menu> subMenu = userMapper.findSubMenuByPid(menu.getId());
        menu.setSubMenuList(subMenu);
    }
    //5.获取资源权限
    List<Resource> resourceList = userMapper.findResourceByRoleId(list);
    //6.封装数据
    Map<String,Object> map = new HashMap<>();
    map.put("menuList",parentMenu); //menuList: 菜单权限数据
    map.put("resourceList",resourceList);//resourceList: 资源权限数据
    ResponseResult result = new ResponseResult(true,200,"响应成功",map);
    return result;
}

web层

/**
* 获取用户权限
 * */
@RequestMapping("/getUserPermissions")
public ResponseResult getUserPermissions(HttpServletRequest request){
    //获取请求头中的 token
    String token = request.getHeader("Authorization");
    //获取session中的access_token
    HttpSession session = request.getSession();
    String access_token = (String)session.getAttribute("access_token");
    //判断
    if(token.equals(access_token)){
        int user_id = (Integer)session.getAttribute("user_id");
        ResponseResult result = userService.getUserPermissions(user_id);
        return result;
    }else{
        ResponseResult result = new ResponseResult(false,400,"获取失败","");
        return result;
    }
}

postman测试
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值