From 1abc344d052c8f88d4c229447b6b361be98305b0 Mon Sep 17 00:00:00 2001 From: hy001 Date: Fri, 15 May 2026 16:50:04 +0800 Subject: [PATCH] fix: show rocket gold rewards in asset records --- .../service/voiceroomrocket/event_test.go | 46 +++++++++++++++++++ internal/service/voiceroomrocket/reward.go | 26 +++++++++-- internal/service/voiceroomrocket/types.go | 3 ++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/internal/service/voiceroomrocket/event_test.go b/internal/service/voiceroomrocket/event_test.go index 39dae01..01ee1ad 100644 --- a/internal/service/voiceroomrocket/event_test.go +++ b/internal/service/voiceroomrocket/event_test.go @@ -336,6 +336,52 @@ func TestPickInRoomRewardCanBeEmpty(t *testing.T) { } } +func TestGrantGoldRewardUsesWalletRocketRewardOrigin(t *testing.T) { + service, _ := newTestService(t) + gateway := newFakeRocketGateway() + service.wallet = gateway + record := model.VoiceRoomRocketRewardRecord{ + UserID: 1001, + SysOrigin: "LIKEI", + Level: 1, + RewardScene: rewardSceneInRoom, + RewardType: rewardTypeGold, + RewardAmount: 100, + GrantEventID: "VOICE_ROOM_ROCKET:launch-1:IN_ROOM:1001:1", + } + + if err := service.grantGoldReward(context.Background(), record); err != nil { + t.Fatalf("grantGoldReward() error = %v", err) + } + walletEventID := walletGoldRewardEventID(record.GrantEventID) + cmd, ok := gateway.goldEvents[walletEventID] + if !ok { + t.Fatalf("gold wallet event was not created") + } + if len(cmd.EventID) > 50 { + t.Fatalf("wallet event id length = %d, want <= 50: %s", len(cmd.EventID), cmd.EventID) + } + if cmd.Origin != walletOriginRocketReward { + t.Fatalf("wallet origin = %q, want %q", cmd.Origin, walletOriginRocketReward) + } + if cmd.CustomizeOrigin != "" { + t.Fatalf("customize origin = %q, want empty", cmd.CustomizeOrigin) + } + if cmd.CustomizeOriginDesc != walletOriginRocketRewardDesc { + t.Fatalf("wallet origin desc = %q, want %q", cmd.CustomizeOriginDesc, walletOriginRocketRewardDesc) + } +} + +func TestRewardGrantEventIDFitsWalletAssetRecord(t *testing.T) { + eventID := rewardGrantEventID("VOICE_ROOM_ROCKET_LAUNCH:20260515:9001:ROUND:1:LEVEL:6:EXTRA-LONG", rewardSceneInRoom, 1001001001001, 9009009009001) + if len(eventID) > 50 { + t.Fatalf("grant event id length = %d, want <= 50: %s", len(eventID), eventID) + } + if eventID != rewardGrantEventID("VOICE_ROOM_ROCKET_LAUNCH:20260515:9001:ROUND:1:LEVEL:6:EXTRA-LONG", rewardSceneInRoom, 1001001001001, 9009009009001) { + t.Fatalf("grant event id must be deterministic") + } +} + func TestInRoomRewardCopiesLimitSelection(t *testing.T) { service, _ := newTestService(t) service.cfg.VoiceRoomRocket.InRoomRewardUserLimit = 10 diff --git a/internal/service/voiceroomrocket/reward.go b/internal/service/voiceroomrocket/reward.go index 6fcd1f8..f468309 100644 --- a/internal/service/voiceroomrocket/reward.go +++ b/internal/service/voiceroomrocket/reward.go @@ -2,6 +2,7 @@ package voiceroomrocket import ( "context" + "crypto/sha1" "errors" "fmt" "net/http" @@ -187,7 +188,8 @@ func (s *Service) grantGoldReward(ctx context.Context, row model.VoiceRoomRocket if s.wallet == nil { return NewAppError(http.StatusServiceUnavailable, "wallet_unavailable", "wallet gateway is unavailable") } - exists, err := s.wallet.ExistsGoldEvent(ctx, row.GrantEventID) + walletEventID := walletGoldRewardEventID(row.GrantEventID) + exists, err := s.wallet.ExistsGoldEvent(ctx, walletEventID) if err != nil { return err } @@ -196,13 +198,13 @@ func (s *Service) grantGoldReward(ctx context.Context, row model.VoiceRoomRocket ReceiptType: "INCOME", UserID: row.UserID, SysOrigin: row.SysOrigin, - EventID: row.GrantEventID, + EventID: walletEventID, Remark: fmt.Sprintf("voice room rocket %s level %d", row.RewardScene, row.Level), Amount: integration.NewPennyAmountPayloadFromDollar(row.RewardAmount), CloseDelayAsset: true, OpUserType: "BACK", - CustomizeOrigin: "VOICE_ROOM_ROCKET", - CustomizeOriginDesc: "Voice Room Rocket Reward", + Origin: walletOriginRocketReward, + CustomizeOriginDesc: walletOriginRocketRewardDesc, }); err != nil { return err } @@ -341,5 +343,19 @@ func (s *Service) acquireRewardLock(ctx context.Context, rewardRecordID int64) ( } func rewardGrantEventID(launchNo, scene string, userID int64, rewardConfigID int64) string { - return fmt.Sprintf("VOICE_ROOM_ROCKET:%s:%s:%d:%d", launchNo, strings.ToUpper(strings.TrimSpace(scene)), userID, rewardConfigID) + raw := fmt.Sprintf("%s:%s:%d:%d", launchNo, strings.ToUpper(strings.TrimSpace(scene)), userID, rewardConfigID) + return "VRR:" + hashString(raw) +} + +func walletGoldRewardEventID(grantEventID string) string { + grantEventID = strings.TrimSpace(grantEventID) + if len(grantEventID) > 0 && len(grantEventID) <= 50 { + return grantEventID + } + return "VRR:" + hashString(grantEventID) +} + +func hashString(value string) string { + sum := sha1.Sum([]byte(value)) + return fmt.Sprintf("%x", sum) } diff --git a/internal/service/voiceroomrocket/types.go b/internal/service/voiceroomrocket/types.go index 17ba6b2..0d3352b 100644 --- a/internal/service/voiceroomrocket/types.go +++ b/internal/service/voiceroomrocket/types.go @@ -77,6 +77,9 @@ const ( propsTypeGift = "GIFT" propsTypeBadge = "BADGE" + walletOriginRocketReward = "ROCKET_REWARD" + walletOriginRocketRewardDesc = "Rocket reward" + imTypeStatusUpdate = "VOICE_ROOM_ROCKET_STATUS_UPDATE" imTypeLaunchBroadcast = "VOICE_ROOM_ROCKET_LAUNCH_BROADCAST" imTypeRewardPopup = "VOICE_ROOM_ROCKET_REWARD_POPUP"