七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
This commit is contained in:
@@ -14,19 +14,25 @@ import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
|
||||
agentrechargeApp "github.com/break/junhong_cmp_fiber/internal/application/agentrecharge"
|
||||
approvalApp "github.com/break/junhong_cmp_fiber/internal/application/approval"
|
||||
cardObservationApp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
|
||||
notificationApp "github.com/break/junhong_cmp_fiber/internal/application/notification"
|
||||
walletApp "github.com/break/junhong_cmp_fiber/internal/application/wallet"
|
||||
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
|
||||
"github.com/break/junhong_cmp_fiber/internal/gateway"
|
||||
approvalInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/approval"
|
||||
cardObservationInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/cardobservation"
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
|
||||
notificationInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/notification"
|
||||
shopInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/shop"
|
||||
walletInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/wallet"
|
||||
wecomInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/wecom"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/polling"
|
||||
iot_card_svc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
|
||||
refundSvc "github.com/break/junhong_cmp_fiber/internal/service/refund"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
pkgBootstrap "github.com/break/junhong_cmp_fiber/pkg/bootstrap"
|
||||
@@ -135,6 +141,7 @@ func runWorker(cfg *config.Config) {
|
||||
|
||||
taskHandler := createTaskHandler(runtime, appLogger)
|
||||
taskHandler.RegisterHandlers()
|
||||
registerWeComApprovalTasks(taskHandler.GetMux(), runtime, cfg, appLogger)
|
||||
outboxHandler := outbox.NewHandler(runtime.outboxConsumers)
|
||||
taskHandler.GetMux().HandleFunc(constants.TaskTypeOutboxDeliver, outboxHandler.Handle)
|
||||
startOutboxRelay(ctx, runtime, cfg.Worker.InstanceName, appLogger)
|
||||
@@ -231,12 +238,14 @@ func initWorkerRuntime(ctx context.Context, cfg *config.Config, appLogger *zap.L
|
||||
Password: cfg.Redis.Password,
|
||||
DB: cfg.Redis.DB,
|
||||
})
|
||||
workerQueueClient := queue.NewClient(redisClient, appLogger)
|
||||
|
||||
workerDeps := &bootstrap.WorkerDependencies{
|
||||
DB: db,
|
||||
Redis: redisClient,
|
||||
Logger: appLogger,
|
||||
AsynqClient: asynqClient,
|
||||
QueueClient: workerQueueClient,
|
||||
StorageService: storageSvc,
|
||||
GatewayClient: gatewayClient,
|
||||
}
|
||||
@@ -247,7 +256,7 @@ func initWorkerRuntime(ctx context.Context, cfg *config.Config, appLogger *zap.L
|
||||
}
|
||||
|
||||
workerServer := queue.NewServer(redisClient, &cfg.Queue, appLogger)
|
||||
outboxQueueClient := queue.NewClient(redisClient, appLogger)
|
||||
outboxQueueClient := workerQueueClient
|
||||
|
||||
pollingConfigStore := postgres.NewPollingConfigStore(db)
|
||||
pollingConfigMgr := polling.NewPollingConfigManager(pollingConfigStore, redisClient, appLogger)
|
||||
@@ -301,9 +310,108 @@ func initWorkerRuntime(ctx context.Context, cfg *config.Config, appLogger *zap.L
|
||||
registerNotificationOutboxConsumer(runtime, appLogger)
|
||||
registerWalletOutboxConsumer(runtime, appLogger)
|
||||
registerCardObservationOutboxConsumer(runtime, appLogger)
|
||||
registerWeComApprovalOutboxConsumer(runtime, cfg, appLogger)
|
||||
return runtime
|
||||
}
|
||||
|
||||
// registerWeComApprovalOutboxConsumer 注册企业微信审批提交和标准终态业务消费者。
|
||||
func registerWeComApprovalOutboxConsumer(runtime *workerRuntime, cfg *config.Config, appLogger *zap.Logger) {
|
||||
applicationRepository := wecomInfra.NewApplicationRepository(runtime.db)
|
||||
credentialCipher, err := wecomInfra.NewCredentialCipher(cfg.WeCom.CredentialEncryptionKey)
|
||||
if err != nil {
|
||||
appLogger.Warn("企业微信凭据加密密钥未配置或无效,审批提交将失败关闭", zap.Error(err))
|
||||
}
|
||||
integrationRepository := integrationlog.NewRepository(runtime.db)
|
||||
tokenProvider := wecomInfra.NewTokenProvider(
|
||||
applicationRepository, credentialCipher, runtime.redisClient, integrationRepository,
|
||||
cfg.WeCom.BaseURL, cfg.WeCom.Timeout, appLogger,
|
||||
)
|
||||
consumer := wecomInfra.NewApprovalSubmissionConsumer(
|
||||
wecomInfra.NewApprovalContextRepository(runtime.db),
|
||||
wecomInfra.NewApprovalSubmissionClient(tokenProvider, integrationRepository, cfg.WeCom.BaseURL, cfg.WeCom.Timeout),
|
||||
wecomInfra.NewApprovalAttachmentUploader(tokenProvider, integrationRepository, runtime.storageSvc, cfg.WeCom.BaseURL, cfg.WeCom.Timeout),
|
||||
)
|
||||
if err := runtime.outboxConsumers.Register(constants.OutboxEventTypeApprovalSubmissionRequested, consumer); err != nil {
|
||||
appLogger.Fatal("注册企业微信审批提交 Outbox 消费者失败",
|
||||
zap.String("event_type", constants.OutboxEventTypeApprovalSubmissionRequested), zap.Error(err))
|
||||
}
|
||||
owner := cfg.Worker.InstanceName
|
||||
if owner == "" {
|
||||
owner = fmt.Sprintf("worker-%d", os.Getpid())
|
||||
}
|
||||
walletPosting := walletApp.NewPostingService(
|
||||
walletInfra.NewCreditEventWriter(outbox.NewRepository()),
|
||||
nil,
|
||||
)
|
||||
stopResumeService, _ := runtime.workerResult.Services.StopResumeService.(*iot_card_svc.StopResumeService)
|
||||
refundService := refundSvc.New(
|
||||
runtime.db,
|
||||
postgres.NewRefundStore(runtime.db),
|
||||
runtime.workerResult.Stores.Order,
|
||||
runtime.workerResult.Stores.CommissionRecord,
|
||||
runtime.workerResult.Stores.AgentWallet,
|
||||
runtime.workerResult.Stores.AgentWalletTransaction,
|
||||
stopResumeService,
|
||||
nil,
|
||||
runtime.workerResult.Services.ActivationService,
|
||||
runtime.workerResult.Stores.IotCard,
|
||||
runtime.workerResult.Stores.Device,
|
||||
runtime.workerResult.Stores.AssetWallet,
|
||||
appLogger,
|
||||
)
|
||||
refundService.SetAgentWalletRefundService(
|
||||
walletApp.NewRefundService(walletInfra.NewRefundEventWriter(outbox.NewRepository()), nil),
|
||||
)
|
||||
decisionDispatcher := approvalApp.NewDecisionDispatcher(
|
||||
approvalInfra.NewDecisionDeliveryStore(runtime.db),
|
||||
map[string]approvalApp.BusinessDecisionHandler{
|
||||
constants.ApprovalBusinessTypeOfflineRecharge: agentrechargeApp.NewApprovalDecisionHandler(runtime.db, walletPosting),
|
||||
constants.ApprovalBusinessTypeRefund: refundService,
|
||||
},
|
||||
owner,
|
||||
appLogger,
|
||||
nil,
|
||||
)
|
||||
decisionConsumer := approvalInfra.NewTerminalDecisionConsumer(decisionDispatcher)
|
||||
if err := runtime.outboxConsumers.Register(constants.OutboxEventTypeApprovalTerminalDecision, decisionConsumer); err != nil {
|
||||
appLogger.Fatal("注册审批标准终态 Outbox 消费者失败",
|
||||
zap.String("event_type", constants.OutboxEventTypeApprovalTerminalDecision), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
// registerWeComApprovalTasks 注册企微权威详情同步和主动恢复任务。
|
||||
func registerWeComApprovalTasks(mux *asynq.ServeMux, runtime *workerRuntime, cfg *config.Config, appLogger *zap.Logger) {
|
||||
applicationRepository := wecomInfra.NewApplicationRepository(runtime.db)
|
||||
credentialCipher, err := wecomInfra.NewCredentialCipher(cfg.WeCom.CredentialEncryptionKey)
|
||||
if err != nil {
|
||||
appLogger.Warn("企业微信凭据加密密钥未配置或无效,审批详情同步将失败关闭", zap.Error(err))
|
||||
}
|
||||
integrationRepository := integrationlog.NewRepository(runtime.db)
|
||||
tokenProvider := wecomInfra.NewTokenProvider(
|
||||
applicationRepository, credentialCipher, runtime.redisClient, integrationRepository,
|
||||
cfg.WeCom.BaseURL, cfg.WeCom.Timeout, appLogger,
|
||||
)
|
||||
decisionSync := approvalApp.NewSyncDecisionService(
|
||||
runtime.db, approvalInfra.NewRepositoryProvider(),
|
||||
approvalInfra.NewTerminalEventWriter(outbox.NewRepository()),
|
||||
approvalInfra.NewDecisionDeliveryStore(runtime.db), nil,
|
||||
)
|
||||
contexts := wecomInfra.NewApprovalContextRepository(runtime.db)
|
||||
detailHandler := wecomInfra.NewApprovalDetailTaskHandler(
|
||||
wecomInfra.NewApprovalDetailClient(tokenProvider, integrationRepository, cfg.WeCom.BaseURL, cfg.WeCom.Timeout),
|
||||
contexts, decisionSync, integrationRepository,
|
||||
)
|
||||
recoveryHandler := wecomInfra.NewApprovalRecoveryTaskHandler(
|
||||
contexts,
|
||||
wecomInfra.NewApprovalInfoClient(tokenProvider, integrationRepository, cfg.WeCom.BaseURL, cfg.WeCom.Timeout),
|
||||
runtime.outboxQueueClient,
|
||||
)
|
||||
mux.HandleFunc(constants.TaskTypeWeComApprovalSync, detailHandler.Handle)
|
||||
mux.HandleFunc(constants.TaskTypeWeComApprovalRecovery, recoveryHandler.Handle)
|
||||
appLogger.Info("注册企业微信审批详情同步任务处理器", zap.String("task_type", constants.TaskTypeWeComApprovalSync))
|
||||
appLogger.Info("注册企业微信审批主动恢复任务处理器", zap.String("task_type", constants.TaskTypeWeComApprovalRecovery))
|
||||
}
|
||||
|
||||
// registerCardObservationOutboxConsumer 注册卡观测领域事件消费者。
|
||||
func registerCardObservationOutboxConsumer(runtime *workerRuntime, appLogger *zap.Logger) {
|
||||
stopResumeService, _ := runtime.workerResult.Services.StopResumeService.(iot_card_svc.StopResumeServiceInterface)
|
||||
@@ -543,7 +651,7 @@ func startAsynqScheduler(cfg *config.Config, redisAddr string, appLogger *zap.Lo
|
||||
}
|
||||
}()
|
||||
|
||||
appLogger.Info("Asynq Scheduler 已启动(订单超时: @every 1m, 告警检查: @every 1m, 数据清理: 0 2 * * *, 通知清理: 15 2 * * *, 每日流量落盘: 0 2 * * *)")
|
||||
appLogger.Info("Asynq Scheduler 已启动(企微审批恢复: 每 2 分钟,套餐临期提醒: 上海时区每日 03:00)")
|
||||
return asynqScheduler
|
||||
}
|
||||
|
||||
@@ -563,6 +671,15 @@ func registerAsynqScheduleTasks(asynqScheduler *asynq.Scheduler) error {
|
||||
)); err != nil {
|
||||
return fmt.Errorf("注册告警检查定时任务失败: %w", err)
|
||||
}
|
||||
if _, err := asynqScheduler.Register("@every 2m", asynq.NewTask(
|
||||
constants.TaskTypeWeComApprovalRecovery,
|
||||
nil,
|
||||
asynq.MaxRetry(3),
|
||||
asynq.Timeout(2*time.Minute),
|
||||
asynq.Queue(constants.QueueForTaskType(constants.TaskTypeWeComApprovalRecovery)),
|
||||
)); err != nil {
|
||||
return fmt.Errorf("注册企业微信审批主动恢复定时任务失败: %w", err)
|
||||
}
|
||||
if _, err := asynqScheduler.Register("0 2 * * *", asynq.NewTask(
|
||||
constants.TaskTypeDataCleanup,
|
||||
nil,
|
||||
@@ -578,6 +695,15 @@ func registerAsynqScheduleTasks(asynqScheduler *asynq.Scheduler) error {
|
||||
)); err != nil {
|
||||
return fmt.Errorf("注册站内通知保留清理定时任务失败: %w", err)
|
||||
}
|
||||
if _, err := asynqScheduler.Register("CRON_TZ=Asia/Shanghai 0 3 * * *", asynq.NewTask(
|
||||
constants.TaskTypePackageExpiryReminder,
|
||||
nil,
|
||||
asynq.MaxRetry(3),
|
||||
asynq.Timeout(10*time.Minute),
|
||||
asynq.Queue(constants.QueueForTaskType(constants.TaskTypePackageExpiryReminder)),
|
||||
)); err != nil {
|
||||
return fmt.Errorf("注册套餐临期提醒定时任务失败: %w", err)
|
||||
}
|
||||
if _, err := asynqScheduler.Register(
|
||||
"0 2 * * *",
|
||||
asynq.NewTask(
|
||||
|
||||
Reference in New Issue
Block a user