SpringBoot + Vue前后端项目分离后台管理系统 笔记 (以及错误总结) 第二篇 后端笔记二

473 阅读8分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

退出数据返回

jwt -username token - 随机码 - redis JwtLogoutSuccessHandler

// 加入Spring 的注解
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
    // 注入 jwt 的工具类
    @Autowired
    JwtUtils jwtUtils;
    @Override
    public void onLogoutSuccess(HttpServletRequest Request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
// 判断是否为空 不为空的话 退出
        if (authentication != null) {
            new SecurityContextLogoutHandler().logout(Request,response,authentication);
        }
        // 响应的格式
        response.setContentType("application/json;charset=UTF-8");
//        输出流
        ServletOutputStream outputStream = response.getOutputStream();
// 头信息
        response.setHeader(jwtUtils.getHeader(), "");
// 返回的 结果

        Results result = Results.succ("");

        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));

        outputStream.flush();
        outputStream.close();
    }
}

无权限数据返回


@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        // 设置头信息 的编码规范
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        // 给一个权限不足的状态吗
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        // 设置输出流
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        // 设置错误的异常输出结果
        Results fail = Results.fail(e.getMessage());
        // 写入的 格式
        outputStream.write(JSONUtil.toJsonStr(fail).getBytes("UTF-8"));
        // 刷新喝关闭流
        outputStream.flush();
        outputStream.close();

    }
}

SpringSecurity就已经完美整合到了我们的项目中来了。

解决跨域问题

上面的调试我们都是使用的postman,如果我们和前端进行对接的时候,会出现跨域的问题 CorsConfig

@Configuration
public class CorsConfig implements WebMvcConfigurer {

	private CorsConfiguration buildConfig() {
		CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.addAllowedOrigin("*");
		corsConfiguration.addAllowedHeader("*");
		corsConfiguration.addAllowedMethod("*");
		corsConfiguration.addExposedHeader("Authorization");
		return corsConfiguration;
	}

	@Bean
	public CorsFilter corsFilter() {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", buildConfig());
		return new CorsFilter(source);
	}

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
				.allowedOrigins("*")
//          .allowCredentials(true)
				.allowedMethods("GET", "POST", "DELETE", "PUT")
				.maxAge(3600);
	}

}

菜单接口开发

开发菜单的接口,因为这3个表:用户表、角色表、菜单表,才有菜单表是不需要通过其他表来获取信息的。比如用户需要关联角色,角色需要关联菜单,而菜单不需要主动关联其他表。 获取菜单导航和权限的链接是/sys/menu/nav,然后我们的菜单导航的json数据应该是这样的:

{   title:
 '角色管理',  
  icon: 'el-icon-rank',  
   path: '/sys/roles',  
    name: 'SysRoles',
       component: 'sys/Role',  
        children: []}

然后返回的权限数据应该是个数组:

["sys:menu:list","sys:menu:save","sys:user:list"...]

注意导航菜单那里有个children,也就是子菜单,是个树形结构,因为我们的菜单可能这样:

系统管理 - 菜单管理 - 添加菜单

这就已经有3级了菜单了。注意这个关系的关联。我们的SysMenu实体类中有个parentId,但是没有children,因此我们可以在SysMenu中添加一个children,当然了其实不添加也可以,因为我们也需要一个dto,这样我们才能按照上面json数据格式返回。 添加一个children吧: SysMenu


@Data
@EqualsAndHashCode(callSuper = true)
public class SysMenu extends BaseEntity {

    private static final long serialVersionUID = 1L;

    /**
     * 父菜单ID,一级菜单为0
     */
    @NotNull(message = "上级菜单不能为空")
    private Long parentId;

    @NotBlank(message = "菜单名称不能为空")
    private String name;

    /**
     * 菜单URL
     */
    private String path;

    /**
     * 授权(多个用逗号分隔,如:user:list,user:create)
     */
    @NotBlank(message = "菜单授权码不能为空")
    private String perms;

    private String component;

    /**
     * 类型     0:目录   1:菜单   2:按钮
     */
    @NotNull(message = "菜单类型不能为空")
    private Integer type;

    /**
     * 菜单图标
     */
    private String icon;

