package repository import ( "errors" "time" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "gorm.io/gorm" ) // ErrInvalidPagination 表示分页参数无效 var ErrInvalidPagination = errors.New("invalid pagination parameters: page and pageSize must be positive") // SensorDataListOptions 定义了查询传感器数据列表时的可选参数 type SensorDataListOptions struct { DeviceID *uint SensorType *models.SensorType StartTime *time.Time EndTime *time.Time OrderBy string // 例如 "time DESC" } // SensorDataRepository 定义了与传感器数据相关的数据库操作接口。 type SensorDataRepository interface { Create(sensorData *models.SensorData) error GetLatestSensorDataByDeviceIDAndSensorType(deviceID uint, sensorType models.SensorType) (*models.SensorData, error) // List 支持分页和过滤的列表查询 List(opts SensorDataListOptions, page, pageSize int) ([]models.SensorData, int64, error) } // gormSensorDataRepository 是 SensorDataRepository 的 GORM 实现。 type gormSensorDataRepository struct { db *gorm.DB } // NewGormSensorDataRepository 创建一个新的 SensorDataRepository GORM 实现实例。 func NewGormSensorDataRepository(db *gorm.DB) SensorDataRepository { return &gormSensorDataRepository{db: db} } // Create 将一条新的传感器数据记录插入数据库。 func (r *gormSensorDataRepository) Create(sensorData *models.SensorData) error { return r.db.Create(sensorData).Error } // GetLatestSensorDataByDeviceIDAndSensorType 根据设备ID和传感器类型查询最新的传感器数据。 func (r *gormSensorDataRepository) GetLatestSensorDataByDeviceIDAndSensorType(deviceID uint, sensorType models.SensorType) (*models.SensorData, error) { var sensorData models.SensorData // 增加一个时间范围来缩小查询范围, 从而加快查找速度, 当使用时序数据库时时间范围可以让数据库忽略时间靠前的分片 err := r.db.Where("device_id = ? AND sensor_type = ? AND time >=?", deviceID, sensorType, time.Now().Add(-24*time.Hour)). Order("time DESC"). First(&sensorData).Error return &sensorData, err } // List 实现了分页和过滤查询传感器数据的功能 func (r *gormSensorDataRepository) List(opts SensorDataListOptions, page, pageSize int) ([]models.SensorData, int64, error) { // --- 校验分页参数 --- if page <= 0 || pageSize <= 0 { return nil, 0, ErrInvalidPagination } var results []models.SensorData var total int64 query := r.db.Model(&models.SensorData{}) // --- 应用过滤条件 --- if opts.DeviceID != nil { query = query.Where("device_id = ?", *opts.DeviceID) } if opts.SensorType != nil { query = query.Where("sensor_type = ?", *opts.SensorType) } if opts.StartTime != nil { query = query.Where("time >= ?", *opts.StartTime) } if opts.EndTime != nil { query = query.Where("time <= ?", *opts.EndTime) } // --- 计算总数 --- if err := query.Count(&total).Error; err != nil { return nil, 0, err } // --- 应用排序条件 --- orderBy := "time DESC" // 默认排序 if opts.OrderBy != "" { orderBy = opts.OrderBy } query = query.Order(orderBy) // --- 分页 --- offset := (page - 1) * pageSize err := query.Limit(pageSize).Offset(offset).Find(&results).Error return results, total, err }