栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringSecurity实现权限管理系统

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringSecurity实现权限管理系统

因为篇幅原因请先参考这篇文章实现登录功能https://blog.csdn.net/grd_java/article/details/121925792

文章目录
  • 一、 数据库表,和实体类
  • 二、菜单管理TODO
    • 1. 实体类
    • 2. Redis 缓存
    • 3. 编写逻辑,查询菜单
  • 三、url角色权限
    • 1. url权限,在全局中设置用户访问的url,需要哪些权限
      • 1. 实现获取每个菜单所需角色权限
      • 2. SpringSecurity 过滤器,拦截请求,获取url,判断url需要哪些角色权限
    • 2. 获取用户角色,判断用户角色权限能否访问url
      • 1. 实现获取角色
      • 2. Security 过滤器,判断用户角色是否可以访问
      • 3. 配置SpringSecurity,让过滤器生效
      • 4. 测试
  • 四、权限组功能实现
    • 1. 角色
    • 2. 菜单
    • 3. 用户
    • 4. 主要功能测试
  • 五、前端对接

一、 数据库表,和实体类
因为前端是VUE写到,所以需要保存组件、路径等




  1. 所有库的sql语句
 
二、菜单管理TODO 

最终结果

1. 实体类

通过Mybatis-plus插件代码生成器,自动生成,然后添加一个字段children

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.List;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;


@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="DdMenu对象", description="")
public class DdMenu implements Serializable {

    private static final long serialVersionUID=1L;

    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "父菜单id")
    private Integer pid;

    @ApiModelProperty(value = "菜单名")
    private String name;

    @ApiModelProperty(value = "菜单类型(目录,按钮)")
    private String type;

    @ApiModelProperty(value = "菜单权限")
    private String permission;

    @ApiModelProperty(value = "url")
    private String url;

    @ApiModelProperty(value = "path")
    private String path;

    @ApiModelProperty(value = "组件")
    private String component;

    @ApiModelProperty(value = "图标")
    @TableField("iconCls")
    private String iconCls;

    @ApiModelProperty(value = "是否保持激活")
    @TableField("keepAlive")
    private Boolean keepAlive;

    @ApiModelProperty(value = "是否要求权限")
    @TableField("requireAuth")
    private Boolean requireAuth;

    @ApiModelProperty(value = "是否启用")
    private Boolean enabled;

    @ApiModelProperty(value = "子菜单")
    @TableField(exist = false)//告诉Mybatis,表中没有这个字段,否则操作时会去数据库找这个字段
    private List children;
}
2. Redis 缓存
  1. 启动redis
  2. 添加依赖


    org.springframework.boot
    spring-boot-starter-data-redis



    org.apache.commons
    commons-pool2

  1. redis配置
spring:
  redis: #redis配置
    host: 127.0.0.1 #你的redis地址
    port: 6379 #端口号
    database: 0
    timeout: 1800000
    lettuce:
      pool:
        max-active: 1024 # 最大连接数
        max-wait: -1 #最大阻塞等待时间(负数表示没限制)
        max-idle: 200 #最大空闲连接
        min-idle: 5 #最小空闲连接
  1. Redis配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate<>();
        //String 类型 key序列器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //String 类型 value序列器
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //Hash 类型 key序列器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //Hash 类型 value序列器
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        //配置工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
}

3. 编写逻辑,查询菜单
  1. controller
import com.dd.security.entity.DdMenu;
import com.dd.security.service.DdMenuService;
import com.dd.security.service.DdUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;


@RestController
@RequestMapping("/security/dd-menu")
public class DdMenuController {
    @Autowired
    private DdMenuService ddMenuService;

    @ApiOperation(value = "通过用户id查询菜单列表")
    @GetMapping("/menu")
    public List getMenusByUserId(){
        return ddMenuService.getMenusByUserId();
    }
}
  1. service
import com.dd.security.entity.DdMenu;
import com.dd.security.entity.DdUser;
import com.dd.security.mapper.DdMenuMapper;
import com.dd.security.service.DdMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.awt.*;
import java.util.List;


@Service
public class DdMenuServiceImpl extends ServiceImpl implements DdMenuService {

