151 lines
3.7 KiB
Go
151 lines
3.7 KiB
Go
package handlers
|
||
|
||
import (
|
||
"context"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
"go.mongodb.org/mongo-driver/v2/bson"
|
||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||
|
||
"yh_web/server/config"
|
||
"yh_web/server/models"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// effectivePagePath 对外访问路径:优先 route_path,否则 /{slug};index 且无 route_path 时返回空(由首页单独处理)
|
||
func effectivePagePath(p models.Page) string {
|
||
if p.RoutePath != "" {
|
||
path := strings.TrimSpace(p.RoutePath)
|
||
if !strings.HasPrefix(path, "/") {
|
||
path = "/" + path
|
||
}
|
||
return path
|
||
}
|
||
if p.Slug == "" || p.Slug == homepageSlug {
|
||
return ""
|
||
}
|
||
return "/" + p.Slug
|
||
}
|
||
|
||
// GetWebRoutes 前台:获取站点已发布页面的动态路由列表(无需鉴权)
|
||
func GetWebRoutes(c *gin.Context) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
|
||
if config.MongoClient == nil {
|
||
c.JSON(http.StatusOK, gin.H{"site_id": "", "routes": []any{}})
|
||
return
|
||
}
|
||
|
||
siteID := c.Query("site_id")
|
||
if siteID == "" {
|
||
siteID = getOfficialSiteID(ctx)
|
||
}
|
||
if siteID == "" {
|
||
c.JSON(http.StatusOK, gin.H{"site_id": "", "routes": []any{}})
|
||
return
|
||
}
|
||
|
||
coll := config.GetDB(config.DBName).Collection("pages")
|
||
opts := options.Find().SetSort(bson.D{{Key: "updated_at", Value: -1}})
|
||
cursor, err := coll.Find(ctx, bson.M{"site_id": siteID}, opts)
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
defer cursor.Close(ctx)
|
||
|
||
var pages []models.Page
|
||
if err = cursor.All(ctx, &pages); err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
routes := make([]gin.H, 0)
|
||
for _, p := range pages {
|
||
if p.Published != nil && !*p.Published {
|
||
continue
|
||
}
|
||
path := effectivePagePath(p)
|
||
if path == "" {
|
||
continue
|
||
}
|
||
routes = append(routes, gin.H{
|
||
"path": path,
|
||
"title": p.Title,
|
||
"slug": p.Slug,
|
||
"id": p.ID.Hex(),
|
||
"mode": p.ContentMode,
|
||
})
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"site_id": siteID, "routes": routes})
|
||
}
|
||
|
||
// GetWebPageByPath 前台:按路径取单页内容(无需鉴权)
|
||
func GetWebPageByPath(c *gin.Context) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
|
||
if config.MongoClient == nil {
|
||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "服务暂不可用"})
|
||
return
|
||
}
|
||
|
||
siteID := c.Query("site_id")
|
||
if siteID == "" {
|
||
siteID = getOfficialSiteID(ctx)
|
||
}
|
||
path := strings.TrimSpace(c.Query("path"))
|
||
if siteID == "" || path == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少 site_id 或 path"})
|
||
return
|
||
}
|
||
if !strings.HasPrefix(path, "/") {
|
||
path = "/" + path
|
||
}
|
||
|
||
coll := config.GetDB(config.DBName).Collection("pages")
|
||
|
||
var page models.Page
|
||
tryDecode := func(filter bson.M) bool {
|
||
page = models.Page{}
|
||
err := coll.FindOne(ctx, filter).Decode(&page)
|
||
return err == nil && !page.ID.IsZero()
|
||
}
|
||
if !tryDecode(bson.M{"site_id": siteID, "route_path": path}) {
|
||
alt := strings.TrimPrefix(path, "/")
|
||
if alt != "" {
|
||
tryDecode(bson.M{"site_id": siteID, "route_path": alt})
|
||
}
|
||
}
|
||
if page.ID.IsZero() {
|
||
slug := strings.TrimPrefix(path, "/")
|
||
if slug != "" {
|
||
tryDecode(bson.M{"site_id": siteID, "slug": slug})
|
||
}
|
||
}
|
||
if page.ID.IsZero() {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "页面不存在"})
|
||
return
|
||
}
|
||
if page.Published != nil && !*page.Published {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "页面未发布"})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"id": page.ID.Hex(),
|
||
"site_id": page.SiteID,
|
||
"slug": page.Slug,
|
||
"title": page.Title,
|
||
"type": page.Type,
|
||
"content": page.Content,
|
||
"content_mode": page.ContentMode,
|
||
"route_path": page.RoutePath,
|
||
"updated_at": page.UpdatedAt,
|
||
})
|
||
}
|