diff --git a/internal/app/service/pig_farm_service.go b/internal/app/service/pig_farm_service.go index 50d084a..8b79c6e 100644 --- a/internal/app/service/pig_farm_service.go +++ b/internal/app/service/pig_farm_service.go @@ -31,17 +31,19 @@ type PigFarmService interface { } type pigFarmService struct { - logger *logs.Logger - repo repository.PigFarmRepository - uow repository.UnitOfWork // 工作单元,用于事务管理 + logger *logs.Logger + farmRepository repository.PigFarmRepository + penRepository repository.PigPenRepository + uow repository.UnitOfWork // 工作单元,用于事务管理 } // NewPigFarmService 创建一个新的 PigFarmService 实例 -func NewPigFarmService(repo repository.PigFarmRepository, uow repository.UnitOfWork, logger *logs.Logger) PigFarmService { +func NewPigFarmService(farmRepository repository.PigFarmRepository, penRepository repository.PigPenRepository, uow repository.UnitOfWork, logger *logs.Logger) PigFarmService { return &pigFarmService{ - logger: logger, - repo: repo, - uow: uow, + logger: logger, + farmRepository: farmRepository, + penRepository: penRepository, + uow: uow, } } @@ -52,16 +54,16 @@ func (s *pigFarmService) CreatePigHouse(name, description string) (*models.PigHo Name: name, Description: description, } - err := s.repo.CreatePigHouse(house) + err := s.farmRepository.CreatePigHouse(house) return house, err } func (s *pigFarmService) GetPigHouseByID(id uint) (*models.PigHouse, error) { - return s.repo.GetPigHouseByID(id) + return s.farmRepository.GetPigHouseByID(id) } func (s *pigFarmService) ListPigHouses() ([]models.PigHouse, error) { - return s.repo.ListPigHouses() + return s.farmRepository.ListPigHouses() } func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*models.PigHouse, error) { @@ -70,7 +72,7 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*mod Name: name, Description: description, } - rowsAffected, err := s.repo.UpdatePigHouse(house) + rowsAffected, err := s.farmRepository.UpdatePigHouse(house) if err != nil { return nil, err } @@ -78,12 +80,12 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*mod return nil, ErrHouseNotFound } // 返回更新后的完整信息 - return s.repo.GetPigHouseByID(id) + return s.farmRepository.GetPigHouseByID(id) } func (s *pigFarmService) DeletePigHouse(id uint) error { // 业务逻辑:检查猪舍是否包含猪栏 - penCount, err := s.repo.CountPensInHouse(id) + penCount, err := s.farmRepository.CountPensInHouse(id) if err != nil { return err } @@ -92,7 +94,7 @@ func (s *pigFarmService) DeletePigHouse(id uint) error { } // 调用仓库层进行删除 - rowsAffected, err := s.repo.DeletePigHouse(id) + rowsAffected, err := s.farmRepository.DeletePigHouse(id) if err != nil { return err } @@ -106,7 +108,7 @@ func (s *pigFarmService) DeletePigHouse(id uint) error { func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int) (*models.Pen, error) { // 业务逻辑:验证所属猪舍是否存在 - _, err := s.repo.GetPigHouseByID(houseID) + _, err := s.farmRepository.GetPigHouseByID(houseID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrHouseNotFound @@ -120,21 +122,21 @@ func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int) Capacity: capacity, Status: models.PenStatusEmpty, } - err = s.repo.CreatePen(pen) + err = s.penRepository.CreatePen(pen) return pen, err } func (s *pigFarmService) GetPenByID(id uint) (*models.Pen, error) { - return s.repo.GetPenByID(id) + return s.penRepository.GetPenByID(id) } func (s *pigFarmService) ListPens() ([]models.Pen, error) { - return s.repo.ListPens() + return s.penRepository.ListPens() } func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*models.Pen, error) { // 业务逻辑:验证所属猪舍是否存在 - _, err := s.repo.GetPigHouseByID(houseID) + _, err := s.farmRepository.GetPigHouseByID(houseID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrHouseNotFound @@ -149,7 +151,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa Capacity: capacity, Status: status, } - rowsAffected, err := s.repo.UpdatePen(pen) + rowsAffected, err := s.penRepository.UpdatePen(pen) if err != nil { return nil, err } @@ -157,12 +159,12 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa return nil, ErrPenNotFound } // 返回更新后的完整信息 - return s.repo.GetPenByID(id) + return s.penRepository.GetPenByID(id) } func (s *pigFarmService) DeletePen(id uint) error { // 业务逻辑:检查猪栏是否被活跃批次使用 - pen, err := s.repo.GetPenByID(id) + pen, err := s.penRepository.GetPenByID(id) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return ErrPenNotFound // 猪栏不存在 @@ -173,7 +175,7 @@ func (s *pigFarmService) DeletePen(id uint) error { // 检查猪栏是否关联了活跃批次 // 注意:pen.PigBatchID 是指针类型,需要检查是否为 nil if pen.PigBatchID != nil && *pen.PigBatchID != 0 { - pigBatch, err := s.repo.GetPigBatchByID(*pen.PigBatchID) + pigBatch, err := s.farmRepository.GetPigBatchByID(*pen.PigBatchID) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return err } @@ -184,7 +186,7 @@ func (s *pigFarmService) DeletePen(id uint) error { } // 调用仓库层进行删除 - rowsAffected, err := s.repo.DeletePen(id) + rowsAffected, err := s.penRepository.DeletePen(id) if err != nil { return err } @@ -198,7 +200,7 @@ func (s *pigFarmService) DeletePen(id uint) error { func (s *pigFarmService) UpdatePenStatus(id uint, newStatus models.PenStatus) (*models.Pen, error) { var updatedPen *models.Pen err := s.uow.ExecuteInTransaction(func(tx *gorm.DB) error { - pen, err := s.repo.GetPenByIDTx(tx, id) + pen, err := s.penRepository.GetPenByIDTx(tx, id) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return ErrPenNotFound @@ -228,13 +230,13 @@ func (s *pigFarmService) UpdatePenStatus(id uint, newStatus models.PenStatus) (* "status": newStatus, } - if err := s.repo.UpdatePenFields(tx, id, updates); err != nil { + if err := s.penRepository.UpdatePenFields(tx, id, updates); err != nil { s.logger.Errorf("更新猪栏 %d 状态失败: %v", id, err) return fmt.Errorf("更新猪栏 %d 状态失败: %w", id, err) } // 获取更新后的猪栏信息 - updatedPen, err = s.repo.GetPenByIDTx(tx, id) + updatedPen, err = s.penRepository.GetPenByIDTx(tx, id) if err != nil { s.logger.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %v", id, err) return fmt.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %w", id, err) diff --git a/internal/core/application.go b/internal/core/application.go index 11c175c..28b7232 100644 --- a/internal/core/application.go +++ b/internal/core/application.go @@ -66,7 +66,6 @@ func NewApplication(configPath string) (*Application, error) { areaControllerRepo := repository.NewGormAreaControllerRepository(storage.GetDB()) deviceTemplateRepo := repository.NewGormDeviceTemplateRepository(storage.GetDB()) planRepo := repository.NewGormPlanRepository(storage.GetDB()) - pigFarmRepo := repository.NewGormPigFarmRepository(storage.GetDB()) pendingTaskRepo := repository.NewGormPendingTaskRepository(storage.GetDB()) executionLogRepo := repository.NewGormExecutionLogRepository(storage.GetDB()) sensorDataRepo := repository.NewGormSensorDataRepository(storage.GetDB()) @@ -74,17 +73,18 @@ func NewApplication(configPath string) (*Application, error) { pendingCollectionRepo := repository.NewGormPendingCollectionRepository(storage.GetDB()) userActionLogRepo := repository.NewGormUserActionLogRepository(storage.GetDB()) pigBatchRepo := repository.NewGormPigBatchRepository(storage.GetDB()) - penRepo := repository.NewPenRepository(storage.GetDB()) + pigFarmRepo := repository.NewGormPigFarmRepository(storage.GetDB()) + pigPenRepo := repository.NewGormPigPenRepository(storage.GetDB()) // 初始化事务管理器 unitOfWork := repository.NewGormUnitOfWork(storage.GetDB(), logger) // 初始化猪群管理领域 - penTransferManager := pig.NewPenTransferManager(penRepo) + penTransferManager := pig.NewPenTransferManager(pigPenRepo) pigBatchDomain := pig.NewPigBatchService(pigBatchRepo, unitOfWork, penTransferManager) // --- 业务逻辑处理器初始化 --- - pigFarmService := service.NewPigFarmService(pigFarmRepo, unitOfWork, logger) + pigFarmService := service.NewPigFarmService(pigFarmRepo, pigPenRepo, unitOfWork, logger) pigBatchService := service.NewPigBatchService(pigBatchDomain, logger) // 初始化审计服务 diff --git a/internal/domain/pig/pen_transfer_manager.go b/internal/domain/pig/pen_transfer_manager.go index 14358d9..a277354 100644 --- a/internal/domain/pig/pen_transfer_manager.go +++ b/internal/domain/pig/pen_transfer_manager.go @@ -13,26 +13,26 @@ type PenTransferManager interface { LogTransfer(tx *gorm.DB, log *models.PigTransferLog) error // GetPenByID 用于获取猪栏的详细信息,供上层服务进行业务校验。 - // 注意: 此方法依赖于您在 PenRepository 中添加对应的 GetPenByIDTx 方法。 + // 注意: 此方法依赖于您在 PigPenRepository 中添加对应的 GetPenByIDTx 方法。 GetPenByID(tx *gorm.DB, penID uint) (*models.Pen, error) // GetPensByBatchID 获取一个猪群当前关联的所有猪栏。 - // 注意: 此方法依赖于您在 PenRepository 中添加对应的 GetPensByBatchIDTx 方法。 + // 注意: 此方法依赖于您在 PigPenRepository 中添加对应的 GetPensByBatchIDTx 方法。 GetPensByBatchID(tx *gorm.DB, batchID uint) ([]*models.Pen, error) // UpdatePenFields 更新一个猪栏的指定字段。 - // 注意: 此方法依赖于您在 PenRepository 中添加对应的 UpdatePenFieldsTx 方法。 + // 注意: 此方法依赖于您在 PigPenRepository 中添加对应的 UpdatePenFieldsTx 方法。 UpdatePenFields(tx *gorm.DB, penID uint, updates map[string]interface{}) error } // penTransferManager 是 PenTransferManager 接口的具体实现。 // 它作为调栏管理器,处理底层的数据库交互。 type penTransferManager struct { - penRepo repository.PenRepository + penRepo repository.PigPenRepository } // NewPenTransferManager 是 penTransferManager 的构造函数。 -func NewPenTransferManager(penRepo repository.PenRepository) PenTransferManager { +func NewPenTransferManager(penRepo repository.PigPenRepository) PenTransferManager { return &penTransferManager{ penRepo: penRepo, } diff --git a/internal/infra/repository/pen_repository.go b/internal/infra/repository/pen_repository.go deleted file mode 100644 index c3a6d40..0000000 --- a/internal/infra/repository/pen_repository.go +++ /dev/null @@ -1,46 +0,0 @@ -package repository - -import ( - "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" - "gorm.io/gorm" -) - -// PenRepository 定义了与猪栏模型相关的数据库操作接口。 -type PenRepository interface { - GetPenByIDTx(tx *gorm.DB, penID uint) (*models.Pen, error) - GetPensByBatchIDTx(tx *gorm.DB, batchID uint) ([]*models.Pen, error) - UpdatePenFieldsTx(tx *gorm.DB, penID uint, updates map[string]interface{}) error -} - -// penRepository 是 PenRepository 接口的 gorm 实现。 -type penRepository struct { - db *gorm.DB -} - -// NewPenRepository 创建一个新的 PenRepository 实例。 -func NewPenRepository(db *gorm.DB) PenRepository { - return &penRepository{db: db} -} - -// GetPenByIDTx 在指定的事务中,通过ID获取单个猪栏信息。 -func (r *penRepository) GetPenByIDTx(tx *gorm.DB, penID uint) (*models.Pen, error) { - var pen models.Pen - if err := tx.First(&pen, penID).Error; err != nil { - return nil, err - } - return &pen, nil -} - -// GetPensByBatchIDTx 在指定的事务中,获取一个猪群当前关联的所有猪栏。 -func (r *penRepository) GetPensByBatchIDTx(tx *gorm.DB, batchID uint) ([]*models.Pen, error) { - var pens []*models.Pen - if err := tx.Where("pig_batch_id = ?", batchID).Find(&pens).Error; err != nil { - return nil, err - } - return pens, nil -} - -// UpdatePenFieldsTx 在指定的事务中,更新一个猪栏的指定字段。 -func (r *penRepository) UpdatePenFieldsTx(tx *gorm.DB, penID uint, updates map[string]interface{}) error { - return tx.Model(&models.Pen{}).Where("id = ?", penID).Updates(updates).Error -} diff --git a/internal/infra/repository/pig_farm_repository.go b/internal/infra/repository/pig_farm_repository.go index 47edb2a..fbd656f 100644 --- a/internal/infra/repository/pig_farm_repository.go +++ b/internal/infra/repository/pig_farm_repository.go @@ -17,22 +17,6 @@ type PigFarmRepository interface { DeletePigHouse(id uint) (int64, error) CountPensInHouse(houseID uint) (int64, error) - // Pen methods - CreatePen(pen *models.Pen) error - // GetPenByID 根据ID获取单个猪栏 (非事务性) - GetPenByID(id uint) (*models.Pen, error) - // GetPenByIDTx 根据ID获取单个猪栏 (事务性) - GetPenByIDTx(tx *gorm.DB, id uint) (*models.Pen, error) - ListPens() ([]models.Pen, error) - // UpdatePen 更新一个猪栏,返回受影响的行数和错误 - UpdatePen(pen *models.Pen) (int64, error) - // DeletePen 根据ID删除一个猪栏,返回受影响的行数和错误 - DeletePen(id uint) (int64, error) - // GetPensByBatchID 根据批次ID获取所有关联的猪栏 (事务性) - GetPensByBatchID(tx *gorm.DB, batchID uint) ([]models.Pen, error) - // UpdatePenFields 更新猪栏的指定字段 (事务性) - UpdatePenFields(tx *gorm.DB, penID uint, updates map[string]interface{}) error - // PigBatch methods // GetPigBatchByID 根据ID获取单个猪批次 (非事务性) GetPigBatchByID(id uint) (*models.PigBatch, error) @@ -100,75 +84,6 @@ func (r *gormPigFarmRepository) CountPensInHouse(houseID uint) (int64, error) { return count, err } -// --- Pen Implementation --- - -// CreatePen 创建一个新的猪栏 -func (r *gormPigFarmRepository) CreatePen(pen *models.Pen) error { - return r.db.Create(pen).Error -} - -// GetPenByID 根据ID获取单个猪栏 (非事务性) -func (r *gormPigFarmRepository) GetPenByID(id uint) (*models.Pen, error) { - var pen models.Pen - if err := r.db.First(&pen, id).Error; err != nil { - return nil, err - } - return &pen, nil -} - -// GetPenByIDTx 根据ID获取单个猪栏 (事务性) -func (r *gormPigFarmRepository) GetPenByIDTx(tx *gorm.DB, id uint) (*models.Pen, error) { - var pen models.Pen - if err := tx.First(&pen, id).Error; err != nil { - return nil, err - } - return &pen, nil -} - -// ListPens 列出所有猪栏 -func (r *gormPigFarmRepository) ListPens() ([]models.Pen, error) { - var pens []models.Pen - if err := r.db.Find(&pens).Error; err != nil { - return nil, err - } - return pens, nil -} - -// UpdatePen 更新一个猪栏,返回受影响的行数和错误 -func (r *gormPigFarmRepository) UpdatePen(pen *models.Pen) (int64, error) { - result := r.db.Model(&models.Pen{}).Where("id = ?", pen.ID).Updates(pen) - if result.Error != nil { - return 0, result.Error - } - return result.RowsAffected, nil -} - -// DeletePen 根据ID删除一个猪栏,返回受影响的行数和错误 -func (r *gormPigFarmRepository) DeletePen(id uint) (int64, error) { - result := r.db.Delete(&models.Pen{}, id) - if result.Error != nil { - return 0, result.Error - } - return result.RowsAffected, nil -} - -// GetPensByBatchID 根据批次ID获取所有关联的猪栏 (事务性) -func (r *gormPigFarmRepository) GetPensByBatchID(tx *gorm.DB, batchID uint) ([]models.Pen, error) { - var pens []models.Pen - // 注意:PigBatchID 是指针类型,需要处理 nil 值 - result := tx.Where("pig_batch_id = ?", batchID).Find(&pens) - if result.Error != nil { - return nil, result.Error - } - return pens, nil -} - -// UpdatePenFields 更新猪栏的指定字段 (事务性) -func (r *gormPigFarmRepository) UpdatePenFields(tx *gorm.DB, penID uint, updates map[string]interface{}) error { - result := tx.Model(&models.Pen{}).Where("id = ?", penID).Updates(updates) - return result.Error -} - // --- PigBatch Implementation --- // GetPigBatchByID 根据ID获取单个猪批次 (非事务性) diff --git a/internal/infra/repository/pig_pen_repository.go b/internal/infra/repository/pig_pen_repository.go new file mode 100644 index 0000000..8d894cc --- /dev/null +++ b/internal/infra/repository/pig_pen_repository.go @@ -0,0 +1,120 @@ +package repository + +import ( + "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" + "gorm.io/gorm" +) + +// PigPenRepository 定义了与猪栏模型相关的数据库操作接口。 +type PigPenRepository interface { + CreatePen(pen *models.Pen) error + // GetPenByID 根据ID获取单个猪栏 (非事务性) + GetPenByID(id uint) (*models.Pen, error) + // GetPenByIDTx 根据ID获取单个猪栏 (事务性) + GetPenByIDTx(tx *gorm.DB, id uint) (*models.Pen, error) + ListPens() ([]models.Pen, error) + // UpdatePen 更新一个猪栏,返回受影响的行数和错误 + UpdatePen(pen *models.Pen) (int64, error) + // DeletePen 根据ID删除一个猪栏,返回受影响的行数和错误 + DeletePen(id uint) (int64, error) + // GetPensByBatchID 根据批次ID获取所有关联的猪栏 (事务性) + GetPensByBatchID(tx *gorm.DB, batchID uint) ([]models.Pen, error) + // UpdatePenFields 更新猪栏的指定字段 (事务性) + UpdatePenFields(tx *gorm.DB, penID uint, updates map[string]interface{}) error + + GetPensByBatchIDTx(tx *gorm.DB, batchID uint) ([]*models.Pen, error) + UpdatePenFieldsTx(tx *gorm.DB, penID uint, updates map[string]interface{}) error +} + +// pigPenRepository 是 PigPenRepository 接口的 gorm 实现。 +type pigPenRepository struct { + db *gorm.DB +} + +// NewGormPigPenRepository 创建一个新的 PigPenRepository 实例。 +func NewGormPigPenRepository(db *gorm.DB) PigPenRepository { + return &pigPenRepository{db: db} +} + +// GetPenByIDTx 在指定的事务中,通过ID获取单个猪栏信息。 +func (r *pigPenRepository) GetPenByIDTx(tx *gorm.DB, penID uint) (*models.Pen, error) { + var pen models.Pen + if err := tx.First(&pen, penID).Error; err != nil { + return nil, err + } + return &pen, nil +} + +// GetPensByBatchIDTx 在指定的事务中,获取一个猪群当前关联的所有猪栏。 +func (r *pigPenRepository) GetPensByBatchIDTx(tx *gorm.DB, batchID uint) ([]*models.Pen, error) { + var pens []*models.Pen + if err := tx.Where("pig_batch_id = ?", batchID).Find(&pens).Error; err != nil { + return nil, err + } + return pens, nil +} + +// UpdatePenFieldsTx 在指定的事务中,更新一个猪栏的指定字段。 +func (r *pigPenRepository) UpdatePenFieldsTx(tx *gorm.DB, penID uint, updates map[string]interface{}) error { + return tx.Model(&models.Pen{}).Where("id = ?", penID).Updates(updates).Error +} + +// --- Pen Implementation --- + +// CreatePen 创建一个新的猪栏 +func (r *pigPenRepository) CreatePen(pen *models.Pen) error { + return r.db.Create(pen).Error +} + +// GetPenByID 根据ID获取单个猪栏 (非事务性) +func (r *pigPenRepository) GetPenByID(id uint) (*models.Pen, error) { + var pen models.Pen + if err := r.db.First(&pen, id).Error; err != nil { + return nil, err + } + return &pen, nil +} + +// ListPens 列出所有猪栏 +func (r *pigPenRepository) ListPens() ([]models.Pen, error) { + var pens []models.Pen + if err := r.db.Find(&pens).Error; err != nil { + return nil, err + } + return pens, nil +} + +// UpdatePen 更新一个猪栏,返回受影响的行数和错误 +func (r *pigPenRepository) UpdatePen(pen *models.Pen) (int64, error) { + result := r.db.Model(&models.Pen{}).Where("id = ?", pen.ID).Updates(pen) + if result.Error != nil { + return 0, result.Error + } + return result.RowsAffected, nil +} + +// DeletePen 根据ID删除一个猪栏,返回受影响的行数和错误 +func (r *pigPenRepository) DeletePen(id uint) (int64, error) { + result := r.db.Delete(&models.Pen{}, id) + if result.Error != nil { + return 0, result.Error + } + return result.RowsAffected, nil +} + +// GetPensByBatchID 根据批次ID获取所有关联的猪栏 (事务性) +func (r *pigPenRepository) GetPensByBatchID(tx *gorm.DB, batchID uint) ([]models.Pen, error) { + var pens []models.Pen + // 注意:PigBatchID 是指针类型,需要处理 nil 值 + result := tx.Where("pig_batch_id = ?", batchID).Find(&pens) + if result.Error != nil { + return nil, result.Error + } + return pens, nil +} + +// UpdatePenFields 更新猪栏的指定字段 (事务性) +func (r *pigPenRepository) UpdatePenFields(tx *gorm.DB, penID uint, updates map[string]interface{}) error { + result := tx.Model(&models.Pen{}).Where("id = ?", penID).Updates(updates) + return result.Error +}