209 lines
6.8 KiB
Go
209 lines
6.8 KiB
Go
package repository
|
||
|
||
import (
|
||
"time"
|
||
|
||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// PigBatchRepository 定义了与猪批次相关的数据库操作接口
|
||
type PigBatchRepository interface {
|
||
CreatePigBatch(batch *models.PigBatch) (*models.PigBatch, error)
|
||
CreatePigBatchTx(tx *gorm.DB, batch *models.PigBatch) (*models.PigBatch, error)
|
||
GetPigBatchByID(id uint) (*models.PigBatch, error)
|
||
GetPigBatchByIDTx(tx *gorm.DB, id uint) (*models.PigBatch, error)
|
||
// UpdatePigBatch 更新一个猪批次,返回更新后的批次、受影响的行数和错误
|
||
UpdatePigBatch(batch *models.PigBatch) (*models.PigBatch, int64, error)
|
||
// DeletePigBatch 根据ID删除一个猪批次,返回受影响的行数和错误
|
||
DeletePigBatch(id uint) (int64, error)
|
||
DeletePigBatchTx(tx *gorm.DB, id uint) (int64, error)
|
||
ListPigBatches(isActive *bool) ([]*models.PigBatch, error)
|
||
|
||
// ListWeighingBatches 支持分页和过滤的批次称重列表查询
|
||
ListWeighingBatches(opts WeighingBatchListOptions, page, pageSize int) ([]models.WeighingBatch, int64, error)
|
||
|
||
// ListWeighingRecords 支持分页和过滤的单次称重记录列表查询
|
||
ListWeighingRecords(opts WeighingRecordListOptions, page, pageSize int) ([]models.WeighingRecord, int64, error)
|
||
}
|
||
|
||
// WeighingBatchListOptions 定义了查询批次称重记录时的可选参数
|
||
type WeighingBatchListOptions struct {
|
||
PigBatchID *uint
|
||
StartTime *time.Time // 基于 weighing_time 字段
|
||
EndTime *time.Time // 基于 weighing_time 字段
|
||
OrderBy string // 例如 "weighing_time asc"
|
||
}
|
||
|
||
// WeighingRecordListOptions 定义了查询单次称重记录时的可选参数
|
||
type WeighingRecordListOptions struct {
|
||
WeighingBatchID *uint
|
||
PenID *uint
|
||
OperatorID *uint
|
||
StartTime *time.Time // 基于 weighing_time 字段
|
||
EndTime *time.Time // 基于 weighing_time 字段
|
||
OrderBy string // 例如 "weighing_time asc"
|
||
}
|
||
|
||
// gormPigBatchRepository 是 PigBatchRepository 的 GORM 实现
|
||
type gormPigBatchRepository struct {
|
||
db *gorm.DB
|
||
}
|
||
|
||
// NewGormPigBatchRepository 创建一个新的 PigBatchRepository GORM 实现实例
|
||
func NewGormPigBatchRepository(db *gorm.DB) PigBatchRepository {
|
||
return &gormPigBatchRepository{db: db}
|
||
}
|
||
|
||
// CreatePigBatch 创建一个新的猪批次
|
||
func (r *gormPigBatchRepository) CreatePigBatch(batch *models.PigBatch) (*models.PigBatch, error) {
|
||
return r.CreatePigBatchTx(r.db, batch)
|
||
}
|
||
|
||
// CreatePigBatchTx 在指定的事务中,创建一个新的猪批次
|
||
func (r *gormPigBatchRepository) CreatePigBatchTx(tx *gorm.DB, batch *models.PigBatch) (*models.PigBatch, error) {
|
||
if err := tx.Create(batch).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
return batch, nil
|
||
}
|
||
|
||
// GetPigBatchByID 根据ID获取单个猪批次
|
||
func (r *gormPigBatchRepository) GetPigBatchByID(id uint) (*models.PigBatch, error) {
|
||
return r.GetPigBatchByIDTx(r.db, id)
|
||
}
|
||
|
||
// UpdatePigBatch 更新一个猪批次
|
||
func (r *gormPigBatchRepository) UpdatePigBatch(batch *models.PigBatch) (*models.PigBatch, int64, error) {
|
||
result := r.db.Model(&models.PigBatch{}).Where("id = ?", batch.ID).Updates(batch)
|
||
if result.Error != nil {
|
||
return nil, 0, result.Error
|
||
}
|
||
// 返回更新后的批次、受影响的行数和错误
|
||
return batch, result.RowsAffected, nil
|
||
}
|
||
|
||
// DeletePigBatch 根据ID删除一个猪批次 (GORM 会执行软删除)
|
||
func (r *gormPigBatchRepository) DeletePigBatch(id uint) (int64, error) {
|
||
return r.DeletePigBatchTx(r.db, id)
|
||
}
|
||
|
||
func (r *gormPigBatchRepository) DeletePigBatchTx(tx *gorm.DB, id uint) (int64, error) {
|
||
result := tx.Delete(&models.PigBatch{}, id)
|
||
if result.Error != nil {
|
||
return 0, result.Error
|
||
}
|
||
// 返回受影响的行数和错误
|
||
return result.RowsAffected, nil
|
||
}
|
||
|
||
// ListPigBatches 批量查询猪批次,支持根据 IsActive 筛选
|
||
func (r *gormPigBatchRepository) ListPigBatches(isActive *bool) ([]*models.PigBatch, error) {
|
||
var batches []*models.PigBatch
|
||
query := r.db.Model(&models.PigBatch{})
|
||
|
||
if isActive != nil {
|
||
if *isActive {
|
||
// 查询活跃的批次:状态不是已出售或已归档
|
||
query = query.Where("status NOT IN (?) ", []models.PigBatchStatus{models.BatchStatusSold, models.BatchStatusArchived})
|
||
} else {
|
||
// 查询非活跃的批次:状态是已出售或已归档
|
||
query = query.Where("status IN (?) ", []models.PigBatchStatus{models.BatchStatusSold, models.BatchStatusArchived})
|
||
}
|
||
}
|
||
|
||
if err := query.Find(&batches).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
return batches, nil
|
||
}
|
||
|
||
// GetPigBatchByIDTx 在指定的事务中,通过ID获取单个猪批次
|
||
func (r *gormPigBatchRepository) GetPigBatchByIDTx(tx *gorm.DB, id uint) (*models.PigBatch, error) {
|
||
var batch models.PigBatch
|
||
if err := tx.First(&batch, id).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
return &batch, nil
|
||
}
|
||
|
||
// ListWeighingBatches 实现了分页和过滤查询批次称重记录的功能
|
||
func (r *gormPigBatchRepository) ListWeighingBatches(opts WeighingBatchListOptions, page, pageSize int) ([]models.WeighingBatch, int64, error) {
|
||
if page <= 0 || pageSize <= 0 {
|
||
return nil, 0, ErrInvalidPagination
|
||
}
|
||
|
||
var results []models.WeighingBatch
|
||
var total int64
|
||
|
||
query := r.db.Model(&models.WeighingBatch{})
|
||
|
||
if opts.PigBatchID != nil {
|
||
query = query.Where("pig_batch_id = ?", *opts.PigBatchID)
|
||
}
|
||
if opts.StartTime != nil {
|
||
query = query.Where("weighing_time >= ?", *opts.StartTime)
|
||
}
|
||
if opts.EndTime != nil {
|
||
query = query.Where("weighing_time <= ?", *opts.EndTime)
|
||
}
|
||
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
orderBy := "weighing_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
|
||
}
|
||
|
||
// ListWeighingRecords 实现了分页和过滤查询单次称重记录的功能
|
||
func (r *gormPigBatchRepository) ListWeighingRecords(opts WeighingRecordListOptions, page, pageSize int) ([]models.WeighingRecord, int64, error) {
|
||
if page <= 0 || pageSize <= 0 {
|
||
return nil, 0, ErrInvalidPagination
|
||
}
|
||
|
||
var results []models.WeighingRecord
|
||
var total int64
|
||
|
||
query := r.db.Model(&models.WeighingRecord{})
|
||
|
||
if opts.WeighingBatchID != nil {
|
||
query = query.Where("weighing_batch_id = ?", *opts.WeighingBatchID)
|
||
}
|
||
if opts.PenID != nil {
|
||
query = query.Where("pen_id = ?", *opts.PenID)
|
||
}
|
||
if opts.OperatorID != nil {
|
||
query = query.Where("operator_id = ?", *opts.OperatorID)
|
||
}
|
||
if opts.StartTime != nil {
|
||
query = query.Where("weighing_time >= ?", *opts.StartTime)
|
||
}
|
||
if opts.EndTime != nil {
|
||
query = query.Where("weighing_time <= ?", *opts.EndTime)
|
||
}
|
||
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
orderBy := "weighing_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
|
||
}
|