diff --git a/internal/app/service/pig_farm_service.go b/internal/app/service/pig_farm_service.go index 5912360..0461e01 100644 --- a/internal/app/service/pig_farm_service.go +++ b/internal/app/service/pig_farm_service.go @@ -1,12 +1,21 @@ package service import ( + "errors" + "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" + "gorm.io/gorm" ) +var ( + ErrHouseContainsPens = errors.New("无法删除包含猪栏的猪舍") + ErrHouseNotFound = errors.New("指定的猪舍不存在") + ErrPenInUse = errors.New("猪栏正在被活跃批次使用,无法删除") +) + // PigFarmService 提供了猪场资产管理的业务逻辑 type PigFarmService interface { // PigHouse methods @@ -71,19 +80,42 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*mod } func (s *pigFarmService) DeletePigHouse(id uint) error { - return s.repo.DeletePigHouse(id) + // 业务逻辑:检查猪舍是否包含猪栏 + penCount, err := s.repo.CountPensInHouse(id) + if err != nil { + return err + } + if penCount > 0 { + return ErrHouseContainsPens + } + + // 调用仓库层进行删除 + err = s.repo.DeletePigHouse(id) + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrHouseNotFound // 或者直接返回 gorm.ErrRecordNotFound,取决于业务需求 + } + return err } // --- Pen Implementation --- func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int, status models.PenStatus) (*models.Pen, error) { + // 业务逻辑:验证所属猪舍是否存在 + _, err := s.repo.GetPigHouseByID(houseID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrHouseNotFound + } + return nil, err + } + pen := &models.Pen{ PenNumber: penNumber, HouseID: houseID, Capacity: capacity, Status: status, } - err := s.repo.CreatePen(pen) + err = s.repo.CreatePen(pen) return pen, err } @@ -96,6 +128,15 @@ func (s *pigFarmService) ListPens() ([]models.Pen, error) { } func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*models.Pen, error) { + // 业务逻辑:验证所属猪舍是否存在 + _, err := s.repo.GetPigHouseByID(houseID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrHouseNotFound + } + return nil, err + } + pen := &models.Pen{ Model: gorm.Model{ID: id}, PenNumber: penNumber, @@ -103,7 +144,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa Capacity: capacity, Status: status, } - err := s.repo.UpdatePen(pen) + err = s.repo.UpdatePen(pen) if err != nil { return nil, err } @@ -112,5 +153,31 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa } func (s *pigFarmService) DeletePen(id uint) error { - return s.repo.DeletePen(id) + // 业务逻辑:检查猪栏是否被活跃批次使用 + pen, err := s.repo.GetPenByID(id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return gorm.ErrRecordNotFound // 猪栏不存在 + } + return err + } + + // 检查猪栏是否关联了活跃批次 + if pen.PigBatchID != 0 { + pigBatch, err := s.repo.GetPigBatchByID(pen.PigBatchID) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + // 如果批次活跃,则不能删除猪栏 + if pigBatch.IsActive() { + return ErrPenInUse + } + } + + // 调用仓库层进行删除 + err = s.repo.DeletePen(id) + if errors.Is(err, gorm.ErrRecordNotFound) { + return gorm.ErrRecordNotFound // 猪栏不存在 + } + return err } diff --git a/internal/infra/repository/pig_farm_repository.go b/internal/infra/repository/pig_farm_repository.go index f6099f7..366bd33 100644 --- a/internal/infra/repository/pig_farm_repository.go +++ b/internal/infra/repository/pig_farm_repository.go @@ -1,18 +1,10 @@ package repository import ( - "errors" - "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "gorm.io/gorm" ) -var ( - ErrHouseContainsPens = errors.New("请在移除所有猪圈后移除当前猪舍") - ErrHouseNotFound = errors.New("猪舍不存在") - ErrPenInUse = errors.New("猪栏正在被活跃批次使用,无法删除") -) - // PigFarmRepository 定义了与猪场资产(猪舍、猪栏)相关的数据库操作接口 type PigFarmRepository interface { // PigHouse methods @@ -21,6 +13,7 @@ type PigFarmRepository interface { ListPigHouses() ([]models.PigHouse, error) UpdatePigHouse(house *models.PigHouse) error DeletePigHouse(id uint) error + CountPensInHouse(houseID uint) (int64, error) // Pen methods CreatePen(pen *models.Pen) error @@ -28,6 +21,9 @@ type PigFarmRepository interface { ListPens() ([]models.Pen, error) UpdatePen(pen *models.Pen) error DeletePen(id uint) error + + // PigBatch methods + GetPigBatchByID(id uint) (*models.PigBatch, error) } // gormPigFarmRepository 是 PigFarmRepository 的 GORM 实现 @@ -74,39 +70,26 @@ func (r *gormPigFarmRepository) UpdatePigHouse(house *models.PigHouse) error { } func (r *gormPigFarmRepository) DeletePigHouse(id uint) error { - return r.db.Transaction(func(tx *gorm.DB) error { - var penCount int64 - if err := tx.Model(&models.Pen{}).Where("house_id = ?", id).Count(&penCount).Error; err != nil { - return err - } - if penCount > 0 { - return ErrHouseContainsPens - } + result := r.db.Delete(&models.PigHouse{}, id) + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + return nil +} - result := tx.Delete(&models.PigHouse{}, id) - if result.Error != nil { - return result.Error - } - if result.RowsAffected == 0 { - return gorm.ErrRecordNotFound - } - return nil - }) +func (r *gormPigFarmRepository) CountPensInHouse(houseID uint) (int64, error) { + var count int64 + err := r.db.Model(&models.Pen{}).Where("house_id = ?", houseID).Count(&count).Error + return count, err } // --- Pen Implementation --- func (r *gormPigFarmRepository) CreatePen(pen *models.Pen) error { - return r.db.Transaction(func(tx *gorm.DB) error { - // 验证所属猪舍是否存在 - if err := tx.First(&models.PigHouse{}, pen.HouseID).Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return ErrHouseNotFound - } - return err - } - return tx.Create(pen).Error - }) + return r.db.Create(pen).Error } func (r *gormPigFarmRepository) GetPenByID(id uint) (*models.Pen, error) { @@ -126,55 +109,33 @@ func (r *gormPigFarmRepository) ListPens() ([]models.Pen, error) { } func (r *gormPigFarmRepository) UpdatePen(pen *models.Pen) error { - return r.db.Transaction(func(tx *gorm.DB) error { - // 验证所属猪舍是否存在 - if err := tx.First(&models.PigHouse{}, pen.HouseID).Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return ErrHouseNotFound - } - return err - } - - result := tx.Model(&models.Pen{}).Where("id = ?", pen.ID).Updates(pen) - if result.Error != nil { - return result.Error - } - if result.RowsAffected == 0 { - return gorm.ErrRecordNotFound - } - return nil - }) + result := r.db.Model(&models.Pen{}).Where("id = ?", pen.ID).Updates(pen) + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + return nil } func (r *gormPigFarmRepository) DeletePen(id uint) error { - return r.db.Transaction(func(tx *gorm.DB) error { - var pen models.Pen - if err := tx.First(&pen, id).Error; err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return gorm.ErrRecordNotFound - } - return err - } - - // 检查猪栏是否被活跃批次使用 - if pen.PigBatchID != 0 { - var pigBatch models.PigBatch - err := tx.First(&pigBatch, pen.PigBatchID).Error - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - return err - } - if pigBatch.IsActive() { - return ErrPenInUse - } - } - - result := tx.Delete(&models.Pen{}, id) - if result.Error != nil { - return result.Error - } - if result.RowsAffected == 0 { - return gorm.ErrRecordNotFound - } - return nil - }) + result := r.db.Delete(&models.Pen{}, id) + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + return nil +} + +// --- PigBatch Implementation --- + +func (r *gormPigFarmRepository) GetPigBatchByID(id uint) (*models.PigBatch, error) { + var batch models.PigBatch + if err := r.db.First(&batch, id).Error; err != nil { + return nil, err + } + return &batch, nil }