本文目录导读:

我来为您详细介绍如何使用 Laravel Spark 快速搭建 SaaS 项目。
环境准备
系统要求
- PHP >= 8.1 - Laravel >= 10.x - MySQL >= 5.7 或 PostgreSQL - Composer - Node.js & NPM
安装 Laravel
# 创建项目 composer create-project laravel/laravel my-saas # 进入项目目录 cd my-saas # 配置环境变量 cp .env.example .env php artisan key:generate
安装 Laravel Spark
通过 Composer 安装
# 添加 Spark 仓库 composer require laravel/spark # 发布配置文件 php artisan vendor:publish --tag=spark-config php artisan vendor:publish --tag=spark-migrations # 运行迁移 php artisan migrate # 安装前端资源 npm install npm run dev
配置 Stripe(支付)
# .env 文件中配置 STRIPE_KEY=your_stripe_key STRIPE_SECRET=your_stripe_secret STRIPE_WEBHOOK_SECRET=your_webhook_secret
基础配置
创建 Plan 配置
// config/spark.php
<?php
return [
'bills' => [
'stripe' => [
'plans' => [
[
'name' => 'Basic',
'short_reference' => 'basic',
'monthly_price' => 9.00,
'yearly_price' => 90.00,
'features' => [
'1 Project',
'5GB Storage',
'Basic Support'
]
],
[
'name' => 'Pro',
'short_reference' => 'pro',
'monthly_price' => 29.00,
'yearly_price' => 290.00,
'features' => [
'Unlimited Projects',
'100GB Storage',
'Priority Support',
'API Access'
]
],
],
],
],
];
配置用户模型
// app/Models/User.php
<?php
namespace App\Models;
use Laravel\Spark\Billable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Billable;
protected $fillable = [
'name',
'email',
'password',
'trial_ends_at',
];
protected $hidden = [
'password',
'remember_token',
];
}
创建 SaaS 核心功能
多租户支持
// app/Traits/TenantTrait.php
<?php
namespace App\Traits;
use Illuminate\Support\Facades\Auth;
trait TenantTrait
{
protected static function bootTenantTrait()
{
static::creating(function ($model) {
if (Auth::check() && empty($model->user_id)) {
$model->user_id = Auth::id();
}
});
static::addGlobalScope('user', function ($builder) {
if (Auth::check()) {
$builder->where('user_id', Auth::id());
}
});
}
}
订阅管理控制器
// app/Http/Controllers/SubscriptionController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Laravel\Spark\Spark;
class SubscriptionController extends Controller
{
public function subscribe(Request $request)
{
$request->validate([
'plan' => 'required|string',
'payment_method' => 'required|string'
]);
try {
$user = $request->user();
// 创建订阅
$subscription = $user->newSubscription(
$request->plan,
$request->plan
)->create($request->payment_method);
return response()->json([
'success' => true,
'subscription' => $subscription
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 422);
}
}
public function cancel(Request $request)
{
$user = $request->user();
$user->subscription()->cancel();
return response()->json(['success' => true]);
}
}
前端页面设置
路由配置
// routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SubscriptionController;
Route::middleware(['auth'])->group(function () {
// 仪表盘
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
// 订阅管理
Route::get('/settings/subscription', function () {
return view('subscription');
})->name('subscription');
Route::post('/subscribe', [SubscriptionController::class, 'subscribe'])->name('subscribe');
Route::post('/cancel-subscription', [SubscriptionController::class, 'cancel'])->name('cancel-subscription');
});
订阅页面视图
{{-- resources/views/subscription.blade.php --}}
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">订阅管理</div>
<div class="card-body">
@if(auth()->user()->subscribed())
<div class="alert alert-success">
当前订阅: {{ auth()->user()->subscription()->stripe_plan }}
</div>
<button class="btn btn-danger" onclick="handleCancel()">
取消订阅
</button>
@else
<form method="POST" action="{{ route('subscribe') }}" id="subscription-form">
@csrf
<div class="form-group">
<label>选择套餐</label>
<select name="plan" class="form-control" required>
<option value="basic">基础版 - $9/月</option>
<option value="pro">专业版 - $29/月</option>
</select>
</div>
<div class="form-group mt-3">
<label>支付方式</label>
<div id="card-element"></div>
</div>
<button type="submit" class="btn btn-primary mt-3">
立即订阅
</button>
</form>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
const stripe = Stripe('{{ config('services.stripe.key') }}');
const elements = stripe.elements();
const card = elements.create('card');
card.mount('#card-element');
const form = document.getElementById('subscription-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const {token} = await stripe.createToken(card);
// 添加 token 到表单
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = 'payment_method';
hiddenInput.value = token.id;
form.appendChild(hiddenInput);
// 提交表单
form.submit();
});
</script>
@endpush
中间件配置
订阅检查中间件
// app/Http/Middleware/CheckSubscription.php
<?php
namespace App\Http\Middleware;
use Closure;
class CheckSubscription
{
public function handle($request, Closure $next)
{
if (!$request->user()->subscribed()) {
return redirect()->route('subscription')
->with('error', '请先订阅才能访问此功能');
}
return $next($request);
}
}
管理后台功能
管理员面板
// app/Http/Controllers/Admin/DashboardController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Models\User;
use App\Models\Subscription;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index()
{
$stats = [
'total_users' => User::count(),
'active_subscriptions' => Subscription::where('status', 'active')->count(),
'monthly_revenue' => Subscription::where('status', 'active')->sum('amount'),
];
return view('admin.dashboard', compact('stats'));
}
}
Webhook 处理
// app/Http/Controllers/WebhookController.php
<?php
namespace App\Http\Controllers;
use Laravel\Spark\Spark;
use Illuminate\Http\Request;
class WebhookController extends Controller
{
public function handleStripeWebhook(Request $request)
{
$payload = json_decode($request->getContent(), true);
// 处理不同事件
switch ($payload['type']) {
case 'invoice.payment_succeeded':
// 更新订阅状态
break;
case 'customer.subscription.deleted':
// 处理订阅取消
break;
}
return response()->json(['received' => true]);
}
}
部署建议
生产环境优化
# 优化配置 php artisan config:cache php artisan route:cache php artisan view:cache # 使用队列 php artisan queue:work redis # 定时任务 (crontab) * * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1
数据库优化
-- 添加索引 ALTER TABLE subscriptions ADD INDEX idx_user_id (user_id); ALTER TABLE subscriptions ADD INDEX idx_status (status);
安全建议
-
API 限流
// app/Http/Kernel.php 'api' => [ 'throttle:60,1', 'bindings', ],
-
数据加密
// 加密敏感数据 $encrypted = encrypt($sensitiveData);
-
审计日志
-
定期备份
Laravel Spark 提供了完整的 SaaS 解决方案,包括:
- ✅ 订阅计费系统
- ✅ 多租户支持
- ✅ 发票管理
- ✅ 客户门户
- ✅ 管理后台
建议根据实际需求调整配置,确保系统安全和性能,如果需要更详细的功能实现,请告诉我具体需求!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播