Files
tyapi-server/internal/container/container.go
2025-08-04 17:16:38 +08:00

875 lines
27 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package container
import (
"context"
"time"
"go.uber.org/fx"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"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"
infra_events "tyapi-server/internal/infrastructure/events"
"tyapi-server/internal/infrastructure/external/alicloud"
"tyapi-server/internal/infrastructure/external/email"
"tyapi-server/internal/infrastructure/external/ocr"
"tyapi-server/internal/infrastructure/external/sms"
"tyapi-server/internal/infrastructure/external/storage"
"tyapi-server/internal/infrastructure/external/tianyancha"
"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) {
if cfg.Logger.EnableLevelSeparation {
// 使用按级别分文件的日志器
levelConfig := logger.LevelLoggerConfig{
BaseConfig: logger.Config{
Level: cfg.Logger.Level,
Format: cfg.Logger.Format,
Output: cfg.Logger.Output,
LogDir: cfg.Logger.LogDir,
MaxSize: cfg.Logger.MaxSize,
MaxBackups: cfg.Logger.MaxBackups,
MaxAge: cfg.Logger.MaxAge,
Compress: cfg.Logger.Compress,
UseDaily: cfg.Logger.UseDaily,
},
EnableLevelSeparation: true,
LevelConfigs: convertLevelConfigs(cfg.Logger.LevelConfigs),
}
return logger.NewLevelLogger(levelConfig)
} else {
// 使用普通日志器
logCfg := logger.Config{
Level: cfg.Logger.Level,
Format: cfg.Logger.Format,
Output: cfg.Logger.Output,
LogDir: cfg.Logger.LogDir,
MaxSize: cfg.Logger.MaxSize,
MaxBackups: cfg.Logger.MaxBackups,
MaxAge: cfg.Logger.MaxAge,
Compress: cfg.Logger.Compress,
UseDaily: cfg.Logger.UseDaily,
}
return logger.NewLogger(logCfg)
}
},
// 提供普通的*zap.Logger用于大多数场景
fx.Annotate(
func(log logger.Logger) *zap.Logger {
// 尝试转换为ZapLogger
if zapLogger, ok := log.(*logger.ZapLogger); ok {
return zapLogger.GetZapLogger()
}
// 尝试转换为LevelLogger
if levelLogger, ok := log.(*logger.LevelLogger); ok {
// 获取Info级别的日志器作为默认
if infoLogger := levelLogger.GetLevelLogger(zapcore.InfoLevel); infoLogger != nil {
return infoLogger
}
}
// 如果类型转换失败创建一个默认的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 {
logger.Error("数据库连接失败",
zap.String("host", cfg.Database.Host),
zap.String("port", cfg.Database.Port),
zap.String("database", cfg.Database.Name),
zap.String("user", cfg.Database.User),
zap.Error(err))
return nil, err
}
logger.Info("数据库连接成功",
zap.String("host", cfg.Database.Host),
zap.String("port", cfg.Database.Port),
zap.String("database", cfg.Database.Name))
// 设置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个工作协程
},
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) *email.QQEmailService {
return email.NewQQEmailService(cfg.Email, logger)
},
),
// 存储服务
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,
)
},
// TianYanChaService - 天眼查服务
func(cfg *config.Config) *tianyancha.TianYanChaService {
return tianyancha.NewTianYanChaService(
cfg.TianYanCha.BaseURL, // 天眼查API基础URL
cfg.TianYanCha.APIKey,
30*time.Second, // 默认超时时间
)
},
// AlicloudService - 阿里云服务
func(cfg *config.Config) *alicloud.AlicloudService {
return alicloud.NewAlicloudService(
cfg.Alicloud.Host,
cfg.Alicloud.AppCode,
)
},
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,
// 新增的中间件
func(logger *zap.Logger) *middleware.PanicRecoveryMiddleware {
return middleware.NewPanicRecoveryMiddleware(logger)
},
func(logger *zap.Logger, cfg *config.Config) *middleware.ComprehensiveLoggerMiddleware {
config := &middleware.ComprehensiveLoggerConfig{
EnableRequestLogging: true,
EnableResponseLogging: true,
EnableRequestBodyLogging: cfg.App.IsDevelopment(), // 开发环境记录请求体
EnableErrorLogging: true,
EnableBusinessLogging: true,
EnablePerformanceLogging: true,
MaxBodySize: 1024 * 10, // 10KB
ExcludePaths: []string{"/health", "/metrics", "/favicon.ico", "/swagger"},
}
return middleware.NewComprehensiveLoggerMiddleware(logger, config)
},
// 业务日志记录器
func(logger *zap.Logger) *middleware.BusinessLogger {
return middleware.NewBusinessLogger(logger)
},
),
// 仓储层 - 用户域
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.Annotate(
finance_repo.NewGormInvoiceApplicationRepository,
fx.As(new(domain_finance_repo.InvoiceApplicationRepository)),
),
// 用户开票信息仓储
fx.Annotate(
finance_repo.NewGormUserInvoiceInfoRepository,
fx.As(new(domain_finance_repo.UserInvoiceInfoRepository)),
),
),
// 仓储层 - 产品域
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)),
),
fx.Annotate(
product_repo.NewGormProductDocumentationRepository,
fx.As(new(domain_product_repo.ProductDocumentationRepository)),
),
),
// 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(
fx.Annotate(
user_service.NewUserAggregateService,
),
user_service.NewUserAuthService,
user_service.NewSMSCodeService,
user_service.NewContractAggregateService,
product_service.NewProductManagementService,
product_service.NewProductSubscriptionService,
product_service.NewProductApiConfigService,
product_service.NewProductDocumentationService,
finance_service.NewWalletAggregateService,
finance_service.NewRechargeRecordService,
// 发票领域服务
fx.Annotate(
finance_service.NewInvoiceDomainService,
),
// 用户开票信息服务
fx.Annotate(
finance_service.NewUserInvoiceInfoService,
),
// 发票事件发布器 - 绑定到接口
fx.Annotate(
func(logger *zap.Logger, eventBus interfaces.EventBus) finance_service.EventPublisher {
return infra_events.NewInvoiceEventPublisher(logger, eventBus)
},
fx.As(new(finance_service.EventPublisher)),
),
// 发票聚合服务 - 需要用户开票信息仓储
fx.Annotate(
func(
applicationRepo domain_finance_repo.InvoiceApplicationRepository,
userInvoiceInfoRepo domain_finance_repo.UserInvoiceInfoRepository,
domainService finance_service.InvoiceDomainService,
qiniuStorageService *storage.QiNiuStorageService,
logger *zap.Logger,
eventPublisher finance_service.EventPublisher,
) finance_service.InvoiceAggregateService {
return finance_service.NewInvoiceAggregateService(
applicationRepo,
userInvoiceInfoRepo,
domainService,
qiniuStorageService,
logger,
eventPublisher,
)
},
),
// 发票事件处理器
infra_events.NewInvoiceEventHandler,
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(
finance.NewInvoiceApplicationService,
fx.As(new(finance.InvoiceApplicationService)),
),
// 管理员发票应用服务 - 绑定到接口
fx.Annotate(
finance.NewAdminInvoiceApplicationService,
fx.As(new(finance.AdminInvoiceApplicationService)),
),
// 产品应用服务 - 绑定到接口
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.NewDocumentationApplicationService,
fx.As(new(product.DocumentationApplicationServiceInterface)),
),
// 订阅应用服务 - 绑定到接口
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,
RegisterEventHandlers,
),
)
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("应用启动中...")
logger.Info("所有依赖注入完成,开始启动应用服务")
return nil
},
OnStop: func(context.Context) error {
logger.Info("应用关闭中...")
return nil
},
})
}
// RegisterMiddlewares 注册中间件
func RegisterMiddlewares(
router *sharedhttp.GinRouter,
panicRecovery *middleware.PanicRecoveryMiddleware,
comprehensiveLogger *middleware.ComprehensiveLoggerMiddleware,
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(panicRecovery)
router.RegisterMiddleware(comprehensiveLogger)
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))
// 在goroutine中记录错误但不会影响主程序
} else {
logger.Info("HTTP服务器启动成功", zap.String("addr", addr))
}
}()
logger.Info("路由注册完成HTTP服务器启动中...")
}
// ================ 中间件包装函数 ================
// 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)
}
// ================ 辅助函数 ================
// convertLevelConfigs 转换级别配置
func convertLevelConfigs(configs map[string]config.LevelFileConfig) map[zapcore.Level]logger.LevelFileConfig {
result := make(map[zapcore.Level]logger.LevelFileConfig)
levelMap := map[string]zapcore.Level{
"debug": zapcore.DebugLevel,
"info": zapcore.InfoLevel,
"warn": zapcore.WarnLevel,
"error": zapcore.ErrorLevel,
"fatal": zapcore.FatalLevel,
"panic": zapcore.PanicLevel,
}
for levelStr, config := range configs {
if level, exists := levelMap[levelStr]; exists {
result[level] = logger.LevelFileConfig{
MaxSize: config.MaxSize,
MaxBackups: config.MaxBackups,
MaxAge: config.MaxAge,
Compress: config.Compress,
}
}
}
return result
}
// ================ 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")
}
// RegisterEventHandlers 注册事件处理器
func RegisterEventHandlers(
eventBus interfaces.EventBus,
invoiceEventHandler *infra_events.InvoiceEventHandler,
logger *zap.Logger,
) {
// 启动事件总线
if err := eventBus.Start(context.Background()); err != nil {
logger.Error("启动事件总线失败", zap.Error(err))
return
}
// 注册发票事件处理器
for _, eventType := range invoiceEventHandler.GetEventTypes() {
if err := eventBus.Subscribe(eventType, invoiceEventHandler); err != nil {
logger.Error("注册发票事件处理器失败",
zap.String("event_type", eventType),
zap.String("handler", invoiceEventHandler.GetName()),
zap.Error(err),
)
} else {
logger.Info("发票事件处理器注册成功",
zap.String("event_type", eventType),
zap.String("handler", invoiceEventHandler.GetName()),
)
}
}
logger.Info("所有事件处理器已注册")
}