Files
2025-11-03 17:29:23 +08:00

2.6 KiB

方案:删除设备前的使用校验

1. 目标

在删除设备前,检查该设备是否被任何任务关联。如果设备正在被使用,则禁止删除,并向用户返回明确的错误提示。

2. 核心思路

我们将遵循您项目清晰的分层架构,将“检查设备是否被任务使用”这一业务规则放在 应用层 (internal/app/service/) 中进行协调。当上层请求删除设备时,应用服务会先调用仓库层查询 device_tasks 关联表,如果发现设备仍被任务关联,则会拒绝删除并返回一个明确的业务错误。

3. 实施步骤

3.1. 仓库层 (DeviceRepository)

  • 动作: 在 internal/infra/repository/device_repository.goDeviceRepository 接口中,增加一个新方法 IsDeviceInUse(deviceID uint) (bool, error)
  • 实现: 在 gormDeviceRepository 中实现此方法。该方法将通过对 models.DeviceTask 模型执行 Count 操作来高效地判断是否存在 device_id 匹配的记录。这比查询完整记录性能更好。

3.2. 应用层 (DeviceService)

  • 动作:
    1. internal/app/service/device_service.go 文件顶部定义一个新的错误变量 ErrDeviceInUse,例如 var ErrDeviceInUse = errors.New("设备正在被一个或多个任务使用,无法删除")
    2. 修改该文件中的 DeleteDevice 方法。
  • 实现: 在 DeleteDevice 方法中,在调用 s.deviceRepo.Delete() 之前,先调用我们刚刚创建的 s.deviceRepo.IsDeviceInUse() 方法。如果返回 true,则立即返回 ErrDeviceInUse 错误,中断删除流程。

3.3. 表现层 (DeviceController)

  • 动作: 修改 internal/app/controller/device/device_controller.go 中的 DeleteDevice 方法。
  • 实现: 在错误处理逻辑中,增加一个 case 来专门捕获从服务层返回的 service.ErrDeviceInUse 错误。当捕获到此错误时,返回一个带有明确提示信息(如“设备正在被任务使用,无法删除”)和合适 HTTP 状态码(例如 409 Conflict)的错误响应。

4. 方案优势

  • 职责清晰: 业务流程的编排和校验逻辑被正确地放置在应用层,符合您项目清晰的分层架构。
  • 高效查询: 通过 COUNT 查询代替 Find,避免了不必要的数据加载,性能更佳。
  • 代码内聚: 与设备相关的数据库操作都统一封装在 DeviceRepository 中。
  • 用户友好: 通过在控制器层处理特定业务错误,可以给前端返回明确、可操作的错误信息。