2025-06-30 19:21:56 +08:00
|
|
|
|
package container
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"go.uber.org/fx"
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
|
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"
|
2025-06-30 19:21:56 +08:00
|
|
|
|
"tyapi-server/internal/config"
|
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"
|
|
|
|
|
|
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-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-28 01:46:39 +08:00
|
|
|
|
"tyapi-server/internal/infrastructure/external/westdex"
|
|
|
|
|
|
"tyapi-server/internal/infrastructure/external/yushan"
|
2025-07-13 16:36:20 +08:00
|
|
|
|
"tyapi-server/internal/infrastructure/http/handlers"
|
|
|
|
|
|
"tyapi-server/internal/infrastructure/http/routes"
|
2025-07-20 20:53:26 +08:00
|
|
|
|
shared_database "tyapi-server/internal/shared/database"
|
|
|
|
|
|
"tyapi-server/internal/shared/esign"
|
2025-06-30 19:21:56 +08:00
|
|
|
|
"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"
|
2025-06-30 19:21:56 +08:00
|
|
|
|
"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"
|
2025-06-30 19:21:56 +08:00
|
|
|
|
"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"
|
2025-06-30 19:21:56 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Container 应用容器
|
|
|
|
|
|
type Container struct {
|
|
|
|
|
|
App *fx.App
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewContainer 创建新的应用容器
|
|
|
|
|
|
func NewContainer() *Container {
|
|
|
|
|
|
app := fx.New(
|
|
|
|
|
|
// 配置模块
|
|
|
|
|
|
fx.Provide(
|
|
|
|
|
|
config.LoadConfig,
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// 基础设施模块
|
|
|
|
|
|
fx.Provide(
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// 日志器 - 提供自定义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,
|
2025-07-28 13:47:58 +08:00
|
|
|
|
LogDir: cfg.Logger.LogDir,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
MaxSize: cfg.Logger.MaxSize,
|
|
|
|
|
|
MaxBackups: cfg.Logger.MaxBackups,
|
|
|
|
|
|
MaxAge: cfg.Logger.MaxAge,
|
|
|
|
|
|
Compress: cfg.Logger.Compress,
|
2025-07-28 13:47:58 +08:00
|
|
|
|
UseDaily: cfg.Logger.UseDaily,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
|
|
},
|
|
|
|
|
|
// 数据库连接
|
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 {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
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客户端
|
2025-06-30 19:21:56 +08:00
|
|
|
|
NewRedisClient,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// 缓存服务
|
|
|
|
|
|
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
|
|
|
|
|
|
},
|
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,
|
|
|
|
|
|
// 存储服务
|
|
|
|
|
|
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,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
|
|
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,
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
2025-07-13 16:36:20 +08:00
|
|
|
|
sharedhttp.NewGinRouter,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// 中间件组件
|
|
|
|
|
|
fx.Provide(
|
2025-07-13 16:36:20 +08:00
|
|
|
|
middleware.NewRequestIDMiddleware,
|
|
|
|
|
|
middleware.NewSecurityHeadersMiddleware,
|
|
|
|
|
|
middleware.NewResponseTimeMiddleware,
|
|
|
|
|
|
middleware.NewCORSMiddleware,
|
|
|
|
|
|
middleware.NewRateLimitMiddleware,
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
),
|
|
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// 仓储层 - 用户域
|
2025-06-30 19:21:56 +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-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)),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// 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-07-28 01:46:39 +08:00
|
|
|
|
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,
|
|
|
|
|
|
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,
|
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-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)),
|
|
|
|
|
|
),
|
|
|
|
|
|
// 订阅应用服务 - 绑定到接口
|
|
|
|
|
|
fx.Annotate(
|
|
|
|
|
|
product.NewSubscriptionApplicationService,
|
|
|
|
|
|
fx.As(new(product.SubscriptionApplicationService)),
|
|
|
|
|
|
),
|
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-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路由
|
|
|
|
|
|
routes.NewApiRoutes,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// 应用生命周期
|
|
|
|
|
|
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)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// RegisterLifecycleHooks 注册生命周期钩子
|
|
|
|
|
|
func RegisterLifecycleHooks(
|
|
|
|
|
|
lifecycle fx.Lifecycle,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
logger *zap.Logger,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
) {
|
|
|
|
|
|
lifecycle.Append(fx.Hook{
|
|
|
|
|
|
OnStart: func(context.Context) error {
|
|
|
|
|
|
logger.Info("应用启动中...")
|
|
|
|
|
|
return nil
|
|
|
|
|
|
},
|
|
|
|
|
|
OnStop: func(context.Context) error {
|
|
|
|
|
|
logger.Info("应用关闭中...")
|
|
|
|
|
|
return nil
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
2025-07-02 16:17:59 +08:00
|
|
|
|
}
|
2025-06-30 19:21:56 +08:00
|
|
|
|
|
|
|
|
|
|
// RegisterMiddlewares 注册中间件
|
|
|
|
|
|
func RegisterMiddlewares(
|
2025-07-02 16:17:59 +08:00
|
|
|
|
router *sharedhttp.GinRouter,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
requestID *middleware.RequestIDMiddleware,
|
|
|
|
|
|
security *middleware.SecurityHeadersMiddleware,
|
|
|
|
|
|
responseTime *middleware.ResponseTimeMiddleware,
|
|
|
|
|
|
cors *middleware.CORSMiddleware,
|
|
|
|
|
|
rateLimit *middleware.RateLimitMiddleware,
|
|
|
|
|
|
requestLogger *middleware.RequestLoggerMiddleware,
|
2025-07-02 16:17:59 +08:00
|
|
|
|
traceIDMiddleware *middleware.TraceIDMiddleware,
|
|
|
|
|
|
errorTrackingMiddleware *middleware.ErrorTrackingMiddleware,
|
|
|
|
|
|
requestBodyLogger *middleware.RequestBodyLoggerMiddleware,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
) {
|
|
|
|
|
|
router.RegisterMiddleware(requestID)
|
|
|
|
|
|
router.RegisterMiddleware(security)
|
|
|
|
|
|
router.RegisterMiddleware(responseTime)
|
|
|
|
|
|
router.RegisterMiddleware(cors)
|
|
|
|
|
|
router.RegisterMiddleware(rateLimit)
|
|
|
|
|
|
router.RegisterMiddleware(requestLogger)
|
2025-07-02 16:17:59 +08:00
|
|
|
|
router.RegisterMiddleware(traceIDMiddleware)
|
|
|
|
|
|
router.RegisterMiddleware(errorTrackingMiddleware)
|
|
|
|
|
|
router.RegisterMiddleware(requestBodyLogger)
|
2025-06-30 19:21:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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-07-28 01:46:39 +08:00
|
|
|
|
apiRoutes *routes.ApiRoutes,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
cfg *config.Config,
|
|
|
|
|
|
logger *zap.Logger,
|
2025-06-30 19:21:56 +08:00
|
|
|
|
) {
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// 打印注册的路由信息
|
2025-06-30 19:21:56 +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-06-30 19:21:56 +08:00
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err := router.Start(addr); err != nil {
|
|
|
|
|
|
logger.Error("HTTP服务器启动失败", zap.Error(err))
|
|
|
|
|
|
}
|
|
|
|
|
|
}()
|
2025-06-30 19:21:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
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-06-30 19:21:56 +08:00
|
|
|
|
}
|