feat: 补充结算批次财务汇总并返回投注与利润数据
This commit is contained in:
@@ -7,6 +7,7 @@ use App\Support\AdminApiList;
|
|||||||
use App\Models\SettlementBatch;
|
use App\Models\SettlementBatch;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Support\SettlementBatchFinancialSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/v1/admin/settlement-batches — 结算批次分页列表。
|
* GET /api/v1/admin/settlement-batches — 结算批次分页列表。
|
||||||
@@ -39,6 +40,8 @@ final class AdminSettlementBatchIndexController extends Controller
|
|||||||
/** @return array<string, mixed> */
|
/** @return array<string, mixed> */
|
||||||
private function row(SettlementBatch $b): array
|
private function row(SettlementBatch $b): array
|
||||||
{
|
{
|
||||||
|
$financial = SettlementBatchFinancialSummary::forBatch($b);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (int) $b->id,
|
'id' => (int) $b->id,
|
||||||
'draw_id' => (int) $b->draw_id,
|
'draw_id' => (int) $b->draw_id,
|
||||||
@@ -51,8 +54,11 @@ final class AdminSettlementBatchIndexController extends Controller
|
|||||||
'paid_at' => $b->paid_at?->toIso8601String(),
|
'paid_at' => $b->paid_at?->toIso8601String(),
|
||||||
'total_ticket_count' => (int) $b->total_ticket_count,
|
'total_ticket_count' => (int) $b->total_ticket_count,
|
||||||
'total_win_count' => (int) $b->total_win_count,
|
'total_win_count' => (int) $b->total_win_count,
|
||||||
|
'total_bet_amount' => $financial['total_bet_amount'],
|
||||||
|
'total_actual_deduct' => $financial['total_actual_deduct'],
|
||||||
'total_payout_amount' => (int) $b->total_payout_amount,
|
'total_payout_amount' => (int) $b->total_payout_amount,
|
||||||
'total_jackpot_payout_amount' => (int) $b->total_jackpot_payout_amount,
|
'total_jackpot_payout_amount' => (int) $b->total_jackpot_payout_amount,
|
||||||
|
'platform_profit' => $financial['platform_profit'],
|
||||||
'started_at' => $b->started_at?->toIso8601String(),
|
'started_at' => $b->started_at?->toIso8601String(),
|
||||||
'finished_at' => $b->finished_at?->toIso8601String(),
|
'finished_at' => $b->finished_at?->toIso8601String(),
|
||||||
'created_at' => $b->created_at?->toIso8601String(),
|
'created_at' => $b->created_at?->toIso8601String(),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use App\Support\ApiResponse;
|
|||||||
use App\Models\SettlementBatch;
|
use App\Models\SettlementBatch;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Support\SettlementBatchFinancialSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/v1/admin/settlement-batches/{batch} — 单批次摘要。
|
* GET /api/v1/admin/settlement-batches/{batch} — 单批次摘要。
|
||||||
@@ -15,6 +16,7 @@ final class AdminSettlementBatchShowController extends Controller
|
|||||||
public function __invoke(SettlementBatch $batch): JsonResponse
|
public function __invoke(SettlementBatch $batch): JsonResponse
|
||||||
{
|
{
|
||||||
$batch->load(['draw:id,draw_no,business_date,status', 'resultBatch:id,result_version,status']);
|
$batch->load(['draw:id,draw_no,business_date,status', 'resultBatch:id,result_version,status']);
|
||||||
|
$financial = SettlementBatchFinancialSummary::forBatch($batch);
|
||||||
|
|
||||||
return ApiResponse::success([
|
return ApiResponse::success([
|
||||||
'id' => (int) $batch->id,
|
'id' => (int) $batch->id,
|
||||||
@@ -33,8 +35,11 @@ final class AdminSettlementBatchShowController extends Controller
|
|||||||
'paid_at' => $batch->paid_at?->toIso8601String(),
|
'paid_at' => $batch->paid_at?->toIso8601String(),
|
||||||
'total_ticket_count' => (int) $batch->total_ticket_count,
|
'total_ticket_count' => (int) $batch->total_ticket_count,
|
||||||
'total_win_count' => (int) $batch->total_win_count,
|
'total_win_count' => (int) $batch->total_win_count,
|
||||||
|
'total_bet_amount' => $financial['total_bet_amount'],
|
||||||
|
'total_actual_deduct' => $financial['total_actual_deduct'],
|
||||||
'total_payout_amount' => (int) $batch->total_payout_amount,
|
'total_payout_amount' => (int) $batch->total_payout_amount,
|
||||||
'total_jackpot_payout_amount' => (int) $batch->total_jackpot_payout_amount,
|
'total_jackpot_payout_amount' => (int) $batch->total_jackpot_payout_amount,
|
||||||
|
'platform_profit' => $financial['platform_profit'],
|
||||||
'started_at' => $batch->started_at?->toIso8601String(),
|
'started_at' => $batch->started_at?->toIso8601String(),
|
||||||
'finished_at' => $batch->finished_at?->toIso8601String(),
|
'finished_at' => $batch->finished_at?->toIso8601String(),
|
||||||
'created_at' => $batch->created_at?->toIso8601String(),
|
'created_at' => $batch->created_at?->toIso8601String(),
|
||||||
|
|||||||
30
app/Support/SettlementBatchFinancialSummary.php
Normal file
30
app/Support/SettlementBatchFinancialSummary.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Support;
|
||||||
|
|
||||||
|
use App\Models\SettlementBatch;
|
||||||
|
|
||||||
|
final class SettlementBatchFinancialSummary
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array{total_bet_amount: int, total_actual_deduct: int, platform_profit: int}
|
||||||
|
*/
|
||||||
|
public static function forBatch(SettlementBatch $batch): array
|
||||||
|
{
|
||||||
|
$totals = $batch->details()
|
||||||
|
->join('ticket_items', 'ticket_items.id', '=', 'ticket_settlement_details.ticket_item_id')
|
||||||
|
->selectRaw('COALESCE(SUM(ticket_items.total_bet_amount), 0) as total_bet_amount')
|
||||||
|
->selectRaw('COALESCE(SUM(ticket_items.actual_deduct_amount), 0) as total_actual_deduct')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$totalBet = (int) ($totals?->total_bet_amount ?? 0);
|
||||||
|
$totalActualDeduct = (int) ($totals?->total_actual_deduct ?? 0);
|
||||||
|
$totalPayout = (int) $batch->total_payout_amount;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'total_bet_amount' => $totalBet,
|
||||||
|
'total_actual_deduct' => $totalActualDeduct,
|
||||||
|
'platform_profit' => $totalActualDeduct - $totalPayout,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -255,6 +255,21 @@ test('admin settlement requires review before payout and can export report', fun
|
|||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonPath('data.status', 'paid');
|
->assertJsonPath('data.status', 'paid');
|
||||||
|
|
||||||
|
$this->withHeader('Authorization', 'Bearer '.$token)
|
||||||
|
->getJson('/api/v1/admin/settlement-batches?draw_no=20260511-901&status=paid')
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.items.0.total_bet_amount', 10_000)
|
||||||
|
->assertJsonPath('data.items.0.total_actual_deduct', 10_000)
|
||||||
|
->assertJsonPath('data.items.0.total_payout_amount', 250_000)
|
||||||
|
->assertJsonPath('data.items.0.platform_profit', -240_000);
|
||||||
|
|
||||||
|
$this->withHeader('Authorization', 'Bearer '.$token)
|
||||||
|
->getJson("/api/v1/admin/settlement-batches/{$settlement->id}")
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.total_bet_amount', 10_000)
|
||||||
|
->assertJsonPath('data.total_actual_deduct', 10_000)
|
||||||
|
->assertJsonPath('data.platform_profit', -240_000);
|
||||||
|
|
||||||
$item->refresh();
|
$item->refresh();
|
||||||
expect($item->status)->toBe('settled_win');
|
expect($item->status)->toBe('settled_win');
|
||||||
expect(WalletTxn::query()->where('biz_type', 'settle_payout')->count())->toBe(1);
|
expect(WalletTxn::query()->where('biz_type', 'settle_payout')->count())->toBe(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user