Browse Source

Add Shutdown listener

tsurumure 5 tháng trước cách đây
mục cha
commit
577ac1df1c

+ 1 - 1
db/__ai_chat_config.sql

@@ -10,7 +10,7 @@
 #     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
 #     `config_key` VARCHAR(255) COMMENT '配置名称',
 #     `config_value` VARCHAR(255) COMMENT '配置值'
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI对话配置表';
+# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI助手配置表';
 #
 # INSERT INTO ai_chat_config(config_key, config_value) VALUES
 #     ('expired_time', 30)

+ 1 - 1
db/ai_chat.sql

@@ -25,5 +25,5 @@ CREATE TABLE `ai_chat` (
     INDEX `idx_history_code` (`history_code`),
     INDEX `idx_user_id` (`user_id`),
     INDEX `idx_robot_code` (`robot_code`)
-) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI对话表';
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI助手表';
 

+ 1 - 1
db/ai_chat_history.sql

@@ -18,7 +18,7 @@ CREATE TABLE `ai_chat_history` (
     UNIQUE KEY `uk_history_code` (`history_code`),
     INDEX `idx_user_id` (`user_id`),
     INDEX `idx_robot_code` (`robot_code`)
-) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI对话历史记录表';
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI助手历史记录表';
 
 # INSERT INTO ai_chat_history(history_code, user_id, robot_code, last_content) VALUES
 #     ('5670822e-f0f7-4635-b766-c9c61edef0fa', 1, '102348821', '生成一条关于制作蛋糕的文案,适用于家用,用料是纯天然无添加剂,主打绿色健康美味的理念'),

+ 1 - 1
db/ai_chat_model.sql

@@ -13,7 +13,7 @@ CREATE TABLE `ai_chat_model` (
     `value` VARCHAR(255) COMMENT '模型 (HUNYUAN-混元, DEEPSEEK_API, DEEPSEEK_R1)',
     `disabled` TINYINT(1) DEFAULT '1' COMMENT '是否禁用 (-1可用, 1禁用)',
     `status` TINYINT(1) DEFAULT '1' COMMENT '状态 (-1禁用, 1启用)'
-) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI对话模型表';
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI助手模型表';
 
 INSERT INTO ai_chat_model(id, parent_id, label, value, disabled, status) VALUES
     (1, -1, 'DeepSeek R1', 'DEEPSEEK_R1', -1, 1),

+ 1 - 1
db/sys_user_role_menu.sql

