Files
pig-farm-controller/internal/infra/repository/pig_batch_repository.go
2025-11-05 23:00:07 +08:00

223 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"context"
"time"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"gorm.io/gorm"
)
// PigBatchRepository 定义了与猪批次相关的数据库操作接口
type PigBatchRepository interface {
CreatePigBatch(ctx context.Context, batch *models.PigBatch) (*models.PigBatch, error)
CreatePigBatchTx(ctx context.Context, tx *gorm.DB, batch *models.PigBatch) (*models.PigBatch, error)
GetPigBatchByID(ctx context.Context, id uint) (*models.PigBatch, error)
GetPigBatchByIDTx(ctx context.Context, tx *gorm.DB, id uint) (*models.PigBatch, error)
// UpdatePigBatch 更新一个猪批次,返回更新后的批次、受影响的行数和错误
UpdatePigBatch(ctx context.Context, batch *models.PigBatch) (*models.PigBatch, int64, error)
// DeletePigBatch 根据ID删除一个猪批次返回受影响的行数和错误
DeletePigBatch(ctx context.Context, id uint) (int64, error)
DeletePigBatchTx(ctx context.Context, tx *gorm.DB, id uint) (int64, error)
ListPigBatches(ctx context.Context, isActive *bool) ([]*models.PigBatch, error)
// ListWeighingBatches 支持分页和过滤的批次称重列表查询
ListWeighingBatches(ctx context.Context, opts WeighingBatchListOptions, page, pageSize int) ([]models.WeighingBatch, int64, error)
// ListWeighingRecords 支持分页和过滤的单次称重记录列表查询
ListWeighingRecords(ctx context.Context, 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 {
ctx context.Context
db *gorm.DB
}
// NewGormPigBatchRepository 创建一个新的 PigBatchRepository GORM 实现实例
func NewGormPigBatchRepository(ctx context.Context, db *gorm.DB) PigBatchRepository {
return &gormPigBatchRepository{ctx: ctx, db: db}
}
// CreatePigBatch 创建一个新的猪批次
func (r *gormPigBatchRepository) CreatePigBatch(ctx context.Context, batch *models.PigBatch) (*models.PigBatch, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePigBatch")
return r.CreatePigBatchTx(repoCtx, r.db, batch)
}
// CreatePigBatchTx 在指定的事务中,创建一个新的猪批次
func (r *gormPigBatchRepository) CreatePigBatchTx(ctx context.Context, tx *gorm.DB, batch *models.PigBatch) (*models.PigBatch, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePigBatchTx")
if err := tx.WithContext(repoCtx).Create(batch).Error; err != nil {
return nil, err
}
return batch, nil
}
// GetPigBatchByID 根据ID获取单个猪批次
func (r *gormPigBatchRepository) GetPigBatchByID(ctx context.Context, id uint) (*models.PigBatch, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "GetPigBatchByID")
return r.GetPigBatchByIDTx(repoCtx, r.db, id)
}
// UpdatePigBatch 更新一个猪批次
func (r *gormPigBatchRepository) UpdatePigBatch(ctx context.Context, batch *models.PigBatch) (*models.PigBatch, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdatePigBatch")
result := r.db.WithContext(repoCtx).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(ctx context.Context, id uint) (int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "DeletePigBatch")
return r.DeletePigBatchTx(repoCtx, r.db, id)
}
func (r *gormPigBatchRepository) DeletePigBatchTx(ctx context.Context, tx *gorm.DB, id uint) (int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "DeletePigBatchTx")
result := tx.WithContext(repoCtx).Delete(&models.PigBatch{}, id)
if result.Error != nil {
return 0, result.Error
}
// 返回受影响的行数和错误
return result.RowsAffected, nil
}
// ListPigBatches 批量查询猪批次,支持根据 IsActive 筛选
func (r *gormPigBatchRepository) ListPigBatches(ctx context.Context, isActive *bool) ([]*models.PigBatch, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListPigBatches")
var batches []*models.PigBatch
query := r.db.WithContext(repoCtx).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(ctx context.Context, tx *gorm.DB, id uint) (*models.PigBatch, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "GetPigBatchByIDTx")
var batch models.PigBatch
if err := tx.WithContext(repoCtx).First(&batch, id).Error; err != nil {
return nil, err
}
return &batch, nil
}
// ListWeighingBatches 实现了分页和过滤查询批次称重记录的功能
func (r *gormPigBatchRepository) ListWeighingBatches(ctx context.Context, opts WeighingBatchListOptions, page, pageSize int) ([]models.WeighingBatch, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListWeighingBatches")
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination
}
var results []models.WeighingBatch
var total int64
query := r.db.WithContext(repoCtx).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(ctx context.Context, opts WeighingRecordListOptions, page, pageSize int) ([]models.WeighingRecord, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListWeighingRecords")
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination
}
var results []models.WeighingRecord
var total int64
query := r.db.WithContext(repoCtx).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
}