refactor: 重构获取登录用户信息方式(线程级存储)

This commit is contained in:
2024-10-10 22:33:20 +08:00
parent 8466105a9b
commit 79ea39dd07
27 changed files with 523 additions and 363 deletions

View File

@@ -17,8 +17,7 @@
package top.continew.admin.common.config.mybatis;
import cn.hutool.core.convert.Convert;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.starter.extension.datapermission.enums.DataScope;
import top.continew.starter.extension.datapermission.filter.DataPermissionUserContextProvider;
import top.continew.starter.extension.datapermission.model.RoleContext;
@@ -36,17 +35,16 @@ public class DefaultDataPermissionUserContextProvider implements DataPermissionU
@Override
public boolean isFilter() {
LoginUser loginUser = LoginHelper.getLoginUser();
return !loginUser.isAdmin();
return !UserContextHolder.isAdmin();
}
@Override
public UserContext getUserContext() {
LoginUser loginUser = LoginHelper.getLoginUser();
top.continew.admin.common.context.UserContext context = UserContextHolder.getContext();
UserContext userContext = new UserContext();
userContext.setUserId(Convert.toStr(loginUser.getId()));
userContext.setDeptId(Convert.toStr(loginUser.getDeptId()));
userContext.setRoles(loginUser.getRoles()
userContext.setUserId(Convert.toStr(context.getId()));
userContext.setDeptId(Convert.toStr(context.getDeptId()));
userContext.setRoles(context.getRoles()
.stream()
.map(r -> new RoleContext(Convert.toStr(r.getId()), DataScope.valueOf(r.getDataScope().name())))
.collect(Collectors.toSet()));

View File

@@ -19,9 +19,8 @@ package top.continew.admin.common.config.mybatis;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.extension.crud.model.entity.BaseDO;
import java.time.LocalDateTime;
@@ -62,7 +61,7 @@ public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
if (null == metaObject) {
return;
}
Long createUser = ExceptionUtils.exToNull(LoginHelper::getUserId);
Long createUser = UserContextHolder.getUserId();
LocalDateTime createTime = LocalDateTime.now();
if (metaObject.getOriginalObject() instanceof BaseDO baseDO) {
// 继承了 BaseDO 的类,填充创建信息字段
@@ -89,8 +88,7 @@ public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
if (null == metaObject) {
return;
}
Long updateUser = LoginHelper.getUserId();
Long updateUser = UserContextHolder.getUserId();
LocalDateTime updateTime = LocalDateTime.now();
if (metaObject.getOriginalObject() instanceof BaseDO baseDO) {
// 继承了 BaseDO 的类,填充修改信息

View File

@@ -16,11 +16,11 @@
package top.continew.admin.common.config.websocket;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.messaging.websocket.core.WebSocketClientService;
/**
@@ -36,7 +36,9 @@ public class WebSocketClientServiceImpl implements WebSocketClientService {
public String getClientId(ServletServerHttpRequest request) {
HttpServletRequest servletRequest = request.getServletRequest();
String token = servletRequest.getParameter("token");
LoginUser loginUser = LoginHelper.getLoginUser(token);
return loginUser.getToken();
if (null == StpUtil.getLoginIdByToken(token)) {
throw new BusinessException("登录已过期,请重新登录");
}
return token;
}
}

View File

@@ -31,11 +31,6 @@ public class CacheConstants {
*/
public static final String DELIMITER = StringConstants.COLON;
/**
* 登录用户键
*/
public static final String LOGIN_USER_KEY = "LOGIN_USER";
/**
* 验证码键前缀
*/

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.continew.admin.common.model.dto;
package top.continew.admin.common.context;
import lombok.Data;
import top.continew.admin.common.enums.DataScopeEnum;
@@ -23,13 +23,13 @@ import java.io.Serial;
import java.io.Serializable;
/**
* 角色信息
* 角色上下文
*
* @author Charles7c
* @since 2023/3/7 22:08
*/
@Data
public class RoleDTO implements Serializable {
public class RoleContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package top.continew.admin.common.model.dto;
package top.continew.admin.common.context;
import cn.hutool.core.collection.CollUtil;
import lombok.Data;
@@ -28,14 +28,14 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
* 登录用户信息
* 用户上下文
*
* @author Charles7c
* @since 2022/12/24 13:01
* @since 2024/10/9 20:29
*/
@Data
@NoArgsConstructor
public class LoginUser implements Serializable {
public class UserContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@@ -55,6 +55,16 @@ public class LoginUser implements Serializable {
*/
private Long deptId;
/**
* 最后一次修改密码时间
*/
private LocalDateTime pwdResetTime;
/**
* 登录时系统设置的密码过期天数
*/
private Integer passwordExpirationDays;
/**
* 权限码集合
*/
@@ -68,57 +78,17 @@ public class LoginUser implements Serializable {
/**
* 角色集合
*/
private Set<RoleDTO> roles;
private Set<RoleContext> roles;
/**
* 令牌
*/
private String token;
/**
* IP
*/
private String ip;
/**
* IP 归属地
*/
private String address;
/**
* 浏览器
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 登录时间
*/
private LocalDateTime loginTime;
/**
* 最后一次修改密码时间
*/
private LocalDateTime pwdResetTime;
/**
* 登录时系统设置的密码过期天数
*/
private Integer passwordExpirationDays;
public LoginUser(Set<String> permissions, Set<RoleDTO> roles, Integer passwordExpirationDays) {
public UserContext(Set<String> permissions, Set<RoleContext> roles, Integer passwordExpirationDays) {
this.permissions = permissions;
this.setRoles(roles);
this.passwordExpirationDays = passwordExpirationDays;
}
public void setRoles(Set<RoleDTO> roles) {
public void setRoles(Set<RoleContext> roles) {
this.roles = roles;
this.roleCodes = roles.stream().map(RoleDTO::getCode).collect(Collectors.toSet());
this.roleCodes = roles.stream().map(RoleContext::getCode).collect(Collectors.toSet());
}
/**

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.common.context;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.spring.SpringUtil;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.extension.crud.service.CommonUserService;
import java.util.Optional;
/**
* 用户上下文 Holder
*
* @author Charles7c
* @since 2022/12/24 12:58
*/
public class UserContextHolder {
private static final ThreadLocal<UserContext> CONTEXT_HOLDER = new ThreadLocal<>();
private static final ThreadLocal<UserExtraContext> EXTRA_CONTEXT_HOLDER = new ThreadLocal<>();
private UserContextHolder() {
}
/**
* 设置上下文
*
* @param context 上下文
*/
public static void setContext(UserContext context) {
setContext(context, true);
}
/**
* 设置上下文
*
* @param context 上下文
* @param isUpdate 是否更新
*/
public static void setContext(UserContext context, boolean isUpdate) {
CONTEXT_HOLDER.set(context);
if (isUpdate) {
StpUtil.getSessionByLoginId(context.getId()).set(SaSession.USER, context);
}
}
/**
* 获取上下文
*
* @return 上下文
*/
public static UserContext getContext() {
UserContext context = CONTEXT_HOLDER.get();
if (null == context) {
context = StpUtil.getSession().getModel(SaSession.USER, UserContext.class);
CONTEXT_HOLDER.set(context);
}
return context;
}
/**
* 获取指定用户的上下文
*
* @param userId 用户 ID
* @return 上下文
*/
public static UserContext getContext(Long userId) {
SaSession session = StpUtil.getSessionByLoginId(userId, false);
if (null == session) {
return null;
}
return session.getModel(SaSession.USER, UserContext.class);
}
/**
* 设置额外上下文
*
* @param context 额外上下文
*/
public static void setExtraContext(UserExtraContext context) {
EXTRA_CONTEXT_HOLDER.set(context);
}
/**
* 获取额外上下文
*
* @return 额外上下文
*/
public static UserExtraContext getExtraContext() {
UserExtraContext context = EXTRA_CONTEXT_HOLDER.get();
if (null == context) {
context = getExtraContext(StpUtil.getTokenValue());
EXTRA_CONTEXT_HOLDER.set(context);
}
return context;
}
/**
* 获取额外上下文
*
* @param token 令牌
* @return 额外上下文
*/
public static UserExtraContext getExtraContext(String token) {
UserExtraContext context = new UserExtraContext();
context.setIp(Convert.toStr(StpUtil.getExtra(token, "ip")));
context.setAddress(Convert.toStr(StpUtil.getExtra(token, "address")));
context.setBrowser(Convert.toStr(StpUtil.getExtra(token, "browser")));
context.setOs(Convert.toStr(StpUtil.getExtra(token, "os")));
context.setLoginTime(Convert.toLocalDateTime(StpUtil.getExtra(token, "loginTime")));
return context;
}
/**
* 清除上下文
*/
public static void clearContext() {
CONTEXT_HOLDER.remove();
EXTRA_CONTEXT_HOLDER.remove();
}
/**
* 获取用户 ID
*
* @return 用户 ID
*/
public static Long getUserId() {
return Optional.ofNullable(getContext()).map(UserContext::getId).orElse(null);
}
/**
* 获取用户名
*
* @return 用户名
*/
public static String getUsername() {
return Optional.ofNullable(getContext()).map(UserContext::getUsername).orElse(null);
}
/**
* 获取用户昵称
*
* @return 用户昵称
*/
public static String getNickname() {
return getNickname(getUserId());
}
/**
* 获取用户昵称
*
* @param userId 登录用户 ID
* @return 用户昵称
*/
public static String getNickname(Long userId) {
return ExceptionUtils.exToNull(() -> SpringUtil.getBean(CommonUserService.class).getNicknameById(userId));
}
/**
* 是否为管理员
*
* @return 是否为管理员
*/
public static Boolean isAdmin() {
StpUtil.checkLogin();
return getContext().isAdmin();
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.common.context;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.NoArgsConstructor;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.core.util.IpUtils;
import top.continew.starter.web.util.ServletUtils;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户额外上下文
*
* @author Charles7c
* @since 2024/10/9 20:29
*/
@Data
@NoArgsConstructor
public class UserExtraContext implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* IP
*/
private String ip;
/**
* IP 归属地
*/
private String address;
/**
* 浏览器
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 登录时间
*/
private LocalDateTime loginTime;
public UserExtraContext(HttpServletRequest request) {
this.ip = JakartaServletUtil.getClientIP(request);
this.address = ExceptionUtils.exToNull(() -> IpUtils.getIpv4Address(this.ip));
this.setBrowser(ServletUtils.getBrowser(request));
this.setLoginTime(LocalDateTime.now());
this.setOs(StrUtil.subBefore(ServletUtils.getOs(request), " or", false));
}
}

View File

@@ -1,152 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.common.util.helper;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.extra.spring.SpringUtil;
import jakarta.servlet.http.HttpServletRequest;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.core.util.IpUtils;
import top.continew.starter.extension.crud.service.CommonUserService;
import top.continew.starter.web.util.ServletUtils;
import top.continew.starter.web.util.SpringWebUtils;
import java.time.LocalDateTime;
/**
* 登录助手
*
* @author Charles7c
* @author Lion Li<a href="https://gitee.com/dromara/RuoYi-Vue-Plus">RuoYi-Vue-Plus</a>
* @since 2022/12/24 12:58
*/
public class LoginHelper {
private LoginHelper() {
}
/**
* 用户登录并缓存用户信息
*
* @param loginUser 登录用户信息
* @return 令牌
*/
public static String login(LoginUser loginUser) {
// 记录登录信息
HttpServletRequest request = SpringWebUtils.getRequest();
loginUser.setIp(JakartaServletUtil.getClientIP(request));
loginUser.setAddress(ExceptionUtils.exToNull(() -> IpUtils.getIpv4Address(loginUser.getIp())));
loginUser.setBrowser(ServletUtils.getBrowser(request));
loginUser.setLoginTime(LocalDateTime.now());
loginUser.setOs(StrUtil.subBefore(ServletUtils.getOs(request), " or", false));
// 登录并缓存用户信息
StpUtil.login(loginUser.getId());
SaHolder.getStorage().set(CacheConstants.LOGIN_USER_KEY, loginUser);
String tokenValue = StpUtil.getTokenValue();
loginUser.setToken(tokenValue);
StpUtil.getTokenSession().set(CacheConstants.LOGIN_USER_KEY, loginUser);
return tokenValue;
}
/**
* 更新登录用户信息
*
* @param loginUser
* 登录用户信息
* @param token 令牌
*/
public static void updateLoginUser(LoginUser loginUser, String token) {
SaHolder.getStorage().delete(CacheConstants.LOGIN_USER_KEY);
StpUtil.getTokenSessionByToken(token).set(CacheConstants.LOGIN_USER_KEY, loginUser);
}
/**
* 获取登录用户信息
*
* @return 登录用户信息
* @throws NotLoginException 未登录异常
*/
public static LoginUser getLoginUser() throws NotLoginException {
StpUtil.checkLogin();
LoginUser loginUser = (LoginUser)SaHolder.getStorage().get(CacheConstants.LOGIN_USER_KEY);
if (null != loginUser) {
return loginUser;
}
SaSession tokenSession = StpUtil.getTokenSession();
loginUser = (LoginUser)tokenSession.get(CacheConstants.LOGIN_USER_KEY);
SaHolder.getStorage().set(CacheConstants.LOGIN_USER_KEY, loginUser);
return loginUser;
}
/**
* 根据 Token 获取登录用户信息
*
* @param token 用户 Token
* @return 登录用户信息
*/
public static LoginUser getLoginUser(String token) {
SaSession tokenSession = StpUtil.getStpLogic().getTokenSessionByToken(token, false);
if (null == tokenSession) {
return null;
}
return (LoginUser)tokenSession.get(CacheConstants.LOGIN_USER_KEY);
}
/**
* 获取登录用户 ID
*
* @return 登录用户 ID
*/
public static Long getUserId() {
return getLoginUser().getId();
}
/**
* 获取登录用户名
*
* @return 登录用户名
*/
public static String getUsername() {
return getLoginUser().getUsername();
}
/**
* 获取登录用户昵称
*
* @return 登录用户昵称
*/
public static String getNickname() {
return getNickname(getUserId());
}
/**
* 获取登录用户昵称
*
* @param userId 登录用户 ID
* @return 登录用户昵称
*/
public static String getNickname(Long userId) {
return ExceptionUtils.exToNull(() -> SpringUtil.getBean(CommonUserService.class).getNicknameById(userId));
}
}

View File

@@ -18,7 +18,6 @@ package top.continew.admin.auth.service;
import top.continew.admin.auth.model.query.OnlineUserQuery;
import top.continew.admin.auth.model.resp.OnlineUserResp;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
@@ -48,7 +47,7 @@ public interface OnlineUserService {
* @param query 查询条件
* @return 列表信息
*/
List<LoginUser> list(OnlineUserQuery query);
List<OnlineUserResp> list(OnlineUserQuery query);
/**
* 查询 Token 最后活跃时间

View File

@@ -16,6 +16,7 @@
package top.continew.admin.auth.service.impl;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
@@ -39,11 +40,12 @@ import top.continew.admin.auth.service.LoginService;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.constant.RegexConstants;
import top.continew.admin.common.constant.SysConstants;
import top.continew.admin.common.context.RoleContext;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.context.UserExtraContext;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.enums.GenderEnum;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.model.dto.RoleDTO;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.enums.MenuTypeEnum;
import top.continew.admin.system.enums.MessageTemplateEnum;
import top.continew.admin.system.enums.MessageTypeEnum;
@@ -61,6 +63,7 @@ import top.continew.starter.core.util.validate.CheckUtils;
import top.continew.starter.extension.crud.annotation.TreeField;
import top.continew.starter.extension.crud.util.TreeUtils;
import top.continew.starter.messaging.websocket.util.WebSocketUtils;
import top.continew.starter.web.util.SpringWebUtils;
import java.time.Duration;
import java.time.LocalDateTime;
@@ -205,15 +208,19 @@ public class LoginServiceImpl implements LoginService {
Long userId = user.getId();
CompletableFuture<Set<String>> permissionFuture = CompletableFuture.supplyAsync(() -> roleService
.listPermissionByUserId(userId), threadPoolTaskExecutor);
CompletableFuture<Set<RoleDTO>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
CompletableFuture<Set<RoleContext>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
.listByUserId(userId), threadPoolTaskExecutor);
CompletableFuture<Integer> passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService
.getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name()));
CompletableFuture.allOf(permissionFuture, roleFuture, passwordExpirationDaysFuture);
LoginUser loginUser = new LoginUser(permissionFuture.join(), roleFuture.join(), passwordExpirationDaysFuture
.join());
BeanUtil.copyProperties(user, loginUser);
return LoginHelper.login(loginUser);
UserContext userContext = new UserContext(permissionFuture.join(), roleFuture
.join(), passwordExpirationDaysFuture.join());
BeanUtil.copyProperties(user, userContext);
// 登录并缓存用户信息
StpUtil.login(userContext.getId(), SaLoginConfig.setExtraData(BeanUtil
.beanToMap(new UserExtraContext(SpringWebUtils.getRequest()))));
UserContextHolder.setContext(userContext);
return StpUtil.getTokenValue();
}
/**

View File

@@ -21,6 +21,7 @@ import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
@@ -28,17 +29,16 @@ import org.springframework.stereotype.Service;
import top.continew.admin.auth.model.query.OnlineUserQuery;
import top.continew.admin.auth.model.resp.OnlineUserResp;
import top.continew.admin.auth.service.OnlineUserService;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.context.UserExtraContext;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* 在线用户业务实现
@@ -53,31 +53,43 @@ public class OnlineUserServiceImpl implements OnlineUserService {
@Override
@AutoOperate(type = OnlineUserResp.class, on = "list")
public PageResp<OnlineUserResp> page(OnlineUserQuery query, PageQuery pageQuery) {
List<LoginUser> loginUserList = this.list(query);
List<OnlineUserResp> list = BeanUtil.copyToList(loginUserList, OnlineUserResp.class);
List<OnlineUserResp> list = this.list(query);
return PageResp.build(pageQuery.getPage(), pageQuery.getSize(), list);
}
@Override
public List<LoginUser> list(OnlineUserQuery query) {
List<LoginUser> loginUserList = new ArrayList<>();
// 查询所有登录用户
public List<OnlineUserResp> list(OnlineUserQuery query) {
List<OnlineUserResp> list = new ArrayList<>();
// 查询所有在线 Token
List<String> tokenKeyList = StpUtil.searchTokenValue(StringConstants.EMPTY, 0, -1, false);
tokenKeyList.parallelStream().forEach(tokenKey -> {
Map<Long, List<String>> tokenMap = tokenKeyList.stream().filter(tokenKey -> {
String token = StrUtil.subAfter(tokenKey, StringConstants.COLON, true);
// 忽略已过期或失效 Token
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) {
return;
return StpUtil.getStpLogic().getTokenActiveTimeoutByToken(token) >= SaTokenDao.NEVER_EXPIRE;
})
.map(tokenKey -> StrUtil.subAfter(tokenKey, StringConstants.COLON, true))
.collect(Collectors.groupingBy(token -> Convert.toLong(StpUtil.getLoginIdByToken(token))));
// 过滤 Token
for (Map.Entry<Long, List<String>> entry : tokenMap.entrySet()) {
Long userId = entry.getKey();
UserContext userContext = UserContextHolder.getContext(userId);
if (null == userContext || !this.isMatchNickname(query.getNickname(), userContext)) {
continue;
}
// 检查是否符合查询条件
LoginUser loginUser = LoginHelper.getLoginUser(token);
if (this.isMatchQuery(query, loginUser)) {
loginUserList.add(loginUser);
}
});
List<Date> loginTimeList = query.getLoginTime();
entry.getValue().parallelStream().forEach(token -> {
UserExtraContext extraContext = UserContextHolder.getExtraContext(token);
if (this.isMatchLoginTime(loginTimeList, extraContext.getLoginTime())) {
OnlineUserResp resp = BeanUtil.copyProperties(userContext, OnlineUserResp.class);
BeanUtil.copyProperties(extraContext, resp);
resp.setToken(token);
list.add(resp);
}
});
}
// 设置排序
CollUtil.sort(loginUserList, Comparator.comparing(LoginUser::getLoginTime).reversed());
return loginUserList;
CollUtil.sort(list, Comparator.comparing(OnlineUserResp::getLoginTime).reversed());
return list;
}
@Override
@@ -95,35 +107,31 @@ public class OnlineUserServiceImpl implements OnlineUserService {
}
/**
* 是否符合查询条件
* 是否匹配昵称
*
* @param query 查询条件
* @param loginUser 登录用户信息
* @return 是否符合查询条件
* @param nickname 昵称
* @param userContext 用户上下文信息
* @return 是否匹配昵称
*/
private boolean isMatchQuery(OnlineUserQuery query, LoginUser loginUser) {
boolean flag1 = true;
String nickname = query.getNickname();
if (StrUtil.isNotBlank(nickname)) {
flag1 = StrUtil.contains(loginUser.getUsername(), nickname) || StrUtil.contains(LoginHelper
.getNickname(loginUser.getId()), nickname);
private boolean isMatchNickname(String nickname, UserContext userContext) {
if (StrUtil.isBlank(nickname)) {
return true;
}
boolean flag2 = true;
List<Date> loginTime = query.getLoginTime();
if (CollUtil.isNotEmpty(loginTime)) {
flag2 = DateUtil.isIn(DateUtil.date(loginUser.getLoginTime()).toJdkDate(), loginTime.get(0), loginTime
.get(1));
return StrUtil.contains(userContext.getUsername(), nickname) || StrUtil.contains(UserContextHolder
.getNickname(userContext.getId()), nickname);
}
/**
* 是否匹配登录时间
*
* @param loginTimeList 登录时间列表
* @param loginTime 登录时间
* @return 是否匹配登录时间
*/
private boolean isMatchLoginTime(List<Date> loginTimeList, LocalDateTime loginTime) {
if (CollUtil.isEmpty(loginTimeList)) {
return true;
}
boolean flag3 = true;
Long userId = query.getUserId();
if (null != userId) {
flag3 = userId.equals(loginUser.getId());
}
boolean flag4 = true;
Long roleId = query.getRoleId();
if (null != roleId) {
flag4 = loginUser.getRoles().stream().anyMatch(r -> r.getId().equals(roleId));
}
return flag1 && flag2 && flag3 && flag4;
return DateUtil.isIn(DateUtil.date(loginTime).toJdkDate(), loginTimeList.get(0), loginTimeList.get(1));
}
}

View File

@@ -26,7 +26,7 @@ import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.recorder.FileRecorder;
import org.dromara.x.file.storage.core.upload.FilePartInfo;
import org.springframework.stereotype.Component;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.system.enums.FileTypeEnum;
import top.continew.admin.system.mapper.FileMapper;
import top.continew.admin.system.mapper.StorageMapper;
@@ -66,7 +66,7 @@ public class FileRecorderImpl implements FileRecorder {
StorageDO storage = (StorageDO)fileInfo.getAttr().get(ClassUtil.getClassName(StorageDO.class, false));
file.setStorageId(storage.getId());
file.setCreateTime(DateUtil.toLocalDateTime(fileInfo.getCreateTime()));
file.setUpdateUser(LoginHelper.getUserId());
file.setUpdateUser(UserContextHolder.getUserId());
file.setUpdateTime(file.getCreateTime());
fileMapper.insert(file);
return true;

View File

@@ -16,13 +16,9 @@
package top.continew.admin.system.mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import top.continew.admin.system.model.entity.UserRoleDO;
import top.continew.starter.data.mp.base.BaseMapper;
import java.util.List;
/**
* 用户和角色 Mapper
*
@@ -30,13 +26,4 @@ import java.util.List;
* @since 2023/2/13 23:13
*/
public interface UserRoleMapper extends BaseMapper<UserRoleDO> {
/**
* 根据用户 ID 查询
*
* @param userId 用户 ID
* @return 角色 ID 列表
*/
@Select("SELECT role_id FROM sys_user_role WHERE user_id = #{userId}")
List<Long> selectRoleIdByUserId(@Param("userId") Long userId);
}

View File

@@ -27,12 +27,12 @@ import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.admin.common.constant.ContainerConstants;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.enums.GenderEnum;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.service.DeptService;
import top.continew.starter.file.excel.converter.ExcelBaseEnumConverter;
import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
import top.continew.starter.file.excel.converter.ExcelBaseEnumConverter;
import top.continew.starter.file.excel.converter.ExcelListConverter;
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
@@ -160,6 +160,6 @@ public class UserDetailResp extends BaseDetailResp {
@Override
public Boolean getDisabled() {
return this.getIsSystem() || Objects.equals(this.getId(), LoginHelper.getUserId());
return this.getIsSystem() || Objects.equals(this.getId(), UserContextHolder.getUserId());
}
}

View File

@@ -21,9 +21,9 @@ import cn.crane4j.core.executor.handler.ManyToManyAssembleOperationHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.admin.common.constant.ContainerConstants;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.enums.GenderEnum;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
import top.continew.starter.security.mask.annotation.JsonMask;
import top.continew.starter.security.mask.enums.MaskType;
@@ -129,6 +129,6 @@ public class UserResp extends BaseDetailResp {
@Override
public Boolean getDisabled() {
return this.getIsSystem() || Objects.equals(this.getId(), LoginHelper.getUserId());
return this.getIsSystem() || Objects.equals(this.getId(), UserContextHolder.getUserId());
}
}

View File

@@ -16,7 +16,7 @@
package top.continew.admin.system.service;
import top.continew.admin.common.model.dto.RoleDTO;
import top.continew.admin.common.context.RoleContext;
import top.continew.admin.system.model.entity.RoleDO;
import top.continew.admin.system.model.query.RoleQuery;
import top.continew.admin.system.model.req.RoleReq;
@@ -66,7 +66,7 @@ public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQ
* @param userId 用户 ID
* @return 角色集合
*/
Set<RoleDTO> listByUserId(Long userId);
Set<RoleContext> listByUserId(Long userId);
/**
* 根据角色编码查询

View File

@@ -59,6 +59,14 @@ public interface UserRoleService {
*/
List<Long> listRoleIdByUserId(Long userId);
/**
* 根据角色 ID 查询
*
* @param roleId 角色 ID
* @return 用户 ID 列表
*/
List<Long> listUserIdByRoleId(Long roleId);
/**
* 根据角色 ID 判断是否已被用户关联
*

View File

@@ -26,15 +26,14 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.continew.admin.auth.model.query.OnlineUserQuery;
import top.continew.admin.auth.service.OnlineUserService;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.constant.ContainerConstants;
import top.continew.admin.common.constant.SysConstants;
import top.continew.admin.common.context.RoleContext;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.enums.DataScopeEnum;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.model.dto.RoleDTO;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.mapper.RoleMapper;
import top.continew.admin.system.model.entity.RoleDO;
import top.continew.admin.system.model.query.RoleQuery;
@@ -104,13 +103,14 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
boolean isSaveDeptSuccess = roleDeptService.add(req.getDeptIds(), id);
// 如果功能权限或数据权限有变更,则更新在线用户权限信息
if (isSaveMenuSuccess || isSaveDeptSuccess || ObjectUtil.notEqual(req.getDataScope(), oldDataScope)) {
OnlineUserQuery query = new OnlineUserQuery();
query.setRoleId(id);
List<LoginUser> loginUserList = onlineUserService.list(query);
loginUserList.forEach(loginUser -> {
loginUser.setRoles(this.listByUserId(loginUser.getId()));
loginUser.setPermissions(this.listPermissionByUserId(loginUser.getId()));
LoginHelper.updateLoginUser(loginUser, loginUser.getToken());
List<Long> userIdList = userRoleService.listUserIdByRoleId(id);
userIdList.parallelStream().forEach(userId -> {
UserContext userContext = UserContextHolder.getContext(userId);
if (null != userContext) {
userContext.setRoles(this.listByUserId(userId));
userContext.setPermissions(this.listPermissionByUserId(userId));
UserContextHolder.setContext(userContext);
}
});
}
}
@@ -171,10 +171,10 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
}
@Override
public Set<RoleDTO> listByUserId(Long userId) {
public Set<RoleContext> listByUserId(Long userId) {
List<Long> roleIdList = userRoleService.listRoleIdByUserId(userId);
List<RoleDO> roleList = baseMapper.lambdaQuery().in(RoleDO::getId, roleIdList).list();
return new HashSet<>(BeanUtil.copyToList(roleList, RoleDTO.class));
return new HashSet<>(BeanUtil.copyToList(roleList, RoleContext.class));
}
@Override

View File

@@ -75,7 +75,24 @@ public class UserRoleServiceImpl implements UserRoleService {
@Override
@ContainerMethod(namespace = ContainerConstants.USER_ROLE_ID_LIST, type = MappingType.ORDER_OF_KEYS)
public List<Long> listRoleIdByUserId(Long userId) {
return baseMapper.selectRoleIdByUserId(userId);
return baseMapper.lambdaQuery()
.select(UserRoleDO::getRoleId)
.eq(UserRoleDO::getUserId, userId)
.list()
.stream()
.map(UserRoleDO::getRoleId)
.toList();
}
@Override
public List<Long> listUserIdByRoleId(Long roleId) {
return baseMapper.lambdaQuery()
.select(UserRoleDO::getUserId)
.eq(UserRoleDO::getRoleId, roleId)
.list()
.stream()
.map(UserRoleDO::getUserId)
.toList();
}
@Override

View File

@@ -52,15 +52,14 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.continew.admin.auth.model.query.OnlineUserQuery;
import top.continew.admin.auth.service.OnlineUserService;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.constant.SysConstants;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.enums.GenderEnum;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.SecureUtils;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.mapper.UserMapper;
import top.continew.admin.system.model.entity.DeptDO;
import top.continew.admin.system.model.entity.RoleDO;
@@ -310,7 +309,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
String phone = req.getPhone();
CheckUtils.throwIf(StrUtil.isNotBlank(phone) && this.isPhoneExists(phone, id), errorMsgTemplate, phone);
DisEnableStatusEnum newStatus = req.getStatus();
CheckUtils.throwIf(DisEnableStatusEnum.DISABLE.equals(newStatus) && ObjectUtil.equal(id, LoginHelper
CheckUtils.throwIf(DisEnableStatusEnum.DISABLE.equals(newStatus) && ObjectUtil.equal(id, UserContextHolder
.getUserId()), "不允许禁用当前用户");
UserDO oldUser = super.getById(id);
if (Boolean.TRUE.equals(oldUser.getIsSystem())) {
@@ -333,14 +332,12 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
}
// 如果角色有变更,则更新在线用户权限信息
if (isSaveUserRoleSuccess) {
OnlineUserQuery query = new OnlineUserQuery();
query.setUserId(id);
List<LoginUser> loginUserList = onlineUserService.list(query);
loginUserList.forEach(loginUser -> {
loginUser.setRoles(roleService.listByUserId(loginUser.getId()));
loginUser.setPermissions(roleService.listPermissionByUserId(loginUser.getId()));
LoginHelper.updateLoginUser(loginUser, loginUser.getToken());
});
UserContext userContext = UserContextHolder.getContext(id);
if (null != userContext) {
userContext.setRoles(roleService.listByUserId(id));
userContext.setPermissions(roleService.listPermissionByUserId(id));
UserContextHolder.setContext(userContext);
}
}
}
@@ -348,7 +345,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
@Transactional(rollbackFor = Exception.class)
@CacheInvalidate(key = "#ids", name = CacheConstants.USER_KEY_PREFIX, multi = true)
public void delete(List<Long> ids) {
CheckUtils.throwIf(CollUtil.contains(ids, LoginHelper.getUserId()), "不允许删除当前用户");
CheckUtils.throwIf(CollUtil.contains(ids, UserContextHolder.getUserId()), "不允许删除当前用户");
List<UserDO> list = baseMapper.lambdaQuery()
.select(UserDO::getNickname, UserDO::getIsSystem)
.in(UserDO::getId, ids)

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.admin.config.satoken;
import cn.dev33.satoken.fun.SaParamFunction;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import top.continew.admin.common.context.UserContextHolder;
/**
* Sa-Token 扩展拦截器
*
* @author Charles7c
* @since 2024/10/10 20:25
*/
public class SaExtensionInterceptor extends SaInterceptor {
public SaExtensionInterceptor(SaParamFunction<Object> auth) {
super(auth);
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
boolean flag = super.preHandle(request, response, handler);
if (flag && StpUtil.isLogin()) {
UserContextHolder.getContext();
UserContextHolder.getExtraContext();
}
return flag;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
@Nullable Exception e) throws Exception {
try {
super.afterCompletion(request, response, handler, e);
} finally {
UserContextHolder.clearContext();
}
}
}

View File

@@ -19,11 +19,12 @@ package top.continew.admin.config.satoken;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionProperties;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.util.validate.CheckUtils;
@@ -54,14 +55,15 @@ public class SaTokenConfiguration {
*/
@Bean
public SaInterceptor saInterceptor() {
return new SaInterceptor(handle -> SaRouter.match(StringConstants.PATH_PATTERN)
return new SaExtensionInterceptor(handle -> SaRouter.match(StringConstants.PATH_PATTERN)
.notMatch(properties.getSecurity().getExcludes())
.check(r -> {
LoginUser loginUser = LoginHelper.getLoginUser();
StpUtil.checkLogin();
if (SaRouter.isMatchCurrURI(loginPasswordProperties.getExcludes())) {
return;
}
CheckUtils.throwIf(loginUser.isPasswordExpired(), "密码已过期,请修改密码");
UserContext userContext = UserContextHolder.getContext();
CheckUtils.throwIf(userContext.isPasswordExpired(), "密码已过期,请修改密码");
}));
}
}

View File

@@ -17,8 +17,8 @@
package top.continew.admin.config.satoken;
import cn.dev33.satoken.stp.StpInterface;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import java.util.ArrayList;
import java.util.List;
@@ -33,13 +33,13 @@ public class SaTokenPermissionImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
return new ArrayList<>(loginUser.getPermissions());
UserContext userContext = UserContextHolder.getContext();
return new ArrayList<>(userContext.getPermissions());
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
LoginUser loginUser = LoginHelper.getLoginUser();
return new ArrayList<>(loginUser.getRoleCodes());
UserContext userContext = UserContextHolder.getContext();
return new ArrayList<>(userContext.getRoleCodes());
}
}

View File

@@ -35,9 +35,9 @@ import top.continew.admin.auth.model.resp.RouteResp;
import top.continew.admin.auth.model.resp.UserInfoResp;
import top.continew.admin.auth.service.LoginService;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.model.dto.LoginUser;
import top.continew.admin.common.context.UserContext;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.util.SecureUtils;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.model.resp.UserDetailResp;
import top.continew.admin.system.service.UserService;
import top.continew.starter.cache.redisson.util.RedisUtils;
@@ -122,12 +122,12 @@ public class AuthController {
@Operation(summary = "获取用户信息", description = "获取登录用户信息")
@GetMapping("/user/info")
public UserInfoResp getUserInfo() {
LoginUser loginUser = LoginHelper.getLoginUser();
UserDetailResp userDetailResp = userService.get(loginUser.getId());
UserContext userContext = UserContextHolder.getContext();
UserDetailResp userDetailResp = userService.get(userContext.getId());
UserInfoResp userInfoResp = BeanUtil.copyProperties(userDetailResp, UserInfoResp.class);
userInfoResp.setPermissions(loginUser.getPermissions());
userInfoResp.setRoles(loginUser.getRoleCodes());
userInfoResp.setPwdExpired(loginUser.isPasswordExpired());
userInfoResp.setPermissions(userContext.getPermissions());
userInfoResp.setRoles(userContext.getRoleCodes());
userInfoResp.setPwdExpired(userContext.isPasswordExpired());
return userInfoResp;
}
@@ -135,6 +135,6 @@ public class AuthController {
@Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
@GetMapping("/route")
public List<RouteResp> listRoute() {
return loginService.buildRouteTree(LoginHelper.getUserId());
return loginService.buildRouteTree(UserContextHolder.getUserId());
}
}

View File

@@ -23,7 +23,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.system.model.query.MessageQuery;
import top.continew.admin.system.model.resp.MessageResp;
import top.continew.admin.system.model.resp.MessageUnreadResp;
@@ -53,7 +53,7 @@ public class MessageController {
@Operation(summary = "分页查询列表", description = "分页查询列表")
@GetMapping
public PageResp<MessageResp> page(MessageQuery query, @Validated PageQuery pageQuery) {
query.setUserId(LoginHelper.getUserId());
query.setUserId(UserContextHolder.getUserId());
return baseService.page(query, pageQuery);
}
@@ -76,6 +76,6 @@ public class MessageController {
@Parameter(name = "isDetail", description = "是否查询详情", example = "true", in = ParameterIn.QUERY)
@GetMapping("/unread")
public MessageUnreadResp countUnreadMessage(@RequestParam(required = false) Boolean detail) {
return messageUserService.countUnreadMessageByUserId(LoginHelper.getUserId(), detail);
return messageUserService.countUnreadMessageByUserId(UserContextHolder.getUserId(), detail);
}
}

View File

@@ -31,8 +31,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.continew.admin.common.constant.CacheConstants;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.common.util.SecureUtils;
import top.continew.admin.common.util.helper.LoginHelper;
import top.continew.admin.system.enums.SocialSourceEnum;
import top.continew.admin.system.model.entity.UserSocialDO;
import top.continew.admin.system.model.req.UserBasicInfoUpdateReq;
@@ -73,14 +73,14 @@ public class UserCenterController {
@PostMapping("/avatar")
public AvatarResp updateAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) throws IOException {
ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空");
String newAvatar = userService.updateAvatar(avatarFile, LoginHelper.getUserId());
String newAvatar = userService.updateAvatar(avatarFile, UserContextHolder.getUserId());
return AvatarResp.builder().avatar(newAvatar).build();
}
@Operation(summary = "修改基础信息", description = "修改用户基础信息")
@PatchMapping("/basic/info")
public void updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) {
userService.updateBasicInfo(req, LoginHelper.getUserId());
userService.updateBasicInfo(req, UserContextHolder.getUserId());
}
@Operation(summary = "修改密码", description = "修改用户登录密码")
@@ -92,7 +92,7 @@ public class UserCenterController {
String rawNewPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(updateReq
.getNewPassword()));
ValidationUtils.throwIfNull(rawNewPassword, "新密码解密失败");
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
userService.updatePassword(rawOldPassword, rawNewPassword, UserContextHolder.getUserId());
}
@Operation(summary = "修改手机号", description = "修改手机号")
@@ -106,7 +106,7 @@ public class UserCenterController {
ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED);
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
RedisUtils.delete(captchaKey);
userService.updatePhone(updateReq.getPhone(), rawOldPassword, LoginHelper.getUserId());
userService.updatePhone(updateReq.getPhone(), rawOldPassword, UserContextHolder.getUserId());
}
@Operation(summary = "修改邮箱", description = "修改用户邮箱")
@@ -120,13 +120,13 @@ public class UserCenterController {
ValidationUtils.throwIfBlank(captcha, CAPTCHA_EXPIRED);
ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
RedisUtils.delete(captchaKey);
userService.updateEmail(updateReq.getEmail(), rawOldPassword, LoginHelper.getUserId());
userService.updateEmail(updateReq.getEmail(), rawOldPassword, UserContextHolder.getUserId());
}
@Operation(summary = "查询绑定的三方账号", description = "查询绑定的三方账号")
@GetMapping("/social")
public List<UserSocialBindResp> listSocialBind() {
List<UserSocialDO> userSocialList = userSocialService.listByUserId(LoginHelper.getUserId());
List<UserSocialDO> userSocialList = userSocialService.listByUserId(UserContextHolder.getUserId());
return userSocialList.stream().map(userSocial -> {
String source = userSocial.getSource();
UserSocialBindResp userSocialBind = new UserSocialBindResp();
@@ -144,13 +144,13 @@ public class UserCenterController {
AuthResponse<AuthUser> response = authRequest.login(callback);
ValidationUtils.throwIf(!response.ok(), response.getMsg());
AuthUser authUser = response.getData();
userSocialService.bind(authUser, LoginHelper.getUserId());
userSocialService.bind(authUser, UserContextHolder.getUserId());
}
@Operation(summary = "解绑三方账号", description = "解绑三方账号")
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@DeleteMapping("/social/{source}")
public void unbindSocial(@PathVariable String source) {
userSocialService.deleteBySourceAndUserId(source, LoginHelper.getUserId());
userSocialService.deleteBySourceAndUserId(source, UserContextHolder.getUserId());
}
}