diff --git a/app/Http/Controllers/Admin/SiteSubscriptionController.php b/app/Http/Controllers/Admin/SiteSubscriptionController.php
index 810ca4a..6a8c422 100644
--- a/app/Http/Controllers/Admin/SiteSubscriptionController.php
+++ b/app/Http/Controllers/Admin/SiteSubscriptionController.php
@@ -9,11 +9,44 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\StreamedResponse;
+use App\Models\PlatformOrder;
class SiteSubscriptionController extends Controller
{
use ResolvesPlatformAdminContext;
+ public function show(Request $request, SiteSubscription $subscription): View
+ {
+ $this->ensurePlatformAdmin($request);
+
+ $subscription->loadMissing(['merchant', 'plan']);
+
+ $platformOrders = PlatformOrder::query()
+ ->where('site_subscription_id', $subscription->id)
+ ->latest('id')
+ ->paginate(10)
+ ->withQueryString();
+
+ $endsAt = $subscription->ends_at;
+ $expiryLabel = '无到期';
+ if ($endsAt) {
+ if ($endsAt->lt(now())) {
+ $expiryLabel = '已过期';
+ } elseif ($endsAt->lt(now()->addDays(7))) {
+ $expiryLabel = '7天内到期';
+ } else {
+ $expiryLabel = '未到期';
+ }
+ }
+
+ return view('admin.site_subscriptions.show', [
+ 'subscription' => $subscription,
+ 'platformOrders' => $platformOrders,
+ 'statusLabels' => $this->statusLabels(),
+ 'expiryLabel' => $expiryLabel,
+ ]);
+ }
+
public function export(Request $request): StreamedResponse
{
$this->ensurePlatformAdmin($request);
diff --git a/resources/views/admin/site_subscriptions/index.blade.php b/resources/views/admin/site_subscriptions/index.blade.php
index 532de2f..6918383 100644
--- a/resources/views/admin/site_subscriptions/index.blade.php
+++ b/resources/views/admin/site_subscriptions/index.blade.php
@@ -106,7 +106,7 @@
| {{ $subscription->id }} |
- {{ $subscription->subscription_no }}
+ {{ $subscription->subscription_no }}
|
@if($subscription->merchant)
diff --git a/resources/views/admin/site_subscriptions/show.blade.php b/resources/views/admin/site_subscriptions/show.blade.php
new file mode 100644
index 0000000..e13ea13
--- /dev/null
+++ b/resources/views/admin/site_subscriptions/show.blade.php
@@ -0,0 +1,135 @@
+@extends('admin.layouts.app')
+
+@section('title', '订阅详情')
+@section('page_title', '订阅详情')
+
+@section('content')
+
+
+ 这里是总台视角的订阅详情页,用于运营排查“订阅状态/到期/关联平台订单/同步记录”。
+
+
+
+
+ 订阅号
+ {{ $subscription->subscription_no }}
+
+
+ 状态
+ {{ ($statusLabels[$subscription->status] ?? $subscription->status) }} ({{ $subscription->status }})
+
+
+ 站点
+ {{ $subscription->merchant?->name ?? '未关联站点' }}
+
+
+ 套餐
+ {{ $subscription->plan_name ?: ($subscription->plan?->name ?? '未设置') }}
+
+
+
+
+
+ 计费周期 / 周期(月)
+ {{ $subscription->billing_cycle ?: '-' }} / {{ (int) $subscription->period_months }}
+
+
+ 金额
+ ¥{{ number_format((float) $subscription->amount, 2) }}
+
+
+ 开始时间
+ {{ optional($subscription->starts_at)->format('Y-m-d H:i:s') ?: '-' }}
+
+
+ 到期时间
+ {{ optional($subscription->ends_at)->format('Y-m-d H:i:s') ?: '-' }}
+
+
+
+
+
+ 到期状态(按到期时间)
+ {{ $expiryLabel }}
+
+
+ 试用到期
+ {{ optional($subscription->trial_ends_at)->format('Y-m-d H:i:s') ?: '-' }}
+
+
+ 生效时间
+ {{ optional($subscription->activated_at)->format('Y-m-d H:i:s') ?: '-' }}
+
+
+ 取消时间
+ {{ optional($subscription->cancelled_at)->format('Y-m-d H:i:s') ?: '-' }}
+
+
+
+
+
+
+
+ 关联平台订单({{ $platformOrders->total() }})
+
+
+
+ | ID |
+ 订单号 |
+ 订单状态 |
+ 支付状态 |
+ 应付/已付 |
+ 下单时间 |
+ 生效时间 |
+ 同步状态 |
+ 操作 |
+
+
+
+ @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
+
+ | {{ $order->id }} |
+ {{ $order->order_no }} |
+ {{ $order->status }} |
+ {{ $order->payment_status }} |
+ ¥{{ number_format((float) $order->payable_amount, 2) }} / ¥{{ number_format((float) $order->paid_amount, 2) }} |
+ {{ optional($order->placed_at)->format('Y-m-d H:i:s') ?: '-' }} |
+ {{ optional($order->activated_at)->format('Y-m-d H:i:s') ?: '-' }} |
+
+ {{ $syncStatus }}
+ @if($syncStatus === '同步失败')
+ ({{ mb_substr($syncErr, 0, 30) }})
+ @endif
+ |
+
+ 详情
+ |
+
+ @empty
+
+ | 暂无关联平台订单。 |
+
+ @endforelse
+
+
+
+
+
+@endsection
diff --git a/routes/web.php b/routes/web.php
index ff54025..a5379b1 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -109,6 +109,7 @@ Route::prefix('admin')->group(function () {
Route::get('/site-subscriptions', [SiteSubscriptionController::class, 'index']);
Route::get('/site-subscriptions/export', [SiteSubscriptionController::class, 'export']);
+ Route::get('/site-subscriptions/{subscription}', [SiteSubscriptionController::class, 'show']);
Route::get('/plans', [PlanController::class, 'index']);
Route::get('/plans/export', [PlanController::class, 'export']);
diff --git a/tests/Feature/AdminSiteSubscriptionShowTest.php b/tests/Feature/AdminSiteSubscriptionShowTest.php
new file mode 100644
index 0000000..3ed3136
--- /dev/null
+++ b/tests/Feature/AdminSiteSubscriptionShowTest.php
@@ -0,0 +1,119 @@
+seed();
+
+ $this->post('/admin/login', [
+ 'email' => 'platform.admin@demo.local',
+ 'password' => 'Platform@123456',
+ ])->assertRedirect('/admin');
+ }
+
+ public function test_platform_admin_can_open_site_subscription_show_page(): void
+ {
+ $this->loginAsPlatformAdmin();
+
+ $merchant = Merchant::query()->firstOrFail();
+ $plan = Plan::query()->create([
+ 'code' => 'sub_show_test',
+ 'name' => '订阅详情测试套餐',
+ 'billing_cycle' => 'monthly',
+ 'price' => 88,
+ 'list_price' => 88,
+ 'status' => 'active',
+ 'sort' => 10,
+ 'published_at' => now(),
+ ]);
+
+ $sub = SiteSubscription::query()->create([
+ 'merchant_id' => $merchant->id,
+ 'plan_id' => $plan->id,
+ 'status' => 'activated',
+ 'source' => 'manual',
+ 'subscription_no' => 'SUB_SHOW_0001',
+ 'plan_name' => $plan->name,
+ 'billing_cycle' => 'monthly',
+ 'period_months' => 1,
+ 'amount' => 88,
+ 'starts_at' => now()->subDays(2),
+ 'ends_at' => now()->addDays(20),
+ 'activated_at' => now()->subDays(2),
+ ]);
+
+ PlatformOrder::query()->create([
+ 'merchant_id' => $merchant->id,
+ 'plan_id' => $plan->id,
+ 'site_subscription_id' => $sub->id,
+ 'created_by_admin_id' => 1,
+ 'order_no' => 'PO_SUB_SHOW_0001',
+ 'order_type' => 'subscription',
+ 'status' => 'activated',
+ 'payment_status' => 'paid',
+ 'plan_name' => $plan->name,
+ 'billing_cycle' => 'monthly',
+ 'period_months' => 1,
+ 'quantity' => 1,
+ 'list_amount' => 88,
+ 'discount_amount' => 0,
+ 'payable_amount' => 88,
+ 'paid_amount' => 88,
+ 'placed_at' => now()->subDay(),
+ 'paid_at' => now()->subDay(),
+ 'activated_at' => now()->subDay(),
+ 'meta' => [
+ 'subscription_activation' => [
+ 'subscription_id' => $sub->id,
+ 'synced_at' => now()->subDay()->toDateTimeString(),
+ 'admin_id' => 1,
+ ],
+ ],
+ ]);
+
+ $this->get('/admin/site-subscriptions/' . $sub->id)
+ ->assertOk()
+ ->assertSee('订阅详情')
+ ->assertSee('SUB_SHOW_0001')
+ ->assertSee('关联平台订单')
+ ->assertSee('PO_SUB_SHOW_0001');
+ }
+
+ public function test_guest_cannot_open_site_subscription_show_page(): void
+ {
+ $merchant = Merchant::query()->create([
+ 'name' => '访客测试站点',
+ 'slug' => 'guest-test',
+ 'status' => 'active',
+ ]);
+
+ $sub = SiteSubscription::query()->create([
+ 'merchant_id' => $merchant->id,
+ 'status' => 'activated',
+ 'source' => 'manual',
+ 'subscription_no' => 'SUB_GUEST_0001',
+ 'plan_name' => '访客测试套餐',
+ 'billing_cycle' => 'monthly',
+ 'period_months' => 1,
+ 'amount' => 88,
+ 'starts_at' => now()->subDay(),
+ 'ends_at' => now()->addDays(29),
+ 'activated_at' => now()->subDay(),
+ ]);
+
+ $this->get('/admin/site-subscriptions/' . $sub->id)
+ ->assertRedirect('/admin/login');
+ }
+}
|