diff --git a/.run/ruoyi-auth.run.xml b/.run/ruoyi-auth.run.xml index ddb2aff6..87d912cc 100644 --- a/.run/ruoyi-auth.run.xml +++ b/.run/ruoyi-auth.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-gateway.run.xml b/.run/ruoyi-gateway.run.xml index 56b7a3c8..953a838f 100644 --- a/.run/ruoyi-gateway.run.xml +++ b/.run/ruoyi-gateway.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-gen.run.xml b/.run/ruoyi-gen.run.xml index 979d425b..ce6d4651 100644 --- a/.run/ruoyi-gen.run.xml +++ b/.run/ruoyi-gen.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-job.run.xml b/.run/ruoyi-job.run.xml index 04ca8c3c..e9377d8a 100644 --- a/.run/ruoyi-job.run.xml +++ b/.run/ruoyi-job.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-monitor.run.xml b/.run/ruoyi-monitor.run.xml index 79d8f7fb..d340665b 100644 --- a/.run/ruoyi-monitor.run.xml +++ b/.run/ruoyi-monitor.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-nacos.run.xml b/.run/ruoyi-nacos.run.xml index 0cdd6760..148f9e50 100644 --- a/.run/ruoyi-nacos.run.xml +++ b/.run/ruoyi-nacos.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-powerjob-server.run.xml b/.run/ruoyi-powerjob-server.run.xml index 9223aa65..3517aea3 100644 --- a/.run/ruoyi-powerjob-server.run.xml +++ b/.run/ruoyi-powerjob-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-resource.run.xml b/.run/ruoyi-resource.run.xml index f3244e2c..2254b74f 100644 --- a/.run/ruoyi-resource.run.xml +++ b/.run/ruoyi-resource.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-seata-server.run.xml b/.run/ruoyi-seata-server.run.xml index 4a82d785..f8618d23 100644 --- a/.run/ruoyi-seata-server.run.xml +++ b/.run/ruoyi-seata-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-sentinel-dashboard.run.xml b/.run/ruoyi-sentinel-dashboard.run.xml index 970ff383..eda30c01 100644 --- a/.run/ruoyi-sentinel-dashboard.run.xml +++ b/.run/ruoyi-sentinel-dashboard.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-system.run.xml b/.run/ruoyi-system.run.xml index 485d90f9..1d91da35 100644 --- a/.run/ruoyi-system.run.xml +++ b/.run/ruoyi-system.run.xml @@ -2,7 +2,7 @@ - diff --git a/README.md b/README.md index f330c431..899dc0e9 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-Cloud-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Cloud-Plus)
-[![RuoYi-Cloud-Plus](https://img.shields.io/badge/RuoYi_Cloud_Plus-2.1.1-success.svg)](https://gitee.com/dromara/RuoYi-Cloud-Plus) +[![RuoYi-Cloud-Plus](https://img.shields.io/badge/RuoYi_Cloud_Plus-2.1.2-success.svg)](https://gitee.com/dromara/RuoYi-Cloud-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-19](https://img.shields.io/badge/JDK-21-green.svg)]() @@ -42,7 +42,7 @@ | Web容器 | 采用 Undertow 基于 XNIO 的高性能容器 | 采用 Tomcat | | 权限认证 | 采用 Sa-Token、Jwt 静态使用功能齐全 低耦合 高扩展 | Spring Security 配置繁琐扩展性极差 | | 权限注解 | 采用 Sa-Token 支持注解 登录校验、角色校验、权限校验、二级认证校验、HttpBasic校验、忽略校验
角色与权限校验支持多种条件 如 `AND` `OR` 或 `权限 OR 角色` 等复杂表达式 | 只支持是否存在匹配 | -| 关系数据库支持 | 原生支持 MySQL、Oracle、PostgreSQL、SQLServer
可同时使用异构切换 | 支持 Mysql、Oracle 不支持同时使用、不支持异构切换 | +| 关系数据库支持 | 原生支持 MySQL、Oracle、PostgreSQL、SQLServer
可同时使用异构切换(支持其他 mybatis-plus 支持的所有数据库 只需要增加jdbc依赖即可使用 达梦金仓等均有成功案例) | 支持 Mysql、Oracle 不支持同时使用、不支持异构切换 | | 缓存数据库 | 支持 Redis 5-7 支持大部分新功能特性 如 分布式限流、分布式队列 | Redis 简单 get set 支持 | | Redis客户端 | 采用 Redisson Redis官方推荐 基于Netty的客户端工具
支持Redis 90%以上的命令 底层优化规避很多不正确的用法 例如: keys被转换为scan
支持单机、哨兵、单主集群、多主集群等模式 | Lettuce + RedisTemplate 支持模式少 工具使用繁琐
连接池采用 common-pool Bug多经常性出问题 | | 缓存注解 | 采用 Spring-Cache 注解 对其扩展了实现支持了更多功能
例如 过期时间 最大空闲时间 组最大长度等 只需一个注解即可完成数据自动缓存 | 需手动编写Redis代码逻辑 | diff --git a/config/nacos/application-common.yml b/config/nacos/application-common.yml index 96d4e5ca..346b18d2 100644 --- a/config/nacos/application-common.yml +++ b/config/nacos/application-common.yml @@ -194,8 +194,11 @@ api-decrypt: enabled: true # AES 加密头标识 headerFlag: encrypt-key - # 公私钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 - publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ== + # 响应加密公钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 + # 对应前端解密私钥 MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE= + publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8wZK++RNlTLcXoMmdZWEQ/u02RgD5LyLAXGjLOjbMtC+/J9qofpSGTKSx/MCAwEAAQ== + # 请求解密私钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 + # 对应前端加密公钥 MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ== privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= # 接口文档配置 @@ -249,3 +252,4 @@ tenant: - sys_user_post - sys_user_role - sys_client + - sys_oss_config diff --git a/config/nacos/datasource.yml b/config/nacos/datasource.yml index 06754e04..ee003009 100644 --- a/config/nacos/datasource.yml +++ b/config/nacos/datasource.yml @@ -46,7 +46,5 @@ spring: idleTimeout: 600000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 maxLifetime: 1800000 - # 连接测试query(配置检测连接是否有效) - connectionTestQuery: SELECT 1 # 多久检查一次连接的活性 keepaliveTime: 30000 diff --git a/config/nacos/ruoyi-gen.yml b/config/nacos/ruoyi-gen.yml index 7b3aa8bd..f15a2487 100644 --- a/config/nacos/ruoyi-gen.yml +++ b/config/nacos/ruoyi-gen.yml @@ -18,8 +18,6 @@ spring: # url: ${datasource.system-oracle.url} # username: ${datasource.system-oracle.username} # password: ${datasource.system-oracle.password} -# hikari: -# connectionTestQuery: SELECT 1 FROM DUAL # postgres: # type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver diff --git a/config/nacos/ruoyi-job.yml b/config/nacos/ruoyi-job.yml index 826d021d..7041f72b 100644 --- a/config/nacos/ruoyi-job.yml +++ b/config/nacos/ruoyi-job.yml @@ -20,7 +20,7 @@ powerjob: enabled: true # 需要先在 powerjob 登录页执行应用注册后才能使用 app-name: ruoyi-worker - enable-test-mode: false + allow-lazy-connect-server: false max-appended-wf-context-length: 4096 max-result-length: 4096 # 29203 端口 随着主应用端口飘逸 避免集群冲突 diff --git a/config/nacos/ruoyi-resource.yml b/config/nacos/ruoyi-resource.yml index dbabf089..a49753c5 100644 --- a/config/nacos/ruoyi-resource.yml +++ b/config/nacos/ruoyi-resource.yml @@ -17,8 +17,6 @@ spring: # url: ${datasource.system-oracle.url} # username: ${datasource.system-oracle.username} # password: ${datasource.system-oracle.password} -# hikari: -# connectionTestQuery: SELECT 1 FROM DUAL # postgres: # type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver diff --git a/config/nacos/ruoyi-system.yml b/config/nacos/ruoyi-system.yml index b0812317..81550294 100644 --- a/config/nacos/ruoyi-system.yml +++ b/config/nacos/ruoyi-system.yml @@ -17,8 +17,6 @@ spring: # url: ${datasource.system-oracle.url} # username: ${datasource.system-oracle.username} # password: ${datasource.system-oracle.password} -# hikari: -# connectionTestQuery: SELECT 1 FROM DUAL # postgres: # type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 411fe3a6..386bd5e8 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -29,7 +29,7 @@ services: network_mode: "host" nacos: - image: ruoyi/ruoyi-nacos:2.1.1 + image: ruoyi/ruoyi-nacos:2.1.2 container_name: nacos ports: - "8848:8848" @@ -96,7 +96,7 @@ services: network_mode: "host" seata-server: - image: ruoyi/ruoyi-seata-server:2.1.1 + image: ruoyi/ruoyi-seata-server:2.1.2 container_name: seata-server ports: - "7091:7091" @@ -135,7 +135,7 @@ services: network_mode: "host" sentinel: - image: ruoyi/ruoyi-sentinel-dashboard:2.1.1 + image: ruoyi/ruoyi-sentinel-dashboard:2.1.2 container_name: sentinel environment: TZ: Asia/Shanghai @@ -150,7 +150,7 @@ services: network_mode: "host" ruoyi-monitor: - image: ruoyi/ruoyi-monitor:2.1.1 + image: ruoyi/ruoyi-monitor:2.1.2 container_name: ruoyi-monitor environment: # 时区上海 @@ -166,7 +166,7 @@ services: network_mode: "host" ruoyi-powerjob-server: - image: ruoyi/ruoyi-powerjob-server:2.1.1 + image: ruoyi/ruoyi-powerjob-server:2.1.2 container_name: ruoyi-powerjob-server environment: # 时区上海 @@ -181,7 +181,7 @@ services: network_mode: "host" ruoyi-gateway: - image: ruoyi/ruoyi-gateway:2.1.1 + image: ruoyi/ruoyi-gateway:2.1.2 container_name: ruoyi-gateway environment: # 时区上海 @@ -197,7 +197,7 @@ services: network_mode: "host" ruoyi-auth: - image: ruoyi/ruoyi-auth:2.1.1 + image: ruoyi/ruoyi-auth:2.1.2 container_name: ruoyi-auth environment: # 时区上海 @@ -213,7 +213,7 @@ services: network_mode: "host" ruoyi-system: - image: ruoyi/ruoyi-system:2.1.1 + image: ruoyi/ruoyi-system:2.1.2 container_name: ruoyi-system environment: # 时区上海 @@ -229,7 +229,7 @@ services: network_mode: "host" ruoyi-gen: - image: ruoyi/ruoyi-gen:2.1.1 + image: ruoyi/ruoyi-gen:2.1.2 container_name: ruoyi-gen environment: # 时区上海 @@ -245,7 +245,7 @@ services: network_mode: "host" ruoyi-job: - image: ruoyi/ruoyi-job:2.1.1 + image: ruoyi/ruoyi-job:2.1.2 container_name: ruoyi-job environment: # 时区上海 @@ -261,7 +261,7 @@ services: network_mode: "host" ruoyi-resource: - image: ruoyi/ruoyi-resource:2.1.1 + image: ruoyi/ruoyi-resource:2.1.2 container_name: ruoyi-resource environment: # 时区上海 diff --git a/docker/nginx/conf/nginx.conf b/docker/nginx/conf/nginx.conf index 176bc05e..12aaa65b 100644 --- a/docker/nginx/conf/nginx.conf +++ b/docker/nginx/conf/nginx.conf @@ -79,7 +79,7 @@ http { } # 解决 powerjob 代理之后静态文件无法访问的问题 请勿修改乱动 - location .*\.(js|css|jpg|png|svg|woff|ttf|ico)?$ { + location ~ ^/(js|css|jpg|png|svg|woff|ttf|ico|img)/ { proxy_pass http://powerjob-server; } diff --git a/pom.xml b/pom.xml index 2bff3ef2..d9277ad4 100644 --- a/pom.xml +++ b/pom.xml @@ -13,14 +13,14 @@ RuoYi-Cloud-Plus微服务系统 - 2.1.1 + 2.1.2 UTF-8 UTF-8 17 - 3.1.5 + 3.1.7 2022.0.4 - 3.1.7 - 3.0.2 + 3.1.8 + 3.0.3 3.5.13 3.5.4 3.9.1 @@ -30,29 +30,29 @@ 2.2.0 0.15.0 5.2.3 - 3.3.2 + 3.3.3 5.8.22 - 3.24.1 + 3.24.3 2.2.5 - 4.3.3 + 4.3.6 1.37.0 1.18.30 7.4 - 1.1.1 + 2.0.0-beta4 7.14.0 8.16.0 1.76 - 2.14.2 + 2.14.4 1.3.5 0.2.0 - 1.16.5 + 1.16.6 2.7.0 1.2.83 - 1.12.540 + 1.12.600 4.10.0 @@ -293,7 +293,7 @@ - cn.easy-es + org.dromara.easy-es easy-es-boot-starter ${easy-es.version} diff --git a/ruoyi-api/ruoyi-api-bom/pom.xml b/ruoyi-api/ruoyi-api-bom/pom.xml index 18291af8..46b61345 100644 --- a/ruoyi-api/ruoyi-api-bom/pom.xml +++ b/ruoyi-api/ruoyi-api-bom/pom.xml @@ -15,7 +15,7 @@ - 2.1.1 + 2.1.2 diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java new file mode 100644 index 00000000..c689f2d1 --- /dev/null +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java @@ -0,0 +1,37 @@ +package org.dromara.resource.api; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.resource.api.domain.RemoteFile; + +/** + * 文件服务(降级处理) + * + * @author Lion Li + */ +@Slf4j +public class RemoteFileServiceMock implements RemoteFileService { + + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + public RemoteFile upload(String name, String originalFilename, String contentType, byte[] file) { + log.warn("服务调用异常 -> 降级处理"); + return null; + } + + /** + * 通过ossId查询对应的url + * + * @param ossIds ossId串逗号分隔 + * @return url串逗号分隔 + */ + public String selectUrlByIds(String ossIds) { + log.warn("服务调用异常 -> 降级处理"); + return StringUtils.EMPTY; + } + +} diff --git a/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceStub.java b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceStub.java new file mode 100644 index 00000000..813fba63 --- /dev/null +++ b/ruoyi-api/ruoyi-api-resource/src/main/java/org/dromara/resource/api/RemoteMessageServiceStub.java @@ -0,0 +1,38 @@ +package org.dromara.resource.api; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * 消息服务 + * + * @author Lion Li + */ +@Slf4j +@RequiredArgsConstructor +public class RemoteMessageServiceStub implements RemoteMessageService { + + private final RemoteMessageService remoteMessageService; + + /** + * 发送消息 + * + * @param sessionKey session主键 一般为用户id + * @param message 消息文本 + */ + public void sendMessage(Long sessionKey, String message) { + try { + remoteMessageService.sendMessage(sessionKey, message); + } catch (Exception e) { + log.warn("websocket 功能未开启或服务未找到"); + } + } + + public void publishAll(String message) { + try { + remoteMessageService.publishAll(message); + } catch (Exception e) { + log.warn("websocket 功能未开启或服务未找到"); + } + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java index 6c348b8c..ff61c12b 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteSocialService.java @@ -3,6 +3,8 @@ package org.dromara.system.api; import org.dromara.system.api.domain.bo.RemoteSocialBo; import org.dromara.system.api.domain.vo.RemoteSocialVo; +import java.util.List; + /** * 社会化关系服务 * @@ -13,7 +15,7 @@ public interface RemoteSocialService { /** * 根据 authId 查询用户信息 */ - RemoteSocialVo selectByAuthId(String authId); + List selectByAuthId(String authId); /** * 保存社会化关系 diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java index 5fe237e1..8401e610 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java @@ -73,6 +73,14 @@ public interface RemoteUserService { */ String selectUserNameById(Long userId); + /** + * 通过用户ID查询用户昵称 + * + * @param userId 用户id + * @return 结果 + */ + String selectNicknameById(Long userId); + /** * 更新用户信息 * diff --git a/ruoyi-auth/Dockerfile b/ruoyi-auth/Dockerfile index c67b6bdd..f6721d21 100644 --- a/ruoyi-auth/Dockerfile +++ b/ruoyi-auth/Dockerfile @@ -9,15 +9,15 @@ RUN mkdir -p /ruoyi/auth/logs \ WORKDIR /ruoyi/auth -ENV SERVER_PORT=9210 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=9210 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-auth.jar ./app.jar -ENTRYPOINT ["java", \ - "-Djava.security.egd=file:/dev/./urandom", \ - "-Dserver.port=${SERVER_PORT}", \ -# "-Dskywalking.agent.service_name=ruoyi-auth", \ -# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ - "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ + #-Dskywalking.agent.service_name=ruoyi-auth \ + #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ + -jar app.jar \ + -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} + diff --git a/ruoyi-auth/pom.xml b/ruoyi-auth/pom.xml index b4f8b202..a09df551 100644 --- a/ruoyi-auth/pom.xml +++ b/ruoyi-auth/pom.xml @@ -65,6 +65,11 @@ ruoyi-common-web + + org.dromara + ruoyi-common-ratelimiter + + org.dromara ruoyi-common-encrypt diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/controller/CaptchaController.java b/ruoyi-auth/src/main/java/org/dromara/auth/controller/CaptchaController.java index 9a381553..63d002cf 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/controller/CaptchaController.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/controller/CaptchaController.java @@ -15,6 +15,8 @@ import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.reflect.ReflectUtils; +import org.dromara.common.ratelimiter.annotation.RateLimiter; +import org.dromara.common.ratelimiter.enums.LimitType; import org.dromara.common.redis.utils.RedisUtils; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -42,6 +44,7 @@ public class CaptchaController { /** * 生成验证码 */ + @RateLimiter(time = 60, count = 10, limitType = LimitType.IP) @GetMapping("/code") public R getCode() { CaptchaVo captchaVo = new CaptchaVo(); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java index 780b0b40..6424a6a0 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java @@ -21,6 +21,7 @@ import org.dromara.common.core.constant.UserConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.model.LoginBody; import org.dromara.common.core.utils.*; +import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.social.config.properties.SocialLoginConfigProperties; @@ -34,7 +35,6 @@ import org.dromara.system.api.RemoteSocialService; import org.dromara.system.api.RemoteTenantService; import org.dromara.system.api.domain.vo.RemoteClientVo; import org.dromara.system.api.domain.vo.RemoteTenantVo; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.net.URL; @@ -48,7 +48,6 @@ import java.util.concurrent.TimeUnit; * @author Lion Li */ @Slf4j -@Validated @RequiredArgsConstructor @RestController public class TokenController { @@ -65,7 +64,7 @@ public class TokenController { private final RemoteClientService remoteClientService; @DubboReference private final RemoteSocialService remoteSocialService; - @DubboReference + @DubboReference(stub = "true") private final RemoteMessageService remoteMessageService; /** @@ -74,8 +73,9 @@ public class TokenController { * @param body 登录信息 * @return 结果 */ + @ApiEncrypt @PostMapping("/login") - public R login(@Validated @RequestBody String body) { + public R login(@RequestBody String body) { LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class); ValidatorUtils.validate(loginBody); // 授权类型和客户端id @@ -167,6 +167,7 @@ public class TokenController { /** * 用户注册 */ + @ApiEncrypt @PostMapping("register") public R register(@RequestBody RegisterBody registerBody) { if (!remoteConfigService.selectRegisterEnabled(registerBody.getTenantId())) { diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/listener/UserActionListener.java b/ruoyi-auth/src/main/java/org/dromara/auth/listener/UserActionListener.java index c13431c4..86df42c7 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/listener/UserActionListener.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/listener/UserActionListener.java @@ -6,19 +6,26 @@ import cn.dev33.satoken.stp.SaLoginModel; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.core.constant.CacheConstants; -import org.dromara.common.core.enums.UserType; +import org.dromara.common.core.constant.Constants; +import org.dromara.common.core.utils.MessageUtils; import org.dromara.common.core.utils.ServletUtils; +import org.dromara.common.core.utils.SpringUtils; 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.resource.api.RemoteMessageService; +import org.dromara.system.api.RemoteUserService; import org.dromara.system.api.domain.SysUserOnline; import org.dromara.system.api.model.LoginUser; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.time.Duration; +import java.util.concurrent.ScheduledExecutorService; /** * 用户行为 侦听器的实现 @@ -31,39 +38,49 @@ import java.time.Duration; public class UserActionListener implements SaTokenListener { private final SaTokenConfig tokenConfig; + private final ScheduledExecutorService scheduledExecutorService; + @DubboReference + private RemoteUserService remoteUserService; + @DubboReference + private RemoteMessageService remoteMessageService; /** * 每次登录时触发 */ @Override public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { - UserType userType = UserType.getUserType(loginId.toString()); - if (userType == UserType.SYS_USER) { - UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); - String ip = ServletUtils.getClientIP(); - LoginUser user = LoginHelper.getLoginUser(); - SysUserOnline userOnline = new SysUserOnline(); - userOnline.setIpaddr(ip); - userOnline.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); - userOnline.setBrowser(userAgent.getBrowser().getName()); - userOnline.setOs(userAgent.getOs().getName()); - userOnline.setLoginTime(System.currentTimeMillis()); - userOnline.setTokenId(tokenValue); - userOnline.setUserName(user.getUsername()); - userOnline.setClientKey(user.getClientKey()); - userOnline.setDeviceType(user.getDeviceType()); - if (ObjectUtil.isNotNull(user.getDeptName())) { - userOnline.setDeptName(user.getDeptName()); - } - if(tokenConfig.getTimeout() == -1) { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline); - } else { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(tokenConfig.getTimeout())); - } - log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue); - } else if (userType == UserType.APP_USER) { - // app端 自行根据业务编写 + UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = ServletUtils.getClientIP(); + LoginUser user = LoginHelper.getLoginUser(); + SysUserOnline userOnline = new SysUserOnline(); + userOnline.setIpaddr(ip); + userOnline.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + userOnline.setBrowser(userAgent.getBrowser().getName()); + userOnline.setOs(userAgent.getOs().getName()); + userOnline.setLoginTime(System.currentTimeMillis()); + userOnline.setTokenId(tokenValue); + userOnline.setUserName(user.getUsername()); + userOnline.setClientKey(user.getClientKey()); + userOnline.setDeviceType(user.getDeviceType()); + if (ObjectUtil.isNotNull(user.getDeptName())) { + userOnline.setDeptName(user.getDeptName()); + } + if (tokenConfig.getTimeout() == -1) { + RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline); + } else { + RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(tokenConfig.getTimeout())); } + // 记录登录日志 + LogininforEvent logininforEvent = new LogininforEvent(); + logininforEvent.setTenantId(user.getTenantId()); + logininforEvent.setUsername(user.getUsername()); + logininforEvent.setStatus(Constants.LOGIN_SUCCESS); + logininforEvent.setMessage(MessageUtils.message("user.login.success")); + logininforEvent.setRequest(ServletUtils.getRequest()); + SpringUtils.context().publishEvent(logininforEvent); + // 更新登录信息 + remoteUserService.recordLoginInfo(user.getUserId(), ServletUtils.getClientIP()); + log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue); } /** diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/SysLoginService.java index 24ebeb57..eb2d7e64 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/SysLoginService.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/SysLoginService.java @@ -4,6 +4,7 @@ import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,7 +19,7 @@ import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.enums.LoginType; import org.dromara.common.core.enums.TenantStatus; import org.dromara.common.core.enums.UserType; -import org.dromara.common.core.exception.CaptchaException; +import org.dromara.common.core.exception.user.CaptchaException; import org.dromara.common.core.exception.user.CaptchaExpireException; import org.dromara.common.core.exception.user.UserException; import org.dromara.common.core.utils.MessageUtils; @@ -43,6 +44,7 @@ import org.springframework.stereotype.Service; import java.time.Duration; import java.util.Date; +import java.util.List; import java.util.function.Supplier; /** @@ -83,13 +85,13 @@ public class SysLoginService { bo.setUserName(authUserData.getUsername()); bo.setNickName(authUserData.getNickname()); // 查询是否已经绑定用户 - RemoteSocialVo vo = remoteSocialService.selectByAuthId(authId); - if (ObjectUtil.isEmpty(vo)) { + List list = remoteSocialService.selectByAuthId(authId); + if (CollUtil.isEmpty(list)) { // 没有绑定用户, 新增用户信息 remoteSocialService.insertByBo(bo); } else { // 更新用户信息 - bo.setId(vo.getId()); + bo.setId(list.get(0).getId()); remoteSocialService.updateByBo(bo); } } @@ -100,6 +102,9 @@ public class SysLoginService { public void logout() { try { LoginUser loginUser = LoginHelper.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + return; + } if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) { // 超级管理员 登出清除动态租户 TenantHelper.clearDynamic(); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/EmailAuthStrategy.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/EmailAuthStrategy.java index c4b66078..8790fe13 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/EmailAuthStrategy.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/EmailAuthStrategy.java @@ -14,7 +14,6 @@ import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.enums.LoginType; import org.dromara.common.core.exception.user.CaptchaExpireException; import org.dromara.common.core.utils.MessageUtils; -import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; @@ -63,9 +62,6 @@ public class EmailAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); - loginService.recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - remoteUserService.recordLoginInfo(loginUser.getUserId(), ServletUtils.getClientIP()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java index e5720a1b..9550485c 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java @@ -14,10 +14,9 @@ import org.dromara.auth.service.SysLoginService; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.enums.LoginType; -import org.dromara.common.core.exception.CaptchaException; +import org.dromara.common.core.exception.user.CaptchaException; import org.dromara.common.core.exception.user.CaptchaExpireException; import org.dromara.common.core.utils.MessageUtils; -import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; @@ -74,9 +73,6 @@ public class PasswordAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); - loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - remoteUserService.recordLoginInfo(loginUser.getUserId(), ServletUtils.getClientIP()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java index d2114ecd..d32b5aa1 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java @@ -14,7 +14,6 @@ import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.enums.LoginType; import org.dromara.common.core.exception.user.CaptchaExpireException; import org.dromara.common.core.utils.MessageUtils; -import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; @@ -63,9 +62,6 @@ public class SmsAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); - loginService.recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - remoteUserService.recordLoginInfo(loginUser.getUserId(), ServletUtils.getClientIP()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SocialAuthStrategy.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SocialAuthStrategy.java index d86392cc..ea1bde11 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SocialAuthStrategy.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SocialAuthStrategy.java @@ -2,9 +2,8 @@ package org.dromara.auth.service.impl; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.http.Method; import lombok.RequiredArgsConstructor; @@ -16,10 +15,7 @@ import org.dromara.auth.domain.vo.LoginVo; import org.dromara.auth.form.SocialLoginBody; import org.dromara.auth.service.IAuthStrategy; import org.dromara.auth.service.SysLoginService; -import org.dromara.common.core.constant.Constants; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.utils.MessageUtils; -import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.satoken.utils.LoginHelper; @@ -32,6 +28,9 @@ import org.dromara.system.api.domain.vo.RemoteSocialVo; import org.dromara.system.api.model.LoginUser; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; + /** * 第三方授权策略 * @@ -53,7 +52,6 @@ public class SocialAuthStrategy implements IAuthStrategy { /** * 登录-第三方授权登录 * - * @param clientId 客户端id * @param body 登录信息 * @param client 客户端信息 */ @@ -78,18 +76,17 @@ public class SocialAuthStrategy implements IAuthStrategy { .executeAsync(); } - RemoteSocialVo socialVo = remoteSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid()); - if (!ObjectUtil.isNotNull(socialVo)) { + List list = remoteSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid()); + if (CollUtil.isEmpty(list)) { throw new ServiceException("你还没有绑定第三方账号,绑定后才可以登录!"); } - // 验证授权表里面的租户id是否包含当前租户id - String tenantId = socialVo.getTenantId(); - if (ObjectUtil.isNotNull(socialVo) && StrUtil.isNotBlank(tenantId) - && !tenantId.contains(loginBody.getTenantId())) { + Optional opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny(); + if (opt.isEmpty()) { throw new ServiceException("对不起,你没有权限登录当前租户!"); } + RemoteSocialVo socialVo = opt.get(); - LoginUser loginUser = remoteUserService.getUserInfo(socialVo.getUserId(), tenantId); + LoginUser loginUser = remoteUserService.getUserInfo(socialVo.getUserId(), socialVo.getTenantId()); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -102,9 +99,6 @@ public class SocialAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); - loginService.recordLogininfor(loginUser.getTenantId(), socialVo.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - remoteUserService.recordLoginInfo(loginUser.getUserId(), ServletUtils.getClientIP()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/XcxAuthStrategy.java b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/XcxAuthStrategy.java index 1d68c6d4..20ec4cc3 100644 --- a/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/XcxAuthStrategy.java +++ b/ruoyi-auth/src/main/java/org/dromara/auth/service/impl/XcxAuthStrategy.java @@ -9,9 +9,6 @@ import org.dromara.auth.domain.vo.LoginVo; import org.dromara.auth.form.XcxLoginBody; import org.dromara.auth.service.IAuthStrategy; import org.dromara.auth.service.SysLoginService; -import org.dromara.common.core.constant.Constants; -import org.dromara.common.core.utils.MessageUtils; -import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.satoken.utils.LoginHelper; @@ -61,9 +58,6 @@ public class XcxAuthStrategy implements IAuthStrategy { // 生成token LoginHelper.login(loginUser, model); - loginService.recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); - remoteUserService.recordLoginInfo(loginUser.getUserId(), ServletUtils.getClientIP()); - LoginVo loginVo = new LoginVo(); loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setExpireIn(StpUtil.getTokenTimeout()); diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index b2cefe10..ff3ea10f 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -26,6 +26,7 @@ ruoyi-common-seata ruoyi-common-loadbalancer ruoyi-common-oss + ruoyi-common-ratelimiter ruoyi-common-idempotent ruoyi-common-mail ruoyi-common-sms diff --git a/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml b/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml index 4cd0a213..4a7cb385 100644 --- a/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml @@ -14,7 +14,7 @@ - 2.1.1 + 2.1.2 2022.0.0.0 1.8.6 1.7.1 diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index bff0b6ed..043824eb 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ - 2.1.1 + 2.1.2 @@ -118,6 +118,13 @@ ${revision} + + + org.dromara + ruoyi-common-ratelimiter + ${revision} + + org.dromara ruoyi-common-idempotent diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml index be8c0924..01d876e7 100644 --- a/ruoyi-common/ruoyi-common-core/pom.xml +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -28,16 +28,6 @@ spring-web - - com.baomidou - mybatis-plus-annotation - - - - org.mybatis - mybatis - - org.springframework.boot @@ -81,12 +71,6 @@ hutool-extra - - cn.hutool - hutool-json - provided - - org.projectlombok lombok diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java index c3425d0a..e59277aa 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java @@ -40,6 +40,11 @@ public interface CacheNames { */ String SYS_USER_NAME = "sys_user_name#30d"; + /** + * 用户名称 + */ + String SYS_NICKNAME = "sys_nickname#30d"; + /** * 部门 */ @@ -53,7 +58,7 @@ public interface CacheNames { /** * OSS配置 */ - String SYS_OSS_CONFIG = "sys_oss_config"; + String SYS_OSS_CONFIG = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss_config"; /** * 在线用户 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CheckedException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CheckedException.java deleted file mode 100644 index 9a7bbeec..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CheckedException.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.dromara.common.core.exception; - -import java.io.Serial; - -/** - * 检查异常 - * - * @author ruoyi - */ -public class CheckedException extends RuntimeException { - @Serial - private static final long serialVersionUID = 1L; - - public CheckedException(String message) { - super(message); - } - - public CheckedException(Throwable cause) { - super(cause); - } - - public CheckedException(String message, Throwable cause) { - super(message, cause); - } - - public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java deleted file mode 100644 index 9916ddf2..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.dromara.common.core.exception; - -import java.io.Serial; - -/** - * 演示模式异常 - * - * @author ruoyi - */ -public class DemoModeException extends RuntimeException { - - @Serial - private static final long serialVersionUID = 1L; - - public DemoModeException() { - } -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java deleted file mode 100644 index 76b1265d..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.dromara.common.core.exception; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -import java.io.Serial; - -/** - * 全局异常 - * - * @author ruoyi - */ -@Data -@EqualsAndHashCode(callSuper = true) -@NoArgsConstructor -@AllArgsConstructor -public class GlobalException extends RuntimeException { - - @Serial - private static final long serialVersionUID = 1L; - - /** - * 错误提示 - */ - private String message; - - /** - * 错误明细,内部调试错误 - */ - private String detailMessage; - - public GlobalException(String message) { - this.message = message; - } - - public String getDetailMessage() { - return detailMessage; - } - - public GlobalException setDetailMessage(String detailMessage) { - this.detailMessage = detailMessage; - return this; - } - - @Override - public String getMessage() { - return message; - } - - public GlobalException setMessage(String message) { - this.message = message; - return this; - } -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java deleted file mode 100644 index a9bf2c60..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.dromara.common.core.exception; - -import java.io.Serial; - -/** - * 工具类异常 - * - * @author ruoyi - */ -public class UtilException extends RuntimeException { - - @Serial - private static final long serialVersionUID = 8247610319171014183L; - - public UtilException(Throwable e) { - super(e.getMessage(), e); - } - - public UtilException(String message) { - super(message); - } - - public UtilException(String message, Throwable throwable) { - super(message, throwable); - } -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CaptchaException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java similarity index 76% rename from ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CaptchaException.java rename to ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java index b828fd4a..a18e581e 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/CaptchaException.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java @@ -1,6 +1,4 @@ -package org.dromara.common.core.exception; - -import org.dromara.common.core.exception.user.UserException; +package org.dromara.common.core.exception.user; import java.io.Serial; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java deleted file mode 100644 index 289cca75..00000000 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.dromara.common.core.exception.user; - -import java.io.Serial; - -/** - * 用户密码不正确或不符合规范异常类 - * - * @author ruoyi - */ -public class UserPasswordNotMatchException extends UserException { - - @Serial - private static final long serialVersionUID = 1L; - - public UserPasswordNotMatchException() { - super("user.password.not.match"); - } -} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java index 1ed01a98..3e109b21 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java @@ -1,9 +1,8 @@ package org.dromara.common.core.utils.sql; -import org.dromara.common.core.exception.UtilException; -import org.dromara.common.core.utils.StringUtils; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.common.core.utils.StringUtils; /** * sql操作工具类 @@ -28,7 +27,7 @@ public class SqlUtil { */ public static String escapeOrderBySql(String value) { if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) { - throw new UtilException("参数不符合规范,不能进行查询"); + throw new IllegalArgumentException("参数不符合规范,不能进行查询"); } return value; } @@ -50,7 +49,7 @@ public class SqlUtil { String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); for (String sqlKeyword : sqlKeywords) { if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) { - throw new UtilException("参数存在SQL注入风险"); + throw new IllegalArgumentException("参数存在SQL注入风险"); } } } diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties index c8635612..cce11c85 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties +++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties @@ -50,7 +50,10 @@ sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1} email.code.not.blank=邮箱验证码不能为空 email.code.retry.limit.count=邮箱验证码输入错误{0}次 email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 -xcx.code.not.blank=小程序code不能为空 +xcx.code.not.blank=小程序[code]不能为空 +social.source.not.blank=第三方登录平台[source]不能为空 +social.code.not.blank=第三方登录平台[code]不能为空 +social.state.not.blank=第三方登录平台[state]不能为空 ##租户 tenant.number.not.blank=租户编号不能为空 tenant.not.exists=对不起, 您的租户不存在,请联系管理员 diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties index 355da843..f948c4ab 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties +++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties @@ -50,7 +50,10 @@ sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for { email.code.not.blank=Email code cannot be blank email.code.retry.limit.count=Email code input error {0} times email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes -xcx.code.not.blank=Mini program code cannot be blank +xcx.code.not.blank=Mini program [code] cannot be blank +social.source.not.blank=Social login platform [source] cannot be blank +social.code.not.blank=Social login platform [code] cannot be blank +social.state.not.blank=Social login platform [state] cannot be blank ##租户 tenant.number.not.blank=Tenant number cannot be blank tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties index c8635612..cce11c85 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties +++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties @@ -50,7 +50,10 @@ sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1} email.code.not.blank=邮箱验证码不能为空 email.code.retry.limit.count=邮箱验证码输入错误{0}次 email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 -xcx.code.not.blank=小程序code不能为空 +xcx.code.not.blank=小程序[code]不能为空 +social.source.not.blank=第三方登录平台[source]不能为空 +social.code.not.blank=第三方登录平台[code]不能为空 +social.state.not.blank=第三方登录平台[state]不能为空 ##租户 tenant.number.not.blank=租户编号不能为空 tenant.not.exists=对不起, 您的租户不存在,请联系管理员 diff --git a/ruoyi-common/ruoyi-common-elasticsearch/pom.xml b/ruoyi-common/ruoyi-common-elasticsearch/pom.xml index 1e542ff2..401320dc 100644 --- a/ruoyi-common/ruoyi-common-elasticsearch/pom.xml +++ b/ruoyi-common/ruoyi-common-elasticsearch/pom.xml @@ -17,7 +17,7 @@ - cn.easy-es + org.dromara.easy-es easy-es-boot-starter diff --git a/ruoyi-common/ruoyi-common-elasticsearch/src/main/java/org/dromara/common/elasticsearch/config/EasyEsConfiguration.java b/ruoyi-common/ruoyi-common-elasticsearch/src/main/java/org/dromara/common/elasticsearch/config/EasyEsConfiguration.java index 837ca93e..3d6354a3 100644 --- a/ruoyi-common/ruoyi-common-elasticsearch/src/main/java/org/dromara/common/elasticsearch/config/EasyEsConfiguration.java +++ b/ruoyi-common/ruoyi-common-elasticsearch/src/main/java/org/dromara/common/elasticsearch/config/EasyEsConfiguration.java @@ -1,6 +1,6 @@ package org.dromara.common.elasticsearch.config; -import cn.easyes.starter.register.EsMapperScan; +import org.dromara.easyes.starter.register.EsMapperScan; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml index 7f580637..df3222be 100644 --- a/ruoyi-common/ruoyi-common-encrypt/pom.xml +++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml @@ -37,6 +37,11 @@ hutool-crypto + + org.springframework + spring-webmvc + + diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java new file mode 100644 index 00000000..7f52de80 --- /dev/null +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java @@ -0,0 +1,20 @@ +package org.dromara.common.encrypt.annotation; + +import java.lang.annotation.*; + +/** + * 强制加密注解 + * + * @author Michelle.Chung + */ +@Documented +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApiEncrypt { + + /** + * 响应加密忽略,默认不加密,为 true 时加密 + */ + boolean response() default false; + +} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java index c31e025a..84b85d38 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java @@ -3,10 +3,19 @@ package org.dromara.common.encrypt.filter; import cn.hutool.core.util.ObjectUtil; import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.encrypt.properties.ApiDecryptProperties; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.io.IOException; @@ -25,8 +34,14 @@ public class CryptoFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - ServletRequest requestWrapper = null; HttpServletRequest servletRequest = (HttpServletRequest) request; + HttpServletResponse servletResponse = (HttpServletResponse) response; + + boolean encryptFlag = false; + ServletRequest requestWrapper = null; + ServletResponse responseWrapper = null; + EncryptResponseBodyWrapper responseBodyWrapper = null; + // 是否为 json 请求 if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { // 是否为 put 或者 post 请求 @@ -34,16 +49,67 @@ public class CryptoFilter implements Filter { // 是否存在加密标头 String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); if (StringUtils.isNotBlank(headerValue)) { - requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPublicKey(), properties.getPrivateKey(), properties.getHeaderFlag()); + // 请求解密 + requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); + // 获取加密注解 + ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); + if (ObjectUtil.isNotNull(apiEncrypt)) { + // 响应加密标志 + encryptFlag = apiEncrypt.response(); + } else { + // 是否有注解,有就报错,没有放行 + HandlerExceptionResolver exceptionResolver = SpringUtils.getBean(HandlerExceptionResolver.class); + exceptionResolver.resolveException( + servletRequest, servletResponse, null, + new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN)); + } + } + // 判断是否响应加密 + if (encryptFlag) { + responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); + responseWrapper = responseBodyWrapper; } } } - chain.doFilter(ObjectUtil.defaultIfNull(requestWrapper, request), response); + chain.doFilter( + ObjectUtil.defaultIfNull(requestWrapper, request), + ObjectUtil.defaultIfNull(responseWrapper, response)); + + if (encryptFlag) { + servletResponse.reset(); + // 对原始内容加密 + String encryptContent = responseBodyWrapper.getEncryptContent( + servletResponse, properties.getPublicKey(), properties.getHeaderFlag()); + // 对加密后的内容写出 + servletResponse.getWriter().write(encryptContent); + } + } + + /** + * 获取 ApiEncrypt 注解 + */ + private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) { + RequestMappingHandlerMapping handlerMapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); + // 获取注解 + try { + HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest); + if (ObjectUtil.isNotNull(mappingHandler)) { + Object handler = mappingHandler.getHandler(); + if (ObjectUtil.isNotNull(handler)) { + // 从handler获取注解 + if (handler instanceof HandlerMethod handlerMethod) { + return handlerMethod.getMethodAnnotation(ApiEncrypt.class); + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; } @Override public void destroy() { - } } diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java index fa9a3107..98f4bc7c 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java @@ -24,7 +24,7 @@ public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper { private final byte[] body; - public DecryptRequestBodyWrapper(HttpServletRequest request, String publicKey, String privateKey, String headerFlag) throws IOException { + public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey, String headerFlag) throws IOException { super(request); // 获取 AES 密码 采用 RSA 加密 String headerRsa = request.getHeader(headerFlag); diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java new file mode 100644 index 00000000..5eb34a71 --- /dev/null +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java @@ -0,0 +1,123 @@ +package org.dromara.common.encrypt.filter; + +import cn.hutool.core.util.RandomUtil; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; +import org.dromara.common.encrypt.utils.EncryptUtils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +/** + * 加密响应参数包装类 + * + * @author Michelle.Chung + */ +public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream byteArrayOutputStream; + private final ServletOutputStream servletOutputStream; + private final PrintWriter printWriter; + + public EncryptResponseBodyWrapper(HttpServletResponse response) throws IOException { + super(response); + this.byteArrayOutputStream = new ByteArrayOutputStream(); + this.servletOutputStream = this.getOutputStream(); + this.printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream)); + } + + @Override + public PrintWriter getWriter() { + return printWriter; + } + + @Override + public void flushBuffer() throws IOException { + if (servletOutputStream != null) { + servletOutputStream.flush(); + } + if (printWriter != null) { + printWriter.flush(); + } + } + + @Override + public void reset() { + byteArrayOutputStream.reset(); + } + + public byte[] getResponseData() throws IOException { + flushBuffer(); + return byteArrayOutputStream.toByteArray(); + } + + public String getContent() throws IOException { + flushBuffer(); + return byteArrayOutputStream.toString(); + } + + /** + * 获取加密内容 + * + * @param servletResponse response + * @param publicKey RSA公钥 (用于加密 AES 秘钥) + * @param headerFlag 请求头标志 + * @return 加密内容 + * @throws IOException + */ + public String getEncryptContent(HttpServletResponse servletResponse, String publicKey, String headerFlag) throws IOException { + // 生成秘钥 + String aesPassword = RandomUtil.randomString(32); + // 秘钥使用 Base64 编码 + String encryptAes = EncryptUtils.encryptByBase64(aesPassword); + // Rsa 公钥加密 Base64 编码 + String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); + + // 设置响应头 + servletResponse.setHeader(headerFlag, encryptPassword); + servletResponse.setHeader("Access-Control-Allow-Origin", "*"); + servletResponse.setHeader("Access-Control-Allow-Methods", "*"); + servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString()); + + // 获取原始内容 + String originalBody = this.getContent(); + // 对内容进行加密 + return EncryptUtils.encryptByAes(originalBody, aesPassword); + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + return new ServletOutputStream() { + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } + + @Override + public void write(int b) throws IOException { + byteArrayOutputStream.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + byteArrayOutputStream.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + byteArrayOutputStream.write(b, off, len); + } + }; + } + +} diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java index 9e25b7b9..6aadb3e0 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java @@ -21,14 +21,14 @@ public class ApiDecryptProperties { */ private String headerFlag; - /** - * 公钥 + * 响应加密公钥 */ private String publicKey; /** - * 私钥 + * 请求解密私钥 */ private String privateKey; + } diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java index 08f4dda2..bcb5be76 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java @@ -98,9 +98,30 @@ public class CellMergeStrategy extends AbstractMergeStrategy { cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); } map.put(field, new RepeatCell(val, i)); - } else if (i == list.size() - 1) { - if (i > repeatCell.getCurrent()) { - cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); + } else if (j == 0) { + if (i == list.size() - 1) { + if (i > repeatCell.getCurrent()) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); + } + } + } else { + // 判断前面的是否合并了 + RepeatCell firstCell = map.get(mergeFields.get(0)); + if (repeatCell.getCurrent() != firstCell.getCurrent()) { + if (i == list.size() - 1) { + if (i > repeatCell.getCurrent()) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); + } + } else if (repeatCell.getCurrent() < firstCell.getCurrent()) { + if (i - repeatCell.getCurrent() > 1) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); + } + map.put(field, new RepeatCell(val, i)); + } + } else if (i == list.size() - 1) { + if (i > repeatCell.getCurrent()) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); + } } } } diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java index 329911d1..a6c14ad5 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java @@ -269,6 +269,26 @@ public class ExcelUtil { } } + /** + * 多sheet模板导出 模板格式为 {key.属性} + * + * @param filename 文件名 + * @param templatePath 模板路径 resource 目录下的路径包括模板文件名 + * 例如: excel/temp.xlsx + * 重点: 模板文件必须放置到启动类对应的 resource 目录下 + * @param data 模板需要的数据 + * @param response 响应体 + */ + public static void exportTemplateMultiSheet(List> data, String filename, String templatePath, HttpServletResponse response) { + try { + resetResponse(filename, response); + ServletOutputStream os = response.getOutputStream(); + exportTemplateMultiSheet(data, templatePath, os); + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } + /** * 多表多数据模板导出 模板格式为 {key.属性} * @@ -303,6 +323,42 @@ public class ExcelUtil { excelWriter.finish(); } + /** + * 多sheet模板导出 模板格式为 {key.属性} + * + * @param templatePath 模板路径 resource 目录下的路径包括模板文件名 + * 例如: excel/temp.xlsx + * 重点: 模板文件必须放置到启动类对应的 resource 目录下 + * @param data 模板需要的数据 + * @param os 输出流 + */ + public static void exportTemplateMultiSheet(List> data, String templatePath, OutputStream os) { + ClassPathResource templateResource = new ClassPathResource(templatePath); + ExcelWriter excelWriter = EasyExcel.write(os) + .withTemplate(templateResource.getStream()) + .autoCloseStream(false) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .build(); + if (CollUtil.isEmpty(data)) { + throw new IllegalArgumentException("数据为空"); + } + for (int i = 0; i < data.size(); i++) { + WriteSheet writeSheet = EasyExcel.writerSheet(i).build(); + for (Map.Entry map : data.get(i).entrySet()) { + // 设置列表后续还有数据 + FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); + if (map.getValue() instanceof Collection) { + // 多表导出必须使用 FillWrapper + excelWriter.fill(new FillWrapper(map.getKey(), (Collection) map.getValue()), fillConfig, writeSheet); + } else { + excelWriter.fill(map.getValue(), writeSheet); + } + } + } + excelWriter.finish(); + } + /** * 重置响应体 */ diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/PowerJobConfig.java b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/PowerJobConfig.java index 75f9412c..35612f3b 100644 --- a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/PowerJobConfig.java +++ b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/PowerJobConfig.java @@ -1,8 +1,8 @@ package org.dromara.common.job.config; import cn.hutool.core.collection.CollUtil; -import org.apache.commons.lang3.StringUtils; import org.dromara.common.core.utils.StreamUtils; +import org.dromara.common.core.utils.StringUtils; import org.dromara.common.job.config.properties.PowerJobProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -10,7 +10,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.annotation.Bean; -import org.springframework.scheduling.annotation.EnableScheduling; import tech.powerjob.common.utils.CommonUtils; import tech.powerjob.common.utils.NetUtils; import tech.powerjob.worker.PowerJobSpringWorker; @@ -20,16 +19,15 @@ import java.util.Arrays; import java.util.List; /** - * 启动定时任务 + * Autoconfiguration class for PowerJob-worker. * - * @author yhan219 - * @since 2023/6/2 + * @author songyinyin + * @since 2020/7/26 16:37 */ @AutoConfiguration -@ConditionalOnProperty(prefix = "powerjob.worker", name = "enabled", havingValue = "true") @EnableConfigurationProperties(PowerJobProperties.class) -@EnableScheduling -public class PowerJobConfig { +@ConditionalOnProperty(prefix = "powerjob.worker", name = "enabled", havingValue = "true", matchIfMissing = true) +public class PowerJobConfig{ @Bean public PowerJobSpringWorker initPowerJob(PowerJobProperties properties, DiscoveryClient discoveryClient) { @@ -87,7 +85,7 @@ public class PowerJobConfig { * When enabledTestMode is set as true, PowerJob-worker no longer connects to PowerJob-server * or validate appName. */ - config.setEnableTestMode(worker.isEnableTestMode()); + config.setAllowLazyConnectServer(worker.isAllowLazyConnectServer()); /* * Max length of appended workflow context . Appended workflow context value that is longer than the value will be ignored. */ diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/PowerJobProperties.java b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/PowerJobProperties.java index 4b7bd7a3..df5f2853 100644 --- a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/PowerJobProperties.java +++ b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/PowerJobProperties.java @@ -81,10 +81,10 @@ public class PowerJobProperties { */ private int maxResultLength = 8192; /** - * If test mode is set as true, Powerjob-worker no longer connects to the server or validates appName. - * Test mode is used for conditions that your have no powerjob-server in your develop env, so you can't start up the application + * If allowLazyConnectServer is set as true, PowerJob worker allows launching without a direct connection to the server. + * allowLazyConnectServer is used for conditions that your have no powerjob-server in your develop env so you can't startup the application */ - private boolean enableTestMode = false; + private boolean allowLazyConnectServer = false; /** * Max length of appended workflow context value length. Appended workflow context value that is longer than the value will be ignored. * {@link WorkflowContext} max length for #appendedContextData diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml index 645b58cf..64876fb2 100644 --- a/ruoyi-common/ruoyi-common-mybatis/pom.xml +++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml @@ -27,9 +27,20 @@ true + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + com.baomidou mybatis-plus-boot-starter + + + org.mybatis + mybatis-spring + + diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java index 64463e60..c517fa72 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java @@ -35,7 +35,7 @@ public class MybatisExceptionHandler { public R handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); String message = e.getMessage(); - if (message.contains("CannotFindDataSourceException")) { + if ("CannotFindDataSourceException".contains(message)) { log.error("请求地址'{}', 未找到数据源", requestURI); return R.fail("未找到数据源,请联系管理员确认"); } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java index fb70db41..dc4f9cb7 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java @@ -149,7 +149,12 @@ public class PlusDataPermissionHandler { int index = sb.lastIndexOf("."); String clazzName = sb.substring(0, index); String methodName = sb.substring(index + 1, sb.length()); - Class clazz = ClassUtil.loadClass(clazzName); + Class clazz; + try { + clazz = ClassUtil.loadClass(clazzName); + } catch (Exception e) { + return null; + } List methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz)) .filter(method -> method.getName().equals(methodName)).toList(); DataPermission dataPermission; diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java index 417f17b8..9d8db933 100644 --- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java +++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java @@ -1,5 +1,7 @@ package org.dromara.common.oss.constant; +import org.dromara.common.core.constant.GlobalConstants; + import java.util.Arrays; import java.util.List; @@ -13,7 +15,7 @@ public interface OssConstant { /** * 默认配置KEY */ - String DEFAULT_CONFIG_KEY = "sys_oss:default_config"; + String DEFAULT_CONFIG_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss:default_config"; /** * 预览列表资源开关Key diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java index 6503eb13..763b090e 100644 --- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java +++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java @@ -39,7 +39,7 @@ public class OssFactory { /** * 根据类型获取实例 */ - public static OssClient instance(String configKey) { + public static synchronized OssClient instance(String configKey) { String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey); if (json == null) { throw new OssException("系统异常, '" + configKey + "'配置信息不存在!"); diff --git a/ruoyi-common/ruoyi-common-ratelimiter/pom.xml b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml new file mode 100644 index 00000000..bbde9409 --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/pom.xml @@ -0,0 +1,30 @@ + + + + org.dromara + ruoyi-common + ${revision} + + 4.0.0 + + ruoyi-common-ratelimiter + + + ruoyi-common-ratelimiter 限流功能 + + + + + org.dromara + ruoyi-common-core + + + + org.dromara + ruoyi-common-redis + + + + diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java new file mode 100644 index 00000000..de09752a --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java @@ -0,0 +1,41 @@ +package org.dromara.common.ratelimiter.annotation; + +import org.dromara.common.ratelimiter.enums.LimitType; + +import java.lang.annotation.*; + +/** + * 限流注解 + * + * @author Lion Li + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter { + /** + * 限流key,支持使用Spring el表达式来动态获取方法上的参数值 + * 格式类似于 #code.id #{#code} + */ + String key() default ""; + + /** + * 限流时间,单位秒 + */ + int time() default 60; + + /** + * 限流次数 + */ + int count() default 100; + + /** + * 限流类型 + */ + LimitType limitType() default LimitType.DEFAULT; + + /** + * 提示消息 支持国际化 格式为 {code} + */ + String message() default "{rate.limiter.message}"; +} diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java new file mode 100644 index 00000000..8f3a5caf --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java @@ -0,0 +1,127 @@ +package org.dromara.common.ratelimiter.aspectj; + +import cn.hutool.core.util.ArrayUtil; +import org.dromara.common.core.constant.GlobalConstants; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MessageUtils; +import org.dromara.common.core.utils.ServletUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.ratelimiter.annotation.RateLimiter; +import org.dromara.common.ratelimiter.enums.LimitType; +import org.dromara.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.redisson.api.RateType; +import org.springframework.core.DefaultParameterNameDiscoverer; +import org.springframework.core.ParameterNameDiscoverer; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.ParserContext; +import org.springframework.expression.common.TemplateParserContext; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +import java.lang.reflect.Method; + +/** + * 限流处理 + * + * @author Lion Li + */ +@Slf4j +@Aspect +public class RateLimiterAspect { + + /** + * 定义spel表达式解析器 + */ + private final ExpressionParser parser = new SpelExpressionParser(); + /** + * 定义spel解析模版 + */ + private final ParserContext parserContext = new TemplateParserContext(); + /** + * 定义spel上下文对象进行解析 + */ + private final EvaluationContext context = new StandardEvaluationContext(); + /** + * 方法参数解析器 + */ + private final ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); + + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable { + int time = rateLimiter.time(); + int count = rateLimiter.count(); + String combineKey = getCombineKey(rateLimiter, point); + try { + RateType rateType = RateType.OVERALL; + if (rateLimiter.limitType() == LimitType.CLUSTER) { + rateType = RateType.PER_CLIENT; + } + long number = RedisUtils.rateLimiter(combineKey, rateType, count, time); + if (number == -1) { + String message = rateLimiter.message(); + if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) { + message = MessageUtils.message(StringUtils.substring(message, 1, message.length() - 1)); + } + throw new ServiceException(message); + } + log.info("限制令牌 => {}, 剩余令牌 => {}, 缓存key => '{}'", count, number, combineKey); + } catch (Exception e) { + if (e instanceof ServiceException) { + throw e; + } else { + throw new RuntimeException("服务器限流异常,请稍候再试"); + } + } + } + + public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { + String key = rateLimiter.key(); + // 获取方法(通过方法签名来获取) + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Class targetClass = method.getDeclaringClass(); + // 判断是否是spel格式 + if (StringUtils.containsAny(key, "#")) { + // 获取参数值 + Object[] args = point.getArgs(); + // 获取方法上参数的名称 + String[] parameterNames = pnd.getParameterNames(method); + if (ArrayUtil.isEmpty(parameterNames)) { + throw new ServiceException("限流key解析异常!请联系管理员!"); + } + for (int i = 0; i < parameterNames.length; i++) { + context.setVariable(parameterNames[i], args[i]); + } + // 解析返回给key + try { + Expression expression; + if (StringUtils.startsWith(key, parserContext.getExpressionPrefix()) + && StringUtils.endsWith(key, parserContext.getExpressionSuffix())) { + expression = parser.parseExpression(key, parserContext); + } else { + expression = parser.parseExpression(key); + } + key = expression.getValue(context, String.class) + ":"; + } catch (Exception e) { + throw new ServiceException("限流key解析异常!请联系管理员!"); + } + } + StringBuilder stringBuffer = new StringBuilder(GlobalConstants.RATE_LIMIT_KEY); + stringBuffer.append(ServletUtils.getRequest().getRequestURI()).append(":"); + if (rateLimiter.limitType() == LimitType.IP) { + // 获取请求ip + stringBuffer.append(ServletUtils.getClientIP()).append(":"); + } else if (rateLimiter.limitType() == LimitType.CLUSTER) { + // 获取客户端实例id + stringBuffer.append(RedisUtils.getClient().getId()).append(":"); + } + return stringBuffer.append(key).toString(); + } +} diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java new file mode 100644 index 00000000..4b7e5b7f --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java @@ -0,0 +1,20 @@ +package org.dromara.common.ratelimiter.config; + +import org.dromara.common.ratelimiter.aspectj.RateLimiterAspect; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.data.redis.connection.RedisConfiguration; + +/** + * @author guangxin + * @date 2023/1/18 + */ +@AutoConfiguration(after = RedisConfiguration.class) +public class RateLimiterConfig { + + @Bean + public RateLimiterAspect rateLimiterAspect() { + return new RateLimiterAspect(); + } + +} diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java new file mode 100644 index 00000000..b7f059fd --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java @@ -0,0 +1,24 @@ +package org.dromara.common.ratelimiter.enums; + +/** + * 限流类型 + * + * @author ruoyi + */ + +public enum LimitType { + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP, + + /** + * 实例限流(集群多后端实例) + */ + CLUSTER +} diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..3b954329 --- /dev/null +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.dromara.common.ratelimiter.config.RateLimiterConfig diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfiguration.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfiguration.java index 3a34cce3..8264423d 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfiguration.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfiguration.java @@ -49,6 +49,8 @@ public class RedisConfiguration { CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec); config.setThreads(redissonProperties.getThreads()) .setNettyThreads(redissonProperties.getNettyThreads()) + // 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现) + .setUseScriptCache(true) .setCodec(codec); RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); if (ObjectUtil.isNotNull(singleServerConfig)) { diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java index 9f59f69f..ce32055b 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java @@ -141,6 +141,18 @@ public class RedisUtils { return bucket.setIfAbsent(value, duration); } + /** + * 如果存在则设置 并返回 true 如果存在则返回 false + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @return set成功或失败 + */ + public static boolean setObjectIfExists(final String key, final T value, final Duration duration) { + RBucket bucket = CLIENT.getBucket(key); + return bucket.setIfExists(value, duration); + } + /** * 注册对象监听器 *

@@ -242,6 +254,18 @@ public class RedisUtils { return rList.addAll(dataList); } + /** + * 追加缓存List数据 + * + * @param key 缓存的键值 + * @param data 待缓存的数据 + * @return 缓存的对象 + */ + public static boolean addCacheList(final String key, final T data) { + RList rList = CLIENT.getList(key); + return rList.add(data); + } + /** * 注册List监听器 *

@@ -266,6 +290,19 @@ public class RedisUtils { return rList.readAll(); } + /** + * 获得缓存的list对象(范围) + * + * @param key 缓存的键值 + * @param form 起始下标 + * @param to 截止下标 + * @return 缓存键值对应的数据 + */ + public static List getCacheListRange(final String key, int form, int to) { + RList rList = CLIENT.getList(key); + return rList.range(form, to); + } + /** * 缓存Set * @@ -278,6 +315,18 @@ public class RedisUtils { return rSet.addAll(dataSet); } + /** + * 追加缓存Set数据 + * + * @param key 缓存的键值 + * @param data 待缓存的数据 + * @return 缓存的对象 + */ + public static boolean addCacheSet(final String key, final T data) { + RSet rSet = CLIENT.getSet(key); + return rSet.add(data); + } + /** * 注册Set监听器 *

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 8d2aac96..d8859622 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 @@ -45,12 +45,9 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public void update(String key, String value) { - long expire = getTimeout(key); - // -2 = 无此键 - if (expire == NOT_VALUE_EXPIRE) { - return; + if (RedisUtils.hasKey(key)) { + RedisUtils.setCacheObject(key, value, true); } - this.set(key, value, expire); } /** @@ -75,17 +72,6 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public void updateTimeout(String key, long timeout) { - // 判断是否想要设置为永久 - if (timeout == NEVER_EXPIRE) { - long expire = getTimeout(key); - if (expire == NEVER_EXPIRE) { - // 如果其已经被设置为永久,则不作任何处理 - } else { - // 如果尚未被设置为永久,那么再次set一次 - this.set(key, this.get(key), timeout); - } - return; - } RedisUtils.expire(key, Duration.ofSeconds(timeout)); } @@ -119,12 +105,9 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public void updateObject(String key, Object object) { - long expire = getObjectTimeout(key); - // -2 = 无此键 - if (expire == NOT_VALUE_EXPIRE) { - return; + if (RedisUtils.hasKey(key)) { + RedisUtils.setCacheObject(key, object, true); } - this.setObject(key, object, expire); } /** @@ -149,17 +132,6 @@ public class PlusSaTokenDao implements SaTokenDao { */ @Override public void updateObjectTimeout(String key, long timeout) { - // 判断是否想要设置为永久 - if (timeout == NEVER_EXPIRE) { - long expire = getObjectTimeout(key); - if (expire == NEVER_EXPIRE) { - // 如果其已经被设置为永久,则不作任何处理 - } else { - // 如果尚未被设置为永久,那么再次set一次 - this.setObject(key, this.getObject(key), timeout); - } - return; - } RedisUtils.expire(key, Duration.ofSeconds(timeout)); } 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 4d3aaa6c..7ef120d6 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 @@ -15,6 +15,7 @@ import org.dromara.common.core.enums.UserType; import org.dromara.system.api.model.LoginUser; import java.util.Set; +import java.util.function.Supplier; /** * 登录鉴权助手 @@ -36,6 +37,7 @@ public class LoginHelper { public static final String USER_KEY = "userId"; public static final String DEPT_KEY = "deptId"; public static final String CLIENT_KEY = "clientid"; + public static final String TENANT_ADMIN_KEY = "isTenantAdmin"; /** * 登录系统 基于 设备类型 @@ -55,32 +57,27 @@ public class LoginHelper { model.setExtra(TENANT_KEY, loginUser.getTenantId()) .setExtra(USER_KEY, loginUser.getUserId()) .setExtra(DEPT_KEY, loginUser.getDeptId())); - StpUtil.getSession().set(LOGIN_USER_KEY, loginUser); + StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); } /** * 获取用户(多级缓存) */ public static LoginUser getLoginUser() { - LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY); - if (loginUser != null) { - return loginUser; - } - SaSession session = StpUtil.getSession(); - if (ObjectUtil.isNull(session)) { - return null; - } - loginUser = (LoginUser) session.get(LOGIN_USER_KEY); - SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser); - return loginUser; + return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> { + SaSession session = StpUtil.getTokenSession(); + if (ObjectUtil.isNull(session)) { + return null; + } + return session.get(LOGIN_USER_KEY); + }); } /** * 获取用户基于token */ public static LoginUser getLoginUser(String token) { - Object loginId = StpUtil.getLoginIdByToken(token); - SaSession session = StpUtil.getSessionByLoginId(loginId); + SaSession session = StpUtil.getTokenSessionByToken(token); if (ObjectUtil.isNull(session)) { return null; } @@ -109,17 +106,7 @@ public class LoginHelper { } private static Object getExtra(String key) { - Object obj; - try { - obj = SaHolder.getStorage().get(key); - if (ObjectUtil.isNull(obj)) { - obj = StpUtil.getExtra(key); - SaHolder.getStorage().set(key, obj); - } - } catch (Exception e) { - return null; - } - return obj; + return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key)); } /** @@ -162,7 +149,26 @@ public class LoginHelper { } public static boolean isTenantAdmin() { - return isTenantAdmin(getLoginUser().getRolePermission()); + Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> { + return isTenantAdmin(getLoginUser().getRolePermission()); + }); + return Convert.toBool(value); + } + + public static boolean isLogin() { + return getLoginUser() != null; } + public static Object getStorageIfAbsentSet(String key, Supplier handle) { + try { + Object obj = SaHolder.getStorage().get(key); + if (ObjectUtil.isNull(obj)) { + obj = handle.get(); + SaHolder.getStorage().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/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java index c89892ac..8fb1f761 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java @@ -11,7 +11,6 @@ import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; -import org.dromara.common.core.exception.DemoModeException; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.base.BaseException; import org.dromara.common.core.utils.StreamUtils; @@ -173,11 +172,4 @@ public class GlobalExceptionHandler { return R.fail(message); } - /** - * 演示模式异常 - */ - @ExceptionHandler(DemoModeException.class) - public R handleDemoModeException(DemoModeException e) { - return R.fail("演示模式,不允许操作"); - } } diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java b/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java deleted file mode 100644 index f0f9021d..00000000 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/properties/SmsProperties.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.ruoyi.common.sms.config.properties;//package com.ruoyi.common.sms.config.properties; -// -//import lombok.Data; -//import org.springframework.boot.context.properties.ConfigurationProperties; -//import org.springframework.stereotype.Component; -// -///** -// * SMS短信 配置属性 -// * -// * @author Lion Li -// * @version 4.2.0 -// */ -//@Data -//@ConfigurationProperties(prefix = "sms") -//public class SmsProperties { -// -// private Boolean enabled; -// -//} diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsAutoConfiguration.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java similarity index 61% rename from ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsAutoConfiguration.java rename to ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java index b9f94bb6..29f60fc5 100644 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/com/ruoyi/common/sms/config/SmsAutoConfiguration.java +++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java @@ -1,15 +1,14 @@ -package com.ruoyi.common.sms.config; +package org.dromara.common.sms.config; import org.springframework.boot.autoconfigure.AutoConfiguration; /** - * 短信配置类 + * 短信配置类(暂时没用 预留扩展) * * @author Lion Li * @version 4.2.0 */ @AutoConfiguration -//@EnableConfigurationProperties(SmsProperties.class) public class SmsAutoConfiguration { } diff --git a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index e4081a1f..5919ce32 100644 --- a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1 @@ -com.ruoyi.common.sms.config.SmsAutoConfiguration +org.dromara.common.sms.config.SmsAutoConfiguration 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 572a5d09..a5ed6f11 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 @@ -35,33 +35,34 @@ public class SocialUtils { if (ObjectUtil.isNull(obj)) { throw new AuthException("不支持的第三方登录类型"); } - String clientId = obj.getClientId(); - String clientSecret = obj.getClientSecret(); - String redirectUri = obj.getRedirectUri(); + final AuthConfig.AuthConfigBuilder builder = AuthConfig.builder() + .clientId(obj.getClientId()) + .clientSecret(obj.getClientSecret()) + .redirectUri(obj.getRedirectUri()); return switch (source.toLowerCase()) { - case "dingtalk" -> new AuthDingTalkRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "baidu" -> new AuthBaiduRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "github" -> new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "gitee" -> new AuthGiteeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "weibo" -> new AuthWeiboRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "coding" -> new AuthCodingRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "oschina" -> new AuthOschinaRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); + case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE); + case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE); + case "github" -> new AuthGithubRequest(builder.build(), STATE_CACHE); + case "gitee" -> new AuthGiteeRequest(builder.build(), STATE_CACHE); + case "weibo" -> new AuthWeiboRequest(builder.build(), STATE_CACHE); + case "coding" -> new AuthCodingRequest(builder.build(), STATE_CACHE); + case "oschina" -> new AuthOschinaRequest(builder.build(), STATE_CACHE); // 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ip - case "alipay_wallet" -> new AuthAlipayRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE); - case "qq" -> new AuthQqRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "wechat_open" -> new AuthWeChatOpenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "taobao" -> new AuthTaobaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "douyin" -> new AuthDouyinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "linkedin" -> new AuthLinkedinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "microsoft" -> new AuthMicrosoftRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "renren" -> new AuthRenrenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "stack_overflow" -> new AuthStackOverflowRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).stackOverflowKey("").build(), STATE_CACHE); - case "huawei" -> new AuthHuaweiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).agentId("").build(), STATE_CACHE); - case "gitlab" -> new AuthGitlabRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "wechat_mp" -> new AuthWeChatMpRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "aliyun" -> new AuthAliyunRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); - case "maxkey" -> new AuthMaxKeyRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE); + case "alipay_wallet" -> new AuthAlipayRequest(builder.build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE); + case "qq" -> new AuthQqRequest(builder.build(), STATE_CACHE); + case "wechat_open" -> new AuthWeChatOpenRequest(builder.build(), STATE_CACHE); + case "taobao" -> new AuthTaobaoRequest(builder.build(), STATE_CACHE); + case "douyin" -> new AuthDouyinRequest(builder.build(), STATE_CACHE); + case "linkedin" -> new AuthLinkedinRequest(builder.build(), STATE_CACHE); + case "microsoft" -> new AuthMicrosoftRequest(builder.build(), STATE_CACHE); + case "renren" -> new AuthRenrenRequest(builder.build(), STATE_CACHE); + case "stack_overflow" -> new AuthStackOverflowRequest(builder.stackOverflowKey("").build(), STATE_CACHE); + case "huawei" -> new AuthHuaweiRequest(builder.build(), STATE_CACHE); + case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId("").build(), STATE_CACHE); + case "gitlab" -> new AuthGitlabRequest(builder.build(), STATE_CACHE); + 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); 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 afcff36c..e830c190 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,6 +1,7 @@ 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; @@ -13,7 +14,6 @@ import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.springframework.web.context.request.RequestContextHolder; import java.util.function.Supplier; @@ -82,10 +82,13 @@ public class TenantHelper { /** * 设置动态租户(一直有效 需要手动清理) *

- * 如果为非web环境 那么只在当前线程内生效 + * 如果为未登录状态下 那么只在当前线程内生效 */ public static void setDynamic(String tenantId) { - if (!isWeb()) { + if (!isEnable()) { + return; + } + if (!isLogin()) { TEMP_DYNAMIC_TENANT.set(tenantId); return; } @@ -97,10 +100,13 @@ public class TenantHelper { /** * 获取动态租户(一直有效 需要手动清理) *

- * 如果为非web环境 那么只在当前线程内生效 + * 如果为未登录状态下 那么只在当前线程内生效 */ public static String getDynamic() { - if (!isWeb()) { + if (!isEnable()) { + return null; + } + if (!isLogin()) { return TEMP_DYNAMIC_TENANT.get(); } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); @@ -117,7 +123,10 @@ public class TenantHelper { * 清除动态租户 */ public static void clearDynamic() { - if (!isWeb()) { + if (!isEnable()) { + return; + } + if (!isLogin()) { TEMP_DYNAMIC_TENANT.remove(); return; } @@ -126,10 +135,41 @@ public class TenantHelper { SaHolder.getStorage().delete(cacheKey); } + /** + * 在动态租户中执行 + * + * @param handle 处理执行方法 + */ + public static void dynamic(String tenantId, Runnable handle) { + setDynamic(tenantId); + try { + handle.run(); + } finally { + clearDynamic(); + } + } + + /** + * 在动态租户中执行 + * + * @param handle 处理执行方法 + */ + public static T dynamic(String tenantId, Supplier handle) { + setDynamic(tenantId); + try { + return handle.get(); + } finally { + clearDynamic(); + } + } + /** * 获取当前租户id(动态租户优先) */ public static String getTenantId() { + if (!isEnable()) { + return null; + } String tenantId = TenantHelper.getDynamic(); if (StringUtils.isBlank(tenantId)) { tenantId = LoginHelper.getTenantId(); @@ -137,11 +177,13 @@ public class TenantHelper { return tenantId; } - /** - * 判断是否web环境 - */ - private static boolean isWeb() { - return RequestContextHolder.getRequestAttributes() != null; + private static boolean isLogin() { + try { + StpUtil.checkLogin(); + return true; + } catch (Exception e) { + return false; + } } } diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java index 25df1c9f..a6ecb2d1 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java @@ -12,6 +12,12 @@ public interface TransConstant { */ String USER_ID_TO_NAME = "user_id_to_name"; + /** + * 用户id转用户昵称 + */ + String USER_ID_TO_NICKNAME = "user_id_to_nickname"; + + /** * 部门id转名称 */ diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java new file mode 100644 index 00000000..b73478ec --- /dev/null +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java @@ -0,0 +1,26 @@ +package org.dromara.common.translation.core.impl; + +import lombok.AllArgsConstructor; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.common.translation.annotation.TranslationType; +import org.dromara.common.translation.constant.TransConstant; +import org.dromara.common.translation.core.TranslationInterface; +import org.dromara.system.api.RemoteUserService; + +/** + * 用户昵称翻译实现 + * + * @author may + */ +@AllArgsConstructor +@TranslationType(type = TransConstant.USER_ID_TO_NICKNAME) +public class NicknameTranslationImpl implements TranslationInterface { + + @DubboReference + private RemoteUserService remoteUserService; + + @Override + public String translation(Object key, String other) { + return remoteUserService.selectNicknameById((Long) key); + } +} diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java index 0277ec1b..b9fe8392 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java +++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java @@ -16,7 +16,7 @@ import org.apache.dubbo.config.annotation.DubboReference; @TranslationType(type = TransConstant.OSS_ID_TO_URL) public class OssUrlTranslationImpl implements TranslationInterface { - @DubboReference + @DubboReference(mock = "true") private RemoteFileService ossService; @Override diff --git a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 45844e01..ad40205e 100644 --- a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -3,3 +3,4 @@ org.dromara.common.translation.core.impl.DeptNameTranslationImpl org.dromara.common.translation.core.impl.DictTypeTranslationImpl org.dromara.common.translation.core.impl.OssUrlTranslationImpl org.dromara.common.translation.core.impl.UserNameTranslationImpl +org.dromara.common.translation.core.impl.NicknameTranslationImpl diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java index 7ead043b..99bb8455 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java @@ -98,7 +98,7 @@ public class WebSocketUtils { private static void sendMessage(WebSocketSession session, WebSocketMessage message) { if (session == null || !session.isOpen()) { - log.error("[send] session会话已经关闭"); + log.warn("[send] session会话已经关闭"); } else { try { session.sendMessage(message); diff --git a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/EsCrudController.java b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/EsCrudController.java index a48952c5..d3a15480 100644 --- a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/EsCrudController.java +++ b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/EsCrudController.java @@ -1,10 +1,10 @@ package org.dromara.demo.controller; -import cn.easyes.core.conditions.LambdaEsQueryWrapper; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.demo.domain.Document; import org.dromara.demo.esmapper.DocumentMapper; -import lombok.RequiredArgsConstructor; +import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.web.bind.annotation.*; diff --git a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java index 0a12d9dc..d82ea3b0 100644 --- a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java +++ b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java @@ -94,6 +94,41 @@ public class TestExcelController { exportExcelService.exportWithOptions(response); } + /** + * 多个sheet导出 + */ + @GetMapping("/exportTemplateMultiSheet") + public void exportTemplateMultiSheet(HttpServletResponse response) { + List list1 = new ArrayList<>(); + list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3")); + list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6")); + List list2 = new ArrayList<>(); + list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3")); + list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6")); + List list3 = new ArrayList<>(); + list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3")); + list3.add(new TestObj1("list3测试4", "list3测试5", "list3测试6")); + List list4 = new ArrayList<>(); + list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3")); + list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6")); + + List> list = new ArrayList<>(); + Map sheetMap1 = new HashMap<>(); + sheetMap1.put("data1", list1); + Map sheetMap2 = new HashMap<>(); + sheetMap2.put("data2", list2); + Map sheetMap3 = new HashMap<>(); + sheetMap3.put("data3", list3); + Map sheetMap4 = new HashMap<>(); + sheetMap4.put("data4", list4); + + list.add(sheetMap1); + list.add(sheetMap2); + list.add(sheetMap3); + list.add(sheetMap4); + ExcelUtil.exportTemplateMultiSheet(list, "多sheet列表", "excel/多sheet列表.xlsx", response); + } + /** * 导入表格 */ diff --git a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/esmapper/DocumentMapper.java b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/esmapper/DocumentMapper.java index f412bc18..c925b626 100644 --- a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/esmapper/DocumentMapper.java +++ b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/esmapper/DocumentMapper.java @@ -1,7 +1,7 @@ package org.dromara.demo.esmapper; -import cn.easyes.core.conditions.interfaces.BaseEsMapper; import org.dromara.demo.domain.Document; +import org.dromara.easyes.core.core.BaseEsMapper; public interface DocumentMapper extends BaseEsMapper { } diff --git a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/SensitiveServiceImpl.java b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/SensitiveServiceImpl.java index 76e0c9db..01cc1a68 100644 --- a/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/SensitiveServiceImpl.java +++ b/ruoyi-example/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/SensitiveServiceImpl.java @@ -22,7 +22,7 @@ public class SensitiveServiceImpl implements SensitiveService { */ @Override public boolean isSensitive(String roleKey, String perms) { - if (!StpUtil.isLogin()) { + if (!LoginHelper.isLogin()) { return true; } boolean roleExist = StringUtils.isNotBlank(roleKey); diff --git a/ruoyi-example/ruoyi-demo/src/main/resources/application.yml b/ruoyi-example/ruoyi-demo/src/main/resources/application.yml index a7238b2f..d35ec413 100644 --- a/ruoyi-example/ruoyi-demo/src/main/resources/application.yml +++ b/ruoyi-example/ruoyi-demo/src/main/resources/application.yml @@ -90,8 +90,6 @@ easy-es: connectTimeout: 5000 # 通信超时时间 单位:ms socketTimeout: 5000 - # 请求超时时间 单位:ms - requestTimeout: 5000 # 连接请求超时时间 单位:ms connectionRequestTimeout: 5000 # 最大连接数 单位:个 @@ -114,5 +112,3 @@ easy-es: enable-track-total-hits: true # 数据刷新策略,默认为不刷新 refresh-policy: immediate - # 是否全局开启must查询类型转换为filter查询类型 默认为false不转换 - enable-must2-filter: false diff --git a/ruoyi-example/ruoyi-demo/src/main/resources/excel/多sheet列表.xlsx b/ruoyi-example/ruoyi-demo/src/main/resources/excel/多sheet列表.xlsx new file mode 100644 index 00000000..5277f2ea Binary files /dev/null and b/ruoyi-example/ruoyi-demo/src/main/resources/excel/多sheet列表.xlsx differ diff --git a/ruoyi-example/ruoyi-stream-mq/pom.xml b/ruoyi-example/ruoyi-stream-mq/pom.xml index 4e3f8463..5b3343e0 100644 --- a/ruoyi-example/ruoyi-stream-mq/pom.xml +++ b/ruoyi-example/ruoyi-stream-mq/pom.xml @@ -64,6 +64,17 @@ ruoyi-common-web + + org.dromara + ruoyi-common-tenant + + + org.dromara + ruoyi-common-mybatis + + + + diff --git a/ruoyi-gateway/Dockerfile b/ruoyi-gateway/Dockerfile index 19e6f5ba..ffaec9fa 100644 --- a/ruoyi-gateway/Dockerfile +++ b/ruoyi-gateway/Dockerfile @@ -9,15 +9,14 @@ RUN mkdir -p /ruoyi/gateway/logs \ WORKDIR /ruoyi/gateway -ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-gateway.jar ./app.jar -ENTRYPOINT ["java", \ - "-Djava.security.egd=file:/dev/./urandom", \ - "-Dserver.port=${SERVER_PORT}", \ -# "-Dskywalking.agent.service_name=ruoyi-gateway", \ -# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ - "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ + #-Dskywalking.agent.service_name=ruoyi-gateway \ + #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ + -jar app.jar \ + -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} diff --git a/ruoyi-modules/ruoyi-gen/Dockerfile b/ruoyi-modules/ruoyi-gen/Dockerfile index 6633de59..5b1f972e 100644 --- a/ruoyi-modules/ruoyi-gen/Dockerfile +++ b/ruoyi-modules/ruoyi-gen/Dockerfile @@ -7,10 +7,10 @@ RUN mkdir -p /ruoyi/gen/logs WORKDIR /ruoyi/gen -ENV SERVER_PORT=9202 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=9202 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-gen.jar ./app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dserver.port=${SERVER_PORT}", "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} -jar app.jar ${JAVA_OPTS} diff --git a/ruoyi-modules/ruoyi-job/Dockerfile b/ruoyi-modules/ruoyi-job/Dockerfile index a465fa0b..2922d841 100644 --- a/ruoyi-modules/ruoyi-job/Dockerfile +++ b/ruoyi-modules/ruoyi-job/Dockerfile @@ -9,15 +9,15 @@ RUN mkdir -p /ruoyi/job/logs \ WORKDIR /ruoyi/job -ENV SERVER_PORT=9203 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=9203 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-job.jar ./app.jar -ENTRYPOINT ["java", \ - "-Djava.security.egd=file:/dev/./urandom", \ - "-Dserver.port=${SERVER_PORT}", \ -# "-Dskywalking.agent.service_name=ruoyi-job", \ -# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ - "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ + #-Dskywalking.agent.service_name=ruoyi-job \ + #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ + -jar app.jar \ + -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} + diff --git a/ruoyi-modules/ruoyi-resource/Dockerfile b/ruoyi-modules/ruoyi-resource/Dockerfile index 5e9410d9..6e0df4f3 100644 --- a/ruoyi-modules/ruoyi-resource/Dockerfile +++ b/ruoyi-modules/ruoyi-resource/Dockerfile @@ -9,15 +9,15 @@ RUN mkdir -p /ruoyi/resource/logs \ WORKDIR /ruoyi/resource -ENV SERVER_PORT=9204 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=9204 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-resource.jar ./app.jar -ENTRYPOINT ["java", \ - "-Djava.security.egd=file:/dev/./urandom", \ - "-Dserver.port=${SERVER_PORT}", \ -# "-Dskywalking.agent.service_name=ruoyi-resource", \ -# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ - "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ + #-Dskywalking.agent.service_name=ruoyi-resource \ + #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ + -jar app.jar \ + -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} + diff --git a/ruoyi-modules/ruoyi-resource/pom.xml b/ruoyi-modules/ruoyi-resource/pom.xml index 14caecfb..61455862 100644 --- a/ruoyi-modules/ruoyi-resource/pom.xml +++ b/ruoyi-modules/ruoyi-resource/pom.xml @@ -64,6 +64,11 @@ ruoyi-common-oss + + org.dromara + ruoyi-common-ratelimiter + + org.dromara ruoyi-common-mail diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysEmailController.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysEmailController.java index b7183502..19da5ba6 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysEmailController.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysEmailController.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.domain.R; +import org.dromara.common.ratelimiter.annotation.RateLimiter; import org.dromara.common.web.core.BaseController; import org.dromara.common.mail.config.properties.MailProperties; import org.dromara.common.mail.utils.MailUtils; @@ -38,6 +39,7 @@ public class SysEmailController extends BaseController { * * @param email 邮箱 */ + @RateLimiter(key = "#email", time = 60, count = 1) @GetMapping("/code") public R emailCode(@NotBlank(message = "{user.email.not.blank}") String email) { if (!mailProperties.getEnabled()) { diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssConfigController.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssConfigController.java index a713326d..506cdb7b 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssConfigController.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssConfigController.java @@ -39,7 +39,7 @@ public class SysOssConfigController extends BaseController { /** * 查询对象存储配置列表 */ - @SaCheckPermission("system:oss:list") + @SaCheckPermission("system:ossConfig:list") @GetMapping("/list") public TableDataInfo list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { return iSysOssConfigService.queryPageList(bo, pageQuery); @@ -50,7 +50,7 @@ public class SysOssConfigController extends BaseController { * * @param ossConfigId OSS配置ID */ - @SaCheckPermission("system:oss:query") + @SaCheckPermission("system:ossConfig:list") @GetMapping("/{ossConfigId}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("ossConfigId") Long ossConfigId) { return R.ok(iSysOssConfigService.queryById(ossConfigId)); @@ -59,7 +59,7 @@ public class SysOssConfigController extends BaseController { /** * 新增对象存储配置 */ - @SaCheckPermission("system:oss:add") + @SaCheckPermission("system:ossConfig:add") @Log(title = "对象存储配置", businessType = BusinessType.INSERT) @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { @@ -69,7 +69,7 @@ public class SysOssConfigController extends BaseController { /** * 修改对象存储配置 */ - @SaCheckPermission("system:oss:edit") + @SaCheckPermission("system:ossConfig:edit") @Log(title = "对象存储配置", businessType = BusinessType.UPDATE) @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { @@ -81,7 +81,7 @@ public class SysOssConfigController extends BaseController { * * @param ossConfigIds OSS配置ID串 */ - @SaCheckPermission("system:oss:remove") + @SaCheckPermission("system:ossConfig:remove") @Log(title = "对象存储配置", businessType = BusinessType.DELETE) @DeleteMapping("/{ossConfigIds}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ossConfigIds) { @@ -91,7 +91,7 @@ public class SysOssConfigController extends BaseController { /** * 状态修改 */ - @SaCheckPermission("system:oss:edit") + @SaCheckPermission("system:ossConfig:edit") @Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public R changeStatus(@RequestBody SysOssConfigBo bo) { diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysSmsController.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysSmsController.java index 21c2afd1..10339427 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysSmsController.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysSmsController.java @@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.domain.R; +import org.dromara.common.ratelimiter.annotation.RateLimiter; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.web.core.BaseController; import org.dromara.sms4j.api.SmsBlend; @@ -39,6 +40,7 @@ public class SysSmsController extends BaseController { * * @param phonenumber 用户手机号 */ + @RateLimiter(key = "#phonenumber", time = 60, count = 1) @GetMapping("/code") public R smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) { String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber; diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java index b720ed02..aebc56e3 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/SysOssConfig.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; -import org.dromara.common.tenant.core.TenantEntity; +import org.dromara.common.mybatis.core.domain.BaseEntity; /** * 对象存储配置对象 sys_oss_config @@ -14,7 +14,7 @@ import org.dromara.common.tenant.core.TenantEntity; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_oss_config") -public class SysOssConfig extends TenantEntity { +public class SysOssConfig extends BaseEntity { /** * 主建 diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssConfigServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssConfigServiceImpl.java index 55cd1f4a..2e7154b5 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssConfigServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssConfigServiceImpl.java @@ -11,7 +11,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.mybatis.core.page.PageQuery; @@ -19,8 +18,6 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.oss.constant.OssConstant; import org.dromara.common.redis.utils.CacheUtils; import org.dromara.common.redis.utils.RedisUtils; -import org.dromara.common.tenant.core.TenantEntity; -import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.resource.domain.SysOssConfig; import org.dromara.resource.domain.bo.SysOssConfigBo; import org.dromara.resource.domain.vo.SysOssConfigVo; @@ -31,7 +28,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 对象存储配置Service业务层处理 @@ -52,25 +48,14 @@ public class SysOssConfigServiceImpl implements ISysOssConfigService { */ @Override public void init() { - List list = TenantHelper.ignore(() -> - baseMapper.selectList( - new LambdaQueryWrapper().orderByAsc(TenantEntity::getTenantId)) - ); - Map> map = StreamUtils.groupByKey(list, SysOssConfig::getTenantId); - try { - for (String tenantId : map.keySet()) { - TenantHelper.setDynamic(tenantId); - // 加载OSS初始化配置 - for (SysOssConfig config : map.get(tenantId)) { - String configKey = config.getConfigKey(); - if ("0".equals(config.getStatus())) { - RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey); - } - CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); - } + List list = baseMapper.selectList(); + // 加载OSS初始化配置 + for (SysOssConfig config : list) { + String configKey = config.getConfigKey(); + if ("0".equals(config.getStatus())) { + RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey); } - } finally { - TenantHelper.clearDynamic(); + CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config)); } } diff --git a/ruoyi-modules/ruoyi-system/Dockerfile b/ruoyi-modules/ruoyi-system/Dockerfile index 98e4fafa..2989fbfc 100644 --- a/ruoyi-modules/ruoyi-system/Dockerfile +++ b/ruoyi-modules/ruoyi-system/Dockerfile @@ -9,15 +9,15 @@ RUN mkdir -p /ruoyi/system/logs \ WORKDIR /ruoyi/system -ENV SERVER_PORT=9201 LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV SERVER_PORT=9201 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" EXPOSE ${SERVER_PORT} ADD ./target/ruoyi-system.jar ./app.jar -ENTRYPOINT ["java", \ - "-Djava.security.egd=file:/dev/./urandom", \ - "-Dserver.port=${SERVER_PORT}", \ -# "-Dskywalking.agent.service_name=ruoyi-system", \ -# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ - "-jar", "app.jar"] +ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ + #-Dskywalking.agent.service_name=ruoyi-system \ + #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \ + -jar app.jar \ + -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS} + 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 abff0f65..5e1a0e74 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 @@ -9,6 +9,7 @@ import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.file.MimeTypeUtils; +import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.web.core.BaseController; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; @@ -66,11 +67,12 @@ public class SysProfileController extends BaseController { @PutMapping public R updateProfile(@RequestBody SysUserProfileBo profile) { SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class); + String username = LoginHelper.getUsername(); if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { - return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + return R.fail("修改用户'" + username + "'失败,手机号码已存在"); } if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { - return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + return R.fail("修改用户'" + username + "'失败,邮箱账号已存在"); } user.setUserId(LoginHelper.getUserId()); if (userService.updateUserProfile(user) > 0) { @@ -84,6 +86,7 @@ public class SysProfileController extends BaseController { * * @param bo 新旧密码 */ + @ApiEncrypt @Log(title = "个人信息", businessType = BusinessType.UPDATE) @PutMapping("/updatePwd") public R updatePwd(@Validated @RequestBody SysUserPasswordBo bo) { diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java index 4b977e21..0d95d0e0 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java @@ -1,6 +1,5 @@ package org.dromara.system.controller.system; -import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.satoken.utils.LoginHelper; @@ -9,7 +8,6 @@ import org.dromara.system.domain.vo.SysSocialVo; import org.dromara.system.service.ISysSocialService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -37,16 +35,4 @@ public class SysSocialController extends BaseController { return R.ok(socialUserService.queryListByUserId(LoginHelper.getUserId())); } - - /** - * 获取社会化关系详细信息 - * - * @param id 主键 - */ - @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable String id) { - return R.ok(socialUserService.queryById(id)); - } - } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java index fc1cdc08..0d43114a 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java @@ -8,6 +8,7 @@ import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.web.core.BaseController; import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -80,6 +81,7 @@ public class SysTenantController extends BaseController { /** * 新增租户 */ + @ApiEncrypt @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckPermission("system:tenant:add") @Log(title = "租户", businessType = BusinessType.INSERT) 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 ccfa953c..08dfaeaf 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 @@ -13,6 +13,7 @@ import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.excel.core.ExcelResult; import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.log.annotation.Log; @@ -209,6 +210,7 @@ public class SysUserController extends BaseController { /** * 重置密码 */ + @ApiEncrypt @SaCheckPermission("system:user:resetPwd") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping("/resetPwd") diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java index 379dc3d1..1c029fe5 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java @@ -1,7 +1,5 @@ package org.dromara.system.domain.vo; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import org.dromara.system.domain.SysSocial; @@ -17,7 +15,6 @@ import java.util.Date; * @author thiszhc */ @Data -@ExcelIgnoreUnannotated @AutoMapper(target = SysSocial.class) public class SysSocialVo implements Serializable { @@ -27,13 +24,11 @@ public class SysSocialVo implements Serializable { /** * 主键 */ - @ExcelProperty(value = "主键") private Long id; /** * 用户ID */ - @ExcelProperty(value = "用户ID") private Long userId; /** @@ -44,127 +39,106 @@ public class SysSocialVo implements Serializable { /** * 的唯一ID */ - @ExcelProperty(value = "授权UUID") private String authId; /** * 用户来源 */ - @ExcelProperty(value = "用户来源") private String source; /** * 用户的授权令牌 */ - @ExcelProperty(value = "用户的授权令牌") private String accessToken; /** * 用户的授权令牌的有效期,部分平台可能没有 */ - @ExcelProperty(value = "用户的授权令牌的有效期,部分平台可能没有") private int expireIn; /** * 刷新令牌,部分平台可能没有 */ - @ExcelProperty(value = "刷新令牌,部分平台可能没有") private String refreshToken; /** * 用户的 open id */ - @ExcelProperty(value = "平台的唯一id") private String openId; /** * 授权的第三方账号 */ - @ExcelProperty(value = "授权的第三方账号") private String userName; /** * 授权的第三方昵称 */ - @ExcelProperty(value = "授权的第三方昵称") private String nickName; /** * 授权的第三方邮箱 */ - @ExcelProperty(value = "授权的第三方邮箱") private String email; /** * 授权的第三方头像地址 */ - @ExcelProperty(value = "授权的第三方头像地址") private String avatar; /** * 平台的授权信息,部分平台可能没有 */ - @ExcelProperty(value = "平台的授权信息,部分平台可能没有") private String accessCode; /** * 用户的 unionid */ - @ExcelProperty(value = "用户的 unionid") private String unionId; /** * 授予的权限,部分平台可能没有 */ - @ExcelProperty(value = "授予的权限,部分平台可能没有") private String scope; /** * 个别平台的授权信息,部分平台可能没有 */ - @ExcelProperty(value = "个别平台的授权信息,部分平台可能没有") private String tokenType; /** * id token,部分平台可能没有 */ - @ExcelProperty(value = "id token,部分平台可能没有") private String idToken; /** * 小米平台用户的附带属性,部分平台可能没有 */ - @ExcelProperty(value = "小米平台用户的附带属性,部分平台可能没有") private String macAlgorithm; /** * 小米平台用户的附带属性,部分平台可能没有 */ - @ExcelProperty(value = "小米平台用户的附带属性,部分平台可能没有") private String macKey; /** * 用户的授权code,部分平台可能没有 */ - @ExcelProperty(value = "用户的授权code,部分平台可能没有") private String code; /** * Twitter平台用户的附带属性,部分平台可能没有 */ - @ExcelProperty(value = "Twitter平台用户的附带属性,部分平台可能没有") private String oauthToken; /** * Twitter平台用户的附带属性,部分平台可能没有 */ - @ExcelProperty(value = "Twitter平台用户的附带属性,部分平台可能没有") private String oauthTokenSecret; /** * 显示绑定时间 */ - @ExcelProperty(value = "绑定时间") private Date createTime; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java index 85bb43cf..3ddef24b 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSocialServiceImpl.java @@ -6,13 +6,14 @@ import org.dromara.common.core.utils.MapstructUtils; import org.dromara.system.api.RemoteSocialService; import org.dromara.system.api.domain.bo.RemoteSocialBo; import org.dromara.system.api.domain.vo.RemoteSocialVo; -import org.dromara.system.domain.SysSocial; import org.dromara.system.domain.bo.SysSocialBo; import org.dromara.system.domain.vo.SysSocialVo; import org.dromara.system.mapper.SysSocialMapper; import org.dromara.system.service.ISysSocialService; import org.springframework.stereotype.Service; +import java.util.List; + /** * 社会化关系服务 * @@ -30,9 +31,9 @@ public class RemoteSocialServiceImpl implements RemoteSocialService { * 根据 authId 查询用户信息 */ @Override - public RemoteSocialVo selectByAuthId(String authId) { - SysSocialVo socialVo = sysSocialService.selectByAuthId(authId); - return MapstructUtils.convert(socialVo, RemoteSocialVo.class); + public List selectByAuthId(String authId) { + List list = sysSocialService.selectByAuthId(authId); + return MapstructUtils.convert(list, RemoteSocialVo.class); } /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java index 2297a5d5..b3287f38 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java @@ -10,6 +10,7 @@ import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.user.UserException; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.mybatis.helper.DataPermissionHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.system.api.RemoteUserService; import org.dromara.system.api.domain.bo.RemoteUserBo; @@ -44,82 +45,74 @@ public class RemoteUserServiceImpl implements RemoteUserService { @Override public LoginUser getUserInfo(String username, String tenantId) throws UserException { - SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getUserName, SysUser::getStatus) - .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) - .eq(SysUser::getUserName, username)); - if (ObjectUtil.isNull(sysUser)) { - throw new UserException("user.not.exists", username); - } - if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { - throw new UserException("user.blocked", username); - } - // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 - // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 - if (TenantHelper.isEnable()) { - return buildLoginUser(userMapper.selectTenantUserByUserName(username, tenantId)); - } - return buildLoginUser(userMapper.selectUserByUserName(username)); + return TenantHelper.dynamic(tenantId, () -> { + SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() + .select(SysUser::getUserName, SysUser::getStatus) + .eq(SysUser::getUserName, username)); + if (ObjectUtil.isNull(sysUser)) { + throw new UserException("user.not.exists", username); + } + if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { + throw new UserException("user.blocked", username); + } + // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 + // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 + return buildLoginUser(userMapper.selectUserByUserName(username)); + }); } @Override public LoginUser getUserInfo(Long userId, String tenantId) throws UserException { - SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getUserName, SysUser::getStatus) - .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) - .eq(SysUser::getUserId, userId)); - if (ObjectUtil.isNull(sysUser)) { - throw new UserException("user.not.exists", ""); - } - if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { - throw new UserException("user.blocked", sysUser.getUserName()); - } - // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 - // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 - if (TenantHelper.isEnable()) { - return buildLoginUser(userMapper.selectTenantUserByUserName(sysUser.getUserName(), tenantId)); - } - return buildLoginUser(userMapper.selectUserByUserName(sysUser.getUserName())); + return TenantHelper.dynamic(tenantId, () -> { + SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() + .select(SysUser::getUserName, SysUser::getStatus) + .eq(SysUser::getUserId, userId)); + if (ObjectUtil.isNull(sysUser)) { + throw new UserException("user.not.exists", ""); + } + if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { + throw new UserException("user.blocked", sysUser.getUserName()); + } + // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 + // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 + return buildLoginUser(userMapper.selectUserByUserName(sysUser.getUserName())); + }); } @Override public LoginUser getUserInfoByPhonenumber(String phonenumber, String tenantId) throws UserException { - SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getPhonenumber, SysUser::getStatus) - .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) - .eq(SysUser::getPhonenumber, phonenumber)); - if (ObjectUtil.isNull(sysUser)) { - throw new UserException("user.not.exists", phonenumber); - } - if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { - throw new UserException("user.blocked", phonenumber); - } - // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 - // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 - if (TenantHelper.isEnable()) { - return buildLoginUser(userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId)); - } - return buildLoginUser(userMapper.selectUserByPhonenumber(phonenumber)); + return TenantHelper.dynamic(tenantId, () -> { + SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper() + .select(SysUser::getPhonenumber, SysUser::getStatus) + .eq(SysUser::getPhonenumber, phonenumber)); + if (ObjectUtil.isNull(sysUser)) { + throw new UserException("user.not.exists", phonenumber); + } + if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) { + throw new UserException("user.blocked", phonenumber); + } + // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 + // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 + return buildLoginUser(userMapper.selectUserByPhonenumber(phonenumber)); + }); } @Override public LoginUser getUserInfoByEmail(String email, String tenantId) throws UserException { - SysUser user = userMapper.selectOne(new LambdaQueryWrapper() - .select(SysUser::getEmail, SysUser::getStatus) - .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) - .eq(SysUser::getEmail, email)); - if (ObjectUtil.isNull(user)) { - throw new UserException("user.not.exists", email); - } - if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { - throw new UserException("user.blocked", email); - } - // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 - // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 - if (TenantHelper.isEnable()) { - return buildLoginUser(userMapper.selectTenantUserByEmail(email, tenantId)); - } - return buildLoginUser(userMapper.selectUserByEmail(email)); + return TenantHelper.dynamic(tenantId, () -> { + SysUser user = userMapper.selectOne(new LambdaQueryWrapper() + .select(SysUser::getEmail, SysUser::getStatus) + .eq(SysUser::getEmail, email)); + if (ObjectUtil.isNull(user)) { + throw new UserException("user.not.exists", email); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + throw new UserException("user.blocked", email); + } + // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 + // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 + return buildLoginUser(userMapper.selectUserByEmail(email)); + }); } @Override @@ -147,13 +140,14 @@ public class RemoteUserServiceImpl implements RemoteUserService { public Boolean registerUserInfo(RemoteUserBo remoteUserBo) throws UserException, ServiceException { SysUserBo sysUserBo = MapstructUtils.convert(remoteUserBo, SysUserBo.class); String username = sysUserBo.getUserName(); - if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) { - throw new ServiceException("当前系统没有开启注册功能"); - } - boolean exist = userMapper.exists(new LambdaQueryWrapper() - .eq(TenantHelper.isEnable(), SysUser::getTenantId, remoteUserBo.getTenantId()) - .eq(SysUser::getUserName, sysUserBo.getUserName()) - .ne(ObjectUtil.isNotNull(sysUserBo.getUserId()), SysUser::getUserId, sysUserBo.getUserId())); + boolean exist = TenantHelper.dynamic(remoteUserBo.getTenantId(), () -> { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) { + throw new ServiceException("当前系统没有开启注册功能"); + } + return userMapper.exists(new LambdaQueryWrapper() + .eq(SysUser::getUserName, sysUserBo.getUserName()) + .ne(ObjectUtil.isNotNull(sysUserBo.getUserId()), SysUser::getUserId, sysUserBo.getUserId())); + }); if (exist) { throw new UserException("user.register.save.error", username); } @@ -165,6 +159,11 @@ public class RemoteUserServiceImpl implements RemoteUserService { return userService.selectUserNameById(userId); } + @Override + public String selectNicknameById(Long userId) { + return userService.selectNicknameById(userId); + } + /** * 构建登录用户 */ @@ -198,7 +197,7 @@ public class RemoteUserServiceImpl implements RemoteUserService { sysUser.setLoginIp(ip); sysUser.setLoginDate(DateUtils.getNowDate()); sysUser.setUpdateBy(userId); - userMapper.updateById(sysUser); + DataPermissionHelper.ignore(() -> userMapper.updateById(sysUser)); } } 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 a4c691f6..43222253 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 @@ -1,15 +1,14 @@ package org.dromara.system.mapper; -import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; 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.SysUserVo; -import org.apache.ibatis.annotations.Param; import java.util.List; @@ -86,36 +85,6 @@ public interface SysUserMapper extends BaseMapperPlus { */ SysUserVo selectUserByEmail(String email); - /** - * 通过用户名查询用户(不走租户插件) - * - * @param userName 用户名 - * @param tenantId 租户id - * @return 用户对象信息 - */ - @InterceptorIgnore(tenantLine = "true") - SysUserVo selectTenantUserByUserName(@Param("userName") String userName, @Param("tenantId") String tenantId); - - /** - * 通过手机号查询用户(不走租户插件) - * - * @param phonenumber 手机号 - * @param tenantId 租户id - * @return 用户对象信息 - */ - @InterceptorIgnore(tenantLine = "true") - SysUserVo selectTenantUserByPhonenumber(@Param("phonenumber") String phonenumber, @Param("tenantId") String tenantId); - - /** - * 通过邮箱查询用户(不走租户插件) - * - * @param email 邮箱 - * @param tenantId 租户id - * @return 用户对象信息 - */ - @InterceptorIgnore(tenantLine = "true") - SysUserVo selectTenantUserByEmail(@Param("email") String email, @Param("tenantId") String tenantId); - /** * 通过用户ID查询用户 * diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java index abcf6d1f..0950b600 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java @@ -50,7 +50,7 @@ public interface ISysSocialService { * @param authId 认证ID * @return SysSocial */ - SysSocialVo selectByAuthId(String authId); + List selectByAuthId(String authId); } 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 65d6355a..32ae8fca 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 @@ -210,6 +210,14 @@ public interface ISysUserService { */ String selectUserNameById(Long userId); + /** + * 通过用户ID查询用户账户 + * + * @param userId 用户ID + * @return 用户账户 + */ + String selectNicknameById(Long userId); + /** * 通过部门id查询当前部门所有用户 * diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java index 26d6f3f9..7f72159f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java @@ -83,9 +83,10 @@ public class SysConfigServiceImpl implements ISysConfigService { */ @Override public boolean selectRegisterEnabled(String tenantId) { - SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper() - .eq(SysConfig::getConfigKey, "sys.account.registerUser") - .eq(TenantHelper.isEnable(),SysConfig::getTenantId, tenantId)); + SysConfig retConfig = TenantHelper.dynamic(tenantId, () -> { + return baseMapper.selectOne(new LambdaQueryWrapper() + .eq(SysConfig::getConfigKey, "sys.account.registerUser")); + }); if (ObjectUtil.isNull(retConfig)) { return false; } 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 74dde549..8f958e88 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 @@ -119,7 +119,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService { */ @Override public SysDictTypeVo selectDictTypeByType(String dictType) { - return baseMapper.selectVoById(new LambdaQueryWrapper().eq(SysDictType::getDictType, dictType)); + return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysDictType::getDictType, dictType)); } /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java index 2f2493aa..369ac6ad 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java @@ -23,7 +23,7 @@ public class SysSensitiveServiceImpl implements SensitiveService { */ @Override public boolean isSensitive(String roleKey, String perms) { - if (!StpUtil.isLogin()) { + if (!LoginHelper.isLogin()) { return true; } boolean roleExist = StringUtils.isNotEmpty(roleKey); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java index 83834efa..a35a7088 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java @@ -100,8 +100,8 @@ public class SysSocialServiceImpl implements ISysSocialService { * @return 授权信息 */ @Override - public SysSocialVo selectByAuthId(String authId) { - return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysSocial::getAuthId, authId)); + public List selectByAuthId(String authId) { + return baseMapper.selectVoList(new LambdaQueryWrapper().eq(SysSocial::getAuthId, authId)); } } 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 1296ef3c..4ffc5c2f 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 @@ -537,4 +537,12 @@ public class SysUserServiceImpl implements ISysUserService { return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName(); } + @Override + @Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId") + public String selectNicknameById(Long userId) { + SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper() + .select(SysUser::getNickName).eq(SysUser::getUserId, userId)); + return ObjectUtil.isNull(sysUser) ? null : sysUser.getNickName(); + } + } 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 6d92234b..e7831fc9 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 @@ -116,21 +116,6 @@ where u.del_flag = '0' and u.email = #{email} - - - - - -