- 新增 API 路由和控制器,允许管理员手动创建、更新和删除抽奖期号。 - 更新抽奖调度逻辑,确保在抽奖时间和封盘时间的管理上更加灵活。 - 添加多语言支持的错误信息,提升用户体验。 - 更新测试用例,确保新功能的正确性和稳定性。
111 lines
5.4 KiB
PHP
111 lines
5.4 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 彩票业务配置(多语言、主站 SSO、玩家鉴权等)。
|
||
*
|
||
* 【locales】API 返回 msg 时使用的语言集合,与库表多语言列命名一致(zh / en / ne)。
|
||
* - supported:合法语言列表;NegotiateLotteryLocale 只会在其中选择。
|
||
* - fallback:无匹配头或缺翻译键时的兜底语言(通常用 en)。
|
||
*/
|
||
|
||
return [
|
||
'locales' => [
|
||
'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'),
|
||
],
|
||
|
||
/*
|
||
| 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', ','),
|
||
],
|
||
],
|
||
],
|
||
];
|