58 lines
1.9 KiB
PHP
58 lines
1.9 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Settlement\Matchers;
|
||
|
||
use App\Models\TicketCombination;
|
||
use App\Models\TicketItem;
|
||
use App\Services\Settlement\Contracts\SettlementPlayMatcher;
|
||
use App\Services\Settlement\OddsSnapshotReader;
|
||
use App\Services\Settlement\PublishedDrawResultBoard;
|
||
use Illuminate\Support\Collection;
|
||
|
||
/** pos_2a / pos_2b / pos_2c:后二位命中对应档。 */
|
||
final class Pos2TierSettlementMatcher implements SettlementPlayMatcher
|
||
{
|
||
/** @var array<string, string> */
|
||
private const PLAY_TO_TIER = [
|
||
'pos_2a' => 'first',
|
||
'pos_2b' => 'second',
|
||
'pos_2c' => 'third',
|
||
];
|
||
|
||
public function __construct(
|
||
private readonly OddsSnapshotReader $odds,
|
||
) {}
|
||
|
||
public function match(TicketItem $item, PublishedDrawResultBoard $board, Collection $combinations): array
|
||
{
|
||
$tier = self::PLAY_TO_TIER[$item->play_code] ?? 'first';
|
||
$suffix = $board->suffix2ForTier($tier, 0);
|
||
if ($suffix === '') {
|
||
return ['win_amount' => 0, 'matched_prize_tier' => null, 'match_detail' => ['reason' => 'no_suffix']];
|
||
}
|
||
|
||
$snapshot = is_array($item->odds_snapshot_json) ? $item->odds_snapshot_json : null;
|
||
$oddsVal = $this->odds->oddsValueForScope($snapshot, $tier);
|
||
$lines = [];
|
||
$total = 0;
|
||
|
||
foreach ($combinations as $c) {
|
||
/** @var TicketCombination $c */
|
||
$n = (string) $c->number_4d;
|
||
if (strlen($n) < 2 || substr($n, -2) !== $suffix) {
|
||
continue;
|
||
}
|
||
$bet = (int) $c->bet_amount;
|
||
$payout = (int) floor($bet * ($oddsVal / 10_000));
|
||
$total += $payout;
|
||
$lines[] = ['number_4d' => $n, 'suffix2' => $suffix, 'payout' => $payout];
|
||
}
|
||
|
||
return [
|
||
'win_amount' => $total,
|
||
'matched_prize_tier' => $total > 0 ? $tier : null,
|
||
'match_detail' => ['lines' => $lines],
|
||
];
|
||
}
|
||
}
|