- Updated AGENTS.md to clarify agent account restrictions and permissions. - Implemented checks in AgentNodeAdminUserStoreController and AgentNodeRoleStoreController to restrict admin user and role creation to the agent's own node. - Enhanced validation in AdminPlayerStoreController and AdminPlayerUpdateController to enforce credit limit and rebate rate rules based on player funding mode. - Refactored various request classes to utilize shared admin account field rules for consistency. - Improved error handling in services related to credit allocation and rebate limits to ensure proper validation and messaging.
79 lines
2.6 KiB
PHP
79 lines
2.6 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Ticket;
|
||
|
||
use App\Models\Player;
|
||
use App\Support\PlayerFundingMode;
|
||
|
||
/**
|
||
* 下注行回水:钱包盘立减实扣;信用盘仅展示账期回水预估,实扣仍按全额占用授信。
|
||
*/
|
||
final class TicketLineInstantRebateApplicator
|
||
{
|
||
public function __construct(
|
||
private readonly InstantRebateResolver $instantRebateResolver,
|
||
) {}
|
||
|
||
/**
|
||
* @param array<string, mixed> $evaluated
|
||
* @return array<string, mixed>
|
||
*/
|
||
public function apply(Player $player, array $evaluated): array
|
||
{
|
||
$resolved = $this->instantRebateResolver->resolveForPlayer(
|
||
$player,
|
||
(string) $evaluated['play_code'],
|
||
(float) $evaluated['rebate_rate_snapshot'],
|
||
);
|
||
|
||
$evaluated['rule_snapshot_json']['base_rebate_rate'] = number_format($resolved['base_rebate_rate'], 4, '.', '');
|
||
$evaluated['rule_snapshot_json']['player_addon_rebate_rate'] = number_format($resolved['player_addon_rebate_rate'], 4, '.', '');
|
||
$evaluated['rule_snapshot_json']['rebate_inherited_from_agent'] = $resolved['inherited_from_agent'];
|
||
$evaluated['rule_snapshot_json']['instant_rebate_applied'] = ! PlayerFundingMode::usesCredit($player);
|
||
|
||
$finalRate = $resolved['final_rebate_rate'];
|
||
$evaluated['rebate_rate_snapshot'] = number_format($finalRate, 4, '.', '');
|
||
|
||
if (PlayerFundingMode::usesCredit($player)) {
|
||
$evaluated['actual_deduct_amount'] = (int) $evaluated['total_bet_amount'];
|
||
|
||
return $evaluated;
|
||
}
|
||
|
||
$evaluated['actual_deduct_amount'] = max(
|
||
0,
|
||
(int) floor((int) $evaluated['total_bet_amount'] * (1 - $finalRate)),
|
||
);
|
||
|
||
return $evaluated;
|
||
}
|
||
|
||
/**
|
||
* 确认弹窗展示用回水:信用盘为账期回水预估,钱包盘为下注立减额。
|
||
*
|
||
* @param array<string, mixed> $evaluated
|
||
*/
|
||
public function displayRebateAmount(Player $player, array $evaluated): int
|
||
{
|
||
$bet = (int) $evaluated['total_bet_amount'];
|
||
|
||
if (PlayerFundingMode::usesCredit($player)) {
|
||
$rate = (float) ($evaluated['rebate_rate_snapshot'] ?? 0);
|
||
|
||
return (int) floor($bet * max(0.0, min(1.0, $rate)));
|
||
}
|
||
|
||
return max(0, $bet - (int) $evaluated['actual_deduct_amount']);
|
||
}
|
||
|
||
/** 落库订单/注单上的即时回水合计(信用盘为 0)。 */
|
||
public function persistedInstantRebateAmount(Player $player, array $evaluated): int
|
||
{
|
||
if (PlayerFundingMode::usesCredit($player)) {
|
||
return 0;
|
||
}
|
||
|
||
return $this->displayRebateAmount($player, $evaluated);
|
||
}
|
||
}
|