fix(core): harden settlement and wallet integration
This commit is contained in:
@@ -4,10 +4,10 @@ namespace App\Services\AgentSettlement;
|
||||
|
||||
use App\Models\Player;
|
||||
use App\Models\TicketItem;
|
||||
use App\Services\Player\PlayerCreditService;
|
||||
use App\Support\PlayerFundingMode;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\QueryException;
|
||||
use App\Services\Player\PlayerCreditService;
|
||||
|
||||
final class GameSettlementReversalService
|
||||
{
|
||||
@@ -15,16 +15,26 @@ final class GameSettlementReversalService
|
||||
private readonly PlayerCreditService $playerCreditService,
|
||||
) {}
|
||||
|
||||
public function reverseTicketItem(TicketItem $item): void
|
||||
public function reverseTicketItem(TicketItem $item, int $settlementVersion = 0): void
|
||||
{
|
||||
$ledger = DB::table('share_ledger')->where('ticket_item_id', $item->id)->whereNull('reversal_of_id')->first();
|
||||
$ledger = DB::table('share_ledger as sl')
|
||||
->where('sl.ticket_item_id', $item->id)
|
||||
->whereNull('sl.reversal_of_id')
|
||||
->whereNotExists(function ($query): void {
|
||||
$query->selectRaw('1')
|
||||
->from('share_ledger as reversal')
|
||||
->whereColumn('reversal.reversal_of_id', 'sl.id');
|
||||
})
|
||||
->orderByDesc('sl.id')
|
||||
->select('sl.*')
|
||||
->first();
|
||||
if ($ledger === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settledAt = now();
|
||||
|
||||
DB::transaction(function () use ($item, $ledger, $settledAt): void {
|
||||
DB::transaction(function () use ($item, $ledger, $settledAt, $settlementVersion): void {
|
||||
// 幂等闸门:share_ledger.reversal_of_id 上有 partial unique 索引,
|
||||
// 同一原账不允许插入多条反转记录。重复调用时唯一约束冲突即视为已反转、跳过。
|
||||
// 一次只让 reversal_of_id 出现一次写入,确保所有后续副作用(rebate、credit 冲正)
|
||||
@@ -79,8 +89,14 @@ final class GameSettlementReversalService
|
||||
if ($player !== null && PlayerFundingMode::usesCredit($player)) {
|
||||
$gameWinLoss = (int) $ledger->game_win_loss;
|
||||
if ($gameWinLoss !== 0) {
|
||||
$this->playerCreditService->reverseGameSettlement($player, $gameWinLoss, $item->id);
|
||||
$this->playerCreditService->reverseGameSettlement($player, $gameWinLoss, $item->id, $settlementVersion);
|
||||
}
|
||||
$this->playerCreditService->restoreBetHoldAfterSettlementReversal(
|
||||
$player,
|
||||
(int) $item->actual_deduct_amount,
|
||||
(int) $item->id,
|
||||
$settlementVersion,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user