package handlers import ( "database/sql" "net/http" "strconv" "github.com/gin-gonic/gin" "lan-manager/server/db" "lan-manager/server/models" ) type LogHandler struct{} func NewLogHandler() *LogHandler { return &LogHandler{} } func (h *LogHandler) List(c *gin.Context) { action := c.Query("action") date := c.Query("date") search := c.Query("search") page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 20 } offset := (page - 1) * pageSize // Build count query countQuery := `SELECT COUNT(*) FROM operation_logs WHERE 1=1` countArgs := []interface{}{} // Build data query query := `SELECT id, action, entity_type, entity_id, entity_name, old_value, new_value, source_ip, username, created_at FROM operation_logs WHERE 1=1` args := []interface{}{} if action != "" { countQuery += ` AND action = ?` query += ` AND action = ?` countArgs = append(countArgs, action) args = append(args, action) } if date != "" { countQuery += ` AND DATE(created_at) = ?` query += ` AND DATE(created_at) = ?` countArgs = append(countArgs, date) args = append(args, date) } if search != "" { searchPattern := "%" + search + "%" countQuery += ` AND (action LIKE ? OR entity_type LIKE ? OR entity_name LIKE ? OR username LIKE ? OR old_value LIKE ? OR new_value LIKE ?)` query += ` AND (action LIKE ? OR entity_type LIKE ? OR entity_name LIKE ? OR username LIKE ? OR old_value LIKE ? OR new_value LIKE ?)` countArgs = append(countArgs, searchPattern, searchPattern, searchPattern, searchPattern, searchPattern, searchPattern) args = append(args, searchPattern, searchPattern, searchPattern, searchPattern, searchPattern, searchPattern) } // Get total count var total int if err := db.DB.QueryRow(countQuery, countArgs...).Scan(&total); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // Get data with pagination query += ` ORDER BY created_at DESC LIMIT ? OFFSET ?` args = append(args, pageSize, offset) rows, err := db.DB.Query(query, args...) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } defer rows.Close() logs := []models.OperationLog{} for rows.Next() { var l models.OperationLog var eid sql.NullInt64 if err := rows.Scan(&l.ID, &l.Action, &l.EntityType, &eid, &l.EntityName, &l.OldValue, &l.NewValue, &l.SourceIP, &l.Username, &l.CreatedAt); err == nil { if eid.Valid { l.EntityID = &eid.Int64 } logs = append(logs, l) } } c.JSON(http.StatusOK, gin.H{ "list": logs, "total": total, "page": page, "page_size": pageSize, }) }