删除设备模板时检查和删除区域主控时检查
This commit is contained in:
		@@ -331,12 +331,17 @@ func (c *Controller) DeleteAreaController(ctx echo.Context) error {
 | 
			
		||||
	acID := ctx.Param("id")
 | 
			
		||||
 | 
			
		||||
	if err := c.deviceService.DeleteAreaController(acID); err != nil {
 | 
			
		||||
		if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
			
		||||
		switch {
 | 
			
		||||
		case errors.Is(err, gorm.ErrRecordNotFound):
 | 
			
		||||
			c.logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
 | 
			
		||||
		case errors.Is(err, service.ErrAreaControllerInUse):
 | 
			
		||||
			c.logger.Warnf("%s: 尝试删除正在被使用的主控, ID: %s", actionType, acID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "主控正在被使用", acID)
 | 
			
		||||
		default:
 | 
			
		||||
			c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, acID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除区域主控失败: "+err.Error(), actionType, "服务层删除失败", acID)
 | 
			
		||||
		}
 | 
			
		||||
		c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, acID)
 | 
			
		||||
		return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除区域主控失败: "+err.Error(), actionType, "服务层删除失败", acID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.logger.Infof("%s: 区域主控删除成功, ID: %s", actionType, acID)
 | 
			
		||||
@@ -469,12 +474,17 @@ func (c *Controller) DeleteDeviceTemplate(ctx echo.Context) error {
 | 
			
		||||
	dtID := ctx.Param("id")
 | 
			
		||||
 | 
			
		||||
	if err := c.deviceService.DeleteDeviceTemplate(dtID); err != nil {
 | 
			
		||||
		if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
			
		||||
		switch {
 | 
			
		||||
		case errors.Is(err, gorm.ErrRecordNotFound):
 | 
			
		||||
			c.logger.Warnf("%s: 设备模板不存在, ID: %s", actionType, dtID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备模板未找到", actionType, "设备模板不存在", dtID)
 | 
			
		||||
		case errors.Is(err, service.ErrDeviceTemplateInUse):
 | 
			
		||||
			c.logger.Warnf("%s: 尝试删除正在被使用的模板, ID: %s", actionType, dtID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "模板正在被使用", dtID)
 | 
			
		||||
		default:
 | 
			
		||||
			c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, dtID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备模板失败: "+err.Error(), actionType, "服务层删除失败", dtID)
 | 
			
		||||
		}
 | 
			
		||||
		c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, dtID)
 | 
			
		||||
		return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备模板失败: "+err.Error(), actionType, "服务层删除失败", dtID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.logger.Infof("%s: 设备模板删除成功, ID: %s", actionType, dtID)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,16 @@ import (
 | 
			
		||||
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrDeviceInUse 表示设备正在被任务使用,无法删除
 | 
			
		||||
var ErrDeviceInUse = errors.New("设备正在被一个或多个任务使用,无法删除")
 | 
			
		||||
var (
 | 
			
		||||
	// ErrDeviceInUse 表示设备正在被任务使用,无法删除
 | 
			
		||||
	ErrDeviceInUse = errors.New("设备正在被一个或多个任务使用,无法删除")
 | 
			
		||||
 | 
			
		||||
	// ErrAreaControllerInUse 表示区域主控正在被设备使用,无法删除
 | 
			
		||||
	ErrAreaControllerInUse = errors.New("区域主控正在被一个或多个设备使用,无法删除")
 | 
			
		||||
 | 
			
		||||
	// ErrDeviceTemplateInUse 表示设备模板正在被设备使用,无法删除
 | 
			
		||||
	ErrDeviceTemplateInUse = errors.New("设备模板正在被一个或多个设备使用,无法删除")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。
 | 
			
		||||
type DeviceService interface {
 | 
			
		||||
@@ -272,15 +280,27 @@ func (s *deviceService) UpdateAreaController(id string, req *dto.UpdateAreaContr
 | 
			
		||||
func (s *deviceService) DeleteAreaController(id string) error {
 | 
			
		||||
	idUint, err := strconv.ParseUint(id, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return fmt.Errorf("无效的ID格式: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	acID := uint(idUint)
 | 
			
		||||
 | 
			
		||||
	_, err = s.areaControllerRepo.FindByID(uint(idUint))
 | 
			
		||||
	// 1. 检查是否存在
 | 
			
		||||
	_, err = s.areaControllerRepo.FindByID(acID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return err // 如果未找到,gorm会返回 ErrRecordNotFound
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.areaControllerRepo.Delete(uint(idUint))
 | 
			
		||||
	// 2. 检查是否被使用(业务逻辑)
 | 
			
		||||
	inUse, err := s.deviceRepo.IsAreaControllerInUse(acID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err // 返回数据库检查错误
 | 
			
		||||
	}
 | 
			
		||||
	if inUse {
 | 
			
		||||
		return ErrAreaControllerInUse // 返回业务错误
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 3. 执行删除
 | 
			
		||||
	return s.areaControllerRepo.Delete(acID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- Device Templates ---
 | 
			
		||||
@@ -378,13 +398,25 @@ func (s *deviceService) UpdateDeviceTemplate(id string, req *dto.UpdateDeviceTem
 | 
			
		||||
func (s *deviceService) DeleteDeviceTemplate(id string) error {
 | 
			
		||||
	idUint, err := strconv.ParseUint(id, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return fmt.Errorf("无效的ID格式: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	dtID := uint(idUint)
 | 
			
		||||
 | 
			
		||||
	_, err = s.deviceTemplateRepo.FindByID(uint(idUint))
 | 
			
		||||
	// 1. 检查是否存在
 | 
			
		||||
	_, err = s.deviceTemplateRepo.FindByID(dtID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.deviceTemplateRepo.Delete(uint(idUint))
 | 
			
		||||
	// 2. 检查是否被使用(业务逻辑)
 | 
			
		||||
	inUse, err := s.deviceTemplateRepo.IsInUse(dtID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if inUse {
 | 
			
		||||
		return ErrDeviceTemplateInUse // 返回业务错误
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 3. 执行删除
 | 
			
		||||
	return s.deviceTemplateRepo.Delete(dtID)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,26 +47,11 @@ func (r *gormAreaControllerRepository) Update(ac *models.AreaController) error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete 删除一个 AreaController 记录。
 | 
			
		||||
// 在删除前会检查是否有设备关联到该主控,如果有,则不允许删除。
 | 
			
		||||
func (r *gormAreaControllerRepository) Delete(id uint) error {
 | 
			
		||||
	return r.db.Transaction(func(tx *gorm.DB) error {
 | 
			
		||||
		// 检查是否有设备关联到这个区域主控
 | 
			
		||||
		var count int64
 | 
			
		||||
		if err := tx.Model(&models.Device{}).Where("area_controller_id = ?", id).Count(&count).Error; err != nil {
 | 
			
		||||
			return fmt.Errorf("检查关联设备失败: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if count > 0 {
 | 
			
		||||
			return fmt.Errorf("无法删除区域主控,因为仍有 %d 个设备关联到它", count)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 如果没有关联设备,则执行删除操作
 | 
			
		||||
		if err := tx.Delete(&models.AreaController{}, id).Error; err != nil {
 | 
			
		||||
			return fmt.Errorf("删除区域主控失败: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	if err := r.db.Delete(&models.AreaController{}, id).Error; err != nil {
 | 
			
		||||
		return fmt.Errorf("删除区域主控失败: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindByID 通过 ID 查找一个 AreaController。
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,9 @@ type DeviceRepository interface {
 | 
			
		||||
 | 
			
		||||
	// IsDeviceInUse 检查设备是否被任何任务使用
 | 
			
		||||
	IsDeviceInUse(deviceID uint) (bool, error)
 | 
			
		||||
 | 
			
		||||
	// IsAreaControllerInUse 检查区域主控是否被任何设备使用
 | 
			
		||||
	IsAreaControllerInUse(areaControllerID uint) (bool, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// gormDeviceRepository 是 DeviceRepository 的 GORM 实现
 | 
			
		||||
@@ -175,3 +178,12 @@ func (r *gormDeviceRepository) IsDeviceInUse(deviceID uint) (bool, error) {
 | 
			
		||||
	}
 | 
			
		||||
	return count > 0, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsAreaControllerInUse 检查区域主控是否被任何设备使用
 | 
			
		||||
func (r *gormDeviceRepository) IsAreaControllerInUse(areaControllerID uint) (bool, error) {
 | 
			
		||||
	var count int64
 | 
			
		||||
	if err := r.db.Model(&models.Device{}).Where("area_controller_id = ?", areaControllerID).Count(&count).Error; err != nil {
 | 
			
		||||
		return false, fmt.Errorf("检查区域主控使用情况失败: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return count > 0, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -83,12 +83,8 @@ func (r *gormDeviceTemplateRepository) IsInUse(id uint) (bool, error) {
 | 
			
		||||
 | 
			
		||||
// Delete 软删除数据库中的设备模板
 | 
			
		||||
func (r *gormDeviceTemplateRepository) Delete(id uint) error {
 | 
			
		||||
	inUse, err := r.IsInUse(id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	if err := r.db.Delete(&models.DeviceTemplate{}, id).Error; err != nil {
 | 
			
		||||
		return fmt.Errorf("删除设备模板失败: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	if inUse {
 | 
			
		||||
		return errors.New("设备模板正在被设备使用,无法删除")
 | 
			
		||||
	}
 | 
			
		||||
	return r.db.Delete(&models.DeviceTemplate{}, id).Error
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user