    /**
     * 排序
     */
    @TableField("orderNum")
    private Integer orderNum;

    @TableField(exist = false)
    private List<SysMenu> children = new ArrayList<>();
}

SysMenuDto吧,知道要返回什么样的数据,我们就只需要去填充数据就好了

package com.example.demo.dto;

import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Data
public class SysMenuDto implements Serializable {
    private Long id;
    private String name;
    private String title;
    private String icon;
    private String path;
    private String component;
    private List<SysMenuDto> children = new ArrayList<>();
}

SysMenuController

package com.example.demo.controller;


import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.Result.Results;
import com.example.demo.dto.SysMenuDto;
import com.example.demo.entity.SysMenu;
import com.example.demo.entity.SysRoleMenu;
import com.example.demo.entity.SysUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author fjj
 * @since 2021-07-05
 */
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController extends BaseController {
    // 获取 菜单的 链接
    @GetMapping("/nav")
    // 获取 nav 的导航
    public Results nav(Principal principal) {
        // 获取当前登录的用户
        SysUser byUsername = sysUserService.getByUsername(principal.getName());
        // 获取权限信息  是 用逗号隔开的
        String userAuthorityInfo = sysUserService.getUserAuthorityInfo(byUsername.getId());
//         转换成数组
        String[] strings = StringUtils.tokenizeToStringArray(userAuthorityInfo, ",");
        // 获取导航的信息
        List<SysMenuDto> navs = sysMenuService.getCurrentUserNav();
        // 返回结果
        return Results.succ(MapUtil.builder()
                .put("authoritys", strings)
                .put("nav", navs)
                .build()
        );
    }

    // 获取用户的信息
    @GetMapping("/userInfo")
    public Results userInfo(Principal principal) {
        SysUser sysUser = sysUserService.getByUsername(principal.getName());
        return Results.succ(MapUtil.builder()
                .put("id", sysUser.getId())
                .put("username", sysUser.getUsername())
                .put("avatar", sysUser.getAvatar())
                .put("created", sysUser.getCreated())
                .map()
        );
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:menu:list')")
    public Results info (@PathVariable(name = "id") Long id) {
        return Results.succ(sysMenuService.getById(id));
    }
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:menu:list')")
    public Results list () {
      List<SysMenu> menus =  sysMenuService.tree ();
      return Results.succ(menus);
    }
    //保存
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:menu:save')")
    public Results save (@Validated @RequestBody SysMenu sysMenu) {
       sysMenu.setCreated(LocalDateTime.now());
       sysMenuService.save(sysMenu);
       return Results.succ(sysMenu);
    }
    // 更新
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:menu:update')")
    public Results update (@Validated @RequestBody SysMenu sysMenu) {
        sysMenu.setUpdated(LocalDateTime.now());
        sysMenuService.updateById(sysMenu);
        // 因为是更新的操作,所以需要清楚缓存
        sysUserService.clearUserAuthorityInfoByMenuId(sysMenu.getId());
        return Results.succ(sysMenu);
    }
//     删除
  @PostMapping("/delete/{id}")
  @PreAuthorize("hasAuthority('sys:menu:delete')")
    public Results delete (@PathVariable ("id") Long id) {
        // 判断 子节点还存在不,不存在才可以删除
      int parent_id = sysMenuService.count(new QueryWrapper<SysMenu>().eq("parent_id", id));
      if (parent_id > 0) {
          return Results.fail("请先删除子菜单");
      }
      // 清楚所有的缓存
      sysUserService.clearUserAuthorityInfoByMenuId(id);
      sysMenuService.removeById(id);
      //删除关联表的数据
      sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("menu_id",id));
      return Results.succ("success");
  }
}

方法中Principal principal表示注入当前用户的信息,getName就可以获取当当前用户的用户名了。sysUserService.getUserAuthorityInfo方法我们之前已经说过了,就在我们登录完成或者身份认证时候需要返回用户权限时候编写的。然后通过StringUtils.tokenizeToStringArray把字符串通过逗号分开组成数组形式。 重点在与sysMenuService.getcurrentUserNav,获取当前用户的菜单导航, SysMenuServiceImpl

