91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"xly/server/internal/model"
|
|
"xly/server/internal/service"
|
|
)
|
|
|
|
// HTTPHandler 负责注册 HTTP 路由。
|
|
// 控制层只做参数校验和响应包装,不承担上游调用逻辑。
|
|
type HTTPHandler struct {
|
|
ai *service.AIService
|
|
}
|
|
|
|
// NewHTTPHandler 创建 HTTP 控制器。
|
|
func NewHTTPHandler(ai *service.AIService) *HTTPHandler {
|
|
return &HTTPHandler{ai: ai}
|
|
}
|
|
|
|
// Register 将接口注册到 Gin 路由树。
|
|
func (h *HTTPHandler) Register(router gin.IRouter) {
|
|
router.GET("/healthz", h.healthz)
|
|
router.GET("/api/v1/ai/status", h.aiStatus)
|
|
router.POST("/api/v1/ai/interpret", h.aiInterpret)
|
|
}
|
|
|
|
func (h *HTTPHandler) healthz(ctx *gin.Context) {
|
|
ctx.JSON(http.StatusOK, model.APIResponse[map[string]string]{
|
|
Data: &map[string]string{
|
|
"status": "ok",
|
|
},
|
|
Message: "service is healthy",
|
|
})
|
|
}
|
|
|
|
func (h *HTTPHandler) aiStatus(ctx *gin.Context) {
|
|
status := h.ai.Status()
|
|
ctx.JSON(http.StatusOK, model.APIResponse[model.AIStatusResponse]{
|
|
Data: &status,
|
|
Message: "ok",
|
|
})
|
|
}
|
|
|
|
func (h *HTTPHandler) aiInterpret(ctx *gin.Context) {
|
|
var request model.InterpretRequest
|
|
if err := ctx.ShouldBindJSON(&request); err != nil {
|
|
ctx.JSON(http.StatusBadRequest, model.APIResponse[model.InterpretResponse]{
|
|
Message: "请求体无效,请检查解卦上下文是否完整。",
|
|
})
|
|
return
|
|
}
|
|
|
|
request.Question = strings.TrimSpace(request.Question)
|
|
if request.Question == "" {
|
|
ctx.JSON(http.StatusBadRequest, model.APIResponse[model.InterpretResponse]{
|
|
Message: "所问之事不能为空。",
|
|
})
|
|
return
|
|
}
|
|
|
|
content, err := h.ai.Interpret(ctx.Request.Context(), request)
|
|
if err != nil {
|
|
statusCode := http.StatusBadGateway
|
|
message := "AI 解卦失败。"
|
|
|
|
switch {
|
|
case errors.Is(err, service.ErrAIUnavailable):
|
|
statusCode = http.StatusServiceUnavailable
|
|
message = "后端 AI 服务尚未完成配置。"
|
|
default:
|
|
message = err.Error()
|
|
}
|
|
|
|
ctx.JSON(statusCode, model.APIResponse[model.InterpretResponse]{
|
|
Message: message,
|
|
})
|
|
return
|
|
}
|
|
|
|
response := model.InterpretResponse{Content: content}
|
|
ctx.JSON(http.StatusOK, model.APIResponse[model.InterpretResponse]{
|
|
Data: &response,
|
|
Message: "ok",
|
|
})
|
|
}
|