修改程序入口
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -34,20 +35,20 @@ type Infrastructure struct {
|
||||
}
|
||||
|
||||
// initInfrastructure 初始化所有基础设施层组件。
|
||||
func initInfrastructure(cfg *config.Config, logger *logs.Logger) (*Infrastructure, error) {
|
||||
storage, err := initStorage(cfg.Database, logger)
|
||||
func initInfrastructure(ctx context.Context, cfg *config.Config) (*Infrastructure, error) {
|
||||
storage, err := initStorage(ctx, cfg.Database)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := initRepositories(storage.GetDB(), logger)
|
||||
repos := initRepositories(ctx, storage.GetDB())
|
||||
|
||||
lora, err := initLora(cfg, logger, repos)
|
||||
lora, err := initLora(ctx, cfg, repos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notifyService, err := initNotifyService(cfg.Notify, logger, repos.userRepo, repos.notificationRepo)
|
||||
notifyService, err := initNotifyService(ctx, cfg.Notify, repos.userRepo, repos.notificationRepo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("初始化通知服务失败: %w", err)
|
||||
}
|
||||
@@ -90,30 +91,31 @@ type Repositories struct {
|
||||
}
|
||||
|
||||
// initRepositories 初始化所有的仓库。
|
||||
func initRepositories(db *gorm.DB, logger *logs.Logger) *Repositories {
|
||||
func initRepositories(ctx context.Context, db *gorm.DB) *Repositories {
|
||||
baseCtx := context.Background()
|
||||
return &Repositories{
|
||||
userRepo: repository.NewGormUserRepository(db),
|
||||
deviceRepo: repository.NewGormDeviceRepository(db),
|
||||
areaControllerRepo: repository.NewGormAreaControllerRepository(db),
|
||||
deviceTemplateRepo: repository.NewGormDeviceTemplateRepository(db),
|
||||
planRepo: repository.NewGormPlanRepository(db),
|
||||
pendingTaskRepo: repository.NewGormPendingTaskRepository(db),
|
||||
executionLogRepo: repository.NewGormExecutionLogRepository(db),
|
||||
sensorDataRepo: repository.NewGormSensorDataRepository(db),
|
||||
deviceCommandLogRepo: repository.NewGormDeviceCommandLogRepository(db),
|
||||
pendingCollectionRepo: repository.NewGormPendingCollectionRepository(db),
|
||||
userActionLogRepo: repository.NewGormUserActionLogRepository(db),
|
||||
pigBatchRepo: repository.NewGormPigBatchRepository(db),
|
||||
pigBatchLogRepo: repository.NewGormPigBatchLogRepository(db),
|
||||
pigFarmRepo: repository.NewGormPigFarmRepository(db),
|
||||
pigPenRepo: repository.NewGormPigPenRepository(db),
|
||||
pigTransferLogRepo: repository.NewGormPigTransferLogRepository(db),
|
||||
pigTradeRepo: repository.NewGormPigTradeRepository(db),
|
||||
pigSickPigLogRepo: repository.NewGormPigSickLogRepository(db),
|
||||
medicationLogRepo: repository.NewGormMedicationLogRepository(db),
|
||||
rawMaterialRepo: repository.NewGormRawMaterialRepository(db),
|
||||
notificationRepo: repository.NewGormNotificationRepository(db),
|
||||
unitOfWork: repository.NewGormUnitOfWork(db, logger),
|
||||
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")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +133,10 @@ type DomainServices struct {
|
||||
}
|
||||
|
||||
// initDomainServices 初始化所有的领域服务。
|
||||
func initDomainServices(cfg *config.Config, infra *Infrastructure, logger *logs.Logger) *DomainServices {
|
||||
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)
|
||||
@@ -144,15 +149,15 @@ func initDomainServices(cfg *config.Config, infra *Infrastructure, logger *logs.
|
||||
infra.repos.deviceRepo,
|
||||
infra.repos.deviceCommandLogRepo,
|
||||
infra.repos.pendingCollectionRepo,
|
||||
logger,
|
||||
logs.AddCompName(baseCtx, "GeneralDeviceService"),
|
||||
infra.lora.comm,
|
||||
)
|
||||
|
||||
// 任务工厂
|
||||
taskFactory := task.NewTaskFactory(logger, infra.repos.sensorDataRepo, infra.repos.deviceRepo, generalDeviceService)
|
||||
taskFactory := task.NewTaskFactory(logs.AddCompName(baseCtx, "TaskFactory"), infra.repos.sensorDataRepo, infra.repos.deviceRepo, generalDeviceService)
|
||||
|
||||
// 计划任务管理器
|
||||
analysisPlanTaskManager := plan.NewAnalysisPlanTaskManager(infra.repos.planRepo, infra.repos.pendingTaskRepo, infra.repos.executionLogRepo, logger)
|
||||
analysisPlanTaskManager := plan.NewAnalysisPlanTaskManager(infra.repos.planRepo, infra.repos.pendingTaskRepo, infra.repos.executionLogRepo, logs.AddCompName(baseCtx, "AnalysisPlanTaskManager"))
|
||||
|
||||
// 任务执行器
|
||||
planExecutionManager := plan.NewPlanExecutionManager(
|
||||
@@ -163,7 +168,7 @@ func initDomainServices(cfg *config.Config, infra *Infrastructure, logger *logs.
|
||||
infra.repos.planRepo,
|
||||
analysisPlanTaskManager,
|
||||
taskFactory,
|
||||
logger,
|
||||
logs.AddCompName(baseCtx, "PlanExecutionManager"),
|
||||
generalDeviceService,
|
||||
time.Duration(cfg.Task.Interval)*time.Second,
|
||||
cfg.Task.NumWorkers,
|
||||
@@ -177,7 +182,7 @@ func initDomainServices(cfg *config.Config, infra *Infrastructure, logger *logs.
|
||||
infra.repos.deviceRepo,
|
||||
infra.repos.unitOfWork,
|
||||
taskFactory,
|
||||
logger)
|
||||
logs.AddCompName(baseCtx, "PlanService"))
|
||||
|
||||
return &DomainServices{
|
||||
pigPenTransferManager: pigPenTransferManager,
|
||||
@@ -204,9 +209,10 @@ type AppServices struct {
|
||||
}
|
||||
|
||||
// initAppServices 初始化所有的应用服务。
|
||||
func initAppServices(infra *Infrastructure, domainServices *DomainServices, logger *logs.Logger) *AppServices {
|
||||
pigFarmService := service.NewPigFarmService(infra.repos.pigFarmRepo, infra.repos.pigPenRepo, infra.repos.pigBatchRepo, domainServices.pigBatchDomain, infra.repos.unitOfWork, logger)
|
||||
pigBatchService := service.NewPigBatchService(domainServices.pigBatchDomain, logger)
|
||||
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"))
|
||||
monitorService := service.NewMonitorService(
|
||||
infra.repos.sensorDataRepo,
|
||||
infra.repos.deviceCommandLogRepo,
|
||||
@@ -229,9 +235,9 @@ func initAppServices(infra *Infrastructure, domainServices *DomainServices, logg
|
||||
infra.repos.deviceTemplateRepo,
|
||||
domainServices.generalDeviceService,
|
||||
)
|
||||
auditService := audit.NewService(infra.repos.userActionLogRepo, logger)
|
||||
planService := service.NewPlanService(logger, domainServices.planService)
|
||||
userService := service.NewUserService(infra.repos.userRepo, infra.tokenService, infra.notifyService, logger)
|
||||
auditService := audit.NewService(infra.repos.userActionLogRepo, logs.AddCompName(baseCtx, "AuditService"))
|
||||
planService := service.NewPlanService(logs.AddCompName(baseCtx, "AppPlanService"), domainServices.planService)
|
||||
userService := service.NewUserService(infra.repos.userRepo, infra.tokenService, infra.notifyService, logs.AddCompName(baseCtx, "UserService"))
|
||||
|
||||
return &AppServices{
|
||||
pigFarmService: pigFarmService,
|
||||
@@ -253,23 +259,25 @@ type LoraComponents struct {
|
||||
|
||||
// initLora 根据配置初始化 LoRa 相关组件。
|
||||
func initLora(
|
||||
ctx context.Context,
|
||||
cfg *config.Config,
|
||||
logger *logs.Logger,
|
||||
repos *Repositories,
|
||||
) (*LoraComponents, error) {
|
||||
var listenHandler webhook.ListenHandler
|
||||
var comm transport.Communicator
|
||||
var loraListener transport.Listener
|
||||
baseCtx := context.Background()
|
||||
|
||||
logger := logs.GetLogger(ctx)
|
||||
if cfg.Lora.Mode == config.LoraMode_LoRaWAN {
|
||||
logger.Info("当前运行模式: lora_wan。初始化 ChirpStack 监听器和传输层。")
|
||||
listenHandler = webhook.NewChirpStackListener(logger, repos.sensorDataRepo, repos.deviceRepo, repos.areaControllerRepo, repos.deviceCommandLogRepo, repos.pendingCollectionRepo)
|
||||
comm = lora.NewChirpStackTransport(cfg.ChirpStack, logger)
|
||||
loraListener = lora.NewPlaceholderTransport(logger)
|
||||
listenHandler = webhook.NewChirpStackListener(logs.AddCompName(baseCtx, "ChirpStackListener"), repos.sensorDataRepo, repos.deviceRepo, repos.areaControllerRepo, repos.deviceCommandLogRepo, repos.pendingCollectionRepo)
|
||||
comm = lora.NewChirpStackTransport(cfg.ChirpStack, logs.AddCompName(baseCtx, "ChirpStackTransport"))
|
||||
loraListener = lora.NewPlaceholderTransport(logs.AddCompName(baseCtx, "PlaceholderTransport"))
|
||||
} else {
|
||||
logger.Info("当前运行模式: lora_mesh。初始化 LoRa Mesh 传输层和占位符监听器。")
|
||||
listenHandler = webhook.NewPlaceholderListener(logger)
|
||||
tp, err := lora.NewLoRaMeshUartPassthroughTransport(cfg.LoraMesh, logger, repos.areaControllerRepo, repos.pendingCollectionRepo, repos.deviceRepo, repos.sensorDataRepo)
|
||||
listenHandler = webhook.NewPlaceholderListener(logs.AddCompName(baseCtx, "PlaceholderListener"))
|
||||
tp, err := lora.NewLoRaMeshUartPassthroughTransport(cfg.LoraMesh, logs.AddCompName(baseCtx, "LoRaMeshTransport"), repos.areaControllerRepo, repos.pendingCollectionRepo, repos.deviceRepo, repos.sensorDataRepo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无法初始化 LoRa Mesh 模块: %w", err)
|
||||
}
|
||||
@@ -287,17 +295,19 @@ func initLora(
|
||||
// initNotifyService 根据配置初始化并返回一个通知领域服务。
|
||||
// 它确保至少有一个 LogNotifier 总是可用,并根据配置启用其他通知器。
|
||||
func initNotifyService(
|
||||
ctx context.Context,
|
||||
cfg config.NotifyConfig,
|
||||
log *logs.Logger,
|
||||
userRepo repository.UserRepository,
|
||||
notificationRepo repository.NotificationRepository,
|
||||
) (domain_notify.Service, error) {
|
||||
var availableNotifiers []notify.Notifier
|
||||
logger := logs.GetLogger(ctx)
|
||||
baseCtx := context.Background()
|
||||
|
||||
// 1. 总是创建 LogNotifier 作为所有告警的最终记录渠道
|
||||
logNotifier := notify.NewLogNotifier(log)
|
||||
logNotifier := notify.NewLogNotifier(logs.AddCompName(baseCtx, "LogNotifier"))
|
||||
availableNotifiers = append(availableNotifiers, logNotifier)
|
||||
log.Info("Log通知器已启用 (作为所有告警的最终记录渠道)")
|
||||
logger.Info("Log通知器已启用 (作为所有告警的最终记录渠道)")
|
||||
|
||||
// 2. 根据配置,按需创建并收集所有启用的其他 Notifier 实例
|
||||
if cfg.SMTP.Enabled {
|
||||
@@ -309,7 +319,7 @@ func initNotifyService(
|
||||
cfg.SMTP.Sender,
|
||||
)
|
||||
availableNotifiers = append(availableNotifiers, smtpNotifier)
|
||||
log.Info("SMTP通知器已启用")
|
||||
logger.Info("SMTP通知器已启用")
|
||||
}
|
||||
|
||||
if cfg.WeChat.Enabled {
|
||||
@@ -319,7 +329,7 @@ func initNotifyService(
|
||||
cfg.WeChat.Secret,
|
||||
)
|
||||
availableNotifiers = append(availableNotifiers, wechatNotifier)
|
||||
log.Info("企业微信通知器已启用")
|
||||
logger.Info("企业微信通知器已启用")
|
||||
}
|
||||
|
||||
if cfg.Lark.Enabled {
|
||||
@@ -328,7 +338,7 @@ func initNotifyService(
|
||||
cfg.Lark.AppSecret,
|
||||
)
|
||||
availableNotifiers = append(availableNotifiers, larkNotifier)
|
||||
log.Info("飞书通知器已启用")
|
||||
logger.Info("飞书通知器已启用")
|
||||
}
|
||||
|
||||
// 3. 动态确定首选通知器
|
||||
@@ -346,12 +356,12 @@ func initNotifyService(
|
||||
// 如果用户指定的主渠道未启用或未指定,则自动选择第一个可用的 (这将是 LogNotifier,如果其他都未启用)
|
||||
if primaryNotifier == nil {
|
||||
primaryNotifier = availableNotifiers[0] // 确保总能找到一个,因为 LogNotifier 总是存在的
|
||||
log.Warnf("配置的首选渠道 '%s' 未启用或未指定,已自动降级使用 '%s' 作为首选渠道。", cfg.Primary, primaryNotifier.Type())
|
||||
logger.Warnf("配置的首选渠道 '%s' 未启用或未指定,已自动降级使用 '%s' 作为首选渠道。", cfg.Primary, primaryNotifier.Type())
|
||||
}
|
||||
|
||||
// 4. 使用创建的 Notifier 列表和 notificationRepo 来组装领域服务
|
||||
notifyService, err := domain_notify.NewFailoverService(
|
||||
log,
|
||||
logs.AddCompName(baseCtx, "FailoverNotifyService"),
|
||||
userRepo,
|
||||
availableNotifiers,
|
||||
primaryNotifier.Type(),
|
||||
@@ -362,14 +372,14 @@ func initNotifyService(
|
||||
return nil, fmt.Errorf("创建故障转移通知服务失败: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("通知服务初始化成功,首选渠道: %s, 故障阈值: %d", primaryNotifier.Type(), cfg.FailureThreshold)
|
||||
logger.Infof("通知服务初始化成功,首选渠道: %s, 故障阈值: %d", primaryNotifier.Type(), cfg.FailureThreshold)
|
||||
return notifyService, nil
|
||||
}
|
||||
|
||||
// initStorage 封装了数据库的初始化、连接和迁移逻辑。
|
||||
func initStorage(cfg config.DatabaseConfig, logger *logs.Logger) (database.Storage, error) {
|
||||
func initStorage(ctx context.Context, cfg config.DatabaseConfig) (database.Storage, error) {
|
||||
// 创建存储实例
|
||||
storage := database.NewStorage(cfg, logger)
|
||||
storage := database.NewStorage(cfg, logs.AddCompName(context.Background(), "Storage"))
|
||||
if err := storage.Connect(); err != nil {
|
||||
// 错误已在 Connect 内部被记录,这里只需包装并返回
|
||||
return nil, fmt.Errorf("数据库连接失败: %w", err)
|
||||
@@ -380,6 +390,6 @@ func initStorage(cfg config.DatabaseConfig, logger *logs.Logger) (database.Stora
|
||||
return nil, fmt.Errorf("数据库迁移失败: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("数据库初始化完成。")
|
||||
logs.GetLogger(ctx).Info("数据库初始化完成。")
|
||||
return storage, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user