package config import ( "encoding/json" "os" "strconv" "strings" "time" ) // Config 是按运行层和业务模块分段后的应用配置。 type Config struct { HTTP HTTPConfig Store StoreConfig Java JavaConfig Worker WorkerConfig Invite InviteConfig RechargeReward RechargeRewardConfig 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 OrderBaseURL 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 } // RechargeRewardConfig 保存充值奖励活动配置。 type RechargeRewardConfig struct { DefaultSysOrigin string Timezone 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), OrderBaseURL: getEnvAny([]string{"CHATAPP_JAVA_ORDER_BASE_URL", "GAME_JAVA_ORDER_BASE_URL"}, "http://127.0.0.1:2600"), 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"), }, RechargeReward: RechargeRewardConfig{ DefaultSysOrigin: strings.ToUpper(getEnvAny( []string{"CHATAPP_RECHARGE_REWARD_DEFAULT_SYS_ORIGIN", "RECHARGE_REWARD_DEFAULT_SYS_ORIGIN", "CHATAPP_WEEK_STAR_DEFAULT_SYS_ORIGIN", "WEEK_STAR_DEFAULT_SYS_ORIGIN"}, "LIKEI", )), Timezone: getEnvAny( []string{"CHATAPP_RECHARGE_REWARD_TIMEZONE", "RECHARGE_REWARD_TIMEZONE", "CHATAPP_WEEK_STAR_TIMEZONE", "WEEK_STAR_TIMEZONE"}, "Asia/Riyadh", ), }, 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 }