feat: 增强奖池与钱包服务的多币种支持能力
更新 JackpotManualBurstService:在解析头奖中奖者时支持币种代码处理。 重构 SettlementBatchWorkflowService:按币种聚合玩家派奖金额,确保各币种结算准确入账。 修改 SettlementOrchestrator:按币种分别处理奖池爆奖流程,提升派奖准确性。 优化 TicketWalletService:在派奖幂等键中加入币种信息,避免多币种场景下的重复处理问题。 新增测试用例,验证多币种派奖场景及待处理交易的正确处理逻辑。
This commit is contained in:
@@ -125,28 +125,41 @@ final class SettlementOrchestrator
|
||||
];
|
||||
}
|
||||
|
||||
$currency = strtoupper((string) ($ticketItems->first()?->order?->currency_code ?? 'NPR'));
|
||||
$pool = JackpotPool::query()
|
||||
->where('currency_code', $currency)
|
||||
->where('status', 1)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
$allocations = [];
|
||||
$totalJackpotPayout = 0;
|
||||
$jackpotTrigger = null;
|
||||
$jackpotPoolAfter = null;
|
||||
if ($pool !== null) {
|
||||
$burstInput = collect($prepared)->map(fn (array $p): array => [
|
||||
$jackpotBursts = [];
|
||||
$preparedByCurrency = collect($prepared)->groupBy(
|
||||
fn (array $p): string => strtoupper((string) ($p['item']->order?->currency_code ?? 'NPR')),
|
||||
);
|
||||
foreach ($preparedByCurrency as $currency => $currencyPrepared) {
|
||||
$pool = JackpotPool::query()
|
||||
->where('currency_code', $currency)
|
||||
->where('status', 1)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
if ($pool === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$burstInput = collect($currencyPrepared)->map(fn (array $p): array => [
|
||||
'item' => $p['item'],
|
||||
'matched_tier' => $p['matched_tier'],
|
||||
'gross_win' => $p['gross_win'],
|
||||
]);
|
||||
$burstOut = $this->jackpotBurst->allocate($locked, $pool, $burstInput);
|
||||
$allocations = $burstOut['allocations'];
|
||||
$totalJackpotPayout = (int) $burstOut['pool_payout'];
|
||||
$jackpotTrigger = $burstOut['trigger'];
|
||||
$jackpotPoolAfter = (int) $pool->fresh()->current_amount;
|
||||
$allocations = array_replace($allocations, $burstOut['allocations']);
|
||||
$currencyPayout = (int) $burstOut['pool_payout'];
|
||||
$totalJackpotPayout += $currencyPayout;
|
||||
|
||||
if ($currencyPayout > 0 && is_string($burstOut['trigger'])) {
|
||||
$jackpotBursts[] = [
|
||||
'currency' => $currency,
|
||||
'payout' => $currencyPayout,
|
||||
'trigger' => $burstOut['trigger'],
|
||||
'pool_after' => (int) $pool->fresh()->current_amount,
|
||||
'winner_count' => count($burstOut['allocations']),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$ticketCount = 0;
|
||||
@@ -206,16 +219,16 @@ final class SettlementOrchestrator
|
||||
'settle_version' => $nextSettleVersion,
|
||||
])->save();
|
||||
|
||||
if ($pool !== null && $totalJackpotPayout > 0 && is_string($jackpotTrigger)) {
|
||||
foreach ($jackpotBursts as $burst) {
|
||||
$this->hallRealtime->notifyJackpotBurst(
|
||||
(int) $locked->id,
|
||||
(string) $locked->draw_no,
|
||||
$board->firstPrizeNumber4d(),
|
||||
$currency,
|
||||
$totalJackpotPayout,
|
||||
count($allocations),
|
||||
$jackpotTrigger,
|
||||
(int) $jackpotPoolAfter,
|
||||
(string) $burst['currency'],
|
||||
(int) $burst['payout'],
|
||||
(int) $burst['winner_count'],
|
||||
(string) $burst['trigger'],
|
||||
(int) $burst['pool_after'],
|
||||
);
|
||||
$this->hallRealtime->notifyStatusChange($this->hallSnapshot->build());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user