[ 'supported' => ['zh', 'en', 'ne'], 'fallback' => 'en', ], 'default_currency' => env('LOTTERY_DEFAULT_CURRENCY', 'NPR'), /* | lottery_settings 表读缓存 TTL(秒)。调小可更快看到后台改值,调大减 DB 压力。 */ 'settings' => [ 'cache_ttl_seconds' => (int) env('LOTTERY_SETTINGS_CACHE_TTL', 60), ], 'risk_pool' => [ /** 生产默认使用 Redis Lua 做号码赔付池原子扣减;testing 自动回退 DB,便于无 Redis 跑测试。 */ 'use_redis_lua' => filter_var(env('LOTTERY_RISK_POOL_USE_REDIS_LUA', true), FILTER_VALIDATE_BOOLEAN), ], 'main_site' => [ 'base_url' => env('MAIN_SITE_BASE_URL'), 'sso_jwt_secret' => env('MAIN_SITE_SSO_JWT_SECRET'), 'wallet_api_url' => env('MAIN_SITE_WALLET_API_URL'), 'wallet_api_key' => env('MAIN_SITE_WALLET_API_KEY'), 'wallet_timeout' => (int) env('MAIN_SITE_WALLET_TIMEOUT', 10), /** 主站钱包 HTTP 相对路径(拼接在 wallet_api_url 后);Stub 模式下忽略 */ 'wallet_debit_path' => env('MAIN_SITE_WALLET_DEBIT_PATH', '/wallet/debit-for-lottery'), 'wallet_credit_path' => env('MAIN_SITE_WALLET_CREDIT_PATH', '/wallet/credit-from-lottery'), 'wallet_balance_path' => env('MAIN_SITE_WALLET_BALANCE_PATH', '/wallet/balance'), ], /* | integration:主站接入站点(admin_sites 扩展字段);未配置库表时可回退 main_site env。 */ 'integration' => [ 'default_site_code' => env('LOTTERY_DEFAULT_SITE_CODE', 'default_site'), 'legacy_env_site_code' => env('LOTTERY_LEGACY_MAIN_SITE_CODE', 'default_site'), ], /* | player_auth:配合 app/Services/PlayerTokenResolver.php | | dev_bypass:仅当 APP_ENV∈{local, testing} 且 LOTTERY_PLAYER_AUTH_DEV_BYPASS=true 时, | 允许 Authorization: Bearer dev:{players.id}(否则 dev: 会被当成 JWT 解析并报 8002) | jwt.* :主站签发的 JWT;验签通过后若无映射行则自动建档 | max_ttl_seconds :允许 (exp-iat) 最大秒数(默认 300=5 分钟),与「短效 Token」对齐 | require_iat_claim:为 true 时必须带 iat,否则拒绝(不建档) | | aes.key_base64 :可选。32 字节原始密钥再做 Base64 写入 env LOTTERY_PLAYER_TOKEN_AES_KEY; | 有值时 Bearer 串(非 xxx.yyy.zzz 外形)会先尝试 AES-GCM 解包为内层 JWT 再验签。 */ 'player_auth' => [ 'dev_bypass' => env('LOTTERY_PLAYER_AUTH_DEV_BYPASS', false), 'jwt' => [ 'algorithm' => env('LOTTERY_JWT_ALGORITHM', 'HS256'), 'claim_site_code' => env('LOTTERY_JWT_CLAIM_SITE_CODE', 'site_code'), 'claim_site_player_id' => env('LOTTERY_JWT_CLAIM_SITE_PLAYER_ID', 'site_player_id'), 'max_ttl_seconds' => max(1, min(3600, (int) env('LOTTERY_JWT_MAX_TTL_SECONDS', 300))), 'require_iat_claim' => filter_var(env('LOTTERY_JWT_REQUIRE_IAT', true), FILTER_VALIDATE_BOOLEAN), ], 'aes' => [ 'key_base64' => env('LOTTERY_PLAYER_TOKEN_AES_KEY'), ], ], /* | admin_api:Sanctum Personal Access Token(auth:sanctum + lottery.admin) | | token_ttl_days:签发时刻起有效日历天数,到期后 Laravel 拒绝该 token,需重新登录。 */ 'admin_api' => [ 'token_ttl_days' => max(1, (int) env('ADMIN_API_TOKEN_TTL_DAYS', 7)), ], /* | 期号调度:PRD/界面文档约定为服务器时区 GMT(即 UTC)。 | 生成计划、封盘判定、API ISO 时刻、前后台 YYYY-MM-DD HH:mm:ss 展示均按 UTC 解释,勿改为本地时区。 */ 'draw' => [ /** 期号「业务日」切分与计划时刻(固定 UTC,与 {@see docs/01-界面文档.md} 一致) */ 'timezone' => 'UTC', /** 开奖时间间隔(分钟),整日从 00:00 起排槽 */ 'interval_minutes' => max(1, min(1440, (int) env('LOTTERY_DRAW_INTERVAL_MINUTES', 5))), /** 下注开放时长(秒):start_time = close_time - betting_window_seconds */ 'betting_window_seconds' => max(10, (int) env('LOTTERY_DRAW_BETTING_WINDOW_SECONDS', 270)), /** 开奖前若干秒封盘:close_time = draw_time - 该值 */ 'close_before_draw_seconds' => max(5, (int) env('LOTTERY_DRAW_CLOSE_BEFORE_SECONDS', 30)), /** 预生成尚未开奖的期号数量(调度补齐);生产可调大,本地/联测建议 6–12 */ 'buffer_draws_ahead' => max(1, (int) env('LOTTERY_DRAW_BUFFER_AHEAD', 8)), /** true:RNG 后进入 review,需后台接口发布 */ 'require_manual_review' => filter_var(env('LOTTERY_DRAW_REQUIRE_MANUAL_REVIEW', true), FILTER_VALIDATE_BOOLEAN), /** 结果发布后的冷静期(分钟),{@see draws.cooling_end_time} */ 'cooldown_minutes' => max(0, (int) env('LOTTERY_DRAW_COOLDOWN_MINUTES', 15)), ], /* | ui.format:API 中 *_formatted 展示用(由 {@see \App\Support\CurrencyFormatter} 读取) */ 'ui' => [ 'format' => [ 'currency' => [ 'decimals' => max(0, min(12, (int) env('LOTTERY_CURRENCY_DISPLAY_DECIMALS', 2))), 'decimal_separator' => env('LOTTERY_CURRENCY_DECIMAL_SEP', '.'), 'thousands_separator' => env('LOTTERY_CURRENCY_THOUSANDS_SEP', ','), ], ], ], ];