30分钟用Wave搭建带认证与计费的SaaS骨架

13 次阅读 0 点赞 0 评论 12 分钟原创技术教程

本文手把手教你使用基于 Laravel 的开源 Starter Kit——Wave,快速跑通一套包含用户认证、订阅计费、角色权限和后台管理的完整 SaaS 骨架。附带 Stripe 测试支付对接与自定义业务页面开发实战,助你省去重复基建时间,将精力聚焦于核心产品打磨。

#Laravel #SaaS #PHP #Stripe #Tailwind #独立开发 #Starter-Kit
30分钟用Wave搭建带认证与计费的SaaS骨架

30分钟用Wave搭建带认证与计费的SaaS骨架

做 SaaS 产品最耗时的往往不是核心业务逻辑,而是那些「每个应用都得有」的基础模块:用户注册登录、权限控制、订阅计费计划、后台管理面板。从零手写这些基建功能,不仅开发周期长,Stripe 或 Paddle 的 Webhook 回调调试也容易让人头疼。

本文以开源项目 Wave 为载体,带你一步步搭建一套能直接运行的 SaaS 骨架。学完本教程,你将获得一套包含完整认证、用户管理、计费系统和管理后台的 Laravel 项目,并掌握如何在此基础上快速接入自己的业务逻辑。

环境准备

Wave 本质上是基于 Laravel 10+ 构建的 Starter Kit,运行前请确保本地环境满足以下要求:

  • PHP >= 8.1(推荐搭配 Laravel Herd 或 Laragon 一键配置)
  • Composer(PHP 依赖管理工具)
  • Node.js & NPM(用于 Tailwind CSS 和 Vite 前端资源编译)
  • MySQL 或 SQLite(本地验证建议直接用 SQLite,零配置最省心)
  • 具备基础的 Laravel 开发认知(熟悉 Artisan 命令、路由定义、Blade 模板语法即可)

如果你是 macOS 用户且使用了 Laravel Herd,可以直接执行 herd new --starter-kit=devdojo/wave 完成初始化。本文采用标准的 Composer 安装方式,确保所有开发者都能复现。

核心步骤:5 分钟拉起完整骨架

1. 初始化项目

打开终端,执行以下命令拉取项目并切换目录:

bash 复制代码
composer create-project devdojo/wave my-saas-app
cd my-saas-app

Composer 会自动下载 Laravel 框架核心及 Wave 的 SaaS 功能模块。安装完成后,你会发现项目目录结构与标准 Laravel 一致,但多了大量预配置的认证、计费视图和中间件。

2. 配置环境变量

复制默认环境配置文件并生成应用加密 Key:

bash 复制代码
cp .env.example .env
php artisan key:generate

编辑 .env 文件,将数据库连接切换为 SQLite,跳过繁琐的本地数据库创建过程:

env 复制代码
DB_CONNECTION=sqlite

随后手动创建空数据库文件:

bash 复制代码
touch database/database.sqlite

3. 迁移数据表与填充初始数据

Wave 已经为你预定义了用户表、订阅计划表、角色权限表等完整结构。运行迁移命令即可一键建表:

bash 复制代码
php artisan migrate --seed

--seed 参数会向数据库中插入默认数据,例如预置的 Free 和 Pro 订阅计划。无需手动写 SQL 或 Migration 脚本。

4. 启动开发服务

bash 复制代码
php artisan serve

浏览器访问 http://localhost:8000,你将直接看到 Wave 默认首页。点击右上角 Register 即可体验完整的注册、登录、密码找回流程。

至此,一套具备基础能力的 SaaS 应用已经跑通。

实战一:开发自定义业务仪表板

骨架跑通只是第一步。假设你正在开发一款「AI 写作助手」,用户登录后需要展示专属的使用量统计与写作面板。

创建控制器

使用 Artisan 生成控制器文件:

bash 复制代码
php artisan make:controller DashboardController

编辑 app/Http/Controllers/DashboardController.php,加入用户认证校验与数据聚合逻辑:

php 复制代码
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function index()
    {
        // Wave 的 auth 中间件已处理未登录拦截,此处可直接获取用户实例
        $user = auth()->user();
        $plan = $user->plan()->first();
        
        return view('wave::dashboard', [
            'user' => $user,
            'plan' => $plan,
            'usage' => $this->getUsage($user),
        ]);
    }

    private function getUsage($user)
    {
        // 替换为你的实际业务统计逻辑(如数据库查询或 API 调用)
        return [
            'words_generated' => 1250,
            'api_calls' => 48,
        ];
    }
}

注册路由

routes/web.php 中添加受保护的路由组:

php 复制代码
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', [App\Http\Controllers\DashboardController::class, 'index'])
         ->name('dashboard');
});

编写视图

