package handlers import ( "context" "net/http" "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" ) // GetSites 站点列表 func GetSites(c *gin.Context) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() coll := config.GetDB(config.DBName).Collection("sites") opts := options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}) cursor, err := coll.Find(ctx, bson.M{}, opts) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } defer cursor.Close(ctx) var list []models.Site if err = cursor.All(ctx, &list); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } total, _ := coll.CountDocuments(ctx, bson.M{}) c.JSON(http.StatusOK, gin.H{"list": list, "total": total}) } // GetSiteByID 单个站点 func GetSiteByID(c *gin.Context) { idStr := c.Param("site_id") oid, err := bson.ObjectIDFromHex(idStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "无效的站点ID"}) return } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() var site models.Site err = config.GetDB(config.DBName).Collection("sites").FindOne(ctx, bson.M{"_id": oid}).Decode(&site) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "站点不存在"}) return } c.JSON(http.StatusOK, site) } // CreateSiteInput 创建站点 type CreateSiteInput struct { Name string `json:"name" binding:"required"` Domain string `json:"domain"` Description string `json:"description"` } // CreateSite 创建站点 func CreateSite(c *gin.Context) { var input CreateSiteInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "请填写站点名称"}) return } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() coll := config.GetDB(config.DBName).Collection("sites") doc := bson.M{ "name": input.Name, "domain": input.Domain, "description": input.Description, "created_at": time.Now().Format(time.RFC3339), } res, err := coll.InsertOne(ctx, doc) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"id": res.InsertedID, "message": "创建成功"}) } // UpdateSiteInput 更新站点 type UpdateSiteInput struct { Name *string `json:"name"` Domain *string `json:"domain"` Description *string `json:"description"` } // UpdateSite 更新站点 func UpdateSite(c *gin.Context) { idStr := c.Param("site_id") oid, err := bson.ObjectIDFromHex(idStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "无效的站点ID"}) return } var input UpdateSiteInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } set := bson.M{} if input.Name != nil { set["name"] = *input.Name } if input.Domain != nil { set["domain"] = *input.Domain } if input.Description != nil { set["description"] = *input.Description } if len(set) == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "无有效更新字段"}) return } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _, err = config.GetDB(config.DBName).Collection("sites").UpdateOne(ctx, bson.M{"_id": oid}, bson.M{"$set": set}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "更新成功"}) } // DeleteSite 删除站点 func DeleteSite(c *gin.Context) { idStr := c.Param("site_id") oid, err := bson.ObjectIDFromHex(idStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "无效的站点ID"}) return } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() db := config.GetDB(config.DBName) _, err = db.Collection("sites").DeleteOne(ctx, bson.M{"_id": oid}) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } db.Collection("pages").DeleteMany(ctx, bson.M{"site_id": idStr}) db.Collection("site_assets").DeleteMany(ctx, bson.M{"site_id": idStr}) c.JSON(http.StatusOK, gin.H{"message": "删除成功"}) }