修改service包

This commit is contained in:
2025-11-05 19:57:30 +08:00
parent bd4f5b83e1
commit 203be4307d
28 changed files with 576 additions and 461 deletions

View File

@@ -1,113 +1,113 @@
- **`internal/app/service/pig_farm_service.go` (`service.PigFarmService`)** - **`internal/app/service/pig_farm_service.go` (`service.PigFarmService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `PigFarmService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `PigFarmService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- [ ] 移除 `PigFarmService` 结构体中的 `repo repository.PigFarmRepository` 成员,改为 - [x] 移除 `PigFarmService` 结构体中的 `repo repository.PigFarmRepository` 成员,改为
`repo repository.PigFarmRepository` `repo repository.PigFarmRepository`
- **构造函数改造 (`NewPigFarmService`)**: - **构造函数改造 (`NewPigFarmService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `PigFarmService` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `PigFarmService` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "PigFarmService")` `selfCtx := logs.AddCompName(ctx, "PigFarmService")`
- [ ] 将这个 `selfCtx` 赋值给 `PigFarmService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `PigFarmService` 结构体的 `selfCtx` 成员。
- **公共方法改造 ( - **公共方法改造 (
所有方法,例如 `CreatePigHouse`, `GetPigHouseByID`, `ListPigHouses`, `UpdatePigHouse`, `DeletePigHouse`, 所有方法,例如 `CreatePigHouse`, `GetPigHouseByID`, `ListPigHouses`, `UpdatePigHouse`, `DeletePigHouse`,
`CreatePen`, `GetPenByID`, `ListPens`, `UpdatePen`, `DeletePen`, `UpdatePenStatus`)**: `CreatePen`, `GetPenByID`, `ListPens`, `UpdatePen`, `DeletePen`, `UpdatePenStatus`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof` - [x] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof`
- [ ] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 - [x] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。
- **`internal/app/service/pig_batch_service.go` (`service.PigBatchService`)** - **`internal/app/service/pig_batch_service.go` (`service.PigBatchService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `PigBatchService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `PigBatchService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewPigBatchService`)**: - **构造函数改造 (`NewPigBatchService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `PigBatchService` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `PigBatchService` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "PigBatchService")` `selfCtx := logs.AddCompName(ctx, "PigBatchService")`
- [ ] 将这个 `selfCtx` 赋值给 `PigBatchService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `PigBatchService` 结构体的 `selfCtx` 成员。
- **公共方法改造 ( - **公共方法改造 (
所有方法,例如 `CreatePigBatch`, `GetPigBatch`, `UpdatePigBatch`, `DeletePigBatch`, `ListPigBatches`, 所有方法,例如 `CreatePigBatch`, `GetPigBatch`, `UpdatePigBatch`, `DeletePigBatch`, `ListPigBatches`,
`AssignEmptyPensToBatch`, `ReclassifyPenToNewBatch`, `RemoveEmptyPenFromBatch`, `MovePigsIntoPen`, `SellPigs`, `AssignEmptyPensToBatch`, `ReclassifyPenToNewBatch`, `RemoveEmptyPenFromBatch`, `MovePigsIntoPen`, `SellPigs`,
`BuyPigs`, `RecordSickPigs`, `RecordSickPigRecovery`, `RecordSickPigDeath`, `RecordSickPigCull`, `RecordDeath`, `BuyPigs`, `RecordSickPigs`, `RecordSickPigRecovery`, `RecordSickPigDeath`, `RecordSickPigCull`, `RecordDeath`,
`RecordCull`)**: `RecordCull`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof` - [x] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof`
- [ ] 确保所有对 `s.pigBatchRepo`, `s.pigBatchLogRepo`, `s.uow`, `s.transferSvc`, `s.tradeSvc`, `s.sickSvc` - [x] 确保所有对 `s.pigBatchRepo`, `s.pigBatchLogRepo`, `s.uow`, `s.transferSvc`, `s.tradeSvc`, `s.sickSvc`
等依赖的调用都将 `newCtx` 作为第一个参数传递。 等依赖的调用都将 `newCtx` 作为第一个参数传递。
- **`internal/app/service/monitor_service.go` (`service.MonitorService`)** - **`internal/app/service/monitor_service.go` (`service.MonitorService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `MonitorService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `MonitorService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewMonitorService`)**: - **构造函数改造 (`NewMonitorService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `MonitorService` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `MonitorService` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "MonitorService")` `selfCtx := logs.AddCompName(ctx, "MonitorService")`
- [ ] 将这个 `selfCtx` 赋值给 `MonitorService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `MonitorService` 结构体的 `selfCtx` 成员。
- **公共方法改造 ( - **公共方法改造 (
所有方法,例如 `ListSensorData`, `ListDeviceCommandLogs`, `ListPlanExecutionLogs`, `ListTaskExecutionLogs`, 所有方法,例如 `ListSensorData`, `ListDeviceCommandLogs`, `ListPlanExecutionLogs`, `ListTaskExecutionLogs`,
`ListPendingCollections`, `ListUserActionLogs`, `ListRawMaterialPurchases`, `ListRawMaterialStockLogs`, `ListPendingCollections`, `ListUserActionLogs`, `ListRawMaterialPurchases`, `ListRawMaterialStockLogs`,
`ListFeedUsageRecords`, `ListMedicationLogs`, `ListPigBatchLogs`, `ListWeighingBatches`, `ListWeighingRecords`, `ListFeedUsageRecords`, `ListMedicationLogs`, `ListPigBatchLogs`, `ListWeighingBatches`, `ListWeighingRecords`,
`ListPigTransferLogs`, `ListPigSickLogs`, `ListPigPurchases`, `ListPigSales`, `ListNotifications`)**: `ListPigTransferLogs`, `ListPigSickLogs`, `ListPigPurchases`, `ListPigSales`, `ListNotifications`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof` - [x] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof`
- [ ] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 - [x] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。
- **`internal/app/service/device_service.go` (`service.DeviceService`)** - **`internal/app/service/device_service.go` (`service.DeviceService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `DeviceService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `DeviceService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewDeviceService`)**: - **构造函数改造 (`NewDeviceService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `DeviceService` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `DeviceService` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "DeviceService")` `selfCtx := logs.AddCompName(ctx, "DeviceService")`
- [ ] 将这个 `selfCtx` 赋值给 `DeviceService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `DeviceService` 结构体的 `selfCtx` 成员。
- **公共方法改造 ( - **公共方法改造 (
所有方法,例如 `CreateDevice`, `GetDevice`, `ListDevices`, `UpdateDevice`, `DeleteDevice`, `ManualControl`, 所有方法,例如 `CreateDevice`, `GetDevice`, `ListDevices`, `UpdateDevice`, `DeleteDevice`, `ManualControl`,
`CreateAreaController`, `GetAreaController`, `ListAreaControllers`, `UpdateAreaController`, `CreateAreaController`, `GetAreaController`, `ListAreaControllers`, `UpdateAreaController`,
`DeleteAreaController`, `CreateDeviceTemplate`, `GetDeviceTemplate`, `ListDeviceTemplates`, `DeleteAreaController`, `CreateDeviceTemplate`, `GetDeviceTemplate`, `ListDeviceTemplates`,
`UpdateDeviceTemplate`, `DeleteDeviceTemplate`)**: `UpdateDeviceTemplate`, `DeleteDeviceTemplate`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf`, `s.logger.Warnf`, `s.logger.Infof` 的调用替换为 `logger.Errorf`, - [x] 将所有对 `s.logger.Errorf`, `s.logger.Warnf`, `s.logger.Infof` 的调用替换为 `logger.Errorf`,
`logger.Warnf`, `logger.Infof` `logger.Warnf`, `logger.Infof`
- [ ] 确保所有对 `s.repo`, `s.generalDeviceService` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - [x] 确保所有对 `s.repo`, `s.generalDeviceService` 等依赖的调用都将 `newCtx` 作为第一个参数传递。
- **`internal/app/service/plan_service.go` (`service.PlanService`)** - **`internal/app/service/plan_service.go` (`service.PlanService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `PlanService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `PlanService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewPlanService`)**: - **构造函数改造 (`NewPlanService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `PlanService` 创建其专属的 `selfCtx``selfCtx := logs.AddCompName(ctx, "PlanService")` - [x] 在函数内部,为 `PlanService` 创建其专属的 `selfCtx``selfCtx := logs.AddCompName(ctx, "PlanService")`
- [ ] 将这个 `selfCtx` 赋值给 `PlanService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `PlanService` 结构体的 `selfCtx` 成员。
- **公共方法改造 ( - **公共方法改造 (
所有方法,例如 `CreatePlan`, `GetPlanByID`, `ListPlans`, `UpdatePlan`, `DeletePlan`, `StartPlan`, `StopPlan`)**: 所有方法,例如 `CreatePlan`, `GetPlanByID`, `ListPlans`, `UpdatePlan`, `DeletePlan`, `StartPlan`, `StopPlan`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof` - [x] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof`
- [ ] 确保所有对 `s.repo`, `s.planExecutionManager`, `s.analysisPlanTaskManager` 等依赖的调用都将 `newCtx` - [x] 确保所有对 `s.repo`, `s.planExecutionManager`, `s.analysisPlanTaskManager` 等依赖的调用都将 `newCtx`
作为第一个参数传递。 作为第一个参数传递。
- **`internal/app/service/user_service.go` (`service.UserService`)** - **`internal/app/service/user_service.go` (`service.UserService`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `UserService` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `UserService` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewUserService`)**: - **构造函数改造 (`NewUserService`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `UserService` 创建其专属的 `selfCtx``selfCtx := logs.AddCompName(ctx, "UserService")` - [x] 在函数内部,为 `UserService` 创建其专属的 `selfCtx``selfCtx := logs.AddCompName(ctx, "UserService")`
- [ ] 将这个 `selfCtx` 赋值给 `UserService` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `UserService` 结构体的 `selfCtx` 成员。
- **公共方法改造 (所有方法,例如 `CreateUser`, `Login`, `SendTestNotification`)**: - **公共方法改造 (所有方法,例如 `CreateUser`, `Login`, `SendTestNotification`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof` - [x] 将所有对 `s.logger.Errorf``s.logger.Infof` 的调用替换为 `logger.Errorf``logger.Infof`
- [ ] 确保所有对 `s.repo`, `s.tokenService`, `s.notifier` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - [x] 确保所有对 `s.repo`, `s.tokenService`, `s.notifier` 等依赖的调用都将 `newCtx` 作为第一个参数传递。

View File

@@ -1,39 +1,39 @@
- **`internal/app/webhook/chirp_stack.go` (`webhook.ChirpStackListener`)** - **`internal/app/webhook/chirp_stack.go` (`webhook.ChirpStackListener`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `ChirpStackListener` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `ChirpStackListener` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewChirpStackListener`)**: - **构造函数改造 (`NewChirpStackListener`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `ChirpStackListener` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `ChirpStackListener` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "ChirpStackListener")` `selfCtx := logs.AddCompName(ctx, "ChirpStackListener")`
- [ ] 将这个 `selfCtx` 赋值给 `ChirpStackListener` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `ChirpStackListener` 结构体的 `selfCtx` 成员。
- **公共方法改造 (`Handler`)**: - **公共方法改造 (`Handler`)**:
- [ ] `Handler` 方法返回 `http.HandlerFunc`。在返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 - [x] `Handler` 方法返回 `http.HandlerFunc`。在返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为
`upstreamCtx` `upstreamCtx`
- [ ] 在 `go c.handler(b, event)` 调用之前,将 `upstreamCtx` 传递给 `c.handler` 方法,即 - [x] 在 `go c.handler(b, event)` 调用之前,将 `upstreamCtx` 传递给 `c.handler` 方法,即
`go c.handler(upstreamCtx, b, event)` `go c.handler(upstreamCtx, b, event)`
- [ ] 将所有对 `c.logger.Errorf` 的调用替换为 `logger.Errorf` (在 `handler` 方法中处理)。 - [x] 将所有对 `c.logger.Errorf` 的调用替换为 `logger.Errorf` (在 `handler` 方法中处理)。
- **内部辅助方法改造 (`handler`, `handleUpEvent`, `handleStatusEvent`, `handleAckEvent`, `handleLogEvent`, - **内部辅助方法改造 (`handler`, `handleUpEvent`, `handleStatusEvent`, `handleAckEvent`, `handleLogEvent`,
`handleJoinEvent`, `handleTxAckEvent`, `handleLocationEvent`, `handleIntegrationEvent`, `recordSensorData`)**: `handleJoinEvent`, `handleTxAckEvent`, `handleLocationEvent`, `handleIntegrationEvent`, `recordSensorData`)**:
- [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。
- [ ] 在每个方法入口处,使用 `newCtx, logger := logs.Trace(ctx, c.selfCtx, "MethodName")` 获取新的 - [x] 在每个方法入口处,使用 `newCtx, logger := logs.Trace(ctx, c.selfCtx, "MethodName")` 获取新的
`context.Context``logger` 实例。 `context.Context``logger` 实例。
- [ ] 将所有对 `c.logger.Errorf`, `c.logger.Infof`, `c.logger.Warnf` 的调用替换为 `logger.Errorf`, - [x] 将所有对 `c.logger.Errorf`, `c.logger.Infof`, `c.logger.Warnf` 的调用替换为 `logger.Errorf`,
`logger.Infof`, `logger.Warnf` `logger.Infof`, `logger.Warnf`
- [ ] 确保所有对 `c.sensorDataRepo`, `c.deviceRepo`, `c.areaControllerRepo`, `c.deviceCommandLogRepo`, - [x] 确保所有对 `c.sensorDataRepo`, `c.deviceRepo`, `c.areaControllerRepo`, `c.deviceCommandLogRepo`,
`c.pendingCollectionRepo` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 `c.pendingCollectionRepo` 等依赖的调用都将 `newCtx` 作为第一个参数传递。
- **`internal/app/webhook/placeholder_listener.go` (`webhook.PlaceholderListener`)** - **`internal/app/webhook/placeholder_listener.go` (`webhook.PlaceholderListener`)**
- **结构体改造**: - **结构体改造**:
- [ ] 移除 `PlaceholderListener` 结构体中的 `logger *logs.Logger` 成员。 - [x] 移除 `PlaceholderListener` 结构体中的 `logger *logs.Logger` 成员。
- [ ] 新增 `selfCtx context.Context` 成员。 - [x] 新增 `selfCtx context.Context` 成员。
- **构造函数改造 (`NewPlaceholderListener`)**: - **构造函数改造 (`NewPlaceholderListener`)**:
- [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context` - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`
- [ ] 在函数内部,为 `PlaceholderListener` 创建其专属的 `selfCtx` - [x] 在函数内部,为 `PlaceholderListener` 创建其专属的 `selfCtx`
`selfCtx := logs.AddCompName(ctx, "PlaceholderListener")` `selfCtx := logs.AddCompName(ctx, "PlaceholderListener")`
- [ ] 将这个 `selfCtx` 赋值给 `PlaceholderListener` 结构体的 `selfCtx` 成员。 - [x] 将这个 `selfCtx` 赋值给 `PlaceholderListener` 结构体的 `selfCtx` 成员。
- [ ] 使用 `newCtx, logger := logs.Trace(ctx, selfCtx, "NewPlaceholderListener")` 获取 `logger` 实例,并替换 - [x] 使用 `newCtx, logger := logs.Trace(ctx, selfCtx, "NewPlaceholderListener")` 获取 `logger` 实例,并替换
`logger.Info` 调用。 `logger.Info` 调用。
- **公共方法改造 (`Handler`)**: - **公共方法改造 (`Handler`)**:
- [ ] 在 `Handler` 方法返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 `upstreamCtx` - [x] 在 `Handler` 方法返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 `upstreamCtx`
- [ ] 使用 `newCtx, logger := logs.Trace(upstreamCtx, p.selfCtx, "Handler")` 获取 `logger` 实例。 - [x] 使用 `newCtx, logger := logs.Trace(upstreamCtx, p.selfCtx, "Handler")` 获取 `logger` 实例。
- [ ] 将所有对 `p.logger.Warn` 的调用替换为 `logger.Warn` - [x] 将所有对 `p.logger.Warn` 的调用替换为 `logger.Warn`

View File

@@ -32,6 +32,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/config" "git.huangwc.com/pig/pig-farm-controller/internal/infra/config"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"
) )

View File

@@ -7,6 +7,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/middleware" "git.huangwc.com/pig/pig-farm-controller/internal/app/middleware"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
echoSwagger "github.com/swaggo/echo-swagger" echoSwagger "github.com/swaggo/echo-swagger"
) )

View File

@@ -4,6 +4,7 @@ import (
"errors" "errors"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -9,6 +9,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"gorm.io/gorm" "gorm.io/gorm"
) )

View File

@@ -7,6 +7,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller" "git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -7,6 +7,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -3,6 +3,7 @@ package management
import ( import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -3,6 +3,7 @@ package management
import ( import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -5,6 +5,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -9,6 +9,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -9,6 +9,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -10,6 +10,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/plan" "git.huangwc.com/pig/pig-farm-controller/internal/domain/plan"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -8,6 +8,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -2,6 +2,7 @@ package dto
import ( import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
) )

View File

@@ -5,6 +5,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/notify" "git.huangwc.com/pig/pig-farm-controller/internal/infra/notify"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
) )

View File

@@ -6,6 +6,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/domain/audit" "git.huangwc.com/pig/pig-farm-controller/internal/domain/audit"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "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/models"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@@ -12,6 +12,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "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/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"gorm.io/gorm" "gorm.io/gorm"
) )

View File

@@ -1,13 +1,13 @@
// Package audit 提供了用户操作审计相关的功能 // Package audit 提供了用户操作审计相关的功能
package audit package service
import ( import (
"context"
"time" "time"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "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/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
// 移除对 "github.com/gin-gonic/gin" 的直接依赖
) )
// RequestContext 封装了审计日志所需的请求上下文信息 // RequestContext 封装了审计日志所需的请求上下文信息
@@ -17,27 +17,32 @@ type RequestContext struct {
HTTPMethod string HTTPMethod string
} }
// Service 定义了审计服务的接口 // AuditService 定义了审计服务的接口
type Service interface { type AuditService interface {
LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) LogAction(ctx context.Context, user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string)
} }
// service 是 Service 接口的实现 // auditService 是 AuditService 接口的实现
type service struct { type auditService struct {
ctx context.Context
userActionLogRepository repository.UserActionLogRepository userActionLogRepository repository.UserActionLogRepository
logger *logs.Logger
} }
// NewService 创建一个新的审计服务实例 // NewAuditService 创建一个新的审计服务实例
func NewService(repo repository.UserActionLogRepository, logger *logs.Logger) Service { func NewAuditService(ctx context.Context, repo repository.UserActionLogRepository) AuditService {
return &service{userActionLogRepository: repo, logger: logger} return &auditService{
ctx: ctx,
userActionLogRepository: repo,
}
} }
// LogAction 记录一个用户操作。它在一个新的 goroutine 中异步执行,以避免阻塞主请求。 // LogAction 记录一个用户操作。它在一个新的 goroutine 中异步执行,以避免阻塞主请求。
func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) { func (s *auditService) LogAction(ctx context.Context, user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "LogAction")
// 不再从 context 中获取用户信息,直接使用传入的 user 对象 // 不再从 context 中获取用户信息,直接使用传入的 user 对象
if user == nil { if user == nil {
s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil") logger.Warnw("无法记录审计日志:传入的用户对象为 nil")
return return
} }
@@ -56,14 +61,14 @@ func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType
// 使用模型提供的方法来设置 TargetResource // 使用模型提供的方法来设置 TargetResource
if err := log.SetTargetResource(targetResource); err != nil { if err := log.SetTargetResource(targetResource); err != nil {
s.logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err) logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err)
// 即使序列化失败,我们可能仍然希望记录操作本身,所以不在此处 return // 即使序列化失败,我们可能仍然希望记录操作本身,所以不在此处 return
} }
// 异步写入数据库,不阻塞当前请求 // 异步写入数据库,不阻塞当前请求
go func() { go func() {
if err := s.userActionLogRepository.Create(log); err != nil { if err := s.userActionLogRepository.Create(serviceCtx, log); err != nil {
s.logger.Errorw("异步保存审计日志失败", "error", err) logger.Errorw("异步保存审计日志失败", "error", err)
} }
}() }()
} }

