package controller import ( "net/http" "time" "ezops/model" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // SessionCommandHandler 会话命令审计处理器 // Logan.Li type SessionCommandHandler struct { db *gorm.DB } // NewSessionCommandHandler 创建会话命令审计处理器 func NewSessionCommandHandler(db *gorm.DB) *SessionCommandHandler { return &SessionCommandHandler{db: db} } // ListSessionCommands 会话命令列表 // GET /api/v1/session-commands?session_id=&username=&page=&page_size= func (h *SessionCommandHandler) ListSessionCommands(c *gin.Context) { var req model.SessionCommandQuery if err := c.ShouldBindQuery(&req); err != nil { c.JSON(http.StatusBadRequest, model.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(&model.SessionCommand{}) if req.SessionID > 0 { query = query.Where("session_id = ?", req.SessionID) } if req.Username != "" { query = query.Where("username LIKE ?", "%"+req.Username+"%") } if req.ServerID > 0 { query = query.Where("server_id = ?", req.ServerID) } if req.Command != "" { query = query.Where("command LIKE ?", "%"+req.Command+"%") } if req.StartDate != "" { if t, err := time.ParseInLocation("2006-01-02", req.StartDate, time.Local); err == nil { query = query.Where("timestamp >= ?", t) } } if req.EndDate != "" { if t, err := time.ParseInLocation("2006-01-02", req.EndDate, time.Local); err == nil { query = query.Where("timestamp < ?", t.Add(24*time.Hour)) } } var total int64 if err := query.Count(&total).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{Code: 500, Message: "查询失败"}) return } // 联表带出会话录制大小,前端可判断能否回放 // Logan.Li var items []model.SessionCommandItem listQuery := h.db.Table("sys_session_commands AS sc"). Select("sc.*, COALESCE(ts.record_size, rs.record_size, 0) AS session_record_size"). Joins("LEFT JOIN sys_terminal_sessions AS ts ON ts.id = sc.session_id AND COALESCE(sc.session_type, 'terminal') = 'terminal'"). Joins("LEFT JOIN sys_rdp_sessions AS rs ON rs.id = sc.session_id AND sc.session_type = 'rdp'") if req.SessionID > 0 { listQuery = listQuery.Where("sc.session_id = ?", req.SessionID) } if req.Username != "" { listQuery = listQuery.Where("sc.username LIKE ?", "%"+req.Username+"%") } if req.ServerID > 0 { listQuery = listQuery.Where("sc.server_id = ?", req.ServerID) } if req.Command != "" { listQuery = listQuery.Where("sc.command LIKE ?", "%"+req.Command+"%") } if req.StartDate != "" { if t, err := time.ParseInLocation("2006-01-02", req.StartDate, time.Local); err == nil { listQuery = listQuery.Where("sc.timestamp >= ?", t) } } if req.EndDate != "" { if t, err := time.ParseInLocation("2006-01-02", req.EndDate, time.Local); err == nil { listQuery = listQuery.Where("sc.timestamp < ?", t.Add(24*time.Hour)) } } if err := listQuery.Order("sc.id DESC"). Offset((req.Page - 1) * req.PageSize). Limit(req.PageSize). Scan(&items).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{Code: 500, Message: "查询失败"}) return } c.JSON(http.StatusOK, model.Response{Code: 200, Data: model.ListResponse{ List: items, Total: total, }}) }