723 lines
22 KiB
Go
723 lines
22 KiB
Go
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"
|
||
"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) {
|
||
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(用于大多数场景)
|
||
func(log logger.Logger) *zap.Logger {
|
||
if zapLogger, ok := log.(*logger.ZapLogger); ok {
|
||
return zapLogger.GetZapLogger()
|
||
}
|
||
// 如果类型转换失败,创建一个默认的zap logger
|
||
defaultLogger, _ := zap.NewProduction()
|
||
return defaultLogger
|
||
},
|
||
// 提供业务日志记录器
|
||
func(logger *zap.Logger) *middleware.BusinessLogger {
|
||
return middleware.NewBusinessLogger(logger)
|
||
},
|
||
// 数据库连接
|
||
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,
|
||
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))
|
||
}
|
||
}()
|
||
}
|
||
|
||
// ================ 中间件包装函数 ================
|
||
|
||
// NewPanicRecoveryMiddlewareWrapper 创建Panic恢复中间件包装器
|
||
func NewPanicRecoveryMiddlewareWrapper(logger *zap.Logger) *middleware.PanicRecoveryMiddleware {
|
||
return middleware.NewPanicRecoveryMiddleware(logger)
|
||
}
|
||
|
||
// NewComprehensiveLoggerMiddlewareWrapper 创建全面日志中间件包装器
|
||
func NewComprehensiveLoggerMiddlewareWrapper(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)
|
||
}
|
||
|
||
// 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")
|
||
}
|