package handlers import ( "net/http" "strconv" "strings" "time" "ezops/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ServerHandler 服务器处理器 type ServerHandler struct { db *gorm.DB } // NewServerHandler 创建服务器处理器 func NewServerHandler(db *gorm.DB) *ServerHandler { return &ServerHandler{db: db} } // ListServers 获取服务器列表 // @Summary 获取服务器列表 // @Description 获取所有服务器列表 // @Tags 服务器 // @Produce json // @Security Bearer // @Param page query int false "页码" // @Param page_size query int false "每页数量" // @Param keyword query string false "搜索关键词" // @Param status query string false "状态过滤" // @Param region_id query int false "区域ID" // @Success 200 {object} models.Response{data=models.ListResponse} // @Router /servers [get] func (h *ServerHandler) ListServers(c *gin.Context) { var query models.PageQuery if err := c.ShouldBindQuery(&query); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误", }) return } db := h.db.Model(&models.Server{}) // 关键词搜索 if query.Keyword != "" { db = db.Where("hostname LIKE ? OR ip LIKE ? OR public_ip LIKE ?", "%"+query.Keyword+"%", "%"+query.Keyword+"%", "%"+query.Keyword+"%") } // 状态过滤 if status := c.Query("status"); status != "" { db = db.Where("status = ?", status) } // 区域过滤 if regionID := c.Query("region_id"); regionID != "" { db = db.Where("region_id = ?", regionID) } var total int64 db.Count(&total) var servers []models.Server db.Preload("Region").Preload("Cloud"). Offset(query.GetOffset()).Limit(query.GetLimit()). Order("created_at DESC"). Find(&servers) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: models.ListResponse{ List: servers, Total: total, }, }) } // GetServer 获取服务器详情 // @Summary 获取服务器详情 // @Description 获取指定服务器的详细信息 // @Tags 服务器 // @Produce json // @Security Bearer // @Param id path int true "服务器ID" // @Success 200 {object} models.Response{data=models.Server} // @Router /servers/{id} [get] func (h *ServerHandler) GetServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var server models.Server if err := h.db.Preload("Region").Preload("Cloud").First(&server, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{ Code: 404, Message: "服务器不存在", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: server, }) } // CreateServer 创建服务器 // @Summary 创建服务器 // @Description 创建新服务器 // @Tags 服务器 // @Accept json // @Produce json // @Security Bearer // @Param request body models.CreateServerRequest true "创建请求" // @Success 200 {object} models.Response{data=models.Server} // @Router /servers [post] func (h *ServerHandler) CreateServer(c *gin.Context) { var req models.CreateServerRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } server := models.Server{ Hostname: req.Hostname, IP: req.IP, PublicIP: req.PublicIP, Port: req.Port, Username: req.Username, Password: req.Password, SSHKey: req.SSHKey, AuthType: req.AuthType, OS: req.OS, CPU: req.CPU, Memory: req.Memory, Disk: req.Disk, RegionID: req.RegionID, CloudID: req.CloudID, Tags: req.Tags, Description: req.Description, Status: "stopped", } if req.Status != "" { server.Status = req.Status } if server.Port == 0 { server.Port = 22 } if server.Username == "" { server.Username = "root" } if server.AuthType == "" { server.AuthType = "password" } if err := h.db.Create(&server).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "创建服务器失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "创建成功", Data: server, }) } // UpdateServer 更新服务器 // @Summary 更新服务器 // @Description 更新指定服务器信息 // @Tags 服务器 // @Accept json // @Produce json // @Security Bearer // @Param id path int true "服务器ID" // @Param request body models.UpdateServerRequest true "更新请求" // @Success 200 {object} models.Response{data=models.Server} // @Router /servers/{id} [put] func (h *ServerHandler) UpdateServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req models.UpdateServerRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } var server models.Server if err := h.db.First(&server, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{ Code: 404, Message: "服务器不存在", }) return } updates := map[string]interface{}{} if req.Hostname != "" { updates["hostname"] = req.Hostname } if req.PublicIP != "" { updates["public_ip"] = req.PublicIP } if req.Port > 0 { updates["port"] = req.Port } if req.Username != "" { updates["username"] = req.Username } if req.Password != "" { updates["password"] = req.Password } if req.SSHKey != "" { updates["ssh_key"] = req.SSHKey } if req.AuthType != "" { updates["auth_type"] = req.AuthType } if req.OS != "" { updates["os"] = req.OS } if req.CPU > 0 { updates["cpu"] = req.CPU } if req.Memory > 0 { updates["memory"] = req.Memory } if req.Disk > 0 { updates["disk"] = req.Disk } if req.Status != "" { updates["status"] = req.Status } if req.RegionID != nil { updates["region_id"] = *req.RegionID } if req.CloudID != nil { updates["cloud_id"] = *req.CloudID } if req.Tags != "" { updates["tags"] = req.Tags } if req.Description != "" { updates["description"] = req.Description } if err := h.db.Model(&server).Updates(updates).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "更新失败", }) return } h.db.Preload("Region").Preload("Cloud").First(&server, id) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "更新成功", Data: server, }) } // DeleteServer 删除服务器 // @Summary 删除服务器 // @Description 删除指定服务器 // @Tags 服务器 // @Produce json // @Security Bearer // @Param id path int true "服务器ID" // @Success 200 {object} models.Response // @Router /servers/{id} [delete] func (h *ServerHandler) DeleteServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := h.db.Delete(&models.Server{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "删除失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "删除成功", }) } // BatchDeleteServers 批量删除服务器 // @Summary 批量删除服务器 // @Description 批量删除服务器 // @Tags 服务器 // @Accept json // @Produce json // @Security Bearer // @Param request body models.IDsRequest true "删除请求" // @Success 200 {object} models.Response // @Router /servers/batch-delete [post] func (h *ServerHandler) BatchDeleteServers(c *gin.Context) { var req models.IDsRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误", }) return } if err := h.db.Delete(&models.Server{}, req.IDs).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "删除失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "删除成功", }) } // GetServerStats 获取服务器统计 // @Summary 获取服务器统计 // @Description 获取服务器统计数据 // @Tags 服务器 // @Produce json // @Security Bearer // @Success 200 {object} models.Response{data=models.ServerStats} // @Router /servers/stats [get] func (h *ServerHandler) GetServerStats(c *gin.Context) { var stats models.ServerStats h.db.Model(&models.Server{}).Count(&stats.Total) h.db.Model(&models.Server{}).Where("status = ?", "running").Count(&stats.Running) h.db.Model(&models.Server{}).Where("status = ?", "stopped").Count(&stats.Stopped) h.db.Model(&models.Server{}).Where("status = ?", "maintenance").Count(&stats.Maintenance) h.db.Model(&models.Server{}).Where("status = ?", "error").Count(&stats.Error) var avgCPU, avgMemory, avgDisk float64 h.db.Model(&models.Server{}).Select("AVG(cpu_usage)").Scan(&avgCPU) h.db.Model(&models.Server{}).Select("AVG(memory_usage)").Scan(&avgMemory) h.db.Model(&models.Server{}).Select("AVG(disk_usage)").Scan(&avgDisk) stats.AvgCPU = avgCPU stats.AvgMemory = avgMemory stats.AvgDisk = avgDisk c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: stats, }) } // CloudAccountHandler 云账号处理器 type CloudAccountHandler struct { db *gorm.DB } // NewCloudAccountHandler 创建云账号处理器 func NewCloudAccountHandler(db *gorm.DB) *CloudAccountHandler { return &CloudAccountHandler{db: db} } // ListCloudAccounts 获取云账号列表 // @Summary 获取云账号列表 // @Description 获取所有云账号列表 // @Tags 云账号 // @Produce json // @Security Bearer // @Success 200 {object} models.Response{data=models.ListResponse} // @Router /cloud-accounts [get] func (h *CloudAccountHandler) ListCloudAccounts(c *gin.Context) { var accounts []models.CloudAccount h.db.Find(&accounts) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: models.ListResponse{ List: accounts, Total: int64(len(accounts)), }, }) } // createCloudAccountRequest 创建云账号请求(独立 request struct,避免 CloudAccount.AccessKey/SecretKey 的 json:"-" 导致无法反序列化) type createCloudAccountRequest struct { Name string `json:"name"` Provider string `json:"provider"` AccessKey string `json:"access_key"` SecretKey string `json:"secret_key"` MonthlyCost float64 `json:"monthly_cost"` Status string `json:"status"` } // CreateCloudAccount 创建云账号 // @Summary 创建云账号 // @Description 创建新云账号 // @Tags 云账号 // @Accept json // @Produce json // @Security Bearer // @Param request body createCloudAccountRequest true "创建请求" // @Success 200 {object} models.Response{data=models.CloudAccount} // @Router /cloud-accounts [post] func (h *CloudAccountHandler) CreateCloudAccount(c *gin.Context) { var req createCloudAccountRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } if strings.TrimSpace(req.Name) == "" || strings.TrimSpace(req.Provider) == "" { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "账号名称和云平台不能为空", }) return } status := strings.TrimSpace(req.Status) if status == "" { status = "active" } account := models.CloudAccount{ Name: strings.TrimSpace(req.Name), Provider: strings.TrimSpace(req.Provider), AccessKey: req.AccessKey, SecretKey: req.SecretKey, MonthlyCost: req.MonthlyCost, Status: status, } if err := h.db.Create(&account).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "创建失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "创建成功", Data: account, }) } // UpdateCloudAccount 更新云账号 // @Summary 更新云账号 // @Description 更新指定云账号信息 // @Tags 云账号 // @Accept json // @Produce json // @Security Bearer // @Param id path int true "云账号ID" // @Param request body createCloudAccountRequest true "更新请求" // @Success 200 {object} models.Response{data=models.CloudAccount} // @Router /cloud-accounts/{id} [put] func (h *CloudAccountHandler) UpdateCloudAccount(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req createCloudAccountRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } var account models.CloudAccount if err := h.db.First(&account, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{ Code: 404, Message: "云账号不存在", }) return } // 只在提供非空值时更新凭证字段 if strings.TrimSpace(req.Name) != "" { account.Name = strings.TrimSpace(req.Name) } if strings.TrimSpace(req.Provider) != "" { account.Provider = strings.TrimSpace(req.Provider) } if strings.TrimSpace(req.AccessKey) != "" { account.AccessKey = req.AccessKey } if strings.TrimSpace(req.SecretKey) != "" { account.SecretKey = req.SecretKey } if strings.TrimSpace(req.Status) != "" { account.Status = strings.TrimSpace(req.Status) } account.MonthlyCost = req.MonthlyCost if err := h.db.Save(&account).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "更新失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "更新成功", Data: account, }) } // DeleteCloudAccount 删除云账号 // @Summary 删除云账号 // @Description 删除指定云账号 // @Tags 云账号 // @Produce json // @Security Bearer // @Param id path int true "云账号ID" // @Success 200 {object} models.Response // @Router /cloud-accounts/{id} [delete] func (h *CloudAccountHandler) DeleteCloudAccount(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := h.db.Delete(&models.CloudAccount{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "删除失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "删除成功", }) } // DomainHandler 域名处理器 type DomainHandler struct { db *gorm.DB } // NewDomainHandler 创建域名处理器 func NewDomainHandler(db *gorm.DB) *DomainHandler { return &DomainHandler{db: db} } // ListDomains 获取域名列表 // @Summary 获取域名列表 // @Description 获取所有域名列表 // @Tags 域名 // @Produce json // @Security Bearer // @Param page query int false "页码" // @Param page_size query int false "每页数量" // @Param keyword query string false "搜索关键词" // @Success 200 {object} models.Response{data=models.ListResponse} // @Router /domains [get] func (h *DomainHandler) ListDomains(c *gin.Context) { var query models.PageQuery c.ShouldBindQuery(&query) db := h.db.Model(&models.Domain{}) if query.Keyword != "" { db = db.Where("name LIKE ?", "%"+query.Keyword+"%") } var total int64 db.Count(&total) var domains []models.Domain db.Offset(query.GetOffset()).Limit(query.GetLimit()).Find(&domains) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: models.ListResponse{ List: domains, Total: total, }, }) } // CreateDomain 创建域名 // @Summary 创建域名 // @Description 创建新域名 // @Tags 域名 // @Accept json // @Produce json // @Security Bearer // @Param request body models.Domain true "创建请求" // @Success 200 {object} models.Response{data=models.Domain} // @Router /domains [post] func (h *DomainHandler) CreateDomain(c *gin.Context) { var req updateDomainRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } if strings.TrimSpace(req.Name) == "" { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "域名不能为空", }) return } status := req.Status if status == "" { status = "active" } domain := models.Domain{ Name: strings.TrimSpace(req.Name), Registrar: req.Registrar, Status: status, ExpireDate: parseDateStr(req.ExpireDate), DNSProvider: req.DNSProvider, RecordCount: req.RecordCount, SSLEnabled: req.SSLEnabled, SSLExpireDate: parseDateStr(req.SSLExpireDate), } if err := h.db.Create(&domain).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "创建失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "创建成功", Data: domain, }) } // updateDomainRequest 域名创建/更新请求(日期字段用字符串接收,避免 RFC3339 解析失败) type updateDomainRequest struct { Name string `json:"name"` Registrar string `json:"registrar"` Status string `json:"status"` ExpireDate string `json:"expire_date"` DNSProvider string `json:"dns_provider"` RecordCount int `json:"record_count"` SSLEnabled bool `json:"ssl_enabled"` SSLExpireDate string `json:"ssl_expire_date"` } // parseDateStr 将 YYYY-MM-DD 格式字符串解析为 *time.Time,空串返回 nil func parseDateStr(s string) *time.Time { s = strings.TrimSpace(s) if s == "" { return nil } t, err := time.Parse("2006-01-02", s) if err != nil { return nil } return &t } // DeleteDomain 删除域名 // @Summary 删除域名 // @Description 删除指定域名 // @Tags 域名 // @Produce json // @Security Bearer // @Param id path int true "域名ID" // @Success 200 {object} models.Response // @Router /domains/{id} [delete] func (h *DomainHandler) DeleteDomain(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := h.db.Delete(&models.Domain{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "删除失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "删除成功", }) } // UpdateDomain 更新域名 // @Summary 更新域名 // @Description 更新指定域名信息 // @Tags 域名 // @Accept json // @Produce json // @Security Bearer // @Param id path int true "域名ID" // @Param request body updateDomainRequest true "更新请求" // @Success 200 {object} models.Response{data=models.Domain} // @Router /domains/{id} [put] func (h *DomainHandler) UpdateDomain(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req updateDomainRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } var domain models.Domain if err := h.db.First(&domain, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{ Code: 404, Message: "域名不存在", }) return } if strings.TrimSpace(req.Name) != "" { domain.Name = strings.TrimSpace(req.Name) } domain.Registrar = req.Registrar domain.Status = req.Status if domain.Status == "" { domain.Status = "active" } domain.ExpireDate = parseDateStr(req.ExpireDate) domain.DNSProvider = req.DNSProvider domain.RecordCount = req.RecordCount domain.SSLEnabled = req.SSLEnabled domain.SSLExpireDate = parseDateStr(req.SSLExpireDate) if err := h.db.Save(&domain).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{ Code: 500, Message: "更新失败", }) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "更新成功", Data: domain, }) } // ==================== 云平台(Platform / Cloud)==================== // PlatformHandler 云平台处理器 type PlatformHandler struct { db *gorm.DB } func NewPlatformHandler(db *gorm.DB) *PlatformHandler { return &PlatformHandler{db: db} } // platformRequest 云平台创建/更新请求 type platformRequest struct { Name string `json:"name"` Code string `json:"code"` Type string `json:"type"` Status string `json:"status"` Website string `json:"website"` Description string `json:"description"` } // ListPlatforms 获取云平台列表 func (h *PlatformHandler) ListPlatforms(c *gin.Context) { var platforms []models.Cloud h.db.Find(&platforms) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: models.ListResponse{ List: platforms, Total: int64(len(platforms)), }, }) } // CreatePlatform 创建云平台 func (h *PlatformHandler) CreatePlatform(c *gin.Context) { var req platformRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请求参数错误: " + err.Error()}) return } if strings.TrimSpace(req.Name) == "" || strings.TrimSpace(req.Code) == "" { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "平台名称和编码不能为空"}) return } cloudType := strings.TrimSpace(req.Type) if cloudType == "" { cloudType = "public" } status := strings.TrimSpace(req.Status) if status == "" { status = "active" } platform := models.Cloud{ Name: strings.TrimSpace(req.Name), Code: strings.TrimSpace(req.Code), Type: cloudType, Status: status, Website: req.Website, Description: req.Description, } if err := h.db.Create(&platform).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "创建失败,编码可能已存在"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "创建成功", Data: platform}) } // UpdatePlatform 更新云平台 func (h *PlatformHandler) UpdatePlatform(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req platformRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请求参数错误: " + err.Error()}) return } var platform models.Cloud if err := h.db.First(&platform, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "云平台不存在"}) return } if strings.TrimSpace(req.Name) != "" { platform.Name = strings.TrimSpace(req.Name) } if strings.TrimSpace(req.Code) != "" { platform.Code = strings.TrimSpace(req.Code) } if strings.TrimSpace(req.Type) != "" { platform.Type = strings.TrimSpace(req.Type) } if strings.TrimSpace(req.Status) != "" { platform.Status = strings.TrimSpace(req.Status) } platform.Website = req.Website platform.Description = req.Description if err := h.db.Save(&platform).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "更新失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "更新成功", Data: platform}) } // DeletePlatform 删除云平台 func (h *PlatformHandler) DeletePlatform(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := h.db.Delete(&models.Cloud{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功"}) } // ==================== 区域管理(Region)==================== // RegionHandler 区域处理器 type RegionHandler struct { db *gorm.DB } func NewRegionHandler(db *gorm.DB) *RegionHandler { return &RegionHandler{db: db} } // regionRequest 区域创建/更新请求 type regionRequest struct { Name string `json:"name"` Code string `json:"code"` Provider string `json:"provider"` Location string `json:"location"` Status string `json:"status"` Endpoint string `json:"endpoint"` } // ListRegions 获取区域列表 func (h *RegionHandler) ListRegions(c *gin.Context) { var regions []models.Region h.db.Find(®ions) c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "success", Data: models.ListResponse{ List: regions, Total: int64(len(regions)), }, }) } // CreateRegion 创建区域 func (h *RegionHandler) CreateRegion(c *gin.Context) { var req regionRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请求参数错误: " + err.Error()}) return } if strings.TrimSpace(req.Name) == "" || strings.TrimSpace(req.Code) == "" { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "区域名称和编码不能为空"}) return } status := strings.TrimSpace(req.Status) if status == "" { status = "active" } region := models.Region{ Name: strings.TrimSpace(req.Name), Code: strings.TrimSpace(req.Code), Provider: strings.TrimSpace(req.Provider), Location: req.Location, Status: status, Endpoint: req.Endpoint, } if err := h.db.Create(®ion).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "创建失败,编码可能已存在"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "创建成功", Data: region}) } // UpdateRegion 更新区域 func (h *RegionHandler) UpdateRegion(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req regionRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请求参数错误: " + err.Error()}) return } var region models.Region if err := h.db.First(®ion, id).Error; err != nil { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "区域不存在"}) return } if strings.TrimSpace(req.Name) != "" { region.Name = strings.TrimSpace(req.Name) } if strings.TrimSpace(req.Code) != "" { region.Code = strings.TrimSpace(req.Code) } if strings.TrimSpace(req.Provider) != "" { region.Provider = strings.TrimSpace(req.Provider) } region.Location = req.Location if strings.TrimSpace(req.Status) != "" { region.Status = strings.TrimSpace(req.Status) } region.Endpoint = req.Endpoint if err := h.db.Save(®ion).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "更新失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "更新成功", Data: region}) } // DeleteRegion 删除区域 func (h *RegionHandler) DeleteRegion(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := h.db.Delete(&models.Region{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功"}) }