修复幸运礼物

This commit is contained in:
hy001 2026-04-23 12:24:32 +08:00
parent 8f8ae40947
commit 3e2719f682
5 changed files with 213 additions and 32 deletions

View File

@ -307,13 +307,13 @@ func normalizeLuckyGiftConfigs(
item.AppID = strings.TrimSpace(item.AppID)
item.AppChannel = strings.TrimSpace(item.AppChannel)
item.AppKey = strings.TrimSpace(item.AppKey)
if sharedBaishunAppID != "" {
if item.AppID == "" && sharedBaishunAppID != "" {
item.AppID = sharedBaishunAppID
}
if sharedBaishunAppChannel != "" {
if item.AppChannel == "" && sharedBaishunAppChannel != "" {
item.AppChannel = sharedBaishunAppChannel
}
if sharedBaishunAppKey != "" {
if item.AppKey == "" && sharedBaishunAppKey != "" {
item.AppKey = sharedBaishunAppKey
}
if item.URL == "" || item.AppID == "" || item.AppChannel == "" || item.AppKey == "" {

View File

@ -5,7 +5,7 @@ import (
"testing"
)
func TestNormalizeLuckyGiftConfigsUsesSharedBaishunAppKey(t *testing.T) {
func TestNormalizeLuckyGiftConfigsKeepsDedicatedAccountWhenSharedPresent(t *testing.T) {
configs := normalizeLuckyGiftConfigs([]LuckyGiftProviderConfig{
{
StandardID: 18816,
@ -18,30 +18,6 @@ func TestNormalizeLuckyGiftConfigsUsesSharedBaishunAppKey(t *testing.T) {
if len(configs) != 1 {
t.Fatalf("expected 1 config, got %d", len(configs))
}
if got := configs[0].AppID; got != "shared-baishun-app-id" {
t.Fatalf("expected baishun app id override, got %q", got)
}
if got := configs[0].AppChannel; got != "shared-baishun-app-channel" {
t.Fatalf("expected baishun app channel override, got %q", got)
}
if got := configs[0].AppKey; got != "shared-baishun-key" {
t.Fatalf("expected baishun key override, got %q", got)
}
}
func TestNormalizeLuckyGiftConfigsKeepsDedicatedKeyWhenSharedBlank(t *testing.T) {
configs := normalizeLuckyGiftConfigs([]LuckyGiftProviderConfig{
{
StandardID: 18816,
URL: "https://provider.example.com",
AppID: "lucky-app-id",
AppChannel: "lucky-app-channel",
AppKey: "legacy-lucky-key",
},
}, "", "", "")
if len(configs) != 1 {
t.Fatalf("expected 1 config, got %d", len(configs))
}
if got := configs[0].AppID; got != "lucky-app-id" {
t.Fatalf("expected dedicated lucky gift app id, got %q", got)
}
@ -53,6 +29,27 @@ func TestNormalizeLuckyGiftConfigsKeepsDedicatedKeyWhenSharedBlank(t *testing.T)
}
}
func TestNormalizeLuckyGiftConfigsFallsBackToSharedAccountWhenDedicatedBlank(t *testing.T) {
configs := normalizeLuckyGiftConfigs([]LuckyGiftProviderConfig{
{
StandardID: 18816,
URL: "https://provider.example.com",
},
}, "shared-baishun-app-id", "shared-baishun-app-channel", "shared-baishun-key")
if len(configs) != 1 {
t.Fatalf("expected 1 config, got %d", len(configs))
}
if got := configs[0].AppID; got != "shared-baishun-app-id" {
t.Fatalf("expected shared baishun app id fallback, got %q", got)
}
if got := configs[0].AppChannel; got != "shared-baishun-app-channel" {
t.Fatalf("expected shared baishun app channel fallback, got %q", got)
}
if got := configs[0].AppKey; got != "shared-baishun-key" {
t.Fatalf("expected shared baishun key fallback, got %q", got)
}
}
func TestGetEnvBoolAliasSupportsLegacyLuckyGiftKey(t *testing.T) {
t.Setenv("LUCKY_GIFT_GO_ENABLED", "true")
if got := getEnvBoolAny([]string{"LUCKY_GIFT_ENABLED", "LUCKY_GIFT_GO_ENABLED"}, false); !got {

View File

@ -24,8 +24,9 @@ func (s *LuckyGiftService) Draw(ctx context.Context, req LuckyGiftDrawRequest) (
if !s.cfg.LuckyGift.Enabled {
return nil, NewAppError(http.StatusServiceUnavailable, "lucky_gift_disabled", "lucky gift service is disabled")
}
if _, ok := findLuckyGiftConfig(s.cfg.LuckyGift.Providers, req.StandardID); !ok {
return nil, NewAppError(http.StatusServiceUnavailable, "lucky_gift_config_missing", "lucky gift provider config is missing")
account, err := s.resolveProviderConfig(ctx, req)
if err != nil {
return nil, err
}
if cached, err := s.loadSuccessfulResponse(ctx, req.BusinessID); err != nil {
@ -65,7 +66,7 @@ func (s *LuckyGiftService) Draw(ctx context.Context, req LuckyGiftDrawRequest) (
return nil, err
}
results, providerCode, rewardTotal, rawProviderResponse, err := s.resolveProviderResults(ctx, req, record, walletEventID)
results, providerCode, rewardTotal, rawProviderResponse, err := s.resolveProviderResults(ctx, account, req, record, walletEventID)
if err != nil {
_ = s.markRequestFailed(ctx, req.BusinessID, providerCode, rawProviderResponse, err.Error())
return nil, err
@ -145,6 +146,7 @@ func (s *LuckyGiftService) Draw(ctx context.Context, req LuckyGiftDrawRequest) (
// resolveProviderResults 优先复用已缓存的三方响应,否则真正调用三方抽奖接口。
func (s *LuckyGiftService) resolveProviderResults(
ctx context.Context,
account config.LuckyGiftProviderConfig,
req LuckyGiftDrawRequest,
record *model.LuckyGiftDrawRequestRecord,
walletEventID string,
@ -161,7 +163,6 @@ func (s *LuckyGiftService) resolveProviderResults(
return results, providerCode, rewardTotal, record.ProviderResponseJSON, nil
}
account, _ := findLuckyGiftConfig(s.cfg.LuckyGift.Providers, req.StandardID)
rawResponse, providerCode, results, rewardTotal, err := s.callLuckyGiftProvider(ctx, account, req)
if err != nil {
return nil, providerCode, 0, rawResponse, err

View File

@ -0,0 +1,105 @@
package luckygift
import (
"chatapp3-golang/internal/config"
"chatapp3-golang/internal/model"
"context"
"net/http"
"strconv"
"strings"
"gorm.io/gorm"
)
type luckyGiftRuntimeAccount struct {
AppID string
AppChannel string
AppKey string
}
func (s *LuckyGiftService) resolveProviderConfig(ctx context.Context, req LuckyGiftDrawRequest) (config.LuckyGiftProviderConfig, error) {
base, ok := findLuckyGiftConfig(s.cfg.LuckyGift.Providers, req.StandardID)
if !ok {
return config.LuckyGiftProviderConfig{}, NewAppError(
http.StatusServiceUnavailable,
"lucky_gift_config_missing",
"lucky gift provider config is missing",
)
}
runtimeAccount, err := s.resolveRuntimeAccount(ctx, req.SysOrigin)
if err != nil {
return config.LuckyGiftProviderConfig{}, NewAppError(
http.StatusInternalServerError,
"lucky_gift_runtime_config_failed",
err.Error(),
)
}
return mergeLuckyGiftProviderConfig(base, runtimeAccount), nil
}
func (s *LuckyGiftService) resolveRuntimeAccount(ctx context.Context, sysOrigin string) (luckyGiftRuntimeAccount, error) {
account := defaultLuckyGiftRuntimeAccount(s.cfg)
var row model.BaishunProviderConfig
err := s.repo.DB.WithContext(ctx).
Where("sys_origin = ?", normalizeLuckyGiftSysOrigin(sysOrigin)).
Limit(1).
First(&row).Error
if err == nil {
return applyLuckyGiftRuntimeAccount(account, row), nil
}
if err == gorm.ErrRecordNotFound {
return account, nil
}
return luckyGiftRuntimeAccount{}, err
}
func defaultLuckyGiftRuntimeAccount(cfg config.Config) luckyGiftRuntimeAccount {
account := luckyGiftRuntimeAccount{
AppChannel: strings.TrimSpace(cfg.Baishun.AppChannel),
AppKey: strings.TrimSpace(cfg.Baishun.AppKey),
}
if cfg.Baishun.AppID > 0 {
account.AppID = strconv.FormatInt(cfg.Baishun.AppID, 10)
}
return account
}
func applyLuckyGiftRuntimeAccount(base luckyGiftRuntimeAccount, row model.BaishunProviderConfig) luckyGiftRuntimeAccount {
if row.AppID > 0 {
base.AppID = strconv.FormatInt(row.AppID, 10)
}
if strings.TrimSpace(row.AppChannel) != "" {
base.AppChannel = strings.TrimSpace(row.AppChannel)
}
if strings.TrimSpace(row.AppKey) != "" {
base.AppKey = strings.TrimSpace(row.AppKey)
}
return base
}
func mergeLuckyGiftProviderConfig(
base config.LuckyGiftProviderConfig,
runtime luckyGiftRuntimeAccount,
) config.LuckyGiftProviderConfig {
merged := base
if runtime.AppID != "" {
merged.AppID = runtime.AppID
}
if runtime.AppChannel != "" {
merged.AppChannel = runtime.AppChannel
}
if runtime.AppKey != "" {
merged.AppKey = runtime.AppKey
}
return merged
}
func normalizeLuckyGiftSysOrigin(sysOrigin string) string {
sysOrigin = strings.ToUpper(strings.TrimSpace(sysOrigin))
if sysOrigin == "" {
return "LIKEI"
}
return sysOrigin
}

View File

@ -0,0 +1,78 @@
package luckygift
import (
"chatapp3-golang/internal/config"
"chatapp3-golang/internal/model"
"testing"
)
func TestMergeLuckyGiftProviderConfigPrefersRuntimeAccount(t *testing.T) {
base := config.LuckyGiftProviderConfig{
StandardID: 18816,
URL: "https://provider.example.com/lucky_gift/start_game",
AppID: "base-app-id",
AppChannel: "base-app-channel",
AppKey: "base-app-key",
}
merged := mergeLuckyGiftProviderConfig(base, luckyGiftRuntimeAccount{
AppID: "runtime-app-id",
AppChannel: "runtime-app-channel",
AppKey: "runtime-app-key",
})
if merged.URL != base.URL {
t.Fatalf("expected url to keep base value, got %q", merged.URL)
}
if merged.AppID != "runtime-app-id" {
t.Fatalf("expected runtime app id, got %q", merged.AppID)
}
if merged.AppChannel != "runtime-app-channel" {
t.Fatalf("expected runtime app channel, got %q", merged.AppChannel)
}
if merged.AppKey != "runtime-app-key" {
t.Fatalf("expected runtime app key, got %q", merged.AppKey)
}
}
func TestApplyLuckyGiftRuntimeAccountUsesProviderConfigRow(t *testing.T) {
account := applyLuckyGiftRuntimeAccount(luckyGiftRuntimeAccount{
AppID: "fallback-app-id",
AppChannel: "fallback-app-channel",
AppKey: "fallback-app-key",
}, model.BaishunProviderConfig{
AppID: 4581045902,
AppChannel: "yumiparty",
AppKey: "test-key",
})
if account.AppID != "4581045902" {
t.Fatalf("expected row app id, got %q", account.AppID)
}
if account.AppChannel != "yumiparty" {
t.Fatalf("expected row app channel, got %q", account.AppChannel)
}
if account.AppKey != "test-key" {
t.Fatalf("expected row app key, got %q", account.AppKey)
}
}
func TestDefaultLuckyGiftRuntimeAccountUsesBaishunConfig(t *testing.T) {
account := defaultLuckyGiftRuntimeAccount(config.Config{
Baishun: config.BaishunConfig{
AppID: 7485318192,
AppChannel: "yumiparty",
AppKey: "shared-key",
},
})
if account.AppID != "7485318192" {
t.Fatalf("expected baishun app id, got %q", account.AppID)
}
if account.AppChannel != "yumiparty" {
t.Fatalf("expected baishun app channel, got %q", account.AppChannel)
}
if account.AppKey != "shared-key" {
t.Fatalf("expected baishun app key, got %q", account.AppKey)
}
}