// Package eventlog 提供操作日志(事件审计)的统一写入与查询封装。 // 参照 MES(bj_power_mes/internal/eventlog)模型,按 WMS 约定落地: // - 表 event_log,时间字段为 Int64 unix 秒 // - 写库失败只记服务日志,绝不阻断业务 package eventlog import ( "context" "log/slog" "time" "bj_power_wms/ent" "bj_power_wms/ent/eventlog" ) // Writer 操作日志写入/查询器 type Writer struct { client *ent.Client } // NewWriter 构造 Writer func NewWriter(client *ent.Client) *Writer { return &Writer{client: client} } // Write 记录一条操作日志。 // eventType 事件类型(如 user.create / inbound.create / auth.login), // operator 操作人(用户名),entityType/entityId 描述业务对象,description 中文描述,payload 扩展负载。 func (w *Writer) Write(ctx context.Context, eventType, operator, entityType, entityID, description string, payload map[string]any) { if ctx == nil { ctx = context.Background() } b := w.client.EventLog.Create(). SetEventType(eventType). SetOperator(operator). SetEntityType(entityType). SetEntityID(entityID). SetDescription(description). SetCreatedAt(time.Now().Unix()) if len(payload) > 0 { b.SetPayload(payload) } if _, err := b.Save(ctx); err != nil { slog.Warn("操作日志写入失败", "eventType", eventType, "error", err.Error()) } } // Query 分页查询操作日志。空参数不参与过滤;from/to 为 Int64 unix 秒(含边界)。 func (w *Writer) Query(ctx context.Context, eventType, operator, entityType string, from, to int64, page, pageSize int) ([]*ent.EventLog, int, error) { q := w.client.EventLog.Query() if eventType != "" { // 事件类型按前缀匹配(如 user.* / inbound.* 族),便于按业务域筛选 q = q.Where(eventlog.EventTypeHasPrefix(eventType)) } if operator != "" { q = q.Where(eventlog.OperatorEQ(operator)) } if entityType != "" { q = q.Where(eventlog.EntityTypeEQ(entityType)) } if from > 0 { q = q.Where(eventlog.CreatedAtGTE(from)) } if to > 0 { q = q.Where(eventlog.CreatedAtLTE(to)) } total, err := q.Count(ctx) if err != nil { return nil, 0, err } if page < 1 { page = 1 } if pageSize < 1 { pageSize = 20 } list, err := q. Order(ent.Desc(eventlog.FieldCreatedAt), ent.Desc(eventlog.FieldID)). Offset((page - 1) * pageSize). Limit(pageSize). All(ctx) if err != nil { return nil, 0, err } return list, total, nil }