View File

@@ -1,12 +1,14 @@
package service package service
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/device" "git.huangwc.com/pig/pig-farm-controller/internal/domain/device"
"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/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
) )
@@ -25,42 +27,45 @@ var (
// DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。 // DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。
// DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。 // DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。
type DeviceService interface { type DeviceService interface {
CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) CreateDevice(ctx context.Context, req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error)
GetDevice(id uint) (*dto.DeviceResponse, error) GetDevice(ctx context.Context, id uint) (*dto.DeviceResponse, error)
ListDevices() ([]*dto.DeviceResponse, error) ListDevices(ctx context.Context) ([]*dto.DeviceResponse, error)
UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) UpdateDevice(ctx context.Context, id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error)
DeleteDevice(id uint) error DeleteDevice(ctx context.Context, id uint) error
ManualControl(id uint, req *dto.ManualControlDeviceRequest) error ManualControl(ctx context.Context, id uint, req *dto.ManualControlDeviceRequest) error
CreateAreaController(req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) CreateAreaController(ctx context.Context, req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error)
GetAreaController(id uint) (*dto.AreaControllerResponse, error) GetAreaController(ctx context.Context, id uint) (*dto.AreaControllerResponse, error)
ListAreaControllers() ([]*dto.AreaControllerResponse, error) ListAreaControllers(ctx context.Context) ([]*dto.AreaControllerResponse, error)
UpdateAreaController(id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) UpdateAreaController(ctx context.Context, id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error)
DeleteAreaController(id uint) error DeleteAreaController(ctx context.Context, id uint) error
CreateDeviceTemplate(req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) CreateDeviceTemplate(ctx context.Context, req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error)
GetDeviceTemplate(id uint) (*dto.DeviceTemplateResponse, error) GetDeviceTemplate(ctx context.Context, id uint) (*dto.DeviceTemplateResponse, error)
ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error) ListDeviceTemplates(ctx context.Context) ([]*dto.DeviceTemplateResponse, error)
UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) UpdateDeviceTemplate(ctx context.Context, id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error)
DeleteDeviceTemplate(id uint) error DeleteDeviceTemplate(ctx context.Context, id uint) error
} }
// deviceService 是 DeviceService 接口的具体实现。 // deviceService 是 DeviceService 接口的具体实现。
type deviceService struct { type deviceService struct {
ctx context.Context
deviceRepo repository.DeviceRepository deviceRepo repository.DeviceRepository
areaControllerRepo repository.AreaControllerRepository areaControllerRepo repository.AreaControllerRepository
deviceTemplateRepo repository.DeviceTemplateRepository deviceTemplateRepo repository.DeviceTemplateRepository
deviceDomainSvc device.Service // 依赖领域服务 deviceDomainSvc device.Service
} }
// NewDeviceService 创建一个新的 DeviceService 实例。 // NewDeviceService 创建一个新的 DeviceService 实例。
func NewDeviceService( func NewDeviceService(
ctx context.Context,
deviceRepo repository.DeviceRepository, deviceRepo repository.DeviceRepository,
areaControllerRepo repository.AreaControllerRepository, areaControllerRepo repository.AreaControllerRepository,
deviceTemplateRepo repository.DeviceTemplateRepository, deviceTemplateRepo repository.DeviceTemplateRepository,
deviceDomainSvc device.Service, deviceDomainSvc device.Service,
) DeviceService { ) DeviceService {
return &deviceService{ return &deviceService{
ctx: ctx,
deviceRepo: deviceRepo, deviceRepo: deviceRepo,
areaControllerRepo: areaControllerRepo, areaControllerRepo: areaControllerRepo,
deviceTemplateRepo: deviceTemplateRepo, deviceTemplateRepo: deviceTemplateRepo,
@@ -70,7 +75,8 @@ func NewDeviceService(
// --- Devices --- // --- Devices ---
func (s *deviceService) CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) { func (s *deviceService) CreateDevice(ctx context.Context, req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateDevice")
propertiesJSON, err := json.Marshal(req.Properties) propertiesJSON, err := json.Marshal(req.Properties)
if err != nil { if err != nil {
return nil, err // Consider wrapping this error for better context return nil, err // Consider wrapping this error for better context
@@ -88,11 +94,11 @@ func (s *deviceService) CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceR
return nil, err return nil, err
} }
if err := s.deviceRepo.Create(device); err != nil { if err := s.deviceRepo.Create(serviceCtx, device); err != nil {
return nil, err return nil, err
} }
createdDevice, err := s.deviceRepo.FindByID(device.ID) createdDevice, err := s.deviceRepo.FindByID(serviceCtx, device.ID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -100,24 +106,27 @@ func (s *deviceService) CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceR
return dto.NewDeviceResponse(createdDevice) return dto.NewDeviceResponse(createdDevice)
} }
func (s *deviceService) GetDevice(id uint) (*dto.DeviceResponse, error) { func (s *deviceService) GetDevice(ctx context.Context, id uint) (*dto.DeviceResponse, error) {
device, err := s.deviceRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetDevice")
device, err := s.deviceRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewDeviceResponse(device) return dto.NewDeviceResponse(device)
} }
func (s *deviceService) ListDevices() ([]*dto.DeviceResponse, error) { func (s *deviceService) ListDevices(ctx context.Context) ([]*dto.DeviceResponse, error) {
devices, err := s.deviceRepo.ListAll() serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListDevices")
devices, err := s.deviceRepo.ListAll(serviceCtx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewListDeviceResponse(devices) return dto.NewListDeviceResponse(devices)
} }
func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) { func (s *deviceService) UpdateDevice(ctx context.Context, id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) {
existingDevice, err := s.deviceRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateDevice")
existingDevice, err := s.deviceRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -137,11 +146,11 @@ func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dt
return nil, err return nil, err
} }
if err := s.deviceRepo.Update(existingDevice); err != nil { if err := s.deviceRepo.Update(serviceCtx, existingDevice); err != nil {
return nil, err return nil, err
} }
updatedDevice, err := s.deviceRepo.FindByID(existingDevice.ID) updatedDevice, err := s.deviceRepo.FindByID(serviceCtx, existingDevice.ID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -149,16 +158,17 @@ func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dt
return dto.NewDeviceResponse(updatedDevice) return dto.NewDeviceResponse(updatedDevice)
} }
func (s *deviceService) DeleteDevice(id uint) error { func (s *deviceService) DeleteDevice(ctx context.Context, id uint) error {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteDevice")
// 检查设备是否存在 // 检查设备是否存在
_, err := s.deviceRepo.FindByID(id) _, err := s.deviceRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return err // 如果未找到,会返回 gorm.ErrRecordNotFound return err // 如果未找到,会返回 gorm.ErrRecordNotFound
} }
// 在删除前检查设备是否被任务使用 // 在删除前检查设备是否被任务使用
inUse, err := s.deviceRepo.IsDeviceInUse(id) inUse, err := s.deviceRepo.IsDeviceInUse(serviceCtx, id)
if err != nil { if err != nil {
// 如果检查过程中发生数据库错误,则返回错误 // 如果检查过程中发生数据库错误,则返回错误
return fmt.Errorf("检查设备使用情况失败: %w", err) return fmt.Errorf("检查设备使用情况失败: %w", err)
@@ -169,17 +179,18 @@ func (s *deviceService) DeleteDevice(id uint) error {
} }
// 只有在未被使用时,才执行删除操作 // 只有在未被使用时,才执行删除操作
return s.deviceRepo.Delete(id) return s.deviceRepo.Delete(serviceCtx, id)
} }
func (s *deviceService) ManualControl(id uint, req *dto.ManualControlDeviceRequest) error { func (s *deviceService) ManualControl(ctx context.Context, id uint, req *dto.ManualControlDeviceRequest) error {
dev, err := s.deviceRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "ManualControl")
dev, err := s.deviceRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
if req.Action == nil { if req.Action == nil {
return s.deviceDomainSvc.Collect(dev.AreaControllerID, []*models.Device{dev}) return s.deviceDomainSvc.Collect(serviceCtx, dev.AreaControllerID, []*models.Device{dev})
} else { } else {
action := device.DeviceActionStart action := device.DeviceActionStart
switch *req.Action { switch *req.Action {
@@ -190,13 +201,14 @@ func (s *deviceService) ManualControl(id uint, req *dto.ManualControlDeviceReque
default: default:
return errors.New("invalid action") return errors.New("invalid action")
} }
return s.deviceDomainSvc.Switch(dev, action) return s.deviceDomainSvc.Switch(serviceCtx, dev, action)
} }
} }
// --- Area Controllers --- // --- Area Controllers ---
func (s *deviceService) CreateAreaController(req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) { func (s *deviceService) CreateAreaController(ctx context.Context, req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateAreaController")
propertiesJSON, err := json.Marshal(req.Properties) propertiesJSON, err := json.Marshal(req.Properties)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -213,31 +225,34 @@ func (s *deviceService) CreateAreaController(req *dto.CreateAreaControllerReques
return nil, err return nil, err
} }
if err := s.areaControllerRepo.Create(ac); err != nil { if err := s.areaControllerRepo.Create(serviceCtx, ac); err != nil {
return nil, err return nil, err
} }
return dto.NewAreaControllerResponse(ac) return dto.NewAreaControllerResponse(ac)
} }
func (s *deviceService) GetAreaController(id uint) (*dto.AreaControllerResponse, error) { func (s *deviceService) GetAreaController(ctx context.Context, id uint) (*dto.AreaControllerResponse, error) {
ac, err := s.areaControllerRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetAreaController")
ac, err := s.areaControllerRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewAreaControllerResponse(ac) return dto.NewAreaControllerResponse(ac)
} }
func (s *deviceService) ListAreaControllers() ([]*dto.AreaControllerResponse, error) { func (s *deviceService) ListAreaControllers(ctx context.Context) ([]*dto.AreaControllerResponse, error) {
acs, err := s.areaControllerRepo.ListAll() serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListAreaControllers")
acs, err := s.areaControllerRepo.ListAll(serviceCtx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewListAreaControllerResponse(acs) return dto.NewListAreaControllerResponse(acs)
} }
func (s *deviceService) UpdateAreaController(id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) { func (s *deviceService) UpdateAreaController(ctx context.Context, id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) {
existingAC, err := s.areaControllerRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateAreaController")
existingAC, err := s.areaControllerRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -256,23 +271,24 @@ func (s *deviceService) UpdateAreaController(id uint, req *dto.UpdateAreaControl
return nil, err return nil, err
} }
if err := s.areaControllerRepo.Update(existingAC); err != nil { if err := s.areaControllerRepo.Update(serviceCtx, existingAC); err != nil {
return nil, err return nil, err
} }
return dto.NewAreaControllerResponse(existingAC) return dto.NewAreaControllerResponse(existingAC)
} }
func (s *deviceService) DeleteAreaController(id uint) error { func (s *deviceService) DeleteAreaController(ctx context.Context, id uint) error {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteAreaController")
// 1. 检查是否存在 // 1. 检查是否存在
_, err := s.areaControllerRepo.FindByID(id) _, err := s.areaControllerRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return err // 如果未找到gorm会返回 ErrRecordNotFound return err // 如果未找到gorm会返回 ErrRecordNotFound
} }
// 2. 检查是否被使用(业务逻辑) // 2. 检查是否被使用(业务逻辑)
inUse, err := s.deviceRepo.IsAreaControllerInUse(id) inUse, err := s.deviceRepo.IsAreaControllerInUse(serviceCtx, id)
if err != nil { if err != nil {
return err // 返回数据库检查错误 return err // 返回数据库检查错误
} }
@@ -281,12 +297,13 @@ func (s *deviceService) DeleteAreaController(id uint) error {
} }
// 3. 执行删除 // 3. 执行删除
return s.areaControllerRepo.Delete(id) return s.areaControllerRepo.Delete(serviceCtx, id)
} }
// --- Device Templates --- // --- Device Templates ---
func (s *deviceService) CreateDeviceTemplate(req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) { func (s *deviceService) CreateDeviceTemplate(ctx context.Context, req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreateDeviceTemplate")
commandsJSON, err := json.Marshal(req.Commands) commandsJSON, err := json.Marshal(req.Commands)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -310,31 +327,34 @@ func (s *deviceService) CreateDeviceTemplate(req *dto.CreateDeviceTemplateReques
return nil, err return nil, err
} }
if err := s.deviceTemplateRepo.Create(deviceTemplate); err != nil { if err := s.deviceTemplateRepo.Create(serviceCtx, deviceTemplate); err != nil {
return nil, err return nil, err
} }
return dto.NewDeviceTemplateResponse(deviceTemplate) return dto.NewDeviceTemplateResponse(deviceTemplate)
} }
func (s *deviceService) GetDeviceTemplate(id uint) (*dto.DeviceTemplateResponse, error) { func (s *deviceService) GetDeviceTemplate(ctx context.Context, id uint) (*dto.DeviceTemplateResponse, error) {
deviceTemplate, err := s.deviceTemplateRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetDeviceTemplate")
deviceTemplate, err := s.deviceTemplateRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewDeviceTemplateResponse(deviceTemplate) return dto.NewDeviceTemplateResponse(deviceTemplate)
} }
func (s *deviceService) ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error) { func (s *deviceService) ListDeviceTemplates(ctx context.Context) ([]*dto.DeviceTemplateResponse, error) {
deviceTemplates, err := s.deviceTemplateRepo.ListAll() serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListDeviceTemplates")
deviceTemplates, err := s.deviceTemplateRepo.ListAll(serviceCtx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dto.NewListDeviceTemplateResponse(deviceTemplates) return dto.NewListDeviceTemplateResponse(deviceTemplates)
} }
func (s *deviceService) UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) { func (s *deviceService) UpdateDeviceTemplate(ctx context.Context, id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) {
existingDeviceTemplate, err := s.deviceTemplateRepo.FindByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateDeviceTemplate")
existingDeviceTemplate, err := s.deviceTemplateRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -360,23 +380,24 @@ func (s *deviceService) UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTempl
return nil, err return nil, err
} }
if err := s.deviceTemplateRepo.Update(existingDeviceTemplate); err != nil { if err := s.deviceTemplateRepo.Update(serviceCtx, existingDeviceTemplate); err != nil {
return nil, err return nil, err
} }
return dto.NewDeviceTemplateResponse(existingDeviceTemplate) return dto.NewDeviceTemplateResponse(existingDeviceTemplate)
} }
func (s *deviceService) DeleteDeviceTemplate(id uint) error { func (s *deviceService) DeleteDeviceTemplate(ctx context.Context, id uint) error {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeleteDeviceTemplate")
// 1. 检查是否存在 // 1. 检查是否存在
_, err := s.deviceTemplateRepo.FindByID(id) _, err := s.deviceTemplateRepo.FindByID(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
// 2. 检查是否被使用(业务逻辑) // 2. 检查是否被使用(业务逻辑)
inUse, err := s.deviceTemplateRepo.IsInUse(id) inUse, err := s.deviceTemplateRepo.IsInUse(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
@@ -385,5 +406,5 @@ func (s *deviceService) DeleteDeviceTemplate(id uint) error {
} }
// 3. 执行删除 // 3. 执行删除
return s.deviceTemplateRepo.Delete(id) return s.deviceTemplateRepo.Delete(serviceCtx, id)
} }

View File

@@ -1,35 +1,39 @@
package service package service
import ( import (
"context"
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"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/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
) )
// MonitorService 定义了监控相关的业务逻辑服务接口 // MonitorService 定义了监控相关的业务逻辑服务接口
type MonitorService interface { type MonitorService interface {
ListSensorData(req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error) ListSensorData(ctx context.Context, req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error)
ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error) ListDeviceCommandLogs(ctx context.Context, req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error)
ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error) ListPlanExecutionLogs(ctx context.Context, req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error)
ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error) ListTaskExecutionLogs(ctx context.Context, req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error)
ListPendingCollections(req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error) ListPendingCollections(ctx context.Context, req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error)
ListUserActionLogs(req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error) ListUserActionLogs(ctx context.Context, req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error)
ListRawMaterialPurchases(req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) ListRawMaterialPurchases(ctx context.Context, req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error)
ListRawMaterialStockLogs(req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) ListRawMaterialStockLogs(ctx context.Context, req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error)
ListFeedUsageRecords(req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) ListFeedUsageRecords(ctx context.Context, req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error)
ListMedicationLogs(req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) ListMedicationLogs(ctx context.Context, req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error)
ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error) ListPigBatchLogs(ctx context.Context, req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error)
ListWeighingBatches(req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error) ListWeighingBatches(ctx context.Context, req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error)
ListWeighingRecords(req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error) ListWeighingRecords(ctx context.Context, req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error)
ListPigTransferLogs(req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error) ListPigTransferLogs(ctx context.Context, req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error)
ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error) ListPigSickLogs(ctx context.Context, req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error)
ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error) ListPigPurchases(ctx context.Context, req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error)
ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error) ListPigSales(ctx context.Context, req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error)
ListNotifications(req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error) ListNotifications(ctx context.Context, req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error)
} }
// monitorService 是 MonitorService 接口的具体实现 // monitorService 是 MonitorService 接口的具体实现
type monitorService struct { type monitorService struct {
ctx context.Context
sensorDataRepo repository.SensorDataRepository sensorDataRepo repository.SensorDataRepository
deviceCommandLogRepo repository.DeviceCommandLogRepository deviceCommandLogRepo repository.DeviceCommandLogRepository
executionLogRepo repository.ExecutionLogRepository executionLogRepo repository.ExecutionLogRepository
@@ -48,6 +52,7 @@ type monitorService struct {
// NewMonitorService 创建一个新的 MonitorService 实例 // NewMonitorService 创建一个新的 MonitorService 实例
func NewMonitorService( func NewMonitorService(
ctx context.Context,
sensorDataRepo repository.SensorDataRepository, sensorDataRepo repository.SensorDataRepository,
deviceCommandLogRepo repository.DeviceCommandLogRepository, deviceCommandLogRepo repository.DeviceCommandLogRepository,
executionLogRepo repository.ExecutionLogRepository, executionLogRepo repository.ExecutionLogRepository,
@@ -64,6 +69,7 @@ func NewMonitorService(
notificationRepo repository.NotificationRepository, notificationRepo repository.NotificationRepository,
) MonitorService { ) MonitorService {
return &monitorService{ return &monitorService{
ctx: ctx,
sensorDataRepo: sensorDataRepo, sensorDataRepo: sensorDataRepo,
deviceCommandLogRepo: deviceCommandLogRepo, deviceCommandLogRepo: deviceCommandLogRepo,
executionLogRepo: executionLogRepo, executionLogRepo: executionLogRepo,
@@ -82,7 +88,8 @@ func NewMonitorService(
} }
// ListSensorData 负责处理查询传感器数据列表的业务逻辑 // ListSensorData 负责处理查询传感器数据列表的业务逻辑
func (s *monitorService) ListSensorData(req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error) { func (s *monitorService) ListSensorData(ctx context.Context, req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListSensorData")
opts := repository.SensorDataListOptions{ opts := repository.SensorDataListOptions{
DeviceID: req.DeviceID, DeviceID: req.DeviceID,
OrderBy: req.OrderBy, OrderBy: req.OrderBy,
@@ -94,7 +101,7 @@ func (s *monitorService) ListSensorData(req *dto.ListSensorDataRequest) (*dto.Li
opts.SensorType = &sensorType opts.SensorType = &sensorType
} }
data, total, err := s.sensorDataRepo.List(opts, req.Page, req.PageSize) data, total, err := s.sensorDataRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -103,7 +110,8 @@ func (s *monitorService) ListSensorData(req *dto.ListSensorDataRequest) (*dto.Li
} }
// ListDeviceCommandLogs 负责处理查询设备命令日志列表的业务逻辑 // ListDeviceCommandLogs 负责处理查询设备命令日志列表的业务逻辑
func (s *monitorService) ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error) { func (s *monitorService) ListDeviceCommandLogs(ctx context.Context, req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListDeviceCommandLogs")
opts := repository.DeviceCommandLogListOptions{ opts := repository.DeviceCommandLogListOptions{
DeviceID: req.DeviceID, DeviceID: req.DeviceID,
ReceivedSuccess: req.ReceivedSuccess, ReceivedSuccess: req.ReceivedSuccess,
@@ -112,7 +120,7 @@ func (s *monitorService) ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequ
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.deviceCommandLogRepo.List(opts, req.Page, req.PageSize) data, total, err := s.deviceCommandLogRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -121,7 +129,8 @@ func (s *monitorService) ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequ
} }
// ListPlanExecutionLogs 负责处理查询计划执行日志列表的业务逻辑 // ListPlanExecutionLogs 负责处理查询计划执行日志列表的业务逻辑
func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error) { func (s *monitorService) ListPlanExecutionLogs(ctx context.Context, req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPlanExecutionLogs")
opts := repository.PlanExecutionLogListOptions{ opts := repository.PlanExecutionLogListOptions{
PlanID: req.PlanID, PlanID: req.PlanID,
OrderBy: req.OrderBy, OrderBy: req.OrderBy,
@@ -133,7 +142,7 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ
opts.Status = &status opts.Status = &status
} }
planLogs, total, err := s.executionLogRepo.ListPlanExecutionLogs(opts, req.Page, req.PageSize) planLogs, total, err := s.executionLogRepo.ListPlanExecutionLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -151,7 +160,7 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ
planIds = append(planIds, datum.PlanID) planIds = append(planIds, datum.PlanID)
} }
} }
plans, err := s.planRepository.GetPlansByIDs(planIds) plans, err := s.planRepository.GetPlansByIDs(serviceCtx, planIds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -159,7 +168,8 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ
} }
// ListTaskExecutionLogs 负责处理查询任务执行日志列表的业务逻辑 // ListTaskExecutionLogs 负责处理查询任务执行日志列表的业务逻辑
func (s *monitorService) ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error) { func (s *monitorService) ListTaskExecutionLogs(ctx context.Context, req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListTaskExecutionLogs")
opts := repository.TaskExecutionLogListOptions{ opts := repository.TaskExecutionLogListOptions{
PlanExecutionLogID: req.PlanExecutionLogID, PlanExecutionLogID: req.PlanExecutionLogID,
TaskID: req.TaskID, TaskID: req.TaskID,
@@ -172,7 +182,7 @@ func (s *monitorService) ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequ
opts.Status = &status opts.Status = &status
} }
data, total, err := s.executionLogRepo.ListTaskExecutionLogs(opts, req.Page, req.PageSize) data, total, err := s.executionLogRepo.ListTaskExecutionLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -181,7 +191,8 @@ func (s *monitorService) ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequ
} }
// ListPendingCollections 负责处理查询待采集请求列表的业务逻辑 // ListPendingCollections 负责处理查询待采集请求列表的业务逻辑
func (s *monitorService) ListPendingCollections(req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error) { func (s *monitorService) ListPendingCollections(ctx context.Context, req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPendingCollections")
opts := repository.PendingCollectionListOptions{ opts := repository.PendingCollectionListOptions{
DeviceID: req.DeviceID, DeviceID: req.DeviceID,
OrderBy: req.OrderBy, OrderBy: req.OrderBy,
@@ -193,7 +204,7 @@ func (s *monitorService) ListPendingCollections(req *dto.ListPendingCollectionRe
opts.Status = &status opts.Status = &status
} }
data, total, err := s.pendingCollectionRepo.List(opts, req.Page, req.PageSize) data, total, err := s.pendingCollectionRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -202,7 +213,8 @@ func (s *monitorService) ListPendingCollections(req *dto.ListPendingCollectionRe
} }
// ListUserActionLogs 负责处理查询用户操作日志列表的业务逻辑 // ListUserActionLogs 负责处理查询用户操作日志列表的业务逻辑
func (s *monitorService) ListUserActionLogs(req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error) { func (s *monitorService) ListUserActionLogs(ctx context.Context, req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListUserActionLogs")
opts := repository.UserActionLogListOptions{ opts := repository.UserActionLogListOptions{
UserID: req.UserID, UserID: req.UserID,
Username: req.Username, Username: req.Username,
@@ -216,7 +228,7 @@ func (s *monitorService) ListUserActionLogs(req *dto.ListUserActionLogRequest) (
opts.Status = &status opts.Status = &status
} }
data, total, err := s.userActionLogRepo.List(opts, req.Page, req.PageSize) data, total, err := s.userActionLogRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -225,7 +237,8 @@ func (s *monitorService) ListUserActionLogs(req *dto.ListUserActionLogRequest) (
} }
// ListRawMaterialPurchases 负责处理查询原料采购记录列表的业务逻辑 // ListRawMaterialPurchases 负责处理查询原料采购记录列表的业务逻辑
func (s *monitorService) ListRawMaterialPurchases(req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) { func (s *monitorService) ListRawMaterialPurchases(ctx context.Context, req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterialPurchases")
opts := repository.RawMaterialPurchaseListOptions{ opts := repository.RawMaterialPurchaseListOptions{
RawMaterialID: req.RawMaterialID, RawMaterialID: req.RawMaterialID,
Supplier: req.Supplier, Supplier: req.Supplier,
@@ -234,7 +247,7 @@ func (s *monitorService) ListRawMaterialPurchases(req *dto.ListRawMaterialPurcha
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.rawMaterialRepo.ListRawMaterialPurchases(opts, req.Page, req.PageSize) data, total, err := s.rawMaterialRepo.ListRawMaterialPurchases(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -243,7 +256,8 @@ func (s *monitorService) ListRawMaterialPurchases(req *dto.ListRawMaterialPurcha
} }
// ListRawMaterialStockLogs 负责处理查询原料库存日志列表的业务逻辑 // ListRawMaterialStockLogs 负责处理查询原料库存日志列表的业务逻辑
func (s *monitorService) ListRawMaterialStockLogs(req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) { func (s *monitorService) ListRawMaterialStockLogs(ctx context.Context, req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListRawMaterialStockLogs")
opts := repository.RawMaterialStockLogListOptions{ opts := repository.RawMaterialStockLogListOptions{
RawMaterialID: req.RawMaterialID, RawMaterialID: req.RawMaterialID,
SourceID: req.SourceID, SourceID: req.SourceID,
@@ -256,7 +270,7 @@ func (s *monitorService) ListRawMaterialStockLogs(req *dto.ListRawMaterialStockL
opts.SourceType = &sourceType opts.SourceType = &sourceType
} }
data, total, err := s.rawMaterialRepo.ListRawMaterialStockLogs(opts, req.Page, req.PageSize) data, total, err := s.rawMaterialRepo.ListRawMaterialStockLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -265,7 +279,8 @@ func (s *monitorService) ListRawMaterialStockLogs(req *dto.ListRawMaterialStockL
} }
// ListFeedUsageRecords 负责处理查询饲料使用记录列表的业务逻辑 // ListFeedUsageRecords 负责处理查询饲料使用记录列表的业务逻辑
func (s *monitorService) ListFeedUsageRecords(req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) { func (s *monitorService) ListFeedUsageRecords(ctx context.Context, req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListFeedUsageRecords")
opts := repository.FeedUsageRecordListOptions{ opts := repository.FeedUsageRecordListOptions{
PenID: req.PenID, PenID: req.PenID,
FeedFormulaID: req.FeedFormulaID, FeedFormulaID: req.FeedFormulaID,
@@ -275,7 +290,7 @@ func (s *monitorService) ListFeedUsageRecords(req *dto.ListFeedUsageRecordReques
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.rawMaterialRepo.ListFeedUsageRecords(opts, req.Page, req.PageSize) data, total, err := s.rawMaterialRepo.ListFeedUsageRecords(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -284,7 +299,8 @@ func (s *monitorService) ListFeedUsageRecords(req *dto.ListFeedUsageRecordReques
} }
// ListMedicationLogs 负责处理查询用药记录列表的业务逻辑 // ListMedicationLogs 负责处理查询用药记录列表的业务逻辑
func (s *monitorService) ListMedicationLogs(req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) { func (s *monitorService) ListMedicationLogs(ctx context.Context, req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListMedicationLogs")
opts := repository.MedicationLogListOptions{ opts := repository.MedicationLogListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
MedicationID: req.MedicationID, MedicationID: req.MedicationID,
@@ -298,7 +314,7 @@ func (s *monitorService) ListMedicationLogs(req *dto.ListMedicationLogRequest) (
opts.Reason = &reason opts.Reason = &reason
} }
data, total, err := s.medicationRepo.ListMedicationLogs(opts, req.Page, req.PageSize) data, total, err := s.medicationRepo.ListMedicationLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -307,7 +323,8 @@ func (s *monitorService) ListMedicationLogs(req *dto.ListMedicationLogRequest) (
} }
// ListPigBatchLogs 负责处理查询猪批次日志列表的业务逻辑 // ListPigBatchLogs 负责处理查询猪批次日志列表的业务逻辑
func (s *monitorService) ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error) { func (s *monitorService) ListPigBatchLogs(ctx context.Context, req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigBatchLogs")
opts := repository.PigBatchLogListOptions{ opts := repository.PigBatchLogListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
OperatorID: req.OperatorID, OperatorID: req.OperatorID,
@@ -320,7 +337,7 @@ func (s *monitorService) ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto
opts.ChangeType = &changeType opts.ChangeType = &changeType
} }
data, total, err := s.pigBatchLogRepo.List(opts, req.Page, req.PageSize) data, total, err := s.pigBatchLogRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -329,7 +346,8 @@ func (s *monitorService) ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto
} }
// ListWeighingBatches 负责处理查询批次称重记录列表的业务逻辑 // ListWeighingBatches 负责处理查询批次称重记录列表的业务逻辑
func (s *monitorService) ListWeighingBatches(req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error) { func (s *monitorService) ListWeighingBatches(ctx context.Context, req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListWeighingBatches")
opts := repository.WeighingBatchListOptions{ opts := repository.WeighingBatchListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
OrderBy: req.OrderBy, OrderBy: req.OrderBy,
@@ -337,7 +355,7 @@ func (s *monitorService) ListWeighingBatches(req *dto.ListWeighingBatchRequest)
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.pigBatchRepo.ListWeighingBatches(opts, req.Page, req.PageSize) data, total, err := s.pigBatchRepo.ListWeighingBatches(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -346,7 +364,8 @@ func (s *monitorService) ListWeighingBatches(req *dto.ListWeighingBatchRequest)
} }
// ListWeighingRecords 负责处理查询单次称重记录列表的业务逻辑 // ListWeighingRecords 负责处理查询单次称重记录列表的业务逻辑
func (s *monitorService) ListWeighingRecords(req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error) { func (s *monitorService) ListWeighingRecords(ctx context.Context, req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListWeighingRecords")
opts := repository.WeighingRecordListOptions{ opts := repository.WeighingRecordListOptions{
WeighingBatchID: req.WeighingBatchID, WeighingBatchID: req.WeighingBatchID,
PenID: req.PenID, PenID: req.PenID,
@@ -356,7 +375,7 @@ func (s *monitorService) ListWeighingRecords(req *dto.ListWeighingRecordRequest)
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.pigBatchRepo.ListWeighingRecords(opts, req.Page, req.PageSize) data, total, err := s.pigBatchRepo.ListWeighingRecords(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -365,7 +384,8 @@ func (s *monitorService) ListWeighingRecords(req *dto.ListWeighingRecordRequest)
} }
// ListPigTransferLogs 负责处理查询猪只迁移日志列表的业务逻辑 // ListPigTransferLogs 负责处理查询猪只迁移日志列表的业务逻辑
func (s *monitorService) ListPigTransferLogs(req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error) { func (s *monitorService) ListPigTransferLogs(ctx context.Context, req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigTransferLogs")
opts := repository.PigTransferLogListOptions{ opts := repository.PigTransferLogListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
PenID: req.PenID, PenID: req.PenID,
@@ -380,7 +400,7 @@ func (s *monitorService) ListPigTransferLogs(req *dto.ListPigTransferLogRequest)
opts.TransferType = &transferType opts.TransferType = &transferType
} }
data, total, err := s.pigTransferLogRepo.ListPigTransferLogs(opts, req.Page, req.PageSize) data, total, err := s.pigTransferLogRepo.ListPigTransferLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -389,7 +409,8 @@ func (s *monitorService) ListPigTransferLogs(req *dto.ListPigTransferLogRequest)
} }
// ListPigSickLogs 负责处理查询病猪日志列表的业务逻辑 // ListPigSickLogs 负责处理查询病猪日志列表的业务逻辑
func (s *monitorService) ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error) { func (s *monitorService) ListPigSickLogs(ctx context.Context, req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigSickLogs")
opts := repository.PigSickLogListOptions{ opts := repository.PigSickLogListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
PenID: req.PenID, PenID: req.PenID,
@@ -407,7 +428,7 @@ func (s *monitorService) ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.L
opts.TreatmentLocation = &treatmentLocation opts.TreatmentLocation = &treatmentLocation
} }
data, total, err := s.pigSickLogRepo.ListPigSickLogs(opts, req.Page, req.PageSize) data, total, err := s.pigSickLogRepo.ListPigSickLogs(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -416,7 +437,8 @@ func (s *monitorService) ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.L
} }
// ListPigPurchases 负责处理查询猪只采购记录列表的业务逻辑 // ListPigPurchases 负责处理查询猪只采购记录列表的业务逻辑
func (s *monitorService) ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error) { func (s *monitorService) ListPigPurchases(ctx context.Context, req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigPurchases")
opts := repository.PigPurchaseListOptions{ opts := repository.PigPurchaseListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
Supplier: req.Supplier, Supplier: req.Supplier,
@@ -426,7 +448,7 @@ func (s *monitorService) ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.pigTradeRepo.ListPigPurchases(opts, req.Page, req.PageSize) data, total, err := s.pigTradeRepo.ListPigPurchases(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -435,7 +457,8 @@ func (s *monitorService) ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto
} }
// ListPigSales 负责处理查询猪只销售记录列表的业务逻辑 // ListPigSales 负责处理查询猪只销售记录列表的业务逻辑
func (s *monitorService) ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error) { func (s *monitorService) ListPigSales(ctx context.Context, req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigSales")
opts := repository.PigSaleListOptions{ opts := repository.PigSaleListOptions{
PigBatchID: req.PigBatchID, PigBatchID: req.PigBatchID,
Buyer: req.Buyer, Buyer: req.Buyer,
@@ -445,7 +468,7 @@ func (s *monitorService) ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPig
EndTime: req.EndTime, EndTime: req.EndTime,
} }
data, total, err := s.pigTradeRepo.ListPigSales(opts, req.Page, req.PageSize) data, total, err := s.pigTradeRepo.ListPigSales(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -454,7 +477,8 @@ func (s *monitorService) ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPig
} }
// ListNotifications 负责处理查询通知列表的业务逻辑 // ListNotifications 负责处理查询通知列表的业务逻辑
func (s *monitorService) ListNotifications(req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error) { func (s *monitorService) ListNotifications(ctx context.Context, req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListNotifications")
opts := repository.NotificationListOptions{ opts := repository.NotificationListOptions{
UserID: req.UserID, UserID: req.UserID,
NotifierType: req.NotifierType, NotifierType: req.NotifierType,
@@ -465,7 +489,7 @@ func (s *monitorService) ListNotifications(req *dto.ListNotificationRequest) (*d
Status: req.Status, Status: req.Status,
} }
data, total, err := s.notificationRepo.List(opts, req.Page, req.PageSize) data, total, err := s.notificationRepo.List(serviceCtx, opts, req.Page, req.PageSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,6 +1,7 @@
package service package service
import ( import (
"context"
"time" "time"
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
@@ -11,47 +12,47 @@ import (
// PigBatchService 接口定义保持不变,继续作为应用层对外的契约。 // PigBatchService 接口定义保持不变,继续作为应用层对外的契约。
type PigBatchService interface { type PigBatchService interface {
CreatePigBatch(operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) CreatePigBatch(ctx context.Context, operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error)
GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) GetPigBatch(ctx context.Context, id uint) (*dto.PigBatchResponseDTO, error)
UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) UpdatePigBatch(ctx context.Context, id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error)
DeletePigBatch(id uint) error DeletePigBatch(ctx context.Context, id uint) error
ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) ListPigBatches(ctx context.Context, isActive *bool) ([]*dto.PigBatchResponseDTO, error)
// Pig Pen Management // Pig Pen Management
AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error AssignEmptyPensToBatch(ctx context.Context, batchID uint, penIDs []uint, operatorID uint) error
ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error ReclassifyPenToNewBatch(ctx context.Context, fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error
RemoveEmptyPenFromBatch(batchID uint, penID uint) error RemoveEmptyPenFromBatch(ctx context.Context, batchID uint, penID uint) error
MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error MovePigsIntoPen(ctx context.Context, batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error
// Trade Sub-service // Trade Sub-service
SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error SellPigs(ctx context.Context, batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
BuyPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error BuyPigs(ctx context.Context, batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
// Transfer Sub-service // Transfer Sub-service
TransferPigsAcrossBatches(sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error TransferPigsAcrossBatches(ctx context.Context, sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error
TransferPigsWithinBatch(batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error TransferPigsWithinBatch(ctx context.Context, batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error
// Sick Pig Management // Sick Pig Management
RecordSickPigs(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error RecordSickPigs(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
RecordSickPigRecovery(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error RecordSickPigRecovery(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
RecordSickPigDeath(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error RecordSickPigDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
RecordSickPigCull(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error RecordSickPigCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
// Normal Pig Management // Normal Pig Management
RecordDeath(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error RecordDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error
RecordCull(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error RecordCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error
} }
// pigBatchService 的实现现在依赖于领域服务接口。 // pigBatchService 的实现现在依赖于领域服务接口。
type pigBatchService struct { type pigBatchService struct {
logger *logs.Logger ctx context.Context
domainService domain_pig.PigBatchService // 依赖注入领域服务 domainService domain_pig.PigBatchService
} }
// NewPigBatchService 构造函数被修改,以注入领域服务。 // NewPigBatchService 构造函数被修改,以注入领域服务。
func NewPigBatchService(domainService domain_pig.PigBatchService, logger *logs.Logger) PigBatchService { func NewPigBatchService(ctx context.Context, domainService domain_pig.PigBatchService) PigBatchService {
return &pigBatchService{ return &pigBatchService{
logger: logger, ctx: ctx,
domainService: domainService, domainService: domainService,
} }
} }
@@ -78,7 +79,8 @@ func (s *pigBatchService) toPigBatchResponseDTO(batch *models.PigBatch, currentT
} }
// CreatePigBatch 现在将请求委托给领域服务处理。 // CreatePigBatch 现在将请求委托给领域服务处理。
func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) { func (s *pigBatchService) CreatePigBatch(ctx context.Context, operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "CreatePigBatch")
// 1. DTO -> 领域模型 // 1. DTO -> 领域模型
batch := &models.PigBatch{ batch := &models.PigBatch{
BatchNumber: dto.BatchNumber, BatchNumber: dto.BatchNumber,
@@ -89,9 +91,9 @@ func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreat
} }
// 2. 调用领域服务 // 2. 调用领域服务
createdBatch, err := s.domainService.CreatePigBatch(operatorID, batch) createdBatch, err := s.domainService.CreatePigBatch(serviceCtx, operatorID, batch)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 创建猪批次失败: %v", err) logger.Errorf("应用层: 创建猪批次失败: %v", err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
@@ -100,31 +102,33 @@ func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreat
} }
// GetPigBatch 从领域服务获取数据并转换为DTO同时处理错误转换。 // GetPigBatch 从领域服务获取数据并转换为DTO同时处理错误转换。
func (s *pigBatchService) GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) { func (s *pigBatchService) GetPigBatch(ctx context.Context, id uint) (*dto.PigBatchResponseDTO, error) {
batch, err := s.domainService.GetPigBatch(id) serviceCtx, logger := logs.Trace(ctx, s.ctx, "GetPigBatch")
batch, err := s.domainService.GetPigBatch(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次失败, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 获取猪批次失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id) currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id) currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
return s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens), nil return s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens), nil
} }
// UpdatePigBatch 协调获取、更新和保存的流程,并处理错误转换。 // UpdatePigBatch 协调获取、更新和保存的流程,并处理错误转换。
func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) { func (s *pigBatchService) UpdatePigBatch(ctx context.Context, id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "UpdatePigBatch")
// 1. 先获取最新的领域模型 // 1. 先获取最新的领域模型
existingBatch, err := s.domainService.GetPigBatch(id) existingBatch, err := s.domainService.GetPigBatch(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 更新猪批次失败,获取原批次信息错误, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 更新猪批次失败,获取原批次信息错误, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
@@ -149,21 +153,21 @@ func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*
} }
// 3. 调用领域服务执行更新 // 3. 调用领域服务执行更新
updatedBatch, err := s.domainService.UpdatePigBatch(existingBatch) updatedBatch, err := s.domainService.UpdatePigBatch(serviceCtx, existingBatch)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 更新猪批次失败, ID: %d, 错误: %v", id, err) logger.Errorf("应用层: 更新猪批次失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
// 4. 填充猪群信息 // 4. 填充猪群信息
currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id) currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id) currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
@@ -172,33 +176,35 @@ func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*
} }
// DeletePigBatch 将删除操作委托给领域服务,并转换领域错误为应用层错误。 // DeletePigBatch 将删除操作委托给领域服务,并转换领域错误为应用层错误。
func (s *pigBatchService) DeletePigBatch(id uint) error { func (s *pigBatchService) DeletePigBatch(ctx context.Context, id uint) error {
err := s.domainService.DeletePigBatch(id) serviceCtx, logger := logs.Trace(ctx, s.ctx, "DeletePigBatch")
err := s.domainService.DeletePigBatch(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 删除猪批次失败, ID: %d, 错误: %v", id, err) logger.Errorf("应用层: 删除猪批次失败, ID: %d, 错误: %v", id, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// ListPigBatches 从领域服务获取列表并进行转换。 // ListPigBatches 从领域服务获取列表并进行转换。
func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) { func (s *pigBatchService) ListPigBatches(ctx context.Context, isActive *bool) ([]*dto.PigBatchResponseDTO, error) {
batches, err := s.domainService.ListPigBatches(isActive) serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListPigBatches")
batches, err := s.domainService.ListPigBatches(serviceCtx, isActive)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 批量查询猪批次失败: %v", err) logger.Errorf("应用层: 批量查询猪批次失败: %v", err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
var responseDTOs []*dto.PigBatchResponseDTO var responseDTOs []*dto.PigBatchResponseDTO
for _, batch := range batches { for _, batch := range batches {
currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(batch.ID) currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, batch.ID)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", batch.ID, err) logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", batch.ID, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(batch.ID) currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, batch.ID)
if err != nil { if err != nil {
s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", batch.ID, err) logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", batch.ID, err)
return nil, MapDomainError(err) return nil, MapDomainError(err)
} }
responseDTOs = append(responseDTOs, s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens)) responseDTOs = append(responseDTOs, s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens))
@@ -208,140 +214,154 @@ func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchRespons
} }
// AssignEmptyPensToBatch 委托给领域服务 // AssignEmptyPensToBatch 委托给领域服务
func (s *pigBatchService) AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error { func (s *pigBatchService) AssignEmptyPensToBatch(ctx context.Context, batchID uint, penIDs []uint, operatorID uint) error {
err := s.domainService.AssignEmptyPensToBatch(batchID, penIDs, operatorID) serviceCtx, logger := logs.Trace(ctx, s.ctx, "AssignEmptyPensToBatch")
err := s.domainService.AssignEmptyPensToBatch(serviceCtx, batchID, penIDs, operatorID)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 为猪批次分配空栏失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 为猪批次分配空栏失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// ReclassifyPenToNewBatch 委托给领域服务 // ReclassifyPenToNewBatch 委托给领域服务
func (s *pigBatchService) ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error { func (s *pigBatchService) ReclassifyPenToNewBatch(ctx context.Context, fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error {
err := s.domainService.ReclassifyPenToNewBatch(fromBatchID, toBatchID, penID, operatorID, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "ReclassifyPenToNewBatch")
err := s.domainService.ReclassifyPenToNewBatch(serviceCtx, fromBatchID, toBatchID, penID, operatorID, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 划拨猪栏到新批次失败, 源批次ID: %d, 错误: %v", fromBatchID, err) logger.Errorf("应用层: 划拨猪栏到新批次失败, 源批次ID: %d, 错误: %v", fromBatchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RemoveEmptyPenFromBatch 委托给领域服务 // RemoveEmptyPenFromBatch 委托给领域服务
func (s *pigBatchService) RemoveEmptyPenFromBatch(batchID uint, penID uint) error { func (s *pigBatchService) RemoveEmptyPenFromBatch(ctx context.Context, batchID uint, penID uint) error {
err := s.domainService.RemoveEmptyPenFromBatch(batchID, penID) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RemoveEmptyPenFromBatch")
err := s.domainService.RemoveEmptyPenFromBatch(serviceCtx, batchID, penID)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 从猪批次移除空栏失败, 批次ID: %d, 猪栏ID: %d, 错误: %v", batchID, penID, err) logger.Errorf("应用层: 从猪批次移除空栏失败, 批次ID: %d, 猪栏ID: %d, 错误: %v", batchID, penID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// MovePigsIntoPen 委托给领域服务 // MovePigsIntoPen 委托给领域服务
func (s *pigBatchService) MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error { func (s *pigBatchService) MovePigsIntoPen(ctx context.Context, batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error {
err := s.domainService.MovePigsIntoPen(batchID, toPenID, quantity, operatorID, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "MovePigsIntoPen")
err := s.domainService.MovePigsIntoPen(serviceCtx, batchID, toPenID, quantity, operatorID, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 将猪只移入猪栏失败, 批次ID: %d, 目标猪栏ID: %d, 错误: %v", batchID, toPenID, err) logger.Errorf("应用层: 将猪只移入猪栏失败, 批次ID: %d, 目标猪栏ID: %d, 错误: %v", batchID, toPenID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// SellPigs 委托给领域服务 // SellPigs 委托给领域服务
func (s *pigBatchService) SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error { func (s *pigBatchService) SellPigs(ctx context.Context, batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error {
err := s.domainService.SellPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID) serviceCtx, logger := logs.Trace(ctx, s.ctx, "SellPigs")
err := s.domainService.SellPigs(serviceCtx, batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 卖猪失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 卖猪失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// BuyPigs 委托给领域服务 // BuyPigs 委托给领域服务
func (s *pigBatchService) BuyPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error { func (s *pigBatchService) BuyPigs(ctx context.Context, batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error {
err := s.domainService.BuyPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID) serviceCtx, logger := logs.Trace(ctx, s.ctx, "BuyPigs")
err := s.domainService.BuyPigs(serviceCtx, batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 买猪失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 买猪失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// TransferPigsAcrossBatches 委托给领域服务 // TransferPigsAcrossBatches 委托给领域服务
func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error { func (s *pigBatchService) TransferPigsAcrossBatches(ctx context.Context, sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error {
err := s.domainService.TransferPigsAcrossBatches(sourceBatchID, destBatchID, fromPenID, toPenID, quantity, operatorID, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "TransferPigsAcrossBatches")
err := s.domainService.TransferPigsAcrossBatches(serviceCtx, sourceBatchID, destBatchID, fromPenID, toPenID, quantity, operatorID, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 跨群调栏失败, 源批次ID: %d, 错误: %v", sourceBatchID, err) logger.Errorf("应用层: 跨群调栏失败, 源批次ID: %d, 错误: %v", sourceBatchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// TransferPigsWithinBatch 委托给领域服务 // TransferPigsWithinBatch 委托给领域服务
func (s *pigBatchService) TransferPigsWithinBatch(batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error { func (s *pigBatchService) TransferPigsWithinBatch(ctx context.Context, batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error {
err := s.domainService.TransferPigsWithinBatch(batchID, fromPenID, toPenID, quantity, operatorID, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "TransferPigsWithinBatch")
err := s.domainService.TransferPigsWithinBatch(serviceCtx, batchID, fromPenID, toPenID, quantity, operatorID, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 群内调栏失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 群内调栏失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordSickPigs 委托给领域服务 // RecordSickPigs 委托给领域服务
func (s *pigBatchService) RecordSickPigs(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordSickPigs(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordSickPigs(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigs")
err := s.domainService.RecordSickPigs(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录病猪事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录病猪事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordSickPigRecovery 委托给领域服务 // RecordSickPigRecovery 委托给领域服务
func (s *pigBatchService) RecordSickPigRecovery(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordSickPigRecovery(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordSickPigRecovery(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigRecovery")
err := s.domainService.RecordSickPigRecovery(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录病猪康复事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录病猪康复事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordSickPigDeath 委托给领域服务 // RecordSickPigDeath 委托给领域服务
func (s *pigBatchService) RecordSickPigDeath(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordSickPigDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordSickPigDeath(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigDeath")
err := s.domainService.RecordSickPigDeath(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录病猪死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录病猪死亡事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordSickPigCull 委托给领域服务 // RecordSickPigCull 委托给领域服务
func (s *pigBatchService) RecordSickPigCull(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordSickPigCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordSickPigCull(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigCull")
err := s.domainService.RecordSickPigCull(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录病猪淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录病猪淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordDeath 委托给领域服务 // RecordDeath 委托给领域服务
func (s *pigBatchService) RecordDeath(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordDeath(operatorID, batchID, penID, quantity, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordDeath")
err := s.domainService.RecordDeath(serviceCtx, operatorID, batchID, penID, quantity, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录正常猪只死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录正常猪只死亡事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil
} }
// RecordCull 委托给领域服务 // RecordCull 委托给领域服务
func (s *pigBatchService) RecordCull(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { func (s *pigBatchService) RecordCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error {
err := s.domainService.RecordCull(operatorID, batchID, penID, quantity, happenedAt, remarks) serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordCull")
err := s.domainService.RecordCull(serviceCtx, operatorID, batchID, penID, quantity, happenedAt, remarks)
if err != nil { if err != nil {
s.logger.Errorf("应用层: 记录正常猪只淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) logger.Errorf("应用层: 记录正常猪只淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err)
return MapDomainError(err) return MapDomainError(err)
} }
return nil return nil

View File

@@ -1,6 +1,7 @@
package service package service
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
@@ -16,40 +17,41 @@ import (
// PigFarmService 提供了猪场资产管理的业务逻辑 // PigFarmService 提供了猪场资产管理的业务逻辑
type PigFarmService interface { type PigFarmService interface {
// PigHouse methods // PigHouse methods
CreatePigHouse(name, description string) (*dto.PigHouseResponse, error) CreatePigHouse(ctx context.Context, name, description string) (*dto.PigHouseResponse, error)
GetPigHouseByID(id uint) (*dto.PigHouseResponse, error) GetPigHouseByID(ctx context.Context, id uint) (*dto.PigHouseResponse, error)
ListPigHouses() ([]dto.PigHouseResponse, error) ListPigHouses(ctx context.Context) ([]dto.PigHouseResponse, error)
UpdatePigHouse(id uint, name, description string) (*dto.PigHouseResponse, error) UpdatePigHouse(ctx context.Context, id uint, name, description string) (*dto.PigHouseResponse, error)
DeletePigHouse(id uint) error DeletePigHouse(ctx context.Context, id uint) error
// Pen methods // Pen methods
CreatePen(penNumber string, houseID uint, capacity int) (*dto.PenResponse, error) CreatePen(ctx context.Context, penNumber string, houseID uint, capacity int) (*dto.PenResponse, error)
GetPenByID(id uint) (*dto.PenResponse, error) GetPenByID(ctx context.Context, id uint) (*dto.PenResponse, error)
ListPens() ([]*dto.PenResponse, error) ListPens(ctx context.Context) ([]*dto.PenResponse, error)
UpdatePen(id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error) UpdatePen(ctx context.Context, id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error)
DeletePen(id uint) error DeletePen(ctx context.Context, id uint) error
// UpdatePenStatus 更新猪栏状态 // UpdatePenStatus 更新猪栏状态
UpdatePenStatus(id uint, newStatus models.PenStatus) (*dto.PenResponse, error) UpdatePenStatus(ctx context.Context, id uint, newStatus models.PenStatus) (*dto.PenResponse, error)
} }
type pigFarmService struct { type pigFarmService struct {
logger *logs.Logger ctx context.Context
farmRepository repository.PigFarmRepository farmRepository repository.PigFarmRepository
penRepository repository.PigPenRepository penRepository repository.PigPenRepository
batchRepository repository.PigBatchRepository batchRepository repository.PigBatchRepository
pigBatchService domain_pig.PigBatchService // Add domain PigBatchService dependency pigBatchService domain_pig.PigBatchService
uow repository.UnitOfWork // 工作单元,用于事务管理 uow repository.UnitOfWork // 工作单元,用于事务管理
} }
// NewPigFarmService 创建一个新的 PigFarmService 实例 // NewPigFarmService 创建一个新的 PigFarmService 实例
func NewPigFarmService(farmRepository repository.PigFarmRepository, func NewPigFarmService(ctx context.Context,
farmRepository repository.PigFarmRepository,
penRepository repository.PigPenRepository, penRepository repository.PigPenRepository,
batchRepository repository.PigBatchRepository, batchRepository repository.PigBatchRepository,
pigBatchService domain_pig.PigBatchService, pigBatchService domain_pig.PigBatchService,
uow repository.UnitOfWork, uow repository.UnitOfWork,
logger *logs.Logger) PigFarmService { ) PigFarmService {
return &pigFarmService{ return &pigFarmService{
logger: logger, ctx: ctx,
farmRepository: farmRepository, farmRepository: farmRepository,
penRepository: penRepository, penRepository: penRepository,
batchRepository: batchRepository, batchRepository: batchRepository,
@@ -60,12 +62,13 @@ func NewPigFarmService(farmRepository repository.PigFarmRepository,
// --- PigHouse Implementation --- // --- PigHouse Implementation ---
func (s *pigFarmService) CreatePigHouse(name, description string) (*dto.PigHouseResponse, error) { func (s *pigFarmService) CreatePigHouse(ctx context.Context, name, description string) (*dto.PigHouseResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePigHouse")
house := &models.PigHouse{ house := &models.PigHouse{
Name: name, Name: name,
Description: description, Description: description,
} }
err := s.farmRepository.CreatePigHouse(house) err := s.farmRepository.CreatePigHouse(serviceCtx, house)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -76,8 +79,9 @@ func (s *pigFarmService) CreatePigHouse(name, description string) (*dto.PigHouse
}, nil }, nil
} }
func (s *pigFarmService) GetPigHouseByID(id uint) (*dto.PigHouseResponse, error) { func (s *pigFarmService) GetPigHouseByID(ctx context.Context, id uint) (*dto.PigHouseResponse, error) {
house, err := s.farmRepository.GetPigHouseByID(id) serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigHouseByID")
house, err := s.farmRepository.GetPigHouseByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -88,8 +92,9 @@ func (s *pigFarmService) GetPigHouseByID(id uint) (*dto.PigHouseResponse, error)
}, nil }, nil
} }
func (s *pigFarmService) ListPigHouses() ([]dto.PigHouseResponse, error) { func (s *pigFarmService) ListPigHouses(ctx context.Context) ([]dto.PigHouseResponse, error) {
houses, err := s.farmRepository.ListPigHouses() serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigHouses")
houses, err := s.farmRepository.ListPigHouses(serviceCtx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -104,13 +109,14 @@ func (s *pigFarmService) ListPigHouses() ([]dto.PigHouseResponse, error) {
return resp, nil return resp, nil
} }
func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*dto.PigHouseResponse, error) { func (s *pigFarmService) UpdatePigHouse(ctx context.Context, id uint, name, description string) (*dto.PigHouseResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePigHouse")
house := &models.PigHouse{ house := &models.PigHouse{
Model: gorm.Model{ID: id}, Model: gorm.Model{ID: id},
Name: name, Name: name,
Description: description, Description: description,
} }
rowsAffected, err := s.farmRepository.UpdatePigHouse(house) rowsAffected, err := s.farmRepository.UpdatePigHouse(serviceCtx, house)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -118,7 +124,7 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*dto
return nil, ErrHouseNotFound return nil, ErrHouseNotFound
} }
// 返回更新后的完整信息 // 返回更新后的完整信息
updatedHouse, err := s.farmRepository.GetPigHouseByID(id) updatedHouse, err := s.farmRepository.GetPigHouseByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -129,9 +135,10 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*dto
}, nil }, nil
} }
func (s *pigFarmService) DeletePigHouse(id uint) error { func (s *pigFarmService) DeletePigHouse(ctx context.Context, id uint) error {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePigHouse")
// 业务逻辑:检查猪舍是否包含猪栏 // 业务逻辑:检查猪舍是否包含猪栏
penCount, err := s.farmRepository.CountPensInHouse(id) penCount, err := s.farmRepository.CountPensInHouse(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
@@ -140,7 +147,7 @@ func (s *pigFarmService) DeletePigHouse(id uint) error {
} }
// 调用仓库层进行删除 // 调用仓库层进行删除
rowsAffected, err := s.farmRepository.DeletePigHouse(id) rowsAffected, err := s.farmRepository.DeletePigHouse(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
@@ -152,9 +159,10 @@ func (s *pigFarmService) DeletePigHouse(id uint) error {
// --- Pen Implementation --- // --- Pen Implementation ---
func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int) (*dto.PenResponse, error) { func (s *pigFarmService) CreatePen(ctx context.Context, penNumber string, houseID uint, capacity int) (*dto.PenResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CreatePen")
// 业务逻辑:验证所属猪舍是否存在 // 业务逻辑:验证所属猪舍是否存在
_, err := s.farmRepository.GetPigHouseByID(houseID) _, err := s.farmRepository.GetPigHouseByID(serviceCtx, houseID)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrHouseNotFound return nil, ErrHouseNotFound
@@ -168,7 +176,7 @@ func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int)
Capacity: capacity, Capacity: capacity,
Status: models.PenStatusEmpty, Status: models.PenStatusEmpty,
} }
err = s.penRepository.CreatePen(pen) err = s.penRepository.CreatePen(serviceCtx, pen)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -181,15 +189,16 @@ func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int)
}, nil }, nil
} }
func (s *pigFarmService) GetPenByID(id uint) (*dto.PenResponse, error) { func (s *pigFarmService) GetPenByID(ctx context.Context, id uint) (*dto.PenResponse, error) {
pen, err := s.penRepository.GetPenByID(id) serviceCtx, logger := logs.Trace(ctx, s.ctx, "GetPenByID")
pen, err := s.penRepository.GetPenByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(id) currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("获取猪栏 %d 存栏量失败: %v", id, err) logger.Errorf("获取猪栏 %d 存栏量失败: %v", id, err)
currentPigCount = 0 // 如果获取计数时出错则默认为0 currentPigCount = 0 // 如果获取计数时出错则默认为0
} }
@@ -209,17 +218,18 @@ func (s *pigFarmService) GetPenByID(id uint) (*dto.PenResponse, error) {
return response, nil return response, nil
} }
func (s *pigFarmService) ListPens() ([]*dto.PenResponse, error) { func (s *pigFarmService) ListPens(ctx context.Context) ([]*dto.PenResponse, error) {
pens, err := s.penRepository.ListPens() serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListPens")
pens, err := s.penRepository.ListPens(serviceCtx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var response []*dto.PenResponse var response []*dto.PenResponse
for _, pen := range pens { for _, pen := range pens {
currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(pen.ID) currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(serviceCtx, pen.ID)
if err != nil { if err != nil {
s.logger.Errorf("获取猪栏 %d 存栏量失败: %v", pen.ID, err) logger.Errorf("获取猪栏 %d 存栏量失败: %v", pen.ID, err)
currentPigCount = 0 // 如果获取计数时出错则默认为0 currentPigCount = 0 // 如果获取计数时出错则默认为0
} }
@@ -241,9 +251,10 @@ func (s *pigFarmService) ListPens() ([]*dto.PenResponse, error) {
return response, nil return response, nil
} }
func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error) { func (s *pigFarmService) UpdatePen(ctx context.Context, id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdatePen")
// 业务逻辑:验证所属猪舍是否存在 // 业务逻辑:验证所属猪舍是否存在
_, err := s.farmRepository.GetPigHouseByID(houseID) _, err := s.farmRepository.GetPigHouseByID(serviceCtx, houseID)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrHouseNotFound return nil, ErrHouseNotFound
@@ -258,7 +269,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa
Capacity: capacity, Capacity: capacity,
Status: status, Status: status,
} }
rowsAffected, err := s.penRepository.UpdatePen(pen) rowsAffected, err := s.penRepository.UpdatePen(serviceCtx, pen)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -266,7 +277,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa
return nil, ErrPenNotFound return nil, ErrPenNotFound
} }
// 返回更新后的完整信息 // 返回更新后的完整信息
updatedPen, err := s.penRepository.GetPenByID(id) updatedPen, err := s.penRepository.GetPenByID(serviceCtx, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -280,9 +291,10 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa
}, nil }, nil
} }
func (s *pigFarmService) DeletePen(id uint) error { func (s *pigFarmService) DeletePen(ctx context.Context, id uint) error {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "DeletePen")
// 业务逻辑:检查猪栏是否被活跃批次使用 // 业务逻辑:检查猪栏是否被活跃批次使用
pen, err := s.penRepository.GetPenByID(id) pen, err := s.penRepository.GetPenByID(serviceCtx, id)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return ErrPenNotFound // 猪栏不存在 return ErrPenNotFound // 猪栏不存在
@@ -293,7 +305,7 @@ func (s *pigFarmService) DeletePen(id uint) error {
// 检查猪栏是否关联了活跃批次 // 检查猪栏是否关联了活跃批次
// 注意pen.PigBatchID 是指针类型,需要检查是否为 nil // 注意pen.PigBatchID 是指针类型,需要检查是否为 nil
if pen.PigBatchID != nil && *pen.PigBatchID != 0 { if pen.PigBatchID != nil && *pen.PigBatchID != 0 {
pigBatch, err := s.batchRepository.GetPigBatchByID(*pen.PigBatchID) pigBatch, err := s.batchRepository.GetPigBatchByID(serviceCtx, *pen.PigBatchID)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err return err
} }
@@ -304,7 +316,7 @@ func (s *pigFarmService) DeletePen(id uint) error {
} }
// 调用仓库层进行删除 // 调用仓库层进行删除
rowsAffected, err := s.penRepository.DeletePen(id) rowsAffected, err := s.penRepository.DeletePen(serviceCtx, id)
if err != nil { if err != nil {
return err return err
} }
@@ -315,15 +327,16 @@ func (s *pigFarmService) DeletePen(id uint) error {
} }
// UpdatePenStatus 更新猪栏状态 // UpdatePenStatus 更新猪栏状态
func (s *pigFarmService) UpdatePenStatus(id uint, newStatus models.PenStatus) (*dto.PenResponse, error) { func (s *pigFarmService) UpdatePenStatus(ctx context.Context, id uint, newStatus models.PenStatus) (*dto.PenResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "UpdatePenStatus")
var updatedPen *models.Pen var updatedPen *models.Pen
err := s.uow.ExecuteInTransaction(func(tx *gorm.DB) error { err := s.uow.ExecuteInTransaction(func(tx *gorm.DB) error {
pen, err := s.penRepository.GetPenByIDTx(tx, id) pen, err := s.penRepository.GetPenByIDTx(serviceCtx, tx, id)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return ErrPenNotFound return ErrPenNotFound
} }
s.logger.Errorf("更新猪栏状态失败: 获取猪栏 %d 信息错误: %v", id, err) logger.Errorf("更新猪栏状态失败: 获取猪栏 %d 信息错误: %v", id, err)
return fmt.Errorf("获取猪栏 %d 信息失败: %w", id, err) return fmt.Errorf("获取猪栏 %d 信息失败: %w", id, err)
} }
@@ -348,15 +361,15 @@ func (s *pigFarmService) UpdatePenStatus(id uint, newStatus models.PenStatus) (*
"status": newStatus, "status": newStatus,
} }
if err := s.penRepository.UpdatePenFieldsTx(tx, id, updates); err != nil { if err := s.penRepository.UpdatePenFieldsTx(serviceCtx, tx, id, updates); err != nil {
s.logger.Errorf("更新猪栏 %d 状态失败: %v", id, err) logger.Errorf("更新猪栏 %d 状态失败: %v", id, err)
return fmt.Errorf("更新猪栏 %d 状态失败: %w", id, err) return fmt.Errorf("更新猪栏 %d 状态失败: %w", id, err)
} }
// 获取更新后的猪栏信息 // 获取更新后的猪栏信息
updatedPen, err = s.penRepository.GetPenByIDTx(tx, id) updatedPen, err = s.penRepository.GetPenByIDTx(serviceCtx, tx, id)
if err != nil { if err != nil {
s.logger.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %v", id, err) logger.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %v", id, err)
return fmt.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %w", id, err) return fmt.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %w", id, err)
} }
return nil return nil

View File

@@ -1,6 +1,7 @@
package service package service
import ( import (
"context"
"errors" "errors"
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
@@ -12,100 +13,103 @@ import (
// PlanService 定义了计划相关的应用服务接口 // PlanService 定义了计划相关的应用服务接口
type PlanService interface { type PlanService interface {
// CreatePlan 创建一个新的计划 // CreatePlan 创建一个新的计划
CreatePlan(req *dto.CreatePlanRequest) (*dto.PlanResponse, error) CreatePlan(ctx context.Context, req *dto.CreatePlanRequest) (*dto.PlanResponse, error)
// GetPlanByID 根据ID获取计划详情 // GetPlanByID 根据ID获取计划详情
GetPlanByID(id uint) (*dto.PlanResponse, error) GetPlanByID(ctx context.Context, id uint) (*dto.PlanResponse, error)
// ListPlans 获取计划列表,支持过滤和分页 // ListPlans 获取计划列表,支持过滤和分页
ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansResponse, error) ListPlans(ctx context.Context, query *dto.ListPlansQuery) (*dto.ListPlansResponse, error)
// UpdatePlan 更新计划 // UpdatePlan 更新计划
UpdatePlan(id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error) UpdatePlan(ctx context.Context, id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error)
// DeletePlan 删除计划(软删除) // DeletePlan 删除计划(软删除)
DeletePlan(id uint) error DeletePlan(ctx context.Context, id uint) error
// StartPlan 启动计划 // StartPlan 启动计划
StartPlan(id uint) error StartPlan(ctx context.Context, id uint) error
// StopPlan 停止计划 // StopPlan 停止计划
StopPlan(id uint) error StopPlan(ctx context.Context, id uint) error
} }
// planService 是 PlanService 接口的实现 // planService 是 PlanService 接口的实现
type planService struct { type planService struct {
logger *logs.Logger ctx context.Context
domainPlanService plan.Service // 替换为领域层的服务接口 domainPlanService plan.Service
} }
// NewPlanService 创建一个新的 PlanService 实例 // NewPlanService 创建一个新的 PlanService 实例
func NewPlanService( func NewPlanService(
logger *logs.Logger, ctx context.Context,
domainPlanService plan.Service, // 接收领域层服务 domainPlanService plan.Service,
) PlanService { ) PlanService {
return &planService{ return &planService{
logger: logger, ctx: ctx,
domainPlanService: domainPlanService, // 注入领域层服务 domainPlanService: domainPlanService,
} }
} }
// CreatePlan 创建一个新的计划 // CreatePlan 创建一个新的计划
func (s *planService) CreatePlan(req *dto.CreatePlanRequest) (*dto.PlanResponse, error) { func (s *planService) CreatePlan(ctx context.Context, req *dto.CreatePlanRequest) (*dto.PlanResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "CreatePlan")
const actionType = "应用服务层:创建计划" const actionType = "应用服务层:创建计划"
// 使用 DTO 转换函数将请求转换为领域实体 // 使用 DTO 转换函数将请求转换为领域实体
planToCreate, err := dto.NewPlanFromCreateRequest(req) planToCreate, err := dto.NewPlanFromCreateRequest(req)
if err != nil { if err != nil {
s.logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) logger.Errorf("%s: 计划数据校验失败: %v", actionType, err)
return nil, err return nil, err
} }
// 调用领域服务创建计划 // 调用领域服务创建计划
createdPlan, err := s.domainPlanService.CreatePlan(planToCreate) createdPlan, err := s.domainPlanService.CreatePlan(serviceCtx, planToCreate)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务创建计划失败: %v", actionType, err) logger.Errorf("%s: 领域服务创建计划失败: %v", actionType, err)
return nil, err // 直接返回领域层错误 return nil, err // 直接返回领域层错误
} }
// 将领域实体转换为响应 DTO // 将领域实体转换为响应 DTO
resp, err := dto.NewPlanToResponse(createdPlan) resp, err := dto.NewPlanToResponse(createdPlan)
if err != nil { if err != nil {
s.logger.Errorf("%s: 序列化响应失败: %v, Plan: %+v", actionType, err, createdPlan) logger.Errorf("%s: 序列化响应失败: %v, Plan: %+v", actionType, err, createdPlan)
return nil, errors.New("计划创建成功,但响应生成失败") return nil, errors.New("计划创建成功,但响应生成失败")
} }
s.logger.Infof("%s: 计划创建成功, ID: %d", actionType, createdPlan.ID) logger.Infof("%s: 计划创建成功, ID: %d", actionType, createdPlan.ID)
return resp, nil return resp, nil
} }
// GetPlanByID 根据ID获取计划详情 // GetPlanByID 根据ID获取计划详情
func (s *planService) GetPlanByID(id uint) (*dto.PlanResponse, error) { func (s *planService) GetPlanByID(ctx context.Context, id uint) (*dto.PlanResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "GetPlanByID")
const actionType = "应用服务层:获取计划详情" const actionType = "应用服务层:获取计划详情"
// 调用领域服务获取计划 // 调用领域服务获取计划
plan, err := s.domainPlanService.GetPlanByID(id) plan, err := s.domainPlanService.GetPlanByID(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务获取计划详情失败: %v, ID: %d", actionType, err, id) logger.Errorf("%s: 领域服务获取计划详情失败: %v, ID: %d", actionType, err, id)
return nil, err // 直接返回领域层错误 return nil, err // 直接返回领域层错误
} }
// 将领域实体转换为响应 DTO // 将领域实体转换为响应 DTO
resp, err := dto.NewPlanToResponse(plan) resp, err := dto.NewPlanToResponse(plan)
if err != nil { if err != nil {
s.logger.Errorf("%s: 序列化响应失败: %v, Plan: %+v", actionType, err, plan) logger.Errorf("%s: 序列化响应失败: %v, Plan: %+v", actionType, err, plan)
return nil, errors.New("获取计划详情失败: 内部数据格式错误") return nil, errors.New("获取计划详情失败: 内部数据格式错误")
} }
s.logger.Infof("%s: 获取计划详情成功, ID: %d", actionType, id) logger.Infof("%s: 获取计划详情成功, ID: %d", actionType, id)
return resp, nil return resp, nil
} }
// ListPlans 获取计划列表,支持过滤和分页 // ListPlans 获取计划列表,支持过滤和分页
func (s *planService) ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansResponse, error) { func (s *planService) ListPlans(ctx context.Context, query *dto.ListPlansQuery) (*dto.ListPlansResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListPlans")
const actionType = "应用服务层:获取计划列表" const actionType = "应用服务层:获取计划列表"
// 将 DTO 查询参数转换为领域层可接受的选项 // 将 DTO 查询参数转换为领域层可接受的选项
opts := repository.ListPlansOptions{PlanType: query.PlanType} opts := repository.ListPlansOptions{PlanType: query.PlanType}
// 调用领域服务获取计划列表 // 调用领域服务获取计划列表
plans, total, err := s.domainPlanService.ListPlans(opts, query.Page, query.PageSize) plans, total, err := s.domainPlanService.ListPlans(serviceCtx, opts, query.Page, query.PageSize)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务获取计划列表失败: %v", actionType, err) logger.Errorf("%s: 领域服务获取计划列表失败: %v", actionType, err)
return nil, err // 直接返回领域层错误 return nil, err // 直接返回领域层错误
} }
@@ -114,7 +118,7 @@ func (s *planService) ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansRespon
for _, p := range plans { for _, p := range plans {
resp, err := dto.NewPlanToResponse(&p) resp, err := dto.NewPlanToResponse(&p)
if err != nil { if err != nil {
s.logger.Errorf("%s: 序列化单个计划响应失败: %v, Plan: %+v", actionType, err, p) logger.Errorf("%s: 序列化单个计划响应失败: %v, Plan: %+v", actionType, err, p)
// 这里选择跳过有问题的计划,并记录错误,而不是中断整个列表的返回 // 这里选择跳过有问题的计划,并记录错误,而不是中断整个列表的返回
continue continue
} }
@@ -125,81 +129,85 @@ func (s *planService) ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansRespon
Plans: planResponses, Plans: planResponses,
Total: total, Total: total,
} }
s.logger.Infof("%s: 获取计划列表成功, 数量: %d", actionType, len(planResponses)) logger.Infof("%s: 获取计划列表成功, 数量: %d", actionType, len(planResponses))
return resp, nil return resp, nil
} }
// UpdatePlan 更新计划 // UpdatePlan 更新计划
func (s *planService) UpdatePlan(id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error) { func (s *planService) UpdatePlan(ctx context.Context, id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "UpdatePlan")
const actionType = "应用服务层:更新计划" const actionType = "应用服务层:更新计划"
// 使用 DTO 转换函数将请求转换为领域实体 // 使用 DTO 转换函数将请求转换为领域实体
planToUpdate, err := dto.NewPlanFromUpdateRequest(req) planToUpdate, err := dto.NewPlanFromUpdateRequest(req)
if err != nil { if err != nil {
s.logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) logger.Errorf("%s: 计划数据校验失败: %v", actionType, err)
return nil, err return nil, err
} }
planToUpdate.ID = id // 确保ID被设置 planToUpdate.ID = id // 确保ID被设置
// 调用领域服务更新计划 // 调用领域服务更新计划
updatedPlan, err := s.domainPlanService.UpdatePlan(planToUpdate) updatedPlan, err := s.domainPlanService.UpdatePlan(serviceCtx, planToUpdate)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务更新计划失败: %v, ID: %d", actionType, err, id) logger.Errorf("%s: 领域服务更新计划失败: %v, ID: %d", actionType, err, id)
return nil, err // 直接返回领域层错误 return nil, err // 直接返回领域层错误
} }
// 将领域实体转换为响应 DTO // 将领域实体转换为响应 DTO
resp, err := dto.NewPlanToResponse(updatedPlan) resp, err := dto.NewPlanToResponse(updatedPlan)
if err != nil { if err != nil {
s.logger.Errorf("%s: 序列化响应失败: %v, Updated Plan: %+v", actionType, err, updatedPlan) logger.Errorf("%s: 序列化响应失败: %v, Updated Plan: %+v", actionType, err, updatedPlan)
return nil, errors.New("计划更新成功,但响应生成失败") return nil, errors.New("计划更新成功,但响应生成失败")
} }
s.logger.Infof("%s: 计划更新成功, ID: %d", actionType, updatedPlan.ID) logger.Infof("%s: 计划更新成功, ID: %d", actionType, updatedPlan.ID)
return resp, nil return resp, nil
} }
// DeletePlan 删除计划(软删除) // DeletePlan 删除计划(软删除)
func (s *planService) DeletePlan(id uint) error { func (s *planService) DeletePlan(ctx context.Context, id uint) error {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "DeletePlan")
const actionType = "应用服务层:删除计划" const actionType = "应用服务层:删除计划"
// 调用领域服务删除计划 // 调用领域服务删除计划
err := s.domainPlanService.DeletePlan(id) err := s.domainPlanService.DeletePlan(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务删除计划失败: %v, ID: %d", actionType, err, id) logger.Errorf("%s: 领域服务删除计划失败: %v, ID: %d", actionType, err, id)
return err // 直接返回领域层错误 return err // 直接返回领域层错误
} }
s.logger.Infof("%s: 计划删除成功, ID: %d", actionType, id) logger.Infof("%s: 计划删除成功, ID: %d", actionType, id)
return nil return nil
} }
// StartPlan 启动计划 // StartPlan 启动计划
func (s *planService) StartPlan(id uint) error { func (s *planService) StartPlan(ctx context.Context, id uint) error {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "StartPlan")
const actionType = "应用服务层:启动计划" const actionType = "应用服务层:启动计划"
// 调用领域服务启动计划 // 调用领域服务启动计划
err := s.domainPlanService.StartPlan(id) err := s.domainPlanService.StartPlan(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务启动计划失败: %v, ID: %d", actionType, err, id) logger.Errorf("%s: 领域服务启动计划失败: %v, ID: %d", actionType, err, id)
return err // 直接返回领域层错误 return err // 直接返回领域层错误
} }
s.logger.Infof("%s: 计划已成功启动, ID: %d", actionType, id) logger.Infof("%s: 计划已成功启动, ID: %d", actionType, id)
return nil return nil
} }
// StopPlan 停止计划 // StopPlan 停止计划
func (s *planService) StopPlan(id uint) error { func (s *planService) StopPlan(ctx context.Context, id uint) error {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "StopPlan")
const actionType = "应用服务层:停止计划" const actionType = "应用服务层:停止计划"
// 调用领域服务停止计划 // 调用领域服务停止计划
err := s.domainPlanService.StopPlan(id) err := s.domainPlanService.StopPlan(serviceCtx, id)
if err != nil { if err != nil {
s.logger.Errorf("%s: 领域服务停止计划失败: %v, ID: %d", actionType, err, id) logger.Errorf("%s: 领域服务停止计划失败: %v, ID: %d", actionType, err, id)
return err // 直接返回领域层错误 return err // 直接返回领域层错误
} }
s.logger.Infof("%s: 计划已成功停止, ID: %d", actionType, id) logger.Infof("%s: 计划已成功停止, ID: %d", actionType, id)
return nil return nil
} }

View File

@@ -1,6 +1,7 @@
package service package service
import ( import (
"context"
"errors" "errors"
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
@@ -9,51 +10,53 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "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/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"gorm.io/gorm" "gorm.io/gorm"
) )
// UserService 定义用户服务接口 // UserService 定义用户服务接口
type UserService interface { type UserService interface {
CreateUser(req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.CreateUserResponse, error)
Login(req *dto.LoginRequest) (*dto.LoginResponse, error) Login(ctx context.Context, req *dto.LoginRequest) (*dto.LoginResponse, error)
SendTestNotification(userID uint, req *dto.SendTestNotificationRequest) error SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error
} }
// userService 实现了 UserService 接口 // userService 实现了 UserService 接口
type userService struct { type userService struct {
ctx context.Context
userRepo repository.UserRepository userRepo repository.UserRepository
tokenService token.Service tokenService token.Service
notifyService domain_notify.Service notifyService domain_notify.Service
logger *logs.Logger
} }
// NewUserService 创建并返回一个新的 UserService 实例 // NewUserService 创建并返回一个新的 UserService 实例
func NewUserService( func NewUserService(
ctx context.Context,
userRepo repository.UserRepository, userRepo repository.UserRepository,
tokenService token.Service, tokenService token.Service,
notifyService domain_notify.Service, notifyService domain_notify.Service,
logger *logs.Logger,
) UserService { ) UserService {
return &userService{ return &userService{
ctx: ctx,
userRepo: userRepo, userRepo: userRepo,
tokenService: tokenService, tokenService: tokenService,
notifyService: notifyService, notifyService: notifyService,
logger: logger,
} }
} }
// CreateUser 创建新用户 // CreateUser 创建新用户
func (s *userService) CreateUser(req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) { func (s *userService) CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "CreateUser")
user := &models.User{ user := &models.User{
Username: req.Username, Username: req.Username,
Password: req.Password, // 密码会在 BeforeSave 钩子中哈希 Password: req.Password, // 密码会在 BeforeSave 钩子中哈希
} }
if err := s.userRepo.Create(user); err != nil { if err := s.userRepo.Create(serviceCtx, user); err != nil {
s.logger.Errorf("创建用户: 创建用户失败: %v", err) logger.Errorf("创建用户: 创建用户失败: %v", err)
// 尝试查询用户,以判断是否是用户名重复导致的错误 // 尝试查询用户,以判断是否是用户名重复导致的错误
_, findErr := s.userRepo.FindByUsername(req.Username) _, findErr := s.userRepo.FindByUsername(serviceCtx, req.Username)
if findErr == nil { // 如果能找到用户,说明是用户名重复 if findErr == nil { // 如果能找到用户,说明是用户名重复
return nil, errors.New("用户名已存在") return nil, errors.New("用户名已存在")
} }
@@ -69,14 +72,15 @@ func (s *userService) CreateUser(req *dto.CreateUserRequest) (*dto.CreateUserRes
} }
// Login 用户登录 // Login 用户登录
func (s *userService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) { func (s *userService) Login(ctx context.Context, req *dto.LoginRequest) (*dto.LoginResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "Login")
// 使用新的方法,通过唯一标识符(用户名、邮箱等)查找用户 // 使用新的方法,通过唯一标识符(用户名、邮箱等)查找用户
user, err := s.userRepo.FindUserForLogin(req.Identifier) user, err := s.userRepo.FindUserForLogin(serviceCtx, req.Identifier)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("登录凭证不正确") return nil, errors.New("登录凭证不正确")
} }
s.logger.Errorf("登录: 查询用户失败: %v", err) logger.Errorf("登录: 查询用户失败: %v", err)
return nil, errors.New("登录失败") return nil, errors.New("登录失败")
} }
@@ -87,7 +91,7 @@ func (s *userService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) {
// 登录成功,生成 JWT token // 登录成功,生成 JWT token
tokenString, err := s.tokenService.GenerateToken(user.ID) tokenString, err := s.tokenService.GenerateToken(user.ID)
if err != nil { if err != nil {
s.logger.Errorf("登录: 生成令牌失败: %v", err) logger.Errorf("登录: 生成令牌失败: %v", err)
return nil, errors.New("登录失败,无法生成认证信息") return nil, errors.New("登录失败,无法生成认证信息")
} }
@@ -99,12 +103,13 @@ func (s *userService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) {
} }
// SendTestNotification 发送测试通知 // SendTestNotification 发送测试通知
func (s *userService) SendTestNotification(userID uint, req *dto.SendTestNotificationRequest) error { func (s *userService) SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error {
err := s.notifyService.SendTestMessage(userID, req.Type) serviceCtx, logger := logs.Trace(ctx, s.ctx, "SendTestNotification")
err := s.notifyService.SendTestMessage(serviceCtx, userID, req.Type)
if err != nil { if err != nil {
s.logger.Errorf("发送测试通知: 服务层调用失败: %v", err) logger.Errorf("发送测试通知: 服务层调用失败: %v", err)
return errors.New("发送测试消息失败: " + err.Error()) return errors.New("发送测试消息失败: " + err.Error())
} }
s.logger.Infof("发送测试通知: 成功为用户 %d 发送类型为 %s 的测试消息", userID, req.Type) logger.Infof("发送测试通知: 成功为用户 %d 发送类型为 %s 的测试消息", userID, req.Type)
return nil return nil
} }

View File

@@ -7,7 +7,6 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/service" "git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/app/webhook" "git.huangwc.com/pig/pig-farm-controller/internal/app/webhook"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/audit"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/device" "git.huangwc.com/pig/pig-farm-controller/internal/domain/device"
domain_notify "git.huangwc.com/pig/pig-farm-controller/internal/domain/notify" domain_notify "git.huangwc.com/pig/pig-farm-controller/internal/domain/notify"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/pig" "git.huangwc.com/pig/pig-farm-controller/internal/domain/pig"
@@ -94,28 +93,28 @@ type Repositories struct {
func initRepositories(ctx context.Context, db *gorm.DB) *Repositories { func initRepositories(ctx context.Context, db *gorm.DB) *Repositories {
baseCtx := context.Background() baseCtx := context.Background()
return &Repositories{ return &Repositories{
userRepo: repository.NewGormUserRepository(db, logs.AddCompName(baseCtx, "UserRepo")), userRepo: repository.NewGormUserRepository(logs.AddCompName(baseCtx, "UserRepo"), db),
deviceRepo: repository.NewGormDeviceRepository(db, logs.AddCompName(baseCtx, "DeviceRepo")), deviceRepo: repository.NewGormDeviceRepository(logs.AddCompName(baseCtx, "DeviceRepo"), db),
areaControllerRepo: repository.NewGormAreaControllerRepository(db, logs.AddCompName(baseCtx, "AreaControllerRepo")), areaControllerRepo: repository.NewGormAreaControllerRepository(logs.AddCompName(baseCtx, "AreaControllerRepo"), db),
deviceTemplateRepo: repository.NewGormDeviceTemplateRepository(db, logs.AddCompName(baseCtx, "DeviceTemplateRepo")), deviceTemplateRepo: repository.NewGormDeviceTemplateRepository(logs.AddCompName(baseCtx, "DeviceTemplateRepo"), db),
planRepo: repository.NewGormPlanRepository(db, logs.AddCompName(baseCtx, "PlanRepo")), planRepo: repository.NewGormPlanRepository(logs.AddCompName(baseCtx, "PlanRepo"), db),
pendingTaskRepo: repository.NewGormPendingTaskRepository(db, logs.AddCompName(baseCtx, "PendingTaskRepo")), pendingTaskRepo: repository.NewGormPendingTaskRepository(logs.AddCompName(baseCtx, "PendingTaskRepo"), db),
executionLogRepo: repository.NewGormExecutionLogRepository(db, logs.AddCompName(baseCtx, "ExecutionLogRepo")), executionLogRepo: repository.NewGormExecutionLogRepository(logs.AddCompName(baseCtx, "ExecutionLogRepo"), db),
sensorDataRepo: repository.NewGormSensorDataRepository(db, logs.AddCompName(baseCtx, "SensorDataRepo")), sensorDataRepo: repository.NewGormSensorDataRepository(logs.AddCompName(baseCtx, "SensorDataRepo"), db),
deviceCommandLogRepo: repository.NewGormDeviceCommandLogRepository(db, logs.AddCompName(baseCtx, "DeviceCommandLogRepo")), deviceCommandLogRepo: repository.NewGormDeviceCommandLogRepository(logs.AddCompName(baseCtx, "DeviceCommandLogRepo"), db),
pendingCollectionRepo: repository.NewGormPendingCollectionRepository(db, logs.AddCompName(baseCtx, "PendingCollectionRepo")), pendingCollectionRepo: repository.NewGormPendingCollectionRepository(logs.AddCompName(baseCtx, "PendingCollectionRepo"), db),
userActionLogRepo: repository.NewGormUserActionLogRepository(db, logs.AddCompName(baseCtx, "UserActionLogRepo")), userActionLogRepo: repository.NewGormUserActionLogRepository(logs.AddCompName(baseCtx, "UserActionLogRepo"), db),
pigBatchRepo: repository.NewGormPigBatchRepository(db, logs.AddCompName(baseCtx, "PigBatchRepo")), pigBatchRepo: repository.NewGormPigBatchRepository(logs.AddCompName(baseCtx, "PigBatchRepo"), db),
pigBatchLogRepo: repository.NewGormPigBatchLogRepository(db, logs.AddCompName(baseCtx, "PigBatchLogRepo")), pigBatchLogRepo: repository.NewGormPigBatchLogRepository(logs.AddCompName(baseCtx, "PigBatchLogRepo"), db),
pigFarmRepo: repository.NewGormPigFarmRepository(db, logs.AddCompName(baseCtx, "PigFarmRepo")), pigFarmRepo: repository.NewGormPigFarmRepository(logs.AddCompName(baseCtx, "PigFarmRepo"), db),
pigPenRepo: repository.NewGormPigPenRepository(db, logs.AddCompName(baseCtx, "PigPenRepo")), pigPenRepo: repository.NewGormPigPenRepository(logs.AddCompName(baseCtx, "PigPenRepo"), db),
pigTransferLogRepo: repository.NewGormPigTransferLogRepository(db, logs.AddCompName(baseCtx, "PigTransferLogRepo")), pigTransferLogRepo: repository.NewGormPigTransferLogRepository(logs.AddCompName(baseCtx, "PigTransferLogRepo"), db),
pigTradeRepo: repository.NewGormPigTradeRepository(db, logs.AddCompName(baseCtx, "PigTradeRepo")), pigTradeRepo: repository.NewGormPigTradeRepository(logs.AddCompName(baseCtx, "PigTradeRepo"), db),
pigSickPigLogRepo: repository.NewGormPigSickLogRepository(db, logs.AddCompName(baseCtx, "PigSickPigLogRepo")), pigSickPigLogRepo: repository.NewGormPigSickLogRepository(logs.AddCompName(baseCtx, "PigSickPigLogRepo"), db),
medicationLogRepo: repository.NewGormMedicationLogRepository(db, logs.AddCompName(baseCtx, "MedicationLogRepo")), medicationLogRepo: repository.NewGormMedicationLogRepository(logs.AddCompName(baseCtx, "MedicationLogRepo"), db),
rawMaterialRepo: repository.NewGormRawMaterialRepository(db, logs.AddCompName(baseCtx, "RawMaterialRepo")), rawMaterialRepo: repository.NewGormRawMaterialRepository(logs.AddCompName(baseCtx, "RawMaterialRepo"), db),
notificationRepo: repository.NewGormNotificationRepository(db, logs.AddCompName(baseCtx, "NotificationRepo")), notificationRepo: repository.NewGormNotificationRepository(logs.AddCompName(baseCtx, "NotificationRepo"), db),
unitOfWork: repository.NewGormUnitOfWork(db, logs.AddCompName(baseCtx, "UnitOfWork")), unitOfWork: repository.NewGormUnitOfWork(logs.AddCompName(baseCtx, "UnitOfWork"), db),
} }
} }
@@ -134,22 +133,21 @@ type DomainServices struct {
// initDomainServices 初始化所有的领域服务。 // initDomainServices 初始化所有的领域服务。
func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastructure) *DomainServices { func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastructure) *DomainServices {
logger := logs.GetLogger(ctx)
baseCtx := context.Background() baseCtx := context.Background()
// 猪群管理相关 // 猪群管理相关
pigPenTransferManager := pig.NewPigPenTransferManager(infra.repos.pigPenRepo, infra.repos.pigTransferLogRepo, infra.repos.pigBatchRepo) pigPenTransferManager := pig.NewPigPenTransferManager(logs.AddCompName(baseCtx, "PigPenTransferManager"), infra.repos.pigPenRepo, infra.repos.pigTransferLogRepo, infra.repos.pigBatchRepo)
pigTradeManager := pig.NewPigTradeManager(infra.repos.pigTradeRepo) pigTradeManager := pig.NewPigTradeManager(logs.AddCompName(baseCtx, "PigTradeManager"), infra.repos.pigTradeRepo)
pigSickManager := pig.NewSickPigManager(infra.repos.pigSickPigLogRepo, infra.repos.medicationLogRepo) pigSickManager := pig.NewSickPigManager(logs.AddCompName(baseCtx, "PigSickManager"), infra.repos.pigSickPigLogRepo, infra.repos.medicationLogRepo)
pigBatchDomain := pig.NewPigBatchService(infra.repos.pigBatchRepo, infra.repos.pigBatchLogRepo, infra.repos.unitOfWork, pigBatchDomain := pig.NewPigBatchService(logs.AddCompName(baseCtx, "PigBatchDomain")), infra.repos.pigBatchRepo, infra.repos.pigBatchLogRepo, infra.repos.unitOfWork,
pigPenTransferManager, pigTradeManager, pigSickManager) pigPenTransferManager, pigTradeManager, pigSickManager)
// 通用设备服务 // 通用设备服务
generalDeviceService := device.NewGeneralDeviceService( generalDeviceService := device.NewGeneralDeviceService(
logs.AddCompName(baseCtx, "GeneralDeviceService"),
infra.repos.deviceRepo, infra.repos.deviceRepo,
infra.repos.deviceCommandLogRepo, infra.repos.deviceCommandLogRepo,
infra.repos.pendingCollectionRepo, infra.repos.pendingCollectionRepo,
logs.AddCompName(baseCtx, "GeneralDeviceService"),
infra.lora.comm, infra.lora.comm,
) )
@@ -157,10 +155,11 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr
taskFactory := task.NewTaskFactory(logs.AddCompName(baseCtx, "TaskFactory"), infra.repos.sensorDataRepo, infra.repos.deviceRepo, generalDeviceService) taskFactory := task.NewTaskFactory(logs.AddCompName(baseCtx, "TaskFactory"), infra.repos.sensorDataRepo, infra.repos.deviceRepo, generalDeviceService)
// 计划任务管理器 // 计划任务管理器
analysisPlanTaskManager := plan.NewAnalysisPlanTaskManager(infra.repos.planRepo, infra.repos.pendingTaskRepo, infra.repos.executionLogRepo, logs.AddCompName(baseCtx, "AnalysisPlanTaskManager")) analysisPlanTaskManager := plan.NewAnalysisPlanTaskManager(logs.AddCompName(baseCtx, "AnalysisPlanTaskManager"), infra.repos.planRepo, infra.repos.pendingTaskRepo, infra.repos.executionLogRepo)
// 任务执行器 // 任务执行器
planExecutionManager := plan.NewPlanExecutionManager( planExecutionManager := plan.NewPlanExecutionManager(
logs.AddCompName(baseCtx, "PlanExecutionManager"),
infra.repos.pendingTaskRepo, infra.repos.pendingTaskRepo,
infra.repos.executionLogRepo, infra.repos.executionLogRepo,
infra.repos.deviceRepo, infra.repos.deviceRepo,
@@ -168,7 +167,6 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr
infra.repos.planRepo, infra.repos.planRepo,
analysisPlanTaskManager, analysisPlanTaskManager,
taskFactory, taskFactory,
logs.AddCompName(baseCtx, "PlanExecutionManager"),
generalDeviceService, generalDeviceService,
time.Duration(cfg.Task.Interval)*time.Second, time.Duration(cfg.Task.Interval)*time.Second,
cfg.Task.NumWorkers, cfg.Task.NumWorkers,
@@ -176,13 +174,14 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr
// 计划管理器 // 计划管理器
planService := plan.NewPlanService( planService := plan.NewPlanService(
logs.AddCompName(baseCtx, "PlanService"),
planExecutionManager, planExecutionManager,
analysisPlanTaskManager, analysisPlanTaskManager,
infra.repos.planRepo, infra.repos.planRepo,
infra.repos.deviceRepo, infra.repos.deviceRepo,
infra.repos.unitOfWork, infra.repos.unitOfWork,
taskFactory, taskFactory,
logs.AddCompName(baseCtx, "PlanService")) )
return &DomainServices{ return &DomainServices{
pigPenTransferManager: pigPenTransferManager, pigPenTransferManager: pigPenTransferManager,
@@ -205,15 +204,16 @@ type AppServices struct {
deviceService service.DeviceService deviceService service.DeviceService
planService service.PlanService planService service.PlanService
userService service.UserService userService service.UserService
auditService audit.Service auditService service.AuditService
} }
// initAppServices 初始化所有的应用服务。 // initAppServices 初始化所有的应用服务。
func initAppServices(ctx context.Context, infra *Infrastructure, domainServices *DomainServices) *AppServices { func initAppServices(ctx context.Context, infra *Infrastructure, domainServices *DomainServices) *AppServices {
baseCtx := context.Background() baseCtx := context.Background()
pigFarmService := service.NewPigFarmService(infra.repos.pigFarmRepo, infra.repos.pigPenRepo, infra.repos.pigBatchRepo, domainServices.pigBatchDomain, infra.repos.unitOfWork, logs.AddCompName(baseCtx, "PigFarmService")) pigFarmService := service.NewPigFarmService(logs.AddCompName(baseCtx, "PigFarmService"), infra.repos.pigFarmRepo, infra.repos.pigPenRepo, infra.repos.pigBatchRepo, domainServices.pigBatchDomain, infra.repos.unitOfWork)
pigBatchService := service.NewPigBatchService(domainServices.pigBatchDomain, logs.AddCompName(baseCtx, "PigBatchService")) pigBatchService := service.NewPigBatchService(logs.AddCompName(baseCtx, "PigBatchService"), domainServices.pigBatchDomain)
monitorService := service.NewMonitorService( monitorService := service.NewMonitorService(
logs.AddCompName(baseCtx, "MonitorService"),
infra.repos.sensorDataRepo, infra.repos.sensorDataRepo,
infra.repos.deviceCommandLogRepo, infra.repos.deviceCommandLogRepo,
infra.repos.executionLogRepo, infra.repos.executionLogRepo,
@@ -230,14 +230,15 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
infra.repos.notificationRepo, infra.repos.notificationRepo,
) )
deviceService := service.NewDeviceService( deviceService := service.NewDeviceService(
logs.AddCompName(baseCtx, "DeviceService"),
infra.repos.deviceRepo, infra.repos.deviceRepo,
infra.repos.areaControllerRepo, infra.repos.areaControllerRepo,
infra.repos.deviceTemplateRepo, infra.repos.deviceTemplateRepo,
domainServices.generalDeviceService, domainServices.generalDeviceService,
) )
auditService := audit.NewService(infra.repos.userActionLogRepo, logs.AddCompName(baseCtx, "AuditService")) auditService := service.NewAuditService(logs.AddCompName(baseCtx, "AuditService"), infra.repos.userActionLogRepo)
planService := service.NewPlanService(logs.AddCompName(baseCtx, "AppPlanService"), domainServices.planService) planService := service.NewPlanService(logs.AddCompName(baseCtx, "AppPlanService"), domainServices.planService)
userService := service.NewUserService(infra.repos.userRepo, infra.tokenService, infra.notifyService, logs.AddCompName(baseCtx, "UserService")) userService := service.NewUserService(logs.AddCompName(baseCtx, "UserService"), infra.repos.userRepo, infra.tokenService, infra.notifyService)
return &AppServices{ return &AppServices{
pigFarmService: pigFarmService, pigFarmService: pigFarmService,
@@ -386,7 +387,7 @@ func initStorage(ctx context.Context, cfg config.DatabaseConfig) (database.Stora
} }
// 执行数据库迁移 // 执行数据库迁移
if err := storage.Migrate(models.GetAllModels()...); err != nil { if err := storage.Migrate(ctx, models.GetAllModels()...); err != nil {
return nil, fmt.Errorf("数据库迁移失败: %w", err) return nil, fmt.Errorf("数据库迁移失败: %w", err)
} }