修复火箭内容
This commit is contained in:
parent
ffd3eeddfd
commit
463d7374af
@ -83,7 +83,19 @@ func registerVoiceRoomRocketRoutes(
|
||||
appGroup.GET("/reward-records", func(c *gin.Context) {
|
||||
cursor, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("cursor", "1")))
|
||||
limit, _ := strconv.Atoi(strings.TrimSpace(c.DefaultQuery("limit", "20")))
|
||||
resp, err := service.PageRewardRecords(c.Request.Context(), mustAuthUser(c), parseInt64(c.Query("roomId")), cursor, limit)
|
||||
user := mustAuthUser(c)
|
||||
roomID := parseInt64(c.Query("roomId"))
|
||||
launchNo := strings.TrimSpace(c.Query("launchNo"))
|
||||
scope := strings.ToLower(strings.TrimSpace(c.Query("scope")))
|
||||
var (
|
||||
resp *voiceroomrocket.RewardRecordPageResponse
|
||||
err error
|
||||
)
|
||||
if launchNo != "" || scope == "room" {
|
||||
resp, err = service.PageRoomRewardRecords(c.Request.Context(), user, roomID, launchNo, cursor, limit)
|
||||
} else {
|
||||
resp, err = service.PageRewardRecords(c.Request.Context(), user, roomID, cursor, limit)
|
||||
}
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
|
||||
@ -109,6 +109,103 @@ func TestProcessGiftPayloadDropsOverflowAndLaunchesOnce(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPageRoomRewardRecordsReturnsAllLaunchWinnersWithProfiles(t *testing.T) {
|
||||
service, db := newTestService(t)
|
||||
ctx := context.Background()
|
||||
gateway := newFakeRocketGateway()
|
||||
gateway.profiles = map[int64]integration.UserProfile{
|
||||
1001: {ID: integration.Int64Value(1001), Account: "1001026", UserNickname: "room1001026", UserAvatar: "https://avatar.example/1001.png"},
|
||||
1002: {ID: integration.Int64Value(1002), Account: "1001027", UserNickname: "room1001027", UserAvatar: "https://avatar.example/1002.png"},
|
||||
}
|
||||
service.userProfiles = gateway
|
||||
seedRocketConfig(t, db)
|
||||
|
||||
now := time.Now()
|
||||
launch := model.VoiceRoomRocketLaunch{
|
||||
ID: 1,
|
||||
LaunchNo: "VRR-test-launch-1",
|
||||
SysOrigin: "LIKEI",
|
||||
RoomID: 9001,
|
||||
DayKey: "2026-05-15",
|
||||
RoundNo: 1,
|
||||
Level: 3,
|
||||
LaunchTime: now,
|
||||
CreateTime: now,
|
||||
UpdateTime: now,
|
||||
}
|
||||
if err := db.Create(&launch).Error; err != nil {
|
||||
t.Fatalf("create launch: %v", err)
|
||||
}
|
||||
rewardItemID := int64(2001)
|
||||
expireDays := 15
|
||||
rows := []model.VoiceRoomRocketRewardRecord{
|
||||
{
|
||||
ID: 11,
|
||||
LaunchID: launch.ID,
|
||||
LaunchNo: launch.LaunchNo,
|
||||
SysOrigin: "LIKEI",
|
||||
RoomID: launch.RoomID,
|
||||
DayKey: launch.DayKey,
|
||||
RoundNo: launch.RoundNo,
|
||||
Level: launch.Level,
|
||||
UserID: 1001,
|
||||
RewardScene: rewardSceneTop1,
|
||||
RewardType: "GOLD",
|
||||
RewardName: "Yumi",
|
||||
RewardAmount: 5000,
|
||||
GrantEventID: "grant-event-11",
|
||||
GrantStatus: rewardStatusSuccess,
|
||||
PopupStatus: popupStatusUnread,
|
||||
CreateTime: now,
|
||||
UpdateTime: now,
|
||||
},
|
||||
{
|
||||
ID: 12,
|
||||
LaunchID: launch.ID,
|
||||
LaunchNo: launch.LaunchNo,
|
||||
SysOrigin: "LIKEI",
|
||||
RoomID: launch.RoomID,
|
||||
DayKey: launch.DayKey,
|
||||
RoundNo: launch.RoundNo,
|
||||
Level: launch.Level,
|
||||
UserID: 1002,
|
||||
RewardScene: rewardSceneInRoom,
|
||||
RewardType: "AVATAR_FRAME",
|
||||
RewardItemID: &rewardItemID,
|
||||
RewardName: "Frame",
|
||||
RewardCover: "https://reward.example/frame.png",
|
||||
RewardAmount: 1,
|
||||
ExpireDays: &expireDays,
|
||||
GrantEventID: "grant-event-12",
|
||||
GrantStatus: rewardStatusSuccess,
|
||||
PopupStatus: popupStatusUnread,
|
||||
CreateTime: now.Add(time.Second),
|
||||
UpdateTime: now.Add(time.Second),
|
||||
},
|
||||
}
|
||||
if err := db.Create(&rows).Error; err != nil {
|
||||
t.Fatalf("create reward records: %v", err)
|
||||
}
|
||||
|
||||
resp, err := service.PageRoomRewardRecords(ctx, AuthUser{UserID: 9999, SysOrigin: "LIKEI"}, launch.RoomID, launch.LaunchNo, 1, 20)
|
||||
if err != nil {
|
||||
t.Fatalf("PageRoomRewardRecords() error = %v", err)
|
||||
}
|
||||
if len(resp.Records) != 2 {
|
||||
t.Fatalf("records len = %d, want 2: %+v", len(resp.Records), resp.Records)
|
||||
}
|
||||
users := map[int64]RewardRecordView{}
|
||||
for _, record := range resp.Records {
|
||||
users[record.UserID] = record
|
||||
}
|
||||
if got := users[1001]; got.Account != "1001026" || got.UserNickname != "room1001026" || got.UserAvatar == "" {
|
||||
t.Fatalf("user 1001 profile = %+v", got)
|
||||
}
|
||||
if got := users[1002]; got.Account != "1001027" || got.UserNickname != "room1001027" || got.UserAvatar == "" {
|
||||
t.Fatalf("user 1002 profile = %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeGiftEventPayloadEnvelope(t *testing.T) {
|
||||
payload := `{"tag":"give_gift_v3","body":"{\"trackId\":\"t1\",\"sendUserId\":\"10\",\"roomId\":\"20\",\"giftValue\":{\"actualAmount\":\"30\"}}"}`
|
||||
event, err := decodeGiftEventPayload(payload, "give_gift_v3")
|
||||
@ -745,6 +842,7 @@ type fakeRocketGateway struct {
|
||||
goldEvents map[string]integration.GoldReceiptCommand
|
||||
props []integration.GivePropsBackpackRequest
|
||||
badges []fakeBadgeGrant
|
||||
profiles map[int64]integration.UserProfile
|
||||
}
|
||||
|
||||
type fakeBadgeGrant struct {
|
||||
@ -790,6 +888,12 @@ func (g *fakeRocketGateway) MapRoomProfiles(ctx context.Context, roomIDs []int64
|
||||
}
|
||||
|
||||
func (g *fakeRocketGateway) GetUserProfile(ctx context.Context, userID int64) (integration.UserProfile, error) {
|
||||
if profile, ok := g.profiles[userID]; ok {
|
||||
if int64(profile.ID) == 0 {
|
||||
profile.ID = integration.Int64Value(userID)
|
||||
}
|
||||
return profile, nil
|
||||
}
|
||||
return integration.UserProfile{ID: integration.Int64Value(userID), Account: strconv.FormatInt(userID, 10), UserNickname: "user", CountryCode: "SA"}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -333,6 +333,30 @@ func toRewardRecordView(row model.VoiceRoomRocketRewardRecord) RewardRecordView
|
||||
}
|
||||
}
|
||||
|
||||
func toRewardRecordViews(rows []model.VoiceRoomRocketRewardRecord, profiles map[int64]integration.UserProfile) []RewardRecordView {
|
||||
records := make([]RewardRecordView, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
view := toRewardRecordView(row)
|
||||
if profile, ok := profiles[row.UserID]; ok {
|
||||
applyRewardRecordProfile(&view, profile)
|
||||
}
|
||||
records = append(records, view)
|
||||
}
|
||||
return records
|
||||
}
|
||||
|
||||
func applyRewardRecordProfile(view *RewardRecordView, profile integration.UserProfile) {
|
||||
if strings.TrimSpace(profile.UserAvatar) != "" {
|
||||
view.UserAvatar = profile.UserAvatar
|
||||
}
|
||||
if strings.TrimSpace(profile.UserNickname) != "" {
|
||||
view.UserNickname = profile.UserNickname
|
||||
}
|
||||
if strings.TrimSpace(profile.Account) != "" {
|
||||
view.Account = profile.Account
|
||||
}
|
||||
}
|
||||
|
||||
func toLaunchRecordView(row model.VoiceRoomRocketLaunch) LaunchRecordView {
|
||||
return LaunchRecordView{
|
||||
ID: row.ID,
|
||||
|
||||
@ -3,6 +3,7 @@ package voiceroomrocket
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"chatapp3-golang/internal/model"
|
||||
@ -22,10 +23,7 @@ func (s *Service) ListRewardPopups(ctx context.Context, user AuthUser, roomID in
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
records := make([]RewardRecordView, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
records = append(records, toRewardRecordView(row))
|
||||
}
|
||||
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
|
||||
return &RewardPopupResponse{Records: records}, nil
|
||||
}
|
||||
|
||||
@ -76,10 +74,7 @@ func (s *Service) PageRewardRecords(ctx context.Context, user AuthUser, roomID i
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
records := make([]RewardRecordView, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
records = append(records, toRewardRecordView(row))
|
||||
}
|
||||
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
|
||||
resp := &RewardRecordPageResponse{
|
||||
Records: records,
|
||||
Cursor: cursor,
|
||||
@ -91,6 +86,54 @@ func (s *Service) PageRewardRecords(ctx context.Context, user AuthUser, roomID i
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// PageRoomRewardRecords 返回房间内某次火箭发射的全部中奖记录。
|
||||
func (s *Service) PageRoomRewardRecords(ctx context.Context, user AuthUser, roomID int64, launchNo string, cursor int, limit int) (*RewardRecordPageResponse, error) {
|
||||
cursor, limit = normalizePage(cursor, limit)
|
||||
snapshot, err := s.loadConfig(ctx, user.SysOrigin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keepDays := snapshot.RewardRecordKeepDays
|
||||
if keepDays <= 0 {
|
||||
keepDays = defaultRewardRecordKeepDays
|
||||
}
|
||||
startAt := time.Now().AddDate(0, 0, -keepDays)
|
||||
launchNo = strings.TrimSpace(launchNo)
|
||||
if launchNo == "" {
|
||||
query := s.repo.DB.WithContext(ctx).
|
||||
Model(&model.VoiceRoomRocketRewardRecord{}).
|
||||
Where("sys_origin = ? AND create_time >= ? AND launch_no <> ?", snapshot.SysOrigin, startAt, "").
|
||||
Order("create_time DESC, id DESC").
|
||||
Limit(1)
|
||||
if roomID > 0 {
|
||||
query = query.Where("room_id = ?", roomID)
|
||||
}
|
||||
var launchNos []string
|
||||
if err := query.Pluck("launch_no", &launchNos).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(launchNos) == 0 {
|
||||
return &RewardRecordPageResponse{Records: []RewardRecordView{}, Cursor: cursor, Limit: limit}, nil
|
||||
}
|
||||
launchNo = launchNos[0]
|
||||
}
|
||||
|
||||
query := s.repo.DB.WithContext(ctx).
|
||||
Where("sys_origin = ? AND launch_no = ? AND create_time >= ?", snapshot.SysOrigin, launchNo, startAt).
|
||||
Order("create_time DESC, id DESC").
|
||||
Offset((cursor - 1) * limit).
|
||||
Limit(limit)
|
||||
if roomID > 0 {
|
||||
query = query.Where("room_id = ?", roomID)
|
||||
}
|
||||
var rows []model.VoiceRoomRocketRewardRecord
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
|
||||
return &RewardRecordPageResponse{Records: records, Cursor: cursor, Limit: limit}, nil
|
||||
}
|
||||
|
||||
// PageAdminLaunchRecords 返回后台发射记录。
|
||||
func (s *Service) PageAdminLaunchRecords(ctx context.Context, sysOrigin string, roomID int64, cursor int, limit int) (*LaunchRecordPageResponse, error) {
|
||||
cursor, limit = normalizePage(cursor, limit)
|
||||
@ -134,9 +177,22 @@ func (s *Service) PageAdminRewardRecords(ctx context.Context, sysOrigin string,
|
||||
if err := query.Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
records := make([]RewardRecordView, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
records = append(records, toRewardRecordView(row))
|
||||
}
|
||||
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
|
||||
return &RewardRecordPageResponse{Records: records, Cursor: cursor, Limit: limit}, nil
|
||||
}
|
||||
|
||||
func rewardRecordUserIDs(rows []model.VoiceRoomRocketRewardRecord) []int64 {
|
||||
seen := make(map[int64]struct{}, len(rows))
|
||||
userIDs := make([]int64, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
if row.UserID <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[row.UserID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[row.UserID] = struct{}{}
|
||||
userIDs = append(userIDs, row.UserID)
|
||||
}
|
||||
return userIDs
|
||||
}
|
||||
|
||||
@ -457,6 +457,9 @@ type RewardRecordView struct {
|
||||
RoundNo int `json:"roundNo"`
|
||||
Level int `json:"level"`
|
||||
UserID int64 `json:"userId,string"`
|
||||
UserAvatar string `json:"userAvatar,omitempty"`
|
||||
UserNickname string `json:"userNickname,omitempty"`
|
||||
Account string `json:"account,omitempty"`
|
||||
RewardScene string `json:"rewardScene"`
|
||||
RewardType string `json:"rewardType"`
|
||||
RewardItemID *int64 `json:"rewardItemId,string,omitempty"`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user