From 7228a4f14a35819685519571beae88ed93cd0cba Mon Sep 17 00:00:00 2001 From: ak Date: Wed, 12 Aug 2026 01:12:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BB=98=E8=B4=B9=E5=9D=97=E6=96=87?= =?UTF-8?q?=E7=AB=A0=E8=A7=A3=E9=94=81=E6=97=A0=E5=93=8D=E5=BA=94=E2=80=94?= =?UTF-8?q?=E2=80=94unlockPost=20=E5=AE=88=E5=8D=AB=E8=AF=AF=E7=94=A8=20ca?= =?UTF-8?q?nReadPost?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 付费块文章的整篇是公开的,canReadPost 恒为 true,导致解锁请求被"已有权限"守卫拦截直接跳回文章页,不创建订单。改为按 canReadPaidContent 判断(能否读付费内容),并补回归测试:付费块解锁→创建订单→沙箱支付→[paid] 块可见 --- .../src/Http/MembershipController.php | 5 ++-- tests/Feature/MembershipFlowTest.php | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/plugins/neatstudio.membership/src/Http/MembershipController.php b/plugins/neatstudio.membership/src/Http/MembershipController.php index d55b596..460f85b 100644 --- a/plugins/neatstudio.membership/src/Http/MembershipController.php +++ b/plugins/neatstudio.membership/src/Http/MembershipController.php @@ -78,8 +78,9 @@ class MembershipController { $user = $request->user(); - // 已有阅读权限(会员 / 作者 / 已解锁):直接查看文章,避免重复支付 - if ($this->service->canReadPost($user, $post)) { + // 已能读付费内容(会员 / 作者 / 已解锁):直接查看文章,避免重复支付。 + // 注意:付费块文章的整篇是公开的,不能用 canReadPost 判断(否则永远"已有权限") + if ($this->service->canReadPaidContent($user, $post)) { return redirect()->route('posts.show', $post->slug ?? $post->id); } diff --git a/tests/Feature/MembershipFlowTest.php b/tests/Feature/MembershipFlowTest.php index 24e6acf..9652426 100644 --- a/tests/Feature/MembershipFlowTest.php +++ b/tests/Feature/MembershipFlowTest.php @@ -186,6 +186,35 @@ class MembershipFlowTest extends TestCase $this->assertSame(0, Payment::query()->count()); } + public function test_unlock_paid_block_creates_payment_for_non_member(): void + { + $post = Post::create([ + 'title' => '付费块文章', + 'slug' => 'paid-block-unlock', + 'content' => "开头\n\n[paid]\n隐藏付费块\n[/paid]\n\n结尾", + 'content_format' => 'markdown', + 'status' => 'published', + 'published_at' => now(), + 'meta' => ['price' => 500], + ]); + + // 付费块文章的整篇公开,但 [paid] 块不可读——解锁必须创建订单,不能误判为"已有权限" + $this->actingAs($this->user) + ->post('/posts/'.$post->id.'/unlock') + ->assertRedirect(route('pay.checkout', Payment::first())); + + $payment = Payment::query()->where('user_id', $this->user->id)->first(); + $this->assertNotNull($payment); + $this->assertTrue($payment->payable->is($post)); + $this->assertSame('pending', $payment->status); + + // 沙箱支付后 [paid] 块可见 + $this->actingAs($this->user)->post('/pay/sandbox/'.$payment->order_no.'/confirm'); + $this->actingAs($this->user)->get('/posts/paid-block-unlock.shtml') + ->assertOk() + ->assertSee('隐藏付费块'); + } + public function test_members_only_post_shows_paywall_to_guest(): void { $post = Post::create([