package app import ( "errors" roomv1 "hyapp.local/api/proto/room/v1" walletv1 "hyapp.local/api/proto/wallet/v1" "hyapp/pkg/tencentim" activityclient "hyapp/services/activity-service/internal/client" "hyapp/services/activity-service/internal/config" achievementservice "hyapp/services/activity-service/internal/service/achievement" activityservice "hyapp/services/activity-service/internal/service/activity" broadcastservice "hyapp/services/activity-service/internal/service/broadcast" cumulativerechargeservice "hyapp/services/activity-service/internal/service/cumulativerecharge" firstrechargeservice "hyapp/services/activity-service/internal/service/firstrecharge" growthservice "hyapp/services/activity-service/internal/service/growth" luckygiftservice "hyapp/services/activity-service/internal/service/luckygift" messageservice "hyapp/services/activity-service/internal/service/message" registrationrewardservice "hyapp/services/activity-service/internal/service/registrationreward" roomturnoverrewardservice "hyapp/services/activity-service/internal/service/roomturnoverreward" sevendaycheckinservice "hyapp/services/activity-service/internal/service/sevendaycheckin" taskservice "hyapp/services/activity-service/internal/service/task" weeklystarservice "hyapp/services/activity-service/internal/service/weeklystar" mysqlstorage "hyapp/services/activity-service/internal/storage/mysql" ) type serviceBundle struct { activity *activityservice.Service message *messageservice.Service task *taskservice.Service registrationReward *registrationrewardservice.Service sevenDayCheckIn *sevendaycheckinservice.Service growth *growthservice.Service achievement *achievementservice.Service weeklyStar *weeklystarservice.Service roomTurnoverReward *roomturnoverrewardservice.Service broadcast *broadcastservice.Service luckyGift *luckygiftservice.Service firstRechargeReward *firstrechargeservice.Service cumulativeRecharge *cumulativerechargeservice.Service broadcastPublisherAvailable bool } func buildServiceBundle(cfg config.Config, repository *mysqlstorage.Repository, clients externalClients) (*serviceBundle, error) { walletClient := walletv1.NewWalletServiceClient(clients.walletConn) roomClient := roomv1.NewRoomQueryServiceClient(clients.roomConn) activitySvc := activityservice.New(activityservice.Config{NodeID: cfg.NodeID}, repository) messageSvc := messageservice.New(messageservice.Config{NodeID: cfg.NodeID}, repository, messageservice.WithTargetSource(activityclient.NewGRPCUserTargetSource(clients.userConn))) taskSvc := taskservice.New(repository, walletClient) registrationRewardSvc := registrationrewardservice.New(repository, walletClient) sevenDayCheckInSvc := sevendaycheckinservice.New(repository, walletClient) growthSvc := growthservice.New(repository, walletClient) achievementSvc := achievementservice.New(repository, walletClient) weeklyStarSvc := weeklystarservice.New(repository, walletClient) roomTurnoverRewardSvc := roomturnoverrewardservice.New(repository, walletClient, roomClient) // Tencent IM 是区域广播、房间礼物播报和红包播报的外部发布器。 // 如果配置要求启动广播 worker,就必须先确认 publisher 可用,避免 worker 启动后只写 outbox 不发消息。 var tencentClient *tencentim.RESTClient var broadcastPublisher broadcastservice.Publisher if cfg.TencentIM.Enabled { client, err := tencentim.NewRESTClient(cfg.TencentIM.RESTConfig()) if err != nil { return nil, err } tencentClient = client broadcastPublisher = client } if cfg.Broadcast.Enabled && broadcastPublisher == nil { return nil, errors.New("broadcast worker requires tencent_im.enabled") } broadcastSvc := broadcastservice.New(broadcastservice.Config{ NodeID: cfg.NodeID, SuperGiftMinValue: cfg.Broadcast.SuperGiftMinValue, WorkerBatchSize: cfg.Broadcast.WorkerBatchSize, WorkerLockTTL: cfg.Broadcast.WorkerLockTTL, WorkerMaxRetry: cfg.Broadcast.WorkerMaxRetry, WorkerPollInterval: cfg.Broadcast.WorkerPollInterval, EnsureGroupsOnStartup: cfg.Broadcast.EnsureGroupsOnStartup, GroupIDPrefix: cfg.TencentIM.GroupIDPrefix, }, repository, broadcastPublisher, activityclient.NewGRPCRegionSource(clients.userConn)) broadcastSvc.SetSenderProfileSource(activityclient.NewGRPCUserProfileSource(clients.userConn)) luckyGiftSvc := luckygiftservice.New(repository, luckygiftservice.WithWallet(walletClient), luckygiftservice.WithRoomPublisher(tencentClient), luckygiftservice.WithRegionBroadcaster(broadcastSvc), ) firstRechargeRewardSvc := firstrechargeservice.New(repository, walletClient) cumulativeRechargeSvc := cumulativerechargeservice.New(repository, walletClient) return &serviceBundle{ activity: activitySvc, message: messageSvc, task: taskSvc, registrationReward: registrationRewardSvc, sevenDayCheckIn: sevenDayCheckInSvc, growth: growthSvc, achievement: achievementSvc, weeklyStar: weeklyStarSvc, roomTurnoverReward: roomTurnoverRewardSvc, broadcast: broadcastSvc, luckyGift: luckyGiftSvc, firstRechargeReward: firstRechargeRewardSvc, cumulativeRecharge: cumulativeRechargeSvc, broadcastPublisherAvailable: broadcastPublisher != nil, }, nil }