// Package handlers_v2 provides thin HTTP handlers that delegate to service layer. // This is the refactored version — handlers contain ONLY HTTP concerns: // parse request → call service → return HTTP response. package controller import ( "net/http" "strconv" "ezops/dto" "ezops/model" "ezops/service" "ezops/utils" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ━━━ Server Handler (v2 thin) ━━━━━━━━━━━━━━━━━━━━━━━━━━ // ServerHandlerV2 服务器处理器 — thin handler,委托给 ServerService type ServerHandlerV2 struct { svc *service.ServerService db *gorm.DB // retained for audit logging until audit is extracted } func NewServerHandlerV2(svc *service.ServerService, db *gorm.DB) *ServerHandlerV2 { return &ServerHandlerV2{svc: svc, db: db} } func (h *ServerHandlerV2) recordAudit(c *gin.Context, action, resource, resourceID string, status int, errMsg string) { userID, _ := c.Get("userID") username, _ := c.Get("username") uid, _ := userID.(uint) uname, _ := username.(string) h.db.Create(&model.AuditLog{ UserID: &uid, Username: uname, IP: c.ClientIP(), UserAgent: c.Request.UserAgent(), Module: "server", Action: action, Resource: resource, ResourceID: resourceID, Status: status, Error: errMsg, }) } func (h *ServerHandlerV2) ListServers(c *gin.Context) { var query model.PageQuery if err := c.ShouldBindQuery(&query); err != nil { utils.BadRequest(c, "请求参数错误") return } status := c.Query("status") regionID := c.Query("region_id") list, total, err := h.svc.ListServers(query.Keyword, status, regionID, query.Page, query.PageSize) if err != nil { utils.InternalError(c, "查询失败") return } utils.ListResponse(c, list, total) } func (h *ServerHandlerV2) GetServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) server, err := h.svc.GetServer(uint(id)) if err != nil { utils.NotFound(c, "服务器不存在") return } utils.OK(c, server) } func (h *ServerHandlerV2) CreateServer(c *gin.Context) { var req dto.CreateServerRequest if err := c.ShouldBindJSON(&req); err != nil { utils.BadRequest(c, "请求参数错误: "+err.Error()) return } server, err := h.svc.CreateServer(&req) if err != nil { utils.InternalError(c, "创建失败: "+err.Error()) return } h.recordAudit(c, "create", server.Hostname+" ("+server.IP+")", strconv.Itoa(int(server.ID)), 1, "") utils.OK(c, server) } func (h *ServerHandlerV2) UpdateServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req dto.UpdateServerRequest if err := c.ShouldBindJSON(&req); err != nil { utils.BadRequest(c, "请求参数错误: "+err.Error()) return } if err := h.svc.UpdateServer(uint(id), &req); err != nil { utils.InternalError(c, "更新失败: "+err.Error()) return } server, _ := h.svc.GetServer(uint(id)) h.recordAudit(c, "update", server.Hostname+" ("+server.IP+")", strconv.Itoa(int(server.ID)), 1, "") utils.OK(c, server) } func (h *ServerHandlerV2) DeleteServer(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) server, err := h.svc.GetServer(uint(id)) if err != nil { utils.NotFound(c, "服务器不存在") return } // 清理关联数据 h.db.Unscoped().Where("hostname = ?", server.Hostname).Delete(&model.AgentReport{}) h.db.Unscoped().Where("hostname = ?", server.Hostname).Delete(&model.MetricsAggregate{}) if err := h.svc.DeleteServer(uint(id)); err != nil { utils.InternalError(c, "删除失败") return } h.recordAudit(c, "delete", server.Hostname+" ("+server.IP+")", strconv.Itoa(int(server.ID)), 1, "") c.JSON(http.StatusOK, model.Response{Code: 200, Message: "服务器已彻底删除"}) } func (h *ServerHandlerV2) GetServerStats(c *gin.Context) { stats, err := h.svc.GetDashboardStats() if err != nil { utils.InternalError(c, "获取统计失败") return } utils.OK(c, stats.ServerStats) } // BatchCreateServers / BatchDeleteServers — 暂时保留原始逻辑(复杂批量操作待后续迁移) func (h *ServerHandlerV2) BatchCreateServers(c *gin.Context) { // 暂时委托给原始 handler 逻辑(从 server.go 复制) var servers []model.Server if err := c.ShouldBindJSON(&servers); err != nil { utils.BadRequest(c, "请求参数错误") return } for i := range servers { if servers[i].Port == 0 { servers[i].Port = 22 } if servers[i].Username == "" { servers[i].Username = "root" } if servers[i].Status == "" { servers[i].Status = "stopped" } } if err := h.db.Create(&servers).Error; err != nil { utils.InternalError(c, "批量创建失败") return } utils.OK(c, servers) } func (h *ServerHandlerV2) BatchDeleteServers(c *gin.Context) { var ids []uint if err := c.ShouldBindJSON(&ids); err != nil { utils.BadRequest(c, "请求参数错误") return } // 清理关联数据 for _, id := range ids { var s model.Server if err := h.db.First(&s, id).Error; err == nil { h.db.Unscoped().Where("hostname = ?", s.Hostname).Delete(&model.AgentReport{}) h.db.Unscoped().Where("hostname = ?", s.Hostname).Delete(&model.MetricsAggregate{}) } } h.db.Unscoped().Delete(&model.Server{}, ids) utils.OK(c, gin.H{"deleted": len(ids)}) }