百顺游戏

This commit is contained in:
hy001 2026-04-24 14:05:15 +08:00
parent 8256fdf7e6
commit fa564ef985
11 changed files with 163 additions and 8 deletions

View File

@ -93,6 +93,8 @@ type WeekStarRocketMQConfig struct {
// BaishunConfig 保存百顺模块配置。
type BaishunConfig struct {
PlatformBaseURL string
GameListURL string
LuckyGiftURL string
AppID int64
AppName string
AppChannel string
@ -185,6 +187,8 @@ func Load() Config {
},
Baishun: BaishunConfig{
PlatformBaseURL: getEnvAny([]string{"CHATAPP_BAISHUN_PLATFORM_BASE_URL", "BAISHUN_PLATFORM_BASE_URL"}, ""),
GameListURL: getEnvAny([]string{"CHATAPP_BAISHUN_GAME_LIST_URL", "BAISHUN_GAME_LIST_URL"}, ""),
LuckyGiftURL: getEnvAny([]string{"CHATAPP_BAISHUN_LUCKY_GIFT_URL", "BAISHUN_LUCKY_GIFT_URL"}, ""),
AppID: getEnvInt64Any([]string{"CHATAPP_BAISHUN_APP_ID", "BAISHUN_APP_ID"}, 0),
AppName: getEnvAny([]string{"CHATAPP_BAISHUN_APP_NAME", "BAISHUN_APP_NAME"}, ""),
AppChannel: getEnvAny([]string{"CHATAPP_BAISHUN_APP_CHANNEL", "BAISHUN_APP_CHANNEL"}, ""),

View File

@ -60,6 +60,8 @@ type BaishunProviderConfig struct {
Profile string `gorm:"column:profile;size:32;default:PROD;uniqueIndex:uk_baishun_provider_sys_origin_profile,priority:2"` // 配置档案PROD/TEST
Active bool `gorm:"column:active;index:idx_baishun_provider_active,priority:2"` // 是否当前启用
PlatformBaseURL string `gorm:"column:platform_base_url;size:1024"` // 百顺平台基础地址
GameListURL string `gorm:"column:game_list_url;size:1024"` // 百顺游戏列表完整地址
LuckyGiftURL string `gorm:"column:lucky_gift_url;size:1024"` // 幸运礼物完整地址
AppID int64 `gorm:"column:app_id;index:idx_baishun_provider_app,priority:1"` // 百顺应用 ID
AppName string `gorm:"column:app_name;size:128"` // 百顺应用名
AppChannel string `gorm:"column:app_channel;size:64;index:idx_baishun_provider_app,priority:2"` // 百顺渠道

View File

@ -2,6 +2,8 @@ package baishun
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
@ -29,6 +31,37 @@ func TestResolveAdminShowcase(t *testing.T) {
})
}
func TestFetchPlatformGamesUsesConfiguredGameListURL(t *testing.T) {
service, _ := newTestBaishunService(t)
ctx := context.Background()
var gotPath string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath = r.URL.Path
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"code":0,"message":"ok","data":[{"game_id":1021,"name":"LuckyGift","download_url":"https://cdn.example.com/lucky/index.html","preview_url":"https://cdn.example.com/lucky.png","game_version":"1.0.0","game_mode":[1],"game_orientation":1,"safe_height":0,"venue_level":[1]}]}`))
}))
defer server.Close()
service.httpClient = server.Client()
games, err := service.fetchPlatformGames(ctx, baishunRuntimeConfig{
PlatformBaseURL: "https://unused.example.com",
GameListURL: server.URL + "/custom/game-list",
AppID: 1001,
AppChannel: "test",
AppKey: "test-key",
})
if err != nil {
t.Fatalf("fetchPlatformGames() error = %v", err)
}
if gotPath != "/custom/game-list" {
t.Fatalf("request path = %q, want configured game list path", gotPath)
}
if len(games) != 1 || games[0].GameID != 1021 {
t.Fatalf("games = %+v, want fetched game 1021", games)
}
}
func TestImportAndListRoomGamesUseActiveProfile(t *testing.T) {
service, db := newTestBaishunService(t)
ctx := context.Background()

View File

@ -106,7 +106,7 @@ func (s *BaishunService) fetchPlatformGames(ctx context.Context, runtimeCfg bais
payload["app_name"] = runtimeCfg.AppName
}
body, _ := json.Marshal(payload)
endpoint := strings.TrimRight(runtimeCfg.PlatformBaseURL, "/") + "/v1/api/gamelist"
endpoint := runtimeCfg.gameListURL()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return nil, err

View File

@ -16,6 +16,8 @@ type baishunRuntimeConfig struct {
SysOrigin string
Profile string
PlatformBaseURL string
GameListURL string
LuckyGiftURL string
AppID int64
AppName string
AppChannel string
@ -29,6 +31,14 @@ func (c baishunRuntimeConfig) appChannel() string {
return defaultIfBlank(strings.TrimSpace(c.AppChannel), "skychat")
}
func (c baishunRuntimeConfig) gameListURL() string {
return resolveBaishunGameListURL(c.PlatformBaseURL, c.GameListURL)
}
func (c baishunRuntimeConfig) luckyGiftURL() string {
return resolveBaishunLuckyGiftURL(c.PlatformBaseURL, c.LuckyGiftURL)
}
func (c baishunRuntimeConfig) gsp() int {
if c.GSP > 0 {
return c.GSP
@ -51,10 +61,13 @@ func (c baishunRuntimeConfig) ssTokenTTLSeconds() int {
}
func (s *BaishunService) defaultRuntimeConfig(sysOrigin string) baishunRuntimeConfig {
platformBaseURL := strings.TrimSpace(s.cfg.Baishun.PlatformBaseURL)
return baishunRuntimeConfig{
SysOrigin: normalizeAdminSysOrigin(sysOrigin),
Profile: baishunProfileProd,
PlatformBaseURL: strings.TrimSpace(s.cfg.Baishun.PlatformBaseURL),
PlatformBaseURL: platformBaseURL,
GameListURL: resolveBaishunGameListURL(platformBaseURL, s.cfg.Baishun.GameListURL),
LuckyGiftURL: resolveBaishunLuckyGiftURL(platformBaseURL, s.cfg.Baishun.LuckyGiftURL),
AppID: s.cfg.Baishun.AppID,
AppName: strings.TrimSpace(s.cfg.Baishun.AppName),
AppChannel: strings.TrimSpace(s.cfg.Baishun.AppChannel),
@ -71,6 +84,16 @@ func applyProviderRow(base baishunRuntimeConfig, row model.BaishunProviderConfig
if strings.TrimSpace(row.PlatformBaseURL) != "" {
base.PlatformBaseURL = strings.TrimSpace(row.PlatformBaseURL)
}
if strings.TrimSpace(row.GameListURL) != "" {
base.GameListURL = strings.TrimSpace(row.GameListURL)
} else {
base.GameListURL = resolveBaishunGameListURL(base.PlatformBaseURL, "")
}
if strings.TrimSpace(row.LuckyGiftURL) != "" {
base.LuckyGiftURL = strings.TrimSpace(row.LuckyGiftURL)
} else {
base.LuckyGiftURL = resolveBaishunLuckyGiftURL(base.PlatformBaseURL, "")
}
if row.AppID > 0 {
base.AppID = row.AppID
}
@ -193,6 +216,8 @@ func (s *BaishunService) GetProviderConfig(ctx context.Context, sysOrigin string
ActiveProfile: activeProfile,
Active: runtimeCfg.Profile == activeProfile,
PlatformBaseURL: runtimeCfg.PlatformBaseURL,
GameListURL: runtimeCfg.gameListURL(),
LuckyGiftURL: runtimeCfg.luckyGiftURL(),
AppID: runtimeCfg.AppID,
AppName: runtimeCfg.AppName,
AppChannel: runtimeCfg.appChannel(),
@ -211,12 +236,22 @@ func (s *BaishunService) SaveProviderConfig(ctx context.Context, req SaveBaishun
return nil, err
}
platformBaseURL := strings.TrimSpace(req.PlatformBaseURL)
gameListURL := strings.TrimSpace(req.GameListURL)
luckyGiftURL := strings.TrimSpace(req.LuckyGiftURL)
appChannel := strings.TrimSpace(req.AppChannel)
appKey := strings.TrimSpace(req.AppKey)
if gameListURL == "" {
gameListURL = resolveBaishunGameListURL(platformBaseURL, "")
}
if luckyGiftURL == "" {
luckyGiftURL = resolveBaishunLuckyGiftURL(platformBaseURL, "")
}
switch {
case platformBaseURL == "":
return nil, NewAppError(http.StatusBadRequest, "platform_base_url_required", "platformBaseUrl is required")
case luckyGiftURL == "":
return nil, NewAppError(http.StatusBadRequest, "lucky_gift_url_required", "luckyGiftUrl is required")
case req.AppID <= 0:
return nil, NewAppError(http.StatusBadRequest, "app_id_required", "appId is required")
case appChannel == "":
@ -235,6 +270,8 @@ func (s *BaishunService) SaveProviderConfig(ctx context.Context, req SaveBaishun
SysOrigin: sysOrigin,
Profile: profile,
PlatformBaseURL: platformBaseURL,
GameListURL: gameListURL,
LuckyGiftURL: luckyGiftURL,
AppID: req.AppID,
AppName: strings.TrimSpace(req.AppName),
AppChannel: appChannel,
@ -266,7 +303,7 @@ func (s *BaishunService) SaveProviderConfig(ctx context.Context, req SaveBaishun
if err := s.repo.DB.WithContext(ctx).Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "sys_origin"}, {Name: "profile"}},
DoUpdates: clause.AssignmentColumns([]string{
"platform_base_url", "app_id", "app_name", "app_channel", "app_key",
"platform_base_url", "game_list_url", "lucky_gift_url", "app_id", "app_name", "app_channel", "app_key",
"gsp", "launch_code_ttl_seconds", "ss_token_ttl_seconds", "update_time",
}),
}).Create(&row).Error; err != nil {
@ -278,6 +315,30 @@ func (s *BaishunService) SaveProviderConfig(ctx context.Context, req SaveBaishun
return s.GetProviderConfig(ctx, sysOrigin, profile)
}
func resolveBaishunGameListURL(platformBaseURL string, gameListURL string) string {
gameListURL = strings.TrimSpace(gameListURL)
if gameListURL != "" {
return gameListURL
}
platformBaseURL = strings.TrimRight(strings.TrimSpace(platformBaseURL), "/")
if platformBaseURL == "" {
return ""
}
return platformBaseURL + "/v1/api/gamelist"
}
func resolveBaishunLuckyGiftURL(platformBaseURL string, luckyGiftURL string) string {
luckyGiftURL = strings.TrimSpace(luckyGiftURL)
if luckyGiftURL != "" {
return luckyGiftURL
}
platformBaseURL = strings.TrimRight(strings.TrimSpace(platformBaseURL), "/")
if platformBaseURL == "" {
return ""
}
return platformBaseURL + "/lucky_gift/start_game"
}
func (s *BaishunService) ActivateProviderProfile(ctx context.Context, req ActivateBaishunProviderProfileRequest) (*BaishunProviderConfigItem, error) {
sysOrigin := normalizeAdminSysOrigin(req.SysOrigin)
profile, err := validateBaishunProfile(req.Profile)

View File

@ -284,6 +284,8 @@ type BaishunProviderConfigItem struct {
ActiveProfile string `json:"activeProfile"`
Active bool `json:"active"`
PlatformBaseURL string `json:"platformBaseUrl"`
GameListURL string `json:"gameListUrl"`
LuckyGiftURL string `json:"luckyGiftUrl"`
AppID int64 `json:"appId"`
AppName string `json:"appName"`
AppChannel string `json:"appChannel"`
@ -299,6 +301,8 @@ type SaveBaishunProviderConfigRequest struct {
SysOrigin string `json:"sysOrigin"`
Profile string `json:"profile"`
PlatformBaseURL string `json:"platformBaseUrl"`
GameListURL string `json:"gameListUrl"`
LuckyGiftURL string `json:"luckyGiftUrl"`
AppID int64 `json:"appId"`
AppName string `json:"appName"`
AppChannel string `json:"appChannel"`

View File

@ -82,10 +82,13 @@ func (s *LuckyGiftService) resolveActiveBaishunProfile(ctx context.Context, sysO
func defaultLuckyGiftRuntimeAccount(cfg config.Config) luckyGiftRuntimeAccount {
account := luckyGiftRuntimeAccount{
URL: strings.TrimSpace(cfg.Baishun.PlatformBaseURL),
URL: strings.TrimSpace(cfg.Baishun.LuckyGiftURL),
AppChannel: strings.TrimSpace(cfg.Baishun.AppChannel),
AppKey: strings.TrimSpace(cfg.Baishun.AppKey),
}
if account.URL == "" {
account.URL = strings.TrimSpace(cfg.Baishun.PlatformBaseURL)
}
if cfg.Baishun.AppID > 0 {
account.AppID = strconv.FormatInt(cfg.Baishun.AppID, 10)
}
@ -93,7 +96,9 @@ func defaultLuckyGiftRuntimeAccount(cfg config.Config) luckyGiftRuntimeAccount {
}
func applyLuckyGiftRuntimeAccount(base luckyGiftRuntimeAccount, row model.BaishunProviderConfig) luckyGiftRuntimeAccount {
if strings.TrimSpace(row.PlatformBaseURL) != "" {
if strings.TrimSpace(row.LuckyGiftURL) != "" {
base.URL = strings.TrimSpace(row.LuckyGiftURL)
} else if strings.TrimSpace(row.PlatformBaseURL) != "" {
base.URL = strings.TrimSpace(row.PlatformBaseURL)
}
if row.AppID > 0 {

View File

@ -49,12 +49,13 @@ func TestApplyLuckyGiftRuntimeAccountUsesProviderConfigRow(t *testing.T) {
AppKey: "fallback-app-key",
}, model.BaishunProviderConfig{
PlatformBaseURL: "https://provider.example.com",
LuckyGiftURL: "https://lucky.example.com/lucky_gift/start_game",
AppID: 4581045902,
AppChannel: "yumiparty",
AppKey: "test-key",
})
if account.URL != "https://provider.example.com" {
if account.URL != "https://lucky.example.com/lucky_gift/start_game" {
t.Fatalf("expected row url, got %q", account.URL)
}
if account.AppID != "4581045902" {
@ -72,13 +73,14 @@ func TestDefaultLuckyGiftRuntimeAccountUsesBaishunConfig(t *testing.T) {
account := defaultLuckyGiftRuntimeAccount(config.Config{
Baishun: config.BaishunConfig{
PlatformBaseURL: "https://provider.example.com",
LuckyGiftURL: "https://lucky.example.com/lucky_gift/start_game",
AppID: 7485318192,
AppChannel: "yumiparty",
AppKey: "shared-key",
},
})
if account.URL != "https://provider.example.com" {
if account.URL != "https://lucky.example.com/lucky_gift/start_game" {
t.Fatalf("expected baishun platform base url, got %q", account.URL)
}
if account.AppID != "7485318192" {
@ -120,6 +122,7 @@ func TestResolveProviderConfigUsesActiveBaishunProfile(t *testing.T) {
Profile: "PROD",
Active: false,
PlatformBaseURL: "https://prod.example.com",
LuckyGiftURL: "https://prod-lucky.example.com/lucky_gift/start_game",
AppID: 222,
AppChannel: "prod",
AppKey: "prod-key",
@ -132,6 +135,7 @@ func TestResolveProviderConfigUsesActiveBaishunProfile(t *testing.T) {
Profile: "TEST",
Active: true,
PlatformBaseURL: "https://test.example.com",
LuckyGiftURL: "https://test-lucky.example.com/lucky_gift/start_game",
AppID: 333,
AppChannel: "test",
AppKey: "test-key",
@ -153,7 +157,7 @@ func TestResolveProviderConfigUsesActiveBaishunProfile(t *testing.T) {
if err != nil {
t.Fatalf("resolve lucky gift endpoint: %v", err)
}
if endpoint != "https://test.example.com/lucky_gift/start_game" {
if endpoint != "https://test-lucky.example.com/lucky_gift/start_game" {
t.Fatalf("endpoint = %q, want active test endpoint", endpoint)
}
if resolved.AppID != "333" || resolved.AppChannel != "test" || resolved.AppKey != "test-key" {

View File

@ -4,6 +4,8 @@ CREATE TABLE IF NOT EXISTS baishun_provider_config (
profile VARCHAR(32) NOT NULL DEFAULT 'PROD',
active TINYINT(1) NOT NULL DEFAULT 1,
platform_base_url VARCHAR(1024) NOT NULL,
game_list_url VARCHAR(1024) NOT NULL DEFAULT '',
lucky_gift_url VARCHAR(1024) NOT NULL DEFAULT '',
app_id BIGINT NOT NULL,
app_name VARCHAR(128) DEFAULT NULL,
app_channel VARCHAR(64) NOT NULL,

View File

@ -0,0 +1,20 @@
SET @current_schema := DATABASE();
SET @add_provider_game_list_url_sql := IF(
NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @current_schema
AND table_name = 'baishun_provider_config'
AND column_name = 'game_list_url'
),
'ALTER TABLE `baishun_provider_config` ADD COLUMN `game_list_url` varchar(1024) NOT NULL DEFAULT '''' AFTER `platform_base_url`',
'SELECT 1'
);
PREPARE add_provider_game_list_url_stmt FROM @add_provider_game_list_url_sql;
EXECUTE add_provider_game_list_url_stmt;
DEALLOCATE PREPARE add_provider_game_list_url_stmt;
UPDATE `baishun_provider_config`
SET `game_list_url` = CONCAT(TRIM(TRAILING '/' FROM `platform_base_url`), '/v1/api/gamelist')
WHERE COALESCE(TRIM(`game_list_url`), '') = ''
AND COALESCE(TRIM(`platform_base_url`), '') <> '';

View File

@ -0,0 +1,20 @@
SET @current_schema := DATABASE();
SET @add_provider_lucky_gift_url_sql := IF(
NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @current_schema
AND table_name = 'baishun_provider_config'
AND column_name = 'lucky_gift_url'
),
'ALTER TABLE `baishun_provider_config` ADD COLUMN `lucky_gift_url` varchar(1024) NOT NULL DEFAULT '''' AFTER `game_list_url`',
'SELECT 1'
);
PREPARE add_provider_lucky_gift_url_stmt FROM @add_provider_lucky_gift_url_sql;
EXECUTE add_provider_lucky_gift_url_stmt;
DEALLOCATE PREPARE add_provider_lucky_gift_url_stmt;
UPDATE `baishun_provider_config`
SET `lucky_gift_url` = CONCAT(TRIM(TRAILING '/' FROM `platform_base_url`), '/lucky_gift/start_game')
WHERE COALESCE(TRIM(`lucky_gift_url`), '') = ''
AND COALESCE(TRIM(`platform_base_url`), '') <> '';