    @Autowired
    private DdMenuMapper ddMenuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    
    @Override
    public List getMenusByUserId() {
        //Security全局上下文获取UserDetails对象
        DdUser user = (DdUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //获取redis对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //先从redis中查询
        List menus = (List) valueOperations.get("menu_" + user.getId());
        //如果redis中没有,查询mysql数据库
        if(CollectionUtils.isEmpty(menus)){
            menus = ddMenuMapper.getMenusByUserId(user.getId());
            //将查询出来的内容放在reids中
            valueOperations.set("menu_" + user.getId(),menus);
        }
        //返回结果
        return menus;
    }
}

  1. mapper
select
	distinct
	m1.*,
	m2.id as id2,
	m2.pid as pid2,
	m2.`name` as name2,
	m2.type as type2,
	m2.permission as permission2,
	m2.url as url2,
	m2.path as path2,
	m2.component as component2,
	m2.iconCls as iconCls2,
	m2.keepAlive as keepAlive2,
	m2.requireAuth as requireAuth,
	m2.enabled as enabled2
from
	dd_menu as m1 
inner join
	dd_menu as m2 #自关联
on
	m1.id = m2.pid
inner join
	dd_role_menu as rm
on
	rm.mid = m2.id
inner join
	dd_user_role as ur
on
	ur.rid = rm.rid
where
	ur.uid = 1






    
    
        
        
        
        
        
        
        
        
        
        
        
        
    
    
    
        
            
            
            
            
            
            
            
            
            
            
            
            
        
    

    
        select
            distinct
            m1.*,
            m2.id as id2,
            m2.pid as pid2,
            m2.`name` as name2,
            m2.type as type2,
            m2.permission as permission2,
            m2.url as url2,
            m2.path as path2,
            m2.component as component2,
            m2.iconCls as iconCls2,
            m2.keepAlive as keepAlive2,
            m2.requireAuth as requireAuth,
            m2.enabled as enabled2
        from
            dd_menu as m1
                inner join
            dd_menu as m2
            on
                m1.id = m2.pid
                inner join
            dd_role_menu as rm
            on
                rm.mid = m2.id
                inner join
            dd_user_role as ur
            on
                ur.rid = rm.rid
        where
            ur.uid = #{id}
    

三、url角色权限
我们如果只控制菜单,用户登录后进入管理系统,只能看到自己角色权限对应的菜单,但是如果这个用户此时通过某种手段获取了我们后台的接口对应的url,那么他就算前端看不到相应的菜单和按钮,无法通过事件访问后端接口。也可以直接通过浏览器地址栏输入url,因为它已经登录过,这时,就可以直接访问url了,尽管我们不想让他具有访问这些接口的权限,让他看不见相应的菜单和按钮,此时也只能眼睁睁看着他获取数据
如何处理这种情况呢,我们的菜单表有一个url字段,记录了url地址
  1. 我们在菜单实体类中,添加访问此url和菜单,需要的角色、权限属性
  2. 规定,菜单表中的url都需要特定的角色和权限才能访问,取余的url,可以允许没有角色或拥有LOGIN_ROLE默认角色的用户访问。
  3. 当用户访问后端时,先过滤请求,判断用户请求的是否是菜单表的url,如果是,判断是否具有相应权限,没有权限拦截请求,返回权限不足。如果不是菜单表url,为其添加默认角色LOGIN_ROLE角色
最终效果



访问需要ROLE_admin角色的路径可以正常访问

访问需要其它角色的url提示权限不足

访问不需要授权的路径,不会触发过滤,不会拦截判断url需要的权限

1. url权限,在全局中设置用户访问的url,需要哪些权限 1. 实现获取每个菜单所需角色权限
实现根据角色获取菜单列表,就是每个菜单有哪些角色有权限

  1. 修改菜单实体类,添加角色属性
  2. service接口

  3. mapper



    
        
        
        
    


    select
        r.id as id,
        r.name as name,
        r.name_zh as nameZh
    from
        dd_role as r
            inner join
        dd_user_role as ur
        on
            r.id = ur.rid
    where
        ur.uid = #{userId}

  1. 修改获取用户信息
  2. 修改自定义UserDetailsService
 
