diff --git a/app/Http/Controllers/Front/PlatformLeadController.php b/app/Http/Controllers/Front/PlatformLeadController.php new file mode 100644 index 0000000..9059879 --- /dev/null +++ b/app/Http/Controllers/Front/PlatformLeadController.php @@ -0,0 +1,42 @@ +validate([ + 'name' => ['required', 'string', 'max:100'], + 'mobile' => ['nullable', 'string', 'max:30'], + 'email' => ['nullable', 'string', 'max:100'], + 'company' => ['nullable', 'string', 'max:100'], + 'plan_id' => ['nullable', 'integer', 'exists:plans,id'], + 'note' => ['nullable', 'string', 'max:2000'], + 'source' => ['nullable', 'string', 'max:50'], + ]); + + PlatformLead::query()->create([ + 'name' => (string) ($data['name'] ?? ''), + 'mobile' => (string) ($data['mobile'] ?? ''), + 'email' => (string) ($data['email'] ?? ''), + 'company' => (string) ($data['company'] ?? ''), + 'plan_id' => (int) ($data['plan_id'] ?? 0) ?: null, + 'note' => $data['note'] ?? null, + 'source' => (string) ($data['source'] ?? 'platform'), + 'status' => 'new', + 'meta' => [ + 'ip' => $request->ip(), + 'user_agent' => (string) $request->userAgent(), + ], + ]); + + return redirect('/platform/plans') + ->with('success', '已收到你的开通意向,我们会尽快联系你。'); + } +} diff --git a/app/Models/PlatformLead.php b/app/Models/PlatformLead.php new file mode 100644 index 0000000..0f7054b --- /dev/null +++ b/app/Models/PlatformLead.php @@ -0,0 +1,27 @@ + 'array', + ]; +} diff --git a/database/migrations/2026_03_14_022630_create_platform_leads_table.php b/database/migrations/2026_03_14_022630_create_platform_leads_table.php new file mode 100644 index 0000000..e899c90 --- /dev/null +++ b/database/migrations/2026_03_14_022630_create_platform_leads_table.php @@ -0,0 +1,45 @@ +id(); + + // 对外平台线索/开通意向(前期先承接 A:站点开通型) + $table->string('name', 100)->default(''); + $table->string('mobile', 30)->default(''); + $table->string('email', 100)->default(''); + $table->string('company', 100)->default(''); + $table->string('source', 50)->default('platform'); + $table->string('status', 30)->default('new'); + $table->text('note')->nullable(); + + // 预期套餐(可选) + $table->unsignedBigInteger('plan_id')->nullable()->index(); + + // 扩展字段:便于后续接入 B(license)或更复杂的开通信息 + $table->json('meta')->nullable(); + + $table->timestamps(); + + $table->index(['status', 'created_at']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('platform_leads'); + } +}; diff --git a/resources/views/platform/plans.blade.php b/resources/views/platform/plans.blade.php index 4030385..50a461e 100644 --- a/resources/views/platform/plans.blade.php +++ b/resources/views/platform/plans.blade.php @@ -22,7 +22,7 @@
@forelse($plans as $p)
-
+

{{ $p->name }}

{{ $p->billing_cycle }}
@@ -32,9 +32,28 @@
{{ $p->description }}
@endif
- 我要开通/下单(暂由运营处理) +
+ @csrf + + + +
开通意向(A:站点开通型,前期先由运营人工开通)
+
+ +
+
+ +
+
+ +
+
+ + 运营手工下单入口 +
+
提示:前期先跑通收费闭环与治理;自助开通/自助支付会在后续版本接入。
+
-
提示:前期先跑通收费闭环与治理;自助开通会在后续版本接入。
@empty
diff --git a/routes/web.php b/routes/web.php index 09b3a7a..bda2366 100644 --- a/routes/web.php +++ b/routes/web.php @@ -41,6 +41,9 @@ Route::get('/wechat/mini', [MiniProgramController::class, 'index']); Route::prefix('platform')->group(function () { Route::get('/', [FrontPlatformController::class, 'index']); Route::get('/plans', [FrontPlatformController::class, 'plans']); + + // A:站点开通型前期先用“线索/开通意向”承接(后续再接自助开通/下单) + Route::post('/leads', [\App\Http\Controllers\Front\PlatformLeadController::class, 'store']); }); Route::get('/health', function () { diff --git a/tests/Feature/FrontPlatformLeadSubmitTest.php b/tests/Feature/FrontPlatformLeadSubmitTest.php new file mode 100644 index 0000000..3676d51 --- /dev/null +++ b/tests/Feature/FrontPlatformLeadSubmitTest.php @@ -0,0 +1,48 @@ +seed(); + + $plan = Plan::query()->create([ + 'code' => 'front_lead_plan_01', + 'name' => '线索提交测试套餐', + 'billing_cycle' => 'monthly', + 'price' => 99, + 'list_price' => 99, + 'status' => 'active', + 'sort' => 10, + 'published_at' => now(), + ]); + + $res = $this->post('/platform/leads', [ + 'name' => '张三', + 'mobile' => '13800000000', + 'company' => '测试公司', + 'plan_id' => $plan->id, + 'source' => 'platform_plans', + ]); + + $res->assertRedirect('/platform/plans'); + + $lead = PlatformLead::query()->latest('id')->first(); + $this->assertNotNull($lead); + $this->assertSame('张三', $lead->name); + $this->assertSame('13800000000', $lead->mobile); + $this->assertSame('测试公司', $lead->company); + $this->assertSame($plan->id, $lead->plan_id); + $this->assertSame('platform_plans', $lead->source); + $this->assertSame('new', $lead->status); + } +} diff --git a/tests/Feature/FrontPlatformPagesUseExternalCssTest.php b/tests/Feature/FrontPlatformPagesUseExternalCssTest.php index a5cafd3..e80cc89 100644 --- a/tests/Feature/FrontPlatformPagesUseExternalCssTest.php +++ b/tests/Feature/FrontPlatformPagesUseExternalCssTest.php @@ -9,16 +9,21 @@ class FrontPlatformPagesUseExternalCssTest extends TestCase { use RefreshDatabase; - public function test_platform_pages_should_link_platform_css_and_not_inline_style_block(): void + public function test_platform_index_should_use_external_css_and_not_inline_style_block(): void { - $res1 = $this->get('/platform'); - $res1->assertOk(); - $res1->assertSee('', false); - $res1->assertDontSee('