feat(platform-orders): 支持支付回执留痕(meta.payment_receipts)
This commit is contained in:
@@ -302,6 +302,24 @@ class PlatformOrderController extends Controller
|
|||||||
$order->paid_at = $order->paid_at ?: $now;
|
$order->paid_at = $order->paid_at ?: $now;
|
||||||
$order->activated_at = $order->activated_at ?: $now;
|
$order->activated_at = $order->activated_at ?: $now;
|
||||||
$order->paid_amount = $order->paid_amount > 0 ? $order->paid_amount : $order->payable_amount;
|
$order->paid_amount = $order->paid_amount > 0 ? $order->paid_amount : $order->payable_amount;
|
||||||
|
|
||||||
|
// 兼容:若尚未写入“支付回执”,则自动补一条(可治理)
|
||||||
|
$meta = (array) ($order->meta ?? []);
|
||||||
|
$receipts = (array) (data_get($meta, 'payment_receipts', []) ?? []);
|
||||||
|
if (count($receipts) === 0) {
|
||||||
|
$receipts[] = [
|
||||||
|
'type' => 'manual_mark_paid',
|
||||||
|
'channel' => (string) ($order->payment_channel ?? ''),
|
||||||
|
'amount' => (float) $order->paid_amount,
|
||||||
|
'paid_at' => $order->paid_at ? $order->paid_at->format('Y-m-d H:i:s') : $now->toDateTimeString(),
|
||||||
|
'note' => '由【标记支付并生效】自动补记(可治理)',
|
||||||
|
'created_at' => $now->toDateTimeString(),
|
||||||
|
'admin_id' => $admin->id,
|
||||||
|
];
|
||||||
|
data_set($meta, 'payment_receipts', $receipts);
|
||||||
|
$order->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
// 立刻同步订阅
|
// 立刻同步订阅
|
||||||
@@ -328,6 +346,40 @@ class PlatformOrderController extends Controller
|
|||||||
return redirect()->back()->with('success', '订单已标记支付并生效,订阅已同步:' . $subscription->subscription_no);
|
return redirect()->back()->with('success', '订单已标记支付并生效,订阅已同步:' . $subscription->subscription_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addPaymentReceipt(Request $request, PlatformOrder $order): RedirectResponse
|
||||||
|
{
|
||||||
|
$admin = $this->ensurePlatformAdmin($request);
|
||||||
|
|
||||||
|
$data = $request->validate([
|
||||||
|
'type' => ['required', 'string', 'max:30'],
|
||||||
|
'channel' => ['nullable', 'string', 'max:30'],
|
||||||
|
'amount' => ['required', 'numeric', 'min:0'],
|
||||||
|
'paid_at' => ['nullable', 'date'],
|
||||||
|
'note' => ['nullable', 'string', 'max:2000'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$now = now();
|
||||||
|
|
||||||
|
$meta = (array) ($order->meta ?? []);
|
||||||
|
$receipts = (array) (data_get($meta, 'payment_receipts', []) ?? []);
|
||||||
|
|
||||||
|
$receipts[] = [
|
||||||
|
'type' => (string) $data['type'],
|
||||||
|
'channel' => (string) ($data['channel'] ?? ''),
|
||||||
|
'amount' => (float) $data['amount'],
|
||||||
|
'paid_at' => $data['paid_at'] ? (string) $data['paid_at'] : null,
|
||||||
|
'note' => (string) ($data['note'] ?? ''),
|
||||||
|
'created_at' => $now->toDateTimeString(),
|
||||||
|
'admin_id' => $admin->id,
|
||||||
|
];
|
||||||
|
|
||||||
|
data_set($meta, 'payment_receipts', $receipts);
|
||||||
|
$order->meta = $meta;
|
||||||
|
$order->save();
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', '已追加支付回执记录(仅用于对账留痕,不自动改状态)。');
|
||||||
|
}
|
||||||
|
|
||||||
public function markActivated(Request $request, PlatformOrder $order): RedirectResponse
|
public function markActivated(Request $request, PlatformOrder $order): RedirectResponse
|
||||||
{
|
{
|
||||||
$admin = $this->ensurePlatformAdmin($request);
|
$admin = $this->ensurePlatformAdmin($request);
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
$activation = data_get($order->meta, 'subscription_activation');
|
$activation = data_get($order->meta, 'subscription_activation');
|
||||||
$activationError = data_get($order->meta, 'subscription_activation_error');
|
$activationError = data_get($order->meta, 'subscription_activation_error');
|
||||||
$audit = (array) (data_get($order->meta, 'audit', []) ?? []);
|
$audit = (array) (data_get($order->meta, 'audit', []) ?? []);
|
||||||
|
$paymentReceipts = (array) (data_get($order->meta, 'payment_receipts', []) ?? []);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@php
|
@php
|
||||||
@@ -107,6 +108,64 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card mb-20">
|
||||||
|
<h3>支付回执(对账留痕)</h3>
|
||||||
|
<p class="muted muted-tight">用于“线下收款/转账/人工核对”的留痕记录(当前阶段先落 meta,不引入独立表)。</p>
|
||||||
|
|
||||||
|
@if(count($paymentReceipts) > 0)
|
||||||
|
@php $items = array_slice(array_reverse($paymentReceipts), 0, 20); @endphp
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:140px;">类型</th>
|
||||||
|
<th style="width:120px;">渠道</th>
|
||||||
|
<th style="width:120px;">金额</th>
|
||||||
|
<th style="width:200px;">支付时间</th>
|
||||||
|
<th style="width:160px;">记录时间</th>
|
||||||
|
<th style="width:100px;">管理员</th>
|
||||||
|
<th>备注</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($items as $r)
|
||||||
|
<tr>
|
||||||
|
<td>{{ data_get($r, 'type') ?: '-' }}</td>
|
||||||
|
<td>{{ data_get($r, 'channel') ?: '-' }}</td>
|
||||||
|
<td>¥{{ number_format((float) (data_get($r, 'amount') ?? 0), 2) }}</td>
|
||||||
|
<td>{{ data_get($r, 'paid_at') ?: '-' }}</td>
|
||||||
|
<td>{{ data_get($r, 'created_at') ?: '-' }}</td>
|
||||||
|
<td>{{ data_get($r, 'admin_id') ?: '-' }}</td>
|
||||||
|
<td class="muted">{{ data_get($r, 'note') ?: '' }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
@else
|
||||||
|
<p class="muted">暂无支付回执记录。</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<details style="margin-top:12px;">
|
||||||
|
<summary class="muted">追加一条支付回执(不自动改状态)</summary>
|
||||||
|
<form method="post" action="/admin/platform-orders/{{ $order->id }}/add-payment-receipt" style="margin-top:10px;">
|
||||||
|
@csrf
|
||||||
|
<div class="grid-3">
|
||||||
|
<input type="text" name="type" placeholder="类型:bank_transfer/现金/支付宝等" value="bank_transfer">
|
||||||
|
<input type="text" name="channel" placeholder="渠道(可选)" value="{{ (string) ($order->payment_channel ?? '') }}">
|
||||||
|
<input type="number" step="0.01" name="amount" placeholder="金额" value="{{ number_format((float) ($order->paid_amount > 0 ? $order->paid_amount : $order->payable_amount), 2, '.', '') }}">
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:10px;">
|
||||||
|
<input type="text" name="paid_at" placeholder="支付时间:YYYY-mm-dd HH:ii:ss(可选)" value="{{ optional($order->paid_at)->format('Y-m-d H:i:s') }}">
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:10px;">
|
||||||
|
<textarea name="note" placeholder="备注(可选,用于对账说明)" rows="3" style="width:100%;"></textarea>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:10px;">
|
||||||
|
<button type="submit">追加回执记录</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card mb-20">
|
<div class="card mb-20">
|
||||||
<h3>订阅同步记录</h3>
|
<h3>订阅同步记录</h3>
|
||||||
@if($activation)
|
@if($activation)
|
||||||
@@ -145,6 +204,8 @@
|
|||||||
$auditActionLabels = [
|
$auditActionLabels = [
|
||||||
'clear_sync_error' => '清除同步失败标记',
|
'clear_sync_error' => '清除同步失败标记',
|
||||||
'batch_activate_subscription' => '批量同步订阅',
|
'batch_activate_subscription' => '批量同步订阅',
|
||||||
|
'mark_activated' => '仅标记为已生效',
|
||||||
|
'batch_mark_activated' => '批量仅标记为已生效',
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ Route::prefix('admin')->group(function () {
|
|||||||
Route::get('/platform-orders/{order}', [PlatformOrderController::class, 'show']);
|
Route::get('/platform-orders/{order}', [PlatformOrderController::class, 'show']);
|
||||||
Route::post('/platform-orders/{order}/activate-subscription', [PlatformOrderController::class, 'activateSubscription']);
|
Route::post('/platform-orders/{order}/activate-subscription', [PlatformOrderController::class, 'activateSubscription']);
|
||||||
Route::post('/platform-orders/{order}/mark-paid-and-activate', [PlatformOrderController::class, 'markPaidAndActivate']);
|
Route::post('/platform-orders/{order}/mark-paid-and-activate', [PlatformOrderController::class, 'markPaidAndActivate']);
|
||||||
|
Route::post('/platform-orders/{order}/add-payment-receipt', [PlatformOrderController::class, 'addPaymentReceipt']);
|
||||||
Route::post('/platform-orders/{order}/mark-activated', [PlatformOrderController::class, 'markActivated']);
|
Route::post('/platform-orders/{order}/mark-activated', [PlatformOrderController::class, 'markActivated']);
|
||||||
|
|
||||||
Route::get('/site-subscriptions', [SiteSubscriptionController::class, 'index']);
|
Route::get('/site-subscriptions', [SiteSubscriptionController::class, 'index']);
|
||||||
|
|||||||
Reference in New Issue
Block a user