feat(bet-provider): 添加开注商管理功能,包括增删改查接口及相关模型和迁移文件
Some checks failed
lotterLaravel CI / test (push) Has been cancelled
lotterLaravel E2E / e2e-api (push) Has been cancelled

This commit is contained in:
2026-07-08 15:56:35 +08:00
parent fbe182f6e6
commit 2d50980999
19 changed files with 382 additions and 57 deletions

View File

@@ -30,6 +30,7 @@ final class TicketPlacementService
private readonly JackpotContributionService $jackpotContribution,
private readonly DrawHallSnapshotBuilder $drawHallSnapshot,
private readonly PlayerCreditService $playerCreditService,
private readonly BetProviderResolver $betProviderResolver,
) {}
/**
@@ -118,6 +119,9 @@ final class TicketPlacementService
}
$configVersions = $this->catalogResolver->lockActiveConfigVersionsForPlacement($expectedVersions);
$providers = $this->betProviderResolver->resolve(
is_array($payload['provider_codes'] ?? null) ? $payload['provider_codes'] : null,
);
$evaluatedLines = [];
$totalBet = 0;
@@ -141,25 +145,24 @@ final class TicketPlacementService
throw $e;
}
$evaluated = $this->ruleEngine->evaluateLine(
(array) $line,
$resolved['play_config'],
$resolved['odds_items'],
);
$evaluated = $this->rebateApplicator->apply($player, $evaluated);
foreach ($providers as $provider) {
$evaluated = $this->ruleEngine->evaluateLine(
(array) $line,
$resolved['play_config'],
$resolved['odds_items'],
);
$evaluated = $this->rebateApplicator->apply($player, $evaluated);
$evaluated['provider_code'] = $provider['code'];
$evaluated['provider_name'] = $provider['name'];
$locks = array_map(fn (array $combo): array => [
'number_4d' => $combo['number_4d'],
'amount' => $combo['estimated_payout'],
], $evaluated['combinations']);
// place 阶段以 acquire 的原子扣减结果为准,允许单行售罄后形成混合成功/失败结果。
$evaluatedLines[] = $evaluated;
$rebateAmount = $this->rebateApplicator->persistedInstantRebateAmount($player, $evaluated);
$totalBet += (int) $evaluated['total_bet_amount'];
$totalRebate += $rebateAmount;
$totalActualDeduct += (int) $evaluated['actual_deduct_amount'];
$totalEstimatedPayout += (int) $evaluated['estimated_max_payout'];
// place 阶段以 acquire 的原子扣减结果为准,允许单行售罄后形成混合成功/失败结果。
$evaluatedLines[] = $evaluated;
$rebateAmount = $this->rebateApplicator->persistedInstantRebateAmount($player, $evaluated);
$totalBet += (int) $evaluated['total_bet_amount'];
$totalRebate += $rebateAmount;
$totalActualDeduct += (int) $evaluated['actual_deduct_amount'];
$totalEstimatedPayout += (int) $evaluated['estimated_max_payout'];
}
}
if ($closedPlayCleanupRows !== []) {
@@ -241,6 +244,8 @@ final class TicketPlacementService
'order_id' => $order->id,
'player_id' => $player->id,
'draw_id' => $draw->id,
'provider_code' => $evaluated['provider_code'],
'provider_name' => $evaluated['provider_name'],
'original_number' => $evaluated['original_number'],
'normalized_number' => $this->normalizedNumberForStorage($evaluated),
'play_code' => $evaluated['play_code'],
@@ -483,6 +488,8 @@ final class TicketPlacementService
->get()
->map(fn (TicketItem $item) => [
'ticket_no' => $item->ticket_no,
'provider_code' => $item->provider_code,
'provider_name' => $item->provider_name,
'play_code' => $item->play_code,
'number' => $item->original_number,
'total_bet_amount' => (int) $item->total_bet_amount,