Files
tyapi-server/internal/container/container.go

968 lines
31 KiB
Go
Raw Normal View History

package container
import (
"context"
2025-09-01 18:29:59 +08:00
"fmt"
"time"
"go.uber.org/fx"
"go.uber.org/zap"
2025-07-28 15:21:37 +08:00
"go.uber.org/zap/zapcore"
"gorm.io/gorm"
2025-09-01 18:29:59 +08:00
"tyapi-server/internal/application/article"
2025-07-13 16:36:20 +08:00
"tyapi-server/internal/application/certification"
"tyapi-server/internal/application/finance"
2025-07-15 13:21:34 +08:00
"tyapi-server/internal/application/product"
2025-07-13 16:36:20 +08:00
"tyapi-server/internal/application/user"
"tyapi-server/internal/config"
2025-09-01 18:29:59 +08:00
domain_article_repo "tyapi-server/internal/domains/article/repositories"
article_service "tyapi-server/internal/domains/article/services"
2025-07-13 16:36:20 +08:00
domain_certification_repo "tyapi-server/internal/domains/certification/repositories"
2025-07-28 01:46:39 +08:00
certification_service "tyapi-server/internal/domains/certification/services"
2025-07-13 16:36:20 +08:00
domain_finance_repo "tyapi-server/internal/domains/finance/repositories"
finance_service "tyapi-server/internal/domains/finance/services"
2025-07-15 13:21:34 +08:00
domain_product_repo "tyapi-server/internal/domains/product/repositories"
product_service "tyapi-server/internal/domains/product/services"
2025-07-13 16:36:20 +08:00
user_service "tyapi-server/internal/domains/user/services"
"tyapi-server/internal/infrastructure/cache"
"tyapi-server/internal/infrastructure/database"
2025-09-01 18:29:59 +08:00
article_repo "tyapi-server/internal/infrastructure/database/repositories/article"
2025-07-13 16:36:20 +08:00
certification_repo "tyapi-server/internal/infrastructure/database/repositories/certification"
finance_repo "tyapi-server/internal/infrastructure/database/repositories/finance"
2025-07-15 13:21:34 +08:00
product_repo "tyapi-server/internal/infrastructure/database/repositories/product"
2025-08-02 02:54:21 +08:00
infra_events "tyapi-server/internal/infrastructure/events"
2025-08-04 17:16:38 +08:00
"tyapi-server/internal/infrastructure/external/alicloud"
2025-08-02 02:54:21 +08:00
"tyapi-server/internal/infrastructure/external/email"
2025-07-13 16:36:20 +08:00
"tyapi-server/internal/infrastructure/external/ocr"
"tyapi-server/internal/infrastructure/external/sms"
"tyapi-server/internal/infrastructure/external/storage"
2025-07-30 00:51:22 +08:00
"tyapi-server/internal/infrastructure/external/tianyancha"
2025-07-28 01:46:39 +08:00
"tyapi-server/internal/infrastructure/external/westdex"
"tyapi-server/internal/infrastructure/external/yushan"
"tyapi-server/internal/infrastructure/external/zhicha"
2025-07-13 16:36:20 +08:00
"tyapi-server/internal/infrastructure/http/handlers"
"tyapi-server/internal/infrastructure/http/routes"
2025-09-01 18:29:59 +08:00
"tyapi-server/internal/infrastructure/task"
2025-07-20 20:53:26 +08:00
shared_database "tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/esign"
"tyapi-server/internal/shared/events"
"tyapi-server/internal/shared/health"
2025-07-02 16:17:59 +08:00
"tyapi-server/internal/shared/hooks"
sharedhttp "tyapi-server/internal/shared/http"
"tyapi-server/internal/shared/interfaces"
2025-07-13 16:36:20 +08:00
"tyapi-server/internal/shared/logger"
2025-07-02 16:17:59 +08:00
"tyapi-server/internal/shared/metrics"
"tyapi-server/internal/shared/middleware"
2025-07-13 16:36:20 +08:00
sharedOCR "tyapi-server/internal/shared/ocr"
2025-07-28 01:46:39 +08:00
"tyapi-server/internal/shared/payment"
2025-07-02 16:17:59 +08:00
"tyapi-server/internal/shared/resilience"
"tyapi-server/internal/shared/saga"
"tyapi-server/internal/shared/tracing"
2025-07-20 20:53:26 +08:00
"tyapi-server/internal/shared/validator"
domain_user_repo "tyapi-server/internal/domains/user/repositories"
user_repo "tyapi-server/internal/infrastructure/database/repositories/user"
2025-07-13 16:36:20 +08:00
"github.com/redis/go-redis/v9"
2025-07-28 01:46:39 +08:00
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(
2025-07-31 15:41:00 +08:00
// 日志器 - 提供自定义Logger和*zap.Logger
func(cfg *config.Config) (logger.Logger, error) {
// 将 config.LoggerConfig 转换为 logger.Config
// 转换 LevelConfigs 类型
levelConfigs := make(map[string]interface{})
for key, value := range cfg.Logger.LevelConfigs {
levelConfigs[key] = value
}
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,
UseColor: cfg.Logger.UseColor,
EnableLevelSeparation: cfg.Logger.EnableLevelSeparation,
LevelConfigs: levelConfigs,
Development: cfg.App.Env == "development",
}
// 初始化全局日志器
if err := logger.InitGlobalLogger(logCfg); err != nil {
return nil, err
}
2025-07-31 15:41:00 +08:00
if cfg.Logger.EnableLevelSeparation {
// 使用按级别分文件的日志器
levelConfig := logger.LevelLoggerConfig{
BaseConfig: logCfg,
2025-07-31 15:41:00 +08:00
EnableLevelSeparation: true,
LevelConfigs: convertLevelConfigs(cfg.Logger.LevelConfigs),
}
return logger.NewLevelLogger(levelConfig)
} else {
// 使用普通日志器
return logger.NewLogger(logCfg)
2025-07-28 15:21:37 +08:00
}
2025-07-31 15:41:00 +08:00
},
// 提供普通的*zap.Logger用于大多数场景
2025-08-02 02:54:21 +08:00
fx.Annotate(
func(log logger.Logger) *zap.Logger {
// 尝试转换为ZapLogger
if zapLogger, ok := log.(*logger.ZapLogger); ok {
return zapLogger.GetZapLogger()
2025-07-31 15:41:00 +08:00
}
2025-08-02 02:54:21 +08:00
// 尝试转换为LevelLogger
if levelLogger, ok := log.(*logger.LevelLogger); ok {
// 获取Info级别的日志器作为默认
if infoLogger := levelLogger.GetLevelLogger(zapcore.InfoLevel); infoLogger != nil {
return infoLogger
}
}
// 如果类型转换失败,使用全局日志器
return logger.GetGlobalLogger()
2025-08-02 02:54:21 +08:00
},
),
2025-07-28 15:30:48 +08:00
2025-07-13 16:36:20 +08:00
// 数据库连接
2025-07-20 20:53:26 +08:00
func(cfg *config.Config, cacheService interfaces.CacheService, logger *zap.Logger) (*gorm.DB, error) {
2025-07-13 16:36:20 +08:00
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 {
2025-07-31 15:41:00 +08:00
logger.Error("数据库连接失败",
2025-07-28 16:13:59 +08:00
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))
2025-07-13 16:36:20 +08:00
return nil, err
}
2025-07-31 15:41:00 +08:00
logger.Info("数据库连接成功",
2025-07-28 16:13:59 +08:00
zap.String("host", cfg.Database.Host),
zap.String("port", cfg.Database.Port),
zap.String("database", cfg.Database.Name))
2025-07-20 20:53:26 +08:00
// 设置GORM缓存插件
if err := SetupGormCache(db.DB, cacheService, cfg, logger); err != nil {
logger.Warn("GORM缓存插件设置失败", zap.Error(err))
// 不返回错误,允许系统在没有缓存的情况下运行
}
2025-07-13 16:36:20 +08:00
return db.DB, nil
},
// Redis客户端
NewRedisClient,
2025-07-13 16:36:20 +08:00
// 缓存服务
fx.Annotate(NewRedisCache, fx.As(new(interfaces.CacheService))),
// 事件总线
// 提供workerCount参数
func() int {
return 5 // 默认5个工作协程
},
2025-08-02 02:54:21 +08:00
fx.Annotate(
events.NewMemoryEventBus,
fx.As(new(interfaces.EventBus)),
),
2025-07-13 16:36:20 +08:00
// 健康检查
health.NewHealthChecker,
// 提供 config.SMSConfig
func(cfg *config.Config) config.SMSConfig {
return cfg.SMS
},
// 提供 config.AppConfig
func(cfg *config.Config) config.AppConfig {
return cfg.App
},
2025-07-20 20:53:26 +08:00
// 事务管理器
func(db *gorm.DB, logger *zap.Logger) *shared_database.TransactionManager {
return shared_database.NewTransactionManager(db, logger)
},
2025-07-13 16:36:20 +08:00
// 短信服务
sms.NewAliSMSService,
2025-08-02 02:54:21 +08:00
// 邮件服务
fx.Annotate(
func(cfg *config.Config, logger *zap.Logger) *email.QQEmailService {
return email.NewQQEmailService(cfg.Email, logger)
},
),
2025-07-13 16:36:20 +08:00
// 存储服务
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)),
),
2025-07-28 01:46:39 +08:00
// e签宝配置
func(cfg *config.Config) (*esign.Config, error) {
return esign.NewConfig(
2025-07-20 20:53:26 +08:00
cfg.Esign.AppID,
cfg.Esign.AppSecret,
cfg.Esign.ServerURL,
cfg.Esign.TemplateID,
2025-07-28 01:46:39 +08:00
&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,
},
2025-07-20 20:53:26 +08:00
)
2025-07-28 01:46:39 +08:00
},
// e签宝服务
func(esignConfig *esign.Config) *esign.Client {
2025-07-20 20:53:26 +08:00
return esign.NewClient(esignConfig)
},
2025-07-28 01:46:39 +08:00
// 支付宝支付服务
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)
},
2025-07-02 16:17:59 +08:00
),
// 高级特性模块
fx.Provide(
2025-07-13 16:36:20 +08:00
// 提供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(
2025-07-13 16:36:20 +08:00
sharedhttp.NewResponseBuilder,
2025-07-20 20:53:26 +08:00
validator.NewRequestValidator,
2025-07-28 01:46:39 +08:00
// WestDexService - 需要从配置中获取参数
func(cfg *config.Config) (*westdex.WestDexService, error) {
return westdex.NewWestDexServiceWithConfig(cfg)
},
// ZhichaService - 智查金控服务
func(cfg *config.Config) (*zhicha.ZhichaService, error) {
return zhicha.NewZhichaServiceWithConfig(cfg)
2025-07-28 01:46:39 +08:00
},
func(cfg *config.Config) *yushan.YushanService {
return yushan.NewYushanService(
cfg.Yushan.URL,
cfg.Yushan.APIKey,
cfg.Yushan.AcctID,
nil, // 暂时不传入logger使用无日志版本
2025-07-28 01:46:39 +08:00
)
},
2025-07-30 00:51:22 +08:00
// TianYanChaService - 天眼查服务
func(cfg *config.Config) *tianyancha.TianYanChaService {
return tianyancha.NewTianYanChaService(
cfg.TianYanCha.BaseURL, // 天眼查API基础URL
cfg.TianYanCha.APIKey,
30*time.Second, // 默认超时时间
)
},
2025-08-04 17:16:38 +08:00
// AlicloudService - 阿里云服务
func(cfg *config.Config) *alicloud.AlicloudService {
return alicloud.NewAlicloudService(
cfg.Alicloud.Host,
cfg.Alicloud.AppCode,
)
},
2025-07-13 16:36:20 +08:00
sharedhttp.NewGinRouter,
),
// 中间件组件
fx.Provide(
2025-07-13 16:36:20 +08:00
middleware.NewRequestIDMiddleware,
middleware.NewSecurityHeadersMiddleware,
middleware.NewResponseTimeMiddleware,
middleware.NewCORSMiddleware,
middleware.NewRateLimitMiddleware,
2025-08-10 14:40:02 +08:00
// 每日限流中间件
func(cfg *config.Config, redis *redis.Client, response interfaces.ResponseBuilder, logger *zap.Logger) *middleware.DailyRateLimitMiddleware {
limitConfig := middleware.DailyRateLimitConfig{
MaxRequestsPerDay: cfg.DailyRateLimit.MaxRequestsPerDay,
MaxRequestsPerIP: cfg.DailyRateLimit.MaxRequestsPerIP,
KeyPrefix: cfg.DailyRateLimit.KeyPrefix,
TTL: cfg.DailyRateLimit.TTL,
MaxConcurrent: cfg.DailyRateLimit.MaxConcurrent,
// 安全配置
EnableIPWhitelist: cfg.DailyRateLimit.EnableIPWhitelist,
IPWhitelist: cfg.DailyRateLimit.IPWhitelist,
EnableIPBlacklist: cfg.DailyRateLimit.EnableIPBlacklist,
IPBlacklist: cfg.DailyRateLimit.IPBlacklist,
EnableUserAgent: cfg.DailyRateLimit.EnableUserAgent,
BlockedUserAgents: cfg.DailyRateLimit.BlockedUserAgents,
EnableReferer: cfg.DailyRateLimit.EnableReferer,
AllowedReferers: cfg.DailyRateLimit.AllowedReferers,
EnableGeoBlock: cfg.DailyRateLimit.EnableGeoBlock,
BlockedCountries: cfg.DailyRateLimit.BlockedCountries,
EnableProxyCheck: cfg.DailyRateLimit.EnableProxyCheck,
}
return middleware.NewDailyRateLimitMiddleware(cfg, redis, response, logger, limitConfig)
},
2025-07-13 16:36:20 +08:00
NewRequestLoggerMiddlewareWrapper,
middleware.NewJWTAuthMiddleware,
middleware.NewOptionalAuthMiddleware,
2025-07-20 20:53:26 +08:00
middleware.NewAdminAuthMiddleware,
2025-07-28 01:46:39 +08:00
middleware.NewDomainAuthMiddleware,
2025-07-13 16:36:20 +08:00
middleware.NewTraceIDMiddleware,
middleware.NewErrorTrackingMiddleware,
NewRequestBodyLoggerMiddlewareWrapper,
2025-07-28 15:30:48 +08:00
// 新增的中间件
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)
},
),
2025-07-13 16:36:20 +08:00
// 仓储层 - 用户域
fx.Provide(
2025-07-13 16:36:20 +08:00
// 用户仓储 - 同时注册具体类型和接口类型
fx.Annotate(
user_repo.NewGormUserRepository,
fx.As(new(domain_user_repo.UserRepository)),
),
2025-07-28 01:46:39 +08:00
// 短信验证码仓储 - 同时注册具体类型和接口类型
fx.Annotate(
user_repo.NewGormSMSCodeRepository,
fx.As(new(domain_user_repo.SMSCodeRepository)),
),
// 用户信息仓储 - 同时注册具体类型和接口类型
2025-07-13 16:36:20 +08:00
fx.Annotate(
user_repo.NewGormEnterpriseInfoRepository,
fx.As(new(domain_user_repo.EnterpriseInfoRepository)),
),
2025-07-28 01:46:39 +08:00
// 合同信息仓储 - 同时注册具体类型和接口类型
2025-07-13 16:36:20 +08:00
fx.Annotate(
2025-07-28 01:46:39 +08:00
user_repo.NewGormContractInfoRepository,
fx.As(new(domain_user_repo.ContractInfoRepository)),
2025-07-13 16:36:20 +08:00
),
),
// 仓储层 - 认证域
fx.Provide(
2025-07-21 15:13:26 +08:00
// 认证命令仓储
2025-07-13 16:36:20 +08:00
fx.Annotate(
2025-07-21 15:13:26 +08:00
certification_repo.NewGormCertificationCommandRepository,
fx.As(new(domain_certification_repo.CertificationCommandRepository)),
2025-07-13 16:36:20 +08:00
),
2025-07-21 15:13:26 +08:00
// 认证查询仓储
2025-07-13 16:36:20 +08:00
fx.Annotate(
2025-07-21 15:13:26 +08:00
certification_repo.NewGormCertificationQueryRepository,
fx.As(new(domain_certification_repo.CertificationQueryRepository)),
2025-07-13 16:36:20 +08:00
),
2025-07-28 01:46:39 +08:00
// 企业信息提交记录仓储
fx.Annotate(
certification_repo.NewGormEnterpriseInfoSubmitRecordRepository,
fx.As(new(domain_certification_repo.EnterpriseInfoSubmitRecordRepository)),
),
2025-07-13 16:36:20 +08:00
),
// 仓储层 - 财务域
fx.Provide(
// 钱包仓储
fx.Annotate(
finance_repo.NewGormWalletRepository,
fx.As(new(domain_finance_repo.WalletRepository)),
),
2025-07-28 01:46:39 +08:00
// 钱包交易记录仓储
2025-07-13 16:36:20 +08:00
fx.Annotate(
2025-07-28 01:46:39 +08:00
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)),
2025-07-13 16:36:20 +08:00
),
2025-08-02 02:54:21 +08:00
// 发票申请仓储
fx.Annotate(
finance_repo.NewGormInvoiceApplicationRepository,
fx.As(new(domain_finance_repo.InvoiceApplicationRepository)),
),
// 用户开票信息仓储
fx.Annotate(
finance_repo.NewGormUserInvoiceInfoRepository,
fx.As(new(domain_finance_repo.UserInvoiceInfoRepository)),
),
2025-07-13 16:36:20 +08:00
),
2025-07-15 13:21:34 +08:00
// 仓储层 - 产品域
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)),
),
2025-07-28 01:46:39 +08:00
// 产品API配置仓储 - 同时注册具体类型和接口类型
fx.Annotate(
product_repo.NewGormProductApiConfigRepository,
fx.As(new(domain_product_repo.ProductApiConfigRepository)),
),
2025-07-31 15:41:00 +08:00
fx.Annotate(
product_repo.NewGormProductDocumentationRepository,
fx.As(new(domain_product_repo.ProductDocumentationRepository)),
),
2025-07-28 01:46:39 +08:00
),
2025-09-01 18:29:59 +08:00
// 仓储层 - 文章域
fx.Provide(
// 文章仓储 - 同时注册具体类型和接口类型
fx.Annotate(
article_repo.NewGormArticleRepository,
fx.As(new(domain_article_repo.ArticleRepository)),
),
// 分类仓储 - 同时注册具体类型和接口类型
fx.Annotate(
article_repo.NewGormCategoryRepository,
fx.As(new(domain_article_repo.CategoryRepository)),
),
// 标签仓储 - 同时注册具体类型和接口类型
fx.Annotate(
article_repo.NewGormTagRepository,
fx.As(new(domain_article_repo.TagRepository)),
),
),
2025-07-28 01:46:39 +08:00
// 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)),
),
2025-07-15 13:21:34 +08:00
),
2025-07-13 16:36:20 +08:00
// 领域服务
fx.Provide(
2025-08-02 02:54:21 +08:00
fx.Annotate(
user_service.NewUserAggregateService,
),
2025-07-20 20:53:26 +08:00
user_service.NewUserAuthService,
2025-07-13 16:36:20 +08:00
user_service.NewSMSCodeService,
2025-07-28 01:46:39 +08:00
user_service.NewContractAggregateService,
2025-07-20 20:53:26 +08:00
product_service.NewProductManagementService,
product_service.NewProductSubscriptionService,
2025-07-28 01:46:39 +08:00
product_service.NewProductApiConfigService,
2025-07-31 15:41:00 +08:00
product_service.NewProductDocumentationService,
2025-07-28 01:46:39 +08:00
finance_service.NewWalletAggregateService,
finance_service.NewRechargeRecordService,
2025-08-02 02:54:21 +08:00
// 发票领域服务
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,
2025-07-28 01:46:39 +08:00
certification_service.NewCertificationAggregateService,
certification_service.NewEnterpriseInfoSubmitRecordService,
2025-09-01 18:29:59 +08:00
// 文章领域服务
article_service.NewArticleService,
2025-07-28 01:46:39 +08:00
),
// API域服务层
fx.Provide(
api_service.NewApiUserAggregateService,
api_service.NewApiCallAggregateService,
api_service.NewApiRequestService,
2025-08-27 22:19:19 +08:00
api_service.NewFormConfigService,
2025-07-28 01:46:39 +08:00
),
// API域应用服务
fx.Provide(
api_app.NewApiApplicationService,
2025-07-13 16:36:20 +08:00
),
2025-09-01 18:29:59 +08:00
// 任务系统
fx.Provide(
// Asynq 客户端
func(cfg *config.Config, logger *zap.Logger) *task.AsynqClient {
2025-09-02 16:37:28 +08:00
redisAddr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
2025-09-01 18:29:59 +08:00
return task.NewAsynqClient(redisAddr, logger)
},
),
2025-07-13 16:36:20 +08:00
// 应用服务
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)),
),
2025-08-02 02:54:21 +08:00
// 发票应用服务 - 绑定到接口
fx.Annotate(
finance.NewInvoiceApplicationService,
fx.As(new(finance.InvoiceApplicationService)),
),
// 管理员发票应用服务 - 绑定到接口
fx.Annotate(
finance.NewAdminInvoiceApplicationService,
fx.As(new(finance.AdminInvoiceApplicationService)),
),
2025-07-15 13:21:34 +08:00
// 产品应用服务 - 绑定到接口
fx.Annotate(
product.NewProductApplicationService,
fx.As(new(product.ProductApplicationService)),
),
2025-07-28 01:46:39 +08:00
// 产品API配置应用服务 - 绑定到接口
fx.Annotate(
product.NewProductApiConfigApplicationService,
fx.As(new(product.ProductApiConfigApplicationService)),
),
2025-07-15 13:21:34 +08:00
// 分类应用服务 - 绑定到接口
fx.Annotate(
product.NewCategoryApplicationService,
fx.As(new(product.CategoryApplicationService)),
),
2025-07-31 15:41:00 +08:00
fx.Annotate(
product.NewDocumentationApplicationService,
fx.As(new(product.DocumentationApplicationServiceInterface)),
),
2025-07-15 13:21:34 +08:00
// 订阅应用服务 - 绑定到接口
fx.Annotate(
product.NewSubscriptionApplicationService,
fx.As(new(product.SubscriptionApplicationService)),
),
2025-09-01 18:29:59 +08:00
// 文章应用服务 - 绑定到接口
fx.Annotate(
article.NewArticleApplicationService,
fx.As(new(article.ArticleApplicationService)),
),
2025-07-13 16:36:20 +08:00
),
// HTTP处理器
fx.Provide(
// 用户HTTP处理器
handlers.NewUserHandler,
// 认证HTTP处理器
handlers.NewCertificationHandler,
// 财务HTTP处理器
handlers.NewFinanceHandler,
2025-07-15 13:21:34 +08:00
// 产品HTTP处理器
handlers.NewProductHandler,
2025-07-20 20:53:26 +08:00
// 产品管理员HTTP处理器
handlers.NewProductAdminHandler,
2025-07-28 01:46:39 +08:00
// API Handler
handlers.NewApiHandler,
2025-09-01 18:29:59 +08:00
// 文章HTTP处理器
func(
appService article.ArticleApplicationService,
responseBuilder interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
) *handlers.ArticleHandler {
return handlers.NewArticleHandler(appService, responseBuilder, validator, logger)
},
2025-07-13 16:36:20 +08:00
),
2025-07-15 13:21:34 +08:00
// 路由注册
2025-07-13 16:36:20 +08:00
fx.Provide(
2025-07-15 13:21:34 +08:00
// 用户路由
2025-07-13 16:36:20 +08:00
routes.NewUserRoutes,
2025-07-15 13:21:34 +08:00
// 认证路由
2025-07-13 16:36:20 +08:00
routes.NewCertificationRoutes,
2025-07-15 13:21:34 +08:00
// 财务路由
2025-07-13 16:36:20 +08:00
routes.NewFinanceRoutes,
2025-07-15 13:21:34 +08:00
// 产品路由
routes.NewProductRoutes,
2025-07-20 20:53:26 +08:00
// 产品管理员路由
routes.NewProductAdminRoutes,
2025-07-28 01:46:39 +08:00
// API路由
2025-09-01 18:29:59 +08:00
// 文章路由
routes.NewArticleRoutes,
2025-07-28 01:46:39 +08:00
routes.NewApiRoutes,
),
// 应用生命周期
fx.Invoke(
RegisterLifecycleHooks,
RegisterMiddlewares,
RegisterRoutes,
2025-08-02 02:54:21 +08:00
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)
}
2025-07-13 16:36:20 +08:00
// RegisterLifecycleHooks 注册生命周期钩子
func RegisterLifecycleHooks(
lifecycle fx.Lifecycle,
logger *zap.Logger,
2025-07-13 16:36:20 +08:00
) {
lifecycle.Append(fx.Hook{
OnStart: func(context.Context) error {
logger.Info("应用启动中...")
2025-07-28 16:13:59 +08:00
logger.Info("所有依赖注入完成,开始启动应用服务")
2025-08-27 22:19:19 +08:00
// 确保校验器最先初始化
validator.InitGlobalValidator()
logger.Info("全局校验器初始化完成")
2025-07-13 16:36:20 +08:00
return nil
},
OnStop: func(context.Context) error {
logger.Info("应用关闭中...")
return nil
},
})
2025-07-02 16:17:59 +08:00
}
// RegisterMiddlewares 注册中间件
func RegisterMiddlewares(
2025-07-02 16:17:59 +08:00
router *sharedhttp.GinRouter,
2025-07-28 15:21:37 +08:00
panicRecovery *middleware.PanicRecoveryMiddleware,
comprehensiveLogger *middleware.ComprehensiveLoggerMiddleware,
requestID *middleware.RequestIDMiddleware,
security *middleware.SecurityHeadersMiddleware,
responseTime *middleware.ResponseTimeMiddleware,
cors *middleware.CORSMiddleware,
rateLimit *middleware.RateLimitMiddleware,
2025-08-10 14:40:02 +08:00
dailyRateLimit *middleware.DailyRateLimitMiddleware,
requestLogger *middleware.RequestLoggerMiddleware,
2025-07-02 16:17:59 +08:00
traceIDMiddleware *middleware.TraceIDMiddleware,
errorTrackingMiddleware *middleware.ErrorTrackingMiddleware,
requestBodyLogger *middleware.RequestBodyLoggerMiddleware,
) {
2025-07-28 15:21:37 +08:00
// 注册所有中间件(按优先级顺序)
router.RegisterMiddleware(panicRecovery)
router.RegisterMiddleware(comprehensiveLogger)
router.RegisterMiddleware(requestID)
router.RegisterMiddleware(security)
router.RegisterMiddleware(responseTime)
router.RegisterMiddleware(cors)
router.RegisterMiddleware(rateLimit)
2025-08-10 14:40:02 +08:00
router.RegisterMiddleware(dailyRateLimit)
router.RegisterMiddleware(requestLogger)
2025-07-02 16:17:59 +08:00
router.RegisterMiddleware(traceIDMiddleware)
router.RegisterMiddleware(errorTrackingMiddleware)
router.RegisterMiddleware(requestBodyLogger)
}
// RegisterRoutes 注册路由
func RegisterRoutes(
2025-07-02 16:17:59 +08:00
router *sharedhttp.GinRouter,
2025-07-13 16:36:20 +08:00
userRoutes *routes.UserRoutes,
certificationRoutes *routes.CertificationRoutes,
financeRoutes *routes.FinanceRoutes,
2025-07-15 13:21:34 +08:00
productRoutes *routes.ProductRoutes,
2025-07-20 20:53:26 +08:00
productAdminRoutes *routes.ProductAdminRoutes,
2025-09-01 18:29:59 +08:00
articleRoutes *routes.ArticleRoutes,
2025-07-28 01:46:39 +08:00
apiRoutes *routes.ApiRoutes,
2025-07-13 16:36:20 +08:00
cfg *config.Config,
logger *zap.Logger,
) {
router.SetupDefaultRoutes()
2025-07-28 01:46:39 +08:00
// api域名路由
apiRoutes.Register(router)
// 所有域名路由路由
2025-07-13 16:36:20 +08:00
userRoutes.Register(router)
certificationRoutes.Register(router)
financeRoutes.Register(router)
2025-07-15 13:21:34 +08:00
productRoutes.Register(router)
2025-07-20 20:53:26 +08:00
productAdminRoutes.Register(router)
2025-09-01 18:29:59 +08:00
articleRoutes.Register(router)
2025-07-13 16:36:20 +08:00
// 打印注册的路由信息
router.PrintRoutes()
2025-07-13 16:36:20 +08:00
// 启动HTTP服务器
go func() {
addr := ":" + cfg.Server.Port
logger.Info("正在启动HTTP服务器", zap.String("addr", addr))
2025-07-13 16:36:20 +08:00
if err := router.Start(addr); err != nil {
logger.Error("HTTP服务器启动失败", zap.Error(err))
2025-07-28 16:19:53 +08:00
// 在goroutine中记录错误但不会影响主程序
2025-07-28 16:13:59 +08:00
} else {
logger.Info("HTTP服务器启动成功", zap.String("addr", addr))
2025-07-13 16:36:20 +08:00
}
}()
2025-07-31 15:41:00 +08:00
2025-07-28 16:13:59 +08:00
logger.Info("路由注册完成HTTP服务器启动中...")
}
2025-07-13 16:36:20 +08:00
// ================ 中间件包装函数 ================
2025-07-02 16:17:59 +08:00
2025-07-13 16:36:20 +08:00
// NewRequestLoggerMiddlewareWrapper 创建请求日志中间件包装器
func NewRequestLoggerMiddlewareWrapper(logger *zap.Logger, cfg *config.Config, tracer *tracing.Tracer) *middleware.RequestLoggerMiddleware {
return middleware.NewRequestLoggerMiddleware(logger, cfg.App.IsDevelopment(), tracer)
2025-07-02 16:17:59 +08:00
}
2025-07-13 16:36:20 +08:00
// NewRequestBodyLoggerMiddlewareWrapper 创建请求体日志中间件包装器
func NewRequestBodyLoggerMiddlewareWrapper(logger *zap.Logger, cfg *config.Config, tracer *tracing.Tracer) *middleware.RequestBodyLoggerMiddleware {
return middleware.NewRequestBodyLoggerMiddleware(logger, cfg.App.IsDevelopment(), tracer)
}
2025-07-28 15:21:37 +08:00
// ================ 辅助函数 ================
// convertLevelConfigs 转换级别配置
func convertLevelConfigs(configs map[string]config.LevelFileConfig) map[zapcore.Level]logger.LevelFileConfig {
result := make(map[zapcore.Level]logger.LevelFileConfig)
2025-07-31 15:41:00 +08:00
2025-07-28 15:21:37 +08:00
levelMap := map[string]zapcore.Level{
"debug": zapcore.DebugLevel,
"info": zapcore.InfoLevel,
"warn": zapcore.WarnLevel,
"error": zapcore.ErrorLevel,
"fatal": zapcore.FatalLevel,
"panic": zapcore.PanicLevel,
}
2025-07-31 15:41:00 +08:00
// 只转换配置文件中存在的级别
2025-07-28 15:21:37 +08:00
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,
}
}
}
2025-07-31 15:41:00 +08:00
2025-07-28 15:21:37 +08:00
return result
}
2025-07-13 16:36:20 +08:00
// ================ 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
}
2025-07-13 16:36:20 +08:00
// NewRedisCache 创建Redis缓存服务
func NewRedisCache(client *redis.Client, logger *zap.Logger, cfg *config.Config) interfaces.CacheService {
return cache.NewRedisCache(client, logger, "app")
}
2025-07-13 16:36:20 +08:00
// 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")
}
2025-08-02 02:54:21 +08:00
// 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("所有事件处理器已注册")
}