package service import ( "strings" roomeventsv1 "hyapp.local/api/proto/events/room/v1" roomv1 "hyapp.local/api/proto/room/v1" walletv1 "hyapp.local/api/proto/wallet/v1" "hyapp/services/room-service/internal/room/command" ) func buildSendGiftBatchDisplay(cmd command.SendGift, billing *walletv1.DebitGiftResponse, targetBillings []giftTargetBilling, targetCurrentGiftValues map[int64]int64, luckyGifts []*roomv1.LuckyGiftDrawResult, roomHeat int64) *roomv1.SendGiftBatchDisplay { displayBilling := giftBillingForDisplay(billing, targetBillings) targets := make([]*roomv1.SendGiftBatchTarget, 0, len(targetBillings)) luckyByTarget := luckyGiftResultsByTarget(luckyGifts) targetUserIDs := make([]int64, 0, len(targetBillings)) for _, targetBilling := range targetBillings { if targetBilling.TargetUserID <= 0 || targetBilling.Billing == nil { continue } targetDisplayProfile := giftDisplayProfileForUser(cmd.TargetDisplayProfiles, targetBilling.TargetUserID) targetUserIDs = append(targetUserIDs, targetBilling.TargetUserID) targets = append(targets, &roomv1.SendGiftBatchTarget{ TargetUserId: targetBilling.TargetUserID, ReceiverNickname: giftDisplayName(targetDisplayProfile), ReceiverAvatar: strings.TrimSpace(targetDisplayProfile.Avatar), ReceiverDisplayUserId: strings.TrimSpace(targetDisplayProfile.DisplayUserID), ReceiverPrettyDisplayUserId: strings.TrimSpace(targetDisplayProfile.PrettyDisplayUserID), GiftValue: targetBilling.Billing.GetHeatValue(), TargetGiftValue: targetCurrentGiftValues[targetBilling.TargetUserID], CoinSpent: targetBilling.Billing.GetCoinSpent(), BillingReceiptId: targetBilling.Billing.GetBillingReceiptId(), CommandId: targetBilling.CommandID, LuckyGift: luckyByTarget[targetBilling.TargetUserID], }) } if len(targetUserIDs) == 0 { targetUserIDs = append(targetUserIDs, cmd.TargetUserIDs...) } return &roomv1.SendGiftBatchDisplay{ SenderUserId: cmd.ActorUserID(), SenderName: giftDisplayName(cmd.SenderDisplayProfile), SenderAvatar: strings.TrimSpace(cmd.SenderDisplayProfile.Avatar), SenderDisplayUserId: strings.TrimSpace(cmd.SenderDisplayProfile.DisplayUserID), SenderPrettyDisplayUserId: strings.TrimSpace(cmd.SenderDisplayProfile.PrettyDisplayUserID), GiftId: cmd.GiftID, GiftCount: cmd.GiftCount, TotalGiftValue: sumTargetGiftValue(targetBillings), TotalCoinSpent: sumTargetCoinSpent(targetBillings, billing), BillingReceiptId: firstNonEmpty(displayBilling.GetBillingReceiptId(), cmd.BillingReceiptID), RoomHeat: roomHeat, PoolId: cmd.PoolID, GiftTypeCode: displayBilling.GetGiftTypeCode(), CpRelationType: displayBilling.GetCpRelationType(), GiftName: displayBilling.GetGiftName(), GiftIconUrl: displayBilling.GetGiftIconUrl(), GiftAnimationUrl: displayBilling.GetGiftAnimationUrl(), GiftEffectTypes: displayBilling.GetGiftEffectTypes(), TargetUserIds: targetUserIDs, Targets: targets, CommandId: cmd.ID(), } } func roomGiftBatchSentEventFromDisplay(display *roomv1.SendGiftBatchDisplay, visibleRegionID int64) *roomeventsv1.RoomGiftBatchSent { if display == nil { return nil } targets := make([]*roomeventsv1.RoomGiftBatchTarget, 0, len(display.GetTargets())) for _, target := range display.GetTargets() { if target == nil { continue } targets = append(targets, &roomeventsv1.RoomGiftBatchTarget{ TargetUserId: target.GetTargetUserId(), ReceiverNickname: target.GetReceiverNickname(), ReceiverAvatar: target.GetReceiverAvatar(), ReceiverDisplayUserId: target.GetReceiverDisplayUserId(), ReceiverPrettyDisplayUserId: target.GetReceiverPrettyDisplayUserId(), GiftValue: target.GetGiftValue(), TargetGiftValue: target.GetTargetGiftValue(), CoinSpent: target.GetCoinSpent(), BillingReceiptId: target.GetBillingReceiptId(), CommandId: target.GetCommandId(), LuckyGift: roomGiftBatchLuckyResultFromRoom(target.GetLuckyGift()), }) } return &roomeventsv1.RoomGiftBatchSent{ SenderUserId: display.GetSenderUserId(), SenderName: display.GetSenderName(), SenderAvatar: display.GetSenderAvatar(), SenderDisplayUserId: display.GetSenderDisplayUserId(), SenderPrettyDisplayUserId: display.GetSenderPrettyDisplayUserId(), GiftId: display.GetGiftId(), GiftCount: display.GetGiftCount(), TotalGiftValue: display.GetTotalGiftValue(), TotalCoinSpent: display.GetTotalCoinSpent(), BillingReceiptId: display.GetBillingReceiptId(), RoomHeat: display.GetRoomHeat(), PoolId: display.GetPoolId(), GiftTypeCode: display.GetGiftTypeCode(), CpRelationType: display.GetCpRelationType(), GiftName: display.GetGiftName(), GiftIconUrl: display.GetGiftIconUrl(), GiftAnimationUrl: display.GetGiftAnimationUrl(), GiftEffectTypes: display.GetGiftEffectTypes(), TargetUserIds: display.GetTargetUserIds(), Targets: targets, CommandId: display.GetCommandId(), VisibleRegionId: visibleRegionID, } } func roomGiftBatchLuckyResultFromRoom(result *roomv1.LuckyGiftDrawResult) *roomeventsv1.RoomGiftBatchLuckyResult { if result == nil { return nil } return &roomeventsv1.RoomGiftBatchLuckyResult{ Enabled: result.GetEnabled(), DrawId: result.GetDrawId(), CommandId: result.GetCommandId(), PoolId: result.GetPoolId(), GiftId: result.GetGiftId(), RuleVersion: result.GetRuleVersion(), ExperiencePool: result.GetExperiencePool(), SelectedTierId: result.GetSelectedTierId(), MultiplierPpm: result.GetMultiplierPpm(), BaseRewardCoins: result.GetBaseRewardCoins(), EffectiveRewardCoins: result.GetEffectiveRewardCoins(), RewardStatus: result.GetRewardStatus(), StageFeedback: result.GetStageFeedback(), HighMultiplier: result.GetHighMultiplier(), CreatedAtMs: result.GetCreatedAtMs(), TargetUserId: result.GetTargetUserId(), } } func luckyGiftResultsByTarget(results []*roomv1.LuckyGiftDrawResult) map[int64]*roomv1.LuckyGiftDrawResult { byTarget := make(map[int64]*roomv1.LuckyGiftDrawResult, len(results)) for _, result := range results { if result == nil || result.GetTargetUserId() <= 0 { continue } byTarget[result.GetTargetUserId()] = result } return byTarget } func giftBillingForDisplay(billing *walletv1.DebitGiftResponse, targetBillings []giftTargetBilling) *walletv1.DebitGiftResponse { if billing != nil { return billing } for _, targetBilling := range targetBillings { if targetBilling.Billing != nil { return targetBilling.Billing } } return &walletv1.DebitGiftResponse{} } func sumTargetGiftValue(targetBillings []giftTargetBilling) int64 { var total int64 for _, targetBilling := range targetBillings { if targetBilling.Billing != nil { total += targetBilling.Billing.GetHeatValue() } } return total } func sumTargetCoinSpent(targetBillings []giftTargetBilling, billing *walletv1.DebitGiftResponse) int64 { var total int64 for _, targetBilling := range targetBillings { if targetBilling.Billing != nil { total += targetBilling.Billing.GetCoinSpent() } } if total > 0 { return total } if billing == nil { return 0 } return billing.GetCoinSpent() } func roomGiftLeaderboardValue(billing *walletv1.DebitGiftResponse) int64 { if billing == nil { return 0 } // 房间贡献榜跟房间热度、房间内贡献人保持同一口径,使用 wallet 已按全局默认比例折算后的 heat_value。 if billing.GetHeatValue() > 0 { return billing.GetHeatValue() } return 0 }