77 lines
4.3 KiB
Go
77 lines
4.3 KiB
Go
package service
|
||
|
||
import (
|
||
"strings"
|
||
"time"
|
||
|
||
roomeventsv1 "hyapp.local/api/proto/events/room/v1"
|
||
"hyapp/services/room-service/internal/room/command"
|
||
"hyapp/services/room-service/internal/room/outbox"
|
||
"hyapp/services/room-service/internal/room/state"
|
||
)
|
||
|
||
func buildRoomGiftSentRecords(roomID string, roomVersion int64, now time.Time, cmd command.SendGift, roomMeta RoomMeta, targetBillings []giftTargetBilling, targetCurrentGiftValues map[int64]int64) ([]outbox.Record, error) {
|
||
// RoomGiftSent 是统计、活动、成长任务和房间展示共同消费的送礼事实;构造时必须按目标拆分,不能用 batch 展示消息替代逐目标账务事实。
|
||
records := make([]outbox.Record, 0, len(targetBillings))
|
||
for _, targetBilling := range targetBillings {
|
||
targetDisplayProfile := giftDisplayProfileForUser(cmd.TargetDisplayProfiles, targetBilling.TargetUserID)
|
||
record, err := outbox.Build(roomID, "RoomGiftSent", roomVersion, now, &roomeventsv1.RoomGiftSent{
|
||
SenderUserId: cmd.ActorUserID(),
|
||
TargetUserId: targetBilling.TargetUserID,
|
||
GiftId: cmd.GiftID,
|
||
PoolId: cmd.PoolID,
|
||
GiftCount: cmd.GiftCount,
|
||
GiftValue: targetBilling.Billing.GetHeatValue(),
|
||
CoinSpent: targetBilling.Billing.GetCoinSpent(),
|
||
BillingReceiptId: targetBilling.Billing.GetBillingReceiptId(),
|
||
VisibleRegionId: roomMeta.VisibleRegionID,
|
||
CountryId: cmd.SenderCountryID,
|
||
RegionId: firstNonZeroInt64(cmd.SenderRegionID, roomMeta.VisibleRegionID),
|
||
CommandId: targetBilling.CommandID,
|
||
GiftTypeCode: targetBilling.Billing.GetGiftTypeCode(),
|
||
CpRelationType: targetBilling.Billing.GetCpRelationType(),
|
||
GiftName: targetBilling.Billing.GetGiftName(),
|
||
GiftIconUrl: targetBilling.Billing.GetGiftIconUrl(),
|
||
GiftAnimationUrl: targetBilling.Billing.GetGiftAnimationUrl(),
|
||
TargetGiftValue: targetCurrentGiftValues[targetBilling.TargetUserID],
|
||
SenderName: giftDisplayName(cmd.SenderDisplayProfile),
|
||
SenderAvatar: strings.TrimSpace(cmd.SenderDisplayProfile.Avatar),
|
||
SenderDisplayUserId: strings.TrimSpace(cmd.SenderDisplayProfile.DisplayUserID),
|
||
SenderPrettyDisplayUserId: strings.TrimSpace(cmd.SenderDisplayProfile.PrettyDisplayUserID),
|
||
ReceiverNickname: giftDisplayName(targetDisplayProfile),
|
||
ReceiverAvatar: strings.TrimSpace(targetDisplayProfile.Avatar),
|
||
ReceiverDisplayUserId: strings.TrimSpace(targetDisplayProfile.DisplayUserID),
|
||
ReceiverPrettyDisplayUserId: strings.TrimSpace(targetDisplayProfile.PrettyDisplayUserID),
|
||
// display_mode 只改变房间展示投递策略;逐目标事实仍然进入 durable outbox,保证统计、activity、CP 和礼物墙消费口径不变。
|
||
DisplayMode: strings.TrimSpace(cmd.DisplayMode),
|
||
// effect_types 来自 wallet-service 已锁定的礼物价格配置;room-service 只透传,避免统计和全服广播各自重新判定礼物效果。
|
||
GiftEffectTypes: targetBilling.Billing.GetGiftEffectTypes(),
|
||
IsRobotGift: cmd.RobotWalletGift,
|
||
SyntheticLuckyGift: cmd.SyntheticLuckyGift,
|
||
RealRoomRobotGift: cmd.RobotWalletGift && !cmd.RobotGift,
|
||
})
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
records = append(records, record)
|
||
}
|
||
return records, nil
|
||
}
|
||
|
||
func buildRoomHeatChangedRecord(roomID string, roomVersion int64, now time.Time, heatDelta int64, currentHeat int64) (outbox.Record, error) {
|
||
// 热度事件只服务房间 UI 展示;当前值仍以 Room Cell 快照为准,客户端丢消息后可通过 snapshot 修复。
|
||
return outbox.Build(roomID, "RoomHeatChanged", roomVersion, now, &roomeventsv1.RoomHeatChanged{
|
||
Delta: heatDelta,
|
||
CurrentHeat: currentHeat,
|
||
})
|
||
}
|
||
|
||
func buildRoomRankChangedRecord(roomID string, roomVersion int64, now time.Time, rankItem state.RankItem) (outbox.Record, error) {
|
||
// 榜单事件表达本次送礼后 sender 在本地礼物榜中的新分值;完整榜单仍由快照和榜单读模型兜底。
|
||
return outbox.Build(roomID, "RoomRankChanged", roomVersion, now, &roomeventsv1.RoomRankChanged{
|
||
UserId: rankItem.UserID,
|
||
Score: rankItem.Score,
|
||
GiftValue: rankItem.GiftValue,
|
||
})
|
||
}
|