package dao import ( "context" "time" "gitee.com/red-future---jilin-g/common/log/consts" "gitee.com/red-future---jilin-g/common/log/model/dto" "gitee.com/red-future---jilin-g/common/log/model/entity" "gitee.com/red-future---jilin-g/common/mongo" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo/options" ) type log struct{} // Log 日志数据访问对象 var Log = &log{} // Create 创建日志记录 func (d *log) Create(ctx context.Context, log *entity.OperationLog) error { _, err := mongo.DB().Insert(ctx, []interface{}{log}, consts.OperationLogCollection) return err } // CreateBatch 批量创建日志记录 func (d *log) CreateBatch(ctx context.Context, logs []*entity.OperationLog) error { if len(logs) == 0 { return nil } documents := make([]interface{}, len(logs)) for i, log := range logs { documents[i] = log } _, err := mongo.DB().Insert(ctx, documents, consts.OperationLogCollection) return err } // GetByID 根据ID获取日志 func (d *log) GetByID(ctx context.Context, id string) (*entity.OperationLog, error) { objectID, err := bson.ObjectIDFromHex(id) if err != nil { return nil, err } filter := bson.M{"_id": objectID} var log entity.OperationLog err = mongo.DB().FindOne(ctx, filter, &log, consts.OperationLogCollection) if err != nil { return nil, err } return &log, nil } // List 查询日志列表(通用方法,通过filter动态拼接查询条件) func (d *log) List(ctx context.Context, filter *dto.ListLogsReq, sortFields ...string) ([]*entity.OperationLog, int64, error) { bsonFilter := buildFilter(filter) total, err := mongo.DB().Count(ctx, bsonFilter, consts.OperationLogCollection) if err != nil { return nil, 0, err } var findOptions []options.Lister[options.FindOptions] if filter.PageNum > 0 && filter.PageSize > 0 { findOptions = append(findOptions, options.Find().SetSkip(int64((filter.PageNum-1)*filter.PageSize)).SetLimit(int64(filter.PageSize))) } if len(sortFields) > 0 { sort := bson.D{} for _, field := range sortFields { var order int if len(field) > 0 && field[0] == '-' { order = -1 field = field[1:] } else { order = 1 } sort = append(sort, bson.E{Key: field, Value: order}) } findOptions = append(findOptions, options.Find().SetSort(sort)) } else { findOptions = append(findOptions, options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})) } var logs []*entity.OperationLog _, err = mongo.DB().Find(ctx, bsonFilter, &logs, consts.OperationLogCollection, nil, nil) if err != nil { return nil, 0, err } return logs, total, nil } // buildFilter 构建MongoDB查询过滤器 func buildFilter(filter interface{}) bson.M { bsonFilter := make(bson.M) // 从ListLogsReq结构体中提取字段值 if req, ok := filter.(*dto.ListLogsReq); ok { if req.ServiceName != "" { bsonFilter["service_name"] = req.ServiceName } if req.Collection != "" { bsonFilter["collection"] = req.Collection } if req.CollectionID != "" { bsonFilter["collection_id"] = req.CollectionID } if req.Operation != "" { bsonFilter["operation"] = req.Operation } // 处理时间范围字段 if req.StartTime != "" || req.EndTime != "" { timeFilter := bson.M{} if req.StartTime != "" { if startTime, err := time.Parse("2006-01-02 15:04:05", req.StartTime); err == nil { timeFilter["$gte"] = startTime } } if req.EndTime != "" { if endTime, err := time.Parse("2006-01-02 15:04:05", req.EndTime); err == nil { timeFilter["$lte"] = endTime } } if len(timeFilter) > 0 { bsonFilter["createdAt"] = timeFilter } } } return bsonFilter }