Wave 的视图系统采用命名空间注册机制。通过 resources/views/vendor/wave/ 目录下的模板,你可以安全覆盖默认布局而不会影响后续框架升级。

创建 resources/views/vendor/wave/dashboard.blade.php

blade 复制代码
@extends('wave::app')

@section('content')
<div class="max-w-4xl mx-auto py-8">
    <h1 class="text-2xl font-bold mb-4">欢迎回来,{{ $user->name }}!</h1>
    <div class="bg-white rounded-lg shadow p-6">
        <p>当前计划:<span class="font-semibold">{{ $plan->name ?? 'Free' }}</span></p>
        <div class="mt-4 grid grid-cols-2 gap-4">
            <div class="p-4 bg-gray-50 rounded">
                <p class="text-sm text-gray-500">已生成字数</p>
                <p class="text-xl font-bold">{{ number_format($usage['words_generated']) }}</p>
            </div>
            <div class="p-4 bg-gray-50 rounded">
                <p class="text-sm text-gray-500">API 调用次数</p>
                <p class="text-xl font-bold">{{ $usage['api_calls'] }}</p>
            </div>
        </div>
    </div>
</div>
@endsection

刷新页面,访问 /dashboard 即可看到你定制的业务面板。

实战二:接入 Stripe 测试支付

Wave 内置了 Stripe 和 Paddle 的计费适配层。开发阶段务必使用测试模式,避免产生真实扣费。

  1. 登录 Stripe 开发者后台,复制测试环境的 Publishable KeySecret Key
  2. .env 中追加以下配置:
env 复制代码
STRIPE_KEY=pk_test_xxxxxxxxxxxxxxxx
STRIPE_SECRET=sk_test_xxxxxxxxxxxxxxxx
BILLING_PROVIDER=stripe

Wave 的计费模块会自动读取环境变量。你可以直接在管理后台(/admin -> Billing -> Plans)可视化创建订阅计划,或使用 Tinker 快速生成:

bash 复制代码
php artisan tinker
php 复制代码
>>> \Wave\Plan::create([
...     'name' => 'Pro',
...     'price' => 19.99,
...     'interval' => 'month',
...     'features' => json_encode(['无限量写作', 'API 高优先级', '专属客服']),
... ]);

配置完成后,访问首页 Pricing 区域即可看到 Pro 计划。点击订阅将跳转至 Stripe Checkout 安全收银台。使用测试卡号 4242 4242 4242 4242(过期日期填未来任意时间,CVC 任意三位)即可模拟完整的支付成功流程。

开发避坑指南

在基于 Wave 进行二次开发时,以下几点能帮你节省大量调试时间:

  1. 前端样式未生效:记得运行 npm install && npm run dev。Vite 需要实时编译 Tailwind 工具类。若样式仍异常,检查 vite.config.js 的入口是否准确指向 resources/css/app.css
  2. 本地收不到 Stripe Webhook:生产环境配置真实域名即可,开发环境推荐使用 Stripe CLI 进行请求转发:stripe listen --forward-to localhost:8000/webhook/stripe。这能让你在本地直接调试异步回调逻辑。
  3. 升级导致自定义视图丢失:绝对不要直接修改 vendor/devdojo/wave/resources/views 下的文件。Composer 的 update 命令会彻底清空该目录。正确做法是将模板复制到 resources/views/vendor/wave/ 后再进行修改,利用 Laravel 的视图覆盖优先级机制保持兼容。
  4. SQLite 外键约束报错:若在迁移时遇到外键限制,在 .env 中设置 DB_FOREIGN_KEYS=true,并在 config/database.php 的 SQLite 驱动配置中启用 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true)

总结与建议

通过不到 10 分钟的环境配置与启动,加上几十分钟的自定义开发与支付联调,你现在手中已经握有一套功能完备的 SaaS 原型。Wave 帮你剥离了重复的底层基建,让你能够直接面对真实用户和核心业务。

接下来的演进路线建议:

  • 注入核心逻辑:将 OpenAI API 调用、文档处理或你的专属算法接入到控制器中。
  • 善用插件机制:尽量通过扩展或插件形式添加新功能,避免污染 Wave 核心代码,方便后续平滑升级。
  • 异步任务处理:配置 Redis 或 Beanstalkd 队列,将订阅成功邮件、账单生成等耗时操作移出请求主线程。
  • 生产环境部署:将 SQLite 替换为 MySQL 或 PostgreSQL,配置 Nginx 反向代理与 HTTPS,选择 VPS 或 Serverless 平台上线。

把节省下来的时间投入到产品体验打磨与用户反馈迭代中,才是独立开发者破局的关键。如果在对接过程中遇到任何报错,欢迎在评论区贴出具体的错误堆栈,我会协助排查。

最后更新:2026-07-31T10:02:44

评论 (0)

发表评论

blog.comments.form.loading
0/500
加载评论中...