Files
lotteryLaravel/config/lottery.php
kang d4779660c8
Some checks failed
lotterLaravel CI / test (push) Has been cancelled
lotterLaravel E2E / e2e-api (push) Has been cancelled
feat(draw): 支持多玩法provider及本地化结算时区功能
- Draw相关控制器添加provider_code和provider_name字段支持
- 允许手动录入开奖批次时指定provider_code
- RNG开奖批次生成支持多provider,分别生成对应批次数据
- DrawPublishService和DrawManualResultService中支持基于provider_code管理开奖版本和发布流程
- DrawResultViewService调整,支持按provider汇总及筛选开奖结果
- Settlement处理逻辑调整,按provider区分待结算票据及批次,分开结算
- 结算期间管理相关服务支持使用站点本地结算时区计算开账建议和日期处理
- 增加AdminSite的settlement_timezone字段及相关请求验证和数据存取支持
- 优化AdminSettlementPeriod相关代码,防止存在未结清票据时关账
- Ticket明细返回接口添加结算时区信息,提升用户时间体验
- 多处查询排序和版本号处理改进,保证多provider数据正确顺序与一致性
2026-07-09 15:48:21 +08:00

137 lines
7.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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'),
'settlement' => [
'default_timezone' => env('LOTTERY_SETTLEMENT_TIMEZONE', env('APP_TIMEZONE', 'UTC')),
],
/*
| 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),
/** 风险池 Redis 快照键 TTL每次初始化/扣减/释放/同步都会续期。 */
'redis_ttl_seconds' => max(60, (int) env('LOTTERY_RISK_POOL_REDIS_TTL_SECONDS', 86400)),
],
'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'),
'wallet_lookup_idempotent_path' => env('MAIN_SITE_WALLET_LOOKUP_IDEMPOTENT_PATH', '/wallet/lookup-idempotent'),
],
/*
| 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'),
],
'native' => [
'secret' => env('LOTTERY_NATIVE_JWT_SECRET', env('MAIN_SITE_SSO_JWT_SECRET', '')),
'ttl_seconds' => max(300, min(86400, (int) env('LOTTERY_NATIVE_JWT_TTL_SECONDS', 28800))),
'claim_player_id' => 'player_id',
'claim_auth_source' => 'auth_source',
'max_login_attempts' => max(3, (int) env('LOTTERY_NATIVE_LOGIN_MAX_ATTEMPTS', 8)),
'lock_minutes' => max(1, (int) env('LOTTERY_NATIVE_LOGIN_LOCK_MINUTES', 15)),
],
],
/*
| admin_apiSanctum Personal Access Tokenauth: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' => env('LOTTERY_DRAW_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)),
/** 预生成尚未开奖的期号数量(调度补齐);生产可调大,本地/联测建议 612 */
'buffer_draws_ahead' => max(1, (int) env('LOTTERY_DRAW_BUFFER_AHEAD', 8)),
/** trueRNG 后进入 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)),
],
/*
| 大厅实时倒计时广播:调度维持每秒,保障封盘/开奖/切期边界精度;
| 完整快照默认按较低频率校准,边界变化时立即补发。
| 可选校准秒数仅支持 Laravel 调度原生子分钟频率1 / 2 / 5 / 10。
*/
'realtime_hall_countdown' => filter_var(env('LOTTERY_REALTIME_HALL_COUNTDOWN', true), FILTER_VALIDATE_BOOLEAN),
'realtime_hall_countdown_sync_interval_seconds' => max(1, (int) env('LOTTERY_REALTIME_HALL_COUNTDOWN_SYNC_INTERVAL_SECONDS', 5)),
'realtime_hall_countdown_warn_threshold_ms' => max(100, (int) env('LOTTERY_REALTIME_HALL_COUNTDOWN_WARN_THRESHOLD_MS', 800)),
'draw_tick_warn_threshold_ms' => max(100, (int) env('LOTTERY_DRAW_TICK_WARN_THRESHOLD_MS', 1500)),
'draw_tick_stage_warn_threshold_ms' => max(50, (int) env('LOTTERY_DRAW_TICK_STAGE_WARN_THRESHOLD_MS', 500)),
'draw_tick_settle_limit' => max(1, (int) env('LOTTERY_DRAW_TICK_SETTLE_LIMIT', 3)),
'draw_tick_finalize_limit' => max(1, (int) env('LOTTERY_DRAW_TICK_FINALIZE_LIMIT', 5)),
'draw_tick_rng_limit' => max(1, (int) env('LOTTERY_DRAW_TICK_RNG_LIMIT', 10)),
];