This commit is contained in:
2025-09-12 01:15:09 +08:00
parent c563b2266b
commit e05ad9e223
103 changed files with 20034 additions and 1041 deletions

View File

@@ -14,8 +14,10 @@ import (
"tyapi-server/internal/application/certification"
"tyapi-server/internal/application/finance"
"tyapi-server/internal/application/product"
"tyapi-server/internal/application/statistics"
"tyapi-server/internal/application/user"
"tyapi-server/internal/config"
api_repositories "tyapi-server/internal/domains/api/repositories"
domain_article_repo "tyapi-server/internal/domains/article/repositories"
article_service "tyapi-server/internal/domains/article/services"
domain_certification_repo "tyapi-server/internal/domains/certification/repositories"
@@ -24,6 +26,7 @@ import (
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"
statistics_service "tyapi-server/internal/domains/statistics/services"
user_service "tyapi-server/internal/domains/user/services"
"tyapi-server/internal/infrastructure/cache"
"tyapi-server/internal/infrastructure/database"
@@ -44,9 +47,14 @@ import (
"tyapi-server/internal/infrastructure/http/handlers"
"tyapi-server/internal/infrastructure/http/routes"
"tyapi-server/internal/infrastructure/task"
task_implementations "tyapi-server/internal/infrastructure/task/implementations"
asynq "tyapi-server/internal/infrastructure/task/implementations/asynq"
task_interfaces "tyapi-server/internal/infrastructure/task/interfaces"
task_repositories "tyapi-server/internal/infrastructure/task/repositories"
shared_database "tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/esign"
"tyapi-server/internal/shared/events"
shared_events "tyapi-server/internal/shared/events"
"tyapi-server/internal/shared/export"
"tyapi-server/internal/shared/health"
"tyapi-server/internal/shared/hooks"
sharedhttp "tyapi-server/internal/shared/http"
@@ -64,12 +72,18 @@ import (
domain_user_repo "tyapi-server/internal/domains/user/repositories"
user_repo "tyapi-server/internal/infrastructure/database/repositories/user"
hibiken_asynq "github.com/hibiken/asynq"
"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_services "tyapi-server/internal/domains/api/services"
finance_services "tyapi-server/internal/domains/finance/services"
product_services "tyapi-server/internal/domains/product/services"
domain_statistics_repo "tyapi-server/internal/domains/statistics/repositories"
user_repositories "tyapi-server/internal/domains/user/repositories"
api_repo "tyapi-server/internal/infrastructure/database/repositories/api"
statistics_repo "tyapi-server/internal/infrastructure/database/repositories/statistics"
)
// Container 应用容器
@@ -97,16 +111,16 @@ func NewContainer() *Container {
}
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,
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",
@@ -197,7 +211,7 @@ func NewContainer() *Container {
return 5 // 默认5个工作协程
},
fx.Annotate(
events.NewMemoryEventBus,
shared_events.NewMemoryEventBus,
fx.As(new(interfaces.EventBus)),
),
// 健康检查
@@ -288,6 +302,10 @@ func NewContainer() *Container {
}
return payment.NewAliPayService(config)
},
// 导出管理器
func(logger *zap.Logger) *export.ExportManager {
return export.NewExportManager(logger)
},
),
// 高级特性模块
@@ -363,8 +381,8 @@ func NewContainer() *Container {
MaxRequestsPerDay: cfg.DailyRateLimit.MaxRequestsPerDay,
MaxRequestsPerIP: cfg.DailyRateLimit.MaxRequestsPerIP,
KeyPrefix: cfg.DailyRateLimit.KeyPrefix,
TTL: cfg.DailyRateLimit.TTL,
MaxConcurrent: cfg.DailyRateLimit.MaxConcurrent,
TTL: cfg.DailyRateLimit.TTL,
MaxConcurrent: cfg.DailyRateLimit.MaxConcurrent,
// 安全配置
EnableIPWhitelist: cfg.DailyRateLimit.EnableIPWhitelist,
IPWhitelist: cfg.DailyRateLimit.IPWhitelist,
@@ -377,6 +395,10 @@ func NewContainer() *Container {
EnableGeoBlock: cfg.DailyRateLimit.EnableGeoBlock,
BlockedCountries: cfg.DailyRateLimit.BlockedCountries,
EnableProxyCheck: cfg.DailyRateLimit.EnableProxyCheck,
// 排除路径配置
ExcludePaths: cfg.DailyRateLimit.ExcludePaths,
// 排除域名配置
ExcludeDomains: cfg.DailyRateLimit.ExcludeDomains,
}
return middleware.NewDailyRateLimitMiddleware(cfg, redis, response, logger, limitConfig)
},
@@ -553,6 +575,22 @@ func NewContainer() *Container {
),
),
// 统计域仓储层
fx.Provide(
fx.Annotate(
statistics_repo.NewGormStatisticsRepository,
fx.As(new(domain_statistics_repo.StatisticsRepository)),
),
fx.Annotate(
statistics_repo.NewGormStatisticsReportRepository,
fx.As(new(domain_statistics_repo.StatisticsReportRepository)),
),
fx.Annotate(
statistics_repo.NewGormStatisticsDashboardRepository,
fx.As(new(domain_statistics_repo.StatisticsDashboardRepository)),
),
),
// 领域服务
fx.Provide(
fx.Annotate(
@@ -565,6 +603,25 @@ func NewContainer() *Container {
product_service.NewProductSubscriptionService,
product_service.NewProductApiConfigService,
product_service.NewProductDocumentationService,
fx.Annotate(
func(
apiUserRepo api_repositories.ApiUserRepository,
userRepo user_repositories.UserRepository,
enterpriseInfoRepo user_repositories.EnterpriseInfoRepository,
smsService *sms.AliSMSService,
config *config.Config,
logger *zap.Logger,
) finance_service.BalanceAlertService {
return finance_service.NewBalanceAlertService(
apiUserRepo,
userRepo,
enterpriseInfoRepo,
smsService,
config,
logger,
)
},
),
finance_service.NewWalletAggregateService,
finance_service.NewRechargeRecordService,
// 发票领域服务
@@ -608,28 +665,122 @@ func NewContainer() *Container {
certification_service.NewEnterpriseInfoSubmitRecordService,
// 文章领域服务
article_service.NewArticleService,
// 统计领域服务
statistics_service.NewStatisticsAggregateService,
statistics_service.NewStatisticsCalculationService,
statistics_service.NewStatisticsReportService,
),
// API域服务层
fx.Provide(
api_service.NewApiUserAggregateService,
api_service.NewApiCallAggregateService,
api_service.NewApiRequestService,
api_service.NewFormConfigService,
fx.Annotate(
api_services.NewApiUserAggregateService,
),
api_services.NewApiCallAggregateService,
api_services.NewApiRequestService,
api_services.NewFormConfigService,
),
// API域应用服务
fx.Provide(
api_app.NewApiApplicationService,
// API应用服务 - 绑定到接口
fx.Annotate(
func(
apiCallService api_services.ApiCallAggregateService,
apiUserService api_services.ApiUserAggregateService,
apiRequestService *api_services.ApiRequestService,
formConfigService api_services.FormConfigService,
apiCallRepository domain_api_repo.ApiCallRepository,
productManagementService *product_services.ProductManagementService,
userRepo user_repositories.UserRepository,
txManager *shared_database.TransactionManager,
config *config.Config,
logger *zap.Logger,
contractInfoService user_repositories.ContractInfoRepository,
taskManager task_interfaces.TaskManager,
walletService finance_services.WalletAggregateService,
subscriptionService *product_services.ProductSubscriptionService,
exportManager *export.ExportManager,
balanceAlertService finance_services.BalanceAlertService,
) api_app.ApiApplicationService {
return api_app.NewApiApplicationService(
apiCallService,
apiUserService,
apiRequestService,
formConfigService,
apiCallRepository,
productManagementService,
userRepo,
txManager,
config,
logger,
contractInfoService,
taskManager,
walletService,
subscriptionService,
exportManager,
balanceAlertService,
)
},
fx.As(new(api_app.ApiApplicationService)),
),
),
// 任务系统
fx.Provide(
// Asynq 客户端
func(cfg *config.Config, scheduledTaskRepo domain_article_repo.ScheduledTaskRepository, logger *zap.Logger) *task.AsynqClient {
// Asynq 客户端 (github.com/hibiken/asynq)
func(cfg *config.Config) *hibiken_asynq.Client {
redisAddr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
return hibiken_asynq.NewClient(hibiken_asynq.RedisClientOpt{Addr: redisAddr})
},
// 自定义Asynq客户端 (用于文章任务)
func(cfg *config.Config, scheduledTaskRepo domain_article_repo.ScheduledTaskRepository, logger *zap.Logger) *asynq.AsynqClient {
redisAddr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
return task.NewAsynqClient(redisAddr, scheduledTaskRepo, logger)
},
// 文章任务队列
func(cfg *config.Config, logger *zap.Logger) task_interfaces.ArticleTaskQueue {
redisAddr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
return task.NewArticleTaskQueue(redisAddr, logger)
},
// AsyncTask 仓库
task_repositories.NewAsyncTaskRepository,
// TaskManager - 统一任务管理器
func(
asynqClient *hibiken_asynq.Client,
asyncTaskRepo task_repositories.AsyncTaskRepository,
logger *zap.Logger,
config *config.Config,
) task_interfaces.TaskManager {
taskConfig := &task_interfaces.TaskManagerConfig{
RedisAddr: fmt.Sprintf("%s:%s", config.Redis.Host, config.Redis.Port),
MaxRetries: 5,
RetryInterval: 5 * time.Minute,
CleanupDays: 30,
}
return task_implementations.NewTaskManager(asynqClient, asyncTaskRepo, logger, taskConfig)
},
// AsynqWorker - 任务处理器
func(
cfg *config.Config,
logger *zap.Logger,
articleApplicationService article.ArticleApplicationService,
apiApplicationService api_app.ApiApplicationService,
walletService finance_services.WalletAggregateService,
subscriptionService *product_services.ProductSubscriptionService,
asyncTaskRepo task_repositories.AsyncTaskRepository,
) *asynq.AsynqWorker {
redisAddr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
return asynq.NewAsynqWorker(
redisAddr,
logger,
articleApplicationService,
apiApplicationService,
walletService,
subscriptionService,
asyncTaskRepo,
)
},
),
// 应用服务
@@ -641,12 +792,70 @@ func NewContainer() *Container {
),
// 认证应用服务 - 绑定到接口
fx.Annotate(
certification.NewCertificationApplicationService,
func(
aggregateService certification_service.CertificationAggregateService,
userAggregateService user_service.UserAggregateService,
queryRepository domain_certification_repo.CertificationQueryRepository,
enterpriseInfoSubmitRecordRepo domain_certification_repo.EnterpriseInfoSubmitRecordRepository,
smsCodeService *user_service.SMSCodeService,
esignClient *esign.Client,
esignConfig *esign.Config,
qiniuStorageService *storage.QiNiuStorageService,
contractAggregateService user_service.ContractAggregateService,
walletAggregateService finance_services.WalletAggregateService,
apiUserAggregateService api_services.ApiUserAggregateService,
enterpriseInfoSubmitRecordService *certification_service.EnterpriseInfoSubmitRecordService,
ocrService sharedOCR.OCRService,
txManager *shared_database.TransactionManager,
logger *zap.Logger,
) certification.CertificationApplicationService {
return certification.NewCertificationApplicationService(
aggregateService,
userAggregateService,
queryRepository,
enterpriseInfoSubmitRecordRepo,
smsCodeService,
esignClient,
esignConfig,
qiniuStorageService,
contractAggregateService,
walletAggregateService,
apiUserAggregateService,
enterpriseInfoSubmitRecordService,
ocrService,
txManager,
logger,
)
},
fx.As(new(certification.CertificationApplicationService)),
),
// 财务应用服务 - 绑定到接口
fx.Annotate(
finance.NewFinanceApplicationService,
func(
aliPayClient *payment.AliPayService,
walletService finance_services.WalletAggregateService,
rechargeRecordService finance_services.RechargeRecordService,
walletTransactionRepo domain_finance_repo.WalletTransactionRepository,
alipayOrderRepo domain_finance_repo.AlipayOrderRepository,
userRepo domain_user_repo.UserRepository,
txManager *shared_database.TransactionManager,
logger *zap.Logger,
config *config.Config,
exportManager *export.ExportManager,
) finance.FinanceApplicationService {
return finance.NewFinanceApplicationService(
aliPayClient,
walletService,
rechargeRecordService,
walletTransactionRepo,
alipayOrderRepo,
userRepo,
txManager,
logger,
config,
exportManager,
)
},
fx.As(new(finance.FinanceApplicationService)),
),
// 发票应用服务 - 绑定到接口
@@ -692,7 +901,7 @@ func NewContainer() *Container {
categoryRepo domain_article_repo.CategoryRepository,
tagRepo domain_article_repo.TagRepository,
articleService *article_service.ArticleService,
asynqClient *task.AsynqClient,
taskManager task_interfaces.TaskManager,
logger *zap.Logger,
) article.ArticleApplicationService {
return article.NewArticleApplicationService(
@@ -700,12 +909,47 @@ func NewContainer() *Container {
categoryRepo,
tagRepo,
articleService,
asynqClient,
taskManager,
logger,
)
},
fx.As(new(article.ArticleApplicationService)),
),
// 统计应用服务 - 绑定到接口
fx.Annotate(
func(
aggregateService statistics_service.StatisticsAggregateService,
calculationService statistics_service.StatisticsCalculationService,
reportService statistics_service.StatisticsReportService,
metricRepo domain_statistics_repo.StatisticsRepository,
reportRepo domain_statistics_repo.StatisticsReportRepository,
dashboardRepo domain_statistics_repo.StatisticsDashboardRepository,
userRepo domain_user_repo.UserRepository,
apiCallRepo domain_api_repo.ApiCallRepository,
walletTransactionRepo domain_finance_repo.WalletTransactionRepository,
rechargeRecordRepo domain_finance_repo.RechargeRecordRepository,
productRepo domain_product_repo.ProductRepository,
certificationRepo domain_certification_repo.CertificationQueryRepository,
logger *zap.Logger,
) statistics.StatisticsApplicationService {
return statistics.NewStatisticsApplicationService(
aggregateService,
calculationService,
reportService,
metricRepo,
reportRepo,
dashboardRepo,
userRepo,
apiCallRepo,
walletTransactionRepo,
rechargeRecordRepo,
productRepo,
certificationRepo,
logger,
)
},
fx.As(new(statistics.StatisticsApplicationService)),
),
),
// HTTP处理器
@@ -722,6 +966,8 @@ func NewContainer() *Container {
handlers.NewProductAdminHandler,
// API Handler
handlers.NewApiHandler,
// 统计HTTP处理器
handlers.NewStatisticsHandler,
// 文章HTTP处理器
func(
appService article.ArticleApplicationService,
@@ -745,10 +991,12 @@ func NewContainer() *Container {
routes.NewProductRoutes,
// 产品管理员路由
routes.NewProductAdminRoutes,
// API路由
// 文章路由
routes.NewArticleRoutes,
// API路由
routes.NewApiRoutes,
// 统计路由
routes.NewStatisticsRoutes,
),
// 应用生命周期
@@ -783,20 +1031,34 @@ func (c *Container) Stop() error {
func RegisterLifecycleHooks(
lifecycle fx.Lifecycle,
logger *zap.Logger,
asynqWorker *asynq.AsynqWorker,
) {
lifecycle.Append(fx.Hook{
OnStart: func(context.Context) error {
logger.Info("应用启动中...")
logger.Info("所有依赖注入完成,开始启动应用服务")
// 确保校验器最先初始化
validator.InitGlobalValidator()
logger.Info("全局校验器初始化完成")
// 启动AsynqWorker
if err := asynqWorker.Start(); err != nil {
logger.Error("启动AsynqWorker失败", zap.Error(err))
return err
}
logger.Info("AsynqWorker启动成功")
return nil
},
OnStop: func(context.Context) error {
logger.Info("应用关闭中...")
// 停止AsynqWorker
asynqWorker.Stop()
asynqWorker.Shutdown()
logger.Info("AsynqWorker已停止")
return nil
},
})
@@ -843,6 +1105,7 @@ func RegisterRoutes(
productAdminRoutes *routes.ProductAdminRoutes,
articleRoutes *routes.ArticleRoutes,
apiRoutes *routes.ApiRoutes,
statisticsRoutes *routes.StatisticsRoutes,
cfg *config.Config,
logger *zap.Logger,
) {
@@ -858,6 +1121,7 @@ func RegisterRoutes(
productRoutes.Register(router)
productAdminRoutes.Register(router)
articleRoutes.Register(router)
statisticsRoutes.Register(router)
// 打印注册的路由信息
router.PrintRoutes()