diff --git a/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchIndexController.php b/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchIndexController.php index 7f502e9..9e191a3 100644 --- a/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchIndexController.php +++ b/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchIndexController.php @@ -7,6 +7,7 @@ use App\Support\AdminApiList; use App\Models\SettlementBatch; use Illuminate\Http\JsonResponse; use App\Http\Controllers\Controller; +use App\Support\SettlementBatchFinancialSummary; /** * GET /api/v1/admin/settlement-batches — 结算批次分页列表。 @@ -39,6 +40,8 @@ final class AdminSettlementBatchIndexController extends Controller /** @return array */ private function row(SettlementBatch $b): array { + $financial = SettlementBatchFinancialSummary::forBatch($b); + return [ 'id' => (int) $b->id, 'draw_id' => (int) $b->draw_id, @@ -51,8 +54,11 @@ final class AdminSettlementBatchIndexController extends Controller 'paid_at' => $b->paid_at?->toIso8601String(), 'total_ticket_count' => (int) $b->total_ticket_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_jackpot_payout_amount' => (int) $b->total_jackpot_payout_amount, + 'platform_profit' => $financial['platform_profit'], 'started_at' => $b->started_at?->toIso8601String(), 'finished_at' => $b->finished_at?->toIso8601String(), 'created_at' => $b->created_at?->toIso8601String(), diff --git a/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchShowController.php b/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchShowController.php index 6844e16..d7b0aa4 100644 --- a/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchShowController.php +++ b/app/Http/Controllers/Api/V1/Admin/Settlement/AdminSettlementBatchShowController.php @@ -6,6 +6,7 @@ use App\Support\ApiResponse; use App\Models\SettlementBatch; use Illuminate\Http\JsonResponse; use App\Http\Controllers\Controller; +use App\Support\SettlementBatchFinancialSummary; /** * GET /api/v1/admin/settlement-batches/{batch} — 单批次摘要。 @@ -15,6 +16,7 @@ final class AdminSettlementBatchShowController extends Controller public function __invoke(SettlementBatch $batch): JsonResponse { $batch->load(['draw:id,draw_no,business_date,status', 'resultBatch:id,result_version,status']); + $financial = SettlementBatchFinancialSummary::forBatch($batch); return ApiResponse::success([ 'id' => (int) $batch->id, @@ -33,8 +35,11 @@ final class AdminSettlementBatchShowController extends Controller 'paid_at' => $batch->paid_at?->toIso8601String(), 'total_ticket_count' => (int) $batch->total_ticket_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_jackpot_payout_amount' => (int) $batch->total_jackpot_payout_amount, + 'platform_profit' => $financial['platform_profit'], 'started_at' => $batch->started_at?->toIso8601String(), 'finished_at' => $batch->finished_at?->toIso8601String(), 'created_at' => $batch->created_at?->toIso8601String(), diff --git a/app/Support/SettlementBatchFinancialSummary.php b/app/Support/SettlementBatchFinancialSummary.php new file mode 100644 index 0000000..4d5a4c0 --- /dev/null +++ b/app/Support/SettlementBatchFinancialSummary.php @@ -0,0 +1,30 @@ +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, + ]; + } +} diff --git a/tests/Feature/SettlementOrchestratorTest.php b/tests/Feature/SettlementOrchestratorTest.php index c98f442..ab7c643 100644 --- a/tests/Feature/SettlementOrchestratorTest.php +++ b/tests/Feature/SettlementOrchestratorTest.php @@ -255,6 +255,21 @@ test('admin settlement requires review before payout and can export report', fun ->assertOk() ->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(); expect($item->status)->toBe('settled_win'); expect(WalletTxn::query()->where('biz_type', 'settle_payout')->count())->toBe(1);