- 1.6.5-snapshot
+ 1.6.6-snapshot
2.7.7
@@ -23,8 +23,8 @@
2.5
1.2.15
- 3.5.3
- 3.5.2
+ 3.5.3.1
+ 3.5.3.1
3.6.1
3.18.0
diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml
index 1928aa88c..3bfc020ba 100644
--- a/yudao-framework/pom.xml
+++ b/yudao-framework/pom.xml
@@ -40,6 +40,7 @@
yudao-spring-boot-starter-flowable
yudao-spring-boot-starter-captcha
+ yudao-spring-boot-starter-websocket
yudao-framework
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java
index a2b11b1dc..f554e0b52 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java
@@ -9,10 +9,11 @@ import io.minio.*;
import java.io.ByteArrayInputStream;
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
+import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT;
/**
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
- *
+ *
* S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库
*
* @author 芋道源码
@@ -78,6 +79,11 @@ public class S3FileClient extends AbstractFileClient {
.replaceAll("-internal", "")// 去除内网 Endpoint 的后缀
.replaceAll("https://", "");
}
+ // 腾讯云必须有 region,否则会报错
+ if (config.getEndpoint().contains(ENDPOINT_TENCENT)) {
+ return StrUtil.subAfter(config.getEndpoint(), ".cos.", false)
+ .replaceAll("." + ENDPOINT_TENCENT, ""); // 去除 Endpoint
+ }
return null;
}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java
index 151159f5e..0c46e8aa6 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java
@@ -19,6 +19,7 @@ public class S3FileClientConfig implements FileClientConfig {
public static final String ENDPOINT_QINIU = "qiniucs.com";
public static final String ENDPOINT_ALIYUN = "aliyuncs.com";
+ public static final String ENDPOINT_TENCENT = "myqcloud.com";
/**
* 节点地址
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml b/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml
new file mode 100644
index 000000000..320e52c48
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ cn.iocoder.boot
+ yudao-framework
+ ${revision}
+
+ 4.0.0
+ yudao-spring-boot-starter-websocket
+ jar
+
+ ${project.artifactId}
+ WebSocket
+ https://github.com/YunaiV/ruoyi-vue-pro
+
+
+
+
+
+ cn.iocoder.boot
+ yudao-common
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-security
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+
+
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketHandlerConfig.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketHandlerConfig.java
new file mode 100644
index 000000000..02c3415d5
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketHandlerConfig.java
@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.framework.websocket.config;
+
+import cn.iocoder.yudao.framework.websocket.core.UserHandshakeInterceptor;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+@EnableConfigurationProperties(WebSocketProperties.class)
+public class WebSocketHandlerConfig {
+ @Bean
+ public HandshakeInterceptor handshakeInterceptor() {
+ return new UserHandshakeInterceptor();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketProperties.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketProperties.java
new file mode 100644
index 000000000..0ab1b498f
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketProperties.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.framework.websocket.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * WebSocket 配置项
+ *
+ * @author xingyu4j
+ */
+@ConfigurationProperties("yudao.websocket")
+@Data
+@Validated
+public class WebSocketProperties {
+
+ /**
+ * 路径
+ */
+ private String path = "";
+ /**
+ * 默认最多允许同时在线用户数
+ */
+ private int maxOnlineCount = 0;
+ /**
+ * 是否保存session
+ */
+ private boolean sessionMap = true;
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java
new file mode 100644
index 000000000..f8c50ae6a
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.framework.websocket.config;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.List;
+
+/**
+ * WebSocket 自动配置
+ *
+ * @author xingyu4j
+ */
+@AutoConfiguration
+// 允许使用 yudao.websocket.enable=false 禁用websocket
+@ConditionalOnProperty(prefix = "yudao.websocket", value = "enable", matchIfMissing = true)
+@EnableConfigurationProperties(WebSocketProperties.class)
+public class YudaoWebSocketAutoConfiguration {
+ @Bean
+ @ConditionalOnMissingBean
+ public WebSocketConfigurer webSocketConfigurer(List handshakeInterceptor,
+ WebSocketHandler webSocketHandler,
+ WebSocketProperties webSocketProperties) {
+
+ return registry -> registry
+ .addHandler(webSocketHandler, webSocketProperties.getPath())
+ .addInterceptors(handshakeInterceptor.toArray(new HandshakeInterceptor[0]));
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/UserHandshakeInterceptor.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/UserHandshakeInterceptor.java
new file mode 100644
index 000000000..3f2fa4ec3
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/UserHandshakeInterceptor.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.framework.websocket.core;
+
+import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.Map;
+
+public class UserHandshakeInterceptor implements HandshakeInterceptor {
+ @Override
+ public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception {
+ LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
+ attributes.put(WebSocketKeyDefine.LOGIN_USER, loginUser);
+ return true;
+ }
+
+ @Override
+ public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
+
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketKeyDefine.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketKeyDefine.java
new file mode 100644
index 000000000..f75ebc41c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketKeyDefine.java
@@ -0,0 +1,9 @@
+package cn.iocoder.yudao.framework.websocket.core;
+
+
+import lombok.Data;
+
+@Data
+public class WebSocketKeyDefine {
+ public static final String LOGIN_USER ="LOGIN_USER";
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketMessageDO.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketMessageDO.java
new file mode 100644
index 000000000..7bb348e99
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketMessageDO.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.framework.websocket.core;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+public class WebSocketMessageDO {
+ /**
+ * 接收消息的seesion
+ */
+ private List