2026-07-12 00:47:20 +08:00

84 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"time"
"google.golang.org/protobuf/proto"
roomv1 "hyapp.local/api/proto/room/v1"
"hyapp/pkg/xerr"
"hyapp/services/room-service/internal/room/command"
)
func marshalMutationResult(result mutationResult) ([]byte, error) {
if result.giftV2 == nil {
return nil, nil
}
payload, err := proto.Marshal(result.giftV2)
if err != nil {
return nil, xerr.New(xerr.Internal, "send gift v2 result cannot be encoded")
}
return payload, nil
}
func replayMutationResult(record CommandRecord, snapshot *roomv1.RoomSnapshot) (mutationResult, error) {
result := mutationResult{snapshot: snapshot}
if record.CommandType != (command.SendGift{}).Type() || len(record.ResultPayload) == 0 {
// 历史命令没有 typed result继续返回当前 snapshot保持 V1 已上线行为,不伪造账务字段。
return result, nil
}
var stored roomv1.SendGiftResultV2
if err := proto.Unmarshal(record.ResultPayload, &stored); err != nil {
// 已提交结果损坏时必须 fail-close不能重跑 wallet 或幸运礼物来“修复”一个已提交命令。
return mutationResult{}, xerr.New(xerr.Internal, "stored send gift result cannot be decoded")
}
replayed := proto.Clone(&stored).(*roomv1.SendGiftResultV2)
replayed.IdempotentReplay = true
replayed.OperationStatus = GiftOperationStatusCommitted
result.billingReceiptID = replayed.GetBillingReceiptId()
result.coinBalanceAfter = replayed.GetCoinBalanceAfter()
result.giftIncomeBalanceAfter = replayed.GetGiftIncomeBalanceAfter()
result.roomHeat = replayed.GetRoomHeat()
result.giftRank = cloneGiftRankItems(replayed.GetGiftRank())
result.luckyGift = replayed.GetLuckyGift()
result.luckyGifts = append([]*roomv1.LuckyGiftDrawResult(nil), replayed.GetLuckyGifts()...)
result.batchDisplay = replayed.GetBatchDisplay()
result.giftV2 = replayed
return result, nil
}
func cloneGiftRankItems(items []*roomv1.RankItem) []*roomv1.RankItem {
out := make([]*roomv1.RankItem, 0, len(items))
for _, item := range items {
if item != nil {
out = append(out, proto.Clone(item).(*roomv1.RankItem))
}
}
return out
}
func luckyHitsFromResults(results []*roomv1.LuckyGiftDrawResult) []*roomv1.SendGiftLuckyHit {
hits := make([]*roomv1.SendGiftLuckyHit, 0)
for _, result := range results {
if result == nil {
continue
}
for _, hit := range result.GetHits() {
if hit != nil && hit.GetRewardCoins() > 0 {
hits = append(hits, proto.Clone(hit).(*roomv1.SendGiftLuckyHit))
}
}
}
return hits
}
func giftOperationCommitForResult(cmd command.Command, resultPayload []byte, now time.Time) *GiftOperationCommit {
if cmd == nil || cmd.Type() != (command.SendGift{}).Type() || len(resultPayload) == 0 {
return nil
}
return &GiftOperationCommit{
CommandID: cmd.ID(),
ResultPayload: resultPayload,
UpdatedAtMS: now.UnixMilli(),
}
}