This repository has been archived on 2026-08-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Cyrene/backend/gateway/internal/handler/session_handler.go
T
AskaEth d15acf587c feat: DevTools综合升级 — 记忆查询 + 会话监看 + WebUI侧边栏重构
- docs: 17个文件重命名为 YYYY-MM-DD.HH-mm-SS-内容.md 格式
- config: 管理员凭据移至 backend/.env (ADMIN_USERNAME/PASSWORD)
- gateway: 新增 SessionState 会话追踪 + GET /api/v1/admin/sessions
- devtools: 新增7个代理端点 (dashboard/sessions/memory)
- devtools: WebUI重构为侧边栏 + 5面板 (仪表盘/记忆/会话/服务/性能)
2026-05-16 15:02:44 +08:00

153 lines
3.4 KiB
Go

package handler
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/yourname/cyrene-ai/gateway/internal/middleware"
"github.com/yourname/cyrene-ai/gateway/internal/ws"
)
// SessionHandler 会话管理处理器
type SessionHandler struct {
// MVP阶段使用内存存储,后续迁移到PostgreSQL
sessions map[string][]SessionInfo // userID -> sessions
hub *ws.Hub
}
// SessionInfo 会话信息
type SessionInfo struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Title string `json:"title"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
// NewSessionHandler 创建会话处理器
func NewSessionHandler(hub *ws.Hub) *SessionHandler {
return &SessionHandler{
sessions: make(map[string][]SessionInfo),
hub: hub,
}
}
// Create 创建新会话
func (h *SessionHandler) Create(c *gin.Context) {
userID := middleware.GetUserID(c)
var req struct {
Title string `json:"title"`
}
if err := c.ShouldBindJSON(&req); err != nil {
// 允许空body
req.Title = "新的对话"
}
if req.Title == "" {
req.Title = "新的对话"
}
session := SessionInfo{
ID: "session_" + randomID(12),
UserID: userID,
Title: req.Title,
CreatedAt: time.Now().UnixMilli(),
UpdatedAt: time.Now().UnixMilli(),
}
h.sessions[userID] = append([]SessionInfo{session}, h.sessions[userID]...)
c.JSON(http.StatusCreated, session)
}
// List 获取会话列表
func (h *SessionHandler) List(c *gin.Context) {
userID := middleware.GetUserID(c)
sessions, ok := h.sessions[userID]
if !ok {
sessions = []SessionInfo{}
}
c.JSON(http.StatusOK, gin.H{
"sessions": sessions,
})
}
// Delete 删除会话
func (h *SessionHandler) Delete(c *gin.Context) {
userID := middleware.GetUserID(c)
sessionID := c.Param("id")
sessions := h.sessions[userID]
for i, s := range sessions {
if s.ID == sessionID {
h.sessions[userID] = append(sessions[:i], sessions[i+1:]...)
c.JSON(http.StatusOK, gin.H{"status": "deleted"})
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
}
// Get 获取单个会话信息
func (h *SessionHandler) Get(c *gin.Context) {
userID := middleware.GetUserID(c)
sessionID := c.Param("id")
for _, s := range h.sessions[userID] {
if s.ID == sessionID {
c.JSON(http.StatusOK, s)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
}
// ========== Admin 端点 ==========
// ListActiveSessions 获取当前所有活跃 WebSocket 会话列表 (管理员)
func (h *SessionHandler) ListActiveSessions(c *gin.Context) {
sessions := h.hub.GetActiveSessions()
if sessions == nil {
sessions = []*ws.SessionState{}
}
c.JSON(http.StatusOK, gin.H{
"sessions": sessions,
"total": len(sessions),
})
}
// GetSession 获取指定会话的详细信息 (管理员)
func (h *SessionHandler) GetSession(c *gin.Context) {
sessionID := c.Param("id")
if sessionID == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少会话ID"})
return
}
session := h.hub.GetSession(sessionID)
if session == nil {
c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
return
}
c.JSON(http.StatusOK, session)
}
// 简单的工具函数
func randomID(n int) string {
const letters = "abcdefghijklmnopqrstuvwxyz0123456789"
b := make([]byte, n)
for i := range b {
b[i] = letters[i%len(letters)]
}
// 使用纳秒时间戳增加唯一性
return string(b)
}