Files
web/server/handlers/web_routes.go

151 lines
3.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
})
}