diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml index 4837d6a42..095b3d7cb 100644 --- a/.run/ruoyi-monitor-admin.run.xml +++ b/.run/ruoyi-monitor-admin.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-powerjob-server.run.xml b/.run/ruoyi-powerjob-server.run.xml index 77a4af095..e36e2acf3 100644 --- a/.run/ruoyi-powerjob-server.run.xml +++ b/.run/ruoyi-powerjob-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml index a29ff2a7f..0463c3439 100644 --- a/.run/ruoyi-server.run.xml +++ b/.run/ruoyi-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/README.md b/README.md index c2ddd191d..e617bc81c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.1.2-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.2.0-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.1-blue.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]() @@ -23,7 +23,13 @@ > 前端项目地址: [plus-ui](https://gitee.com/JavaLionLi/plus-ui) -> 文档地址: [plus-doc](https://plus-doc.dromara.org) - [plus-doc(国内备用)](https://dromara.gitee.io/plus-doc) +> 文档地址: [plus-doc](https://plus-doc.dromara.org) + +## 赞助商 + +MaxKey - https://gitee.com/dromara/MaxKey
+CCFlow - https://gitee.com/opencc/RuoYi-JFlow
+[如何成为赞助商 加群联系作者详谈](https://plus-doc.dromara.org/#/common/add_group) # 本框架与RuoYi的功能差异 @@ -115,13 +121,12 @@ > >[部署项目 必看](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy) >>[https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy](https://plus-doc.dromara.org/#/ruoyi-vue-plus/quickstart/deploy) -> +> +>[如何加群](https://plus-doc.dromara.org/#/common/add_group) +>>[https://plus-doc.dromara.org/#/common/add_group](https://plus-doc.dromara.org/#/common/add_group) +> >[参考文档 Wiki](https://plus-doc.dromara.org) >>[https://plus-doc.dromara.org](https://plus-doc.dromara.org) -> ->[参考文档(国内备份)](https://dromara.gitee.io/plus-doc) ->>[https://dromara.gitee.io/plus-doc](https://dromara.gitee.io/plus-doc) - ## 软件架构图 @@ -131,18 +136,6 @@ [参与贡献的方式 https://plus-doc.dromara.org/#/common/contribution](https://plus-doc.dromara.org/#/common/contribution) -### 其他 - -* 定期同步升级 RuoYi-Vue 有用的更新 -* GitHub 地址 [RuoYi-Vue-Plus](https://github.com/dromara/RuoYi-Vue-Plus) -* 微服务 分支 [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus) -* 前端项目 地址 [plus-ui](https://gitee.com/JavaLionLi/plus-ui) -* 用户扩展项目 [扩展项目列表](https://plus-doc.dromara.org/#/ruoyi-vue-plus/extend-project/list) - -## 加群与捐献 ->[加群与捐献](https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat) ->>[https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat](https://plus-doc.dromara.org/#/ruoyi-vue-plus/other/group_chat) - ## 捐献作者 作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭 diff --git a/pom.xml b/pom.xml index 4cebfda9f..de3d6e94e 100644 --- a/pom.xml +++ b/pom.xml @@ -13,13 +13,13 @@ RuoYi-Vue-Plus多租户管理系统 - 5.1.2 - 3.1.7 + 5.2.0-SNAPSHOT + 3.2.1 UTF-8 UTF-8 17 3.0.3 - 2.2.0 + 2.3.0 0.15.0 5.2.3 3.3.3 @@ -27,12 +27,12 @@ 1.37.0 3.5.5 3.9.1 - 5.8.22 + 5.8.24 4.10.0 - 3.1.8 - 3.24.3 + 3.2.0 + 3.25.2 2.2.5 - 4.2.0 + 4.3.0 2.14.4 4.3.6 1.3.5 @@ -223,7 +223,7 @@ com.baomidou - mybatis-plus-boot-starter + mybatis-plus-spring-boot3-starter ${mybatis-plus.version} diff --git a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java index 6d67fb112..a4724043b 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java @@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.domain.dto.UserOnlineDTO; -import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.utils.MessageUtils; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; @@ -18,6 +17,7 @@ import org.dromara.common.core.utils.ip.AddressUtils; import org.dromara.common.log.event.LogininforEvent; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.web.service.SysLoginService; import org.springframework.stereotype.Component; @@ -43,7 +43,6 @@ public class UserActionListener implements SaTokenListener { public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); String ip = ServletUtils.getClientIP(); - LoginUser user = LoginHelper.getLoginUser(); UserOnlineDTO dto = new UserOnlineDTO(); dto.setIpaddr(ip); dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); @@ -51,25 +50,29 @@ public class UserActionListener implements SaTokenListener { dto.setOs(userAgent.getOs().getName()); dto.setLoginTime(System.currentTimeMillis()); dto.setTokenId(tokenValue); - dto.setUserName(user.getUsername()); - dto.setClientKey(user.getClientKey()); - dto.setDeviceType(user.getDeviceType()); - dto.setDeptName(user.getDeptName()); - if(tokenConfig.getTimeout() == -1) { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); - } else { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); - } + String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY); + String tenantId = (String) loginModel.getExtra(LoginHelper.TENANT_KEY); + dto.setUserName(username); + dto.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY)); + dto.setDeviceType(loginModel.getDevice()); + dto.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY)); + TenantHelper.dynamic(tenantId, () -> { + if(tokenConfig.getTimeout() == -1) { + RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); + } else { + RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout())); + } + }); // 记录登录日志 LogininforEvent logininforEvent = new LogininforEvent(); - logininforEvent.setTenantId(user.getTenantId()); - logininforEvent.setUsername(user.getUsername()); + logininforEvent.setTenantId(tenantId); + logininforEvent.setUsername(username); logininforEvent.setStatus(Constants.LOGIN_SUCCESS); logininforEvent.setMessage(MessageUtils.message("user.login.success")); logininforEvent.setRequest(ServletUtils.getRequest()); SpringUtils.context().publishEvent(logininforEvent); // 更新登录信息 - loginService.recordLoginInfo(user.getUserId(), ip); + loginService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip); log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java index a269d380f..f9b7f2c69 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java @@ -57,7 +57,7 @@ public class SysLoginService { private final ISysPermissionService permissionService; private final ISysSocialService sysSocialService; private final ISysRoleService roleService; - private final SysDeptMapper deptMapper; + private final ISysDeptService deptService; private final SysUserMapper userMapper; @@ -145,11 +145,9 @@ public class SysLoginService { loginUser.setUserType(user.getUserType()); loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); - SysDeptVo dept = deptMapper.selectVoById(user.getDeptId()); + SysDeptVo dept = deptService.selectDeptById(user.getDeptId()); loginUser.setDeptName(ObjectUtil.isNull(dept) ? "" : dept.getDeptName()); - List roles = DataPermissionHelper.ignore(() -> { - return roleService.selectRolesByUserId(user.getUserId()); - }); + List roles = roleService.selectRolesByUserId(user.getUserId()); loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); return loginUser; } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java index 4b00ddb8a..66941651c 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java @@ -7,7 +7,6 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpUtil; import cn.hutool.http.Method; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthResponse; @@ -23,8 +22,6 @@ import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.social.config.properties.SocialProperties; import org.dromara.common.social.utils.SocialUtils; import org.dromara.common.tenant.helper.TenantHelper; -import org.dromara.system.domain.SysClient; -import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysClientVo; import org.dromara.system.domain.vo.SysSocialVo; import org.dromara.system.domain.vo.SysUserVo; @@ -84,11 +81,16 @@ public class SocialAuthStrategy implements IAuthStrategy { if (CollUtil.isEmpty(list)) { throw new ServiceException("你还没有绑定第三方账号,绑定后才可以登录!"); } - Optional opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny(); - if (opt.isEmpty()) { - throw new ServiceException("对不起,你没有权限登录当前租户!"); + SysSocialVo social; + if (TenantHelper.isEnable()) { + Optional opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny(); + if (opt.isEmpty()) { + throw new ServiceException("对不起,你没有权限登录当前租户!"); + } + social = opt.get(); + } else { + social = list.get(0); } - SysSocialVo social = opt.get(); // 查找用户 SysUserVo user = loadUser(social.getTenantId(), social.getUserId()); diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index b7ef18dbd..d4484926e 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -207,6 +207,13 @@ justauth: client-id: 876892492581044224 client-secret: x1Y5MTMwNzIwMjMxNTM4NDc3Mzche8 redirect-uri: ${justauth.address}/social-callback?source=maxkey + topiam: + # topiam 服务器地址 + server-url: http://127.0.0.1:1989/api/v1/authorize/y0q************spq***********8ol + client-id: 449c4*********937************759 + client-secret: ac7***********1e0************28d + redirect-uri: ${justauth.address}/social-callback?source=topiam + scopes: [openid, email, phone, profile] qq: client-id: 10**********6 client-secret: 1f7d08**********5b7**********29e diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3f54f649b..265e1ef1b 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -61,6 +61,11 @@ user: spring: application: name: ${ruoyi.name} + threads: + # 开启虚拟线程 仅jdk21可用 + # 开启后还需更改 UndertowConfig 虚拟线程配置 + virtual: + enabled: false # 资源信息 messages: # 国际化资源文件路径 diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 004b035de..4a2dc1ceb 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ - 5.1.2 + 5.2.0-SNAPSHOT diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java deleted file mode 100644 index e527dab92..000000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.dromara.common.core.context; - -import com.alibaba.ttl.TransmittableThreadLocal; - -import java.util.HashMap; -import java.util.Map; - -/** - * 线程持有类 - * - * @author Michelle.Chung - */ -public class ThreadLocalHolder { - - /** - * 初始化 (支持异步) - */ - private static final ThreadLocal> THREAD_LOCAL = TransmittableThreadLocal.withInitial(HashMap::new); - - /** - * 设置值 - * - * @param key 键 - * @param value 值 - */ - public static void set(String key, T value) { - THREAD_LOCAL.get().put(key, value); - } - - /** - * 获取值 - * - * @param key 键 - * @return 值 - */ - @SuppressWarnings("unchecked") - public static T get(String key) { - return (T) THREAD_LOCAL.get().get(key); - } - - /** - * 移除值 - * - * @param key 键 - */ - public static void remove(String key) { - THREAD_LOCAL.get().remove(key); - } - - /** - * 清空值 - */ - public static void clear() { - THREAD_LOCAL.remove(); - } - -} diff --git a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java index 553d0db6e..5a27e9189 100644 --- a/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java +++ b/ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java @@ -4,8 +4,14 @@ import cn.dev33.satoken.SaManager; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.SecureUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; import org.dromara.common.core.constant.GlobalConstants; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.domain.R; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MessageUtils; @@ -14,13 +20,6 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.redis.utils.RedisUtils; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.AfterThrowing; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; @@ -37,7 +36,7 @@ import java.util.StringJoiner; @Aspect public class RepeatSubmitAspect { - private static final String KEY_CACHE = "keyCache"; + private static final ThreadLocal KEY_CACHE = new ThreadLocal<>(); @Before("@annotation(repeatSubmit)") public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable { @@ -60,7 +59,7 @@ public class RepeatSubmitAspect { // 唯一标识(指定key + url + 消息头) String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey; if (RedisUtils.setObjectIfAbsent(cacheRepeatKey, "", Duration.ofMillis(interval))) { - ThreadLocalHolder.set(KEY_CACHE, cacheRepeatKey); + KEY_CACHE.set(cacheRepeatKey); } else { String message = repeatSubmit.message(); if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) { @@ -83,10 +82,9 @@ public class RepeatSubmitAspect { if (r.getCode() == R.SUCCESS) { return; } - String cacheKey = ThreadLocalHolder.get(KEY_CACHE); - RedisUtils.deleteObject(cacheKey); + RedisUtils.deleteObject(KEY_CACHE.get()); } finally { - ThreadLocalHolder.remove(KEY_CACHE); + KEY_CACHE.remove(); } } } @@ -99,9 +97,8 @@ public class RepeatSubmitAspect { */ @AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) { - String cacheKey = ThreadLocalHolder.get(KEY_CACHE); - RedisUtils.deleteObject(cacheKey); - ThreadLocalHolder.remove(KEY_CACHE); + RedisUtils.deleteObject(KEY_CACHE.get()); + KEY_CACHE.remove(); } /** @@ -130,7 +127,7 @@ public class RepeatSubmitAspect { public boolean isFilterObject(final Object o) { Class clazz = o.getClass(); if (clazz.isArray()) { - return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); } else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) o; for (Object value : collection) { diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java index 5e6af1137..87240729c 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java @@ -4,16 +4,6 @@ import cn.hutool.core.lang.Dict; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; -import org.dromara.common.core.context.ThreadLocalHolder; -import org.dromara.common.core.domain.model.LoginUser; -import org.dromara.common.core.utils.ServletUtils; -import org.dromara.common.core.utils.SpringUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.json.utils.JsonUtils; -import org.dromara.common.log.annotation.Log; -import org.dromara.common.log.enums.BusinessStatus; -import org.dromara.common.log.event.OperLogEvent; -import org.dromara.common.satoken.utils.LoginHelper; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -23,6 +13,15 @@ import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; +import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.core.utils.ServletUtils; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.json.utils.JsonUtils; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessStatus; +import org.dromara.common.log.event.OperLogEvent; +import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.http.HttpMethod; import org.springframework.validation.BindingResult; @@ -51,7 +50,7 @@ public class LogAspect { /** * 计时 key */ - private static final String LOG_STOP_WATCH_KEY = "logStopwatch"; + private static final ThreadLocal KEY_CACHE = new ThreadLocal<>(); /** * 处理请求前执行 @@ -59,7 +58,7 @@ public class LogAspect { @Before(value = "@annotation(controllerLog)") public void boBefore(JoinPoint joinPoint, Log controllerLog) { StopWatch stopWatch = new StopWatch(); - ThreadLocalHolder.set(LOG_STOP_WATCH_KEY, stopWatch); + KEY_CACHE.set(stopWatch); stopWatch.start(); } @@ -112,7 +111,7 @@ public class LogAspect { // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); // 设置消耗时间 - StopWatch stopWatch = ThreadLocalHolder.get(LOG_STOP_WATCH_KEY); + StopWatch stopWatch = KEY_CACHE.get(); stopWatch.stop(); operLog.setCostTime(stopWatch.getTime()); // 发布事件保存数据库 @@ -122,7 +121,7 @@ public class LogAspect { log.error("异常信息:{}", exp.getMessage()); exp.printStackTrace(); } finally { - ThreadLocalHolder.remove(LOG_STOP_WATCH_KEY); + KEY_CACHE.remove(); } } @@ -204,7 +203,7 @@ public class LogAspect { public boolean isFilterObject(final Object o) { Class clazz = o.getClass(); if (clazz.isArray()) { - return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); } else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) o; for (Object value : collection) { diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml index 2088b5439..16d8d5cf1 100644 --- a/ruoyi-common/ruoyi-common-mybatis/pom.xml +++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml @@ -39,7 +39,7 @@ com.baomidou - mybatis-plus-boot-starter + mybatis-plus-spring-boot3-starter org.mybatis diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java index a7bca2089..7f6ab1f00 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java @@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.dromara.common.core.context.ThreadLocalHolder; import java.util.HashMap; import java.util.Map; diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml index 5e5c277f3..140866575 100644 --- a/ruoyi-common/ruoyi-common-redis/pom.xml +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -32,6 +32,11 @@ com.baomidou lock4j-redisson-spring-boot-starter + + + com.github.ben-manes.caffeine + caffeine + diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java new file mode 100644 index 000000000..d57ba4e65 --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/CacheConfig.java @@ -0,0 +1,45 @@ +package org.dromara.common.redis.config; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import org.dromara.common.redis.manager.PlusSpringCacheManager; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; + +import java.util.concurrent.TimeUnit; + +/** + * 缓存配置 + * + * @author Lion Li + */ +@AutoConfiguration +@EnableCaching +public class CacheConfig { + + /** + * caffeine 本地缓存处理器 + */ + @Bean + public Cache caffeine() { + return Caffeine.newBuilder() + // 设置最后一次写入或访问后经过固定时间过期 + .expireAfterWrite(30, TimeUnit.SECONDS) + // 初始的缓存空间大小 + .initialCapacity(100) + // 缓存的最大条数 + .maximumSize(1000) + .build(); + } + + /** + * 自定义缓存管理器 整合spring-cache + */ + @Bean + public CacheManager cacheManager() { + return new PlusSpringCacheManager(); + } + +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java index 7999f2b34..0833d2b52 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator import lombok.extern.slf4j.Slf4j; import org.dromara.common.redis.config.properties.RedissonProperties; import org.dromara.common.redis.handler.KeyPrefixHandler; -import org.dromara.common.redis.manager.PlusSpringCacheManager; import org.redisson.client.codec.StringCodec; import org.redisson.codec.CompositeCodec; import org.redisson.codec.TypedJsonJacksonCodec; @@ -16,8 +15,6 @@ import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; /** @@ -27,7 +24,6 @@ import org.springframework.context.annotation.Bean; */ @Slf4j @AutoConfiguration -@EnableCaching @EnableConfigurationProperties(RedissonProperties.class) public class RedisConfig { @@ -86,14 +82,6 @@ public class RedisConfig { }; } - /** - * 自定义缓存管理器 整合spring-cache - */ - @Bean - public CacheManager cacheManager() { - return new PlusSpringCacheManager(); - } - /** * redis集群配置 yml * diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java new file mode 100644 index 000000000..1d02efda7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java @@ -0,0 +1,88 @@ +package org.dromara.common.redis.manager; + +import cn.hutool.core.lang.Console; +import org.dromara.common.core.utils.SpringUtils; +import org.springframework.cache.Cache; + +import java.util.concurrent.Callable; + +/** + * Cache 装饰器模式(用于扩展 Caffeine 一级缓存) + * + * @author LionLi + */ +public class CaffeineCacheDecorator implements Cache { + + private static final com.github.benmanes.caffeine.cache.Cache + CAFFEINE = SpringUtils.getBean("caffeine"); + + private final Cache cache; + + public CaffeineCacheDecorator(Cache cache) { + this.cache = cache; + } + + @Override + public String getName() { + return cache.getName(); + } + + @Override + public Object getNativeCache() { + return cache.getNativeCache(); + } + + @Override + public ValueWrapper get(Object key) { + Object o = CAFFEINE.get(key, k -> cache.get(key)); + Console.log("redisson caffeine -> key: " + key + ",value:" + o); + return (ValueWrapper) o; + } + + @SuppressWarnings("unchecked") + public T get(Object key, Class type) { + Object o = CAFFEINE.get(key, k -> cache.get(key, type)); + Console.log("redisson caffeine -> key: " + key + ",value:" + o); + return (T) o; + } + + @Override + public void put(Object key, Object value) { + cache.put(key, value); + } + + public ValueWrapper putIfAbsent(Object key, Object value) { + return cache.putIfAbsent(key, value); + } + + @Override + public void evict(Object key) { + evictIfPresent(key); + } + + public boolean evictIfPresent(Object key) { + boolean b = cache.evictIfPresent(key); + if (b) { + CAFFEINE.invalidate(key); + } + return b; + } + + @Override + public void clear() { + cache.clear(); + } + + public boolean invalidate() { + return cache.invalidate(); + } + + @SuppressWarnings("unchecked") + @Override + public T get(Object key, Callable valueLoader) { + Object o = CAFFEINE.get(key, k -> cache.get(key, valueLoader)); + Console.log("redisson caffeine -> key: " + key + ",value:" + o); + return (T) o; + } + +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java index 08ebc7826..a48cb1422 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java @@ -156,7 +156,7 @@ public class PlusSpringCacheManager implements CacheManager { private Cache createMap(String name, CacheConfig config) { RMap map = RedisUtils.getClient().getMap(name); - Cache cache = new RedissonCache(map, allowNullValues); + Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, allowNullValues)); if (transactionAware) { cache = new TransactionAwareCacheDecorator(cache); } @@ -170,7 +170,7 @@ public class PlusSpringCacheManager implements CacheManager { private Cache createMapCache(String name, CacheConfig config) { RMapCache map = RedisUtils.getClient().getMapCache(name); - Cache cache = new RedissonCache(map, config, allowNullValues); + Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, config, allowNullValues)); if (transactionAware) { cache = new TransactionAwareCacheDecorator(cache); } diff --git a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 59192c5ce..0475b19f4 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,2 @@ org.dromara.common.redis.config.RedisConfig +org.dromara.common.redis.config.CacheConfig diff --git a/ruoyi-common/ruoyi-common-satoken/pom.xml b/ruoyi-common/ruoyi-common-satoken/pom.xml index 01c282b63..4df7d4ded 100644 --- a/ruoyi-common/ruoyi-common-satoken/pom.xml +++ b/ruoyi-common/ruoyi-common-satoken/pom.xml @@ -36,6 +36,11 @@ sa-token-jwt + + com.github.ben-manes.caffeine + caffeine + + diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java index d88596228..2cfc927c5 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java @@ -2,26 +2,43 @@ package org.dromara.common.satoken.core.dao; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.util.SaFoxUtil; +import cn.hutool.core.lang.Console; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import org.dromara.common.redis.utils.RedisUtils; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.TimeUnit; /** * Sa-Token持久层接口(使用框架自带RedisUtils实现 协议统一) + *

+ * 采用 caffeine + redis 多级缓存 优化并发查询效率 * * @author Lion Li */ public class PlusSaTokenDao implements SaTokenDao { + private static final Cache CAFFEINE = Caffeine.newBuilder() + // 设置最后一次写入或访问后经过固定时间过期 + .expireAfterWrite(5, TimeUnit.SECONDS) + // 初始的缓存空间大小 + .initialCapacity(100) + // 缓存的最大条数 + .maximumSize(1000) + .build(); + /** * 获取Value,如无返空 */ @Override public String get(String key) { - return RedisUtils.getCacheObject(key); + Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); + Console.log("caffeine -> key:" + key + ",value:" + o); + return (String) o; } /** @@ -38,6 +55,7 @@ public class PlusSaTokenDao implements SaTokenDao { } else { RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout)); } + CAFFEINE.put(key, value); } /** @@ -47,6 +65,7 @@ public class PlusSaTokenDao implements SaTokenDao { public void update(String key, String value) { if (RedisUtils.hasKey(key)) { RedisUtils.setCacheObject(key, value, true); + CAFFEINE.put(key, value); } } @@ -81,7 +100,9 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public Object getObject(String key) { - return RedisUtils.getCacheObject(key); + Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); + Console.log("caffeine -> key:" + key + ",value:" + o); + return o; } /** @@ -98,6 +119,7 @@ public class PlusSaTokenDao implements SaTokenDao { } else { RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout)); } + CAFFEINE.put(key, object); } /** @@ -107,6 +129,7 @@ public class PlusSaTokenDao implements SaTokenDao { public void updateObject(String key, Object object) { if (RedisUtils.hasKey(key)) { RedisUtils.setCacheObject(key, object, true); + CAFFEINE.put(key, object); } } @@ -139,10 +162,14 @@ public class PlusSaTokenDao implements SaTokenDao { /** * 搜索数据 */ + @SuppressWarnings("unchecked") @Override public List searchData(String prefix, String keyword, int start, int size, boolean sortType) { - Collection keys = RedisUtils.keys(prefix + "*" + keyword + "*"); - List list = new ArrayList<>(keys); - return SaFoxUtil.searchList(list, start, size, sortType); + String keyStr = prefix + "*" + keyword + "*"; + return (List) CAFFEINE.get(keyStr, k -> { + Collection keys = RedisUtils.keys(keyStr); + List list = new ArrayList<>(keys); + return SaFoxUtil.searchList(list, start, size, sortType); + }); } } diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java index 5f36ac323..058dee769 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java @@ -9,12 +9,10 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.constant.UserConstants; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.enums.UserType; import java.util.Set; -import java.util.function.Supplier; /** * 登录鉴权助手 @@ -34,9 +32,10 @@ public class LoginHelper { public static final String LOGIN_USER_KEY = "loginUser"; public static final String TENANT_KEY = "tenantId"; public static final String USER_KEY = "userId"; + public static final String USER_NAME_KEY = "userName"; public static final String DEPT_KEY = "deptId"; + public static final String DEPT_NAME_KEY = "deptName"; public static final String CLIENT_KEY = "clientid"; - public static final String TENANT_ADMIN_KEY = "isTenantAdmin"; /** * 登录系统 基于 设备类型 @@ -46,29 +45,28 @@ public class LoginHelper { * @param model 配置参数 */ public static void login(LoginUser loginUser, SaLoginModel model) { - ThreadLocalHolder.set(LOGIN_USER_KEY, loginUser); - ThreadLocalHolder.set(TENANT_KEY, loginUser.getTenantId()); - ThreadLocalHolder.set(USER_KEY, loginUser.getUserId()); - ThreadLocalHolder.set(DEPT_KEY, loginUser.getDeptId()); model = ObjectUtil.defaultIfNull(model, new SaLoginModel()); StpUtil.login(loginUser.getLoginId(), model.setExtra(TENANT_KEY, loginUser.getTenantId()) .setExtra(USER_KEY, loginUser.getUserId()) - .setExtra(DEPT_KEY, loginUser.getDeptId())); - StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); + .setExtra(USER_NAME_KEY, loginUser.getUsername()) + .setExtra(DEPT_KEY, loginUser.getDeptId()) + .setExtra(DEPT_NAME_KEY, loginUser.getDeptName()) + ); + SaSession tokenSession = StpUtil.getTokenSession(); + tokenSession.updateTimeout(model.getTimeout()); + tokenSession.set(LOGIN_USER_KEY, loginUser); } /** * 获取用户(多级缓存) */ public static LoginUser getLoginUser() { - return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> { - SaSession session = StpUtil.getTokenSession(); - if (ObjectUtil.isNull(session)) { - return null; - } - return session.get(LOGIN_USER_KEY); - }); + SaSession session = StpUtil.getTokenSession(); + if (ObjectUtil.isNull(session)) { + return null; + } + return (LoginUser) session.get(LOGIN_USER_KEY); } /** @@ -86,7 +84,7 @@ public class LoginHelper { * 获取用户id */ public static Long getUserId() { - return Convert.toLong(getExtra(USER_KEY)); + return Convert.toLong(getExtra(USER_KEY)); } /** @@ -104,7 +102,12 @@ public class LoginHelper { } private static Object getExtra(String key) { - return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key)); + try { + return StpUtil.getExtra(key); + } catch (Exception e) { + return null; + } + } /** @@ -147,26 +150,11 @@ public class LoginHelper { } public static boolean isTenantAdmin() { - Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> { - return isTenantAdmin(getLoginUser().getRolePermission()); - }); - return Convert.toBool(value); + return Convert.toBool(isTenantAdmin(getLoginUser().getRolePermission())); } public static boolean isLogin() { return getLoginUser() != null; } - public static Object getStorageIfAbsentSet(String key, Supplier handle) { - try { - Object obj = ThreadLocalHolder.get(key); - if (ObjectUtil.isNull(obj)) { - obj = handle.get(); - ThreadLocalHolder.set(key, obj); - } - return obj; - } catch (Exception e) { - return null; - } - } } diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index ace0668e3..b9283e038 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -4,17 +4,14 @@ import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.security.config.properties.SecurityProperties; import org.dromara.common.security.handler.AllUrlHandler; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -62,9 +59,6 @@ public class SecurityConfig implements WebMvcConfigurer { StpUtil.getTokenValue()); } - // 保存用户信息 - ThreadLocalHolder.set(LoginHelper.LOGIN_USER_KEY, LoginHelper.getLoginUser()); - // 有效率影响 用于临时测试 // if (log.isDebugEnabled()) { // log.info("剩余有效时间: {}", StpUtil.getTokenTimeout()); @@ -72,13 +66,7 @@ public class SecurityConfig implements WebMvcConfigurer { // } }); - }) - { - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - ThreadLocalHolder.remove(LoginHelper.LOGIN_USER_KEY); - } - }).addPathPatterns("/**") + })).addPathPatterns("/**") // 排除不需要拦截的路径 .excludePathPatterns(securityProperties.getExcludes()); } diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java index 76be234c6..5f49d9c27 100644 --- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java @@ -2,6 +2,8 @@ package org.dromara.common.social.config.properties; import lombok.Data; +import java.util.List; + /** * 社交登录配置 * @@ -65,4 +67,9 @@ public class SocialLoginConfigProperties { */ private String serverUrl; + /** + * 请求范围 + */ + private List scopes; + } diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java new file mode 100644 index 000000000..13649f9fd --- /dev/null +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java @@ -0,0 +1,100 @@ +package org.dromara.common.social.topiam; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import com.xkcoding.http.support.HttpHeader; +import lombok.extern.slf4j.Slf4j; +import me.zhyd.oauth.cache.AuthStateCache; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthToken; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.request.AuthDefaultRequest; +import me.zhyd.oauth.utils.HttpUtils; +import me.zhyd.oauth.utils.UrlBuilder; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.json.utils.JsonUtils; + +import static org.dromara.common.social.topiam.AuthTopiamSource.TOPIAM; + +/** + * TopIAM 认证请求 + * + * @author xlsea + * @since 2024-01-06 + */ +@Slf4j +public class AuthTopIamRequest extends AuthDefaultRequest { + + public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.topiam.server-url"); + + /** + * 设定归属域 + */ + public AuthTopIamRequest(AuthConfig config) { + super(config, TOPIAM); + } + + public AuthTopIamRequest(AuthConfig config, AuthStateCache authStateCache) { + super(config, TOPIAM, authStateCache); + } + + @Override + protected AuthToken getAccessToken(AuthCallback authCallback) { + String body = doPostAuthorizationCode(authCallback.getCode()); + Dict object = JsonUtils.parseMap(body); + checkResponse(object); + return AuthToken.builder() + .accessToken(object.getStr("access_token")) + .refreshToken(object.getStr("refresh_token")) + .idToken(object.getStr("id_token")) + .tokenType(object.getStr("token_type")) + .scope(object.getStr("scope")) + .build(); + } + + @Override + protected AuthUser getUserInfo(AuthToken authToken) { + String body = doGetUserInfo(authToken); + Dict object = JsonUtils.parseMap(body); + checkResponse(object); + return AuthUser.builder() + .uuid(object.getStr("sub")) + .username(object.getStr("preferred_username")) + .nickname(object.getStr("nickname")) + .avatar(object.getStr("picture")) + .email(object.getStr("email")) + .token(authToken) + .source(source.toString()) + .build(); + } + + + @Override + protected String doGetUserInfo(AuthToken authToken) { + return new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader() + .add("Content-Type", "application/json") + .add("Authorization", "Bearer " + authToken.getAccessToken()), false).getBody(); + } + + + @Override + public String authorize(String state) { + return UrlBuilder.fromBaseUrl(super.authorize(state)) + .queryParam("scope", StrUtil.join("%20", config.getScopes())) + .build(); + } + + public static void checkResponse(Dict object) { + // oauth/token 验证异常 + if (object.containsKey("error")) { + throw new AuthException(object.getStr("error_description")); + } + // user 验证异常 + if (object.containsKey("message")) { + throw new AuthException(object.getStr("message")); + } + } + +} diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopiamSource.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopiamSource.java new file mode 100644 index 000000000..e47d6c640 --- /dev/null +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopiamSource.java @@ -0,0 +1,51 @@ +package org.dromara.common.social.topiam; + +import me.zhyd.oauth.config.AuthSource; +import me.zhyd.oauth.request.AuthDefaultRequest; + +/** + * Oauth2 默认接口说明 + * + * @author xlsea + * @since 2024-01-06 + */ +public enum AuthTopiamSource implements AuthSource { + + /** + * 测试 + */ + TOPIAM { + /** + * 授权的api + */ + @Override + public String authorize() { + return AuthTopIamRequest.SERVER_URL + "/oauth2/auth"; + } + + /** + * 获取accessToken的api + */ + @Override + public String accessToken() { + return AuthTopIamRequest.SERVER_URL + "/oauth2/token"; + } + + /** + * 获取用户信息的api + */ + @Override + public String userInfo() { + return AuthTopIamRequest.SERVER_URL + "/oauth2/userinfo"; + } + + /** + * 平台对应的 AuthRequest 实现类,必须继承自 {@link AuthDefaultRequest} + */ + @Override + public Class getTargetClass() { + return AuthTopIamRequest.class; + } + + } +} diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java index 51b7e13d7..04f621489 100644 --- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java @@ -11,6 +11,7 @@ import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.social.config.properties.SocialLoginConfigProperties; import org.dromara.common.social.config.properties.SocialProperties; import org.dromara.common.social.maxkey.AuthMaxKeyRequest; +import org.dromara.common.social.topiam.AuthTopIamRequest; /** * 认证授权工具类 @@ -38,7 +39,8 @@ public class SocialUtils { AuthConfig.AuthConfigBuilder builder = AuthConfig.builder() .clientId(obj.getClientId()) .clientSecret(obj.getClientSecret()) - .redirectUri(obj.getRedirectUri()); + .redirectUri(obj.getRedirectUri()) + .scopes(obj.getScopes()); return switch (source.toLowerCase()) { case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE); case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE); @@ -63,6 +65,7 @@ public class SocialUtils { case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE); case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE); case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE); + case "topiam" -> new AuthTopIamRequest(builder.build(), STATE_CACHE); default -> throw new AuthException("未获取到有效的Auth配置"); }; } diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java index 7a3a431cc..e830c190a 100644 --- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java @@ -1,14 +1,15 @@ package org.dromara.common.tenant.helper; +import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.convert.Convert; +import com.alibaba.ttl.TransmittableThreadLocal; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.GlobalConstants; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.redis.utils.RedisUtils; @@ -27,7 +28,7 @@ public class TenantHelper { private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant"; - private static final String TENANT_ID_KEY = "tempDynamicTenant"; + private static final ThreadLocal TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>(); /** * 租户功能是否启用 @@ -88,12 +89,12 @@ public class TenantHelper { return; } if (!isLogin()) { - ThreadLocalHolder.set(TENANT_ID_KEY, tenantId); + TEMP_DYNAMIC_TENANT.set(tenantId); return; } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); RedisUtils.setCacheObject(cacheKey, tenantId); - ThreadLocalHolder.set(cacheKey, tenantId); + SaHolder.getStorage().set(cacheKey, tenantId); } /** @@ -106,15 +107,15 @@ public class TenantHelper { return null; } if (!isLogin()) { - return ThreadLocalHolder.get(TENANT_ID_KEY); + return TEMP_DYNAMIC_TENANT.get(); } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); - String tenantId = ThreadLocalHolder.get(cacheKey); + String tenantId = (String) SaHolder.getStorage().get(cacheKey); if (StringUtils.isNotBlank(tenantId)) { return tenantId; } tenantId = RedisUtils.getCacheObject(cacheKey); - ThreadLocalHolder.set(cacheKey, tenantId); + SaHolder.getStorage().set(cacheKey, tenantId); return tenantId; } @@ -126,12 +127,12 @@ public class TenantHelper { return; } if (!isLogin()) { - ThreadLocalHolder.remove(TENANT_ID_KEY); + TEMP_DYNAMIC_TENANT.remove(); return; } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); RedisUtils.deleteObject(cacheKey); - ThreadLocalHolder.remove(cacheKey); + SaHolder.getStorage().delete(cacheKey); } /** diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java index 421ce6d14..282f1bf40 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java @@ -24,6 +24,10 @@ public class UndertowConfig implements WebServerFactoryCustomizer KEY_CACHE = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { @@ -56,7 +55,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { } StopWatch stopWatch = new StopWatch(); - ThreadLocalHolder.set(STOP_WATCH_KEY, stopWatch); + KEY_CACHE.set(stopWatch); stopWatch.start(); } return true; @@ -70,10 +69,10 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - StopWatch stopWatch = ThreadLocalHolder.get(STOP_WATCH_KEY); + StopWatch stopWatch = KEY_CACHE.get(); stopWatch.stop(); log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); - ThreadLocalHolder.clear(); + KEY_CACHE.remove(); } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java index ccba0cf02..0cdb67548 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java @@ -41,7 +41,6 @@ import java.util.Arrays; public class SysProfileController extends BaseController { private final ISysUserService userService; - private final ISysRoleService roleService; private final ISysOssService ossService; /** @@ -50,7 +49,6 @@ public class SysProfileController extends BaseController { @GetMapping public R profile() { SysUserVo user = userService.selectUserById(LoginHelper.getUserId()); - user.setRoles(roleService.selectRolesByUserId(user.getUserId())); ProfileVo profileVo = new ProfileVo(); profileVo.setUser(user); profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserId())); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java index 41319c182..9ab25e71e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java @@ -72,9 +72,8 @@ public class SysUserController extends BaseController { @SaCheckPermission("system:user:export") @PostMapping("/export") public void export(SysUserBo user, HttpServletResponse response) { - List list = userService.selectUserList(user); - List listVo = MapstructUtils.convert(list, SysUserExportVo.class); - ExcelUtil.exportExcel(listVo, "用户数据", SysUserExportVo.class, response); + List list = userService.selectUserExportList(user); + ExcelUtil.exportExcel(list, "用户数据", SysUserExportVo.class, response); } /** @@ -116,7 +115,6 @@ public class SysUserController extends BaseController { if (ObjectUtil.isNull(user)) { return R.fail("没有权限访问用户数据!"); } - user.setRoles(roleService.selectRolesByUserId(user.getUserId())); userInfoVo.setUser(user); userInfoVo.setPermissions(loginUser.getMenuPermission()); userInfoVo.setRoles(loginUser.getRolePermission()); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java index 3cc5186c8..37ec6b709 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java @@ -20,7 +20,6 @@ import java.util.Date; @Data @NoArgsConstructor -@AutoMapper(target = SysUserVo.class, convertGenerate = false) public class SysUserExportVo implements Serializable { @Serial @@ -85,14 +84,12 @@ public class SysUserExportVo implements Serializable { /** * 部门名称 */ - @ReverseAutoMapping(target = "deptName", source = "dept.deptName") @ExcelProperty(value = "部门名称") private String deptName; /** * 负责人 */ - @ReverseAutoMapping(target = "leaderName", source = "dept.leaderName") @ExcelProperty(value = "部门负责人") private String leaderName; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index 7db91d180..d1f405919 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -114,9 +114,10 @@ public class SysUserVo implements Serializable { private Date createTime; /** - * 部门对象 + * 部门名 */ - private SysDeptVo dept; + @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "deptId") + private String deptName; /** * 角色对象 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java index d349832dc..d226d9976 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java @@ -8,6 +8,7 @@ import org.dromara.common.mybatis.annotation.DataColumn; import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.system.domain.SysUser; +import org.dromara.system.domain.vo.SysUserExportVo; import org.dromara.system.domain.vo.SysUserVo; import java.util.List; @@ -20,7 +21,7 @@ import java.util.List; public interface SysUserMapper extends BaseMapperPlus { @DataPermission({ - @DataColumn(key = "deptName", value = "d.dept_id"), + @DataColumn(key = "deptName", value = "u.dept_id"), @DataColumn(key = "userName", value = "u.user_id") }) Page selectPageUserList(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); @@ -35,7 +36,7 @@ public interface SysUserMapper extends BaseMapperPlus { @DataColumn(key = "deptName", value = "d.dept_id"), @DataColumn(key = "userName", value = "u.user_id") }) - List selectUserList(@Param(Constants.WRAPPER) Wrapper queryWrapper); + List selectUserExportList(@Param(Constants.WRAPPER) Wrapper queryWrapper); /** * 根据条件分页查询已配用户角色列表 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java index 6c7323c2b..a5a28cbec 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java @@ -3,6 +3,7 @@ package org.dromara.system.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.system.domain.bo.SysUserBo; +import org.dromara.system.domain.vo.SysUserExportVo; import org.dromara.system.domain.vo.SysUserVo; import java.util.List; @@ -23,7 +24,7 @@ public interface ISysUserService { * @param user 用户信息 * @return 用户信息集合信息 */ - List selectUserList(SysUserBo user); + List selectUserExportList(SysUserBo user); /** * 根据条件分页查询已分配用户角色列表 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java index b20bf65c3..bc6663f0c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java @@ -6,9 +6,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.dromara.common.core.constant.CacheConstants; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.constant.CacheNames; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.DictService; import org.dromara.common.core.utils.MapstructUtils; @@ -26,7 +25,6 @@ import org.dromara.system.domain.vo.SysDictTypeVo; import org.dromara.system.mapper.SysDictDataMapper; import org.dromara.system.mapper.SysDictTypeMapper; import org.dromara.system.service.ISysDictTypeService; -import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -217,16 +215,9 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService * @param separator 分隔符 * @return 字典标签 */ - @SuppressWarnings("unchecked cast") @Override public String getDictLabel(String dictType, String dictValue, String separator) { - // 优先从本地缓存获取 - List datas = ThreadLocalHolder.get(CacheConstants.SYS_DICT_KEY + dictType); - if (ObjectUtil.isNull(datas)) { - datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - ThreadLocalHolder.set(CacheConstants.SYS_DICT_KEY + dictType, datas); - } - + List datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); Map map = StreamUtils.toMap(datas, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel); if (StringUtils.containsAny(dictValue, separator)) { return Arrays.stream(dictValue.split(separator)) @@ -245,16 +236,9 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService * @param separator 分隔符 * @return 字典值 */ - @SuppressWarnings("unchecked cast") @Override public String getDictValue(String dictType, String dictLabel, String separator) { - // 优先从本地缓存获取 - List datas = ThreadLocalHolder.get(CacheConstants.SYS_DICT_KEY + dictType); - if (ObjectUtil.isNull(datas)) { - datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - ThreadLocalHolder.set(CacheConstants.SYS_DICT_KEY + dictType, datas); - } - + List datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); Map map = StreamUtils.toMap(datas, SysDictDataVo::getDictLabel, SysDictDataVo::getDictValue); if (StringUtils.containsAny(dictLabel, separator)) { return Arrays.stream(dictLabel.split(separator)) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java index a831f7e95..191dc98dd 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java @@ -80,7 +80,6 @@ public class SysRoleServiceImpl implements ISysRoleService { .between(params.get("beginTime") != null && params.get("endTime") != null, "r.create_time", params.get("beginTime"), params.get("endTime")) .orderByAsc("r.role_sort").orderByAsc("r.create_time"); - ; return wrapper; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index bde624407..5dcd683e5 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -29,6 +29,7 @@ import org.dromara.system.domain.SysUserRole; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.vo.SysRoleVo; +import org.dromara.system.domain.vo.SysUserExportVo; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.mapper.*; import org.dromara.system.service.ISysUserService; @@ -69,8 +70,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { * @return 用户信息集合信息 */ @Override - public List selectUserList(SysUserBo user) { - return baseMapper.selectUserList(this.buildQueryWrapper(user)); + public List selectUserExportList(SysUserBo user) { + return baseMapper.selectUserExportList(this.buildQueryWrapper(user)); } private Wrapper buildQueryWrapper(SysUserBo user) { @@ -163,7 +164,12 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ @Override public SysUserVo selectUserById(Long userId) { - return baseMapper.selectVoById(userId); + SysUserVo user = baseMapper.selectVoById(userId); + if (ObjectUtil.isNull(user)) { + return user; + } + user.setRoles(roleMapper.selectRolesByUserId(user.getUserId())); + return user; } /** diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index ce1c0d625..8f94866d6 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -4,31 +4,21 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - + + - select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader, u1.user_name as leaderName diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index 63d819e0c..503d2e131 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -100,7 +100,7 @@ services: network_mode: "host" ruoyi-server1: - image: ruoyi/ruoyi-server:5.1.2 + image: ruoyi/ruoyi-server:5.2.0 container_name: ruoyi-server1 environment: # 时区上海 @@ -115,7 +115,7 @@ services: network_mode: "host" ruoyi-server2: - image: ruoyi/ruoyi-server:5.1.2 + image: ruoyi/ruoyi-server:5.2.0 container_name: ruoyi-server2 environment: # 时区上海 @@ -130,7 +130,7 @@ services: network_mode: "host" ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:5.1.2 + image: ruoyi/ruoyi-monitor-admin:5.2.0 container_name: ruoyi-monitor-admin environment: # 时区上海 @@ -142,7 +142,7 @@ services: network_mode: "host" ruoyi-powerjob-server: - image: ruoyi/ruoyi-powerjob-server:5.1.2 + image: ruoyi/ruoyi-powerjob-server:5.2.0 container_name: ruoyi-powerjob-server environment: # 时区上海 diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index 2aa6587da..0e9856abe 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -108,7 +108,7 @@ http { } # 解决 powerjob 代理之后静态文件无法访问的问题 请勿修改乱动 - location ~ ^/(js|css|jpg|png|svg|woff|ttf|ico|img)/ { + location ~ ^/(js|img|fonts)/ { proxy_pass http://powerjob-server; } diff --git a/script/sql/oracle/oracle_ry_vue_5.X.sql b/script/sql/oracle/oracle_ry_vue_5.X.sql index ef45c5f8e..0cbb04f8e 100644 --- a/script/sql/oracle/oracle_ry_vue_5.X.sql +++ b/script/sql/oracle/oracle_ry_vue_5.X.sql @@ -20,7 +20,7 @@ create table sys_social union_id varchar2(255) default null, scope varchar2(255) default null, token_type varchar2(255) default null, - id_token varchar2(255) default null, + id_token varchar2(2000) default null, mac_algorithm varchar2(255) default null, mac_key varchar2(255) default null, code varchar2(255) default null, diff --git a/script/sql/postgres/postgres_ry_vue_5.X.sql b/script/sql/postgres/postgres_ry_vue_5.X.sql index a6d6f1a03..b5e60faea 100644 --- a/script/sql/postgres/postgres_ry_vue_5.X.sql +++ b/script/sql/postgres/postgres_ry_vue_5.X.sql @@ -20,7 +20,7 @@ create table sys_social union_id varchar(255) default null::varchar, scope varchar(255) default null::varchar, token_type varchar(255) default null::varchar, - id_token varchar(255) default null::varchar, + id_token varchar(2000) default null::varchar, mac_algorithm varchar(255) default null::varchar, mac_key varchar(255) default null::varchar, code varchar(255) default null::varchar, diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql index ea365bd01..252779151 100644 --- a/script/sql/ry_vue_5.X.sql +++ b/script/sql/ry_vue_5.X.sql @@ -21,7 +21,7 @@ create table sys_social union_id varchar(255) default null comment '用户的 unionid', scope varchar(255) default null comment '授予的权限,部分平台可能没有', token_type varchar(255) default null comment '个别平台的授权信息,部分平台可能没有', - id_token varchar(255) default null comment 'id token,部分平台可能没有', + id_token varchar(2000) default null comment 'id token,部分平台可能没有', mac_algorithm varchar(255) default null comment '小米平台用户的附带属性,部分平台可能没有', mac_key varchar(255) default null comment '小米平台用户的附带属性,部分平台可能没有', code varchar(255) default null comment '用户的授权code,部分平台可能没有', diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql index a27ac5def..90eec3d70 100644 --- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql +++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql @@ -17,7 +17,7 @@ create table sys_social union_id nvarchar(255) NULL, scope nvarchar(255) NULL, token_type nvarchar(255) NULL, - id_token nvarchar(255) NULL, + id_token nvarchar(2000) NULL, mac_algorithm nvarchar(255) NULL, mac_key nvarchar(255) NULL, code nvarchar(255) NULL,