feat: 用户可以用邮箱或者用户名登录,修改部分缺陷
This commit is contained in:
parent
deb521abcd
commit
d08946ec5e
|
@ -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<String, Object> 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<String, Object> getMapByToken(String token, String signKey) {
|
||||
try {
|
||||
if (!StringUtils.hasText(token)) return null;
|
||||
if (!StringUtils.hasText(token)) throw new BunnyException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
Jws<Claims> 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<Claims> 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<Claims> 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<Claims> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = "邮箱不能为空")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = "邮箱不能为空")
|
||||
|
|
|
@ -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 = "邮箱不能为空")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, "服务异常"),
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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<String> permissions = new ArrayList<>();
|
||||
|
||||
@Schema(name = "readMeDay", title = "记住我多久")
|
||||
private Long readMeDay;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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<Result<UserVo>> getUserinfo() {
|
||||
UserVo vo = userService.getUserinfo();
|
||||
public Mono<Result<LoginVo>> getUserinfo() {
|
||||
LoginVo vo = userService.getUserinfo();
|
||||
return Mono.just(Result.success(vo));
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> 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);
|
||||
|
|
|
@ -46,11 +46,4 @@ public interface PowerMapper extends BaseMapper<Power> {
|
|||
@NotNull
|
||||
List<Power> selectListByUserId(long userId);
|
||||
|
||||
/**
|
||||
* * 根据权限码查询可以访问URL
|
||||
*
|
||||
* @param powerCodes 权限码
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<Power> selectListByPowerCodes(List<String> powerCodes);
|
||||
}
|
||||
|
|
|
@ -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<RolePower> {
|
|||
List<RolePower> selectPowerListByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* * 根据角色id列表获取权限内容
|
||||
* 查看所有角色关联的权限
|
||||
*
|
||||
* @param roleIds 角色id列表
|
||||
* @return 已选择的权限列表
|
||||
* @return 角色权限关系视图
|
||||
*/
|
||||
List<Power> selectPowerListByRoleIds(List<Long> roleIds);
|
||||
List<ViewRolePower> viewRolePowerWithAll();
|
||||
}
|
||||
|
|
|
@ -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<RouterRole> {
|
|||
* @param roleIds 角色id列表
|
||||
*/
|
||||
void deleteBatchIdsByRoleIdsWithPhysics(List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 查看所有路由关联角色
|
||||
*
|
||||
* @return 路由角色关系视图列表
|
||||
*/
|
||||
List<ViewRouterRole> viewRouterRolesWithAll();
|
||||
}
|
||||
|
|
|
@ -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<AdminUser> {
|
|||
* @param dto 用户信息查询表单
|
||||
* @return 用户信息分页结果
|
||||
*/
|
||||
IPage<AdminUserAndDept> selectListByPage(@Param("page") Page<AdminUser> pageParams, @Param("dto") AdminUserDto dto);
|
||||
IPage<ViewUserDept> selectListByPage(@Param("page") Page<AdminUser> pageParams, @Param("dto") AdminUserDto dto);
|
||||
|
||||
/**
|
||||
* 物理删除用户信息
|
||||
|
|
|
@ -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("*::*");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -34,11 +34,9 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
|||
*/
|
||||
private UsernamePasswordAuthenticationToken getAuthentication() {
|
||||
// 请求头是否有token
|
||||
LoginVo LoginVo = BaseContext.getLoginVo();
|
||||
|
||||
// 通过username从redis获取权限数据
|
||||
String username = LoginVo.getUsername();
|
||||
List<String> roleList = LoginVo.getRoles();
|
||||
LoginVo loginVo = BaseContext.getLoginVo();
|
||||
String username = loginVo.getUsername();
|
||||
List<String> roleList = loginVo.getRoles();
|
||||
|
||||
// 角色列表
|
||||
List<SimpleGrantedAuthority> authList = roleList.stream().map(SimpleGrantedAuthority::new).toList();
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<AdminUser> queryWrapper = new LambdaQueryWrapper<AdminUser>()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<AdminUser> {
|
|||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
UserVo getUserinfo();
|
||||
LoginVo getUserinfo();
|
||||
|
||||
/**
|
||||
* * 更新本地用户信息
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -53,7 +54,10 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
|
|||
private RoleMapper roleMapper;
|
||||
|
||||
@Autowired
|
||||
private PowerMapper powerMapper;
|
||||
private RouterRoleMapper routerRoleMapper;
|
||||
|
||||
@Autowired
|
||||
private RolePowerMapper rolePowerMapper;
|
||||
|
||||
/**
|
||||
* * 获取路由内容
|
||||
|
@ -66,35 +70,68 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
|
|||
Long userId = BaseContext.getUserId();
|
||||
|
||||
// 查询角色信息
|
||||
List<Role> roleList = roleMapper.selectListByUserId(userId);
|
||||
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
|
||||
List<Role> roleList;
|
||||
List<String> 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<Power> powerList = powerMapper.selectListByUserId(userId);
|
||||
List<String> powerCodeList = powerList.stream().map(Power::getPowerCode).toList();
|
||||
|
||||
// 路由列表,根据用户角色判断
|
||||
List<Router> routerList;
|
||||
if (userRoleCodeList.isEmpty()) return new ArrayList<>();
|
||||
|
||||
// 返回路由列表
|
||||
List<UserRouterVo> list = new ArrayList<>();
|
||||
|
||||
// 查询用户角色,判断是否是管理员角色
|
||||
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList);
|
||||
if (isAdmin) routerList = list();
|
||||
else {
|
||||
List<Long> routerIds = baseMapper.selectListByUserId(userId);
|
||||
routerList = baseMapper.selectParentListByRouterId(routerIds);
|
||||
}
|
||||
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(userRoleCodeList);
|
||||
|
||||
// 查询路由和角色对应关系
|
||||
List<ViewRouterRole> routerRoleList = routerRoleMapper.viewRouterRolesWithAll();
|
||||
Map<Long, List<String>> routerIdWithRoleCodeMap = routerRoleList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
ViewRouterRole::getRouterId,
|
||||
Collectors.mapping(ViewRouterRole::getRoleCode, Collectors.toUnmodifiableList())
|
||||
));
|
||||
|
||||
// 角色和权限对应关系
|
||||
List<ViewRolePower> rolePowerList = rolePowerMapper.viewRolePowerWithAll();
|
||||
Map<String, Set<String>> roleCodeWithPowerCodeMap = rolePowerList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
ViewRolePower::getRoleCode,
|
||||
Collectors.mapping(ViewRolePower::getPowerCode, Collectors.toUnmodifiableSet())
|
||||
));
|
||||
|
||||
// 查询所有路由内容
|
||||
List<Router> routerList = list();
|
||||
|
||||
// 构建返回路由列表
|
||||
List<UserRouterVo> routerVoList = routerList.stream()
|
||||
.sorted(Comparator.comparing(Router::getRouterRank))
|
||||
.filter(Router::getVisible)
|
||||
.map(router -> {
|
||||
// 角色码列表
|
||||
List<String> roleCodeList;
|
||||
|
||||
// 权限码列表
|
||||
List<String> 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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -31,8 +38,13 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
|||
private UserRoleMapper userRoleMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
private UserFactory userFactory;
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* * 根据用户id获取角色列表
|
||||
|
@ -58,6 +70,12 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
|||
Long userId = dto.getUserId();
|
||||
List<Long> roleIds = dto.getRoleIds();
|
||||
|
||||
// 查询当前用户
|
||||
AdminUser adminUser = userMapper.selectOne(Wrappers.<AdminUser>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<UserRoleMapper, UserRole> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<UserMapper, AdminUser> 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<UserMapper, AdminUser> 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.<AdminUser>lambdaQuery().eq(AdminUser::getId, id));
|
||||
UserLoginLog userLoginLog = userFactory.setUserLoginLog(adminUser, loginVo.getToken(), ipAddr, ipRegion, "logout");
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> 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<UserMapper, AdminUser> implemen
|
|||
|
||||
// 根据id查询用户登录前缀
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> implemen
|
|||
* @return 用户信息
|
||||
*/
|
||||
@Override
|
||||
public UserVo getUserinfo() {
|
||||
// 查询当前用户信息
|
||||
Long userId = BaseContext.getUserId();
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> implemen
|
|||
@Override
|
||||
public void updateAdminUserByLocalUser(AdminUserUpdateByLocalUserDto dto) {
|
||||
Long userId = BaseContext.getUserId();
|
||||
LoginVo loginVo = BaseContext.getLoginVo();
|
||||
|
||||
// 判断是否存在这个用户
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
||||
if (adminUser == null) throw new BunnyException(ResultCodeEnum.USER_IS_EMPTY);
|
||||
AdminUser user = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> 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<UserMapper, AdminUser> implemen
|
|||
@Override
|
||||
public PageResult<AdminUserVo> getAdminUserList(Page<AdminUser> pageParams, AdminUserDto dto) {
|
||||
// 分页查询菜单图标
|
||||
IPage<AdminUserAndDept> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
IPage<ViewUserDept> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
List<AdminUserVo> voList = page.getRecords().stream()
|
||||
.map(adminUser -> {
|
||||
|
@ -419,17 +415,29 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
|||
}
|
||||
|
||||
/**
|
||||
* 添加用户信息
|
||||
* * 添加用户信息
|
||||
* 需要确认用户名-username是唯一的
|
||||
* 需要确认邮箱-email是唯一的
|
||||
*
|
||||
* @param dto 用户信息添加
|
||||
*/
|
||||
@Override
|
||||
public void addAdminUser(@Valid AdminUserAddDto dto) {
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> implemen
|
|||
*/
|
||||
@Override
|
||||
public void updateAdminUser(AdminUserUpdateDto dto) {
|
||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>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<UserMapper, AdminUser> implemen
|
|||
if (adminUserList.isEmpty()) throw new BunnyException(ResultCodeEnum.DATA_NOT_EXIST);
|
||||
|
||||
// 更新用户
|
||||
AdminUser adminUser = new AdminUser();
|
||||
adminUser = new AdminUser();
|
||||
BeanUtils.copyProperties(dto, adminUser);
|
||||
updateById(adminUser);
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
and type_name like CONCAT('%',#{dto.typeName},'%')
|
||||
</if>
|
||||
</where>
|
||||
order by update_time
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -64,12 +64,4 @@
|
|||
AND rp.power_id = p.id
|
||||
AND u.id = #{userId}
|
||||
</select>
|
||||
|
||||
<!-- 根据权限码返回权限列表 -->
|
||||
<select id="selectListByPowerCodes" resultType="cn.bunny.dao.entity.system.Power">
|
||||
SELECT * FROM sys_power WHERE power_code IN
|
||||
<foreach collection="powerCodes" separator="," item="code" open="(" close=")">
|
||||
#{code}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -46,15 +46,19 @@
|
|||
where role_id = #{roleId}
|
||||
</select>
|
||||
|
||||
<!-- 根据角色id列表获取权限内容 -->
|
||||
<select id="selectPowerListByRoleIds" resultType="cn.bunny.dao.entity.system.Power">
|
||||
SELECT power.*
|
||||
<!-- 查看所有角色关联的权限 -->
|
||||
<select id="viewRolePowerWithAll" resultType="cn.bunny.dao.view.ViewRolePower">
|
||||
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
|
||||
<foreach collection="roleIds" item="id" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
LEFT JOIN sys_role role ON rp.role_id = role.id
|
||||
LEFT JOIN sys_power power ON rp.power_id = power.id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -39,4 +39,25 @@
|
|||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 查看所有路由的角色 -->
|
||||
<select id="viewRouterRolesWithAll" resultType="cn.bunny.dao.view.ViewRouterRole">
|
||||
SELECT rr.router_id,
|
||||
router.parent_id,
|
||||
router.path,
|
||||
router.component,
|
||||
router.frame_src,
|
||||
router.route_name,
|
||||
router.title,
|
||||
router.menu_type,
|
||||
router.icon,
|
||||
router.router_rank,
|
||||
router.visible,
|
||||
rr.role_id,
|
||||
role.role_code,
|
||||
role.description
|
||||
FROM sys_router_role rr
|
||||
LEFT JOIN sys_router router ON rr.router_id = router.id
|
||||
LEFT JOIN sys_role role ON rr.role_id = role.id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<resultMap id="BaseResultMap" type="cn.bunny.dao.entity.system.AdminUser">
|
||||
<id column="id" property="id"/>
|
||||
<result column="username" property="username"/>
|
||||
<result column="nick_name" property="nickName"/>
|
||||
<result column="nickname" property="nickname"/>
|
||||
<result column="email" property="email"/>
|
||||
<result column="phone" property="phone"/>
|
||||
<result column="password" property="password"/>
|
||||
|
@ -25,11 +25,11 @@
|
|||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
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
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询用户信息内容 -->
|
||||
<select id="selectListByPage" resultType="cn.bunny.dao.entity.system.AdminUserAndDept">
|
||||
<select id="selectListByPage" resultType="cn.bunny.dao.view.ViewUserDept">
|
||||
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 @@
|
|||
<if test="dto.username != null and dto.username != ''">
|
||||
and username like CONCAT('%',#{dto.username},'%')
|
||||
</if>
|
||||
<if test="dto.nickName != null and dto.nickName != ''">
|
||||
and nick_name like CONCAT('%',#{dto.nickName},'%')
|
||||
<if test="dto.nickname != null and dto.nickname != ''">
|
||||
and nickname like CONCAT('%',#{dto.nickname},'%')
|
||||
</if>
|
||||
<if test="dto.email != null and dto.email != ''">
|
||||
and email like CONCAT('%',#{dto.email},'%')
|
||||
|
@ -72,7 +72,7 @@
|
|||
<where>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
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}, '%')
|
||||
</if>
|
||||
|
|
Loading…
Reference in New Issue