feat: 更新项目代码

This commit is contained in:
2026-04-01 22:03:57 +08:00
parent 1c81d4e6ea
commit 284b5a5260
53 changed files with 6240 additions and 22665 deletions

View File

@@ -1,7 +1,10 @@
package router
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
@@ -11,6 +14,31 @@ import (
"infogenie-backend/internal/middleware"
)
func probeSixtyPublicAPI(ctx context.Context, base string) (ok bool, httpStatus int, errMsg string, ms int64, probeURL string) {
b := strings.TrimSpace(base)
if b == "" {
return false, 0, "empty_base", 0, ""
}
probeURL = strings.TrimRight(b, "/") + "/v2/ip"
client := &http.Client{Timeout: 6 * time.Second}
t0 := time.Now()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, probeURL, nil)
if err != nil {
return false, 0, err.Error(), time.Since(t0).Milliseconds(), probeURL
}
resp, err := client.Do(req)
ms = time.Since(t0).Milliseconds()
if err != nil {
return false, 0, err.Error(), ms, probeURL
}
_ = resp.Body.Close()
ok = resp.StatusCode >= 200 && resp.StatusCode < 500
if !ok && errMsg == "" {
errMsg = fmt.Sprintf("http_%d", resp.StatusCode)
}
return ok, resp.StatusCode, "", ms, probeURL
}
func Setup(r *gin.Engine) {
r.Use(middleware.CORS())
@@ -24,33 +52,66 @@ func Setup(r *gin.Engine) {
c.JSON(http.StatusOK, gin.H{
"message": "万象口袋 后端 API 服务运行中",
"description": "提供AI模型应用接口用户认证由萌芽账户认证中心提供",
"version": "3.2.0-go",
"version": "3.3.0-go",
"timestamp": time.Now().Format(time.RFC3339),
"endpoints": gin.H{
"auth": "/api/auth (via 萌芽认证中心)",
"user": "/api/user",
"aimodelapp": "/api/aimodelapp",
"site": "/api/site",
"site": "/api/site (含 feature-card-clicks)",
"admin_site": "/api/admin/site/*",
},
})
})
// 健康检查:实际检测数据库连接
// 健康检查:数据库 Ping + 当前配置的 60s 上游轻量探测GET …/v2/ip
r.GET("/api/health", func(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 8*time.Second)
defer cancel()
dbStatus := "connected"
if database.DB != nil {
sqlDB, err := database.DB.DB()
if err != nil || sqlDB.Ping() != nil {
if err != nil || sqlDB.PingContext(ctx) != nil {
dbStatus = "disconnected"
}
} else {
dbStatus = "not_initialized"
}
mysqlOK := dbStatus == "connected"
sid, sixtyBase, sixtyLabel := handler.EffectiveSixtyUpstream(database.DB)
sixtyOK, sixtyHTTP, sixtyErr, sixtyMs, probeURL := probeSixtyPublicAPI(ctx, sixtyBase)
if !sixtyOK && sixtyErr == "" && sixtyHTTP >= 500 {
sixtyErr = fmt.Sprintf("http_%d", sixtyHTTP)
}
overall := "running"
if !mysqlOK || !sixtyOK {
overall = "degraded"
}
c.JSON(http.StatusOK, gin.H{
"status": "running",
"database": dbStatus,
"status": overall,
"timestamp": time.Now().Format(time.RFC3339),
"database": dbStatus,
"mysql": gin.H{
"ok": mysqlOK,
"status": dbStatus,
},
"backend_api": gin.H{
"ok": true,
},
"sixty_api": gin.H{
"ok": sixtyOK,
"source_id": sid,
"base_url": sixtyBase,
"label": sixtyLabel,
"probe_url": probeURL,
"http_status": sixtyHTTP,
"latency_ms": sixtyMs,
"error": sixtyErr,
},
})
})
@@ -68,6 +129,8 @@ func Setup(r *gin.Engine) {
r.GET("/api/site/60s-disabled", siteH.Get60sDisabled)
r.GET("/api/site/60s-source", siteH.Get60sSource)
r.GET("/api/site/ai-model-disabled", siteH.GetAIModelDisabled)
r.GET("/api/site/feature-card-clicks", siteH.GetFeatureCardClicks)
r.POST("/api/site/feature-card-clicks/increment", siteH.PostFeatureCardClickIncrement)
r.PUT("/api/admin/site/60s-disabled", siteH.Put60sDisabled)
r.PUT("/api/admin/site/60s-source", siteH.Put60sSource)
r.PUT("/api/admin/site/ai-model-disabled", siteH.PutAIModelDisabled)
@@ -77,6 +140,7 @@ func Setup(r *gin.Engine) {
ai := r.Group("/api/aimodelapp")
{
ai.POST("/chat", middleware.JWTAuth(), aiH.Chat)
ai.POST("/chat/stream", middleware.JWTAuth(), aiH.ChatStream)
ai.POST("/name-analysis", middleware.JWTAuth(), aiH.NameAnalysis)
ai.POST("/variable-naming", middleware.JWTAuth(), aiH.VariableNaming)
ai.POST("/poetry", middleware.JWTAuth(), aiH.Poetry)