package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.dto.SysMenuDto;
import com.example.demo.entity.SysMenu;
import com.example.demo.entity.SysUser;
import com.example.demo.mapper.SysMenuMapper;
import com.example.demo.mapper.SysUserMapper;
import com.example.demo.service.ISysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author fjj
 * @since 2021-07-05
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
    @Autowired
    SysUserServiceImpl sysUserService;
    @Autowired
    SysUserMapper sysUserMapper;

    @Override
    public List<SysMenuDto> getCurrentUserNav() {
        // 获取 登录的用户
        String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        // 通过用户名获取
        SysUser sysUser = sysUserService.getByUsername(username);
        // 通过 用户Id 获取 菜单Id
        List<Long> navMenuIds = sysUserMapper.getNavMenuIds(sysUser.getId());
        // 通过菜单 id 获取 菜单
        List<SysMenu> sysMenus = this.listByIds(navMenuIds);
        // 转换成树桩结构
        List<SysMenu> menustree = buildTreeMeun(sysMenus);
        // 实体类转换
        return convert(menustree);
    }

    @Override
    public List<SysMenu> tree() {
        // 获取所有菜单信息
        List<SysMenu> sysMenus = this.list(new QueryWrapper<SysMenu>().orderByAsc("orderNum"));
        // 转成 树桩结构
        List<SysMenu> menus = buildTreeMeun(sysMenus);
        return menus;
    }

    private List<SysMenuDto> convert(List<SysMenu> menustree) {
        ArrayList<SysMenuDto> menuDtos = new ArrayList<>();
        menustree.forEach(m -> {
            SysMenuDto dto = new SysMenuDto();
            dto.setId(m.getId());
            dto.setName(m.getPerms());
            dto.setTitle(m.getName());
            dto.setComponent(m.getComponent());
            dto.setPath(m.getPath());
            // 如果 长度大于就给 字节点复制
            if (m.getChildren().size() > 0) {
                // 子节点调用当前的方法 进行复制。
                dto.setChildren(convert(m.getChildren()));
            }
            menuDtos.add(dto);
        });
        return menuDtos;
    }
// 转换树桩结构
    private List<SysMenu> buildTreeMeun(List<SysMenu> sysMenus) {
        // 准备返回的list
        ArrayList<SysMenu> finalMenus = new ArrayList<>();
        // 找到各自的子节点
        for (SysMenu sysMenu : sysMenus) {
            for (SysMenu sysMenu1 : sysMenus) {
            // 如果 id 相同说明就是自己的孩子了
                if (sysMenu.getId() == sysMenu1.getParentId()) {
                    sysMenu.getChildren().add(sysMenu1);
                }
            }
            // 提取出来父节点
            if (sysMenu.getParentId() == 0L) {
                finalMenus.add(sysMenu);
            }
        }
        return finalMenus;
    }
}

接口中sysUserMapper.getNavMenuIds我们之前就已经写过的了,通过用户id获取菜单的id,然后后面就是转成树形结构,buildTreeMenu方法的思想很简单,我们现实把菜单循环,让所有菜单先找到各自的子节点,然后我们在把最顶级的菜单获取出来,这样顶级下面有二级,二级也有自己的三级。最后就是convert把menu转成menuDto。这个比较简单,就不说了。好了,导航菜单已经开发完毕,我们来写菜单管理的增删改查,因为菜单列表也是个树形接口,这次我们就不是获取当前用户的菜单列表的,而是所有菜单然后组成树形结构,一样的思想,数据不一样而已。 删除、更新菜单的时候记得调用根据菜单id清楚用户权限缓存信息的方法哈。然后每个方法前都会带有权限注解:@PreAuthorize("hasAuthority('sys:menu:delete')"),这就要求用户有特定的操作权限才能调用这个接口,sys:menu:delete这些数据不是乱写出来的,我们必须和数据库的数据保持一致才行,然后component字段,也是要和前端进行沟通,因为这个是链接到的前端的组件页面。有了增删改查,我们就去先添加我们的所有的菜单权限数据先。效果如下: 在这里插入图片描述 在这里插入图片描述

角色接口开发

角色的增删改查其实也简单,而且字段这么少 SysRoleController

