Files
lotteryLaravel/app/Services/Ticket/NumberNormalizer.php
kang cbb18b976f
Some checks failed
lotterLaravel CI / test (push) Has been cancelled
lotterLaravel E2E / e2e-api (push) Has been cancelled
feat(lottery): 扩展传统马来赔率、玩法结算与开注商短码支持
2026-07-10 17:04:28 +08:00

62 lines
2.1 KiB
PHP

<?php
namespace App\Services\Ticket;
use App\Lottery\ErrorCode;
use App\Exceptions\TicketOperationException;
final class NumberNormalizer
{
public function normalize(string $playCode, string $number, ?string $dimension = null): string
{
$trimmed = strtoupper(str_replace(' ', '', trim($number)));
return match ($playCode) {
'roll' => $this->normalizeRoll($trimmed),
default => $this->normalizeDigits($playCode, $trimmed, $dimension),
};
}
private function normalizeRoll(string $value): string
{
if (! preg_match('/^[0-9R]{4}$/', $value)) {
throw new TicketOperationException('invalid_roll_number', ErrorCode::BetInvalidNumber->value);
}
if (! str_contains($value, 'R')) {
throw new TicketOperationException('roll_requires_r', ErrorCode::BetInvalidPlayInput->value);
}
return $value;
}
private function normalizeDigits(string $playCode, string $value, ?string $dimension = null): string
{
if (! preg_match('/^[0-9]+$/', $value)) {
throw new TicketOperationException('invalid_number', ErrorCode::BetInvalidNumber->value);
}
$length = strlen($value);
$expected = match ($playCode) {
'big', 'small', 'pos_4a', 'pos_4b', 'pos_4c', 'pos_4d', 'pos_4e', 'four_any', 'four_top', 'four_lower', 'straight', 'box', 'ibox', 'mbox' => 4,
'pos_3a', 'pos_3b', 'pos_3c', 'pos_3d', 'pos_3e', 'pos_3lower', 'pos_3abc' => 3,
'pos_2a', 'pos_2b', 'pos_2c', 'pos_2d', 'pos_2e', 'pos_2any', 'pos_2abc' => 2,
'five_d' => 5,
'six_d' => 6,
'head', 'tail', 'odd', 'even', 'digit_big', 'digit_small' => match ($dimension) {
'D2' => 1,
'D3' => 1,
'D4', null => 1,
default => 1,
},
default => null,
};
if ($expected !== null && $length !== $expected) {
throw new TicketOperationException('invalid_number_length', ErrorCode::BetInvalidNumber->value);
}
return $value;
}
}