package store import ( "strings" ) // OpLog 操作日志。 type OpLog struct { ID int64 OperatorID int64 OperatorName string Action string Entity string EntityID int64 Summary string Detail string IP string CreatedAt string } // Log 写一条操作日志。 func (db *DB) Log(l OpLog) error { _, err := db.sql.Exec(`INSERT INTO op_logs(operator_id,operator_name,action,entity,entity_id,summary,detail,ip,created_at) VALUES(?,?,?,?,?,?,?,?,?)`, nullIfZero(l.OperatorID), l.OperatorName, l.Action, l.Entity, nullIfZero(l.EntityID), l.Summary, l.Detail, l.IP, nowStamp()) return err } func nullIfZero(v int64) any { if v == 0 { return nil } return v } // ListLogs 分页查询日志。 func (db *DB) ListLogs(q string, limit, offset int) ([]OpLog, int, error) { where := "1=1" args := []any{} if q = strings.TrimSpace(q); q != "" { like := "%" + q + "%" where = "(summary LIKE ? OR action LIKE ? OR operator_name LIKE ? OR entity LIKE ?)" args = append(args, like, like, like, like) } var total int if err := db.sql.QueryRow(`SELECT COUNT(*) FROM op_logs WHERE `+where, args...).Scan(&total); err != nil { return nil, 0, err } rows, err := db.sql.Query(`SELECT id,IFNULL(operator_id,0),operator_name,action,entity,IFNULL(entity_id,0),summary,detail,ip,created_at FROM op_logs WHERE `+where+` ORDER BY id DESC LIMIT ? OFFSET ?`, append(args, limit, offset)...) if err != nil { return nil, 0, err } defer rows.Close() out := []OpLog{} for rows.Next() { var l OpLog if err := rows.Scan(&l.ID, &l.OperatorID, &l.OperatorName, &l.Action, &l.Entity, &l.EntityID, &l.Summary, &l.Detail, &l.IP, &l.CreatedAt); err != nil { return nil, 0, err } out = append(out, l) } return out, total, rows.Err() } // LogCount 日志总数。 func (db *DB) LogCount() (int, error) { var n int err := db.sql.QueryRow(`SELECT COUNT(*) FROM op_logs`).Scan(&n) return n, err }