package com.example.demo.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Result.Results;
import com.example.demo.entity.SysMenu;
import com.example.demo.entity.SysRole;
import com.example.demo.entity.SysRoleMenu;
import com.example.demo.entity.SysUserRole;
import com.example.demo.utils.Const;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author fjj
 * @since 2021-07-05
 */
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/info/{id}")
    public Results info(@PathVariable("id") Long id) {
        // 获取到实体类
        SysRole byId = sysRoleService.getById(id);
        //获取关联表的 meunid
        List<SysRoleMenu> role_id = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", byId));
        // 通过 流 来获取 出meunid
        List<Long> collect = role_id.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        byId.setMenuIds(collect);
        return Results.succ(byId);
    }
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/list")
    public Results list(String name) {
        // 分页查询 ,判断有没有名字
        Page page = sysRoleService.page(getPage(),
                new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name), "name", name));
        return Results.succ(page);
    }
    @PreAuthorize("hasAuthority('sys:role:save')")
    @PostMapping("/save")
    public Results save(@Validated @RequestBody SysRole sysRole) {
        // 新增 的方法
        // 获取当前的 更改的时间
        sysRole.setCreated(LocalDateTime.now());
        // 保存的状态
        sysRole.setStatu(Const.STATUS_ON);
        sysRoleService.save(sysRole);
        return Results.succ(sysRole);
    }
    @PreAuthorize("hasAuthority('sys:role:update')")
    // 更新的
    @PostMapping("/update")
    public Results update(@Validated @RequestBody SysRole sysRole) {
        // 设置更新的时间
        sysRole.setCreated(LocalDateTime.now());
        //调用更新的方法
        sysRoleService.updateById(sysRole);
        // 删除 缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());
        return Results.succ(sysRole);
    }
// 批量删除
@PreAuthorize("hasAuthority('sys:role:delete')")
    @PostMapping("/delete")
    //加上事务避免出现 删除失败的情况
    @Transactional
    public Results delete(@RequestBody Long[] RoleIds) {
        // 调用方法
        sysRoleService.removeByIds(Arrays.asList(RoleIds));
        // 删除中间表
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id",RoleIds));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id",RoleIds));
        // 删除缓存
        Arrays.stream(RoleIds).forEach(f -> {
            sysUserService.clearUserAuthorityInfoByRoleId(f);
        });
        return Results.succ("success");
    }
    @PreAuthorize("hasAuthority('sys:role:perm')")
    @PostMapping("/perm/{roleId}")
    @Transactional
    public Results info(@PathVariable("roleId") Long roleId,@RequestBody Long[] menuId) {
        // 用来存放的集合
       List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
       Arrays.stream(menuId).forEach(menuid -> {
           SysRoleMenu roleMenu = new SysRoleMenu();
           roleMenu.setMenuId(menuid);
           roleMenu.setRoleId(roleId);
           sysRoleMenus.add(roleMenu);
       });
       //删除记录
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",roleId));
        //保存新的
        sysRoleMenuService.saveBatch(sysRoleMenus);
        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return Results.succ(menuId);
    }
}


上面方法中:info方法获取角色信息的方法,因为我们不仅仅在编辑角色时候会用到这个方法,在回显角色关联菜单的时候也需要被调用,因此我们需要把角色关联的所有的菜单的id也一并查询出来,也就是分配权限的操作。对应到前端就是这样的,点击分配权限,会弹出出所有的菜单列表,然后根据角色已经关联的菜单的id回显勾选上已经关联过的。

用户接口开发

用户管理里面有个用户关联角色的分配角色操作,和角色关联菜单的写法差不多的

package com.example.demo.controller;


