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

276 lines
12 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
// back 参数用于“返回上一页(保留上下文)”,但 back 本身不应再包含 back避免无限嵌套导致 URL 膨胀)
// 注意:使用相对路径而非绝对 URL避免不同 APP_URL 环境影响,以及 show 页 back 安全校验(要求以 / 开头)
$currentQuery = request()->query();
unset($currentQuery['back']);
$selfWithoutBack = '/' . ltrim(request()->path(), '/');
if (count($currentQuery) > 0) {
$selfWithoutBack .= '?' . \Illuminate\Support\Arr::query($currentQuery);
}
$back = $selfWithoutBack;
// 用于构建“保留当前筛选上下文”的站内跳转链接(且不透传 back避免嵌套/污染)
$buildSelfUrl = function (array $overrides = []) use ($currentQuery) {
$q = $currentQuery;
foreach ($overrides as $k => $v) {
if ($v === null) {
unset($q[$k]);
} else {
$q[$k] = $v;
}
}
$url = '/' . ltrim(request()->path(), '/');
if (count($q) > 0) {
$url .= '?' . \Illuminate\Support\Arr::query($q);
}
return $url;
};
@endphp
<div class="card mb-20">
<p class="muted muted-tight">这里是总台视角的订阅目录页,承接“套餐 -> 订阅 -> 平台订单”的收费主链中间层。</p>
<p class="muted">当前阶段先做到:可访问列表、可筛选、统计摘要;后续再接:订阅激活服务 / 续费 / 取消 / 对账。</p>
@php
$incomingBack = (string) request()->query('back', '');
$safeBack = str_starts_with($incomingBack, '/') ? $incomingBack : '';
@endphp
@if($safeBack)
<div class="mt-10">
<a href="{{ $safeBack }}" class="muted"> 返回上一页(保留上下文)</a>
</div>
@endif
</div>
<div class="card mb-20">
<h3>快捷筛选</h3>
<div class="muted mb-10">用于运营快速定位需要处理的订阅集合(口径基于筛选条件组合)。</div>
<div>
<a href="/admin/site-subscriptions" class="muted">全部</a>
<span class="muted"></span>
<a href="/admin/site-subscriptions?status=activated" class="muted">已生效</a>
<span class="muted"></span>
<a href="/admin/site-subscriptions?status=pending" class="muted">待生效</a>
<span class="muted"></span>
<a href="/admin/site-subscriptions?status=cancelled" class="muted">已取消</a>
<span class="muted"></span>
<a href="/admin/site-subscriptions?expiry=expired" class="muted">已过期</a>
<span class="muted"></span>
<a href="/admin/site-subscriptions?expiry=expiring_7d" class="muted">7天内到期</a>
</div>
</div>
<div class="card mb-20">
<h3>筛选条件</h3>
<form method="get" action="/admin/site-subscriptions" class="grid-4">
<select name="status">
<option value="">全部状态</option>
@foreach(($filterOptions['statuses'] ?? []) as $value => $label)
<option value="{{ $value }}" @selected(($filters['status'] ?? '') === $value)>{{ $label }}</option>
@endforeach
</select>
<select name="expiry">
<option value="">全部到期状态</option>
<option value="expiring_7d" @selected(($filters['expiry'] ?? '') === 'expiring_7d')>7天内到期</option>
<option value="expired" @selected(($filters['expiry'] ?? '') === 'expired')>已过期</option>
</select>
<select name="merchant_id">
<option value="">全部站点</option>
@foreach(($merchants ?? []) as $merchant)
<option value="{{ $merchant->id }}" @selected(($filters['merchant_id'] ?? '') == $merchant->id)>{{ $merchant->name }}</option>
@endforeach
</select>
<select name="plan_id">
<option value="">全部套餐</option>
@foreach(($plans ?? []) as $plan)
<option value="{{ $plan->id }}" @selected(($filters['plan_id'] ?? '') == $plan->id)>{{ $plan->name }}</option>
@endforeach
</select>
<input name="keyword" placeholder="搜索订阅号 / 站点 / 套餐 / 计费周期" value="{{ $filters['keyword'] ?? '' }}">
<div>
<button type="submit">应用筛选</button>
</div>
</form>
</div>
<div class="grid-4 mb-20">
<div class="card">
<h3>订阅总数</h3>
<div class="num-md">{{ $summaryStats['total_subscriptions'] ?? 0 }}</div>
</div>
<div class="card">
<h3>已生效</h3>
<div class="num-md">{{ $summaryStats['activated_subscriptions'] ?? 0 }}</div>
</div>
<div class="card">
<h3>待生效</h3>
<div class="num-md">{{ $summaryStats['pending_subscriptions'] ?? 0 }}</div>
</div>
<div class="card">
<h3>已取消</h3>
<div class="num-md">{{ $summaryStats['cancelled_subscriptions'] ?? 0 }}</div>
</div>
<div class="card">
<h3>已过期(按到期时间)</h3>
<div class="num-md">{{ $summaryStats['expired_subscriptions'] ?? 0 }}</div>
</div>
<div class="card">
<h3>7天内到期</h3>
<div class="num-md">{{ $summaryStats['expiring_7d_subscriptions'] ?? 0 }}</div>
</div>
</div>
<div class="card mb-20">
<h3>工具</h3>
<div class="grid-2">
<form method="get" action="/admin/site-subscriptions/export">
<input type="hidden" name="download" value="1">
<input type="hidden" name="status" value="{{ $filters['status'] ?? '' }}">
<input type="hidden" name="merchant_id" value="{{ $filters['merchant_id'] ?? '' }}">
<input type="hidden" name="plan_id" value="{{ $filters['plan_id'] ?? '' }}">
<input type="hidden" name="expiry" value="{{ $filters['expiry'] ?? '' }}">
<input type="hidden" name="keyword" value="{{ $filters['keyword'] ?? '' }}">
<button type="submit">导出当前筛选结果CSV</button>
</form>
@php
$q = [
'order_type' => 'renewal',
'back' => $selfWithoutBack,
];
if ((int) ($filters['merchant_id'] ?? 0) > 0) {
$q['merchant_id'] = (int) $filters['merchant_id'];
}
if ((int) ($filters['plan_id'] ?? 0) > 0) {
$q['plan_id'] = (int) $filters['plan_id'];
}
$createOrderFromSubIndexUrl = '/admin/platform-orders/create?' . \Illuminate\Support\Arr::query($q);
@endphp
<a class="btn" href="{!! $createOrderFromSubIndexUrl !!}">创建续费订单(带当前筛选)</a>
</div>
<div class="muted muted-xs" style="margin-top:6px;">用于运营从订阅目录快速补单/续费:会把当前 merchant_id/plan_id/site_subscription_id 作为默认值带到下单页。</div>
</div>
<div class="card">
<h3>订阅列表</h3>
<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>
<th>关联订单数</th>
<th>生效时间</th>
</tr>
</thead>
<tbody>
@forelse($subscriptions as $subscription)
<tr>
<td>{{ $subscription->id }}</td>
<td>
@php
$subShowUrl = '/admin/site-subscriptions/' . $subscription->id . '?' . \Illuminate\Support\Arr::query([
'back' => $back,
]);
@endphp
<a href="{!! $subShowUrl !!}">{{ $subscription->subscription_no }}</a>
@php
$remarkPrefix = (string) config('saasshop.platform_orders.renewal_order_remark_prefix', '来自订阅:');
$q = [
'order_type' => 'renewal',
'site_subscription_id' => $subscription->id,
'quantity' => 1,
'remark' => $remarkPrefix . $subscription->subscription_no,
'back' => $back,
];
if ((int) ($subscription->merchant_id ?? 0) > 0) {
$q['merchant_id'] = (int) $subscription->merchant_id;
}
if ((int) ($subscription->plan_id ?? 0) > 0) {
$q['plan_id'] = (int) $subscription->plan_id;
}
$renewOrderUrl = '/admin/platform-orders/create?' . \Illuminate\Support\Arr::query($q);
@endphp
<div class="muted muted-xs" style="margin-top:4px;">
<a class="muted" href="{!! $renewOrderUrl !!}">续费下单</a>
</div>
</td>
<td>
@if($subscription->merchant)
<a class="link" href="{{ $buildSelfUrl(['merchant_id' => $subscription->merchant->id, 'page' => null]) }}">{{ $subscription->merchant->name }}</a>
@else
未关联站点
@endif
</td>
<td>
@if($subscription->plan)
<a class="link" href="{{ $buildSelfUrl(['plan_id' => $subscription->plan->id, 'page' => null]) }}">{{ $subscription->plan_name ?: $subscription->plan->name }}</a>
@else
{{ $subscription->plan_name ?: '未设置' }}
@endif
</td>
<td>{{ ($statusLabels[$subscription->status] ?? $subscription->status) }} <span class="muted">({{ $subscription->status }})</span></td>
<td>{{ $subscription->billing_cycle ?: '-' }}</td>
<td>{{ $subscription->period_months }}</td>
<td>¥{{ number_format((float) $subscription->amount, 2) }}</td>
<td>{{ optional($subscription->starts_at)->format('Y-m-d H:i:s') ?: '-' }}</td>
<td>{{ optional($subscription->ends_at)->format('Y-m-d H:i:s') ?: '-' }}</td>
<td>
@php
$endsAt = $subscription->ends_at;
$expiryLabel = '无到期';
if ($endsAt) {
if ($endsAt->lt(now())) {
$expiryLabel = '已过期';
} elseif ($endsAt->lt(now()->addDays(7))) {
$expiryLabel = '7天内到期';
} else {
$expiryLabel = '未到期';
}
}
@endphp
{{ $expiryLabel }}
</td>
<td>
@php $cnt = (int) ($subscription->platform_orders_count ?? 0); @endphp
@if($cnt > 0)
@php
$platformOrdersUrl = '/admin/platform-orders?' . \Illuminate\Support\Arr::query([
'site_subscription_id' => $subscription->id,
'back' => $back,
]);
@endphp
<a href="{!! $platformOrdersUrl !!}">{{ $cnt }}</a>
@else
<span class="muted">0</span>
@endif
</td>
<td>{{ optional($subscription->activated_at)->format('Y-m-d H:i:s') ?: '-' }}</td>
</tr>
@empty
<tr>
<td colspan="13" class="muted">暂无订阅数据,当前阶段先把订阅主表与总台目录立起来,后续再接订阅创建/激活/续费链路。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="pagination-wrap">{{ $subscriptions->links() }}</div>
@endsection