package handler import ( "strconv" "health-ai/internal/api/middleware" "health-ai/internal/service" "health-ai/pkg/response" "github.com/gin-gonic/gin" ) type ConversationHandler struct { convService *service.ConversationService } func NewConversationHandler() *ConversationHandler { return &ConversationHandler{ convService: service.NewConversationService(), } } // GetConversations 获取对话列表 // @Summary 获取对话列表 // @Tags AI对话 // @Accept json // @Produce json // @Param Authorization header string true "Bearer Token" // @Success 200 {object} response.Response{data=[]service.ConversationResponse} // @Router /api/conversations [get] func (h *ConversationHandler) GetConversations(c *gin.Context) { userID := middleware.GetUserID(c) convs, err := h.convService.GetConversations(userID) if err != nil { response.Error(c, 500, err.Error()) return } response.Success(c, convs) } // CreateConversation 创建新对话 // @Summary 创建新对话 // @Tags AI对话 // @Accept json // @Produce json // @Param Authorization header string true "Bearer Token" // @Param request body service.CreateConversationRequest true "对话标题(可选)" // @Success 200 {object} response.Response{data=service.ConversationResponse} // @Router /api/conversations [post] func (h *ConversationHandler) CreateConversation(c *gin.Context) { userID := middleware.GetUserID(c) var req service.CreateConversationRequest c.ShouldBindJSON(&req) conv, err := h.convService.CreateConversation(userID, req.Title) if err != nil { response.Error(c, 500, err.Error()) return } response.Success(c, conv) } // GetConversation 获取对话详情 // @Summary 获取对话详情(含消息历史) // @Tags AI对话 // @Accept json // @Produce json // @Param Authorization header string true "Bearer Token" // @Param id path int true "对话ID" // @Success 200 {object} response.Response{data=service.ConversationResponse} // @Router /api/conversations/{id} [get] func (h *ConversationHandler) GetConversation(c *gin.Context) { userID := middleware.GetUserID(c) convID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { response.BadRequest(c, "无效的对话ID") return } conv, err := h.convService.GetConversation(userID, uint(convID)) if err != nil { response.Error(c, 404, err.Error()) return } response.Success(c, conv) } // DeleteConversation 删除对话 // @Summary 删除对话 // @Tags AI对话 // @Accept json // @Produce json // @Param Authorization header string true "Bearer Token" // @Param id path int true "对话ID" // @Success 200 {object} response.Response // @Router /api/conversations/{id} [delete] func (h *ConversationHandler) DeleteConversation(c *gin.Context) { userID := middleware.GetUserID(c) convID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { response.BadRequest(c, "无效的对话ID") return } if err := h.convService.DeleteConversation(userID, uint(convID)); err != nil { response.Error(c, 400, err.Error()) return } response.SuccessWithMessage(c, "对话已删除", nil) } // SendMessage 发送消息 // @Summary 发送消息并获取AI回复 // @Tags AI对话 // @Accept json // @Produce json // @Param Authorization header string true "Bearer Token" // @Param id path int true "对话ID" // @Param request body service.SendMessageRequest true "消息内容" // @Success 200 {object} response.Response{data=service.MessageResponse} // @Router /api/conversations/{id}/messages [post] func (h *ConversationHandler) SendMessage(c *gin.Context) { userID := middleware.GetUserID(c) convID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { response.BadRequest(c, "无效的对话ID") return } var req service.SendMessageRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请输入消息内容") return } if req.Content == "" { response.BadRequest(c, "消息内容不能为空") return } reply, err := h.convService.SendMessage(c.Request.Context(), userID, uint(convID), req.Content) if err != nil { response.Error(c, 500, "AI回复失败: "+err.Error()) return } response.Success(c, reply) } // SendMessageStream 流式发送消息(SSE) // @Summary 流式发送消息 // @Tags AI对话 // @Accept json // @Produce text/event-stream // @Param Authorization header string true "Bearer Token" // @Param id path int true "对话ID" // @Param request body service.SendMessageRequest true "消息内容" // @Router /api/conversations/{id}/messages/stream [post] func (h *ConversationHandler) SendMessageStream(c *gin.Context) { userID := middleware.GetUserID(c) convID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { response.BadRequest(c, "无效的对话ID") return } var req service.SendMessageRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请输入消息内容") return } // 设置 SSE 响应头 c.Header("Content-Type", "text/event-stream") c.Header("Cache-Control", "no-cache") c.Header("Connection", "keep-alive") err = h.convService.SendMessageStream(c.Request.Context(), userID, uint(convID), req.Content, c.Writer) if err != nil { c.SSEvent("error", err.Error()) } c.SSEvent("done", "") }