diff --git a/app/Http/Controllers/Admin/PlatformOrderController.php b/app/Http/Controllers/Admin/PlatformOrderController.php index 1eef921..6853605 100644 --- a/app/Http/Controllers/Admin/PlatformOrderController.php +++ b/app/Http/Controllers/Admin/PlatformOrderController.php @@ -426,17 +426,39 @@ class PlatformOrderController extends Controller $paymentReceipts = (array) (data_get($order->meta, 'payment_receipts', []) ?? []); $refundReceipts = (array) (data_get($order->meta, 'refund_receipts', []) ?? []); + $includeOrderSnapshot = (string) $request->query('include_order_snapshot', '') === '1'; + $filename = 'platform_order_' . $order->id . '_ledger_' . now()->format('Ymd_His') . '.csv'; - return response()->streamDownload(function () use ($order, $paymentReceipts, $refundReceipts) { + return response()->streamDownload(function () use ($order, $paymentReceipts, $refundReceipts, $includeOrderSnapshot) { $out = fopen('php://output', 'w'); // UTF-8 BOM,避免 Excel 打开中文乱码 fwrite($out, "\xEF\xBB\xBF"); - // 订单摘要(两行) + // 订单摘要(基础两行) fputcsv($out, ['order_id', (string) $order->id]); fputcsv($out, ['order_no', (string) $order->order_no]); + + // 可选:导出更多订单快照字段(便于财务/对账留档,不必另截图) + if ($includeOrderSnapshot) { + fputcsv($out, ['merchant_id', (string) ($order->merchant_id ?? '')]); + fputcsv($out, ['merchant_name', (string) ($order->merchant?->name ?? '')]); + fputcsv($out, ['plan_id', (string) ($order->plan_id ?? '')]); + fputcsv($out, ['plan_name', (string) ($order->plan_name ?? ($order->plan?->name ?? ''))]); + fputcsv($out, ['order_type', (string) ($order->order_type ?? '')]); + fputcsv($out, ['status', (string) ($order->status ?? '')]); + fputcsv($out, ['payment_status', (string) ($order->payment_status ?? '')]); + fputcsv($out, ['payable_amount', (string) ($order->payable_amount ?? '')]); + fputcsv($out, ['paid_amount', (string) ($order->paid_amount ?? '')]); + fputcsv($out, ['placed_at', (string) (optional($order->placed_at)->format('Y-m-d H:i:s') ?? '')]); + fputcsv($out, ['paid_at', (string) (optional($order->paid_at)->format('Y-m-d H:i:s') ?? '')]); + fputcsv($out, ['activated_at', (string) (optional($order->activated_at)->format('Y-m-d H:i:s') ?? '')]); + fputcsv($out, ['refunded_at', (string) (optional($order->refunded_at)->format('Y-m-d H:i:s') ?? '')]); + fputcsv($out, ['site_subscription_id', (string) ($order->site_subscription_id ?? '')]); + fputcsv($out, ['subscription_no', (string) ($order->siteSubscription?->subscription_no ?? '')]); + } + fputcsv($out, []); // 明细表头 diff --git a/resources/views/admin/platform_orders/show.blade.php b/resources/views/admin/platform_orders/show.blade.php index b37ef38..82dbdd8 100644 --- a/resources/views/admin/platform_orders/show.blade.php +++ b/resources/views/admin/platform_orders/show.blade.php @@ -326,7 +326,10 @@

支付回执(对账留痕)

- 导出对账明细(CSV) +

用于“线下收款/转账/人工核对”的留痕记录(当前阶段先落 meta,不引入独立表)。

diff --git a/tests/Feature/AdminPlatformOrderExportLedgerTest.php b/tests/Feature/AdminPlatformOrderExportLedgerTest.php index d8ed7d9..80bb5df 100644 --- a/tests/Feature/AdminPlatformOrderExportLedgerTest.php +++ b/tests/Feature/AdminPlatformOrderExportLedgerTest.php @@ -83,15 +83,27 @@ class AdminPlatformOrderExportLedgerTest extends TestCase $content = $res->streamedContent(); + $res2 = $this->get('/admin/platform-orders/' . $order->id . '/export-ledger?include_order_snapshot=1'); + $res2->assertOk(); + + $content2 = $res2->streamedContent(); + // UTF-8 BOM $this->assertStringStartsWith("\xEF\xBB\xBF", $content); + $this->assertStringStartsWith("\xEF\xBB\xBF", $content2); // 核心表头 $this->assertStringContainsString('record_type,receipt_type,channel,amount,biz_time,created_at,admin_id,note', $content); + $this->assertStringContainsString('record_type,receipt_type,channel,amount,biz_time,created_at,admin_id,note', $content2); // 至少包含一条 payment 与一条 refund 行(包含 type 字段) $this->assertStringContainsString('payment,bank_transfer,offline,10', $content); $this->assertStringContainsString('refund,refund,offline,1', $content); + + // include_order_snapshot=1 时应包含更多摘要字段 + $this->assertStringContainsString("merchant_id,{$merchant->id}", $content2); + $this->assertStringContainsString('payment_status,unpaid', $content2); + $this->assertStringContainsString('site_subscription_id,', $content2); } public function test_show_page_should_render_export_ledger_link(): void @@ -131,6 +143,8 @@ class AdminPlatformOrderExportLedgerTest extends TestCase $res->assertOk(); $res->assertSee('/admin/platform-orders/' . $order->id . '/export-ledger', false); + $res->assertSee('/admin/platform-orders/' . $order->id . '/export-ledger?include_order_snapshot=1', false); $res->assertSee('导出对账明细(CSV)', false); + $res->assertSee('导出含订单摘要(CSV)', false); } }