删除设备时检查
This commit is contained in:
		@@ -154,12 +154,18 @@ func (c *Controller) DeleteDevice(ctx echo.Context) error {
 | 
			
		||||
	deviceID := ctx.Param("id")
 | 
			
		||||
 | 
			
		||||
	if err := c.deviceService.DeleteDevice(deviceID); err != nil {
 | 
			
		||||
		if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
			
		||||
		switch {
 | 
			
		||||
		case errors.Is(err, gorm.ErrRecordNotFound):
 | 
			
		||||
			c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
 | 
			
		||||
		case errors.Is(err, service.ErrDeviceInUse):
 | 
			
		||||
			c.logger.Warnf("%s: 尝试删除正在被使用的设备, ID: %s", actionType, deviceID)
 | 
			
		||||
			// 返回 409 Conflict 状态码,表示请求与服务器当前状态冲突
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeConflict, err.Error(), actionType, "设备正在被使用", deviceID)
 | 
			
		||||
		default:
 | 
			
		||||
			c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, deviceID)
 | 
			
		||||
			return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "服务层删除失败", deviceID)
 | 
			
		||||
		}
 | 
			
		||||
		c.logger.Errorf("%s: 服务层删除失败: %v, ID: %s", actionType, err, deviceID)
 | 
			
		||||
		return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "服务层删除失败", deviceID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.logger.Infof("%s: 设备删除成功, ID: %s", actionType, deviceID)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package service
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
 | 
			
		||||
@@ -11,6 +12,9 @@ import (
 | 
			
		||||
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrDeviceInUse 表示设备正在被任务使用,无法删除
 | 
			
		||||
var ErrDeviceInUse = errors.New("设备正在被一个或多个任务使用,无法删除")
 | 
			
		||||
 | 
			
		||||
// DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。
 | 
			
		||||
type DeviceService interface {
 | 
			
		||||
	CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error)
 | 
			
		||||
@@ -142,14 +146,27 @@ func (s *deviceService) DeleteDevice(id string) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	deviceID := uint(idUint)
 | 
			
		||||
 | 
			
		||||
	// Check if device exists before deleting
 | 
			
		||||
	_, err = s.deviceRepo.FindByID(uint(idUint))
 | 
			
		||||
	// 检查设备是否存在
 | 
			
		||||
	_, err = s.deviceRepo.FindByID(deviceID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return err // 如果未找到,会返回 gorm.ErrRecordNotFound
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.deviceRepo.Delete(uint(idUint))
 | 
			
		||||
	// 在删除前检查设备是否被任务使用
 | 
			
		||||
	inUse, err := s.deviceRepo.IsDeviceInUse(deviceID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// 如果检查过程中发生数据库错误,则返回错误
 | 
			
		||||
		return fmt.Errorf("检查设备使用情况失败: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	if inUse {
 | 
			
		||||
		// 如果设备正在被使用,则返回特定的业务错误
 | 
			
		||||
		return ErrDeviceInUse
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 只有在未被使用时,才执行删除操作
 | 
			
		||||
	return s.deviceRepo.Delete(deviceID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *deviceService) ManualControl(id string, req *dto.ManualControlDeviceRequest) error {
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,9 @@ type DeviceRepository interface {
 | 
			
		||||
 | 
			
		||||
	// GetDevicesByIDsTx 在指定事务中根据ID列表获取设备
 | 
			
		||||
	GetDevicesByIDsTx(tx *gorm.DB, ids []uint) ([]models.Device, error)
 | 
			
		||||
 | 
			
		||||
	// IsDeviceInUse 检查设备是否被任何任务使用
 | 
			
		||||
	IsDeviceInUse(deviceID uint) (bool, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// gormDeviceRepository 是 DeviceRepository 的 GORM 实现
 | 
			
		||||
@@ -161,3 +164,14 @@ func (r *gormDeviceRepository) FindByAreaControllerAndPhysicalAddress(areaContro
 | 
			
		||||
	}
 | 
			
		||||
	return &device, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsDeviceInUse 检查设备是否被任何任务使用
 | 
			
		||||
func (r *gormDeviceRepository) IsDeviceInUse(deviceID uint) (bool, error) {
 | 
			
		||||
	var count int64
 | 
			
		||||
	// 直接对 device_tasks 关联表进行 COUNT 操作,性能最高
 | 
			
		||||
	err := r.db.Model(&models.DeviceTask{}).Where("device_id = ?", deviceID).Count(&count).Error
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, fmt.Errorf("查询设备任务关联失败: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return count > 0, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user