修复周星

This commit is contained in:
hy001 2026-04-30 20:53:40 +08:00
parent d76a11f62f
commit dc6f15369c
4 changed files with 147 additions and 4 deletions

View File

@ -217,7 +217,7 @@ func Load() Config {
AccessSecret: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_ACCESS_SECRET", "WEEK_STAR_ROCKETMQ_ACCESS_SECRET"}, ""),
SecurityToken: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_SECURITY_TOKEN", "WEEK_STAR_ROCKETMQ_SECURITY_TOKEN"}, ""),
ConsumerGroup: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_CONSUMER_GROUP", "WEEK_STAR_ROCKETMQ_CONSUMER_GROUP"}, "week-star-activity"),
Topic: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_TOPIC", "WEEK_STAR_ROCKETMQ_TOPIC"}, "GIVE_GIFTS"),
Topic: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_TOPIC", "WEEK_STAR_ROCKETMQ_TOPIC"}, "RC_DEFAULT_APP_ORDINARY"),
Tag: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_TAG", "WEEK_STAR_ROCKETMQ_TAG"}, "give_gift_v3"),
},
},

View File

@ -97,9 +97,64 @@ func (s *WeekStarService) ProcessGiftPayload(ctx context.Context, payload string
if payload == "" {
return nil
}
var event weekStarGiftEvent
if err := json.Unmarshal([]byte(payload), &event); err != nil {
event, err := decodeWeekStarGiftEventPayload(payload, s.cfg.WeekStar.RocketMQ.Tag)
if err != nil {
return err
}
return s.ProcessGiftEvent(ctx, event, payload)
}
func decodeWeekStarGiftEventPayload(payload string, expectedTag string) (weekStarGiftEvent, error) {
var event weekStarGiftEvent
if err := json.Unmarshal([]byte(payload), &event); err != nil {
return event, err
}
if event.hasBusinessFields() {
return event, nil
}
var envelope weekStarMessageEventEnvelope
if err := json.Unmarshal([]byte(payload), &envelope); err != nil {
return event, err
}
if strings.TrimSpace(expectedTag) != "" &&
strings.TrimSpace(envelope.Tag) != "" &&
strings.TrimSpace(envelope.Tag) != strings.TrimSpace(expectedTag) {
return weekStarGiftEvent{}, nil
}
bodyPayload, ok, err := envelope.bodyPayload()
if err != nil || !ok {
return event, err
}
if err := json.Unmarshal([]byte(bodyPayload), &event); err != nil {
return event, err
}
return event, nil
}
type weekStarMessageEventEnvelope struct {
Tag string `json:"tag"`
Body json.RawMessage `json:"body"`
}
func (e weekStarMessageEventEnvelope) bodyPayload() (string, bool, error) {
raw := strings.TrimSpace(string(e.Body))
if raw == "" || raw == "null" {
return "", false, nil
}
if strings.HasPrefix(raw, "\"") {
var body string
if err := json.Unmarshal(e.Body, &body); err != nil {
return "", false, err
}
body = strings.TrimSpace(body)
return body, body != "", nil
}
return raw, true, nil
}
func (e weekStarGiftEvent) hasBusinessFields() bool {
return strings.TrimSpace(e.TrackID) != "" ||
int64(e.SendUserID) > 0 ||
int64(e.GiftConfig.ID) > 0
}

View File

@ -17,7 +17,7 @@ func TestStartMessageConsumerDoesNotBlockAPIStartup(t *testing.T) {
AccessKey: "test-access-key",
AccessSecret: "test-access-secret",
ConsumerGroup: "week-star-activity-test",
Topic: "GIVE_GIFTS",
Topic: "RC_DEFAULT_APP_ORDINARY",
Tag: "give_gift_v3",
},
},

View File

@ -2,6 +2,7 @@ package weekstar
import (
"context"
"encoding/json"
"testing"
"time"
@ -225,6 +226,93 @@ func TestProcessGiftEventCountsConfiguredNonDefaultSysOrigin(t *testing.T) {
}
}
func TestProcessGiftPayloadUnwrapsJavaMessageEventEnvelope(t *testing.T) {
ctx := context.Background()
service, db := newTestWeekStarService(t)
service.cfg.WeekStar.RocketMQ.Tag = "give_gift_v3"
if err := db.AutoMigrate(&model.WeekStarGiftLog{}); err != nil {
t.Fatalf("auto migrate gift log: %v", err)
}
redisServer := miniredis.RunT(t)
redisClient := redis.NewClient(&redis.Options{Addr: redisServer.Addr()})
defer redisClient.Close()
service.repo.Redis = redisClient
now := time.Now().In(service.location)
cycleStart, cycleEnd := service.cycleBounds(now)
configRow := model.WeekStarActivityConfig{
ID: 104,
SysOrigin: "LIKEI",
Enabled: true,
StartAt: service.toStorageWallClock(cycleStart.Add(-time.Hour)),
EndAt: service.toStorageWallClock(cycleEnd.Add(time.Hour)),
Timezone: "Asia/Riyadh",
CreateTime: now,
UpdateTime: now,
}
if err := db.Create(&configRow).Error; err != nil {
t.Fatalf("create config: %v", err)
}
if err := db.Create(&model.WeekStarActivityGiftConfig{
ConfigID: configRow.ID,
GiftID: 2044977670327955458,
GiftName: "Like",
GiftCandy: 100,
Sort: 1,
}).Error; err != nil {
t.Fatalf("create gift config: %v", err)
}
body, err := json.Marshal(map[string]any{
"trackId": "2049831533035974657",
"sysOrigin": "LIKEI",
"sendUserId": "2042274349343506434",
"quantity": 4,
"createTime": now.UnixMilli(),
"accepts": []map[string]any{
{"acceptUserId": "2042274349343506434"},
},
"giftConfig": map[string]any{
"id": "2044977670327955458",
"giftCandy": "100.00",
"giftName": "Like",
},
})
if err != nil {
t.Fatalf("marshal body: %v", err)
}
payload, err := json.Marshal(map[string]any{
"consumeId": "2049831533035974657",
"topic": "RC_DEFAULT_APP_ORDINARY",
"tag": "give_gift_v3",
"body": string(body),
})
if err != nil {
t.Fatalf("marshal payload: %v", err)
}
if err := service.ProcessGiftPayload(ctx, string(payload)); err != nil {
t.Fatalf("ProcessGiftPayload() error = %v", err)
}
score, err := redisClient.ZScore(ctx, service.rankRedisKey(configRow.ID, service.cycleKey(cycleStart)), "2042274349343506434").Result()
if err != nil {
t.Fatalf("ZScore() error = %v", err)
}
if score != 400 {
t.Fatalf("score = %v, want 400", score)
}
var count int64
if err := db.Model(&model.WeekStarGiftLog{}).
Where("config_id = ? AND send_user_id = ? AND status = ?", configRow.ID, int64(2042274349343506434), weekStarGiftLogStatusSuccess).
Count(&count).Error; err != nil {
t.Fatalf("count gift log: %v", err)
}
if count != 1 {
t.Fatalf("success gift log count = %d, want 1", count)
}
}
func TestCurrentRankingReturnsDisabledWhenNoActiveConfig(t *testing.T) {
service, _ := newTestWeekStarService(t)