Files
CamTalk/backend/internal/api/session.go
hhs 6487a8ecab feat: 扩展 Session Manager 接口,新增 ListByUser、UpdateTitle 方法
- Manager.Create 签名新增 userID 参数
- 新增 ConversationSummary 类型和 ListByUser 分页查询
- 新增 UpdateTitle 方法
- MemoryManager 实现:ListByUser 遍历+过滤+排序,UpdateTitle,自动标题生成
- RedisManager 实现:user:{id}:sessions 索引,ListByUser 通过 SMEMBERS 查询
- AppendMessage 自动更新标题(首条 user 消息时,取前 20 字符)
- 更新 ws handler、api/session.go、orchestrator mock 的 Create 调用
2026-06-14 17:35:20 +08:00

92 lines
2.3 KiB
Go

// Package api 提供 REST API 处理函数。
package api
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/hhs/camtalk/internal/models"
"github.com/hhs/camtalk/internal/session"
)
// SessionHandler 提供会话相关的 REST 端点。
type SessionHandler struct {
sessionMgr session.Manager
}
// NewSessionHandler 创建 SessionHandler。
func NewSessionHandler(sessionMgr session.Manager) *SessionHandler {
return &SessionHandler{sessionMgr: sessionMgr}
}
// CreateSessionRequest POST /api/sessions 请求体(所有字段可选)。
type CreateSessionRequest struct {
Config *models.SessionConfig `json:"config,omitempty"`
}
// CreateSession POST /api/sessions — 创建新会话。
func (h *SessionHandler) CreateSession(c *gin.Context) {
var req CreateSessionRequest
// 请求体可选,解析失败不报错(使用默认配置)
_ = c.ShouldBindJSON(&req)
cfg := models.DefaultConfig()
if req.Config != nil {
cfg = *req.Config
}
sessionID, err := h.sessionMgr.Create(c.Request.Context(), "", cfg)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": "INTERNAL_ERROR",
"message": "failed to create session",
})
return
}
// 获取创建后的会话以返回 created_at
sess, err := h.sessionMgr.Get(c.Request.Context(), sessionID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": "INTERNAL_ERROR",
"message": "failed to retrieve created session",
})
return
}
c.JSON(http.StatusCreated, gin.H{
"session_id": sess.ID,
"created_at": sess.CreatedAt,
})
}
// DestroySession DELETE /api/sessions/:id — 销毁会话。
func (h *SessionHandler) DestroySession(c *gin.Context) {
sessionID := c.Param("id")
err := h.sessionMgr.Destroy(c.Request.Context(), sessionID)
if err != nil {
if err == session.ErrSessionNotFound {
c.JSON(http.StatusNotFound, gin.H{
"code": "SESSION_NOT_FOUND",
"message": "session not found or already expired",
})
return
}
c.JSON(http.StatusInternalServerError, gin.H{
"code": "INTERNAL_ERROR",
"message": "failed to destroy session",
})
return
}
c.Status(http.StatusNoContent)
}
// RegisterRoutes 注册会话相关路由到给定的路由组。
func (h *SessionHandler) RegisterRoutes(rg *gin.RouterGroup) {
rg.POST("/sessions", h.CreateSession)
rg.DELETE("/sessions/:id", h.DestroySession)
}