平台订单对账明细导出:支持 include_order_snapshot 并加入口
This commit is contained in:
@@ -426,17 +426,39 @@ class PlatformOrderController extends Controller
|
|||||||
$paymentReceipts = (array) (data_get($order->meta, 'payment_receipts', []) ?? []);
|
$paymentReceipts = (array) (data_get($order->meta, 'payment_receipts', []) ?? []);
|
||||||
$refundReceipts = (array) (data_get($order->meta, 'refund_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';
|
$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');
|
$out = fopen('php://output', 'w');
|
||||||
|
|
||||||
// UTF-8 BOM,避免 Excel 打开中文乱码
|
// UTF-8 BOM,避免 Excel 打开中文乱码
|
||||||
fwrite($out, "\xEF\xBB\xBF");
|
fwrite($out, "\xEF\xBB\xBF");
|
||||||
|
|
||||||
// 订单摘要(两行)
|
// 订单摘要(基础两行)
|
||||||
fputcsv($out, ['order_id', (string) $order->id]);
|
fputcsv($out, ['order_id', (string) $order->id]);
|
||||||
fputcsv($out, ['order_no', (string) $order->order_no]);
|
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, []);
|
fputcsv($out, []);
|
||||||
|
|
||||||
// 明细表头
|
// 明细表头
|
||||||
|
|||||||
@@ -326,7 +326,10 @@
|
|||||||
<div class="card mb-20" id="payment-receipts">
|
<div class="card mb-20" id="payment-receipts">
|
||||||
<div class="flex-between" style="align-items:center;">
|
<div class="flex-between" style="align-items:center;">
|
||||||
<h3 style="margin:0;">支付回执(对账留痕)</h3>
|
<h3 style="margin:0;">支付回执(对账留痕)</h3>
|
||||||
<a class="muted" href="/admin/platform-orders/{{ $order->id }}/export-ledger">导出对账明细(CSV)</a>
|
<div class="muted" style="display:flex; gap:10px;">
|
||||||
|
<a class="muted" href="/admin/platform-orders/{{ $order->id }}/export-ledger">导出对账明细(CSV)</a>
|
||||||
|
<a class="muted" href="/admin/platform-orders/{{ $order->id }}/export-ledger?include_order_snapshot=1">导出含订单摘要(CSV)</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="muted muted-tight">用于“线下收款/转账/人工核对”的留痕记录(当前阶段先落 meta,不引入独立表)。</p>
|
<p class="muted muted-tight">用于“线下收款/转账/人工核对”的留痕记录(当前阶段先落 meta,不引入独立表)。</p>
|
||||||
|
|
||||||
|
|||||||
@@ -83,15 +83,27 @@ class AdminPlatformOrderExportLedgerTest extends TestCase
|
|||||||
|
|
||||||
$content = $res->streamedContent();
|
$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
|
// UTF-8 BOM
|
||||||
$this->assertStringStartsWith("\xEF\xBB\xBF", $content);
|
$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', $content);
|
||||||
|
$this->assertStringContainsString('record_type,receipt_type,channel,amount,biz_time,created_at,admin_id,note', $content2);
|
||||||
|
|
||||||
// 至少包含一条 payment 与一条 refund 行(包含 type 字段)
|
// 至少包含一条 payment 与一条 refund 行(包含 type 字段)
|
||||||
$this->assertStringContainsString('payment,bank_transfer,offline,10', $content);
|
$this->assertStringContainsString('payment,bank_transfer,offline,10', $content);
|
||||||
$this->assertStringContainsString('refund,refund,offline,1', $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
|
public function test_show_page_should_render_export_ledger_link(): void
|
||||||
@@ -131,6 +143,8 @@ class AdminPlatformOrderExportLedgerTest extends TestCase
|
|||||||
$res->assertOk();
|
$res->assertOk();
|
||||||
|
|
||||||
$res->assertSee('/admin/platform-orders/' . $order->id . '/export-ledger', false);
|
$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);
|
||||||
|
$res->assertSee('导出含订单摘要(CSV)', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user