Files
saasshop/resources/views/admin/site_subscriptions/show.blade.php

333 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('admin.layouts.app')
@section('title', '订阅详情')
@section('page_title', '订阅详情')
@section('content')
@php
// 统一构造平台订单跳转链接:避免手写拼接导致编码/漏字段问题
// 注意:这里使用相对路径,避免测试/不同 APP_URL 环境下生成绝对域名导致断言与展示不一致
$platformOrdersBaseUrl = '/admin/platform-orders';
$makePlatformOrderUrl = function (array $query) use ($platformOrdersBaseUrl) {
return $platformOrdersBaseUrl . '?' . \Illuminate\Support\Arr::query($query);
};
@endphp
<div class="card mb-20">
<p class="muted muted-tight">
这里是总台视角的订阅详情页,用于运营排查“订阅状态/到期/关联平台订单/同步记录”。
</p>
<div class="grid-4">
<div>
<div class="muted">订阅号</div>
<div class="num-md">{{ $subscription->subscription_no }}</div>
</div>
<div>
<div class="muted">状态</div>
<div class="num-md">{{ ($statusLabels[$subscription->status] ?? $subscription->status) }} <span class="muted">({{ $subscription->status }})</span></div>
</div>
<div>
<div class="muted">站点</div>
<div class="num-md">
@if($subscription->merchant)
<a class="link" href="/admin/site-subscriptions?merchant_id={{ $subscription->merchant->id }}">{{ $subscription->merchant->name }}</a>
@else
未关联站点
@endif
</div>
</div>
<div>
<div class="muted">套餐</div>
<div class="num-md">
@php $planName = $subscription->plan_name ?: ($subscription->plan?->name ?? '未设置'); @endphp
@if($subscription->plan)
<a class="link" href="/admin/site-subscriptions?plan_id={{ $subscription->plan->id }}">{{ $planName }}</a>
@else
{{ $planName }}
@endif
</div>
</div>
</div>
<div class="grid-4 mt-10">
<div>
<div class="muted">计费周期 / 周期()</div>
<div class="num-md">{{ $subscription->billing_cycle ?: '-' }} / {{ (int) $subscription->period_months }}</div>
</div>
<div>
<div class="muted">金额</div>
<div class="num-md">¥{{ number_format((float) $subscription->amount, 2) }}</div>
</div>
<div>
<div class="muted">开始时间</div>
<div class="num-md">{{ optional($subscription->starts_at)->format('Y-m-d H:i:s') ?: '-' }}</div>
</div>
<div>
<div class="muted">到期时间</div>
<div class="num-md">{{ optional($subscription->ends_at)->format('Y-m-d H:i:s') ?: '-' }}</div>
</div>
</div>
<div class="grid-4 mt-10">
<div>
<div class="muted">到期状态(按到期时间)</div>
<div class="num-md">{{ $expiryLabel }}</div>
</div>
<div>
<div class="muted">试用到期</div>
<div class="num-md">{{ optional($subscription->trial_ends_at)->format('Y-m-d H:i:s') ?: '-' }}</div>
</div>
<div>
<div class="muted">生效时间</div>
<div class="num-md">{{ optional($subscription->activated_at)->format('Y-m-d H:i:s') ?: '-' }}</div>
</div>
<div>
<div class="muted">取消时间</div>
<div class="num-md">{{ optional($subscription->cancelled_at)->format('Y-m-d H:i:s') ?: '-' }}</div>
</div>
</div>
<div class="mt-10">
@php
$back = (string) request()->query('back', '');
$safeBack = str_starts_with($back, '/') ? $back : '';
@endphp
@if($safeBack)
<a href="{{ $safeBack }}" class="muted"> 返回上一页(保留上下文)</a>
<span class="muted"></span>
@endif
<a href="/admin/site-subscriptions" class="muted"> 返回订阅列表</a>
@if($subscription->subscription_no)
<span class="muted"></span>
<a href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id]) !!}" class="muted">查看关联平台订单按订阅ID精确过滤</a>
<span class="muted"></span>
<a href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'syncable_only' => '1']) !!}" class="muted">查看可同步订单</a>
<span class="muted"></span>
@php
$createRenewalOrderUrl = '/admin/platform-orders/create?' . \Illuminate\Support\Arr::query([
'merchant_id' => $subscription->merchant_id,
'plan_id' => $subscription->plan_id,
'site_subscription_id' => $subscription->id,
'order_type' => 'renewal',
'quantity' => 1,
'remark' => '来自订阅:' . $subscription->subscription_no,
]);
@endphp
<a href="{!! $createRenewalOrderUrl !!}" class="muted">创建续费订单</a>
@endif
</div>
<div class="mt-10" id="syncable-batch">
<form method="post" action="/admin/platform-orders/batch-activate-subscriptions" onsubmit="return confirm('确认批量同步该订阅下“可同步”的订单?(仅处理:已支付+已生效+未同步)');">
@csrf
<input type="hidden" name="scope" value="filtered">
<input type="hidden" name="site_subscription_id" value="{{ $subscription->id }}">
<input type="hidden" name="syncable_only" value="1">
<label class="muted form-inline-row mb-8">
<span>本次最多处理</span>
<input type="number" name="limit" value="50" min="1" max="500" class="w-90">
<span>条(安全阀)</span>
</label>
<button type="submit">批量同步该订阅下可同步订单</button>
</form>
<div class="muted muted-xs mt-6">说明:该按钮等价于平台订单页的“批量同步订阅(当前筛选范围)”,已内置只处理可同步订单(已支付+已生效+未同步)。</div>
</div>
</div>
<div class="grid-4 mb-20">
<div class="card">
<h3>关联订单总数</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id]) !!}">{{ $summaryStats['total_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">点击跳转:该订阅下全部平台订单</div>
</div>
<div class="card">
<h3>已同步</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'sync_status' => 'synced']) !!}">{{ $summaryStats['synced_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">点击跳转:该订阅下「已同步」订单</div>
</div>
<div class="card">
<h3>同步失败</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'sync_status' => 'failed']) !!}">{{ $summaryStats['failed_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">点击跳转:该订阅下「同步失败」订单</div>
</div>
<div class="card">
<h3>可同步(已支付+已生效+未同步)</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'syncable_only' => '1']) !!}">{{ $summaryStats['syncable_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">点击跳转:该订阅下「可同步订阅」订单</div>
</div>
<div class="card">
<h3>未同步(无记录)</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'sync_status' => 'unsynced']) !!}">{{ $summaryStats['unsynced_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">口径meta activation 且无 error点击跳转可查看明细</div>
</div>
<div class="card">
<h3>有回执订单 / 回执总额</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'receipt_status' => 'has']) !!}">{{ $summaryStats['receipt_orders'] ?? 0 }}</a>
/ ¥{{ number_format((float) ($summaryStats['total_receipt_amount'] ?? 0), 2) }}
</div>
<div class="muted muted-xs">点击订单数可跳转:该订阅下「有回执」订单</div>
<div class="muted muted-xs">
无回执订单:
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'receipt_status' => 'none']) !!}">{{ $summaryStats['no_receipt_orders'] ?? 0 }}</a>
</div>
</div>
<div class="card">
<h3>有退款订单 / 退款总额</h3>
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'refund_status' => 'has']) !!}">{{ $summaryStats['refund_orders'] ?? 0 }}</a>
/ ¥{{ number_format((float) ($summaryStats['total_refunded_amount'] ?? 0), 2) }}
</div>
<div class="muted muted-xs">点击订单数可跳转:该订阅下「有退款」订单</div>
<div class="muted muted-xs">
无退款订单:
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'refund_status' => 'none']) !!}">{{ $summaryStats['no_refund_orders'] ?? 0 }}</a>
</div>
<div class="muted muted-xs">
退款不一致订单:
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'refund_inconsistent' => '1']) !!}">{{ $summaryStats['refund_inconsistent_orders'] ?? 0 }}</a>
</div>
@if(((int) ($summaryStats['refund_inconsistent_orders'] ?? 0)) > 0)
<div class="muted muted-xs text-danger">
提示:存在退款状态与退款总额不一致订单。
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'refund_inconsistent' => '1']) !!}">进入退款不一致订单列表</a>
(建议先逐单核对退款轨迹,再在订单详情页使用「退款状态治理」修正状态;仅修口径,不会自动生成回执/退款回执)。
</div>
@endif
</div>
<div class="card">
<h3>对账差额(回执-已付)</h3>
@php $delta = (float) ($summaryStats['reconciliation_delta'] ?? 0); @endphp
<div class="num-md">
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'reconcile_mismatch' => '1']) !!}">¥{{ number_format($delta, 2) }}</a>
</div>
<div class="muted muted-xs">点击差额可跳转:该订阅下「对账不一致」订单</div>
@if(abs($delta) >= 0.01)
<div class="muted muted-xs text-danger">提示:差额非 0,可能存在回执金额与订单已付金额不一致。</div>
@else
<div class="muted muted-xs">差额为 0(当前订阅维度)</div>
@endif
</div>
<div class="card">
<h3>失败原因Top3</h3>
@php $failedReasonStats = $failedReasonStats ?? []; @endphp
@if(count($failedReasonStats) > 0)
<div class="muted mt-6">
@foreach($failedReasonStats as $item)
@php $reason = (string) ($item['reason'] ?? ''); @endphp
<div>
<a class="link" href="{!! $makePlatformOrderUrl(['site_subscription_id' => $subscription->id, 'sync_status' => 'failed', 'sync_error_keyword' => $reason]) !!}">{{ $reason }}</a>
<span class="muted">{{ $item['count'] }}</span>
</div>
@endforeach
</div>
@else
<div class="muted">暂无失败原因聚合数据</div>
@endif
</div>
</div>
<div class="card">
<h3>关联平台订单({{ $platformOrders->total() }}</h3>
<div class="mb-10">
<span class="muted">同步状态筛选:</span>
@php $cur = $summaryStats['current_order_sync_status'] ?? ''; @endphp
<a href="?" class="muted">全部</a>
<span class="muted"></span>
<a href="?order_sync_status=synced" class="muted">已同步</a>
<span class="muted"></span>
<a href="?order_sync_status=failed" class="muted">同步失败</a>
<span class="muted"></span>
<a href="?order_sync_status=unsynced" class="muted">未同步</a>
<span class="muted"></span>
<a href="?order_sync_status=syncable" class="muted">可同步</a>
<span class="muted"></span>
<a href="/admin/platform-orders?site_subscription_id={{ $subscription->id }}" class="muted">在平台订单页打开</a>
@if($cur)
<span class="muted">(当前:{{ $cur }}</span>
@endif
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>订单号</th>
<th>订单状态</th>
<th>支付状态</th>
<th>应付/已付</th>
<th>下单时间</th>
<th>生效时间</th>
<th>同步状态</th>
<th>同步时间</th>
<th>失败原因</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@forelse($platformOrders as $order)
@php
$syncedId = (int) data_get($order->meta, 'subscription_activation.subscription_id', 0);
$syncErr = (string) (data_get($order->meta, 'subscription_activation_error.message') ?? '');
if ($syncedId > 0) {
$syncStatus = '已同步';
} elseif ($syncErr !== '') {
$syncStatus = '同步失败';
} else {
$syncStatus = '未同步';
}
@endphp
<tr>
<td>{{ $order->id }}</td>
<td><a href="/admin/platform-orders/{{ $order->id }}">{{ $order->order_no }}</a></td>
<td>{{ $order->status }}</td>
<td>{{ $order->payment_status }}</td>
<td>¥{{ number_format((float) $order->payable_amount, 2) }} / ¥{{ number_format((float) $order->paid_amount, 2) }}</td>
<td>{{ optional($order->placed_at)->format('Y-m-d H:i:s') ?: '-' }}</td>
<td>{{ optional($order->activated_at)->format('Y-m-d H:i:s') ?: '-' }}</td>
<td>
{{ $syncStatus }}
</td>
<td>{{ data_get($order->meta, 'subscription_activation.synced_at') ?: '-' }}</td>
<td>
@if($syncStatus === '同步失败')
<span class="text-danger">{{ mb_substr($syncErr, 0, 60) }}</span>
@else
<span class="muted">-</span>
@endif
</td>
<td>
<a href="/admin/platform-orders/{{ $order->id }}">详情</a>
</td>
</tr>
@empty
<tr>
<td colspan="11" class="muted">暂无关联平台订单。</td>
</tr>
@endforelse
</tbody>
</table>
<div class="pagination-wrap">{{ $platformOrders->links() }}</div>
</div>
@endsection