package queue import ( "github.com/hibiken/asynq" "github.com/redis/go-redis/v9" "go.uber.org/zap" "gorm.io/gorm" "github.com/break/junhong_cmp_fiber/internal/exporter" "github.com/break/junhong_cmp_fiber/internal/gateway" "github.com/break/junhong_cmp_fiber/internal/polling" iot_card_svc "github.com/break/junhong_cmp_fiber/internal/service/iot_card" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "github.com/break/junhong_cmp_fiber/internal/task" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/storage" ) type Handler struct { mux *asynq.ServeMux logger *zap.Logger db *gorm.DB redis *redis.Client storage *storage.Service gatewayClient *gateway.Client pollingCallback task.PollingCallback workerResult *WorkerBootstrapResult asynqClient *asynq.Client pollingBase *task.PollingBase pollingStopResumeSvc iot_card_svc.StopResumeServiceInterface } func NewHandler( db *gorm.DB, redis *redis.Client, storageSvc *storage.Service, gatewayClient *gateway.Client, pollingCallback task.PollingCallback, workerResult *WorkerBootstrapResult, asynqClient *asynq.Client, logger *zap.Logger, pollingBase *task.PollingBase, pollingStopResumeSvc iot_card_svc.StopResumeServiceInterface, ) *Handler { return &Handler{ mux: asynq.NewServeMux(), logger: logger, db: db, redis: redis, storage: storageSvc, gatewayClient: gatewayClient, pollingCallback: pollingCallback, workerResult: workerResult, asynqClient: asynqClient, pollingBase: pollingBase, pollingStopResumeSvc: pollingStopResumeSvc, } } func (h *Handler) RegisterHandlers() *asynq.ServeMux { emailHandler := task.NewEmailHandler(h.redis, h.logger) h.mux.HandleFunc(constants.TaskTypeEmailSend, emailHandler.HandleEmailSend) h.logger.Info("注册邮件发送任务处理器", zap.String("task_type", constants.TaskTypeEmailSend)) h.registerIotCardImportHandler() h.registerDeviceImportHandler() h.registerOrderPackageInvalidateHandler() h.registerExportHandlers() h.registerCommissionStatsHandlers() h.registerCommissionCalculationHandler() h.registerPollingHandlers() h.registerPackageActivationHandlers() h.registerOrderExpireHandler() h.registerAlertCheckHandler() h.registerDataCleanupHandler() h.registerAutoPurchaseHandler() h.registerDailyTrafficFlushHandler() h.logger.Info("所有任务处理器注册完成") return h.mux } func (h *Handler) registerIotCardImportHandler() { iotCardImportHandler := task.NewIotCardImportHandler( h.db, h.redis, h.workerResult.Stores.IotCardImportTask, h.workerResult.Stores.IotCard, h.workerResult.Stores.AssetWallet, h.workerResult.Stores.AssetIdentifier, h.storage, h.pollingCallback, h.logger, ) h.mux.HandleFunc(constants.TaskTypeIotCardImport, iotCardImportHandler.HandleIotCardImport) h.logger.Info("注册 IoT 卡导入任务处理器", zap.String("task_type", constants.TaskTypeIotCardImport)) } func (h *Handler) registerOrderPackageInvalidateHandler() { orderPkgHandler := task.NewOrderPackageInvalidateHandler( h.workerResult.Stores.OrderPackageInvalidateTask, h.workerResult.Stores.Order, h.workerResult.Stores.PackageUsage, h.storage, h.logger, ) h.mux.HandleFunc(constants.TaskTypeOrderPackageInvalidate, orderPkgHandler.Handle) h.logger.Info("注册订单套餐批量失效任务处理器", zap.String("task_type", constants.TaskTypeOrderPackageInvalidate)) } func (h *Handler) registerDeviceImportHandler() { deviceImportHandler := task.NewDeviceImportHandler( h.db, h.redis, h.workerResult.Stores.DeviceImportTask, h.workerResult.Stores.Device, h.workerResult.Stores.DeviceSimBinding, h.workerResult.Stores.IotCard, h.workerResult.Stores.AssetWallet, h.workerResult.Stores.AssetIdentifier, h.storage, h.logger, ) h.mux.HandleFunc(constants.TaskTypeDeviceImport, deviceImportHandler.HandleDeviceImport) h.logger.Info("注册设备导入任务处理器", zap.String("task_type", constants.TaskTypeDeviceImport)) } func (h *Handler) registerExportHandlers() { sceneRegistry := exporter.NewDefaultRegistry(h.db) dispatchHandler := task.NewExportDispatchHandler( h.db, h.redis, h.workerResult.Stores.ExportTask, h.workerResult.Stores.ExportShardTask, h.asynqClient, sceneRegistry, h.logger, ) shardHandler := task.NewExportShardHandler( h.redis, h.workerResult.Stores.ExportTask, h.workerResult.Stores.ExportShardTask, h.asynqClient, h.storage, sceneRegistry, h.logger, ) finalizeHandler := task.NewExportFinalizeHandler( h.redis, h.workerResult.Stores.ExportTask, h.workerResult.Stores.ExportShardTask, h.storage, sceneRegistry, h.logger, ) h.mux.HandleFunc(constants.TaskTypeExportDispatch, dispatchHandler.HandleExportDispatch) h.logger.Info("注册导出 dispatch 任务处理器", zap.String("task_type", constants.TaskTypeExportDispatch)) h.mux.HandleFunc(constants.TaskTypeExportShard, shardHandler.HandleExportShard) h.logger.Info("注册导出 shard 任务处理器", zap.String("task_type", constants.TaskTypeExportShard)) h.mux.HandleFunc(constants.TaskTypeExportFinalize, finalizeHandler.HandleExportFinalize) h.logger.Info("注册导出 finalize 任务处理器", zap.String("task_type", constants.TaskTypeExportFinalize)) } func (h *Handler) registerCommissionStatsHandlers() { updateHandler := task.NewCommissionStatsUpdateHandler( h.redis, h.workerResult.Stores.ShopSeriesCommissionStats, h.workerResult.Stores.ShopPackageAllocation, h.logger, ) syncHandler := task.NewCommissionStatsSyncHandler( h.db, h.redis, h.workerResult.Stores.ShopSeriesCommissionStats, h.logger, ) archiveHandler := task.NewCommissionStatsArchiveHandler( h.db, h.redis, h.workerResult.Stores.ShopSeriesCommissionStats, h.logger, ) h.mux.HandleFunc(constants.TaskTypeCommissionStatsUpdate, updateHandler.HandleCommissionStatsUpdate) h.logger.Info("注册佣金统计更新任务处理器", zap.String("task_type", constants.TaskTypeCommissionStatsUpdate)) h.mux.HandleFunc(constants.TaskTypeCommissionStatsSync, syncHandler.HandleCommissionStatsSync) h.logger.Info("注册佣金统计同步任务处理器", zap.String("task_type", constants.TaskTypeCommissionStatsSync)) h.mux.HandleFunc(constants.TaskTypeCommissionStatsArchive, archiveHandler.HandleCommissionStatsArchive) h.logger.Info("注册佣金统计归档任务处理器", zap.String("task_type", constants.TaskTypeCommissionStatsArchive)) } func (h *Handler) registerCommissionCalculationHandler() { commissionCalculationHandler := task.NewCommissionCalculationHandler( h.db, h.workerResult.Services.CommissionCalculation, h.logger, ) h.mux.HandleFunc(constants.TaskTypeCommission, commissionCalculationHandler.HandleCommissionCalculation) h.logger.Info("注册佣金计算任务处理器", zap.String("task_type", constants.TaskTypeCommission)) } func (h *Handler) registerPollingHandlers() { realnameHandler := task.NewPollingRealnameHandler( h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard, h.asynqClient, h.pollingStopResumeSvc, h.workerResult.Stores.DeviceSimBinding) carrierStore := postgres.NewCarrierStore(h.db) carddataHandler := task.NewPollingCarddataHandler( h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard, carrierStore, h.workerResult.Services.UsageService, h.pollingStopResumeSvc) packageHandler := task.NewPollingPackageHandler( h.pollingBase, h.workerResult.Stores.IotCard, h.pollingStopResumeSvc) protectHandler := task.NewPollingProtectHandler( h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard, h.workerResult.Stores.DeviceSimBinding, h.pollingStopResumeSvc) cardStatusHandler := task.NewPollingCardStatusHandler( h.pollingBase, h.gatewayClient, h.workerResult.Stores.IotCard, h.pollingStopResumeSvc) h.mux.HandleFunc(constants.TaskTypePollingRealname, realnameHandler.Handle) h.mux.HandleFunc(constants.TaskTypePollingCarddata, carddataHandler.Handle) h.mux.HandleFunc(constants.TaskTypePollingPackage, packageHandler.Handle) h.mux.HandleFunc(constants.TaskTypePollingProtect, protectHandler.Handle) h.mux.HandleFunc(constants.TaskTypePollingCardStatus, cardStatusHandler.Handle) h.logger.Info("已注册轮询任务处理器(realname/carddata/package/protect/card_status)") } func (h *Handler) registerPackageActivationHandlers() { packageActivationHandler := polling.NewPackageActivationHandler( h.db, h.redis, h.asynqClient, h.workerResult.Services.ActivationService, nil, h.logger, ) h.mux.HandleFunc(constants.TaskTypePackageFirstActivation, packageActivationHandler.HandlePackageFirstActivation) h.logger.Info("注册首次实名激活任务处理器", zap.String("task_type", constants.TaskTypePackageFirstActivation)) h.mux.HandleFunc(constants.TaskTypePackageQueueActivation, packageActivationHandler.HandlePackageQueueActivation) h.logger.Info("注册排队激活任务处理器", zap.String("task_type", constants.TaskTypePackageQueueActivation)) } func (h *Handler) registerOrderExpireHandler() { orderExpireHandler := task.NewOrderExpireHandler(h.workerResult.Services.OrderExpirer, h.logger) h.mux.HandleFunc(constants.TaskTypeOrderExpire, orderExpireHandler.HandleOrderExpire) h.logger.Info("注册订单超时取消任务处理器", zap.String("task_type", constants.TaskTypeOrderExpire)) } func (h *Handler) registerAlertCheckHandler() { alertCheckHandler := task.NewAlertCheckHandler(h.workerResult.Services.AlertService, h.logger) h.mux.HandleFunc(constants.TaskTypeAlertCheck, alertCheckHandler.HandleAlertCheck) h.logger.Info("注册告警检查任务处理器", zap.String("task_type", constants.TaskTypeAlertCheck)) } func (h *Handler) registerDataCleanupHandler() { dataCleanupHandler := task.NewDataCleanupHandler(h.workerResult.Services.CleanupService, h.logger) h.mux.HandleFunc(constants.TaskTypeDataCleanup, dataCleanupHandler.HandleDataCleanup) h.logger.Info("注册数据清理任务处理器", zap.String("task_type", constants.TaskTypeDataCleanup)) } func (h *Handler) registerAutoPurchaseHandler() { autoPurchaseHandler := task.NewAutoPurchaseHandler( h.db, h.workerResult.Stores.Order, nil, // RechargeOrderStore:在 NewAutoPurchaseHandler 内按需初始化 nil, // PaymentStore:在 NewAutoPurchaseHandler 内按需初始化 h.workerResult.Stores.AssetWallet, nil, // AssetWalletTransactionStore:在 NewAutoPurchaseHandler 内按需初始化 h.workerResult.Stores.PackageUsage, h.redis, h.asynqClient, h.logger, ) h.mux.HandleFunc(constants.TaskTypeAutoPurchaseAfterRecharge, autoPurchaseHandler.ProcessTask) h.logger.Info("注册自动购包任务处理器", zap.String("task_type", constants.TaskTypeAutoPurchaseAfterRecharge)) } func (h *Handler) registerDailyTrafficFlushHandler() { cardDailyUsageStore := postgres.NewCardDailyUsageStore(h.db) dailyTrafficFlushHandler := task.NewDailyTrafficFlushHandler(h.redis, cardDailyUsageStore, h.logger) h.mux.HandleFunc(constants.TaskTypeDailyTrafficFlush, dailyTrafficFlushHandler.HandleDailyTrafficFlush) h.logger.Info("注册每日流量落盘任务处理器", zap.String("task_type", constants.TaskTypeDailyTrafficFlush)) } // GetMux 获取 ServeMux(用于启动 Worker 服务器) func (h *Handler) GetMux() *asynq.ServeMux { return h.mux }