feat: 新增赔率版本和玩法配置版本的删除接口,支持删除草稿版本

This commit is contained in:
2026-05-15 15:30:40 +08:00
parent 5398af0a55
commit c0cd8be0fb
18 changed files with 574 additions and 125 deletions

View File

@@ -137,28 +137,17 @@ final class LotteryTransferService
DB::transaction(function () use ($player, $currencyCode, $amountMinor, $order, $main, $transferNo, $idempotentKey): void {
$wallet = $this->lockLotteryWallet($player, $currencyCode);
$before = (int) $wallet->balance;
$after = $before + $amountMinor;
$wallet->forceFill([
'balance' => $after,
'version' => (int) $wallet->version + 1,
])->save();
WalletTxn::query()->create([
'txn_no' => $this->newTxnNo(),
'player_id' => $player->id,
'wallet_id' => $wallet->id,
'biz_type' => self::BIZ_TRANSFER_IN,
'biz_no' => $transferNo,
'direction' => self::TXN_DIR_IN,
'amount' => $amountMinor,
'balance_before' => $before,
'balance_after' => $after,
'status' => self::TXN_POSTED,
'external_ref_no' => $main->externalRefNo,
'idempotent_key' => $idempotentKey,
'remark' => null,
]);
$this->postLotteryWalletMovement(
wallet: $wallet,
bizType: self::BIZ_TRANSFER_IN,
direction: self::TXN_DIR_IN,
amountMinor: $amountMinor,
bizNo: $transferNo,
externalRefNo: $main->externalRefNo,
idempotentKey: $idempotentKey,
remark: null,
deltaSign: 1,
);
$order->forceFill([
'status' => self::ST_SUCCESS,
@@ -222,34 +211,18 @@ final class LotteryTransferService
try {
DB::transaction(function () use ($player, $currencyCode, $amountMinor, $transferNo, $idempotentKey): void {
$wallet = $this->lockLotteryWallet($player, $currencyCode);
$before = (int) $wallet->balance;
if ($before < $amountMinor) {
throw new WalletOperationException(
'insufficient_balance',
ErrorCode::WalletInsufficientBalance->value,
);
}
$after = $before - $amountMinor;
$wallet->forceFill([
'balance' => $after,
'version' => (int) $wallet->version + 1,
])->save();
WalletTxn::query()->create([
'txn_no' => $this->newTxnNo(),
'player_id' => $player->id,
'wallet_id' => $wallet->id,
'biz_type' => self::BIZ_TRANSFER_OUT,
'biz_no' => $transferNo,
'direction' => self::TXN_DIR_OUT,
'amount' => $amountMinor,
'balance_before' => $before,
'balance_after' => $after,
'status' => self::TXN_POSTED,
'external_ref_no' => null,
'idempotent_key' => $idempotentKey,
'remark' => null,
]);
$this->postLotteryWalletMovement(
wallet: $wallet,
bizType: self::BIZ_TRANSFER_OUT,
direction: self::TXN_DIR_OUT,
amountMinor: $amountMinor,
bizNo: $transferNo,
externalRefNo: null,
idempotentKey: $idempotentKey,
remark: null,
deltaSign: -1,
requireBalance: true,
);
});
} catch (WalletOperationException $e) {
if ($e->lotteryCode === ErrorCode::WalletInsufficientBalance->value) {
@@ -292,28 +265,17 @@ final class LotteryTransferService
DB::transaction(function () use ($player, $currencyCode, $amountMinor, $transferNo, $idempotentKey, $order, $main): void {
$wallet = $this->lockLotteryWallet($player, $currencyCode);
$before = (int) $wallet->balance;
$after = $before + $amountMinor;
$wallet->forceFill([
'balance' => $after,
'version' => (int) $wallet->version + 1,
])->save();
WalletTxn::query()->create([
'txn_no' => $this->newTxnNo(),
'player_id' => $player->id,
'wallet_id' => $wallet->id,
'biz_type' => self::BIZ_TRANSFER_OUT_REFUND,
'biz_no' => $transferNo,
'direction' => self::TXN_DIR_IN,
'amount' => $amountMinor,
'balance_before' => $before,
'balance_after' => $after,
'status' => self::TXN_POSTED,
'external_ref_no' => null,
'idempotent_key' => $idempotentKey,
'remark' => 'withdraw_failed_refund',
]);
$this->postLotteryWalletMovement(
wallet: $wallet,
bizType: self::BIZ_TRANSFER_OUT_REFUND,
direction: self::TXN_DIR_IN,
amountMinor: $amountMinor,
bizNo: $transferNo,
externalRefNo: null,
idempotentKey: $idempotentKey,
remark: 'withdraw_failed_refund',
deltaSign: 1,
);
$order->forceFill([
'status' => self::ST_FAILED,
@@ -386,28 +348,17 @@ final class LotteryTransferService
if ($order->direction === self::DIR_OUT) {
DB::transaction(function () use ($order, $remark): void {
$wallet = $this->lockLotteryWalletById($order->player_id, $order->currency_code);
$before = (int) $wallet->balance;
$after = $before + (int) $order->amount;
$wallet->forceFill([
'balance' => $after,
'version' => (int) $wallet->version + 1,
])->save();
WalletTxn::query()->create([
'txn_no' => $this->newTxnNo(),
'player_id' => (int) $order->player_id,
'wallet_id' => $wallet->id,
'biz_type' => self::BIZ_REVERSAL,
'biz_no' => $order->transfer_no,
'direction' => self::TXN_DIR_IN,
'amount' => (int) $order->amount,
'balance_before' => $before,
'balance_after' => $after,
'status' => self::TXN_POSTED,
'external_ref_no' => null,
'idempotent_key' => null,
'remark' => $remark ?: 'reversal_pending_reconcile',
]);
$this->postLotteryWalletMovement(
wallet: $wallet,
bizType: self::BIZ_REVERSAL,
direction: self::TXN_DIR_IN,
amountMinor: (int) $order->amount,
bizNo: $order->transfer_no,
externalRefNo: null,
idempotentKey: null,
remark: $remark ?: 'reversal_pending_reconcile',
deltaSign: 1,
);
$order->forceFill([
'status' => self::ST_REVERSED,
@@ -701,6 +652,61 @@ final class LotteryTransferService
return 'WX_'.Str::lower(str_replace('-', '', Str::uuid()->toString()));
}
/**
* 统一执行彩票钱包余额变更并记录流水。
*
* @return array{before: int, after: int}
*/
private function postLotteryWalletMovement(
PlayerWallet $wallet,
string $bizType,
int $direction,
int $amountMinor,
string $bizNo,
?string $externalRefNo,
?string $idempotentKey,
?string $remark,
int $deltaSign,
bool $requireBalance = false,
): array {
$before = (int) $wallet->balance;
if ($requireBalance && $deltaSign < 0 && $before < $amountMinor) {
throw new WalletOperationException(
'insufficient_balance',
ErrorCode::WalletInsufficientBalance->value,
);
}
$delta = $amountMinor * $deltaSign;
$after = $before + $delta;
$wallet->forceFill([
'balance' => $after,
'version' => (int) $wallet->version + 1,
])->save();
WalletTxn::query()->create([
'txn_no' => $this->newTxnNo(),
'player_id' => $wallet->player_id,
'wallet_id' => $wallet->id,
'biz_type' => $bizType,
'biz_no' => $bizNo,
'direction' => $direction,
'amount' => $amountMinor,
'balance_before' => $before,
'balance_after' => $after,
'status' => self::TXN_POSTED,
'external_ref_no' => $externalRefNo,
'idempotent_key' => $idempotentKey,
'remark' => $remark,
]);
return [
'before' => $before,
'after' => $after,
];
}
private function failedOrderToException(TransferOrder $order): WalletOperationException
{
if (($order->fail_reason ?? '') === 'insufficient_balance') {