package handlers import ( "net/http" "strconv" "ezops/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // TerminalSessionHandler 终端会话审计处理器 // Logan.Li type TerminalSessionHandler struct { db *gorm.DB } // NewTerminalSessionHandler 创建终端会话审计处理器 func NewTerminalSessionHandler(db *gorm.DB) *TerminalSessionHandler { return &TerminalSessionHandler{db: db} } // ListTerminalSessions 终端会话列表 // GET /api/v1/terminal-sessions?server_id=&username=&status=&page=&page_size= func (h *TerminalSessionHandler) ListTerminalSessions(c *gin.Context) { var req models.TerminalSessionQuery if err := c.ShouldBindQuery(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: err.Error()}) return } if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 { req.PageSize = 20 } query := h.db.Model(&models.TerminalSession{}) if req.ServerID > 0 { query = query.Where("server_id = ?", req.ServerID) } if req.Username != "" { query = query.Where("username LIKE ?", "%"+req.Username+"%") } if req.Status != "" { query = query.Where("status = ?", req.Status) } var total int64 if err := query.Count(&total).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"}) return } var sessions []models.TerminalSession if err := query.Order("id DESC"). Offset((req.Page - 1) * req.PageSize). Limit(req.PageSize). Find(&sessions).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Data: models.ListResponse{ List: sessions, Total: total, }}) } // GetTerminalSession 终端会话详情 // GET /api/v1/terminal-sessions/:id func (h *TerminalSessionHandler) GetTerminalSession(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效的会话ID"}) return } var session models.TerminalSession if err := h.db.First(&session, id).Error; err != nil { if err == gorm.ErrRecordNotFound { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "会话不存在"}) return } c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Data: session}) } // GetTerminalRecord 终端会话录制数据(用于回放) // GET /api/v1/terminal-sessions/:id/record func (h *TerminalSessionHandler) GetTerminalRecord(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效的会话ID"}) return } var session models.TerminalSession if err := h.db.First(&session, id).Error; err != nil { if err == gorm.ErrRecordNotFound { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "会话不存在"}) return } c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Data: session.RecordData}) } // DeleteTerminalSession 删除终端会话记录 // DELETE /api/v1/terminal-sessions/:id func (h *TerminalSessionHandler) DeleteTerminalSession(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效的会话ID"}) return } if err := h.db.Delete(&models.TerminalSession{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功"}) } // BatchDeleteTerminalSessions 批量删除终端会话记录 // POST /api/v1/terminal-sessions/batch-delete func (h *TerminalSessionHandler) BatchDeleteTerminalSessions(c *gin.Context) { var req models.IDsRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效的请求参数"}) return } result := h.db.Where("id IN ?", req.IDs).Delete(&models.TerminalSession{}) if result.Error != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功", Data: gin.H{"deleted": result.RowsAffected}}) }