2026-04-28 18:05:13 +08:00

365 lines
15 KiB
Go

package config
import (
"encoding/json"
"os"
"strconv"
"strings"
"time"
)
// Config 是按运行层和业务模块分段后的应用配置。
type Config struct {
HTTP HTTPConfig
Store StoreConfig
Java JavaConfig
Worker WorkerConfig
Invite InviteConfig
WeekStar WeekStarConfig
RoomTurnoverReward RoomTurnoverRewardConfig
Baishun BaishunConfig
Lingxian LingxianConfig
GameOpen GameOpenConfig
LuckyGift LuckyGiftConfig
}
// HTTPConfig 保存 HTTP 服务运行配置。
type HTTPConfig struct {
ListenAddr string
Timeout time.Duration
ShutdownTimeout time.Duration
InternalCallbackSecret string
}
// StoreConfig 保存 MySQL 和 Redis 连接配置。
type StoreConfig struct {
MySQLDSN string
RedisAddr string
RedisPassword string
RedisDB int
}
// JavaConfig 保存各类 Java 下游服务地址。
type JavaConfig struct {
AuthBaseURL string
ConsoleBaseURL string
DeviceBaseURL string
AppBaseURL string
BridgeBaseURL string
ExternalBaseURL string
OtherBaseURL string
WalletBaseURL string
}
// WorkerConfig 保存事件消费类 worker 的运行配置。
type WorkerConfig struct {
RegisterReward RegisterRewardWorkerConfig
}
// RegisterRewardWorkerConfig 保存注册奖励消费配置。
type RegisterRewardWorkerConfig struct {
StreamKey string
ConsumerGroup string
ConsumerName string
BatchSize int64
Block time.Duration
MinIdle time.Duration
}
// InviteConfig 保存邀请活动相关配置。
type InviteConfig struct {
PublicBaseURL string
PublicH5Path string
}
// WeekStarConfig 保存周榜模块配置。
type WeekStarConfig struct {
DefaultSysOrigin string
Timezone string
RetryStreamKey string
RocketMQ WeekStarRocketMQConfig
}
// WeekStarRocketMQConfig 保存周榜 MQ 消费配置。
type WeekStarRocketMQConfig struct {
Enabled bool
Endpoint string
Namespace string
AccessKey string
AccessSecret string
SecurityToken string
ConsumerGroup string
Topic string
Tag string
}
// RoomTurnoverRewardConfig 保存房间流水奖励模块配置。
type RoomTurnoverRewardConfig struct {
DefaultSysOrigin string
Timezone string
CycleDuration time.Duration
}
// BaishunConfig 保存百顺模块配置。
type BaishunConfig struct {
PlatformBaseURL string
GameListURL string
LuckyGiftURL string
AppID int64
AppName string
AppChannel string
AppKey string
GSP int
LaunchCodeTTLSeconds int
SSTokenTTLSeconds int
}
// LingxianConfig 保存灵仙模块配置。
type LingxianConfig struct {
GameListURL string
AppKey string
}
// GameOpenConfig 保存统一三方游戏回调配置。
type GameOpenConfig struct {
PublicBaseURL string
AppKey string
TestUserID int64
TestAccount string
TestPassword string
}
// LuckyGiftConfig 保存幸运礼物模块配置。
type LuckyGiftConfig struct {
Enabled bool
Timeout time.Duration
RewardStreamKey string
Providers []LuckyGiftProviderConfig
}
type LuckyGiftProviderConfig struct {
StandardID int64 `json:"standardId"`
URL string `json:"url"`
AppID string `json:"appId"`
AppChannel string `json:"appChannel"`
AppKey string `json:"appKey"`
}
func Load() Config {
javaAppBaseURL := getEnvAny([]string{"CHATAPP_JAVA_APP_BASE_URL", "INVITE_JAVA_APP_BASE_URL"}, "http://127.0.0.1:2400")
consoleBaseURL := getEnvAny([]string{"CHATAPP_JAVA_CONSOLE_BASE_URL", "JAVA_CONSOLE_BASE_URL"}, "http://127.0.0.1:2700/console")
return Config{
HTTP: HTTPConfig{
ListenAddr: getEnvAny([]string{"CHATAPP_HTTP_LISTEN_ADDR", "INVITE_HTTP_ADDR"}, ":2900"),
Timeout: time.Duration(getEnvIntAny([]string{"CHATAPP_HTTP_TIMEOUT_SECONDS", "INVITE_HTTP_TIMEOUT_SECONDS"}, 8)) * time.Second,
ShutdownTimeout: time.Duration(getEnvIntAny([]string{"CHATAPP_HTTP_SHUTDOWN_TIMEOUT_SECONDS", "INVITE_HTTP_SHUTDOWN_TIMEOUT_SECONDS"}, 30)) * time.Second,
InternalCallbackSecret: getEnvAny([]string{"CHATAPP_HTTP_INTERNAL_CALLBACK_SECRET", "GAME_INTERNAL_CALLBACK_SECRET"}, ""),
},
Store: StoreConfig{
MySQLDSN: getEnvAny([]string{"CHATAPP_STORE_MYSQL_DSN", "INVITE_MYSQL_DSN"}, "root:root@tcp(127.0.0.1:3306)/chatapp3?charset=utf8mb4&parseTime=True&loc=Local"),
RedisAddr: getEnvAny([]string{"CHATAPP_STORE_REDIS_ADDR", "INVITE_REDIS_ADDR"}, "127.0.0.1:6379"),
RedisPassword: getEnvAny([]string{"CHATAPP_STORE_REDIS_PASSWORD", "INVITE_REDIS_PASSWORD"}, ""),
RedisDB: getEnvIntAny([]string{"CHATAPP_STORE_REDIS_DB", "INVITE_REDIS_DB"}, 0),
},
Java: JavaConfig{
AuthBaseURL: getEnvAny([]string{"CHATAPP_JAVA_AUTH_BASE_URL", "INVITE_JAVA_AUTH_BASE_URL"}, "http://127.0.0.1:2100"),
ConsoleBaseURL: consoleBaseURL,
DeviceBaseURL: getEnvAny([]string{"CHATAPP_JAVA_DEVICE_BASE_URL", "INVITE_JAVA_DEVICE_BASE_URL"}, "http://127.0.0.1:2400"),
AppBaseURL: javaAppBaseURL,
BridgeBaseURL: getEnvAny([]string{"CHATAPP_JAVA_BRIDGE_BASE_URL", "INVITE_JAVA_BRIDGE_BASE_URL"}, consoleBaseURL),
ExternalBaseURL: getEnvAny([]string{"CHATAPP_JAVA_EXTERNAL_BASE_URL", "INVITE_JAVA_EXTERNAL_BASE_URL"}, "http://127.0.0.1:3000"),
OtherBaseURL: getEnvAny([]string{"CHATAPP_JAVA_OTHER_BASE_URL", "GAME_JAVA_OTHER_BASE_URL", "INVITE_JAVA_APP_BASE_URL"}, javaAppBaseURL),
WalletBaseURL: getEnvAny([]string{"CHATAPP_JAVA_WALLET_BASE_URL", "GAME_JAVA_WALLET_BASE_URL"}, "http://127.0.0.1:2300"),
},
Worker: WorkerConfig{
RegisterReward: RegisterRewardWorkerConfig{
StreamKey: getEnvAny([]string{"CHATAPP_REGISTER_REWARD_STREAM_KEY", "REGISTER_REWARD_STREAM_KEY"}, "activity:register:reward"),
ConsumerGroup: getEnvAny([]string{"CHATAPP_REGISTER_REWARD_CONSUMER_GROUP", "REGISTER_REWARD_CONSUMER_GROUP"}, "register-reward"),
ConsumerName: getEnvAny([]string{"CHATAPP_REGISTER_REWARD_CONSUMER_NAME", "REGISTER_REWARD_CONSUMER_NAME"}, defaultConsumerName("register-reward")),
BatchSize: int64(getEnvIntAny([]string{"CHATAPP_REGISTER_REWARD_BATCH_SIZE", "REGISTER_REWARD_BATCH_SIZE"}, 10)),
Block: time.Duration(getEnvIntAny([]string{"CHATAPP_REGISTER_REWARD_BLOCK_MILLIS", "REGISTER_REWARD_BLOCK_MILLIS"}, 5000)) * time.Millisecond,
MinIdle: time.Duration(getEnvIntAny([]string{"CHATAPP_REGISTER_REWARD_MIN_IDLE_MILLIS", "REGISTER_REWARD_MIN_IDLE_MILLIS"}, 60000)) * time.Millisecond,
},
},
Invite: InviteConfig{
PublicBaseURL: getEnvAny([]string{"CHATAPP_INVITE_PUBLIC_BASE_URL", "INVITE_PUBLIC_BASE_URL"}, "http://localhost:2900"),
PublicH5Path: getEnvAny([]string{"CHATAPP_INVITE_PUBLIC_H5_PATH", "INVITE_PUBLIC_H5_PATH"}, "/h5/app-invite/landing.html"),
},
WeekStar: WeekStarConfig{
DefaultSysOrigin: strings.ToUpper(getEnvAny([]string{"CHATAPP_WEEK_STAR_DEFAULT_SYS_ORIGIN", "WEEK_STAR_DEFAULT_SYS_ORIGIN"}, "LIKEI")),
Timezone: getEnvAny([]string{"CHATAPP_WEEK_STAR_TIMEZONE", "WEEK_STAR_TIMEZONE"}, "Asia/Riyadh"),
RetryStreamKey: getEnvAny([]string{"CHATAPP_WEEK_STAR_RETRY_STREAM_KEY", "WEEK_STAR_RETRY_STREAM_KEY"}, "week-star:reward-retry"),
RocketMQ: WeekStarRocketMQConfig{
Enabled: getEnvBoolAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_ENABLED", "WEEK_STAR_ROCKETMQ_ENABLED"}, false),
Endpoint: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_ENDPOINT", "WEEK_STAR_ROCKETMQ_ENDPOINT"}, ""),
Namespace: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_NAMESPACE", "WEEK_STAR_ROCKETMQ_NAMESPACE"}, ""),
AccessKey: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_ACCESS_KEY", "WEEK_STAR_ROCKETMQ_ACCESS_KEY"}, ""),
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"),
Tag: getEnvAny([]string{"CHATAPP_WEEK_STAR_ROCKETMQ_TAG", "WEEK_STAR_ROCKETMQ_TAG"}, "give_gift_v3"),
},
},
RoomTurnoverReward: RoomTurnoverRewardConfig{
DefaultSysOrigin: strings.ToUpper(getEnvAny(
[]string{"CHATAPP_ROOM_TURNOVER_REWARD_DEFAULT_SYS_ORIGIN", "ROOM_TURNOVER_REWARD_DEFAULT_SYS_ORIGIN", "CHATAPP_WEEK_STAR_DEFAULT_SYS_ORIGIN", "WEEK_STAR_DEFAULT_SYS_ORIGIN"},
"LIKEI",
)),
Timezone: getEnvAny(
[]string{"CHATAPP_ROOM_TURNOVER_REWARD_TIMEZONE", "ROOM_TURNOVER_REWARD_TIMEZONE", "CHATAPP_WEEK_STAR_TIMEZONE", "WEEK_STAR_TIMEZONE"},
"Asia/Riyadh",
),
CycleDuration: time.Duration(getEnvIntAny(
[]string{"CHATAPP_ROOM_TURNOVER_REWARD_CYCLE_SECONDS", "ROOM_TURNOVER_REWARD_CYCLE_SECONDS"},
10,
)) * time.Second,
},
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"}, ""),
AppKey: getEnvAny([]string{"CHATAPP_BAISHUN_APP_KEY", "BAISHUN_APP_KEY"}, ""),
GSP: getEnvIntAny([]string{"CHATAPP_BAISHUN_GSP", "BAISHUN_GSP"}, 101),
LaunchCodeTTLSeconds: getEnvIntAny([]string{"CHATAPP_BAISHUN_LAUNCH_CODE_TTL_SECONDS", "BAISHUN_LAUNCH_CODE_TTL_SECONDS"}, 300),
SSTokenTTLSeconds: getEnvIntAny([]string{"CHATAPP_BAISHUN_SS_TOKEN_TTL_SECONDS", "BAISHUN_SS_TOKEN_TTL_SECONDS"}, 86400),
},
Lingxian: LingxianConfig{
GameListURL: getEnvAny([]string{"CHATAPP_LINGXIAN_GAME_LIST_URL", "LINGXIAN_GAME_LIST_URL"}, "https://sg-test.leadercc.com/yumichat_games/test_game_list.json"),
AppKey: getEnvAny([]string{"CHATAPP_LINGXIAN_APP_KEY", "LINGXIAN_APP_KEY", "GAME_HKYS_SIGN_KEY", "LIKEI_GAME_HKYS_SIGN_KEY"}, ""),
},
GameOpen: GameOpenConfig{
PublicBaseURL: getEnvAny([]string{"CHATAPP_GAME_OPEN_PUBLIC_BASE_URL", "GAME_OPEN_PUBLIC_BASE_URL"}, ""),
AppKey: getEnvAny([]string{"CHATAPP_GAME_OPEN_APP_KEY", "GAME_OPEN_APP_KEY"}, "game-open-test-key"),
TestUserID: getEnvInt64Any([]string{"CHATAPP_GAME_OPEN_TEST_USER_ID", "GAME_OPEN_TEST_USER_ID"}, 1234567),
TestAccount: getEnvAny([]string{"CHATAPP_GAME_OPEN_TEST_ACCOUNT", "GAME_OPEN_TEST_ACCOUNT"}, "1234567"),
TestPassword: getEnvAny([]string{"CHATAPP_GAME_OPEN_TEST_PASSWORD", "GAME_OPEN_TEST_PASSWORD"}, "1234567"),
},
LuckyGift: LuckyGiftConfig{
Enabled: getEnvBoolAny([]string{"CHATAPP_LUCKY_GIFT_ENABLED", "LUCKY_GIFT_ENABLED", "LUCKY_GIFT_GO_ENABLED"}, false),
Timeout: time.Duration(getEnvIntAny([]string{"CHATAPP_LUCKY_GIFT_TIMEOUT_MILLIS", "LUCKY_GIFT_TIMEOUT_MILLIS", "LUCKY_GIFT_GO_TIMEOUT_MILLIS"}, 8000)) * time.Millisecond,
RewardStreamKey: getEnvAny([]string{"CHATAPP_LUCKY_GIFT_REWARD_STREAM_KEY", "LUCKY_GIFT_REWARD_STREAM_KEY"}, "lucky-gift:reward"),
Providers: loadLuckyGiftConfigs(),
},
}
}
func getEnvAny(keys []string, fallback string) string {
for _, key := range keys {
if value := os.Getenv(strings.TrimSpace(key)); value != "" {
return value
}
}
return fallback
}
func getEnvIntAny(keys []string, fallback int) int {
value := getEnvAny(keys, "")
if value == "" {
return fallback
}
parsed, err := strconv.Atoi(value)
if err != nil {
return fallback
}
return parsed
}
func getEnvInt64Any(keys []string, fallback int64) int64 {
value := getEnvAny(keys, "")
if value == "" {
return fallback
}
parsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return fallback
}
return parsed
}
func getEnvBoolAny(keys []string, fallback bool) bool {
value := getEnvAny(keys, "")
if value == "" {
return fallback
}
parsed, err := strconv.ParseBool(value)
if err != nil {
return fallback
}
return parsed
}
func defaultConsumerName(prefix string) string {
host, err := os.Hostname()
if err != nil {
return prefix
}
host = strings.TrimSpace(host)
if host == "" {
return prefix
}
return prefix + "-" + host
}
func loadLuckyGiftConfigs() []LuckyGiftProviderConfig {
raw := strings.TrimSpace(getEnvAny([]string{"CHATAPP_LUCKY_GIFT_CONFIGS_JSON", "LUCKY_GIFT_CONFIGS_JSON", "LUCKY_GIFT_CONFIGS"}, ""))
sharedBaishunAppID := strings.TrimSpace(getEnvAny([]string{"CHATAPP_BAISHUN_APP_ID", "BAISHUN_APP_ID"}, ""))
sharedBaishunAppChannel := strings.TrimSpace(getEnvAny([]string{"CHATAPP_BAISHUN_APP_CHANNEL", "BAISHUN_APP_CHANNEL"}, ""))
sharedBaishunAppKey := strings.TrimSpace(getEnvAny([]string{"CHATAPP_BAISHUN_APP_KEY", "BAISHUN_APP_KEY"}, ""))
if raw != "" {
var list []LuckyGiftProviderConfig
if err := json.Unmarshal([]byte(raw), &list); err == nil {
return normalizeLuckyGiftConfigs(list, sharedBaishunAppID, sharedBaishunAppChannel, sharedBaishunAppKey)
}
var single LuckyGiftProviderConfig
if err := json.Unmarshal([]byte(raw), &single); err == nil {
return normalizeLuckyGiftConfigs([]LuckyGiftProviderConfig{single}, sharedBaishunAppID, sharedBaishunAppChannel, sharedBaishunAppKey)
}
}
single := LuckyGiftProviderConfig{
StandardID: getEnvInt64Any([]string{"CHATAPP_LUCKY_GIFT_STANDARD_ID", "LUCKY_GIFT_STANDARD_ID"}, 0),
URL: getEnvAny([]string{"CHATAPP_LUCKY_GIFT_URL", "LUCKY_GIFT_URL", "LUCKY_GIFT_API_DEFAULT_URL"}, ""),
AppID: getEnvAny([]string{"CHATAPP_LUCKY_GIFT_APP_ID", "LUCKY_GIFT_APP_ID", "LUCKY_GIFT_API_DEFAULT_APP_ID"}, sharedBaishunAppID),
AppChannel: getEnvAny([]string{"CHATAPP_LUCKY_GIFT_APP_CHANNEL", "LUCKY_GIFT_APP_CHANNEL", "LUCKY_GIFT_API_DEFAULT_APP_CHANNEL"}, sharedBaishunAppChannel),
AppKey: getEnvAny([]string{"CHATAPP_LUCKY_GIFT_APP_KEY", "LUCKY_GIFT_APP_KEY", "LUCKY_GIFT_API_DEFAULT_APP_KEY"}, sharedBaishunAppKey),
}
return normalizeLuckyGiftConfigs([]LuckyGiftProviderConfig{single}, sharedBaishunAppID, sharedBaishunAppChannel, sharedBaishunAppKey)
}
func normalizeLuckyGiftConfigs(
list []LuckyGiftProviderConfig,
sharedBaishunAppID string,
sharedBaishunAppChannel string,
sharedBaishunAppKey string,
) []LuckyGiftProviderConfig {
result := make([]LuckyGiftProviderConfig, 0, len(list))
sharedBaishunAppID = strings.TrimSpace(sharedBaishunAppID)
sharedBaishunAppChannel = strings.TrimSpace(sharedBaishunAppChannel)
sharedBaishunAppKey = strings.TrimSpace(sharedBaishunAppKey)
for _, item := range list {
item.URL = strings.TrimSpace(item.URL)
item.AppID = strings.TrimSpace(item.AppID)
item.AppChannel = strings.TrimSpace(item.AppChannel)
item.AppKey = strings.TrimSpace(item.AppKey)
if item.AppID == "" && sharedBaishunAppID != "" {
item.AppID = sharedBaishunAppID
}
if item.AppChannel == "" && sharedBaishunAppChannel != "" {
item.AppChannel = sharedBaishunAppChannel
}
if item.AppKey == "" && sharedBaishunAppKey != "" {
item.AppKey = sharedBaishunAppKey
}
if item.URL == "" || item.AppID == "" || item.AppChannel == "" || item.AppKey == "" {
continue
}
result = append(result, item)
}
return result
}