package handlers import ( "net/http" "strconv" "tonav-go/database" "tonav-go/models" "github.com/gin-gonic/gin" ) // API 响应结构 type Response struct { Success bool `json:"success"` Message string `json:"message"` Data interface{} `json:"data,omitempty"` } // GetServices 获取所有服务 func GetServices(c *gin.Context) { var services []models.Service database.DB.Order("category_id asc, sort_order desc").Find(&services) c.JSON(http.StatusOK, Response{Success: true, Data: services}) } // SaveService 创建或更新服务 func SaveService(c *gin.Context) { var service models.Service if err := c.ShouldBindJSON(&service); err != nil { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "请求数据格式错误: " + err.Error()}) return } // 验证必填字段 if service.Name == "" { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "服务名称不能为空"}) return } if service.URL == "" { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "服务地址不能为空"}) return } // 如果 URL 路径中有 id,使用路径参数 if idStr := c.Param("id"); idStr != "" { id, err := strconv.ParseUint(idStr, 10, 32) if err == nil { service.ID = uint(id) } } if service.ID > 0 { // 更新时只更新指定字段,避免覆盖 created_at 等 result := database.DB.Model(&models.Service{}).Where("id = ?", service.ID).Updates(map[string]interface{}{ "name": service.Name, "url": service.URL, "description": service.Description, "icon": service.Icon, "category_id": service.CategoryID, "tags": service.Tags, "is_enabled": service.IsEnabled, "sort_order": service.SortOrder, "health_check_url": service.HealthCheckURL, "health_check_enabled": service.HealthCheckEnabled, }) if result.Error != nil { c.JSON(http.StatusInternalServerError, Response{Success: false, Message: "更新失败: " + result.Error.Error()}) return } } else { if err := database.DB.Create(&service).Error; err != nil { c.JSON(http.StatusInternalServerError, Response{Success: false, Message: "创建失败: " + err.Error()}) return } } c.JSON(http.StatusOK, Response{Success: true, Message: "保存成功", Data: service}) } // DeleteService 删除服务 func DeleteService(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "缺少服务ID"}) return } if err := database.DB.Delete(&models.Service{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, Response{Success: false, Message: "删除失败"}) return } c.JSON(http.StatusOK, Response{Success: true, Message: "删除成功"}) } // GetCategories 获取所有分类 func GetCategories(c *gin.Context) { var categories []models.Category database.DB.Order("sort_order desc").Find(&categories) c.JSON(http.StatusOK, Response{Success: true, Data: categories}) } // SaveCategory 保存分类 func SaveCategory(c *gin.Context) { var category models.Category if err := c.ShouldBindJSON(&category); err != nil { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "请求数据格式错误: " + err.Error()}) return } if category.Name == "" { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "分类名称不能为空"}) return } // 如果 URL 路径中有 id if idStr := c.Param("id"); idStr != "" { id, err := strconv.ParseUint(idStr, 10, 32) if err == nil { category.ID = uint(id) } } if category.ID > 0 { result := database.DB.Model(&models.Category{}).Where("id = ?", category.ID).Updates(map[string]interface{}{ "name": category.Name, "sort_order": category.SortOrder, }) if result.Error != nil { c.JSON(http.StatusInternalServerError, Response{Success: false, Message: "更新失败: " + result.Error.Error()}) return } } else { if err := database.DB.Create(&category).Error; err != nil { c.JSON(http.StatusInternalServerError, Response{Success: false, Message: "创建失败: " + err.Error()}) return } } c.JSON(http.StatusOK, Response{Success: true, Message: "保存成功", Data: category}) } // DeleteCategory 删除分类 func DeleteCategory(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "缺少分类ID"}) return } // 检查是否有服务属于该分类 var count int64 database.DB.Model(&models.Service{}).Where("category_id = ?", id).Count(&count) if count > 0 { c.JSON(http.StatusBadRequest, Response{Success: false, Message: "该分类下仍有服务,无法删除"}) return } database.DB.Delete(&models.Category{}, id) c.JSON(http.StatusOK, Response{Success: true, Message: "删除成功"}) }