 @Bean
 @Override
 public UserDetailsService userDetailsService() {
     return username->{
         DdUser user = ddUserService.getLoginInfoByUsername(username);
         if(user == null){
             throw new UsernameNotFoundException("用户名或密码不正确");
         }
         List rolesByUserId = ddRoleService.getRolesByUserId(user.getId());
         user.setRoles(rolesByUserId);
         return user;
     };
 }
2. Security 过滤器,判断用户角色是否可以访问

截图中忘了加@Component注解

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;


import java.util.Collection;
@Component
public class CustomUrlDecisionManager implements AccessDecisionManager {
    
    @Override
    public void decide(Authentication authentication, Object o, Collection collection) throws AccessDeniedException, InsufficientAuthenticationException {

        //遍历ConfigAttribute
        for(ConfigAttribute configAttribute : collection){
            //获取当前访问url,需要的角色权限,这些值在再CustomFilter中设置进去的
            String needRole = configAttribute.getAttribute();
            //判断url是否登录即可访问,再CustomFilter 中设置
            if("ROLE_LOGIN".equals(needRole)){
                //如果当前用户是匿名用户(未登录用户),抛异常,让用户登录
                if(authentication instanceof AnonymousAuthenticationToken){
                    throw new AccessDeniedException("尚未登录,请登录!!!");
                }else{
                    return;
                }
            }
            //如果当前url,不是登录就可以访问的
            //判断当前用户的GrantedAuthority里面有没有需要的角色,如果有就放行
            //如果用户没有相应角色,就不放行,同时:没登录的用户因为没有角色,也不会被放行
            Collection authorities = authentication.getAuthorities();
            for(GrantedAuthority authority:authorities){
                if(authority.getAuthority().equals(needRole)){
                    return;
                }
            }
        }
        throw new AccessDeniedException("权限不足,请联系管理员!!!");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return false;
    }

    @Override
    public boolean supports(Class aClass) {
        return false;
    }
}
3. 配置SpringSecurity,让过滤器生效
说明:这些过滤器不会过滤在Security配置类中放行的路径

