package container import ( "context" "time" "go.uber.org/fx" "go.uber.org/zap" "gorm.io/gorm" "tyapi-server/internal/application/admin" "tyapi-server/internal/application/certification" "tyapi-server/internal/application/finance" "tyapi-server/internal/application/product" "tyapi-server/internal/application/user" "tyapi-server/internal/config" domain_admin_repo "tyapi-server/internal/domains/admin/repositories" admin_service "tyapi-server/internal/domains/admin/services" domain_certification_repo "tyapi-server/internal/domains/certification/repositories" certification_service "tyapi-server/internal/domains/certification/services" domain_finance_repo "tyapi-server/internal/domains/finance/repositories" finance_service "tyapi-server/internal/domains/finance/services" domain_product_repo "tyapi-server/internal/domains/product/repositories" product_service "tyapi-server/internal/domains/product/services" domain_user_repo "tyapi-server/internal/domains/user/repositories" user_service "tyapi-server/internal/domains/user/services" "tyapi-server/internal/infrastructure/cache" "tyapi-server/internal/infrastructure/database" admin_repo "tyapi-server/internal/infrastructure/database/repositories/admin" certification_repo "tyapi-server/internal/infrastructure/database/repositories/certification" finance_repo "tyapi-server/internal/infrastructure/database/repositories/finance" product_repo "tyapi-server/internal/infrastructure/database/repositories/product" user_repo "tyapi-server/internal/infrastructure/database/repositories/user" "tyapi-server/internal/infrastructure/external/ocr" "tyapi-server/internal/infrastructure/external/sms" "tyapi-server/internal/infrastructure/external/storage" "tyapi-server/internal/infrastructure/http/handlers" "tyapi-server/internal/infrastructure/http/routes" "tyapi-server/internal/shared/events" "tyapi-server/internal/shared/health" "tyapi-server/internal/shared/hooks" sharedhttp "tyapi-server/internal/shared/http" "tyapi-server/internal/shared/interfaces" "tyapi-server/internal/shared/logger" "tyapi-server/internal/shared/metrics" "tyapi-server/internal/shared/middleware" sharedOCR "tyapi-server/internal/shared/ocr" "tyapi-server/internal/shared/resilience" "tyapi-server/internal/shared/saga" sharedStorage "tyapi-server/internal/shared/storage" "tyapi-server/internal/shared/tracing" "github.com/redis/go-redis/v9" ) // Container 应用容器 type Container struct { App *fx.App } // NewContainer 创建新的应用容器 func NewContainer() *Container { app := fx.New( // 配置模块 fx.Provide( config.LoadConfig, ), // 基础设施模块 fx.Provide( // 日志器 - 提供自定义Logger和*zap.Logger func(cfg *config.Config) (logger.Logger, error) { logCfg := logger.Config{ Level: cfg.Logger.Level, Format: cfg.Logger.Format, Output: cfg.Logger.Output, FilePath: cfg.Logger.FilePath, MaxSize: cfg.Logger.MaxSize, MaxBackups: cfg.Logger.MaxBackups, MaxAge: cfg.Logger.MaxAge, Compress: cfg.Logger.Compress, } return logger.NewLogger(logCfg) }, // 提供普通的*zap.Logger(用于大多数场景) func(log logger.Logger) *zap.Logger { if zapLogger, ok := log.(*logger.ZapLogger); ok { return zapLogger.GetZapLogger() } // 如果类型转换失败,创建一个默认的zap logger defaultLogger, _ := zap.NewProduction() return defaultLogger }, // 数据库连接 func(cfg *config.Config) (*gorm.DB, error) { dbCfg := database.Config{ Host: cfg.Database.Host, Port: cfg.Database.Port, User: cfg.Database.User, Password: cfg.Database.Password, Name: cfg.Database.Name, SSLMode: cfg.Database.SSLMode, Timezone: cfg.Database.Timezone, MaxOpenConns: cfg.Database.MaxOpenConns, MaxIdleConns: cfg.Database.MaxIdleConns, ConnMaxLifetime: cfg.Database.ConnMaxLifetime, } db, err := database.NewConnection(dbCfg) if err != nil { return nil, err } return db.DB, nil }, // Redis客户端 NewRedisClient, // 缓存服务 fx.Annotate(NewRedisCache, fx.As(new(interfaces.CacheService))), // 事件总线 // 提供workerCount参数 func() int { return 5 // 默认5个工作协程 }, events.NewMemoryEventBus, fx.Annotate(events.NewMemoryEventBus, fx.As(new(interfaces.EventBus))), // 健康检查 health.NewHealthChecker, // 提供 config.SMSConfig func(cfg *config.Config) config.SMSConfig { return cfg.SMS }, // 提供 config.AppConfig func(cfg *config.Config) config.AppConfig { return cfg.App }, // 短信服务 sms.NewAliSMSService, // 存储服务 fx.Annotate( func(cfg *config.Config, logger *zap.Logger) *storage.QiNiuStorageService { return storage.NewQiNiuStorageService( cfg.Storage.AccessKey, cfg.Storage.SecretKey, cfg.Storage.Bucket, cfg.Storage.Domain, logger, ) }, fx.As(new(sharedStorage.StorageService)), ), // OCR服务 fx.Annotate( func(cfg *config.Config, logger *zap.Logger) *ocr.BaiduOCRService { return ocr.NewBaiduOCRService( cfg.OCR.APIKey, cfg.OCR.SecretKey, logger, ) }, fx.As(new(sharedOCR.OCRService)), ), ), // 高级特性模块 fx.Provide( // 提供TracerConfig func(cfg *config.Config) tracing.TracerConfig { return tracing.TracerConfig{ ServiceName: cfg.App.Name, ServiceVersion: cfg.App.Version, Environment: cfg.App.Env, Endpoint: cfg.Monitoring.TracingEndpoint, SampleRate: cfg.Monitoring.SampleRate, Enabled: cfg.Monitoring.TracingEnabled, } }, tracing.NewTracer, metrics.NewPrometheusMetrics, metrics.NewBusinessMetrics, resilience.NewWrapper, resilience.NewRetryerWrapper, saga.NewSagaManager, hooks.NewHookSystem, ), // HTTP基础组件 fx.Provide( sharedhttp.NewResponseBuilder, sharedhttp.NewRequestValidatorZh, sharedhttp.NewGinRouter, ), // 中间件组件 fx.Provide( middleware.NewRequestIDMiddleware, middleware.NewSecurityHeadersMiddleware, middleware.NewResponseTimeMiddleware, middleware.NewCORSMiddleware, middleware.NewRateLimitMiddleware, NewRequestLoggerMiddlewareWrapper, middleware.NewJWTAuthMiddleware, middleware.NewOptionalAuthMiddleware, middleware.NewTraceIDMiddleware, middleware.NewErrorTrackingMiddleware, NewRequestBodyLoggerMiddlewareWrapper, ), // 仓储层 - 用户域 fx.Provide( // 用户仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormUserRepository, fx.As(new(domain_user_repo.UserRepository)), ), // 企业信息仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormEnterpriseInfoRepository, fx.As(new(domain_user_repo.EnterpriseInfoRepository)), ), // 短信验证码仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormSMSCodeRepository, fx.As(new(domain_user_repo.SMSCodeRepository)), ), ), // 仓储层 - 管理员域 fx.Provide( // 管理员仓储 - 同时注册具体类型和接口类型 fx.Annotate( admin_repo.NewGormAdminRepository, fx.As(new(domain_admin_repo.AdminRepository)), ), // 管理员登录日志仓储 fx.Annotate( admin_repo.NewGormAdminLoginLogRepository, fx.As(new(domain_admin_repo.AdminLoginLogRepository)), ), // 管理员操作日志仓储 fx.Annotate( admin_repo.NewGormAdminOperationLogRepository, fx.As(new(domain_admin_repo.AdminOperationLogRepository)), ), // 管理员权限仓储 fx.Annotate( admin_repo.NewGormAdminPermissionRepository, fx.As(new(domain_admin_repo.AdminPermissionRepository)), ), ), // 仓储层 - 认证域 fx.Provide( // 认证申请仓储 fx.Annotate( certification_repo.NewGormCertificationRepository, fx.As(new(domain_certification_repo.CertificationRepository)), ), // 人脸识别记录仓储 fx.Annotate( certification_repo.NewGormFaceVerifyRecordRepository, fx.As(new(domain_certification_repo.FaceVerifyRecordRepository)), ), // 合同记录仓储 fx.Annotate( certification_repo.NewGormContractRecordRepository, fx.As(new(domain_certification_repo.ContractRecordRepository)), ), // 营业执照上传记录仓储 fx.Annotate( certification_repo.NewGormLicenseUploadRecordRepository, fx.As(new(domain_certification_repo.LicenseUploadRecordRepository)), ), // 通知记录仓储 fx.Annotate( certification_repo.NewGormNotificationRecordRepository, fx.As(new(domain_certification_repo.NotificationRecordRepository)), ), ), // 仓储层 - 财务域 fx.Provide( // 钱包仓储 fx.Annotate( finance_repo.NewGormWalletRepository, fx.As(new(domain_finance_repo.WalletRepository)), ), // 用户密钥仓储 fx.Annotate( finance_repo.NewGormUserSecretsRepository, fx.As(new(domain_finance_repo.UserSecretsRepository)), ), ), // 仓储层 - 产品域 fx.Provide( // 产品仓储 - 同时注册具体类型和接口类型 fx.Annotate( product_repo.NewGormProductRepository, fx.As(new(domain_product_repo.ProductRepository)), ), // 产品分类仓储 - 同时注册具体类型和接口类型 fx.Annotate( product_repo.NewGormProductCategoryRepository, fx.As(new(domain_product_repo.ProductCategoryRepository)), ), // 订阅仓储 - 同时注册具体类型和接口类型 fx.Annotate( product_repo.NewGormSubscriptionRepository, fx.As(new(domain_product_repo.SubscriptionRepository)), ), ), // 领域服务 fx.Provide( user_service.NewUserService, user_service.NewSMSCodeService, user_service.NewEnterpriseService, admin_service.NewAdminService, certification_service.NewCertificationService, certification_service.NewCertificationStateMachine, finance_service.NewFinanceService, product_service.NewProductService, ), // 应用服务 fx.Provide( // 用户应用服务 - 绑定到接口 fx.Annotate( user.NewUserApplicationService, fx.As(new(user.UserApplicationService)), ), // 管理员应用服务 - 绑定到接口 fx.Annotate( admin.NewAdminApplicationService, fx.As(new(admin.AdminApplicationService)), ), // 认证应用服务 - 绑定到接口 fx.Annotate( certification.NewCertificationApplicationService, fx.As(new(certification.CertificationApplicationService)), ), // 财务应用服务 - 绑定到接口 fx.Annotate( finance.NewFinanceApplicationService, fx.As(new(finance.FinanceApplicationService)), ), // 产品应用服务 - 绑定到接口 fx.Annotate( product.NewProductApplicationService, fx.As(new(product.ProductApplicationService)), ), // 分类应用服务 - 绑定到接口 fx.Annotate( product.NewCategoryApplicationService, fx.As(new(product.CategoryApplicationService)), ), // 订阅应用服务 - 绑定到接口 fx.Annotate( product.NewSubscriptionApplicationService, fx.As(new(product.SubscriptionApplicationService)), ), ), // HTTP处理器 fx.Provide( // 用户HTTP处理器 handlers.NewUserHandler, // 管理员HTTP处理器 handlers.NewAdminHandler, // 认证HTTP处理器 handlers.NewCertificationHandler, // 财务HTTP处理器 handlers.NewFinanceHandler, // 产品HTTP处理器 handlers.NewProductHandler, ), // 路由注册 fx.Provide( // 用户路由 routes.NewUserRoutes, // 管理员路由 routes.NewAdminRoutes, // 认证路由 routes.NewCertificationRoutes, // 财务路由 routes.NewFinanceRoutes, // 产品路由 routes.NewProductRoutes, ), // 应用生命周期 fx.Invoke( RegisterLifecycleHooks, RegisterMiddlewares, RegisterRoutes, ), ) return &Container{App: app} } // Start 启动容器 func (c *Container) Start() error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() return c.App.Start(ctx) } // Stop 停止容器 func (c *Container) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() return c.App.Stop(ctx) } // RegisterLifecycleHooks 注册生命周期钩子 func RegisterLifecycleHooks( lifecycle fx.Lifecycle, logger *zap.Logger, ) { lifecycle.Append(fx.Hook{ OnStart: func(context.Context) error { logger.Info("应用启动中...") return nil }, OnStop: func(context.Context) error { logger.Info("应用关闭中...") return nil }, }) } // RegisterMiddlewares 注册中间件 func RegisterMiddlewares( router *sharedhttp.GinRouter, requestID *middleware.RequestIDMiddleware, security *middleware.SecurityHeadersMiddleware, responseTime *middleware.ResponseTimeMiddleware, cors *middleware.CORSMiddleware, rateLimit *middleware.RateLimitMiddleware, requestLogger *middleware.RequestLoggerMiddleware, traceIDMiddleware *middleware.TraceIDMiddleware, errorTrackingMiddleware *middleware.ErrorTrackingMiddleware, requestBodyLogger *middleware.RequestBodyLoggerMiddleware, ) { router.RegisterMiddleware(requestID) router.RegisterMiddleware(security) router.RegisterMiddleware(responseTime) router.RegisterMiddleware(cors) router.RegisterMiddleware(rateLimit) router.RegisterMiddleware(requestLogger) router.RegisterMiddleware(traceIDMiddleware) router.RegisterMiddleware(errorTrackingMiddleware) router.RegisterMiddleware(requestBodyLogger) } // RegisterRoutes 注册路由 func RegisterRoutes( router *sharedhttp.GinRouter, userRoutes *routes.UserRoutes, adminRoutes *routes.AdminRoutes, certificationRoutes *routes.CertificationRoutes, financeRoutes *routes.FinanceRoutes, productRoutes *routes.ProductRoutes, cfg *config.Config, logger *zap.Logger, ) { router.SetupDefaultRoutes() // 注册所有路由 userRoutes.Register(router) adminRoutes.Register(router) certificationRoutes.Register(router) financeRoutes.Register(router) productRoutes.Register(router) // 打印注册的路由信息 router.PrintRoutes() // 启动HTTP服务器 go func() { addr := ":" + cfg.Server.Port logger.Info("正在启动HTTP服务器", zap.String("addr", addr)) if err := router.Start(addr); err != nil { logger.Error("HTTP服务器启动失败", zap.Error(err)) } }() } // ================ 中间件包装函数 ================ // NewRequestLoggerMiddlewareWrapper 创建请求日志中间件包装器 func NewRequestLoggerMiddlewareWrapper(logger *zap.Logger, cfg *config.Config, tracer *tracing.Tracer) *middleware.RequestLoggerMiddleware { return middleware.NewRequestLoggerMiddleware(logger, cfg.App.IsDevelopment(), tracer) } // NewRequestBodyLoggerMiddlewareWrapper 创建请求体日志中间件包装器 func NewRequestBodyLoggerMiddlewareWrapper(logger *zap.Logger, cfg *config.Config, tracer *tracing.Tracer) *middleware.RequestBodyLoggerMiddleware { return middleware.NewRequestBodyLoggerMiddleware(logger, cfg.App.IsDevelopment(), tracer) } // ================ Redis相关工厂函数 ================ // NewRedisClient 创建Redis客户端 func NewRedisClient(cfg *config.Config, logger *zap.Logger) (*redis.Client, error) { client := redis.NewClient(&redis.Options{ Addr: cfg.Redis.GetRedisAddr(), Password: cfg.Redis.Password, DB: cfg.Redis.DB, PoolSize: cfg.Redis.PoolSize, MinIdleConns: cfg.Redis.MinIdleConns, DialTimeout: cfg.Redis.DialTimeout, ReadTimeout: cfg.Redis.ReadTimeout, WriteTimeout: cfg.Redis.WriteTimeout, }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _, err := client.Ping(ctx).Result() if err != nil { logger.Error("Redis连接失败", zap.Error(err)) return nil, err } logger.Info("Redis连接已建立") return client, nil } // NewRedisCache 创建Redis缓存服务 func NewRedisCache(client *redis.Client, logger *zap.Logger, cfg *config.Config) interfaces.CacheService { return cache.NewRedisCache(client, logger, "app") } // NewTracedRedisCache 创建带追踪的Redis缓存服务 func NewTracedRedisCache(client *redis.Client, tracer *tracing.Tracer, logger *zap.Logger, cfg *config.Config) interfaces.CacheService { return tracing.NewTracedRedisCache(client, tracer, logger, "app") }