OJO 教程示例:YihuiCrew 独立站
这是一个 OJO 教程的示例项目,演示如何把 OJO 生成的多页面原型,接成可以浏览商品、管理内容、执行测试结账的独立站。
项目保留了原型的首页、商品列表、商品详情和博客界面,并提供 React 业务前端、Supabase 后端和 Stripe 测试支付。适合跟着教程学习、修改和搭建自己的示例站点。
本仓库是教学示例,使用 Stripe 测试模式,不会真实扣款或发货。示例商品、价格、库存和文章用于演示,不代表实际销售承诺。仓库不包含原站点的密钥、管理员账号、订单数据或部署凭证。
包含什么
- 原型界面:OJO 多页面原型、主题配置、商品展示、搜索、购物车。
- 业务前端:页面路由、商品分类与排序、颜色/尺码选择、购物车、中英文与 USD/CNY 切换。
- 管理后台:邮件链接登录,商品编辑、图片上传、文章草稿/发布和订单查询。
- Supabase:Postgres 表结构、RLS 权限、Storage 图片桶、Edge Functions。
- Stripe:服务端计算价格、库存预留、签名 Webhook、幂等订单处理和付款结果页。
USD/CNY 是后台分别设置的价格;示例人民币价格按美元数值的 7 倍填充,不是实时汇率。三篇示例文章保留为草稿,补齐正文并发布后才会显示在业务站博客中。
项目结构
prototype/ OJO 原型,可直接运行,无需配置后端
components/ 原型共享组件
business/ React + Vite 业务前端
src/ui/ 按原型还原的页面与组件
src/pages/ 后台、说明页、付款结果页
data/ 示例商品和文章,不含订单或用户数据
public/images/ 仓库自带的演示图片
.env.example 前端环境变量模板
supabase/
migrations/ 数据库结构与权限
functions/ 测试结账、订单状态、Stripe Webhook
.env.example Edge Functions 环境变量模板
lib/ API 客户端、集成工具与代码生成
scripts/ 示例数据导入和公开文件检查
.env.example 本地数据导入/数据库测试变量模板1. 先运行原型
需要 Node.js 22.12+(推荐 Node.js 24 LTS)和 pnpm 10。
git clone https://github.com/yihui-dev/ojo-yihuicrew-tutorial.git
cd ojo-yihuicrew-tutorial
pnpm install --frozen-lockfile
pnpm dev:prototype打开 http://localhost:3000。原型使用本地示例数据和图片,不需要 Supabase、Stripe 或 OJO 登录。原型购物车与结账是演示交互;真实后端接入在 business/ 中。
2. 配置自己的 Supabase
创建一个用于教程的 Supabase 项目,然后从仓库根目录执行:
pnpm exec supabase login
pnpm exec supabase link --project-ref YOUR_PROJECT_REF
pnpm exec supabase db push这会创建商品、文章、管理员白名单、订单和支付事件表,以及 crew-media 图片桶和访问策略。迁移默认不添加任何管理员。
在该项目的 SQL Editor 中,把下面的示例邮箱替换成你自己的管理员邮箱再执行:
insert into public.admin_emails (email)
values (lower('your-admin@example.com'))
on conflict (email) do nothing;在 Supabase Authentication → URL Configuration 中设置:
- Site URL:
http://localhost:5173 - Redirect URLs:
http://localhost:5173/admin - 部署后再添加你自己的 HTTPS 域名及
/admin回调地址。
管理员需要实际收到并打开登录邮件,且已验证的邮箱命中白名单。前端环境变量不能授予管理员权限。
3. 填写环境变量
本项目有三份 .env.example,用途不同,按下表复制并填写。模板中的值留空或使用占位符,请勿上传填好的环境文件。
| 文件 | 复制为 | 用途 |
|---|---|---|
business/.env.example | business/.env.local | Vite 前端读取的公开配置 |
supabase/functions/.env.example | supabase/functions/.env | 仅供 Edge Functions 使用的测试支付配置 |
.env.example | .env | 仅在本机运行示例数据导入和数据库测试 |
cp business/.env.example business/.env.local
cp supabase/functions/.env.example supabase/functions/.env
cp .env.example .env前端:business/.env.local
| 变量 | 说明 |
|---|---|
VITE_SUPABASE_URL | 自己的 Supabase Project URL |
VITE_SUPABASE_ANON_KEY | 自己项目的公开 anon key 或 publishable key |
VITE_CONTACT_EMAIL | 页面显示的联系邮箱,可选;不控制管理权限 |
VITE_ 开头的值会进入浏览器包。绝对不要把 service role key、Stripe secret key 或访问令牌放进 VITE_ 变量。
Edge Functions:supabase/functions/.env
| 变量 | 说明 |
|---|---|
STRIPE_SECRET_KEY | 自己 Stripe 测试模式的 secret key;代码拒绝正式模式密钥 |
STRIPE_WEBHOOK_SECRET | 自己的 Webhook endpoint 对应的签名密钥 |
SITE_URL | 付款成功/取消跳转地址的站点根 URL,无末尾 / |
EXTRA_ORIGINS | 额外允许的前端来源,用英文逗号分隔;可留空 |
托管 Supabase Edge Functions 自动提供 SUPABASE_URL 和 SUPABASE_SERVICE_ROLE_KEY,不需要把它们加入这份文件。参见 Supabase 环境变量文档。
本机:根目录 .env
SUPABASE_URL 和 SUPABASE_SERVICE_ROLE_KEY 用于导入示例商品;SUPABASE_ACCESS_TOKEN、SUPABASE_PROJECT_REF 仅在运行数据库测试时需要。它们不被 Vite 读取,也不应提交到仓库。
4. 导入示例数据并启动业务前端
填写根目录 .env 后执行:
pnpm seed:check
pnpm seed:demo
pnpm dev:business打开 http://localhost:5173,管理后台位于 /admin。
导入脚本只添加仓库中的 15 件演示商品和 3 篇文章草稿。遇到相同 slug 会跳过,不会重置已有商品的价格、库存或文章。它不创建管理员、用户或订单。
图片随仓库提供,使用 /images/demo-*.png,不依赖作者的 Supabase Storage。后台上传的新图片会进入你自己的 Storage。相对路径图片不会发送给 Stripe,测试 Checkout 仍会显示商品名称和金额;如需 Checkout 图片,可在后台使用你自己的公开 HTTPS 图片地址。
5. 接通 Stripe 测试支付
- 在你自己的 Stripe 测试环境取得 secret key,填入
supabase/functions/.env。 - 建立 Webhook endpoint:
https://YOUR_PROJECT_REF.supabase.co/functions/v1/stripe-webhook,订阅checkout.session.completed、checkout.session.async_payment_succeeded、checkout.session.expired、checkout.session.async_payment_failed。 - 将该 endpoint 的签名密钥填入
STRIPE_WEBHOOK_SECRET,设置SITE_URL=http://localhost:5173。 - 从仓库根目录上传密钥并部署函数:
pnpm exec supabase secrets set --env-file supabase/functions/.env
pnpm exec supabase functions deploy --use-api从业务站加入购物车并结账,使用 Stripe 官方测试卡,例如 4242 4242 4242 4242,填写未来的有效期和任意三位 CVC。只有收到并校验服务端付款事件,订单才会变为已支付。
本地运行 Edge Functions 时可用:
pnpm exec supabase functions serve --env-file supabase/functions/.env
stripe listen --forward-to http://127.0.0.1:54321/functions/v1/stripe-webhook这条本地路径需要先运行本地 Supabase(Docker + pnpm exec supabase start),前端也需改为本地 Supabase URL/key;监听命令输出的签名密钥与托管 endpoint 的密钥不同。参见 Stripe CLI 文档。
6. 构建、检查与部署
pnpm check:public
pnpm typecheck
pnpm test:supabase-api
pnpm --filter prototype test
pnpm build:all数据库测试会在事务中回滚测试数据;先填写根目录 .env 中的管理访问令牌和项目标识,再执行:
node --env-file=.env business/scripts/test-database.mjsbusiness/dist/ 可以部署到支持 SPA 回退的静态托管服务。仓库提供不含账号和域名的 Cloudflare Workers 配置:
pnpm dlx wrangler login
pnpm build:business
pnpm dlx wrangler deploy --config business/wrangler.jsonc使用你自己的 Cloudflare 账号,按需修改 Worker 名称或绑定自己的域名。部署后更新 Supabase Auth 的回调地址、Edge Functions 的 SITE_URL/EXTRA_ORIGINS,并重新上传函数环境变量。前端配置变化后需要重新构建。
公开范围与限制
- 代码采用 MIT License;Jost 字体遵循其 SIL Open Font License,依赖包保留各自许可证。
- 演示图片随仓库提供,原型布局和业务功能代码均可用于跟练。
- Git 忽略实际
.env、本地凭证、OJO/云平台运行状态、数据库备份和构建输出;仅提交.env.example。 check:public检查 Git 跟踪文件中的常见凭证格式与禁止提交的文件类型;它是辅助检查,不代表能识别所有秘密。- 本示例没有真实发货、自动税费、退款管理、实时汇率或邮件订阅服务。用于正式业务前,需要根据自己的商品和运营规则完善这些部分。