  1. 引入两个过滤器
  2. 动态权限配置两个过滤器
@Override
protected void configure(HttpSecurity http) throws Exception {

    //使用JWT不需要csrg
    http.csrf().disable()
            //使用Token,不需要session
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()//接下来配置授权
            .authorizeRequests()
            //下面授权在configure(WebSecurity web)方法中配置了,这里不需要了
//                .antMatchers("/login","/logout").permitAll()//允许访问/login,/logout的请求无需认证即可通行
            .anyRequest().authenticated()//除了上面配置的,剩下的请求全部拦截,必须认证通过才能访问
            .withObjectPostProcessor(new ObjectPostProcessor() {//动态权限配置
                @Override
                public  O postProcess(O o) {
                    o.setAccessDecisionManager(customUrlDecisionManager);//判断用户角色是否可以访问url过滤器
                    o.setSecuritymetadataSource(customFilter);//根据请求url分析所需角色过滤器
                    return o;
                }
            })
            .and()//接下来配置缓存
            .headers()
            .cacheControl()
            ;
    //添加JWT登录授权过滤拦截器
    http.addFilterBefore(jwtAuthencationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    //添加自定义未授权,和未登录结果返回,前后端分离,需要返回状态码
    http.exceptionHandling()
            .accessDeniedHandler(restAccessDeniedHandler)
            .authenticationEntryPoint(restAuthorizationEntryPoint);

}
4. 测试


四、权限组功能实现 1. 角色
SpringSecurity 的角色必须带有ROLE_前缀,否则不会被SpringSecurity捕获

正确的角色名:ROLE_admin、ROLE_adsfasdf
错误的角色名:r_admin、admin、ROLE_

  1. 所以当我们添加角色时,要判断用户是否以ROLE_开头,不是就补充上再执行添加逻辑,是就直接执行添加逻辑
  1. Controller
import com.dd.common_utils.Result;
import com.dd.security.entity.DdRole;
import com.dd.security.service.DdRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/security/dd-role")
public class DdRoleController {
    @Autowired
    private DdRoleService ddRoleService;

    @ApiOperation("获取所有角色")
    @GetMapping("/")
    public Result getAllRoles(){
        List list = ddRoleService.list();
        if(list.isEmpty()){
            return Result.error().message("没有获取的任何角色信息!!!");
        }
        return Result.ok().data("RoleAllList",list);
    }
    @ApiOperation("添加角色")
    @PostMapping("/")
    public Result addRole(@RequestBody DdRole ddRole){
        //如果角色名不是ROLE_打头,就补充上
        if(!ddRole.getName().startsWith("ROLE_")){
            ddRole.setName("ROLE_"+ddRole.getName());
        }
        if(ddRoleService.save(ddRole)){
            return Result.ok().message("添加成功");
        }
        return Result.error().message("添加失败");
    }

    @ApiOperation("删除角色")
    @DeleteMapping("/role/{id}")
    public Result deleteRole(@PathVariable(value = "id",name = "id") Integer id){
        if(ddRoleService.removeById(id)){
            return Result.ok().message("删除成功");
        }
        return Result.error().message("删除失败");
    }
}
2. 菜单
  1. controller
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dd.common_utils.Result;
import com.dd.security.entity.DdMenu;
import com.dd.security.entity.DdRoleMenu;
import com.dd.security.service.DdMenuService;
import com.dd.security.service.DdRoleMenuService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/security/dd-menu")
public class DdMenuController {
    @Autowired
    private DdMenuService ddMenuService;
    @Autowired
    private DdRoleMenuService ddRoleMenuService;

    @ApiOperation(value = "通过用户id查询菜单列表")
    @GetMapping("/menu")
    public List getMenusByUserId(){
        return ddMenuService.getMenusByUserId();
    }

    @ApiOperation(value = "查询所有菜单")
    @GetMapping("/menus")
    public Result getMenus(){
        List list = ddMenuService.list();
        if(list.isEmpty()){
            return Result.error().message("没有菜单!!");
        }
        return Result.ok().data("menuAllList",list);
    }

    @ApiOperation(value = "根据角色id查询菜单id")
    @GetMapping("/menuIdByRoleId/{rid}")
    public Result getMenuIdByRoleId(@PathVariable Integer rid){
        List mids = ddRoleMenuService.list(new QueryWrapper().eq("rid", rid))
                .stream().map(DdRoleMenu::getMid).collect(Collectors.toList());
        if(mids.isEmpty()){
            return Result.error().message("获取菜单失败");
        }
        return Result.ok().data("menuId",mids);
    }

    @ApiOperation(value = "根据角色id查询菜单")
    @GetMapping("/menuByRoleId/{rid}")
    public Result getMenuByRoleId(@PathVariable Integer rid){
        List list = ddMenuService.getMenuByRoleId(rid);
        if(list.isEmpty()){
            return Result.error().message("没有菜单!!");
        }
        return Result.ok().data("menuList",list);
    }

    @ApiOperation(value = "更新角色菜单")
    @PutMapping("/")
    public Result updateMenuRole(Integer rid,Integer[] mids){
        return ddMenuService.updateMenuRole(rid,mids);
    }
}
  1. service

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dd.common_utils.Result;
import com.dd.security.entity.DdMenu;
import com.dd.security.entity.DdRoleMenu;
import com.dd.security.entity.DdUser;
import com.dd.security.mapper.DdMenuMapper;
import com.dd.security.mapper.DdRoleMenuMapper;
import com.dd.security.service.DdMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.security.service.DdRoleMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.awt.*;
import java.util.List;


@Service
public class DdMenuServiceImpl extends ServiceImpl implements DdMenuService {

    @Autowired
    private DdMenuMapper ddMenuMapper;
    @Autowired
    private DdRoleMenuMapper ddRoleMenuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    
    @Override
    public List getMenusByUserId() {
        //Security全局上下文获取UserDetails对象
        DdUser user = (DdUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //获取redis对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //先从redis中查询
        List menus = (List) valueOperations.get("menu_" + user.getId());
        //如果redis中没有,查询mysql数据库
        if(CollectionUtils.isEmpty(menus)){
            menus = ddMenuMapper.getMenusByUserId(user.getId());
            //将查询出来的内容放在reids中
            valueOperations.set("menu_" + user.getId(),menus);
        }
        //返回结果
        return menus;
    }

    
    @Override
    public List getMenusWithRole() {
        return ddMenuMapper.getMenusWithRole();
    }

    @Override
    public List getMenuByRoleId(Integer rid) {
        return ddMenuMapper.getMenuByRoleId(rid);
    }

    
    @Override
    @Transactional//自己写更新的操作,一定要加事务
    public Result updateMenuRole(Integer rid, Integer[] mids) {
        //先全删了,否则得一次次判断,太费资源
        ddRoleMenuMapper.delete(new QueryWrapper().eq("rid", rid));
        //要更新的菜单id为空,则直接返回
        if(null == mids||mids.length == 0){
            return Result.ok().message("更新菜单成功");
        }
        //如果传了菜单id过来,则更新
        ddMenuMapper.insertRecord(rid,mids);
        return null;
    }
}
  1. mapper

    
    
        insert into dd_role_menu(rid,mid) values
        
            (#{rid},#{mid})
        
    
3. 用户
  1. controller

import com.dd.common_utils.Result;
import com.dd.security.entity.DdMenu;
import com.dd.security.entity.DdUser;
import com.dd.security.service.DdUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@RestController
@Api("传递查询条件时,不要携带security的字段,只携带DdUser对象本身的字段,JSON")
@RequestMapping("/security/dd-user-role")
public class DdUserRoleController {
    @Autowired
    private DdUserService ddUserService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @ApiOperation("获取所有操作员以及它拥有的角色和权限,传递查询条件时,不要携带security的字段,只携带DdUser对象本身的字段,JSON")
    @PostMapping("/")
    public Result getAllUser(@RequestBody DdUser ddUser){
        List list = ddUserService.getAllUser(ddUser);
        if(list.isEmpty()){
           return Result.error().message("没有获取的用户信息!!!");
        }
        return Result.ok().data("allUserList",list);
    }

    @ApiOperation("更新用户")
    @PutMapping("/")
    public Result updateUser(@RequestBody DdUser ddUser){
        ddUser.setPassword(null);//不允许直接改密码

        if(ddUserService.updateById(ddUser)){
          return Result.ok().message("修改用户成功!!!");
        }
        return Result.error().message("修改失败!!!");
    }

    @ApiOperation("更新用户拥有的角色")
    @PutMapping("/updateUserRole")
    public Result updateUserRole(Integer uid,Integer[] rids){
        return ddUserService.updateUserRole(uid,rids);
    }

    @ApiOperation("修改密码")
    @PutMapping("/updatePasswordById/{id}/{password}")
    public Result updatePassword(@PathVariable Integer id, @PathVariable String password){
        String encode = passwordEncoder.encode(password);
        DdUser ddUser = new DdUser();
        ddUser.setId(id);
        ddUser.setPassword(encode);
        if(ddUserService.updateById(ddUser)){
           return Result.ok().message("修改密码成功!!!");
        }
        return Result.error().message("修改密码失败!!!");
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public Result deleteById(@PathVariable Integer id){
        if(ddUserService.removeById(id)){
            return Result.ok().message("删除成功!!!");
        }
        return Result.error().message("删除失败!!!");
    }

}
  1. service

@Autowired
private DdUserRoleMapper ddUserRoleMapper;

@Override
public List getAllUser(DdUser ddUser) {

    return ddUserMapper.getAllUser(ddUser);
}


@Override
@Transactional//自己写更新的操作,一定要加事务
public Result updateUserRole(Integer uid, Integer[] rids) {
    //先全删了,否则得一次次判断,太费资源
    ddUserRoleMapper.delete(new QueryWrapper().eq("uid", uid));
    //要更新的菜单id为空,则直接返回
    if(null == rids||rids.length == 0){
        return Result.ok().message("更新用户角色成功");
    }
    //如果传了菜单id过来,则更新
    ddUserMapper.insertRecord(uid,rids);
    return Result.ok().message("更新菜单成功");
}
  1. mapper





    
    
        
        
        
    

    
        
            
            
            
        
    

    
        select
        u.id as id,
            u.username as username,
            u.`password` as `password`,
            r.id as rid,
            r.`name` as rname,
            r.name_zh as rnameZh
        from
            dd_user as u
        inner join
            dd_user_role as ur
        on
            u.id = ur.uid
        inner join
            dd_role as r
        on
            ur.rid = r.id
        
            
                and u.id = #{id}
                and u.username like concat('%', #{username}, '%')
            
        
    
    
    
        insert into dd_user_role(uid,rid) values
        
            (#{uid},#{rid})
        
    

4. 主要功能测试
  1. 菜单

五、前端对接
由于篇幅限制,我将其放在这篇文章中
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/666141.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号