@@ -37,7 +37,7 @@ INSERT INTO sys_user_role_menu(id, parent_id, menu_name, menu_name_en, type, pat
 #     (2, '订单管理', 'Orders', 1, '/b2c/order/b2cOrder', '/src/views/b2c/order/b2cOrder.vue', '{}', null, null, 4),
 #     (2, '订单详情', 'Orders Detail', 2, '/b2c/order/b2cOrderDetail', '/src/views/b2c/order/b2cOrderDetail.vue', '{"isBack":true,"isHide":true}', null, null, 4),
 
-    (2, -1, 'AI对话', 'AI Chat', 1, '/ai/chat/chat', '/src/views/ai/chat.vue', '{}', 'Document', '31', 900),
+    (2, -1, 'AI助手', 'AI Chat', 1, '/ai/chat/chat', '/src/views/ai/chat.vue', '{}', 'Document', '31', 900),
 
     (3, -1, 'AI图片生成器', 'AI Image', 1, '/ai/imagePicker', '', '{}', 'Picture', '35', 901),
     (4, 3, 'AI模特', 'AI Model', 1, '/ai/modelCloth/make', '', '{}', '', '', 902),

+ 1 - 1
db/sys_user_role_permission.sql

@@ -26,7 +26,7 @@ INSERT INTO sys_user_role_permission(id, parent_id, permission_name, sort) VALUE
 
     ('2', -1, '创意中心', 2),
 
-    ('31', -1, 'AI对话', 3),
+    ('31', -1, 'AI助手', 3),
     ('32', -1, 'AI商品图', 4),
         ('32.1', '32', 'AI商品图-运营权限', null),
     ('33', -1, 'AI数智人', 5),

+ 12 - 12
db/sys_user_role_permission_relation.sql

@@ -90,14 +90,14 @@ INSERT INTO sys_user_role_permission_relation(role_id, permission_id) VALUES
             (1, '21.3.1'), (1, '21.3.2'), (1, '21.3.3'), (1, '21.3.4'),
 
     (1, '31'),
-    (1, '32'),
-        (1, '32.1'),
-    (1, '33'),
-        (1, '33.1'),
-    (1, '34'),
-        (1, '34.1'),
-    (1, '35'),
-        (1, '35.1'),
+#     (1, '32'),
+#         (1, '32.1'),
+#     (1, '33'),
+#         (1, '33.1'),
+#     (1, '34'),
+#         (1, '34.1'),
+#     (1, '35'),
+#         (1, '35.1'),
 
 
     (1, '100'),
@@ -122,10 +122,10 @@ INSERT INTO sys_user_role_permission_relation(role_id, permission_id) VALUES
     (2, '4.1'),
 
     (2, '31'),
-    (2, '32'),
-    (2, '33'),
-    (2, '34'),
-    (2, '35'),
+#     (2, '32'),
+#     (2, '33'),
+#     (2, '34'),
+#     (2, '35'),
 
 
     (3, '3'),

+ 25 - 0
src/main/java/com/backendsys/modules/common/listener/ShutdownListener.java

@@ -0,0 +1,25 @@
+package com.backendsys.modules.common.listener;
+
+import com.backendsys.modules.sse.entity.SseResponse;
+import com.backendsys.modules.sse.entity.SseResponseEnum;
+import com.backendsys.modules.sse.utils.SseUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ShutdownListener implements ApplicationListener<ContextClosedEvent> {
+
+    @Autowired
+    private SseUtil sseUtil;
+
+    @Override
+    public void onApplicationEvent(ContextClosedEvent event) {
+        System.out.println("(ShutdownListener) Application is shutting down...");
+        // 发送 SSE 消息通知前端
+        // sseUtil.sendToAll(new SseResponse(SseResponseEnum.DISCONNECT, "Application is shutting down.").toJsonStr());
+        sseUtil.closeAllEmitters();
+    }
+
+}

+ 9 - 3
src/main/java/com/backendsys/modules/sse/emitter/SseEmitterManager.java

@@ -34,13 +34,19 @@ public class SseEmitterManager {
     public SseEmitterUTF8 getEmitter(String emitterKey) {
         return this.emitters.get(emitterKey);
     }
+    // 公共方法,获取所有SseEmitter实例
+    public ConcurrentHashMap<String, SseEmitterUTF8> getAllEmitters() {
+        return this.emitters;
+    }
     // 公共方法,供外部移除SseEmitter
     public void removeEmitter(SseEmitterUTF8 emitter) {
         this.emitters.values().removeIf(e -> e == emitter); // 安全移除
         emitter.complete(); // 显式调用complete方法
     }
-    // 公共方法,获取所有SseEmitter实例
-    public ConcurrentHashMap<String, SseEmitterUTF8> getAllEmitters() {
-        return this.emitters;
+    // 公共方法,供外部移除SseEmitter (全部)
+    public void removeAllEmitter() {
+        for (SseEmitterUTF8 emitter : emitters.values()) {
+            removeEmitter(emitter);
+        }
     }
 }

+ 10 - 0
src/main/java/com/backendsys/modules/sse/utils/SseUtil.java

@@ -11,6 +11,9 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 @Component
@@ -85,4 +88,11 @@ public class SseUtil {
         }
     }
 
+    // 添加一个新的方法:关闭所有 SSE 连接
+    public void closeAllEmitters() {
+        System.out.println("Closing all SSE connections...");
+        SseEmitterManager manager = SseEmitterManager.getInstance();
+        manager.removeAllEmitter();
+    }
+
 }