fix: generate lucky gift tier ids in admin
This commit is contained in:
parent
982ac46415
commit
93e5cd0218
@ -2,6 +2,7 @@ package luckygift
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -227,12 +228,17 @@ func (h *Handler) activityContext(c *gin.Context) (context.Context, context.Canc
|
|||||||
func configToProto(req configRequest) *activityv1.LuckyGiftRuleConfig {
|
func configToProto(req configRequest) *activityv1.LuckyGiftRuleConfig {
|
||||||
stages := make([]*activityv1.LuckyGiftRuleStage, 0, len(req.Stages))
|
stages := make([]*activityv1.LuckyGiftRuleStage, 0, len(req.Stages))
|
||||||
for _, stage := range req.Stages {
|
for _, stage := range req.Stages {
|
||||||
|
stageName := strings.TrimSpace(stage.Stage)
|
||||||
|
tierIDCounts := make(map[string]int, len(stage.Tiers))
|
||||||
tiers := make([]*activityv1.LuckyGiftRuleTier, 0, len(stage.Tiers))
|
tiers := make([]*activityv1.LuckyGiftRuleTier, 0, len(stage.Tiers))
|
||||||
for _, tier := range stage.Tiers {
|
for _, tier := range stage.Tiers {
|
||||||
|
multiplierPPM := multiplierToPPM(tier.Multiplier)
|
||||||
tiers = append(tiers, &activityv1.LuckyGiftRuleTier{
|
tiers = append(tiers, &activityv1.LuckyGiftRuleTier{
|
||||||
Stage: strings.TrimSpace(stage.Stage),
|
Stage: stageName,
|
||||||
TierId: strings.TrimSpace(tier.TierID),
|
// 奖档 ID 是 activity-service 持久化主键的一部分,不能让运营手工维护;admin-server 按阶段和倍率生成稳定 ID,
|
||||||
MultiplierPpm: multiplierToPPM(tier.Multiplier),
|
// 同一阶段同倍率出现多行时追加序号,保证进入 activity-service 前已经满足唯一性。
|
||||||
|
TierId: generatedLuckyGiftTierID(stageName, multiplierPPM, tierIDCounts),
|
||||||
|
MultiplierPpm: multiplierPPM,
|
||||||
BaseWeightPpm: percentToPPM(tier.ProbabilityPercent),
|
BaseWeightPpm: percentToPPM(tier.ProbabilityPercent),
|
||||||
RewardSource: strings.TrimSpace(tier.RewardSource),
|
RewardSource: strings.TrimSpace(tier.RewardSource),
|
||||||
HighWaterOnly: tier.HighWaterOnly,
|
HighWaterOnly: tier.HighWaterOnly,
|
||||||
@ -241,7 +247,7 @@ func configToProto(req configRequest) *activityv1.LuckyGiftRuleConfig {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
stages = append(stages, &activityv1.LuckyGiftRuleStage{
|
stages = append(stages, &activityv1.LuckyGiftRuleStage{
|
||||||
Stage: strings.TrimSpace(stage.Stage),
|
Stage: stageName,
|
||||||
Tiers: tiers,
|
Tiers: tiers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -317,6 +323,29 @@ func configFromProto(config *activityv1.LuckyGiftRuleConfig) configDTO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generatedLuckyGiftTierID(stage string, multiplierPPM int64, counts map[string]int) string {
|
||||||
|
baseID := luckyGiftTierIDBase(stage, multiplierPPM)
|
||||||
|
counts[baseID]++
|
||||||
|
if counts[baseID] == 1 {
|
||||||
|
return baseID
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s_%d", baseID, counts[baseID])
|
||||||
|
}
|
||||||
|
|
||||||
|
func luckyGiftTierIDBase(stage string, multiplierPPM int64) string {
|
||||||
|
stage = strings.TrimSpace(stage)
|
||||||
|
if multiplierPPM <= 0 {
|
||||||
|
return stage + "_none"
|
||||||
|
}
|
||||||
|
whole := multiplierPPM / 1_000_000
|
||||||
|
fraction := multiplierPPM % 1_000_000
|
||||||
|
if fraction == 0 {
|
||||||
|
return fmt.Sprintf("%s_%dx", stage, whole)
|
||||||
|
}
|
||||||
|
fractionText := strings.TrimRight(fmt.Sprintf("%06d", fraction), "0")
|
||||||
|
return fmt.Sprintf("%s_%d_%sx", stage, whole, fractionText)
|
||||||
|
}
|
||||||
|
|
||||||
func percentToPPM(value float64) int64 {
|
func percentToPPM(value float64) int64 {
|
||||||
return int64(math.Round(value * 10_000))
|
return int64(math.Round(value * 10_000))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,6 +64,32 @@ func TestConfigToProtoConvertsBusinessUnitsToPPM(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfigToProtoGeneratesUniqueTierIDs(t *testing.T) {
|
||||||
|
config := configToProto(configRequest{
|
||||||
|
PoolID: "lucky",
|
||||||
|
Stages: []stageDTO{
|
||||||
|
{
|
||||||
|
Stage: "advanced",
|
||||||
|
Tiers: []tierDTO{
|
||||||
|
{TierID: "manual_one", Multiplier: 0, ProbabilityPercent: 50, RewardSource: "base_rtp", Enabled: true},
|
||||||
|
{TierID: "manual_two", Multiplier: 5, ProbabilityPercent: 25, RewardSource: "base_rtp", Enabled: true},
|
||||||
|
{TierID: "manual_two", Multiplier: 5, ProbabilityPercent: 25, RewardSource: "base_rtp", Enabled: true},
|
||||||
|
{TierID: "manual_decimal", Multiplier: 0.5, ProbabilityPercent: 0, RewardSource: "base_rtp"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tiers := config.GetStages()[0].GetTiers()
|
||||||
|
got := []string{tiers[0].GetTierId(), tiers[1].GetTierId(), tiers[2].GetTierId(), tiers[3].GetTierId()}
|
||||||
|
want := []string{"advanced_none", "advanced_5x", "advanced_5x_2", "advanced_0_5x"}
|
||||||
|
for index := range want {
|
||||||
|
if got[index] != want[index] {
|
||||||
|
t.Fatalf("tier id[%d] = %q, want %q; all=%v", index, got[index], want[index], got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigFromProtoConvertsPPMToBusinessUnits(t *testing.T) {
|
func TestConfigFromProtoConvertsPPMToBusinessUnits(t *testing.T) {
|
||||||
config := configFromProto(&activityv1.LuckyGiftRuleConfig{
|
config := configFromProto(&activityv1.LuckyGiftRuleConfig{
|
||||||
AppCode: "hyapp",
|
AppCode: "hyapp",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user