diff --git a/design/provide-logger-with-mothed/task-service.md b/design/provide-logger-with-mothed/task-service.md index 7fdc0ca..9e5d1f4 100644 --- a/design/provide-logger-with-mothed/task-service.md +++ b/design/provide-logger-with-mothed/task-service.md @@ -1,113 +1,113 @@ - **`internal/app/service/pig_farm_service.go` (`service.PigFarmService`)** - **结构体改造**: - - [ ] 移除 `PigFarmService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 - - [ ] 移除 `PigFarmService` 结构体中的 `repo repository.PigFarmRepository` 成员,改为 + - [x] 移除 `PigFarmService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `PigFarmService` 结构体中的 `repo repository.PigFarmRepository` 成员,改为 `repo repository.PigFarmRepository`。 - **构造函数改造 (`NewPigFarmService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `PigFarmService` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `PigFarmService` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "PigFarmService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `PigFarmService` 结构体的 `selfCtx` 成员。 + - [x] 将这个 `selfCtx` 赋值给 `PigFarmService` 结构体的 `selfCtx` 成员。 - **公共方法改造 ( 所有方法,例如 `CreatePigHouse`, `GetPigHouseByID`, `ListPigHouses`, `UpdatePigHouse`, `DeletePigHouse`, `CreatePen`, `GetPenByID`, `ListPens`, `UpdatePen`, `DeletePen`, `UpdatePenStatus`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `context.Context` 和 `logger` 实例。 - - [ ] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 - - [ ] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 + - [x] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 + - [x] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/service/pig_batch_service.go` (`service.PigBatchService`)** - **结构体改造**: - - [ ] 移除 `PigBatchService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `PigBatchService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewPigBatchService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `PigBatchService` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `PigBatchService` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "PigBatchService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `PigBatchService` 结构体的 `selfCtx` 成员。 + - [x] 将这个 `selfCtx` 赋值给 `PigBatchService` 结构体的 `selfCtx` 成员。 - **公共方法改造 ( 所有方法,例如 `CreatePigBatch`, `GetPigBatch`, `UpdatePigBatch`, `DeletePigBatch`, `ListPigBatches`, `AssignEmptyPensToBatch`, `ReclassifyPenToNewBatch`, `RemoveEmptyPenFromBatch`, `MovePigsIntoPen`, `SellPigs`, `BuyPigs`, `RecordSickPigs`, `RecordSickPigRecovery`, `RecordSickPigDeath`, `RecordSickPigCull`, `RecordDeath`, `RecordCull`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `context.Context` 和 `logger` 实例。 - - [ ] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 - - [ ] 确保所有对 `s.pigBatchRepo`, `s.pigBatchLogRepo`, `s.uow`, `s.transferSvc`, `s.tradeSvc`, `s.sickSvc` + - [x] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 + - [x] 确保所有对 `s.pigBatchRepo`, `s.pigBatchLogRepo`, `s.uow`, `s.transferSvc`, `s.tradeSvc`, `s.sickSvc` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/service/monitor_service.go` (`service.MonitorService`)** - **结构体改造**: - - [ ] 移除 `MonitorService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `MonitorService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewMonitorService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `MonitorService` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `MonitorService` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "MonitorService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `MonitorService` 结构体的 `selfCtx` 成员。 + - [x] 将这个 `selfCtx` 赋值给 `MonitorService` 结构体的 `selfCtx` 成员。 - **公共方法改造 ( 所有方法,例如 `ListSensorData`, `ListDeviceCommandLogs`, `ListPlanExecutionLogs`, `ListTaskExecutionLogs`, `ListPendingCollections`, `ListUserActionLogs`, `ListRawMaterialPurchases`, `ListRawMaterialStockLogs`, `ListFeedUsageRecords`, `ListMedicationLogs`, `ListPigBatchLogs`, `ListWeighingBatches`, `ListWeighingRecords`, `ListPigTransferLogs`, `ListPigSickLogs`, `ListPigPurchases`, `ListPigSales`, `ListNotifications`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `context.Context` 和 `logger` 实例。 - - [ ] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 - - [ ] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 + - [x] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 + - [x] 确保所有对 `s.repo` 的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/service/device_service.go` (`service.DeviceService`)** - **结构体改造**: - - [ ] 移除 `DeviceService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `DeviceService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewDeviceService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `DeviceService` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `DeviceService` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "DeviceService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `DeviceService` 结构体的 `selfCtx` 成员。 + - [x] 将这个 `selfCtx` 赋值给 `DeviceService` 结构体的 `selfCtx` 成员。 - **公共方法改造 ( 所有方法,例如 `CreateDevice`, `GetDevice`, `ListDevices`, `UpdateDevice`, `DeleteDevice`, `ManualControl`, `CreateAreaController`, `GetAreaController`, `ListAreaControllers`, `UpdateAreaController`, `DeleteAreaController`, `CreateDeviceTemplate`, `GetDeviceTemplate`, `ListDeviceTemplates`, `UpdateDeviceTemplate`, `DeleteDeviceTemplate`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `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`。 - - [ ] 确保所有对 `s.repo`, `s.generalDeviceService` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 + - [x] 确保所有对 `s.repo`, `s.generalDeviceService` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/service/plan_service.go` (`service.PlanService`)** - **结构体改造**: - - [ ] 移除 `PlanService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `PlanService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewPlanService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `PlanService` 创建其专属的 `selfCtx`:`selfCtx := logs.AddCompName(ctx, "PlanService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `PlanService` 结构体的 `selfCtx` 成员。 + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `PlanService` 创建其专属的 `selfCtx`:`selfCtx := logs.AddCompName(ctx, "PlanService")`。 + - [x] 将这个 `selfCtx` 赋值给 `PlanService` 结构体的 `selfCtx` 成员。 - **公共方法改造 ( 所有方法,例如 `CreatePlan`, `GetPlanByID`, `ListPlans`, `UpdatePlan`, `DeletePlan`, `StartPlan`, `StopPlan`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `context.Context` 和 `logger` 实例。 - - [ ] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 - - [ ] 确保所有对 `s.repo`, `s.planExecutionManager`, `s.analysisPlanTaskManager` 等依赖的调用都将 `newCtx` + - [x] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 + - [x] 确保所有对 `s.repo`, `s.planExecutionManager`, `s.analysisPlanTaskManager` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/service/user_service.go` (`service.UserService`)** - **结构体改造**: - - [ ] 移除 `UserService` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `UserService` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewUserService`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `UserService` 创建其专属的 `selfCtx`:`selfCtx := logs.AddCompName(ctx, "UserService")`。 - - [ ] 将这个 `selfCtx` 赋值给 `UserService` 结构体的 `selfCtx` 成员。 + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `UserService` 创建其专属的 `selfCtx`:`selfCtx := logs.AddCompName(ctx, "UserService")`。 + - [x] 将这个 `selfCtx` 赋值给 `UserService` 结构体的 `selfCtx` 成员。 - **公共方法改造 (所有方法,例如 `CreateUser`, `Login`, `SendTestNotification`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在方法入口处,使用 `newCtx, logger := logs.Trace(ctx, s.selfCtx, "MethodName")` 获取新的 `context.Context` 和 `logger` 实例。 - - [ ] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 - - [ ] 确保所有对 `s.repo`, `s.tokenService`, `s.notifier` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 \ No newline at end of file + - [x] 将所有对 `s.logger.Errorf` 和 `s.logger.Infof` 的调用替换为 `logger.Errorf` 和 `logger.Infof`。 + - [x] 确保所有对 `s.repo`, `s.tokenService`, `s.notifier` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 \ No newline at end of file diff --git a/design/provide-logger-with-mothed/task-webhook.md b/design/provide-logger-with-mothed/task-webhook.md index d6e42d8..1042dbf 100644 --- a/design/provide-logger-with-mothed/task-webhook.md +++ b/design/provide-logger-with-mothed/task-webhook.md @@ -1,39 +1,39 @@ - **`internal/app/webhook/chirp_stack.go` (`webhook.ChirpStackListener`)** - **结构体改造**: - - [ ] 移除 `ChirpStackListener` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `ChirpStackListener` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewChirpStackListener`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `ChirpStackListener` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `ChirpStackListener` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "ChirpStackListener")`。 - - [ ] 将这个 `selfCtx` 赋值给 `ChirpStackListener` 结构体的 `selfCtx` 成员。 + - [x] 将这个 `selfCtx` 赋值给 `ChirpStackListener` 结构体的 `selfCtx` 成员。 - **公共方法改造 (`Handler`)**: - - [ ] `Handler` 方法返回 `http.HandlerFunc`。在返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 + - [x] `Handler` 方法返回 `http.HandlerFunc`。在返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 `upstreamCtx`。 - - [ ] 在 `go c.handler(b, event)` 调用之前,将 `upstreamCtx` 传递给 `c.handler` 方法,即 + - [x] 在 `go c.handler(b, event)` 调用之前,将 `upstreamCtx` 传递给 `c.handler` 方法,即 `go c.handler(upstreamCtx, b, event)`。 - - [ ] 将所有对 `c.logger.Errorf` 的调用替换为 `logger.Errorf` (在 `handler` 方法中处理)。 + - [x] 将所有对 `c.logger.Errorf` 的调用替换为 `logger.Errorf` (在 `handler` 方法中处理)。 - **内部辅助方法改造 (`handler`, `handleUpEvent`, `handleStatusEvent`, `handleAckEvent`, `handleLogEvent`, `handleJoinEvent`, `handleTxAckEvent`, `handleLocationEvent`, `handleIntegrationEvent`, `recordSensorData`)**: - - [ ] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 - - [ ] 在每个方法入口处,使用 `newCtx, logger := logs.Trace(ctx, c.selfCtx, "MethodName")` 获取新的 + - [x] 修改方法签名,添加 `ctx context.Context` 作为第一个参数。 + - [x] 在每个方法入口处,使用 `newCtx, logger := logs.Trace(ctx, c.selfCtx, "MethodName")` 获取新的 `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`。 - - [ ] 确保所有对 `c.sensorDataRepo`, `c.deviceRepo`, `c.areaControllerRepo`, `c.deviceCommandLogRepo`, + - [x] 确保所有对 `c.sensorDataRepo`, `c.deviceRepo`, `c.areaControllerRepo`, `c.deviceCommandLogRepo`, `c.pendingCollectionRepo` 等依赖的调用都将 `newCtx` 作为第一个参数传递。 - **`internal/app/webhook/placeholder_listener.go` (`webhook.PlaceholderListener`)** - **结构体改造**: - - [ ] 移除 `PlaceholderListener` 结构体中的 `logger *logs.Logger` 成员。 - - [ ] 新增 `selfCtx context.Context` 成员。 + - [x] 移除 `PlaceholderListener` 结构体中的 `logger *logs.Logger` 成员。 + - [x] 新增 `selfCtx context.Context` 成员。 - **构造函数改造 (`NewPlaceholderListener`)**: - - [ ] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 - - [ ] 在函数内部,为 `PlaceholderListener` 创建其专属的 `selfCtx`: + - [x] 修改函数签名,移除 `logger *logs.Logger` 参数,改为接收 `ctx context.Context`。 + - [x] 在函数内部,为 `PlaceholderListener` 创建其专属的 `selfCtx`: `selfCtx := logs.AddCompName(ctx, "PlaceholderListener")`。 - - [ ] 将这个 `selfCtx` 赋值给 `PlaceholderListener` 结构体的 `selfCtx` 成员。 - - [ ] 使用 `newCtx, logger := logs.Trace(ctx, selfCtx, "NewPlaceholderListener")` 获取 `logger` 实例,并替换 + - [x] 将这个 `selfCtx` 赋值给 `PlaceholderListener` 结构体的 `selfCtx` 成员。 + - [x] 使用 `newCtx, logger := logs.Trace(ctx, selfCtx, "NewPlaceholderListener")` 获取 `logger` 实例,并替换 `logger.Info` 调用。 - **公共方法改造 (`Handler`)**: - - [ ] 在 `Handler` 方法返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 `upstreamCtx`。 - - [ ] 使用 `newCtx, logger := logs.Trace(upstreamCtx, p.selfCtx, "Handler")` 获取 `logger` 实例。 - - [ ] 将所有对 `p.logger.Warn` 的调用替换为 `logger.Warn`。 \ No newline at end of file + - [x] 在 `Handler` 方法返回的 `http.HandlerFunc` 内部,获取 `r.Context()` 作为 `upstreamCtx`。 + - [x] 使用 `newCtx, logger := logs.Trace(upstreamCtx, p.selfCtx, "Handler")` 获取 `logger` 实例。 + - [x] 将所有对 `p.logger.Warn` 的调用替换为 `logger.Warn`。 \ No newline at end of file diff --git a/internal/app/api/api.go b/internal/app/api/api.go index cb5d874..446a12b 100644 --- a/internal/app/api/api.go +++ b/internal/app/api/api.go @@ -32,6 +32,7 @@ import ( "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/repository" + "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) diff --git a/internal/app/api/router.go b/internal/app/api/router.go index 9774987..5b019cf 100644 --- a/internal/app/api/router.go +++ b/internal/app/api/router.go @@ -7,6 +7,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/app/middleware" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" + "github.com/labstack/echo/v4" echoSwagger "github.com/swaggo/echo-swagger" ) diff --git a/internal/app/controller/auth_utils.go b/internal/app/controller/auth_utils.go index aa8f447..25d28b8 100644 --- a/internal/app/controller/auth_utils.go +++ b/internal/app/controller/auth_utils.go @@ -4,6 +4,7 @@ import ( "errors" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/device/device_controller.go b/internal/app/controller/device/device_controller.go index ac0e4b0..451b22b 100644 --- a/internal/app/controller/device/device_controller.go +++ b/internal/app/controller/device/device_controller.go @@ -9,6 +9,7 @@ import ( "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/infra/logs" + "github.com/labstack/echo/v4" "gorm.io/gorm" ) diff --git a/internal/app/controller/management/controller_helpers.go b/internal/app/controller/management/controller_helpers.go index 97cec5b..c9c7613 100644 --- a/internal/app/controller/management/controller_helpers.go +++ b/internal/app/controller/management/controller_helpers.go @@ -7,6 +7,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/app/controller" "git.huangwc.com/pig/pig-farm-controller/internal/app/service" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/management/pig_batch_controller.go b/internal/app/controller/management/pig_batch_controller.go index 2a0725f..8367967 100644 --- a/internal/app/controller/management/pig_batch_controller.go +++ b/internal/app/controller/management/pig_batch_controller.go @@ -7,6 +7,7 @@ import ( "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/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/management/pig_batch_health_controller.go b/internal/app/controller/management/pig_batch_health_controller.go index bc97e46..f801943 100644 --- a/internal/app/controller/management/pig_batch_health_controller.go +++ b/internal/app/controller/management/pig_batch_health_controller.go @@ -3,6 +3,7 @@ package management import ( "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/management/pig_batch_trade_controller.go b/internal/app/controller/management/pig_batch_trade_controller.go index 763134a..42291a3 100644 --- a/internal/app/controller/management/pig_batch_trade_controller.go +++ b/internal/app/controller/management/pig_batch_trade_controller.go @@ -3,6 +3,7 @@ package management import ( "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/management/pig_batch_transfer_controller.go b/internal/app/controller/management/pig_batch_transfer_controller.go index 68c9cca..2cbc9a4 100644 --- a/internal/app/controller/management/pig_batch_transfer_controller.go +++ b/internal/app/controller/management/pig_batch_transfer_controller.go @@ -5,6 +5,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/management/pig_farm_controller.go b/internal/app/controller/management/pig_farm_controller.go index a4a483b..0a6733c 100644 --- a/internal/app/controller/management/pig_farm_controller.go +++ b/internal/app/controller/management/pig_farm_controller.go @@ -9,6 +9,7 @@ import ( "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/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/monitor/monitor_controller.go b/internal/app/controller/monitor/monitor_controller.go index 3444f1e..ae787ad 100644 --- a/internal/app/controller/monitor/monitor_controller.go +++ b/internal/app/controller/monitor/monitor_controller.go @@ -9,6 +9,7 @@ import ( "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/repository" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/plan/plan_controller.go b/internal/app/controller/plan/plan_controller.go index 4c38e50..35fa6b5 100644 --- a/internal/app/controller/plan/plan_controller.go +++ b/internal/app/controller/plan/plan_controller.go @@ -10,6 +10,7 @@ import ( "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/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/response.go b/internal/app/controller/response.go index 5986159..4fdaae8 100644 --- a/internal/app/controller/response.go +++ b/internal/app/controller/response.go @@ -4,6 +4,7 @@ import ( "net/http" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/controller/user/user_controller.go b/internal/app/controller/user/user_controller.go index 4392333..1aa38c3 100644 --- a/internal/app/controller/user/user_controller.go +++ b/internal/app/controller/user/user_controller.go @@ -8,6 +8,7 @@ import ( "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/infra/logs" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/dto/notification_converter.go b/internal/app/dto/notification_converter.go index 5df25a8..fbc49b7 100644 --- a/internal/app/dto/notification_converter.go +++ b/internal/app/dto/notification_converter.go @@ -2,6 +2,7 @@ package dto import ( "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" + "go.uber.org/zap/zapcore" ) diff --git a/internal/app/dto/notification_dto.go b/internal/app/dto/notification_dto.go index 9cbc9b0..b493d4e 100644 --- a/internal/app/dto/notification_dto.go +++ b/internal/app/dto/notification_dto.go @@ -5,6 +5,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/notify" + "go.uber.org/zap/zapcore" ) diff --git a/internal/app/middleware/audit.go b/internal/app/middleware/audit.go index 2a09dc5..9cb6e36 100644 --- a/internal/app/middleware/audit.go +++ b/internal/app/middleware/audit.go @@ -6,6 +6,7 @@ import ( "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/models" + "github.com/labstack/echo/v4" ) diff --git a/internal/app/middleware/auth.go b/internal/app/middleware/auth.go index 8f9b9fb..f8b1cb7 100644 --- a/internal/app/middleware/auth.go +++ b/internal/app/middleware/auth.go @@ -12,6 +12,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" + "github.com/labstack/echo/v4" "gorm.io/gorm" ) diff --git a/internal/domain/audit/service.go b/internal/app/service/audit_service.go similarity index 53% rename from internal/domain/audit/service.go rename to internal/app/service/audit_service.go index 6f72396..6a43c3a 100644 --- a/internal/domain/audit/service.go +++ b/internal/app/service/audit_service.go @@ -1,13 +1,13 @@ // Package audit 提供了用户操作审计相关的功能 -package audit +package service import ( + "context" "time" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" - // 移除对 "github.com/gin-gonic/gin" 的直接依赖 ) // RequestContext 封装了审计日志所需的请求上下文信息 @@ -17,27 +17,32 @@ type RequestContext struct { HTTPMethod string } -// Service 定义了审计服务的接口 -type Service interface { - LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) +// AuditService 定义了审计服务的接口 +type AuditService interface { + LogAction(ctx context.Context, user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) } -// service 是 Service 接口的实现 -type service struct { +// auditService 是 AuditService 接口的实现 +type auditService struct { + ctx context.Context userActionLogRepository repository.UserActionLogRepository - logger *logs.Logger } -// NewService 创建一个新的审计服务实例 -func NewService(repo repository.UserActionLogRepository, logger *logs.Logger) Service { - return &service{userActionLogRepository: repo, logger: logger} +// NewAuditService 创建一个新的审计服务实例 +func NewAuditService(ctx context.Context, repo repository.UserActionLogRepository) AuditService { + return &auditService{ + ctx: ctx, + userActionLogRepository: repo, + } } // 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 对象 if user == nil { - s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil") + logger.Warnw("无法记录审计日志:传入的用户对象为 nil") return } @@ -56,14 +61,14 @@ func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType // 使用模型提供的方法来设置 TargetResource if err := log.SetTargetResource(targetResource); err != nil { - s.logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err) + logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err) // 即使序列化失败,我们可能仍然希望记录操作本身,所以不在此处 return } // 异步写入数据库,不阻塞当前请求 go func() { - if err := s.userActionLogRepository.Create(log); err != nil { - s.logger.Errorw("异步保存审计日志失败", "error", err) + if err := s.userActionLogRepository.Create(serviceCtx, log); err != nil { + logger.Errorw("异步保存审计日志失败", "error", err) } }() } diff --git a/internal/app/service/device_service.go b/internal/app/service/device_service.go index 82733a2..d00080e 100644 --- a/internal/app/service/device_service.go +++ b/internal/app/service/device_service.go @@ -1,12 +1,14 @@ package service import ( + "context" "encoding/json" "errors" "fmt" "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/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" ) @@ -25,42 +27,45 @@ var ( // DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。 // DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。 type DeviceService interface { - CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) - GetDevice(id uint) (*dto.DeviceResponse, error) - ListDevices() ([]*dto.DeviceResponse, error) - UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) - DeleteDevice(id uint) error - ManualControl(id uint, req *dto.ManualControlDeviceRequest) error + CreateDevice(ctx context.Context, req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) + GetDevice(ctx context.Context, id uint) (*dto.DeviceResponse, error) + ListDevices(ctx context.Context) ([]*dto.DeviceResponse, error) + UpdateDevice(ctx context.Context, id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) + DeleteDevice(ctx context.Context, id uint) error + ManualControl(ctx context.Context, id uint, req *dto.ManualControlDeviceRequest) error - CreateAreaController(req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) - GetAreaController(id uint) (*dto.AreaControllerResponse, error) - ListAreaControllers() ([]*dto.AreaControllerResponse, error) - UpdateAreaController(id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) - DeleteAreaController(id uint) error + CreateAreaController(ctx context.Context, req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) + GetAreaController(ctx context.Context, id uint) (*dto.AreaControllerResponse, error) + ListAreaControllers(ctx context.Context) ([]*dto.AreaControllerResponse, error) + UpdateAreaController(ctx context.Context, id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) + DeleteAreaController(ctx context.Context, id uint) error - CreateDeviceTemplate(req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) - GetDeviceTemplate(id uint) (*dto.DeviceTemplateResponse, error) - ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error) - UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) - DeleteDeviceTemplate(id uint) error + CreateDeviceTemplate(ctx context.Context, req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) + GetDeviceTemplate(ctx context.Context, id uint) (*dto.DeviceTemplateResponse, error) + ListDeviceTemplates(ctx context.Context) ([]*dto.DeviceTemplateResponse, error) + UpdateDeviceTemplate(ctx context.Context, id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) + DeleteDeviceTemplate(ctx context.Context, id uint) error } // deviceService 是 DeviceService 接口的具体实现。 type deviceService struct { + ctx context.Context deviceRepo repository.DeviceRepository areaControllerRepo repository.AreaControllerRepository deviceTemplateRepo repository.DeviceTemplateRepository - deviceDomainSvc device.Service // 依赖领域服务 + deviceDomainSvc device.Service } // NewDeviceService 创建一个新的 DeviceService 实例。 func NewDeviceService( + ctx context.Context, deviceRepo repository.DeviceRepository, areaControllerRepo repository.AreaControllerRepository, deviceTemplateRepo repository.DeviceTemplateRepository, deviceDomainSvc device.Service, ) DeviceService { return &deviceService{ + ctx: ctx, deviceRepo: deviceRepo, areaControllerRepo: areaControllerRepo, deviceTemplateRepo: deviceTemplateRepo, @@ -70,7 +75,8 @@ func NewDeviceService( // --- 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) if err != nil { 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 } - if err := s.deviceRepo.Create(device); err != nil { + if err := s.deviceRepo.Create(serviceCtx, device); err != nil { return nil, err } - createdDevice, err := s.deviceRepo.FindByID(device.ID) + createdDevice, err := s.deviceRepo.FindByID(serviceCtx, device.ID) if err != nil { return nil, err } @@ -100,24 +106,27 @@ func (s *deviceService) CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceR return dto.NewDeviceResponse(createdDevice) } -func (s *deviceService) GetDevice(id uint) (*dto.DeviceResponse, error) { - device, err := s.deviceRepo.FindByID(id) +func (s *deviceService) GetDevice(ctx context.Context, id uint) (*dto.DeviceResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetDevice") + device, err := s.deviceRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } return dto.NewDeviceResponse(device) } -func (s *deviceService) ListDevices() ([]*dto.DeviceResponse, error) { - devices, err := s.deviceRepo.ListAll() +func (s *deviceService) ListDevices(ctx context.Context) ([]*dto.DeviceResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListDevices") + devices, err := s.deviceRepo.ListAll(serviceCtx) if err != nil { return nil, err } return dto.NewListDeviceResponse(devices) } -func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) { - existingDevice, err := s.deviceRepo.FindByID(id) +func (s *deviceService) UpdateDevice(ctx context.Context, id uint, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateDevice") + existingDevice, err := s.deviceRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } @@ -137,11 +146,11 @@ func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dt return nil, err } - if err := s.deviceRepo.Update(existingDevice); err != nil { + if err := s.deviceRepo.Update(serviceCtx, existingDevice); err != nil { return nil, err } - updatedDevice, err := s.deviceRepo.FindByID(existingDevice.ID) + updatedDevice, err := s.deviceRepo.FindByID(serviceCtx, existingDevice.ID) if err != nil { return nil, err } @@ -149,16 +158,17 @@ func (s *deviceService) UpdateDevice(id uint, req *dto.UpdateDeviceRequest) (*dt 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 { return err // 如果未找到,会返回 gorm.ErrRecordNotFound } // 在删除前检查设备是否被任务使用 - inUse, err := s.deviceRepo.IsDeviceInUse(id) + inUse, err := s.deviceRepo.IsDeviceInUse(serviceCtx, id) if err != nil { // 如果检查过程中发生数据库错误,则返回错误 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 { - dev, err := s.deviceRepo.FindByID(id) +func (s *deviceService) ManualControl(ctx context.Context, id uint, req *dto.ManualControlDeviceRequest) error { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "ManualControl") + dev, err := s.deviceRepo.FindByID(serviceCtx, id) if err != nil { return err } if req.Action == nil { - return s.deviceDomainSvc.Collect(dev.AreaControllerID, []*models.Device{dev}) + return s.deviceDomainSvc.Collect(serviceCtx, dev.AreaControllerID, []*models.Device{dev}) } else { action := device.DeviceActionStart switch *req.Action { @@ -190,13 +201,14 @@ func (s *deviceService) ManualControl(id uint, req *dto.ManualControlDeviceReque default: return errors.New("invalid action") } - return s.deviceDomainSvc.Switch(dev, action) + return s.deviceDomainSvc.Switch(serviceCtx, dev, action) } } // --- 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) if err != nil { return nil, err @@ -213,31 +225,34 @@ func (s *deviceService) CreateAreaController(req *dto.CreateAreaControllerReques return nil, err } - if err := s.areaControllerRepo.Create(ac); err != nil { + if err := s.areaControllerRepo.Create(serviceCtx, ac); err != nil { return nil, err } return dto.NewAreaControllerResponse(ac) } -func (s *deviceService) GetAreaController(id uint) (*dto.AreaControllerResponse, error) { - ac, err := s.areaControllerRepo.FindByID(id) +func (s *deviceService) GetAreaController(ctx context.Context, id uint) (*dto.AreaControllerResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetAreaController") + ac, err := s.areaControllerRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } return dto.NewAreaControllerResponse(ac) } -func (s *deviceService) ListAreaControllers() ([]*dto.AreaControllerResponse, error) { - acs, err := s.areaControllerRepo.ListAll() +func (s *deviceService) ListAreaControllers(ctx context.Context) ([]*dto.AreaControllerResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListAreaControllers") + acs, err := s.areaControllerRepo.ListAll(serviceCtx) if err != nil { return nil, err } return dto.NewListAreaControllerResponse(acs) } -func (s *deviceService) UpdateAreaController(id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) { - existingAC, err := s.areaControllerRepo.FindByID(id) +func (s *deviceService) UpdateAreaController(ctx context.Context, id uint, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateAreaController") + existingAC, err := s.areaControllerRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } @@ -256,23 +271,24 @@ func (s *deviceService) UpdateAreaController(id uint, req *dto.UpdateAreaControl return nil, err } - if err := s.areaControllerRepo.Update(existingAC); err != nil { + if err := s.areaControllerRepo.Update(serviceCtx, existingAC); err != nil { return nil, err } 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. 检查是否存在 - _, err := s.areaControllerRepo.FindByID(id) + _, err := s.areaControllerRepo.FindByID(serviceCtx, id) if err != nil { return err // 如果未找到,gorm会返回 ErrRecordNotFound } // 2. 检查是否被使用(业务逻辑) - inUse, err := s.deviceRepo.IsAreaControllerInUse(id) + inUse, err := s.deviceRepo.IsAreaControllerInUse(serviceCtx, id) if err != nil { return err // 返回数据库检查错误 } @@ -281,12 +297,13 @@ func (s *deviceService) DeleteAreaController(id uint) error { } // 3. 执行删除 - return s.areaControllerRepo.Delete(id) + return s.areaControllerRepo.Delete(serviceCtx, id) } // --- 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) if err != nil { return nil, err @@ -310,31 +327,34 @@ func (s *deviceService) CreateDeviceTemplate(req *dto.CreateDeviceTemplateReques return nil, err } - if err := s.deviceTemplateRepo.Create(deviceTemplate); err != nil { + if err := s.deviceTemplateRepo.Create(serviceCtx, deviceTemplate); err != nil { return nil, err } return dto.NewDeviceTemplateResponse(deviceTemplate) } -func (s *deviceService) GetDeviceTemplate(id uint) (*dto.DeviceTemplateResponse, error) { - deviceTemplate, err := s.deviceTemplateRepo.FindByID(id) +func (s *deviceService) GetDeviceTemplate(ctx context.Context, id uint) (*dto.DeviceTemplateResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetDeviceTemplate") + deviceTemplate, err := s.deviceTemplateRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } return dto.NewDeviceTemplateResponse(deviceTemplate) } -func (s *deviceService) ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error) { - deviceTemplates, err := s.deviceTemplateRepo.ListAll() +func (s *deviceService) ListDeviceTemplates(ctx context.Context) ([]*dto.DeviceTemplateResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListDeviceTemplates") + deviceTemplates, err := s.deviceTemplateRepo.ListAll(serviceCtx) if err != nil { return nil, err } return dto.NewListDeviceTemplateResponse(deviceTemplates) } -func (s *deviceService) UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) { - existingDeviceTemplate, err := s.deviceTemplateRepo.FindByID(id) +func (s *deviceService) UpdateDeviceTemplate(ctx context.Context, id uint, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "UpdateDeviceTemplate") + existingDeviceTemplate, err := s.deviceTemplateRepo.FindByID(serviceCtx, id) if err != nil { return nil, err } @@ -360,23 +380,24 @@ func (s *deviceService) UpdateDeviceTemplate(id uint, req *dto.UpdateDeviceTempl return nil, err } - if err := s.deviceTemplateRepo.Update(existingDeviceTemplate); err != nil { + if err := s.deviceTemplateRepo.Update(serviceCtx, existingDeviceTemplate); err != nil { return nil, err } 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. 检查是否存在 - _, err := s.deviceTemplateRepo.FindByID(id) + _, err := s.deviceTemplateRepo.FindByID(serviceCtx, id) if err != nil { return err } // 2. 检查是否被使用(业务逻辑) - inUse, err := s.deviceTemplateRepo.IsInUse(id) + inUse, err := s.deviceTemplateRepo.IsInUse(serviceCtx, id) if err != nil { return err } @@ -385,5 +406,5 @@ func (s *deviceService) DeleteDeviceTemplate(id uint) error { } // 3. 执行删除 - return s.deviceTemplateRepo.Delete(id) + return s.deviceTemplateRepo.Delete(serviceCtx, id) } diff --git a/internal/app/service/monitor_service.go b/internal/app/service/monitor_service.go index 4f2f9e5..ea3bbab 100644 --- a/internal/app/service/monitor_service.go +++ b/internal/app/service/monitor_service.go @@ -1,35 +1,39 @@ package service import ( + "context" + "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/repository" ) // MonitorService 定义了监控相关的业务逻辑服务接口 type MonitorService interface { - ListSensorData(req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error) - ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error) - ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error) - ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error) - ListPendingCollections(req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error) - ListUserActionLogs(req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error) - ListRawMaterialPurchases(req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) - ListRawMaterialStockLogs(req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) - ListFeedUsageRecords(req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) - ListMedicationLogs(req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) - ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error) - ListWeighingBatches(req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error) - ListWeighingRecords(req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error) - ListPigTransferLogs(req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error) - ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error) - ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error) - ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error) - ListNotifications(req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error) + ListSensorData(ctx context.Context, req *dto.ListSensorDataRequest) (*dto.ListSensorDataResponse, error) + ListDeviceCommandLogs(ctx context.Context, req *dto.ListDeviceCommandLogRequest) (*dto.ListDeviceCommandLogResponse, error) + ListPlanExecutionLogs(ctx context.Context, req *dto.ListPlanExecutionLogRequest) (*dto.ListPlanExecutionLogResponse, error) + ListTaskExecutionLogs(ctx context.Context, req *dto.ListTaskExecutionLogRequest) (*dto.ListTaskExecutionLogResponse, error) + ListPendingCollections(ctx context.Context, req *dto.ListPendingCollectionRequest) (*dto.ListPendingCollectionResponse, error) + ListUserActionLogs(ctx context.Context, req *dto.ListUserActionLogRequest) (*dto.ListUserActionLogResponse, error) + ListRawMaterialPurchases(ctx context.Context, req *dto.ListRawMaterialPurchaseRequest) (*dto.ListRawMaterialPurchaseResponse, error) + ListRawMaterialStockLogs(ctx context.Context, req *dto.ListRawMaterialStockLogRequest) (*dto.ListRawMaterialStockLogResponse, error) + ListFeedUsageRecords(ctx context.Context, req *dto.ListFeedUsageRecordRequest) (*dto.ListFeedUsageRecordResponse, error) + ListMedicationLogs(ctx context.Context, req *dto.ListMedicationLogRequest) (*dto.ListMedicationLogResponse, error) + ListPigBatchLogs(ctx context.Context, req *dto.ListPigBatchLogRequest) (*dto.ListPigBatchLogResponse, error) + ListWeighingBatches(ctx context.Context, req *dto.ListWeighingBatchRequest) (*dto.ListWeighingBatchResponse, error) + ListWeighingRecords(ctx context.Context, req *dto.ListWeighingRecordRequest) (*dto.ListWeighingRecordResponse, error) + ListPigTransferLogs(ctx context.Context, req *dto.ListPigTransferLogRequest) (*dto.ListPigTransferLogResponse, error) + ListPigSickLogs(ctx context.Context, req *dto.ListPigSickLogRequest) (*dto.ListPigSickLogResponse, error) + ListPigPurchases(ctx context.Context, req *dto.ListPigPurchaseRequest) (*dto.ListPigPurchaseResponse, error) + ListPigSales(ctx context.Context, req *dto.ListPigSaleRequest) (*dto.ListPigSaleResponse, error) + ListNotifications(ctx context.Context, req *dto.ListNotificationRequest) (*dto.ListNotificationResponse, error) } // monitorService 是 MonitorService 接口的具体实现 type monitorService struct { + ctx context.Context sensorDataRepo repository.SensorDataRepository deviceCommandLogRepo repository.DeviceCommandLogRepository executionLogRepo repository.ExecutionLogRepository @@ -48,6 +52,7 @@ type monitorService struct { // NewMonitorService 创建一个新的 MonitorService 实例 func NewMonitorService( + ctx context.Context, sensorDataRepo repository.SensorDataRepository, deviceCommandLogRepo repository.DeviceCommandLogRepository, executionLogRepo repository.ExecutionLogRepository, @@ -64,6 +69,7 @@ func NewMonitorService( notificationRepo repository.NotificationRepository, ) MonitorService { return &monitorService{ + ctx: ctx, sensorDataRepo: sensorDataRepo, deviceCommandLogRepo: deviceCommandLogRepo, executionLogRepo: executionLogRepo, @@ -82,7 +88,8 @@ func NewMonitorService( } // 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{ DeviceID: req.DeviceID, OrderBy: req.OrderBy, @@ -94,7 +101,7 @@ func (s *monitorService) ListSensorData(req *dto.ListSensorDataRequest) (*dto.Li 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 { return nil, err } @@ -103,7 +110,8 @@ func (s *monitorService) ListSensorData(req *dto.ListSensorDataRequest) (*dto.Li } // 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{ DeviceID: req.DeviceID, ReceivedSuccess: req.ReceivedSuccess, @@ -112,7 +120,7 @@ func (s *monitorService) ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequ 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 { return nil, err } @@ -121,7 +129,8 @@ func (s *monitorService) ListDeviceCommandLogs(req *dto.ListDeviceCommandLogRequ } // 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{ PlanID: req.PlanID, OrderBy: req.OrderBy, @@ -133,7 +142,7 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ 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 { return nil, err } @@ -151,7 +160,7 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ planIds = append(planIds, datum.PlanID) } } - plans, err := s.planRepository.GetPlansByIDs(planIds) + plans, err := s.planRepository.GetPlansByIDs(serviceCtx, planIds) if err != nil { return nil, err } @@ -159,7 +168,8 @@ func (s *monitorService) ListPlanExecutionLogs(req *dto.ListPlanExecutionLogRequ } // 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{ PlanExecutionLogID: req.PlanExecutionLogID, TaskID: req.TaskID, @@ -172,7 +182,7 @@ func (s *monitorService) ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequ 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 { return nil, err } @@ -181,7 +191,8 @@ func (s *monitorService) ListTaskExecutionLogs(req *dto.ListTaskExecutionLogRequ } // 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{ DeviceID: req.DeviceID, OrderBy: req.OrderBy, @@ -193,7 +204,7 @@ func (s *monitorService) ListPendingCollections(req *dto.ListPendingCollectionRe 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 { return nil, err } @@ -202,7 +213,8 @@ func (s *monitorService) ListPendingCollections(req *dto.ListPendingCollectionRe } // 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{ UserID: req.UserID, Username: req.Username, @@ -216,7 +228,7 @@ func (s *monitorService) ListUserActionLogs(req *dto.ListUserActionLogRequest) ( 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 { return nil, err } @@ -225,7 +237,8 @@ func (s *monitorService) ListUserActionLogs(req *dto.ListUserActionLogRequest) ( } // 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{ RawMaterialID: req.RawMaterialID, Supplier: req.Supplier, @@ -234,7 +247,7 @@ func (s *monitorService) ListRawMaterialPurchases(req *dto.ListRawMaterialPurcha 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 { return nil, err } @@ -243,7 +256,8 @@ func (s *monitorService) ListRawMaterialPurchases(req *dto.ListRawMaterialPurcha } // 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{ RawMaterialID: req.RawMaterialID, SourceID: req.SourceID, @@ -256,7 +270,7 @@ func (s *monitorService) ListRawMaterialStockLogs(req *dto.ListRawMaterialStockL 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 { return nil, err } @@ -265,7 +279,8 @@ func (s *monitorService) ListRawMaterialStockLogs(req *dto.ListRawMaterialStockL } // 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{ PenID: req.PenID, FeedFormulaID: req.FeedFormulaID, @@ -275,7 +290,7 @@ func (s *monitorService) ListFeedUsageRecords(req *dto.ListFeedUsageRecordReques 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 { return nil, err } @@ -284,7 +299,8 @@ func (s *monitorService) ListFeedUsageRecords(req *dto.ListFeedUsageRecordReques } // 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{ PigBatchID: req.PigBatchID, MedicationID: req.MedicationID, @@ -298,7 +314,7 @@ func (s *monitorService) ListMedicationLogs(req *dto.ListMedicationLogRequest) ( 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 { return nil, err } @@ -307,7 +323,8 @@ func (s *monitorService) ListMedicationLogs(req *dto.ListMedicationLogRequest) ( } // 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{ PigBatchID: req.PigBatchID, OperatorID: req.OperatorID, @@ -320,7 +337,7 @@ func (s *monitorService) ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto 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 { return nil, err } @@ -329,7 +346,8 @@ func (s *monitorService) ListPigBatchLogs(req *dto.ListPigBatchLogRequest) (*dto } // 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{ PigBatchID: req.PigBatchID, OrderBy: req.OrderBy, @@ -337,7 +355,7 @@ func (s *monitorService) ListWeighingBatches(req *dto.ListWeighingBatchRequest) 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 { return nil, err } @@ -346,7 +364,8 @@ func (s *monitorService) ListWeighingBatches(req *dto.ListWeighingBatchRequest) } // 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{ WeighingBatchID: req.WeighingBatchID, PenID: req.PenID, @@ -356,7 +375,7 @@ func (s *monitorService) ListWeighingRecords(req *dto.ListWeighingRecordRequest) 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 { return nil, err } @@ -365,7 +384,8 @@ func (s *monitorService) ListWeighingRecords(req *dto.ListWeighingRecordRequest) } // 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{ PigBatchID: req.PigBatchID, PenID: req.PenID, @@ -380,7 +400,7 @@ func (s *monitorService) ListPigTransferLogs(req *dto.ListPigTransferLogRequest) 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 { return nil, err } @@ -389,7 +409,8 @@ func (s *monitorService) ListPigTransferLogs(req *dto.ListPigTransferLogRequest) } // 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{ PigBatchID: req.PigBatchID, PenID: req.PenID, @@ -407,7 +428,7 @@ func (s *monitorService) ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.L 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 { return nil, err } @@ -416,7 +437,8 @@ func (s *monitorService) ListPigSickLogs(req *dto.ListPigSickLogRequest) (*dto.L } // 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{ PigBatchID: req.PigBatchID, Supplier: req.Supplier, @@ -426,7 +448,7 @@ func (s *monitorService) ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto 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 { return nil, err } @@ -435,7 +457,8 @@ func (s *monitorService) ListPigPurchases(req *dto.ListPigPurchaseRequest) (*dto } // 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{ PigBatchID: req.PigBatchID, Buyer: req.Buyer, @@ -445,7 +468,7 @@ func (s *monitorService) ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPig 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 { return nil, err } @@ -454,7 +477,8 @@ func (s *monitorService) ListPigSales(req *dto.ListPigSaleRequest) (*dto.ListPig } // 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{ UserID: req.UserID, NotifierType: req.NotifierType, @@ -465,7 +489,7 @@ func (s *monitorService) ListNotifications(req *dto.ListNotificationRequest) (*d 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 { return nil, err } diff --git a/internal/app/service/pig_batch_service.go b/internal/app/service/pig_batch_service.go index e5bc777..4ee78ac 100644 --- a/internal/app/service/pig_batch_service.go +++ b/internal/app/service/pig_batch_service.go @@ -1,6 +1,7 @@ package service import ( + "context" "time" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" @@ -11,47 +12,47 @@ import ( // PigBatchService 接口定义保持不变,继续作为应用层对外的契约。 type PigBatchService interface { - CreatePigBatch(operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) - GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) - UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) - DeletePigBatch(id uint) error - ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) + CreatePigBatch(ctx context.Context, operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) + GetPigBatch(ctx context.Context, id uint) (*dto.PigBatchResponseDTO, error) + UpdatePigBatch(ctx context.Context, id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) + DeletePigBatch(ctx context.Context, id uint) error + ListPigBatches(ctx context.Context, isActive *bool) ([]*dto.PigBatchResponseDTO, error) // Pig Pen Management - AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error - ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error - RemoveEmptyPenFromBatch(batchID uint, penID uint) error - MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error + AssignEmptyPensToBatch(ctx context.Context, batchID uint, penIDs []uint, operatorID uint) error + ReclassifyPenToNewBatch(ctx context.Context, fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error + RemoveEmptyPenFromBatch(ctx context.Context, batchID uint, penID uint) error + MovePigsIntoPen(ctx context.Context, batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error // Trade Sub-service - SellPigs(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 + 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(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 - TransferPigsAcrossBatches(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 + TransferPigsAcrossBatches(ctx context.Context, sourceBatchID uint, destBatchID 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 - RecordSickPigs(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 - RecordSickPigDeath(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 + RecordSickPigs(ctx context.Context, 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(ctx context.Context, 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 - RecordDeath(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 + RecordDeath(ctx context.Context, 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 的实现现在依赖于领域服务接口。 type pigBatchService struct { - logger *logs.Logger - domainService domain_pig.PigBatchService // 依赖注入领域服务 + ctx context.Context + domainService domain_pig.PigBatchService } // NewPigBatchService 构造函数被修改,以注入领域服务。 -func NewPigBatchService(domainService domain_pig.PigBatchService, logger *logs.Logger) PigBatchService { +func NewPigBatchService(ctx context.Context, domainService domain_pig.PigBatchService) PigBatchService { return &pigBatchService{ - logger: logger, + ctx: ctx, domainService: domainService, } } @@ -78,7 +79,8 @@ func (s *pigBatchService) toPigBatchResponseDTO(batch *models.PigBatch, currentT } // 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 -> 领域模型 batch := &models.PigBatch{ BatchNumber: dto.BatchNumber, @@ -89,9 +91,9 @@ func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreat } // 2. 调用领域服务 - createdBatch, err := s.domainService.CreatePigBatch(operatorID, batch) + createdBatch, err := s.domainService.CreatePigBatch(serviceCtx, operatorID, batch) if err != nil { - s.logger.Errorf("应用层: 创建猪批次失败: %v", err) + logger.Errorf("应用层: 创建猪批次失败: %v", err) return nil, MapDomainError(err) } @@ -100,31 +102,33 @@ func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreat } // GetPigBatch 从领域服务获取数据并转换为DTO,同时处理错误转换。 -func (s *pigBatchService) GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) { - batch, err := s.domainService.GetPigBatch(id) +func (s *pigBatchService) GetPigBatch(ctx context.Context, id uint) (*dto.PigBatchResponseDTO, error) { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "GetPigBatch") + batch, err := s.domainService.GetPigBatch(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 获取猪批次失败, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 获取猪批次失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } - currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id) + currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } - currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id) + currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } return s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens), nil } // 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. 先获取最新的领域模型 - existingBatch, err := s.domainService.GetPigBatch(id) + existingBatch, err := s.domainService.GetPigBatch(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 更新猪批次失败,获取原批次信息错误, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 更新猪批次失败,获取原批次信息错误, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } @@ -149,21 +153,21 @@ func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (* } // 3. 调用领域服务执行更新 - updatedBatch, err := s.domainService.UpdatePigBatch(existingBatch) + updatedBatch, err := s.domainService.UpdatePigBatch(serviceCtx, existingBatch) if err != nil { - s.logger.Errorf("应用层: 更新猪批次失败, ID: %d, 错误: %v", id, err) + logger.Errorf("应用层: 更新猪批次失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } // 4. 填充猪群信息 - currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id) + currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } - currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id) + currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, id) if err != nil { - s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) + logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err) return nil, MapDomainError(err) } @@ -172,33 +176,35 @@ func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (* } // DeletePigBatch 将删除操作委托给领域服务,并转换领域错误为应用层错误。 -func (s *pigBatchService) DeletePigBatch(id uint) error { - err := s.domainService.DeletePigBatch(id) +func (s *pigBatchService) DeletePigBatch(ctx context.Context, id uint) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "DeletePigBatch") + err := s.domainService.DeletePigBatch(serviceCtx, id) if err != nil { - s.logger.Errorf("应用层: 删除猪批次失败, ID: %d, 错误: %v", id, err) + logger.Errorf("应用层: 删除猪批次失败, ID: %d, 错误: %v", id, err) return MapDomainError(err) } return nil } // ListPigBatches 从领域服务获取列表并进行转换。 -func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) { - batches, err := s.domainService.ListPigBatches(isActive) +func (s *pigBatchService) ListPigBatches(ctx context.Context, isActive *bool) ([]*dto.PigBatchResponseDTO, error) { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListPigBatches") + batches, err := s.domainService.ListPigBatches(serviceCtx, isActive) if err != nil { - s.logger.Errorf("应用层: 批量查询猪批次失败: %v", err) + logger.Errorf("应用层: 批量查询猪批次失败: %v", err) return nil, MapDomainError(err) } var responseDTOs []*dto.PigBatchResponseDTO for _, batch := range batches { - currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(batch.ID) + currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(serviceCtx, batch.ID) if err != nil { - s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", batch.ID, err) + logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", batch.ID, err) return nil, MapDomainError(err) } - currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(batch.ID) + currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(serviceCtx, batch.ID) if err != nil { - s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", batch.ID, err) + logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", batch.ID, err) return nil, MapDomainError(err) } responseDTOs = append(responseDTOs, s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens)) @@ -208,140 +214,154 @@ func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchRespons } // AssignEmptyPensToBatch 委托给领域服务 -func (s *pigBatchService) AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error { - err := s.domainService.AssignEmptyPensToBatch(batchID, penIDs, operatorID) +func (s *pigBatchService) AssignEmptyPensToBatch(ctx context.Context, batchID uint, penIDs []uint, operatorID uint) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "AssignEmptyPensToBatch") + err := s.domainService.AssignEmptyPensToBatch(serviceCtx, batchID, penIDs, operatorID) if err != nil { - s.logger.Errorf("应用层: 为猪批次分配空栏失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 为猪批次分配空栏失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // ReclassifyPenToNewBatch 委托给领域服务 -func (s *pigBatchService) ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error { - err := s.domainService.ReclassifyPenToNewBatch(fromBatchID, toBatchID, penID, operatorID, remarks) +func (s *pigBatchService) ReclassifyPenToNewBatch(ctx context.Context, fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "ReclassifyPenToNewBatch") + err := s.domainService.ReclassifyPenToNewBatch(serviceCtx, fromBatchID, toBatchID, penID, operatorID, remarks) if err != nil { - s.logger.Errorf("应用层: 划拨猪栏到新批次失败, 源批次ID: %d, 错误: %v", fromBatchID, err) + logger.Errorf("应用层: 划拨猪栏到新批次失败, 源批次ID: %d, 错误: %v", fromBatchID, err) return MapDomainError(err) } return nil } // RemoveEmptyPenFromBatch 委托给领域服务 -func (s *pigBatchService) RemoveEmptyPenFromBatch(batchID uint, penID uint) error { - err := s.domainService.RemoveEmptyPenFromBatch(batchID, penID) +func (s *pigBatchService) RemoveEmptyPenFromBatch(ctx context.Context, batchID uint, penID uint) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RemoveEmptyPenFromBatch") + err := s.domainService.RemoveEmptyPenFromBatch(serviceCtx, batchID, penID) 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 nil } // MovePigsIntoPen 委托给领域服务 -func (s *pigBatchService) MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error { - err := s.domainService.MovePigsIntoPen(batchID, toPenID, quantity, operatorID, remarks) +func (s *pigBatchService) MovePigsIntoPen(ctx context.Context, batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "MovePigsIntoPen") + err := s.domainService.MovePigsIntoPen(serviceCtx, batchID, toPenID, quantity, operatorID, remarks) 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 nil } // 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 { - err := s.domainService.SellPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID) +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 { + 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 { - s.logger.Errorf("应用层: 卖猪失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 卖猪失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // 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 { - err := s.domainService.BuyPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID) +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 { + 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 { - s.logger.Errorf("应用层: 买猪失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 买猪失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // TransferPigsAcrossBatches 委托给领域服务 -func (s *pigBatchService) TransferPigsAcrossBatches(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) +func (s *pigBatchService) TransferPigsAcrossBatches(ctx context.Context, sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "TransferPigsAcrossBatches") + err := s.domainService.TransferPigsAcrossBatches(serviceCtx, sourceBatchID, destBatchID, fromPenID, toPenID, quantity, operatorID, remarks) if err != nil { - s.logger.Errorf("应用层: 跨群调栏失败, 源批次ID: %d, 错误: %v", sourceBatchID, err) + logger.Errorf("应用层: 跨群调栏失败, 源批次ID: %d, 错误: %v", sourceBatchID, err) return MapDomainError(err) } return nil } // TransferPigsWithinBatch 委托给领域服务 -func (s *pigBatchService) TransferPigsWithinBatch(batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error { - err := s.domainService.TransferPigsWithinBatch(batchID, fromPenID, toPenID, quantity, operatorID, remarks) +func (s *pigBatchService) TransferPigsWithinBatch(ctx context.Context, batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "TransferPigsWithinBatch") + err := s.domainService.TransferPigsWithinBatch(serviceCtx, batchID, fromPenID, toPenID, quantity, operatorID, remarks) if err != nil { - s.logger.Errorf("应用层: 群内调栏失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 群内调栏失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordSickPigs 委托给领域服务 -func (s *pigBatchService) RecordSickPigs(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) +func (s *pigBatchService) RecordSickPigs(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigs") + err := s.domainService.RecordSickPigs(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录病猪事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录病猪事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordSickPigRecovery 委托给领域服务 -func (s *pigBatchService) RecordSickPigRecovery(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) +func (s *pigBatchService) RecordSickPigRecovery(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigRecovery") + err := s.domainService.RecordSickPigRecovery(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录病猪康复事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录病猪康复事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordSickPigDeath 委托给领域服务 -func (s *pigBatchService) RecordSickPigDeath(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) +func (s *pigBatchService) RecordSickPigDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigDeath") + err := s.domainService.RecordSickPigDeath(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录病猪死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录病猪死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordSickPigCull 委托给领域服务 -func (s *pigBatchService) RecordSickPigCull(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) +func (s *pigBatchService) RecordSickPigCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordSickPigCull") + err := s.domainService.RecordSickPigCull(serviceCtx, operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录病猪淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录病猪淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordDeath 委托给领域服务 -func (s *pigBatchService) RecordDeath(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { - err := s.domainService.RecordDeath(operatorID, batchID, penID, quantity, happenedAt, remarks) +func (s *pigBatchService) RecordDeath(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordDeath") + err := s.domainService.RecordDeath(serviceCtx, operatorID, batchID, penID, quantity, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录正常猪只死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录正常猪只死亡事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil } // RecordCull 委托给领域服务 -func (s *pigBatchService) RecordCull(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { - err := s.domainService.RecordCull(operatorID, batchID, penID, quantity, happenedAt, remarks) +func (s *pigBatchService) RecordCull(ctx context.Context, operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "RecordCull") + err := s.domainService.RecordCull(serviceCtx, operatorID, batchID, penID, quantity, happenedAt, remarks) if err != nil { - s.logger.Errorf("应用层: 记录正常猪只淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) + logger.Errorf("应用层: 记录正常猪只淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err) return MapDomainError(err) } return nil diff --git a/internal/app/service/pig_farm_service.go b/internal/app/service/pig_farm_service.go index b24f65f..56d9de1 100644 --- a/internal/app/service/pig_farm_service.go +++ b/internal/app/service/pig_farm_service.go @@ -1,6 +1,7 @@ package service import ( + "context" "errors" "fmt" @@ -16,40 +17,41 @@ import ( // PigFarmService 提供了猪场资产管理的业务逻辑 type PigFarmService interface { // PigHouse methods - CreatePigHouse(name, description string) (*dto.PigHouseResponse, error) - GetPigHouseByID(id uint) (*dto.PigHouseResponse, error) - ListPigHouses() ([]dto.PigHouseResponse, error) - UpdatePigHouse(id uint, name, description string) (*dto.PigHouseResponse, error) - DeletePigHouse(id uint) error + CreatePigHouse(ctx context.Context, name, description string) (*dto.PigHouseResponse, error) + GetPigHouseByID(ctx context.Context, id uint) (*dto.PigHouseResponse, error) + ListPigHouses(ctx context.Context) ([]dto.PigHouseResponse, error) + UpdatePigHouse(ctx context.Context, id uint, name, description string) (*dto.PigHouseResponse, error) + DeletePigHouse(ctx context.Context, id uint) error // Pen methods - CreatePen(penNumber string, houseID uint, capacity int) (*dto.PenResponse, error) - GetPenByID(id uint) (*dto.PenResponse, error) - ListPens() ([]*dto.PenResponse, error) - UpdatePen(id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error) - DeletePen(id uint) error + CreatePen(ctx context.Context, penNumber string, houseID uint, capacity int) (*dto.PenResponse, error) + GetPenByID(ctx context.Context, id uint) (*dto.PenResponse, error) + ListPens(ctx context.Context) ([]*dto.PenResponse, error) + UpdatePen(ctx context.Context, id uint, penNumber string, houseID uint, capacity int, status models.PenStatus) (*dto.PenResponse, error) + DeletePen(ctx context.Context, id uint) error // 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 { - logger *logs.Logger + ctx context.Context farmRepository repository.PigFarmRepository penRepository repository.PigPenRepository batchRepository repository.PigBatchRepository - pigBatchService domain_pig.PigBatchService // Add domain PigBatchService dependency - uow repository.UnitOfWork // 工作单元,用于事务管理 + pigBatchService domain_pig.PigBatchService + uow repository.UnitOfWork // 工作单元,用于事务管理 } // NewPigFarmService 创建一个新的 PigFarmService 实例 -func NewPigFarmService(farmRepository repository.PigFarmRepository, +func NewPigFarmService(ctx context.Context, + farmRepository repository.PigFarmRepository, penRepository repository.PigPenRepository, batchRepository repository.PigBatchRepository, pigBatchService domain_pig.PigBatchService, uow repository.UnitOfWork, - logger *logs.Logger) PigFarmService { +) PigFarmService { return &pigFarmService{ - logger: logger, + ctx: ctx, farmRepository: farmRepository, penRepository: penRepository, batchRepository: batchRepository, @@ -60,12 +62,13 @@ func NewPigFarmService(farmRepository repository.PigFarmRepository, // --- 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{ Name: name, Description: description, } - err := s.farmRepository.CreatePigHouse(house) + err := s.farmRepository.CreatePigHouse(serviceCtx, house) if err != nil { return nil, err } @@ -76,8 +79,9 @@ func (s *pigFarmService) CreatePigHouse(name, description string) (*dto.PigHouse }, nil } -func (s *pigFarmService) GetPigHouseByID(id uint) (*dto.PigHouseResponse, error) { - house, err := s.farmRepository.GetPigHouseByID(id) +func (s *pigFarmService) GetPigHouseByID(ctx context.Context, id uint) (*dto.PigHouseResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "GetPigHouseByID") + house, err := s.farmRepository.GetPigHouseByID(serviceCtx, id) if err != nil { return nil, err } @@ -88,8 +92,9 @@ func (s *pigFarmService) GetPigHouseByID(id uint) (*dto.PigHouseResponse, error) }, nil } -func (s *pigFarmService) ListPigHouses() ([]dto.PigHouseResponse, error) { - houses, err := s.farmRepository.ListPigHouses() +func (s *pigFarmService) ListPigHouses(ctx context.Context) ([]dto.PigHouseResponse, error) { + serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListPigHouses") + houses, err := s.farmRepository.ListPigHouses(serviceCtx) if err != nil { return nil, err } @@ -104,13 +109,14 @@ func (s *pigFarmService) ListPigHouses() ([]dto.PigHouseResponse, error) { 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{ Model: gorm.Model{ID: id}, Name: name, Description: description, } - rowsAffected, err := s.farmRepository.UpdatePigHouse(house) + rowsAffected, err := s.farmRepository.UpdatePigHouse(serviceCtx, house) if err != nil { return nil, err } @@ -118,7 +124,7 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*dto return nil, ErrHouseNotFound } // 返回更新后的完整信息 - updatedHouse, err := s.farmRepository.GetPigHouseByID(id) + updatedHouse, err := s.farmRepository.GetPigHouseByID(serviceCtx, id) if err != nil { return nil, err } @@ -129,9 +135,10 @@ func (s *pigFarmService) UpdatePigHouse(id uint, name, description string) (*dto }, 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 { 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 { return err } @@ -152,9 +159,10 @@ func (s *pigFarmService) DeletePigHouse(id uint) error { // --- 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 errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrHouseNotFound @@ -168,7 +176,7 @@ func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int) Capacity: capacity, Status: models.PenStatusEmpty, } - err = s.penRepository.CreatePen(pen) + err = s.penRepository.CreatePen(serviceCtx, pen) if err != nil { return nil, err } @@ -181,15 +189,16 @@ func (s *pigFarmService) CreatePen(penNumber string, houseID uint, capacity int) }, nil } -func (s *pigFarmService) GetPenByID(id uint) (*dto.PenResponse, error) { - pen, err := s.penRepository.GetPenByID(id) +func (s *pigFarmService) GetPenByID(ctx context.Context, id uint) (*dto.PenResponse, error) { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "GetPenByID") + pen, err := s.penRepository.GetPenByID(serviceCtx, id) if err != nil { return nil, err } - currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(id) + currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(serviceCtx, id) if err != nil { - s.logger.Errorf("获取猪栏 %d 存栏量失败: %v", id, err) + logger.Errorf("获取猪栏 %d 存栏量失败: %v", id, err) currentPigCount = 0 // 如果获取计数时出错,则默认为0 } @@ -209,17 +218,18 @@ func (s *pigFarmService) GetPenByID(id uint) (*dto.PenResponse, error) { return response, nil } -func (s *pigFarmService) ListPens() ([]*dto.PenResponse, error) { - pens, err := s.penRepository.ListPens() +func (s *pigFarmService) ListPens(ctx context.Context) ([]*dto.PenResponse, error) { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListPens") + pens, err := s.penRepository.ListPens(serviceCtx) if err != nil { return nil, err } var response []*dto.PenResponse for _, pen := range pens { - currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(pen.ID) + currentPigCount, err := s.pigBatchService.GetCurrentPigsInPen(serviceCtx, pen.ID) if err != nil { - s.logger.Errorf("获取猪栏 %d 存栏量失败: %v", pen.ID, err) + logger.Errorf("获取猪栏 %d 存栏量失败: %v", pen.ID, err) currentPigCount = 0 // 如果获取计数时出错,则默认为0 } @@ -241,9 +251,10 @@ func (s *pigFarmService) ListPens() ([]*dto.PenResponse, error) { 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 errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrHouseNotFound @@ -258,7 +269,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa Capacity: capacity, Status: status, } - rowsAffected, err := s.penRepository.UpdatePen(pen) + rowsAffected, err := s.penRepository.UpdatePen(serviceCtx, pen) if err != nil { return nil, err } @@ -266,7 +277,7 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa return nil, ErrPenNotFound } // 返回更新后的完整信息 - updatedPen, err := s.penRepository.GetPenByID(id) + updatedPen, err := s.penRepository.GetPenByID(serviceCtx, id) if err != nil { return nil, err } @@ -280,9 +291,10 @@ func (s *pigFarmService) UpdatePen(id uint, penNumber string, houseID uint, capa }, 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 errors.Is(err, gorm.ErrRecordNotFound) { return ErrPenNotFound // 猪栏不存在 @@ -293,7 +305,7 @@ func (s *pigFarmService) DeletePen(id uint) error { // 检查猪栏是否关联了活跃批次 // 注意:pen.PigBatchID 是指针类型,需要检查是否为 nil 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) { 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 { return err } @@ -315,15 +327,16 @@ func (s *pigFarmService) DeletePen(id uint) error { } // 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 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 errors.Is(err, gorm.ErrRecordNotFound) { return ErrPenNotFound } - s.logger.Errorf("更新猪栏状态失败: 获取猪栏 %d 信息错误: %v", id, err) + logger.Errorf("更新猪栏状态失败: 获取猪栏 %d 信息错误: %v", id, err) return fmt.Errorf("获取猪栏 %d 信息失败: %w", id, err) } @@ -348,15 +361,15 @@ func (s *pigFarmService) UpdatePenStatus(id uint, newStatus models.PenStatus) (* "status": newStatus, } - if err := s.penRepository.UpdatePenFieldsTx(tx, id, updates); err != nil { - s.logger.Errorf("更新猪栏 %d 状态失败: %v", id, err) + if err := s.penRepository.UpdatePenFieldsTx(serviceCtx, tx, id, updates); err != nil { + logger.Errorf("更新猪栏 %d 状态失败: %v", 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 { - s.logger.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %v", id, err) + logger.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %v", id, err) return fmt.Errorf("更新猪栏状态后获取猪栏 %d 信息失败: %w", id, err) } return nil diff --git a/internal/app/service/plan_service.go b/internal/app/service/plan_service.go index 5678fe0..ba8b416 100644 --- a/internal/app/service/plan_service.go +++ b/internal/app/service/plan_service.go @@ -1,6 +1,7 @@ package service import ( + "context" "errors" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" @@ -12,100 +13,103 @@ import ( // PlanService 定义了计划相关的应用服务接口 type PlanService interface { // CreatePlan 创建一个新的计划 - CreatePlan(req *dto.CreatePlanRequest) (*dto.PlanResponse, error) + CreatePlan(ctx context.Context, req *dto.CreatePlanRequest) (*dto.PlanResponse, error) // GetPlanByID 根据ID获取计划详情 - GetPlanByID(id uint) (*dto.PlanResponse, error) + GetPlanByID(ctx context.Context, id uint) (*dto.PlanResponse, error) // ListPlans 获取计划列表,支持过滤和分页 - ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansResponse, error) + ListPlans(ctx context.Context, query *dto.ListPlansQuery) (*dto.ListPlansResponse, error) // UpdatePlan 更新计划 - UpdatePlan(id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error) + UpdatePlan(ctx context.Context, id uint, req *dto.UpdatePlanRequest) (*dto.PlanResponse, error) // DeletePlan 删除计划(软删除) - DeletePlan(id uint) error + DeletePlan(ctx context.Context, id uint) error // StartPlan 启动计划 - StartPlan(id uint) error + StartPlan(ctx context.Context, id uint) error // StopPlan 停止计划 - StopPlan(id uint) error + StopPlan(ctx context.Context, id uint) error } // planService 是 PlanService 接口的实现 type planService struct { - logger *logs.Logger - domainPlanService plan.Service // 替换为领域层的服务接口 + ctx context.Context + domainPlanService plan.Service } // NewPlanService 创建一个新的 PlanService 实例 func NewPlanService( - logger *logs.Logger, - domainPlanService plan.Service, // 接收领域层服务 + ctx context.Context, + domainPlanService plan.Service, ) PlanService { return &planService{ - logger: logger, - domainPlanService: domainPlanService, // 注入领域层服务 + ctx: ctx, + domainPlanService: domainPlanService, } } // 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 = "应用服务层:创建计划" // 使用 DTO 转换函数将请求转换为领域实体 planToCreate, err := dto.NewPlanFromCreateRequest(req) if err != nil { - s.logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) + logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) return nil, err } // 调用领域服务创建计划 - createdPlan, err := s.domainPlanService.CreatePlan(planToCreate) + createdPlan, err := s.domainPlanService.CreatePlan(serviceCtx, planToCreate) if err != nil { - s.logger.Errorf("%s: 领域服务创建计划失败: %v", actionType, err) + logger.Errorf("%s: 领域服务创建计划失败: %v", actionType, err) return nil, err // 直接返回领域层错误 } // 将领域实体转换为响应 DTO resp, err := dto.NewPlanToResponse(createdPlan) 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("计划创建成功,但响应生成失败") } - s.logger.Infof("%s: 计划创建成功, ID: %d", actionType, createdPlan.ID) + logger.Infof("%s: 计划创建成功, ID: %d", actionType, createdPlan.ID) return resp, nil } // 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 = "应用服务层:获取计划详情" // 调用领域服务获取计划 - plan, err := s.domainPlanService.GetPlanByID(id) + plan, err := s.domainPlanService.GetPlanByID(serviceCtx, id) 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 // 直接返回领域层错误 } // 将领域实体转换为响应 DTO resp, err := dto.NewPlanToResponse(plan) 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("获取计划详情失败: 内部数据格式错误") } - s.logger.Infof("%s: 获取计划详情成功, ID: %d", actionType, id) + logger.Infof("%s: 获取计划详情成功, ID: %d", actionType, id) return resp, nil } // 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 = "应用服务层:获取计划列表" // 将 DTO 查询参数转换为领域层可接受的选项 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 { - s.logger.Errorf("%s: 领域服务获取计划列表失败: %v", actionType, err) + logger.Errorf("%s: 领域服务获取计划列表失败: %v", actionType, err) return nil, err // 直接返回领域层错误 } @@ -114,7 +118,7 @@ func (s *planService) ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansRespon for _, p := range plans { resp, err := dto.NewPlanToResponse(&p) if err != nil { - s.logger.Errorf("%s: 序列化单个计划响应失败: %v, Plan: %+v", actionType, err, p) + logger.Errorf("%s: 序列化单个计划响应失败: %v, Plan: %+v", actionType, err, p) // 这里选择跳过有问题的计划,并记录错误,而不是中断整个列表的返回 continue } @@ -125,81 +129,85 @@ func (s *planService) ListPlans(query *dto.ListPlansQuery) (*dto.ListPlansRespon Plans: planResponses, Total: total, } - s.logger.Infof("%s: 获取计划列表成功, 数量: %d", actionType, len(planResponses)) + logger.Infof("%s: 获取计划列表成功, 数量: %d", actionType, len(planResponses)) return resp, nil } // 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 = "应用服务层:更新计划" // 使用 DTO 转换函数将请求转换为领域实体 planToUpdate, err := dto.NewPlanFromUpdateRequest(req) if err != nil { - s.logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) + logger.Errorf("%s: 计划数据校验失败: %v", actionType, err) return nil, err } planToUpdate.ID = id // 确保ID被设置 // 调用领域服务更新计划 - updatedPlan, err := s.domainPlanService.UpdatePlan(planToUpdate) + updatedPlan, err := s.domainPlanService.UpdatePlan(serviceCtx, planToUpdate) 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 // 直接返回领域层错误 } // 将领域实体转换为响应 DTO resp, err := dto.NewPlanToResponse(updatedPlan) 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("计划更新成功,但响应生成失败") } - s.logger.Infof("%s: 计划更新成功, ID: %d", actionType, updatedPlan.ID) + logger.Infof("%s: 计划更新成功, ID: %d", actionType, updatedPlan.ID) return resp, nil } // 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 = "应用服务层:删除计划" // 调用领域服务删除计划 - err := s.domainPlanService.DeletePlan(id) + err := s.domainPlanService.DeletePlan(serviceCtx, id) if err != nil { - s.logger.Errorf("%s: 领域服务删除计划失败: %v, ID: %d", actionType, err, id) + logger.Errorf("%s: 领域服务删除计划失败: %v, ID: %d", actionType, err, id) return err // 直接返回领域层错误 } - s.logger.Infof("%s: 计划删除成功, ID: %d", actionType, id) + logger.Infof("%s: 计划删除成功, ID: %d", actionType, id) return nil } // 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 = "应用服务层:启动计划" // 调用领域服务启动计划 - err := s.domainPlanService.StartPlan(id) + err := s.domainPlanService.StartPlan(serviceCtx, id) if err != nil { - s.logger.Errorf("%s: 领域服务启动计划失败: %v, ID: %d", actionType, err, id) + logger.Errorf("%s: 领域服务启动计划失败: %v, ID: %d", actionType, err, id) return err // 直接返回领域层错误 } - s.logger.Infof("%s: 计划已成功启动, ID: %d", actionType, id) + logger.Infof("%s: 计划已成功启动, ID: %d", actionType, id) return nil } // 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 = "应用服务层:停止计划" // 调用领域服务停止计划 - err := s.domainPlanService.StopPlan(id) + err := s.domainPlanService.StopPlan(serviceCtx, id) if err != nil { - s.logger.Errorf("%s: 领域服务停止计划失败: %v, ID: %d", actionType, err, id) + logger.Errorf("%s: 领域服务停止计划失败: %v, ID: %d", actionType, err, id) return err // 直接返回领域层错误 } - s.logger.Infof("%s: 计划已成功停止, ID: %d", actionType, id) + logger.Infof("%s: 计划已成功停止, ID: %d", actionType, id) return nil } diff --git a/internal/app/service/user_service.go b/internal/app/service/user_service.go index 49de862..f73d63e 100644 --- a/internal/app/service/user_service.go +++ b/internal/app/service/user_service.go @@ -1,6 +1,7 @@ package service import ( + "context" "errors" "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/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" + "gorm.io/gorm" ) // UserService 定义用户服务接口 type UserService interface { - CreateUser(req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) - Login(req *dto.LoginRequest) (*dto.LoginResponse, error) - SendTestNotification(userID uint, req *dto.SendTestNotificationRequest) error + CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) + Login(ctx context.Context, req *dto.LoginRequest) (*dto.LoginResponse, error) + SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error } // userService 实现了 UserService 接口 type userService struct { + ctx context.Context userRepo repository.UserRepository tokenService token.Service notifyService domain_notify.Service - logger *logs.Logger } // NewUserService 创建并返回一个新的 UserService 实例 func NewUserService( + ctx context.Context, userRepo repository.UserRepository, tokenService token.Service, notifyService domain_notify.Service, - logger *logs.Logger, ) UserService { return &userService{ + ctx: ctx, userRepo: userRepo, tokenService: tokenService, notifyService: notifyService, - logger: logger, } } // 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{ Username: req.Username, Password: req.Password, // 密码会在 BeforeSave 钩子中哈希 } - if err := s.userRepo.Create(user); err != nil { - s.logger.Errorf("创建用户: 创建用户失败: %v", err) + if err := s.userRepo.Create(serviceCtx, user); err != nil { + logger.Errorf("创建用户: 创建用户失败: %v", err) // 尝试查询用户,以判断是否是用户名重复导致的错误 - _, findErr := s.userRepo.FindByUsername(req.Username) + _, findErr := s.userRepo.FindByUsername(serviceCtx, req.Username) if findErr == nil { // 如果能找到用户,说明是用户名重复 return nil, errors.New("用户名已存在") } @@ -69,14 +72,15 @@ func (s *userService) CreateUser(req *dto.CreateUserRequest) (*dto.CreateUserRes } // 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 errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("登录凭证不正确") } - s.logger.Errorf("登录: 查询用户失败: %v", err) + logger.Errorf("登录: 查询用户失败: %v", err) return nil, errors.New("登录失败") } @@ -87,7 +91,7 @@ func (s *userService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) { // 登录成功,生成 JWT token tokenString, err := s.tokenService.GenerateToken(user.ID) if err != nil { - s.logger.Errorf("登录: 生成令牌失败: %v", err) + logger.Errorf("登录: 生成令牌失败: %v", err) return nil, errors.New("登录失败,无法生成认证信息") } @@ -99,12 +103,13 @@ func (s *userService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) { } // SendTestNotification 发送测试通知 -func (s *userService) SendTestNotification(userID uint, req *dto.SendTestNotificationRequest) error { - err := s.notifyService.SendTestMessage(userID, req.Type) +func (s *userService) SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error { + serviceCtx, logger := logs.Trace(ctx, s.ctx, "SendTestNotification") + err := s.notifyService.SendTestMessage(serviceCtx, userID, req.Type) if err != nil { - s.logger.Errorf("发送测试通知: 服务层调用失败: %v", err) + logger.Errorf("发送测试通知: 服务层调用失败: %v", err) return errors.New("发送测试消息失败: " + err.Error()) } - s.logger.Infof("发送测试通知: 成功为用户 %d 发送类型为 %s 的测试消息", userID, req.Type) + logger.Infof("发送测试通知: 成功为用户 %d 发送类型为 %s 的测试消息", userID, req.Type) return nil } diff --git a/internal/core/component_initializers.go b/internal/core/component_initializers.go index 49d4729..95e9967 100644 --- a/internal/core/component_initializers.go +++ b/internal/core/component_initializers.go @@ -7,7 +7,6 @@ import ( "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/domain/audit" "git.huangwc.com/pig/pig-farm-controller/internal/domain/device" domain_notify "git.huangwc.com/pig/pig-farm-controller/internal/domain/notify" "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 { baseCtx := context.Background() return &Repositories{ - userRepo: repository.NewGormUserRepository(db, logs.AddCompName(baseCtx, "UserRepo")), - deviceRepo: repository.NewGormDeviceRepository(db, logs.AddCompName(baseCtx, "DeviceRepo")), - areaControllerRepo: repository.NewGormAreaControllerRepository(db, logs.AddCompName(baseCtx, "AreaControllerRepo")), - deviceTemplateRepo: repository.NewGormDeviceTemplateRepository(db, logs.AddCompName(baseCtx, "DeviceTemplateRepo")), - planRepo: repository.NewGormPlanRepository(db, logs.AddCompName(baseCtx, "PlanRepo")), - pendingTaskRepo: repository.NewGormPendingTaskRepository(db, logs.AddCompName(baseCtx, "PendingTaskRepo")), - executionLogRepo: repository.NewGormExecutionLogRepository(db, logs.AddCompName(baseCtx, "ExecutionLogRepo")), - sensorDataRepo: repository.NewGormSensorDataRepository(db, logs.AddCompName(baseCtx, "SensorDataRepo")), - deviceCommandLogRepo: repository.NewGormDeviceCommandLogRepository(db, logs.AddCompName(baseCtx, "DeviceCommandLogRepo")), - pendingCollectionRepo: repository.NewGormPendingCollectionRepository(db, logs.AddCompName(baseCtx, "PendingCollectionRepo")), - userActionLogRepo: repository.NewGormUserActionLogRepository(db, logs.AddCompName(baseCtx, "UserActionLogRepo")), - pigBatchRepo: repository.NewGormPigBatchRepository(db, logs.AddCompName(baseCtx, "PigBatchRepo")), - pigBatchLogRepo: repository.NewGormPigBatchLogRepository(db, logs.AddCompName(baseCtx, "PigBatchLogRepo")), - pigFarmRepo: repository.NewGormPigFarmRepository(db, logs.AddCompName(baseCtx, "PigFarmRepo")), - pigPenRepo: repository.NewGormPigPenRepository(db, logs.AddCompName(baseCtx, "PigPenRepo")), - pigTransferLogRepo: repository.NewGormPigTransferLogRepository(db, logs.AddCompName(baseCtx, "PigTransferLogRepo")), - pigTradeRepo: repository.NewGormPigTradeRepository(db, logs.AddCompName(baseCtx, "PigTradeRepo")), - pigSickPigLogRepo: repository.NewGormPigSickLogRepository(db, logs.AddCompName(baseCtx, "PigSickPigLogRepo")), - medicationLogRepo: repository.NewGormMedicationLogRepository(db, logs.AddCompName(baseCtx, "MedicationLogRepo")), - rawMaterialRepo: repository.NewGormRawMaterialRepository(db, logs.AddCompName(baseCtx, "RawMaterialRepo")), - notificationRepo: repository.NewGormNotificationRepository(db, logs.AddCompName(baseCtx, "NotificationRepo")), - unitOfWork: repository.NewGormUnitOfWork(db, logs.AddCompName(baseCtx, "UnitOfWork")), + userRepo: repository.NewGormUserRepository(logs.AddCompName(baseCtx, "UserRepo"), db), + deviceRepo: repository.NewGormDeviceRepository(logs.AddCompName(baseCtx, "DeviceRepo"), db), + areaControllerRepo: repository.NewGormAreaControllerRepository(logs.AddCompName(baseCtx, "AreaControllerRepo"), db), + deviceTemplateRepo: repository.NewGormDeviceTemplateRepository(logs.AddCompName(baseCtx, "DeviceTemplateRepo"), db), + planRepo: repository.NewGormPlanRepository(logs.AddCompName(baseCtx, "PlanRepo"), db), + pendingTaskRepo: repository.NewGormPendingTaskRepository(logs.AddCompName(baseCtx, "PendingTaskRepo"), db), + executionLogRepo: repository.NewGormExecutionLogRepository(logs.AddCompName(baseCtx, "ExecutionLogRepo"), db), + sensorDataRepo: repository.NewGormSensorDataRepository(logs.AddCompName(baseCtx, "SensorDataRepo"), db), + deviceCommandLogRepo: repository.NewGormDeviceCommandLogRepository(logs.AddCompName(baseCtx, "DeviceCommandLogRepo"), db), + pendingCollectionRepo: repository.NewGormPendingCollectionRepository(logs.AddCompName(baseCtx, "PendingCollectionRepo"), db), + userActionLogRepo: repository.NewGormUserActionLogRepository(logs.AddCompName(baseCtx, "UserActionLogRepo"), db), + pigBatchRepo: repository.NewGormPigBatchRepository(logs.AddCompName(baseCtx, "PigBatchRepo"), db), + pigBatchLogRepo: repository.NewGormPigBatchLogRepository(logs.AddCompName(baseCtx, "PigBatchLogRepo"), db), + pigFarmRepo: repository.NewGormPigFarmRepository(logs.AddCompName(baseCtx, "PigFarmRepo"), db), + pigPenRepo: repository.NewGormPigPenRepository(logs.AddCompName(baseCtx, "PigPenRepo"), db), + pigTransferLogRepo: repository.NewGormPigTransferLogRepository(logs.AddCompName(baseCtx, "PigTransferLogRepo"), db), + pigTradeRepo: repository.NewGormPigTradeRepository(logs.AddCompName(baseCtx, "PigTradeRepo"), db), + pigSickPigLogRepo: repository.NewGormPigSickLogRepository(logs.AddCompName(baseCtx, "PigSickPigLogRepo"), db), + medicationLogRepo: repository.NewGormMedicationLogRepository(logs.AddCompName(baseCtx, "MedicationLogRepo"), db), + rawMaterialRepo: repository.NewGormRawMaterialRepository(logs.AddCompName(baseCtx, "RawMaterialRepo"), db), + notificationRepo: repository.NewGormNotificationRepository(logs.AddCompName(baseCtx, "NotificationRepo"), db), + unitOfWork: repository.NewGormUnitOfWork(logs.AddCompName(baseCtx, "UnitOfWork"), db), } } @@ -134,22 +133,21 @@ type DomainServices struct { // initDomainServices 初始化所有的领域服务。 func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastructure) *DomainServices { - logger := logs.GetLogger(ctx) baseCtx := context.Background() // 猪群管理相关 - pigPenTransferManager := pig.NewPigPenTransferManager(infra.repos.pigPenRepo, infra.repos.pigTransferLogRepo, infra.repos.pigBatchRepo) - pigTradeManager := pig.NewPigTradeManager(infra.repos.pigTradeRepo) - pigSickManager := pig.NewSickPigManager(infra.repos.pigSickPigLogRepo, infra.repos.medicationLogRepo) - pigBatchDomain := pig.NewPigBatchService(infra.repos.pigBatchRepo, infra.repos.pigBatchLogRepo, infra.repos.unitOfWork, + pigPenTransferManager := pig.NewPigPenTransferManager(logs.AddCompName(baseCtx, "PigPenTransferManager"), infra.repos.pigPenRepo, infra.repos.pigTransferLogRepo, infra.repos.pigBatchRepo) + pigTradeManager := pig.NewPigTradeManager(logs.AddCompName(baseCtx, "PigTradeManager"), infra.repos.pigTradeRepo) + pigSickManager := pig.NewSickPigManager(logs.AddCompName(baseCtx, "PigSickManager"), infra.repos.pigSickPigLogRepo, infra.repos.medicationLogRepo) + pigBatchDomain := pig.NewPigBatchService(logs.AddCompName(baseCtx, "PigBatchDomain")), infra.repos.pigBatchRepo, infra.repos.pigBatchLogRepo, infra.repos.unitOfWork, pigPenTransferManager, pigTradeManager, pigSickManager) // 通用设备服务 generalDeviceService := device.NewGeneralDeviceService( + logs.AddCompName(baseCtx, "GeneralDeviceService"), infra.repos.deviceRepo, infra.repos.deviceCommandLogRepo, infra.repos.pendingCollectionRepo, - logs.AddCompName(baseCtx, "GeneralDeviceService"), 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) // 计划任务管理器 - 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( + logs.AddCompName(baseCtx, "PlanExecutionManager"), infra.repos.pendingTaskRepo, infra.repos.executionLogRepo, infra.repos.deviceRepo, @@ -168,7 +167,6 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr infra.repos.planRepo, analysisPlanTaskManager, taskFactory, - logs.AddCompName(baseCtx, "PlanExecutionManager"), generalDeviceService, time.Duration(cfg.Task.Interval)*time.Second, cfg.Task.NumWorkers, @@ -176,13 +174,14 @@ func initDomainServices(ctx context.Context, cfg *config.Config, infra *Infrastr // 计划管理器 planService := plan.NewPlanService( + logs.AddCompName(baseCtx, "PlanService"), planExecutionManager, analysisPlanTaskManager, infra.repos.planRepo, infra.repos.deviceRepo, infra.repos.unitOfWork, taskFactory, - logs.AddCompName(baseCtx, "PlanService")) + ) return &DomainServices{ pigPenTransferManager: pigPenTransferManager, @@ -205,15 +204,16 @@ type AppServices struct { deviceService service.DeviceService planService service.PlanService userService service.UserService - auditService audit.Service + auditService service.AuditService } // initAppServices 初始化所有的应用服务。 func initAppServices(ctx context.Context, infra *Infrastructure, domainServices *DomainServices) *AppServices { baseCtx := context.Background() - pigFarmService := service.NewPigFarmService(infra.repos.pigFarmRepo, infra.repos.pigPenRepo, infra.repos.pigBatchRepo, domainServices.pigBatchDomain, infra.repos.unitOfWork, logs.AddCompName(baseCtx, "PigFarmService")) - pigBatchService := service.NewPigBatchService(domainServices.pigBatchDomain, logs.AddCompName(baseCtx, "PigBatchService")) + pigFarmService := service.NewPigFarmService(logs.AddCompName(baseCtx, "PigFarmService"), infra.repos.pigFarmRepo, infra.repos.pigPenRepo, infra.repos.pigBatchRepo, domainServices.pigBatchDomain, infra.repos.unitOfWork) + pigBatchService := service.NewPigBatchService(logs.AddCompName(baseCtx, "PigBatchService"), domainServices.pigBatchDomain) monitorService := service.NewMonitorService( + logs.AddCompName(baseCtx, "MonitorService"), infra.repos.sensorDataRepo, infra.repos.deviceCommandLogRepo, infra.repos.executionLogRepo, @@ -230,14 +230,15 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices infra.repos.notificationRepo, ) deviceService := service.NewDeviceService( + logs.AddCompName(baseCtx, "DeviceService"), infra.repos.deviceRepo, infra.repos.areaControllerRepo, infra.repos.deviceTemplateRepo, 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) - 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{ 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) }