package container import ( "context" "time" "go.uber.org/fx" "go.uber.org/zap" "gorm.io/gorm" "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_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" user_service "tyapi-server/internal/domains/user/services" "tyapi-server/internal/infrastructure/cache" "tyapi-server/internal/infrastructure/database" 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" "tyapi-server/internal/infrastructure/external/ocr" "tyapi-server/internal/infrastructure/external/sms" "tyapi-server/internal/infrastructure/external/storage" "tyapi-server/internal/infrastructure/external/westdex" "tyapi-server/internal/infrastructure/external/yushan" "tyapi-server/internal/infrastructure/http/handlers" "tyapi-server/internal/infrastructure/http/routes" shared_database "tyapi-server/internal/shared/database" "tyapi-server/internal/shared/esign" "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/payment" "tyapi-server/internal/shared/resilience" "tyapi-server/internal/shared/saga" "tyapi-server/internal/shared/tracing" "tyapi-server/internal/shared/validator" domain_user_repo "tyapi-server/internal/domains/user/repositories" user_repo "tyapi-server/internal/infrastructure/database/repositories/user" "github.com/redis/go-redis/v9" api_app "tyapi-server/internal/application/api" domain_api_repo "tyapi-server/internal/domains/api/repositories" api_service "tyapi-server/internal/domains/api/services" api_repo "tyapi-server/internal/infrastructure/database/repositories/api" ) // 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, cacheService interfaces.CacheService, logger *zap.Logger) (*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 } // 设置GORM缓存插件 if err := SetupGormCache(db.DB, cacheService, cfg, logger); err != nil { logger.Warn("GORM缓存插件设置失败", zap.Error(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 }, // 事务管理器 func(db *gorm.DB, logger *zap.Logger) *shared_database.TransactionManager { return shared_database.NewTransactionManager(db, logger) }, // 短信服务 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, ) }, ), // 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)), ), // e签宝配置 func(cfg *config.Config) (*esign.Config, error) { return esign.NewConfig( cfg.Esign.AppID, cfg.Esign.AppSecret, cfg.Esign.ServerURL, cfg.Esign.TemplateID, &esign.EsignContractConfig{ Name: cfg.Esign.Contract.Name, ExpireDays: cfg.Esign.Contract.ExpireDays, RetryCount: cfg.Esign.Contract.RetryCount, }, &esign.EsignAuthConfig{ OrgAuthModes: cfg.Esign.Auth.OrgAuthModes, DefaultAuthMode: cfg.Esign.Auth.DefaultAuthMode, PsnAuthModes: cfg.Esign.Auth.PsnAuthModes, WillingnessAuthModes: cfg.Esign.Auth.WillingnessAuthModes, RedirectUrl: cfg.Esign.Auth.RedirectURL, }, &esign.EsignSignConfig{ AutoFinish: cfg.Esign.Sign.AutoFinish, SignFieldStyle: cfg.Esign.Sign.SignFieldStyle, ClientType: cfg.Esign.Sign.ClientType, RedirectUrl: cfg.Esign.Sign.RedirectURL, }, ) }, // e签宝服务 func(esignConfig *esign.Config) *esign.Client { return esign.NewClient(esignConfig) }, // 支付宝支付服务 func(cfg *config.Config) *payment.AliPayService { config := payment.AlipayConfig{ AppID: cfg.AliPay.AppID, PrivateKey: cfg.AliPay.PrivateKey, AlipayPublicKey: cfg.AliPay.AlipayPublicKey, IsProduction: cfg.AliPay.IsProduction, NotifyUrl: cfg.AliPay.NotifyURL, ReturnURL: cfg.AliPay.ReturnURL, } return payment.NewAliPayService(config) }, ), // 高级特性模块 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, validator.NewRequestValidator, // WestDexService - 需要从配置中获取参数 func(cfg *config.Config) *westdex.WestDexService { return westdex.NewWestDexService( cfg.WestDex.URL, cfg.WestDex.Key, cfg.WestDex.SecretId, cfg.WestDex.SecretSecondId, ) }, func(cfg *config.Config) *yushan.YushanService { return yushan.NewYushanService( cfg.Yushan.URL, cfg.Yushan.APIKey, cfg.Yushan.AcctID, ) }, sharedhttp.NewGinRouter, ), // 中间件组件 fx.Provide( middleware.NewRequestIDMiddleware, middleware.NewSecurityHeadersMiddleware, middleware.NewResponseTimeMiddleware, middleware.NewCORSMiddleware, middleware.NewRateLimitMiddleware, NewRequestLoggerMiddlewareWrapper, middleware.NewJWTAuthMiddleware, middleware.NewOptionalAuthMiddleware, middleware.NewAdminAuthMiddleware, middleware.NewDomainAuthMiddleware, middleware.NewTraceIDMiddleware, middleware.NewErrorTrackingMiddleware, NewRequestBodyLoggerMiddlewareWrapper, ), // 仓储层 - 用户域 fx.Provide( // 用户仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormUserRepository, fx.As(new(domain_user_repo.UserRepository)), ), // 短信验证码仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormSMSCodeRepository, fx.As(new(domain_user_repo.SMSCodeRepository)), ), // 用户信息仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormEnterpriseInfoRepository, fx.As(new(domain_user_repo.EnterpriseInfoRepository)), ), // 合同信息仓储 - 同时注册具体类型和接口类型 fx.Annotate( user_repo.NewGormContractInfoRepository, fx.As(new(domain_user_repo.ContractInfoRepository)), ), ), // 仓储层 - 认证域 fx.Provide( // 认证命令仓储 fx.Annotate( certification_repo.NewGormCertificationCommandRepository, fx.As(new(domain_certification_repo.CertificationCommandRepository)), ), // 认证查询仓储 fx.Annotate( certification_repo.NewGormCertificationQueryRepository, fx.As(new(domain_certification_repo.CertificationQueryRepository)), ), // 企业信息提交记录仓储 fx.Annotate( certification_repo.NewGormEnterpriseInfoSubmitRecordRepository, fx.As(new(domain_certification_repo.EnterpriseInfoSubmitRecordRepository)), ), ), // 仓储层 - 财务域 fx.Provide( // 钱包仓储 fx.Annotate( finance_repo.NewGormWalletRepository, fx.As(new(domain_finance_repo.WalletRepository)), ), // 钱包交易记录仓储 fx.Annotate( finance_repo.NewGormWalletTransactionRepository, fx.As(new(domain_finance_repo.WalletTransactionRepository)), ), // 充值记录仓储 fx.Annotate( finance_repo.NewGormRechargeRecordRepository, fx.As(new(domain_finance_repo.RechargeRecordRepository)), ), // 支付宝订单仓储 fx.Annotate( finance_repo.NewGormAlipayOrderRepository, fx.As(new(domain_finance_repo.AlipayOrderRepository)), ), ), // 仓储层 - 产品域 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)), ), // 产品API配置仓储 - 同时注册具体类型和接口类型 fx.Annotate( product_repo.NewGormProductApiConfigRepository, fx.As(new(domain_product_repo.ProductApiConfigRepository)), ), ), // API域仓储层 fx.Provide( fx.Annotate( api_repo.NewGormApiUserRepository, fx.As(new(domain_api_repo.ApiUserRepository)), ), fx.Annotate( api_repo.NewGormApiCallRepository, fx.As(new(domain_api_repo.ApiCallRepository)), ), ), // 领域服务 fx.Provide( user_service.NewUserAggregateService, user_service.NewUserAuthService, user_service.NewSMSCodeService, user_service.NewContractAggregateService, product_service.NewProductManagementService, product_service.NewProductSubscriptionService, product_service.NewProductApiConfigService, finance_service.NewWalletAggregateService, finance_service.NewRechargeRecordService, certification_service.NewCertificationAggregateService, certification_service.NewEnterpriseInfoSubmitRecordService, ), // API域服务层 fx.Provide( api_service.NewApiUserAggregateService, api_service.NewApiCallAggregateService, api_service.NewApiRequestService, ), // API域应用服务 fx.Provide( api_app.NewApiApplicationService, ), // 应用服务 fx.Provide( // 用户应用服务 - 绑定到接口 fx.Annotate( user.NewUserApplicationService, fx.As(new(user.UserApplicationService)), ), // 认证应用服务 - 绑定到接口 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)), ), // 产品API配置应用服务 - 绑定到接口 fx.Annotate( product.NewProductApiConfigApplicationService, fx.As(new(product.ProductApiConfigApplicationService)), ), // 分类应用服务 - 绑定到接口 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.NewCertificationHandler, // 财务HTTP处理器 handlers.NewFinanceHandler, // 产品HTTP处理器 handlers.NewProductHandler, // 产品管理员HTTP处理器 handlers.NewProductAdminHandler, // API Handler handlers.NewApiHandler, ), // 路由注册 fx.Provide( // 用户路由 routes.NewUserRoutes, // 认证路由 routes.NewCertificationRoutes, // 财务路由 routes.NewFinanceRoutes, // 产品路由 routes.NewProductRoutes, // 产品管理员路由 routes.NewProductAdminRoutes, // API路由 routes.NewApiRoutes, ), // 应用生命周期 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, certificationRoutes *routes.CertificationRoutes, financeRoutes *routes.FinanceRoutes, productRoutes *routes.ProductRoutes, productAdminRoutes *routes.ProductAdminRoutes, apiRoutes *routes.ApiRoutes, cfg *config.Config, logger *zap.Logger, ) { router.SetupDefaultRoutes() // api域名路由 apiRoutes.Register(router) // 所有域名路由路由 userRoutes.Register(router) certificationRoutes.Register(router) financeRoutes.Register(router) productRoutes.Register(router) productAdminRoutes.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") }