From d08946ec5e4aa6b074cc27ff884e0d6c69c9dbc3 Mon Sep 17 00:00:00 2001 From: Bunny <1319900154@qq.com> Date: Sun, 27 Oct 2024 17:27:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=A8=E6=88=B7=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E7=94=A8=E9=82=AE=E7=AE=B1=E6=88=96=E8=80=85=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=90=8D=E7=99=BB=E5=BD=95,=E4=BF=AE=E6=94=B9=E9=83=A8?= =?UTF-8?q?=E5=88=86=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bunny/common/service/utils/JwtHelper.java | 28 ++++--- .../dao/dto/system/user/AdminUserAddDto.java | 4 +- .../dao/dto/system/user/AdminUserDto.java | 4 +- .../user/AdminUserUpdateByLocalUserDto.java | 9 +- .../dto/system/user/AdminUserUpdateDto.java | 4 +- .../cn/bunny/dao/entity/system/AdminUser.java | 4 +- .../bunny/dao/pojo/result/ResultCodeEnum.java | 3 +- .../java/cn/bunny/dao/view/ViewRolePower.java | 37 ++++++++ .../cn/bunny/dao/view/ViewRouterRole.java | 58 +++++++++++++ .../ViewUserDept.java} | 8 +- .../bunny/dao/vo/system/user/AdminUserVo.java | 4 +- .../cn/bunny/dao/vo/system/user/LoginVo.java | 4 + .../cn/bunny/dao/vo/system/user/UserVo.java | 4 +- .../services/controller/UserController.java | 5 +- .../bunny/services/factory/UserFactory.java | 48 ++++++++--- .../cn/bunny/services/mapper/PowerMapper.java | 7 -- .../services/mapper/RolePowerMapper.java | 9 +- .../services/mapper/RouterRoleMapper.java | 8 ++ .../cn/bunny/services/mapper/UserMapper.java | 4 +- .../security/custom/CustomCheckIsAdmin.java | 2 +- .../filter/NoTokenAuthenticationFilter.java | 4 +- .../filter/TokenAuthenticationFilter.java | 8 +- .../filter/TokenLoginFilterService.java | 30 ++++--- .../service/CustomUserDetailsService.java | 3 +- .../impl/CustomUserDetailsServiceImpl.java | 20 +++-- .../bunny/services/service/UserService.java | 3 +- .../service/impl/RouterServiceImpl.java | 81 +++++++++++++----- .../service/impl/UserRoleServiceImpl.java | 29 ++++++- .../service/impl/UserServiceImpl.java | 84 +++++++++++-------- .../src/main/resources/mapper/I18nMapper.xml | 1 - .../src/main/resources/mapper/PowerMapper.xml | 8 -- .../main/resources/mapper/RolePowerMapper.xml | 20 +++-- .../resources/mapper/RouterRoleMapper.xml | 21 +++++ .../src/main/resources/mapper/UserMapper.xml | 12 +-- 34 files changed, 407 insertions(+), 171 deletions(-) create mode 100644 dao/src/main/java/cn/bunny/dao/view/ViewRolePower.java create mode 100644 dao/src/main/java/cn/bunny/dao/view/ViewRouterRole.java rename dao/src/main/java/cn/bunny/dao/{entity/system/AdminUserAndDept.java => view/ViewUserDept.java} (89%) diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/utils/JwtHelper.java b/common/service-utils/src/main/java/cn/bunny/common/service/utils/JwtHelper.java index 07394bf..efca21b 100644 --- a/common/service-utils/src/main/java/cn/bunny/common/service/utils/JwtHelper.java +++ b/common/service-utils/src/main/java/cn/bunny/common/service/utils/JwtHelper.java @@ -1,5 +1,7 @@ package cn.bunny.common.service.utils; +import cn.bunny.common.service.exception.BunnyException; +import cn.bunny.dao.pojo.result.ResultCodeEnum; import io.jsonwebtoken.*; import io.micrometer.common.lang.Nullable; import org.springframework.util.StringUtils; @@ -184,16 +186,16 @@ public class JwtHelper { * 根据用户名和ID创建token * * @param userId 用户ID - * @param userName 用户名 + * @param username 用户名 * @param day 过期时间 * @return token值 */ - public static String createToken(Long userId, String userName, Integer day) { + public static String createToken(Long userId, String username, Integer day) { return Jwts.builder() .setSubject(subject) .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration * day)) .claim("userId", userId) - .claim("userName", userName) + .claim("username", username) .setId(UUID.randomUUID().toString()) .signWith(SignatureAlgorithm.HS256, tokenSignKey) .compressWith(CompressionCodecs.GZIP) @@ -208,14 +210,14 @@ public class JwtHelper { */ public static Map getMapByToken(String token) { try { - if (!StringUtils.hasText(token)) return null; + if (!StringUtils.hasText(token)) throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); Claims claims = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody(); // 将 body 值转为map return new HashMap<>(claims); } catch (Exception exception) { - return null; + throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); } } @@ -228,14 +230,14 @@ public class JwtHelper { */ public static Map getMapByToken(String token, String signKey) { try { - if (!StringUtils.hasText(token)) return null; + if (!StringUtils.hasText(token)) throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); Jws claimsJws = Jwts.parser().setSigningKey(signKey).parseClaimsJws(token); Claims body = claimsJws.getBody(); // 将 body 值转为map return new HashMap<>(body); } catch (Exception exception) { - return null; + throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); } } @@ -252,14 +254,14 @@ public class JwtHelper { @Nullable private static String getSubjectByTokenHandler(String token, String tokenSignKey) { try { - if (!StringUtils.hasText(token)) return null; + if (!StringUtils.hasText(token)) throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims body = claimsJws.getBody(); return body.getSubject(); } catch (Exception exception) { - return null; + throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); } } @@ -281,14 +283,14 @@ public class JwtHelper { */ public static Long getUserId(String token) { try { - if (!StringUtils.hasText(token)) return null; + if (!StringUtils.hasText(token)) throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); return Long.valueOf(String.valueOf(claims.get("userId"))); } catch (Exception exception) { - return null; + throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); } } @@ -304,9 +306,9 @@ public class JwtHelper { Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); - return (String) claims.get("userName"); + return (String) claims.get("username"); } catch (Exception exception) { - return null; + throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED); } } diff --git a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserAddDto.java b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserAddDto.java index 4362beb..baf15f1 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserAddDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserAddDto.java @@ -21,10 +21,10 @@ public class AdminUserAddDto { @NotNull(message = "用户名不能为空") private String username; - @Schema(name = "nickName", title = "昵称") + @Schema(name = "nickname", title = "昵称") @NotBlank(message = "昵称不能为空") @NotNull(message = "昵称不能为空") - private String nickName; + private String nickname; @Schema(name = "email", title = "邮箱") @NotBlank(message = "邮箱不能为空") diff --git a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserDto.java b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserDto.java index 38f75f3..6f86af9 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserDto.java @@ -18,8 +18,8 @@ public class AdminUserDto { @Schema(name = "username", title = "用户名") private String username; - @Schema(name = "nickName", title = "昵称") - private String nickName; + @Schema(name = "nickname", title = "昵称") + private String nickname; @Schema(name = "email", title = "邮箱") private String email; diff --git a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateByLocalUserDto.java b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateByLocalUserDto.java index 5303cf2..09349bc 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateByLocalUserDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateByLocalUserDto.java @@ -16,15 +16,10 @@ import lombok.NoArgsConstructor; @Schema(name = "AdminUserUpdateByLocalUserDto对象", title = "更新本地用户信息", description = "更新本地用户信息") public class AdminUserUpdateByLocalUserDto { - @Schema(name = "username", title = "用户名") - @NotBlank(message = "用户名不能为空") - @NotNull(message = "用户名不能为空") - private String username; - - @Schema(name = "nickName", title = "昵称") + @Schema(name = "nickname", title = "昵称") @NotBlank(message = "昵称不能为空") @NotNull(message = "昵称不能为空") - private String nickName; + private String nickname; @Schema(name = "email", title = "邮箱") @NotBlank(message = "邮箱不能为空") diff --git a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateDto.java b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateDto.java index 0ed93a2..f749ba4 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/system/user/AdminUserUpdateDto.java @@ -24,10 +24,10 @@ public class AdminUserUpdateDto { @NotNull(message = "用户名不能为空") private String username; - @Schema(name = "nickName", title = "昵称") + @Schema(name = "nickname", title = "昵称") @NotBlank(message = "昵称不能为空") @NotNull(message = "昵称不能为空") - private String nickName; + private String nickname; @Schema(name = "email", title = "邮箱") @NotBlank(message = "邮箱不能为空") diff --git a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java b/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java index 7c61c8c..8773b07 100644 --- a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java +++ b/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java @@ -25,8 +25,8 @@ public class AdminUser extends BaseEntity { @Schema(name = "username", title = "用户名") private String username; - @Schema(name = "nickName", title = "昵称") - private String nickName; + @Schema(name = "nickname", title = "昵称") + private String nickname; @Schema(name = "email", title = "邮箱") private String email; diff --git a/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java b/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java index 66d0e71..1154dd6 100644 --- a/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java +++ b/dao/src/main/java/cn/bunny/dao/pojo/result/ResultCodeEnum.java @@ -55,7 +55,7 @@ public enum ResultCodeEnum { SESSION_EXPIRATION(208, "会话过期"), // 封禁 209 - FAIL_NO_ACCESS_DENIED_USER_LOCKED(209, "该账户被封禁"), + FAIL_NO_ACCESS_DENIED_USER_LOCKED(209, "该账户已封禁"), THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"), // 提示错误 @@ -71,6 +71,7 @@ public enum ResultCodeEnum { FAIL_NO_ACCESS_DENIED(403, "无权访问"), FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"), LOGGED_IN_FROM_ANOTHER_DEVICE(403, "没有权限访问"), + TOKEN_PARSING_FAILED(403, "token解析失败"), // 系统错误 500 UNKNOWN_EXCEPTION(500, "服务异常"), diff --git a/dao/src/main/java/cn/bunny/dao/view/ViewRolePower.java b/dao/src/main/java/cn/bunny/dao/view/ViewRolePower.java new file mode 100644 index 0000000..c599277 --- /dev/null +++ b/dao/src/main/java/cn/bunny/dao/view/ViewRolePower.java @@ -0,0 +1,37 @@ +package cn.bunny.dao.view; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Setter +@Getter +@Accessors(chain = true) +@TableName("sys_role_power") +@Schema(name = "ViewRolePower对象", title = "角色权限关系视图", description = "角色权限关系视图") +public class ViewRolePower { + + @Schema(name = "roleId", title = "角色ID") + private Long roleId; + + @Schema(name = "roleCode", title = "角色代码") + private String roleCode; + + @Schema(name = "description", title = "描述") + private String description; + + @Schema(name = "parentId", title = "父级id") + private Long parentId; + + @Schema(name = "parentId", title = "权限编码") + private String powerCode; + + @Schema(name = "powerName", title = "权限名称") + private String powerName; + + @Schema(name = "requestUrl", title = "请求路径") + private String requestUrl; + +} \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/view/ViewRouterRole.java b/dao/src/main/java/cn/bunny/dao/view/ViewRouterRole.java new file mode 100644 index 0000000..62ea93e --- /dev/null +++ b/dao/src/main/java/cn/bunny/dao/view/ViewRouterRole.java @@ -0,0 +1,58 @@ +package cn.bunny.dao.view; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Getter +@Setter +@Accessors(chain = true) +@TableName("sys_router_role") +@Schema(name = "RouterRoleViewRouterRole象", title = "路由角色关系视图", description = "路由角色关系视图") +public class ViewRouterRole { + + @Schema(name = "routerId", title = "路由ID") + private Long routerId; + + @Schema(name = "parentId", title = "父级id") + private Long parentId; + + @Schema(name = "path", title = "在项目中路径") + private String path; + + @Schema(name = "component", title = "组件位置") + private String component; + + @Schema(name = "frameSrc", title = "frame路径") + private String frameSrc; + + @Schema(name = "routeName", title = "路由名称") + private String routeName; + + @Schema(name = "title", title = "路由title") + private String title; + + @Schema(name = "menuType", title = "菜单类型") + private Integer menuType; + + @Schema(name = "icon", title = "图标") + private String icon; + + @Schema(name = "routerRank", title = "等级") + private Integer routerRank; + + @Schema(name = "visible", title = "是否显示") + private Boolean visible; + + @Schema(name = "roleId", title = "角色ID") + private Long roleId; + + @Schema(name = "roleCode", title = "角色代码") + private String roleCode; + + @Schema(name = "description", title = "描述") + private String description; + +} \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUserAndDept.java b/dao/src/main/java/cn/bunny/dao/view/ViewUserDept.java similarity index 89% rename from dao/src/main/java/cn/bunny/dao/entity/system/AdminUserAndDept.java rename to dao/src/main/java/cn/bunny/dao/view/ViewUserDept.java index a15b551..8442f00 100644 --- a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUserAndDept.java +++ b/dao/src/main/java/cn/bunny/dao/view/ViewUserDept.java @@ -1,4 +1,4 @@ -package cn.bunny.dao.entity.system; +package cn.bunny.dao.view; import cn.bunny.dao.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; @@ -20,13 +20,13 @@ import lombok.experimental.Accessors; @Accessors(chain = true) @TableName("sys_user") @Schema(name = "AdminUserAndDept对象", title = "用户信息和部门Id", description = "用户信息和部门Id") -public class AdminUserAndDept extends BaseEntity { +public class ViewUserDept extends BaseEntity { @Schema(name = "username", title = "用户名") private String username; - @Schema(name = "nickName", title = "昵称") - private String nickName; + @Schema(name = "nickname", title = "昵称") + private String nickname; @Schema(name = "email", title = "邮箱") private String email; diff --git a/dao/src/main/java/cn/bunny/dao/vo/system/user/AdminUserVo.java b/dao/src/main/java/cn/bunny/dao/vo/system/user/AdminUserVo.java index 628ed9d..9b750da 100644 --- a/dao/src/main/java/cn/bunny/dao/vo/system/user/AdminUserVo.java +++ b/dao/src/main/java/cn/bunny/dao/vo/system/user/AdminUserVo.java @@ -17,8 +17,8 @@ public class AdminUserVo extends BaseVo { @Schema(name = "username", title = "用户名") private String username; - @Schema(name = "nickName", title = "昵称") - private String nickName; + @Schema(name = "nickname", title = "昵称") + private String nickname; @Schema(name = "email", title = "邮箱") private String email; diff --git a/dao/src/main/java/cn/bunny/dao/vo/system/user/LoginVo.java b/dao/src/main/java/cn/bunny/dao/vo/system/user/LoginVo.java index f3f5995..d45a171 100644 --- a/dao/src/main/java/cn/bunny/dao/vo/system/user/LoginVo.java +++ b/dao/src/main/java/cn/bunny/dao/vo/system/user/LoginVo.java @@ -17,6 +17,7 @@ import java.util.List; @Builder @Schema(name = "LoginVo对象", title = "登录成功返回内容", description = "登录成功返回内容") public class LoginVo extends BaseVo { + @Schema(name = "nickname", title = "昵称") private String nickname; @@ -65,4 +66,7 @@ public class LoginVo extends BaseVo { @Schema(name = "powerList", title = "权限列表") private List permissions = new ArrayList<>(); + @Schema(name = "readMeDay", title = "记住我多久") + private Long readMeDay; + } \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/vo/system/user/UserVo.java b/dao/src/main/java/cn/bunny/dao/vo/system/user/UserVo.java index 4b71f55..c3735d7 100644 --- a/dao/src/main/java/cn/bunny/dao/vo/system/user/UserVo.java +++ b/dao/src/main/java/cn/bunny/dao/vo/system/user/UserVo.java @@ -12,8 +12,8 @@ import lombok.*; @Schema(name = "LoginVo对象", title = "登录成功返回内容", description = "登录成功返回内容") public class UserVo extends BaseVo { - @Schema(name = "nickName", title = "昵称") - private String nickName; + @Schema(name = "nickname", title = "昵称") + private String nickname; @Schema(name = "username", title = "用户名") private String username; diff --git a/service/src/main/java/cn/bunny/services/controller/UserController.java b/service/src/main/java/cn/bunny/services/controller/UserController.java index 69e0c2d..ce368cb 100644 --- a/service/src/main/java/cn/bunny/services/controller/UserController.java +++ b/service/src/main/java/cn/bunny/services/controller/UserController.java @@ -6,6 +6,7 @@ import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.pojo.result.Result; import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.AdminUserVo; +import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.dao.vo.system.user.RefreshTokenVo; import cn.bunny.dao.vo.system.user.UserVo; import cn.bunny.services.service.UserService; @@ -44,8 +45,8 @@ public class UserController { @Operation(summary = "获取本地登录用户信息", description = "获取本地登录用户信息") @GetMapping("noManage/getUserinfo") - public Mono> getUserinfo() { - UserVo vo = userService.getUserinfo(); + public Mono> getUserinfo() { + LoginVo vo = userService.getUserinfo(); return Mono.just(Result.success(vo)); } diff --git a/service/src/main/java/cn/bunny/services/factory/UserFactory.java b/service/src/main/java/cn/bunny/services/factory/UserFactory.java index 83694f4..1f58518 100644 --- a/service/src/main/java/cn/bunny/services/factory/UserFactory.java +++ b/service/src/main/java/cn/bunny/services/factory/UserFactory.java @@ -35,7 +35,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Component -@Transactional public class UserFactory { @Autowired private PowerMapper powerMapper; @@ -55,17 +54,18 @@ public class UserFactory { @Autowired private MinioUtil minioUtil; - public LoginVo buildUserVo(AdminUser user, long readMeDay) { - // 创建token + @Transactional + public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) { Long userId = user.getId(); String email = user.getEmail(); - String token = JwtHelper.createToken(userId, email, (int) readMeDay); + String username = user.getUsername(); - // 获取IP地址 + // 使用用户名创建token + String token = JwtHelper.createToken(userId, username, (int) readMeDay); + + // 获取IP地址并更新用户登录信息 String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr(); String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); - - // 更新用户登录信息 setUpdateUser(userId, ipAddr, ipRegion); // 将用户登录保存在用户登录日志表中 @@ -74,8 +74,8 @@ public class UserFactory { // 设置用户返回信息 LoginVo loginVo = setLoginVo(user, token, readMeDay, ipAddr, ipRegion); - // 将信息保存在Redis中 - redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS); + // 将信息保存在Redis中,一定要确保用户名是唯一的 + redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS); // 将Redis中验证码删除 redisTemplate.delete(RedisUserConstant.getAdminUserEmailCodePrefix(email)); @@ -83,6 +83,20 @@ public class UserFactory { return loginVo; } + public void buildUserVo(AdminUser user, long readMeDay) { + Long userId = user.getId(); + String username = user.getUsername(); + + // 使用用户名创建token + String token = JwtHelper.createToken(userId, username, (int) readMeDay); + + // 设置用户返回信息 + LoginVo loginVo = setLoginVo(user, token, readMeDay, user.getIpAddress(), user.getIpRegion()); + + // 将信息保存在Redis中,一定要确保用户名是唯一的 + redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS); + } + /** * * 设置更新用户设置内容 @@ -90,9 +104,10 @@ public class UserFactory { public LoginVo setLoginVo(AdminUser user, String token, long readMeDay, String ipAddr, String ipRegion) { Long userId = user.getId(); - // 判断用户是否有头像,如果没有头像设置默认头像 + // 判断用户是否有头像,如果没有头像设置默认头像,并且用户头像不能和默认头像相同 String avatar = user.getAvatar(); - avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR; + String userAvatar = UserConstant.USER_AVATAR; + avatar = StringUtils.hasText(avatar) && !avatar.equals(userAvatar) ? minioUtil.getObjectNameFullPath(avatar) : userAvatar; // 查找用户橘色 List roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList()); @@ -113,7 +128,7 @@ public class UserFactory { // 构建返回对象,设置用户需要内容 LoginVo loginVo = new LoginVo(); BeanUtils.copyProperties(user, loginVo); - loginVo.setNickname(user.getNickName()); + loginVo.setNickname(user.getNickname()); loginVo.setAvatar(avatar); loginVo.setToken(token); loginVo.setRefreshToken(token); @@ -122,7 +137,9 @@ public class UserFactory { loginVo.setRoles(roles); loginVo.setPermissions(permissions); loginVo.setUpdateUser(userId); + loginVo.setPersonDescription(user.getSummary()); loginVo.setExpires(expires); + loginVo.setReadMeDay(readMeDay); return loginVo; } @@ -132,6 +149,7 @@ public class UserFactory { * * @param userId 用户ID */ + @Transactional public void setUpdateUser(Long userId, String ipAddr, String ipRegion) { // 设置用户IP地址,并更新用户信息 AdminUser updateUser = new AdminUser(); @@ -148,7 +166,11 @@ public class UserFactory { * @return 整理好的头像内容 */ public String checkUserAvatar(String avatar) { - if (!StringUtils.hasText(avatar)) return null; + // 如果用户没有头像或者用户头像和默认头像相同,返回默认头像 + String userAvatar = UserConstant.USER_AVATAR; + if (!StringUtils.hasText(avatar) || avatar.equals(userAvatar)) return userAvatar; + + // 替换前端发送的host前缀,将其删除,只保留路径名称 String regex = "^https?://.*?/(.*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(avatar); diff --git a/service/src/main/java/cn/bunny/services/mapper/PowerMapper.java b/service/src/main/java/cn/bunny/services/mapper/PowerMapper.java index 8d44cf6..1349d3b 100644 --- a/service/src/main/java/cn/bunny/services/mapper/PowerMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/PowerMapper.java @@ -46,11 +46,4 @@ public interface PowerMapper extends BaseMapper { @NotNull List selectListByUserId(long userId); - /** - * * 根据权限码查询可以访问URL - * - * @param powerCodes 权限码 - * @return 权限列表 - */ - List selectListByPowerCodes(List powerCodes); } diff --git a/service/src/main/java/cn/bunny/services/mapper/RolePowerMapper.java b/service/src/main/java/cn/bunny/services/mapper/RolePowerMapper.java index 507f094..693350a 100644 --- a/service/src/main/java/cn/bunny/services/mapper/RolePowerMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/RolePowerMapper.java @@ -1,7 +1,7 @@ package cn.bunny.services.mapper; -import cn.bunny.dao.entity.system.Power; import cn.bunny.dao.entity.system.RolePower; +import cn.bunny.dao.view.ViewRolePower; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @@ -41,10 +41,9 @@ public interface RolePowerMapper extends BaseMapper { List selectPowerListByRoleId(Long roleId); /** - * * 根据角色id列表获取权限内容 + * 查看所有角色关联的权限 * - * @param roleIds 角色id列表 - * @return 已选择的权限列表 + * @return 角色权限关系视图 */ - List selectPowerListByRoleIds(List roleIds); + List viewRolePowerWithAll(); } diff --git a/service/src/main/java/cn/bunny/services/mapper/RouterRoleMapper.java b/service/src/main/java/cn/bunny/services/mapper/RouterRoleMapper.java index a7a22d3..a541e06 100644 --- a/service/src/main/java/cn/bunny/services/mapper/RouterRoleMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/RouterRoleMapper.java @@ -1,6 +1,7 @@ package cn.bunny.services.mapper; import cn.bunny.dao.entity.system.RouterRole; +import cn.bunny.dao.view.ViewRouterRole; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @@ -30,4 +31,11 @@ public interface RouterRoleMapper extends BaseMapper { * @param roleIds 角色id列表 */ void deleteBatchIdsByRoleIdsWithPhysics(List roleIds); + + /** + * 查看所有路由关联角色 + * + * @return 路由角色关系视图列表 + */ + List viewRouterRolesWithAll(); } diff --git a/service/src/main/java/cn/bunny/services/mapper/UserMapper.java b/service/src/main/java/cn/bunny/services/mapper/UserMapper.java index 44d98e4..47182ee 100644 --- a/service/src/main/java/cn/bunny/services/mapper/UserMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/UserMapper.java @@ -2,7 +2,7 @@ package cn.bunny.services.mapper; import cn.bunny.dao.dto.system.user.AdminUserDto; import cn.bunny.dao.entity.system.AdminUser; -import cn.bunny.dao.entity.system.AdminUserAndDept; +import cn.bunny.dao.view.ViewUserDept; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -29,7 +29,7 @@ public interface UserMapper extends BaseMapper { * @param dto 用户信息查询表单 * @return 用户信息分页结果 */ - IPage selectListByPage(@Param("page") Page pageParams, @Param("dto") AdminUserDto dto); + IPage selectListByPage(@Param("page") Page pageParams, @Param("dto") AdminUserDto dto); /** * 物理删除用户信息 diff --git a/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java b/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java index 1eee1c4..4650302 100644 --- a/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java +++ b/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java @@ -38,7 +38,7 @@ public class CustomCheckIsAdmin { boolean isAdmin = roleList.stream().anyMatch(role -> role.equals("admin")); // 判断是否是 admin - if (!isIdAdmin || !isAdmin) { + if (isIdAdmin || isAdmin) { roleList.add("admin"); permissions.add("*"); permissions.add("*::*"); diff --git a/service/src/main/java/cn/bunny/services/security/filter/NoTokenAuthenticationFilter.java b/service/src/main/java/cn/bunny/services/security/filter/NoTokenAuthenticationFilter.java index 5171c81..269300b 100644 --- a/service/src/main/java/cn/bunny/services/security/filter/NoTokenAuthenticationFilter.java +++ b/service/src/main/java/cn/bunny/services/security/filter/NoTokenAuthenticationFilter.java @@ -41,9 +41,11 @@ public class NoTokenAuthenticationFilter extends OncePerRequestFilter { return; } - // 查找 Redis + // 解析JWT中的用户名 String username = JwtHelper.getUsername(token); Long userId = JwtHelper.getUserId(token); + + // 查找 Redis Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username)); LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); diff --git a/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java b/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java index 66cc65b..b4b4b1f 100644 --- a/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java +++ b/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java @@ -34,11 +34,9 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { */ private UsernamePasswordAuthenticationToken getAuthentication() { // 请求头是否有token - LoginVo LoginVo = BaseContext.getLoginVo(); - - // 通过username从redis获取权限数据 - String username = LoginVo.getUsername(); - List roleList = LoginVo.getRoles(); + LoginVo loginVo = BaseContext.getLoginVo(); + String username = loginVo.getUsername(); + List roleList = loginVo.getRoles(); // 角色列表 List authList = roleList.stream().map(SimpleGrantedAuthority::new).toList(); diff --git a/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java b/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java index 97ef498..8234f34 100644 --- a/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java +++ b/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java @@ -2,6 +2,7 @@ package cn.bunny.services.security.filter; import cn.bunny.dao.dto.system.user.LoginDto; +import cn.bunny.dao.pojo.constant.RedisUserConstant; import cn.bunny.dao.pojo.result.Result; import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.LoginVo; @@ -58,21 +59,25 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte try { loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class); - String emailCode = loginDto.getEmailCode().toLowerCase(); + String emailCode = loginDto.getEmailCode(); String username = loginDto.getUsername(); String password = loginDto.getPassword(); - // Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username)); - // if (redisEmailCode == null) { - // out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY)); - // return null; - // } + // 如果有邮箱验证码,表示是邮箱登录 + if (StringUtils.hasText(emailCode)) { + emailCode = emailCode.toLowerCase(); + Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username)); + if (redisEmailCode == null) { + out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY)); + return null; + } - // 判断用户邮箱验证码是否和Redis中发送的验证码 - // if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) { - // out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING)); - // return null; - // } + // 判断用户邮箱验证码是否和Redis中发送的验证码 + if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) { + out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING)); + return null; + } + } Authentication authenticationToken = new UsernamePasswordAuthenticationToken(username, password); return getAuthenticationManager().authenticate(authenticationToken); @@ -87,7 +92,8 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) { // 获取登录返回信息 - LoginVo loginVo = customUserDetailsService.login(loginDto); + LoginVo loginVo = customUserDetailsService.login(loginDto, response); + if (loginVo == null) return; // 判断用户是否禁用 if (loginVo.getStatus()) { diff --git a/service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java b/service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java index b20d91b..af8f6d0 100644 --- a/service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java +++ b/service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java @@ -2,6 +2,7 @@ package cn.bunny.services.security.service; import cn.bunny.dao.dto.system.user.LoginDto; import cn.bunny.dao.vo.system.user.LoginVo; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -19,5 +20,5 @@ public interface CustomUserDetailsService extends UserDetailsService { * @param loginDto 登录参数 * @return 登录后结果返回 */ - LoginVo login(LoginDto loginDto); + LoginVo login(LoginDto loginDto, HttpServletResponse response); } diff --git a/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java b/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java index 494921d..9ac8a7a 100644 --- a/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java @@ -3,12 +3,14 @@ package cn.bunny.services.security.service.impl; import cn.bunny.common.service.exception.BunnyException; import cn.bunny.dao.dto.system.user.LoginDto; import cn.bunny.dao.entity.system.AdminUser; +import cn.bunny.dao.pojo.result.Result; import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.services.factory.UserFactory; import cn.bunny.services.mapper.UserMapper; import cn.bunny.services.security.custom.CustomUser; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; @@ -16,6 +18,8 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import org.springframework.util.DigestUtils; +import static cn.bunny.common.service.utils.ResponseUtil.out; + @Component public class CustomUserDetailsServiceImpl implements cn.bunny.services.security.service.CustomUserDetailsService { @@ -40,7 +44,7 @@ public class CustomUserDetailsServiceImpl implements cn.bunny.services.security. // 根据邮箱查询用户名 AdminUser adminUser = userMapper.selectOne(queryWrapper); - if (adminUser == null) throw new UsernameNotFoundException("用户不存在"); + if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage()); return new CustomUser(adminUser, AuthorityUtils.createAuthorityList()); } @@ -53,22 +57,28 @@ public class CustomUserDetailsServiceImpl implements cn.bunny.services.security. * @return 登录后结果返回 */ @Override - public LoginVo login(LoginDto loginDto) { + public LoginVo login(LoginDto loginDto, HttpServletResponse response) { String username = loginDto.getUsername(); String password = loginDto.getPassword(); Long readMeDay = loginDto.getReadMeDay(); // 查询用户相关内容 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() - .eq(AdminUser::getEmail, username) + .eq(AdminUser::getUsername, username) .or() - .eq(AdminUser::getUsername, username); + .eq(AdminUser::getEmail, username); AdminUser user = userMapper.selectOne(queryWrapper); + // 判断用户是否为空 + if (user == null) { + out(response, Result.error(ResultCodeEnum.LOGIN_ERROR)); + return null; + } + // 对登录密码进行md5加密判断,是否与数据库中一致 String md5Password = DigestUtils.md5DigestAsHex(password.getBytes()); if (!user.getPassword().equals(md5Password)) throw new BunnyException(ResultCodeEnum.LOGIN_ERROR); - return userFactory.buildUserVo(user, readMeDay); + return userFactory.buildLoginUserVo(user, readMeDay); } } diff --git a/service/src/main/java/cn/bunny/services/service/UserService.java b/service/src/main/java/cn/bunny/services/service/UserService.java index 9d8d594..662ae81 100644 --- a/service/src/main/java/cn/bunny/services/service/UserService.java +++ b/service/src/main/java/cn/bunny/services/service/UserService.java @@ -4,6 +4,7 @@ import cn.bunny.dao.dto.system.user.*; import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.vo.system.user.AdminUserVo; +import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.dao.vo.system.user.RefreshTokenVo; import cn.bunny.dao.vo.system.user.UserVo; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -121,7 +122,7 @@ public interface UserService extends IService { * * @return 用户信息 */ - UserVo getUserinfo(); + LoginVo getUserinfo(); /** * * 更新本地用户信息 diff --git a/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java index fa0cda3..7986aa1 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java @@ -6,18 +6,20 @@ import cn.bunny.dao.dto.system.router.RouterAddDto; import cn.bunny.dao.dto.system.router.RouterManageDto; import cn.bunny.dao.dto.system.router.RouterUpdateByIdWithRankDto; import cn.bunny.dao.dto.system.router.RouterUpdateDto; -import cn.bunny.dao.entity.system.Power; import cn.bunny.dao.entity.system.Role; import cn.bunny.dao.entity.system.Router; import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.pojo.result.ResultCodeEnum; +import cn.bunny.dao.view.ViewRolePower; +import cn.bunny.dao.view.ViewRouterRole; import cn.bunny.dao.vo.system.router.RouterManageVo; import cn.bunny.dao.vo.system.router.RouterMeta; import cn.bunny.dao.vo.system.router.UserRouterVo; import cn.bunny.services.factory.RouterServiceFactory; -import cn.bunny.services.mapper.PowerMapper; import cn.bunny.services.mapper.RoleMapper; +import cn.bunny.services.mapper.RolePowerMapper; import cn.bunny.services.mapper.RouterMapper; +import cn.bunny.services.mapper.RouterRoleMapper; import cn.bunny.services.security.custom.CustomCheckIsAdmin; import cn.bunny.services.service.RouterService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -31,9 +33,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** *

@@ -53,7 +54,10 @@ public class RouterServiceImpl extends ServiceImpl impleme private RoleMapper roleMapper; @Autowired - private PowerMapper powerMapper; + private RouterRoleMapper routerRoleMapper; + + @Autowired + private RolePowerMapper rolePowerMapper; /** * * 获取路由内容 @@ -66,35 +70,68 @@ public class RouterServiceImpl extends ServiceImpl impleme Long userId = BaseContext.getUserId(); // 查询角色信息 - List roleList = roleMapper.selectListByUserId(userId); - List roleCodeList = roleList.stream().map(Role::getRoleCode).toList(); + List roleList; + List userRoleCodeList; + if (userId.equals(1L)) { + userRoleCodeList = List.of("admin"); + } else { + roleList = roleMapper.selectListByUserId(userId); + userRoleCodeList = roleList.stream().map(Role::getRoleCode).toList(); + } // 如果没有分配角色直接返回空数组 - if (roleCodeList.isEmpty()) return new ArrayList<>(); - - // 根据角色列表查询权限信息 - List powerList = powerMapper.selectListByUserId(userId); - List powerCodeList = powerList.stream().map(Power::getPowerCode).toList(); - - // 路由列表,根据用户角色判断 - List routerList; + if (userRoleCodeList.isEmpty()) return new ArrayList<>(); // 返回路由列表 List list = new ArrayList<>(); // 查询用户角色,判断是否是管理员角色 - boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList); - if (isAdmin) routerList = list(); - else { - List routerIds = baseMapper.selectListByUserId(userId); - routerList = baseMapper.selectParentListByRouterId(routerIds); - } + boolean isAdmin = CustomCheckIsAdmin.checkAdmin(userRoleCodeList); + + // 查询路由和角色对应关系 + List routerRoleList = routerRoleMapper.viewRouterRolesWithAll(); + Map> routerIdWithRoleCodeMap = routerRoleList.stream() + .collect(Collectors.groupingBy( + ViewRouterRole::getRouterId, + Collectors.mapping(ViewRouterRole::getRoleCode, Collectors.toUnmodifiableList()) + )); + + // 角色和权限对应关系 + List rolePowerList = rolePowerMapper.viewRolePowerWithAll(); + Map> roleCodeWithPowerCodeMap = rolePowerList.stream() + .collect(Collectors.groupingBy( + ViewRolePower::getRoleCode, + Collectors.mapping(ViewRolePower::getPowerCode, Collectors.toUnmodifiableSet()) + )); + + // 查询所有路由内容 + List routerList = list(); // 构建返回路由列表 List routerVoList = routerList.stream() .sorted(Comparator.comparing(Router::getRouterRank)) .filter(Router::getVisible) .map(router -> { + // 角色码列表 + List roleCodeList; + + // 权限码列表 + List powerCodeList; + + // 判断是否是admin + if (isAdmin) { + roleCodeList = userRoleCodeList; + powerCodeList = List.of("*", "*::*", "*::*::*"); + } else { + roleCodeList = routerIdWithRoleCodeMap.getOrDefault(router.getId(), Collections.emptyList()); + powerCodeList = roleCodeList.stream() + .map(roleCodeWithPowerCodeMap::get) + .filter(Objects::nonNull) + .flatMap(Set::stream) + .collect(Collectors.toUnmodifiableSet()) + .stream().toList(); + } + // 复制对象 UserRouterVo routerVo = new UserRouterVo(); BeanUtils.copyProperties(router, routerVo); diff --git a/service/src/main/java/cn/bunny/services/service/impl/UserRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/UserRoleServiceImpl.java index 1d12224..b6a8a16 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/UserRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/UserRoleServiceImpl.java @@ -1,9 +1,15 @@ package cn.bunny.services.service.impl; +import cn.bunny.common.service.context.BaseContext; import cn.bunny.common.service.exception.BunnyException; import cn.bunny.dao.dto.system.user.AssignRolesToUsersDto; +import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.dao.entity.system.UserRole; +import cn.bunny.dao.pojo.constant.RedisUserConstant; import cn.bunny.dao.pojo.result.ResultCodeEnum; +import cn.bunny.dao.vo.system.user.LoginVo; +import cn.bunny.services.factory.UserFactory; +import cn.bunny.services.mapper.UserMapper; import cn.bunny.services.mapper.UserRoleMapper; import cn.bunny.services.service.UserRoleService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -14,6 +20,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.concurrent.TimeUnit; /** *

@@ -31,8 +38,13 @@ public class UserRoleServiceImpl extends ServiceImpl i private UserRoleMapper userRoleMapper; @Autowired - private RedisTemplate redisTemplate; + private UserFactory userFactory; + @Autowired + private UserMapper userMapper; + + @Autowired + private RedisTemplate redisTemplate; /** * * 根据用户id获取角色列表 @@ -58,6 +70,12 @@ public class UserRoleServiceImpl extends ServiceImpl i Long userId = dto.getUserId(); List roleIds = dto.getRoleIds(); + // 查询当前用户 + AdminUser adminUser = userMapper.selectOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); + if (adminUser == null) { + throw new BunnyException(ResultCodeEnum.USER_IS_EMPTY); + } + // 删除这个用户下所有已经分配好的角色内容 baseMapper.deleteBatchIdsByUserIdsWithPhysics(List.of(userId)); @@ -69,5 +87,14 @@ public class UserRoleServiceImpl extends ServiceImpl i return userRole; }).toList(); saveBatch(roleList); + + // 获取记住我时间 + LoginVo loginVo = BaseContext.getLoginVo(); + Long readMeDay = loginVo != null ? loginVo.getReadMeDay() : RedisUserConstant.REDIS_EXPIRATION_TIME; + + // 重新设置Redis中的用户存储信息vo对象 + String username = adminUser.getUsername(); + loginVo = userFactory.buildLoginUserVo(adminUser, readMeDay); + redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS); } } diff --git a/service/src/main/java/cn/bunny/services/service/impl/UserServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/UserServiceImpl.java index 6d64fa2..b273458 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/UserServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/UserServiceImpl.java @@ -8,12 +8,16 @@ import cn.bunny.common.service.utils.minio.MinioUtil; import cn.bunny.dao.dto.system.files.FileUploadDto; import cn.bunny.dao.dto.system.user.*; import cn.bunny.dao.entity.log.UserLoginLog; -import cn.bunny.dao.entity.system.*; +import cn.bunny.dao.entity.system.AdminUser; +import cn.bunny.dao.entity.system.EmailTemplate; +import cn.bunny.dao.entity.system.Role; +import cn.bunny.dao.entity.system.UserDept; import cn.bunny.dao.pojo.constant.MinioConstant; import cn.bunny.dao.pojo.constant.RedisUserConstant; import cn.bunny.dao.pojo.enums.EmailTemplateEnums; import cn.bunny.dao.pojo.result.PageResult; import cn.bunny.dao.pojo.result.ResultCodeEnum; +import cn.bunny.dao.view.ViewUserDept; import cn.bunny.dao.vo.system.files.FileInfoVo; import cn.bunny.dao.vo.system.user.AdminUserVo; import cn.bunny.dao.vo.system.user.LoginVo; @@ -136,7 +140,7 @@ public class UserServiceImpl extends ServiceImpl implemen if (adminUser == null) throw new BunnyException(ResultCodeEnum.FAIL_REQUEST_NOT_AUTH); if (adminUser.getStatus()) throw new BunnyException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED); - LoginVo buildUserVo = userFactory.buildUserVo(adminUser, dto.getReadMeDay()); + LoginVo buildUserVo = userFactory.buildLoginUserVo(adminUser, dto.getReadMeDay()); RefreshTokenVo refreshTokenVo = new RefreshTokenVo(); BeanUtils.copyProperties(buildUserVo, refreshTokenVo); @@ -148,20 +152,22 @@ public class UserServiceImpl extends ServiceImpl implemen */ @Override public void logout() { + // 获取上下文对象中的用户ID和用户token LoginVo loginVo = BaseContext.getLoginVo(); - Long id = loginVo.getId(); + String token = loginVo.getToken(); + Long userId = BaseContext.getUserId(); // 获取IP地址 String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr(); String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); // 查询用户信息 - AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, id)); - UserLoginLog userLoginLog = userFactory.setUserLoginLog(adminUser, loginVo.getToken(), ipAddr, ipRegion, "logout"); + AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); + UserLoginLog userLoginLog = userFactory.setUserLoginLog(adminUser, token, ipAddr, ipRegion, "logout"); userLoginLogMapper.insert(userLoginLog); // 删除Redis中用户信息 - redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(loginVo.getUsername())); + redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername())); } /** @@ -210,7 +216,7 @@ public class UserServiceImpl extends ServiceImpl implemen throw new BunnyException(ResultCodeEnum.UPDATE_NEW_PASSWORD_SAME_AS_OLD_PASSWORD); // 删除Redis中登录用户信息 - redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getEmail())); + redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername())); // 更新用户密码 adminUser = new AdminUser(); @@ -256,8 +262,7 @@ public class UserServiceImpl extends ServiceImpl implemen // 根据id查询用户登录前缀 AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, id)); - String email = adminUser.getEmail(); - String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(email); + String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername()); // 将用户登录保存在用户登录日志表中 UserLoginLog userLoginLog = new UserLoginLog(); @@ -310,19 +315,8 @@ public class UserServiceImpl extends ServiceImpl implemen * @return 用户信息 */ @Override - public UserVo getUserinfo() { - // 查询当前用户信息 - Long userId = BaseContext.getUserId(); - AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); - - // 赋值对象 - UserVo userVo = new UserVo(); - BeanUtils.copyProperties(adminUser, userVo); - - // 设置用户头像内容 - String avatar = adminUser.getAvatar(); - if (StringUtils.hasText(avatar)) userVo.setAvatar(minioUtil.getObjectNameFullPath(avatar)); - return userVo; + public LoginVo getUserinfo() { + return BaseContext.getLoginVo(); } /** @@ -333,20 +327,24 @@ public class UserServiceImpl extends ServiceImpl implemen @Override public void updateAdminUserByLocalUser(AdminUserUpdateByLocalUserDto dto) { Long userId = BaseContext.getUserId(); + LoginVo loginVo = BaseContext.getLoginVo(); // 判断是否存在这个用户 - AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); - if (adminUser == null) throw new BunnyException(ResultCodeEnum.USER_IS_EMPTY); + AdminUser user = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); + if (user == null) throw new BunnyException(ResultCodeEnum.USER_IS_EMPTY); // 检查用户头像 dto.setAvatar(userFactory.checkUserAvatar(dto.getAvatar())); // 更新用户 - adminUser = new AdminUser(); + AdminUser adminUser = new AdminUser(); adminUser.setId(userId); BeanUtils.copyProperties(dto, adminUser); - updateById(adminUser); + + // 重新生成用户信息到Redis中 + BeanUtils.copyProperties(dto, user); + userFactory.buildUserVo(user, loginVo.getReadMeDay()); } /** @@ -371,15 +369,13 @@ public class UserServiceImpl extends ServiceImpl implemen if (dbPassword.equals(password)) throw new BunnyException(ResultCodeEnum.NEW_PASSWORD_SAME_OLD_PASSWORD); // 删除Redis中登录用户信息 - redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getEmail())); + redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername())); // 更新用户密码 adminUser = new AdminUser(); adminUser.setId(userId); adminUser.setPassword(password); updateById(adminUser); - - } /** @@ -392,7 +388,7 @@ public class UserServiceImpl extends ServiceImpl implemen @Override public PageResult getAdminUserList(Page pageParams, AdminUserDto dto) { // 分页查询菜单图标 - IPage page = baseMapper.selectListByPage(pageParams, dto); + IPage page = baseMapper.selectListByPage(pageParams, dto); List voList = page.getRecords().stream() .map(adminUser -> { @@ -419,17 +415,29 @@ public class UserServiceImpl extends ServiceImpl implemen } /** - * 添加用户信息 + * * 添加用户信息 + * 需要确认用户名-username是唯一的 + * 需要确认邮箱-email是唯一的 * * @param dto 用户信息添加 */ @Override public void addAdminUser(@Valid AdminUserAddDto dto) { + AdminUser adminUser = getOne(Wrappers.lambdaQuery() + .eq(AdminUser::getEmail, dto.getEmail()) + .or() + .eq(AdminUser::getUsername, dto.getUsername())); + + // 确保邮箱和用户名不能重复 + if (adminUser != null) { + throw new BunnyException(ResultCodeEnum.ALREADY_USER_EXCEPTION); + } + // 对密码加密 String md5Password = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes()); // 保存数据 - AdminUser adminUser = new AdminUser(); + adminUser = new AdminUser(); BeanUtils.copyProperties(dto, adminUser); adminUser.setPassword(md5Password); save(adminUser); @@ -452,6 +460,16 @@ public class UserServiceImpl extends ServiceImpl implemen */ @Override public void updateAdminUser(AdminUserUpdateDto dto) { + AdminUser adminUser = getOne(Wrappers.lambdaQuery() + .eq(AdminUser::getEmail, dto.getEmail()) + .or() + .eq(AdminUser::getUsername, dto.getUsername())); + + // 确保邮箱和用户名不能重复 + if (adminUser != null) { + throw new BunnyException(ResultCodeEnum.ALREADY_USER_EXCEPTION); + } + // 部门Id Long deptId = dto.getDeptId(); Long userId = dto.getId(); @@ -461,7 +479,7 @@ public class UserServiceImpl extends ServiceImpl implemen if (adminUserList.isEmpty()) throw new BunnyException(ResultCodeEnum.DATA_NOT_EXIST); // 更新用户 - AdminUser adminUser = new AdminUser(); + adminUser = new AdminUser(); BeanUtils.copyProperties(dto, adminUser); updateById(adminUser); diff --git a/service/src/main/resources/mapper/I18nMapper.xml b/service/src/main/resources/mapper/I18nMapper.xml index c8f1835..c8f3d77 100644 --- a/service/src/main/resources/mapper/I18nMapper.xml +++ b/service/src/main/resources/mapper/I18nMapper.xml @@ -47,7 +47,6 @@ and type_name like CONCAT('%',#{dto.typeName},'%') - order by update_time diff --git a/service/src/main/resources/mapper/PowerMapper.xml b/service/src/main/resources/mapper/PowerMapper.xml index 27712ba..849a373 100644 --- a/service/src/main/resources/mapper/PowerMapper.xml +++ b/service/src/main/resources/mapper/PowerMapper.xml @@ -64,12 +64,4 @@ AND rp.power_id = p.id AND u.id = #{userId} - - - diff --git a/service/src/main/resources/mapper/RolePowerMapper.xml b/service/src/main/resources/mapper/RolePowerMapper.xml index 0d49ef4..25b9b7f 100644 --- a/service/src/main/resources/mapper/RolePowerMapper.xml +++ b/service/src/main/resources/mapper/RolePowerMapper.xml @@ -46,15 +46,19 @@ where role_id = #{roleId} - - + SELECT rp.power_id, + power.parent_id, + power.power_code, + power.power_name, + power.request_url, + rp.role_id, + role.role_code, + role.description FROM sys_role_power rp - LEFT JOIN sys_role role ON rp.role_id = role.id - LEFT JOIN sys_power power ON rp.power_id = power.id AND rp.role_id in - - #{id} - + LEFT JOIN sys_role role ON rp.role_id = role.id + LEFT JOIN sys_power power ON rp.power_id = power.id diff --git a/service/src/main/resources/mapper/RouterRoleMapper.xml b/service/src/main/resources/mapper/RouterRoleMapper.xml index 90631ca..558a642 100644 --- a/service/src/main/resources/mapper/RouterRoleMapper.xml +++ b/service/src/main/resources/mapper/RouterRoleMapper.xml @@ -39,4 +39,25 @@ + + + diff --git a/service/src/main/resources/mapper/UserMapper.xml b/service/src/main/resources/mapper/UserMapper.xml index 019d001..9751709 100644 --- a/service/src/main/resources/mapper/UserMapper.xml +++ b/service/src/main/resources/mapper/UserMapper.xml @@ -6,7 +6,7 @@ - + @@ -25,11 +25,11 @@ - id, username, nick_name, email, phone, password, avatar, sex, summary, ip_address, ip_region, status, create_user, create_time, update_time, update_user, is_deleted + id, username, nickname, email, phone, password, avatar, sex, summary, ip_address, ip_region, status, create_user, create_time, update_time, update_user, is_deleted - select user.*,user_dept.dept_id from sys_user user left join sys_user_dept user_dept on user.id = user_dept.user_id @@ -38,8 +38,8 @@ and username like CONCAT('%',#{dto.username},'%') - - and nick_name like CONCAT('%',#{dto.nickName},'%') + + and nickname like CONCAT('%',#{dto.nickname},'%') and email like CONCAT('%',#{dto.email},'%') @@ -72,7 +72,7 @@ username like CONCAT('%', #{keyword}, '%') - or nick_name like CONCAT('%', #{keyword}, '%') + or nickname like CONCAT('%', #{keyword}, '%') or email like CONCAT('%', #{keyword}, '%') or phone like CONCAT('%', #{keyword}, '%')