80 lines
2.4 KiB
PHP
80 lines
2.4 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Settlement\Matchers;
|
||
|
||
use App\Models\TicketItem;
|
||
use Illuminate\Support\Collection;
|
||
use App\Services\Settlement\OddsSnapshotReader;
|
||
use App\Services\Settlement\PublishedDrawResultBoard;
|
||
use App\Services\Settlement\Contracts\SettlementPlayMatcher;
|
||
|
||
/** pos_3abc:后三位命中头/二/三任意一档;取最优档赔率。 */
|
||
final class Pos3AbcSettlementMatcher implements SettlementPlayMatcher
|
||
{
|
||
public function __construct(
|
||
private readonly OddsSnapshotReader $odds,
|
||
) {}
|
||
|
||
public function match(TicketItem $item, PublishedDrawResultBoard $board, Collection $combinations): array
|
||
{
|
||
$tiers = ['first', 'second', 'third'];
|
||
$suffixByTier = [];
|
||
foreach ($tiers as $t) {
|
||
$s = $board->suffix3ForTier($t, 0);
|
||
if ($s !== '') {
|
||
$suffixByTier[$t] = $s;
|
||
}
|
||
}
|
||
if ($suffixByTier === []) {
|
||
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;
|
||
$lines = [];
|
||
$total = 0;
|
||
$bestTier = null;
|
||
$bestRank = 99;
|
||
|
||
$suf = substr((string) $item->normalized_number, -3);
|
||
$hitTier = null;
|
||
$rank = 99;
|
||
foreach ($suffixByTier as $t => $sx) {
|
||
if ($suf !== $sx) {
|
||
continue;
|
||
}
|
||
$r = match ($t) {
|
||
'first' => 0,
|
||
'second' => 1,
|
||
'third' => 2,
|
||
default => 99,
|
||
};
|
||
if ($r < $rank) {
|
||
$rank = $r;
|
||
$hitTier = $t;
|
||
}
|
||
}
|
||
|
||
if ($hitTier !== null) {
|
||
$oddsVal = $this->odds->oddsValueForScope($snapshot, $hitTier);
|
||
$bet = (int) $item->unit_bet_amount;
|
||
$total = (int) floor($bet * ($oddsVal / 10_000));
|
||
$lines[] = [
|
||
'number' => $item->original_number,
|
||
'suffix3' => $suf,
|
||
'tier' => $hitTier,
|
||
'bet_amount' => $bet,
|
||
'odds_value' => $oddsVal,
|
||
'payout' => $total,
|
||
];
|
||
$bestRank = $rank;
|
||
$bestTier = $hitTier;
|
||
}
|
||
|
||
return [
|
||
'win_amount' => $total,
|
||
'matched_prize_tier' => $bestTier,
|
||
'match_detail' => ['lines' => $lines],
|
||
];
|
||
}
|
||
}
|