import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Result.Results;
import com.example.demo.dto.PassDto;
import com.example.demo.entity.SysRole;
import com.example.demo.entity.SysRoleMenu;
import com.example.demo.entity.SysUser;
import com.example.demo.entity.SysUserRole;
import com.example.demo.utils.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author fjj
 * @since 2021-07-05
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController extends BaseController {
    // 注入加密的
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public Results info(@PathVariable("id") Long id) {
        SysUser sysUser = sysUserService.getById(id);
        // 断言判断是不是为空
        Assert.notNull(sysUser, "找不到该管理员");
        List<SysRole> sysRoles = sysRoleService.listRolesByUserId(id);
        sysUser.setSysRoles(sysRoles);
        return Results.succ(sysUser);
    }
    @PreAuthorize("hasAuthority('sys:user:list')")
    @GetMapping("/list")
    public Results list(String username) {
        Page<SysUser> page = sysUserService.page(getPage(), new QueryWrapper<SysUser>().like(StringUtils.isNotBlank(username), "username", username));
        page.getRecords().forEach(p -> {
            p.setSysRoles(sysRoleService.listRolesByUserId(p.getId()));
        });
        return Results.succ(page);
    }
    @PreAuthorize("hasAuthority('sys:user:save')")
    @PostMapping("/save")
    public Results save(@Validated @RequestBody SysUser sysUser) {
        // 设置 更新时间
        sysUser.setCreated(LocalDateTime.now());
        // 默认的状态
        sysUser.setStatu(Const.STATUS_ON);
        // 设置默认的加密的密码
        String password = bCryptPasswordEncoder.encode(Const.PASS_WORD);
        sysUser.setPassword(password);
        // 设置默认的头像
        sysUser.setAvatar(Const.Avatar);
        sysUserService.save(sysUser);
        return Results.succ(sysUser);
    }
    @PreAuthorize("hasAuthority('sys:user:update')")
    @PostMapping("/update")
    public Results update(@Validated @RequestBody SysUser sysUser) {
        // 设置更新的时间
//        sysUser.setCreated(LocalDateTime.now());
        sysUser.setUpdated(LocalDateTime.now());
        sysUserService.updateById(sysUser);
        return Results.succ(sysUser);
    }
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @PostMapping("/delete")
    @Transactional
    public Results delete(@RequestBody Long [] ids) {
        sysUserService.removeByIds(Arrays.asList(ids));
        // 删除中间的关系表
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",ids));
        return Results.succ("");
    }
    @PreAuthorize("hasAuthority('sys:user:role')")
    @PostMapping("/role/{userId}")
    @Transactional
    public Results rolePerm(@PathVariable Long userId,@RequestBody Long [] roleIds) {
        ArrayList<SysUserRole> UserRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(r ->{
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(r);
            userRole.setUserId(userId);
            UserRoleList.add(userRole);
        });
        // 删除关联表的数据
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",userId));
        sysUserRoleService.saveBatch(UserRoleList);
        // 删除缓存
        SysUser sysUser = sysUserService.getById(userId);
        sysUserService.clearUserAuthorityInfo(sysUser.getUsername());
        return Results.succ("");
    }

    @PostMapping("/repass")
    @PreAuthorize("hasAuthority('sys:user:repass')")
    public Results repass(@RequestBody Long id) {
        SysUser byId = sysUserService.getById(id);
        byId.setPassword(bCryptPasswordEncoder.encode(Const.PASS_WORD));
        byId.setCreated(LocalDateTime.now());
        sysUserService.save(byId);
        return Results.succ("");
    }
    //  个人中心修改

    @PostMapping("/updatePass")
    public Results updatePass(@Validated @RequestBody PassDto passDto, Principal principal) {
        SysUser sysUser = sysUserService.getByUsername(principal.getName());
        boolean matches = bCryptPasswordEncoder.matches(passDto.getCurrentPass(), sysUser.getPassword());
        if (!matches) {
            return Results.fail("密码不正确");
        }
        sysUser.setPassword(bCryptPasswordEncoder.encode(Const.PASS_WORD));
        sysUser.setUpdated(LocalDateTime.now());
        sysUserService.updateById(sysUser);
        return Results.succ("");
    }

}

上面用到一个sysRoleService.listRolesByUserId,通过用户id获取所有关联的角色,用到了中间表,可以写sql,这里我这样写的

@Overridepublic List<SysRole> listRolesByUserId(Long userId) {   return this.list(         new QueryWrapper<SysRole>()               .inSql("id", "select role_id from sys_user_role where user_id = " + userId));}

userId一定要是自己数据库查出来的,千万别让前端传过来啥就直接调用这个方法,不然会可能会被攻击 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

结束

所有的资源放在了资源里面可以下载。

参考的up主 添加链接描述