From dbd322807dbd70f156f095087bd4d17ad448e484 Mon Sep 17 00:00:00 2001
From: wangshun <932054296@qq.com>
Date: Fri, 5 Sep 2025 16:24:09 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=BF=BD=E5=8A=A0=EF=BC=9A?=
=?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=9C=A8=E7=BA=BF=E4=BA=BA=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/openisle/config/CachingConfig.java | 2 +
.../com/openisle/config/SecurityConfig.java | 5 +-
.../openisle/controller/OnlineController.java | 33 ++++++++++
frontend_nuxt/components/HeaderComponent.vue | 62 ++++++++++++++++++-
4 files changed, 100 insertions(+), 2 deletions(-)
create mode 100644 backend/src/main/java/com/openisle/controller/OnlineController.java
diff --git a/backend/src/main/java/com/openisle/config/CachingConfig.java b/backend/src/main/java/com/openisle/config/CachingConfig.java
index ded16138a..268c7f945 100644
--- a/backend/src/main/java/com/openisle/config/CachingConfig.java
+++ b/backend/src/main/java/com/openisle/config/CachingConfig.java
@@ -36,6 +36,8 @@ public class CachingConfig {
public static final String TAG_CACHE_NAME="openisle_tags";
// 分类缓存名
public static final String CATEGORY_CACHE_NAME="openisle_categories";
+ // 在线人数缓存名
+ public static final String ONLINE_CACHE_NAME="openisle_online";
/**
* 自定义Redis的序列化器
diff --git a/backend/src/main/java/com/openisle/config/SecurityConfig.java b/backend/src/main/java/com/openisle/config/SecurityConfig.java
index 9cfc4d880..a4dc948db 100644
--- a/backend/src/main/java/com/openisle/config/SecurityConfig.java
+++ b/backend/src/main/java/com/openisle/config/SecurityConfig.java
@@ -129,6 +129,8 @@ public class SecurityConfig {
.requestMatchers(HttpMethod.GET, "/api/sitemap.xml").permitAll()
.requestMatchers(HttpMethod.GET, "/api/channels").permitAll()
.requestMatchers(HttpMethod.GET, "/api/rss").permitAll()
+ .requestMatchers(HttpMethod.GET, "/api/online/**").permitAll()
+ .requestMatchers(HttpMethod.POST, "/api/online/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/point-goods").permitAll()
.requestMatchers(HttpMethod.POST, "/api/point-goods").permitAll()
.requestMatchers(HttpMethod.POST, "/api/categories/**").hasAuthority("ADMIN")
@@ -183,7 +185,8 @@ public class SecurityConfig {
}
} else if (!uri.startsWith("/api/auth") && !publicGet
&& !uri.startsWith("/api/ws") && !uri.startsWith("/api/sockjs")
- && !uri.startsWith("/api/v3/api-docs")) {
+ && !uri.startsWith("/api/v3/api-docs")
+ && !uri.startsWith("/api/online")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"error\": \"Missing token\"}");
diff --git a/backend/src/main/java/com/openisle/controller/OnlineController.java b/backend/src/main/java/com/openisle/controller/OnlineController.java
new file mode 100644
index 000000000..2f6a307c2
--- /dev/null
+++ b/backend/src/main/java/com/openisle/controller/OnlineController.java
@@ -0,0 +1,33 @@
+package com.openisle.controller;
+
+import com.openisle.config.CachingConfig;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.Duration;
+
+/**
+ * @author smallclover
+ * @since 2025-09-05
+ * 统计在线人数
+ */
+@RestController
+@RequestMapping("/api/online")
+@RequiredArgsConstructor
+public class OnlineController {
+
+ private final RedisTemplate redisTemplate;
+ private static final String ONLINE_KEY = CachingConfig.ONLINE_CACHE_NAME +":";
+
+ @PostMapping("/heartbeat")
+ public void ping(@RequestParam String userId){
+ redisTemplate.opsForValue().set(ONLINE_KEY+userId,"1", Duration.ofSeconds(150));
+ }
+
+ @GetMapping("/count")
+ public long count(){
+ return redisTemplate.keys(ONLINE_KEY+"*").size();
+ }
+}
diff --git a/frontend_nuxt/components/HeaderComponent.vue b/frontend_nuxt/components/HeaderComponent.vue
index 6393075f8..18d3194f2 100644
--- a/frontend_nuxt/components/HeaderComponent.vue
+++ b/frontend_nuxt/components/HeaderComponent.vue
@@ -37,7 +37,12 @@
邀请
-
+
+
+
+ {{ onlineCount }}
+
+