fix: 部分收付累计释额并扩展结算 E2E 与 CI
账期收付改为按累计已付同步 credit_ledger,修复多笔 partial_paid 与坏账核销重复释额;新增 API E2E(占成、权限、部分收付/坏账)与 GitHub Actions e2e-api job。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -359,62 +359,89 @@ final class PlayerCreditService
|
||||
]);
|
||||
}
|
||||
|
||||
public function releaseFromSettlement(Player $player, int $amountMinor, int $billId): void
|
||||
/**
|
||||
* @param int $cumulativePaidMinor 账单累计已登记收付(minor),支持部分收付多笔递增。
|
||||
*/
|
||||
public function releaseFromSettlement(Player $player, int $cumulativePaidMinor, int $billId): void
|
||||
{
|
||||
if ($amountMinor <= 0 || ! PlayerFundingMode::usesCredit($player)) {
|
||||
if ($cumulativePaidMinor <= 0 || ! PlayerFundingMode::usesCredit($player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 幂等闸门:credit_ledger (settlement_bill, settlement_confirm) 唯一;重复调用直接返回。
|
||||
try {
|
||||
DB::table('credit_ledger')->insert([
|
||||
'owner_type' => 'player',
|
||||
'owner_id' => $player->id,
|
||||
'amount' => $amountMinor,
|
||||
'reason' => 'settlement_confirm',
|
||||
'ref_type' => 'settlement_bill',
|
||||
'ref_id' => $billId,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
} catch (QueryException $e) {
|
||||
if ($this->isUniqueViolation($e)) {
|
||||
return;
|
||||
}
|
||||
throw $e;
|
||||
$delta = $this->syncSettlementBillLedger(
|
||||
$player,
|
||||
$billId,
|
||||
'settlement_confirm',
|
||||
$cumulativePaidMinor,
|
||||
);
|
||||
if ($delta > 0) {
|
||||
$this->decreaseUsedCredit($player, $delta);
|
||||
}
|
||||
|
||||
$this->decreaseUsedCredit($player, $amountMinor);
|
||||
}
|
||||
|
||||
public function applySettlementPayout(Player $player, int $amountMinor, int $billId): void
|
||||
/**
|
||||
* @param int $cumulativePaidMinor 账单累计已登记收付(minor),支持部分收付多笔递增。
|
||||
*/
|
||||
public function applySettlementPayout(Player $player, int $cumulativePaidMinor, int $billId): void
|
||||
{
|
||||
if ($amountMinor <= 0) {
|
||||
if ($cumulativePaidMinor <= 0 || ! PlayerFundingMode::usesCredit($player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! PlayerFundingMode::usesCredit($player)) {
|
||||
return;
|
||||
$this->syncSettlementBillLedger(
|
||||
$player,
|
||||
$billId,
|
||||
'settlement_payout',
|
||||
$cumulativePaidMinor,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步账期收付台账:每账单每种 reason 仅一行,amount 为累计已付;返回本次应追加的 minor 增量。
|
||||
*/
|
||||
private function syncSettlementBillLedger(
|
||||
Player $player,
|
||||
int $billId,
|
||||
string $reason,
|
||||
int $cumulativeMinor,
|
||||
): int {
|
||||
$existing = DB::table('credit_ledger')
|
||||
->where('owner_type', 'player')
|
||||
->where('owner_id', $player->id)
|
||||
->where('reason', $reason)
|
||||
->where('ref_type', 'settlement_bill')
|
||||
->where('ref_id', $billId)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
$recorded = $existing !== null ? (int) $existing->amount : 0;
|
||||
$delta = $cumulativeMinor - $recorded;
|
||||
if ($delta <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 幂等闸门:credit_ledger (settlement_bill, settlement_payout) 唯一;重复入账直接返回。
|
||||
try {
|
||||
$now = now();
|
||||
if ($existing === null) {
|
||||
DB::table('credit_ledger')->insert([
|
||||
'owner_type' => 'player',
|
||||
'owner_id' => $player->id,
|
||||
'amount' => $amountMinor,
|
||||
'reason' => 'settlement_payout',
|
||||
'amount' => $cumulativeMinor,
|
||||
'reason' => $reason,
|
||||
'ref_type' => 'settlement_bill',
|
||||
'ref_id' => $billId,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
} catch (QueryException $e) {
|
||||
if ($this->isUniqueViolation($e)) {
|
||||
return;
|
||||
}
|
||||
throw $e;
|
||||
} else {
|
||||
DB::table('credit_ledger')
|
||||
->where('id', (int) $existing->id)
|
||||
->update([
|
||||
'amount' => $cumulativeMinor,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
return $delta;
|
||||
}
|
||||
|
||||
private function decreaseUsedCredit(Player $player, int $amountMinor): void
|
||||
|
||||
Reference in New Issue
Block a user