Merge pull request 'feat: 补全设计文档中的 REST 端点' (#41) from feature/phase6 into develop
Reviewed-on: http://8.161.227.145:3000/XEngineers/CamTalk/pulls/41
This commit was merged in pull request #41.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"github.com/hhs/camtalk/internal/api"
|
||||||
"github.com/hhs/camtalk/internal/ai/llm"
|
"github.com/hhs/camtalk/internal/ai/llm"
|
||||||
"github.com/hhs/camtalk/internal/ai/stt"
|
"github.com/hhs/camtalk/internal/ai/stt"
|
||||||
"github.com/hhs/camtalk/internal/ai/tts"
|
"github.com/hhs/camtalk/internal/ai/tts"
|
||||||
@@ -61,11 +62,15 @@ func main() {
|
|||||||
r.Use(gin.Recovery())
|
r.Use(gin.Recovery())
|
||||||
|
|
||||||
// REST API
|
// REST API
|
||||||
api := r.Group("/api")
|
apiGroup := r.Group("/api")
|
||||||
{
|
{
|
||||||
api.GET("/health", healthHandler(sessionMgr))
|
apiGroup.GET("/health", healthHandler(sessionMgr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Session REST 端点
|
||||||
|
sessionHandler := api.NewSessionHandler(sessionMgr)
|
||||||
|
sessionHandler.RegisterRoutes(apiGroup)
|
||||||
|
|
||||||
// WebSocket
|
// WebSocket
|
||||||
r.GET("/ws", ws.ServeWS(sessionMgr, orch))
|
r.GET("/ws", ws.ServeWS(sessionMgr, orch))
|
||||||
|
|
||||||
@@ -106,7 +111,7 @@ func healthHandler(sessionMgr session.Manager) gin.HandlerFunc {
|
|||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"uptime": time.Since(startTime).String(),
|
"uptime_seconds": int(time.Since(startTime).Seconds()),
|
||||||
"active_sessions": sessionMgr.ActiveCount(),
|
"active_sessions": sessionMgr.ActiveCount(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
91
backend/internal/api/session.go
Normal file
91
backend/internal/api/session.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user