feat(draw): 支持多玩法provider及本地化结算时区功能
Some checks failed
lotterLaravel CI / test (push) Has been cancelled
lotterLaravel E2E / e2e-api (push) Has been cancelled

- Draw相关控制器添加provider_code和provider_name字段支持
- 允许手动录入开奖批次时指定provider_code
- RNG开奖批次生成支持多provider,分别生成对应批次数据
- DrawPublishService和DrawManualResultService中支持基于provider_code管理开奖版本和发布流程
- DrawResultViewService调整,支持按provider汇总及筛选开奖结果
- Settlement处理逻辑调整,按provider区分待结算票据及批次,分开结算
- 结算期间管理相关服务支持使用站点本地结算时区计算开账建议和日期处理
- 增加AdminSite的settlement_timezone字段及相关请求验证和数据存取支持
- 优化AdminSettlementPeriod相关代码,防止存在未结清票据时关账
- Ticket明细返回接口添加结算时区信息,提升用户时间体验
- 多处查询排序和版本号处理改进,保证多provider数据正确顺序与一致性
This commit is contained in:
2026-07-09 15:48:21 +08:00
parent c6c10f1397
commit d4779660c8
38 changed files with 1121 additions and 271 deletions

View File

@@ -103,6 +103,8 @@ final class AdminDrawApiPresenter
$row = [
'id' => (int) $batch->id,
'provider_code' => $batch->provider_code,
'provider_name' => $batch->provider_name,
'result_version' => (int) $batch->result_version,
'status' => $batch->status,
'confirmed_at' => $batch->confirmed_at?->toIso8601String(),

View File

@@ -17,6 +17,7 @@ final class AdminIntegrationSitePresenter
'name' => (string) $site->name,
'has_line_root' => $hasLineRoot,
'currency_code' => (string) $site->currency_code,
'settlement_timezone' => (string) ($site->settlement_timezone ?? config('lottery.settlement.default_timezone', 'UTC')),
'status' => (int) $site->status,
'wallet_api_url' => $site->wallet_api_url,
'lottery_h5_base_url' => $site->lottery_h5_base_url,
@@ -96,6 +97,7 @@ final class AdminIntegrationSitePresenter
'name' => (string) $site->name,
'status' => (int) $site->status === 1 ? 'enabled' : 'disabled',
'currency_code' => (string) $site->currency_code,
'settlement_timezone' => (string) ($site->settlement_timezone ?? config('lottery.settlement.default_timezone', 'UTC')),
'lottery_h5_base_url' => $h5Base,
'wallet_api_url' => $site->wallet_api_url,
'wallet_balance_url' => $fullUrl($site->wallet_balance_path),

View File

@@ -30,12 +30,15 @@ final class AgentSettlementPeriodWindow
}
/**
* 开账 API支持 `Y-m-d` 或带时刻字符串;前者按 UTC 自然日扩界,后者按 UTC 解释。
* 开账 API支持 `Y-m-d` 或带时刻字符串;前者按站点业务时区扩界,后者按 UTC 解释。
*
* @return array{0: string, 1: string}
*/
public static function normalizeInputBounds(string $periodStart, string $periodEnd): array
{
public static function normalizeInputBounds(
string $periodStart,
string $periodEnd,
string $timezone = 'UTC',
): array {
$startRaw = trim($periodStart);
$endRaw = trim($periodEnd);
@@ -45,12 +48,14 @@ final class AgentSettlementPeriodWindow
]);
}
$tz = AgentSettlementSiteTimezone::isValid($timezone) ? $timezone : 'UTC';
$startAt = self::isDateOnly($startRaw)
? Carbon::parse($startRaw.' 00:00:00', 'UTC')
? Carbon::parse($startRaw.' 00:00:00', $tz)->utc()
: Carbon::parse($startRaw)->utc();
$endAt = self::isDateOnly($endRaw)
? Carbon::parse($endRaw.' 23:59:59', 'UTC')
? Carbon::parse($endRaw.' 23:59:59', $tz)->utc()
: Carbon::parse($endRaw)->utc();
if ($endAt->lessThan($startAt)) {

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Support;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
final class AgentSettlementSiteTimezone
{
public static function forSiteId(int $adminSiteId): string
{
return self::normalize((string) (DB::table('admin_sites')
->where('id', $adminSiteId)
->value('settlement_timezone') ?? ''));
}
public static function forSiteCode(string $siteCode): string
{
return self::normalize((string) (DB::table('admin_sites')
->where('code', $siteCode)
->value('settlement_timezone') ?? ''));
}
public static function isValid(?string $timezone): bool
{
return is_string($timezone)
&& $timezone !== ''
&& in_array($timezone, timezone_identifiers_list(), true);
}
public static function localDayFromUtc(mixed $instant, string $timezone): string
{
return Carbon::parse((string) $instant, 'UTC')
->timezone($timezone)
->toDateString();
}
private static function normalize(?string $timezone): string
{
if (self::isValid($timezone)) {
return (string) $timezone;
}
$fallback = (string) config('lottery.settlement.default_timezone', config('app.timezone', 'UTC'));
return self::isValid($fallback) ? $fallback : 'UTC';
}
}