loadRoutes(__DIR__.'/../routes/web.php'); // 支付成功:按购买实体分发(激活会员订阅 / 解锁单篇付费文章) $manager->addAction('payment.paid', function (Payment $payment) { $user = $payment->user; $payable = $payment->payable; if (! $user || ! $payable) { return; } if ($payable instanceof MembershipPlan) { $now = now(); Subscription::create([ 'user_id' => $user->id, 'membership_plan_id' => $payable->id, 'status' => 'active', 'starts_at' => $now, 'ends_at' => $now->copy()->addDays($payable->duration_days), ]); } if ($payable instanceof Post) { $meta = $payable->meta ?? []; $unlocked = $meta['unlocked_user_ids'] ?? []; $unlocked[] = $user->id; $payable->update(['meta' => array_merge($meta, ['unlocked_user_ids' => array_values(array_unique($unlocked))])]); } }, 10); // 付费文章:[paid]...[/paid] —— 无权限访客替换为 teaser;有权限替换为付费内容块(避免原始标签裸露在页面) $manager->addFilter('post.rendered', function (string $html, \App\Models\Post $post) { $service = app(Services\MembershipService::class); $user = auth()->user(); if (preg_match('/\[paid\](.*?)\[\/paid\]/s', $html)) { // Markdown 转换会给短代码包上
,先去掉,避免替换后残留未闭合标签 $html = preg_replace('/
\s*\[(\/?paid)\]\s*<\/p>/i', '[$1]', $html); $html = preg_replace_callback( '/\[paid\](.*?)\[\/paid\]/s', function (array $m) use ($service, $user, $post) { if ($service->canReadPaidContent($user, $post)) { return '
'; } return view('membership.paid-teaser', ['post' => $post])->render(); }, $html ); } if (! $service->canReadPost($user, $post)) { return view('membership.paywall', ['post' => $post])->render(); } return $html; }, 10); // 后台文章表单注入:付费设置(meta.price 单篇价格 + meta.members_only 会员专享) $manager->addAction('filament.post_form', function (Schema $schema) { $schema->components([ ...$schema->getComponents(), Section::make('付费设置') ->description('需启用支付插件并配置支付渠道;0 = 免费') ->columns(3) ->collapsible() ->schema([ TextInput::make('meta.price') ->label('单篇价格(分)') ->numeric() ->minValue(0) ->default(0) ->helperText('例:9900 = ¥99;填 0 表示单篇免费'), Toggle::make('meta.members_only') ->label('会员专享') ->helperText('整篇文章仅会员可读'), ]), ]); }); // 后台文章表格注入:付费标识(价格/会员徽章,停用插件后消失) $manager->addAction('filament.post_table', function (Table $table) { $table->pushColumns([ TextColumn::make('meta.members_only') ->label('付费') ->badge() ->formatStateUsing(function ($state, $record) { $meta = $record->meta ?? []; $price = (int) ($meta['price'] ?? 0); if (! empty($meta['members_only'])) { return '会员'; } return $price > 0 ? '付费 ¥'.number_format($price / 100, 2) : '—'; }) ->color(function ($state, $record) { $meta = $record->meta ?? []; if (! empty($meta['members_only'])) { return 'warning'; } return (int) ($meta['price'] ?? 0) > 0 ? 'danger' : 'gray'; }) ->placeholder('—'), ]); }); } }