draft
This commit is contained in:
126
backend/internal/app/app.go
Normal file
126
backend/internal/app/app.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"pay-bridge/internal/repository"
|
||||
"pay-bridge/internal/service"
|
||||
"pay-bridge/pkg/config"
|
||||
"pay-bridge/pkg/sequence"
|
||||
)
|
||||
|
||||
// App 应用容器,持有所有初始化完成的 service 实例
|
||||
type App struct {
|
||||
Cfg *config.Config
|
||||
|
||||
// 对外暴露供 router 使用的 service
|
||||
AdminAuthSvc *service.AdminAuthService
|
||||
AppSvc *service.AppService
|
||||
TradeSvc *service.TradeService
|
||||
RefundSvc *service.RefundService
|
||||
NotifySvc *service.NotifyService
|
||||
MatchSvc *service.PaymentMatchService
|
||||
MerchantSvc *service.MerchantService
|
||||
ReconSvc *service.ReconciliationService
|
||||
ChannelSvc *service.ChannelService
|
||||
|
||||
// 内部资源
|
||||
db *gorm.DB
|
||||
rdb *redis.Client
|
||||
}
|
||||
|
||||
// New 初始化所有基础设施和 service,返回就绪的 App 实例
|
||||
func New(cfg *config.Config) (*App, error) {
|
||||
a := &App{Cfg: cfg}
|
||||
|
||||
if err := a.initInfra(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.initServices()
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Start 启动后台任务(notify poller 等)
|
||||
func (a *App) Start(ctx context.Context) {
|
||||
a.NotifySvc.StartPoller(ctx, a.Cfg.Notify.PollerInterval, a.Cfg.Notify.PollerBatch)
|
||||
}
|
||||
|
||||
// Shutdown 优雅关闭:关闭 DB 和 Redis 连接
|
||||
func (a *App) Shutdown(ctx context.Context) {
|
||||
if a.rdb != nil {
|
||||
if err := a.rdb.Close(); err != nil {
|
||||
slog.Error("redis close error", "err", err)
|
||||
}
|
||||
}
|
||||
if a.db != nil {
|
||||
sqlDB, err := a.db.DB()
|
||||
if err == nil {
|
||||
if err := sqlDB.Close(); err != nil {
|
||||
slog.Error("db close error", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initInfra 初始化 DB 和 Redis
|
||||
func (a *App) initInfra() error {
|
||||
db, err := config.NewDB(a.Cfg.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.db = db
|
||||
|
||||
rdb, err := config.NewRedis(a.Cfg.Redis)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.rdb = rdb
|
||||
return nil
|
||||
}
|
||||
|
||||
// initServices 按依赖顺序构建 repo → service
|
||||
func (a *App) initServices() {
|
||||
encKey := a.Cfg.Security.FieldEncryptKey
|
||||
|
||||
// Repositories
|
||||
adminUserRepo := repository.NewAdminUserRepository(a.db)
|
||||
appRepo := repository.NewAppRepository(a.db)
|
||||
tradeRepo := repository.NewTradeOrderRepository(a.db)
|
||||
refundRepo := repository.NewRefundOrderRepository(a.db)
|
||||
notifyRepo := repository.NewNotifyLogRepository(a.db)
|
||||
channelCfgRepo := repository.NewChannelConfigRepository(a.db)
|
||||
seqRepo := repository.NewSequenceRepository(a.db)
|
||||
profitSharingRepo := repository.NewProfitSharingRepository(a.db)
|
||||
serviceFeeRepo := repository.NewServiceFeeRepository(a.db)
|
||||
matchRepo := repository.NewPaymentMatchRepository(a.db)
|
||||
merchantRepo := repository.NewMerchantRepository(a.db)
|
||||
wechatRepo := repository.NewWechatRepository(a.db)
|
||||
reconRepo := repository.NewReconciliationRepository(a.db)
|
||||
|
||||
// JWT expire hours
|
||||
jwtExpireHours := a.Cfg.JWT.ExpireHours
|
||||
if jwtExpireHours == 0 {
|
||||
jwtExpireHours = 24
|
||||
}
|
||||
|
||||
// Services
|
||||
a.AdminAuthSvc = service.NewAdminAuthService(adminUserRepo, a.Cfg.JWT.Secret, jwtExpireHours)
|
||||
a.ChannelSvc = service.NewChannelService(channelCfgRepo, encKey, a.Cfg.Channels)
|
||||
seqSvc := sequence.NewService(seqRepo)
|
||||
a.AppSvc = service.NewAppService(appRepo, encKey)
|
||||
a.NotifySvc = service.NewNotifyService(notifyRepo, tradeRepo, a.Cfg.Notify.HTTPTimeout)
|
||||
a.MerchantSvc = service.NewMerchantService(merchantRepo, a.ChannelSvc)
|
||||
a.TradeSvc = service.NewTradeService(tradeRepo, a.ChannelSvc, seqSvc, a.rdb, a.NotifySvc, a.MerchantSvc)
|
||||
a.RefundSvc = service.NewRefundService(refundRepo, tradeRepo, a.ChannelSvc, seqSvc, a.NotifySvc)
|
||||
a.MatchSvc = service.NewPaymentMatchService(matchRepo, tradeRepo, a.NotifySvc, a.TradeSvc)
|
||||
a.ReconSvc = service.NewReconciliationService(reconRepo, tradeRepo, a.ChannelSvc, appRepo)
|
||||
|
||||
// 以下 service 目前未直接暴露给 router,但已初始化供将来扩展使用
|
||||
_ = service.NewProfitSharingService(profitSharingRepo, tradeRepo, a.ChannelSvc, seqSvc, a.rdb)
|
||||
_ = service.NewServiceFeeService(serviceFeeRepo, tradeRepo, a.ChannelSvc)
|
||||
_ = service.NewWechatService(wechatRepo, encKey)
|
||||
}
|
||||
Reference in New Issue
Block a user