@extends('admin.layouts.app') @section('title', '套餐管理') @section('page_title', '套餐管理') @section('content') @php // back 参数用于“返回上一页(保留上下文)”,但 back 本身不应再包含 back(避免无限嵌套导致 URL 膨胀) $currentQuery = request()->query(); unset($currentQuery['back']); $selfWithoutBack = '/' . ltrim(request()->path(), '/'); if (count($currentQuery) > 0) { $selfWithoutBack .= '?' . \Illuminate\Support\Arr::query($currentQuery); } // 用于构建“从套餐页跳转到订阅/订单页后可返回套餐页”的链接 $makeSubscriptionUrl = function (array $query) use ($selfWithoutBack) { $query = $query + ['back' => $selfWithoutBack]; return '/admin/site-subscriptions?' . \Illuminate\Support\Arr::query($query); }; $makePlatformOrderUrl = function (array $query) use ($selfWithoutBack) { $query = $query + ['back' => $selfWithoutBack]; return '/admin/platform-orders?' . \Illuminate\Support\Arr::query($query); }; // back 安全护栏(全页通用): // - 仅允许站内相对路径(/ 开头) // - 拒绝引号/尖括号(由于本页大量 href 采用 `{!! !!}` 原样输出,必须严控注入风险) // - 拒绝 nested back=(避免 URL 膨胀/绕过) $incomingBack = (string) request()->query('back', ''); $safeBackForLinks = \App\Support\BackUrl::sanitizeForLinks($incomingBack); @endphp

这里是总台视角的套餐目录页,用于沉淀平台可售卖的标准能力包。

当前阶段先完成套餐主数据可见、可筛与口径收拢,后续再接授权项、售价规则与上下架动作。

@if($safeBackForLinks !== '')
← 返回上一页(保留上下文)
@endif

快捷筛选

用于运营快速定位需要处理的套餐集合(口径基于筛选条件组合)。
@php // 快捷筛选:仅保留“上下文”字段(back/keyword),避免把其它筛选条件叠加导致空结果 $buildQuickFilterUrl = function (array $overrides) use ($safeBackForLinks) { return \App\Support\BackUrl::currentPathQuickFilter(['keyword'], $overrides, $safeBackForLinks); }; // “全部”:清空筛选,但保留安全 back(用于返回来源页) $allUrl = \App\Support\BackUrl::withBack('/admin/plans', $safeBackForLinks); @endphp
全部 启用中 停用 已发布 未发布 月付 年付

工具

@csrf
安全护栏:当库中已存在套餐时会自动阻止,避免污染运营数据。

筛选条件

@if($safeBackForLinks !== '') @endif

套餐总数

{{ $summaryStats['total_plans'] ?? 0 }}

启用中套餐

{{ $summaryStats['active_plans'] ?? 0 }}

月付套餐

{{ $summaryStats['monthly_plans'] ?? 0 }}

年付套餐

{{ $summaryStats['yearly_plans'] ?? 0 }}

关联订阅总量

{{ $summaryStats['subscriptions_count'] ?? 0 }}

关联平台订单总量

{{ $summaryStats['platform_orders_count'] ?? 0 }}

套餐列表

后续将从这里进入套餐详情、授权项与订阅联动。

@php $createPlanUrl = '/admin/plans/create?' . \Illuminate\Support\Arr::query(['back' => $selfWithoutBack]); @endphp 新建套餐
@forelse($plans as $plan) @empty @endforelse
ID 套餐名称 编码 计费周期 售价 划线价 状态 排序 发布时间 关联订阅 关联平台订单 操作
{{ $plan->id }} {{ $plan->name }}
{{ $plan->description ?: '暂无说明' }}
{{ $plan->code }} {{ $billingCycleLabels[$plan->billing_cycle] ?? $plan->billing_cycle }} ¥{{ number_format((float) $plan->price, 2) }} ¥{{ number_format((float) $plan->list_price, 2) }} {{ $statusLabels[$plan->status] ?? $plan->status }} {{ $plan->sort }} {{ optional($plan->published_at)->format('Y-m-d H:i:s') ?: '-' }} @php $subCount = (int) ($plan->subscriptions_count ?? 0); @endphp @if($subCount > 0) {{ $subCount }} 个 @else 0 @endif @php $orderCount = (int) ($plan->platform_orders_count ?? 0); @endphp @if($orderCount > 0) {{ $orderCount }} 单 @else 0 @endif @php $editPlanUrl = '/admin/plans/' . $plan->id . '/edit?' . \Illuminate\Support\Arr::query(['back' => $selfWithoutBack]); $createOrderUrl = '/admin/platform-orders/create?' . \Illuminate\Support\Arr::query([ 'plan_id' => $plan->id, 'order_type' => 'new_purchase', 'back' => $selfWithoutBack, ]); @endphp
@csrf
暂无套餐数据,当前阶段先把套餐主表与总台目录立起来,后续可继续接套餐创建、授权项与订阅关联。
{{ $plans->links() }}
@endsection