package handlers import ( "net/http" "strconv" "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, }) }