English Version | 项目规范 | 原型说明
Veloform 是一款基于 Next.js、Tailwind CSS 并由 Supabase 驱动的高级自行车配置器应用。它允许用户浏览和定制不同类别自行车的配置清单,包括公路车 (Road)、山地车 (MTB) 和折叠车 (Fold)。
生产地址: https://veloform.app
代码仓库: https://github.com/sutchan/Veloform
- 工业奢华设计: 极简克制、充足留白与清晰视觉层次,烧锡色 (Burnt Sienna) 单一品牌主色,SF Pro 字体
- 双主题支持: 支持深色/浅色双主题模式,风格统一
- 实时价格与重量计算: 动态计算并展示整车造价及预计重量
- 配置云同步: 深度集成 Supabase Postgres 数据库与 Row Level Security,安全留存用户的独家配置方案
- 自动同步机制: 用户登录后自动加载云端配置,实现多设备间数据同步
- 车型分类: 在公路车、山地车和折叠车间无缝瞬间切换
- 完美响应式: 贯彻移动端优先范式,但保留毫不妥协的桌面端设计美学体验
- 双语支持: 内置 EN/ZH-CN 国际化系统,一键切换语言
- 配置库管理: 保存、加载、分享个人配置方案
- 流畅动画: 基于 Framer Motion 的微交互动画,提供自然流畅的用户体验
- 性能优化: 选择性状态订阅,避免不必要的组件重渲染
完整技术栈说明见 架构概览。
| 技术 | 版本 | 用途 |
|---|---|---|
| Next.js | v14.1.0 | App Router 架构,React Server Components |
| React | v18.2.0 | UI 组件库 |
| TypeScript | v5.x | 类型安全 |
| 技术 | 版本 | 用途 |
|---|---|---|
| Zustand | v4.5.0 | 轻量级状态管理 |
| 技术 | 版本 | 用途 |
|---|---|---|
| Tailwind CSS | v3.4.0 | 样式框架 |
| Framer Motion | v10.16.4 | 动画效果 |
| Lucide React | v0.294.0 | 图标库 |
| @base-ui/react | v1.5.0 | 无样式 UI 组件库 |
| class-variance-authority | v0.7.1 | 组件变体管理 |
| 技术 | 版本 | 用途 |
|---|---|---|
| Supabase | v2.45.0 | Postgres 数据库 + Row Level Security |
| 技术 | 版本 | 用途 |
|---|---|---|
| Vitest | v1.2.0 | 单元测试框架 |
| ESLint | v8.x | 代码检查 |
| Prettier | v3.2.0 | 代码格式化 |
| Husky | v9.0.0 | Git Hooks |
| Playwright | v1.60.0 | E2E 测试 |
src/
├── app/ # App Router 路由文件
│ ├── layout.tsx # 根布局(含 SyncProvider)
│ ├── page.tsx # 首页/配置器
│ ├── providers.tsx # 全局提供者
│ ├── globals.css # 全局样式
│ ├── error.tsx # 全局错误页面
│ ├── loading.tsx # 全局加载状态
│ ├── not-found.tsx # 404 页面
│ ├── about/ # 关于页面
│ │ └── page.tsx
│ ├── faq/ # FAQ 页面
│ │ └── page.tsx
│ └── library/ # 配置库页面
│ ├── page.tsx
│ ├── loading.tsx
│ └── error.tsx
├── components/ # UI 组件
│ ├── configurator/ # 配置器组件
│ │ ├── BikeTypeSelector.tsx # 车型选择器
│ │ ├── BuildList.tsx # 组件清单
│ │ ├── ComponentDetailModal.tsx # 组件详情模态框
│ │ ├── ComponentSelector.tsx # 组件选择器
│ │ ├── CostBreakdownChart.tsx # 成本分解图表
│ │ ├── RecommendedConfigs.tsx # 推荐配置
│ │ ├── ComparePanel.tsx # 配置对比面板
│ │ ├── ShareModal.tsx # 分享模态框
│ │ └── SummaryPanel.tsx # 汇总面板
│ ├── layout/ # 布局组件
│ │ ├── Navbar.tsx # 导航栏
│ │ └── Footer.tsx # 页脚
│ ├── sections/ # 页面区块组件
│ │ ├── Hero.tsx # 英雄区块
│ │ ├── Features.tsx # 功能特性区块
│ │ ├── Pricing.tsx # 定价区块
│ │ └── Cta.tsx # 行动召唤区块
│ ├── ui/ # 通用 UI 组件
│ │ ├── button.tsx # 按钮组件
│ │ ├── card.tsx # 卡片组件
│ │ ├── ErrorBoundary.tsx # 错误边界
│ │ ├── AsyncBoundary.tsx # 异步边界
│ │ ├── LoadingScreen.tsx # 加载屏幕
│ │ ├── Modal.tsx # 模态框
│ │ ├── OnboardingGuide.tsx # 新手引导
│ │ ├── SupportModal.tsx # 支持模态框
│ │ ├── ThemeToggle.tsx # 主题切换
│ │ └── ... # 更多 UI 组件
│ ├── SyncProvider.tsx # 云同步提供者(Auth + Supabase)
│ └── ClientErrorBoundary.tsx # 客户端错误边界
├── lib/ # 工具库
│ ├── stores/ # Zustand 状态管理
│ │ ├── config-store.ts # 配置状态
│ │ ├── config-ui-store.ts # UI 状态
│ │ ├── compare-store.ts # 对比状态
│ │ ├── user-store.ts # 用户状态
│ │ └── index.ts # 状态导出
│ ├── hooks/ # 自定义 Hooks
│ │ └── use-client-reduced-motion.ts
│ ├── data/ # 模块化数据
│ │ ├── index.ts
│ │ ├── component-details/ # 组件详情数据(已模块化拆分)
│ │ └── component-alternatives.ts
│ ├── i18n/ # 国际化
│ │ ├── index.ts # i18n 核心逻辑
│ │ ├── en.ts # 英语翻译
│ │ └── zh-CN.ts # 简体中文翻译
│ ├── auth.ts # Supabase 认证服务
│ ├── constants.ts # 应用常量
│ ├── env.ts # 环境变量验证
│ ├── supabase-service.ts # Supabase 数据服务
│ ├── supabase.ts # Supabase 客户端配置
│ ├── config-service.ts # 配置服务
│ ├── shareable-config.ts # 可分享配置
│ ├── recommended-configs.ts # 推荐配置
│ ├── utils.ts # 工具函数
│ ├── animation.ts # 动画配置
│ ├── lazy.tsx # 懒加载组件
│ └── logger.ts # 日志工具
├── types/ # TypeScript 类型定义
│ └── index.ts # 强化类型定义(含组件规格接口)
└── middleware.ts # Next.js 中间件
详细开发规范请参阅 openspec/PROJECT_GUIDELINES.md。
- Node.js >= 18.x
- npm 或 pnpm
- Supabase 项目(用于 Postgres 数据库 + Row Level Security)
-
克隆仓库:
git clone https://github.com/sutchan/Veloform.git cd Veloform -
安装依赖:
npm install # 或使用 pnpm pnpm install -
配置环境变量:
cp .env.example .env # 编辑 .env 填入 Supabase URL 和 anon key -
启动开发服务器:
npm run dev
-
访问应用: 浏览器打开
http://localhost:3000
- 访问 Supabase Dashboard
- 创建新项目
- 在 SQL Editor 中按顺序运行
supabase/migrations/目录下的所有迁移脚本(含初始表结构与 RLS 安全策略加固) - 在 Authentication 中启用 Email/Password 和 Google OAuth 登录
- 在项目设置中获取 Web App 配置
- 将配置值填入
.env文件
| 命令 | 说明 |
|---|---|
npm run dev |
启动开发服务器(端口 3000) |
npm run build |
构建生产版本 |
npm run start |
启动生产服务器 |
| 命令 | 说明 |
|---|---|
npm run lint |
运行 ESLint 检查 |
npm run lint:fix |
自动修复 ESLint 错误 |
npm run format |
使用 Prettier 格式化代码 |
npm run format:check |
检查代码格式是否符合规范 |
| 命令 | 说明 |
|---|---|
npm run test |
运行单元测试 |
npm run test:coverage |
运行测试并生成覆盖率报告 |
| 命令 | 说明 |
|---|---|
npm run analyze |
分析打包体积 |
npm run generate-icons |
生成图标资源 |
npm run prepare |
初始化 Git Hooks (Husky) |
本项目内置完整的国际化系统,当前支持以下语言:
- 英语 (English) -
en - 简体中文 -
zh-CN
- 类型安全: 编译时验证翻译键,避免运行时错误
- 嵌套翻译: 支持多层级的翻译结构
- 参数插值: 支持动态参数替换
{param} - 数组支持: 支持返回字符串数组的翻译键
import { useTranslation, useLanguage, useSetLanguage } from '@/lib/i18n';
function MyComponent() {
const t = useTranslation();
const language = useLanguage();
const setLanguage = useSetLanguage();
return (
<div>
<h1>{t('app.name')}</h1>
<p>{t('configurator.totalCost', { cost: '¥12,000' })}</p>
<button onClick={() => setLanguage(language === 'en' ? 'zh-CN' : 'en')}>
{language === 'en' ? '切换到中文' : 'Switch to English'}
</button>
</div>
);
}- 在
src/lib/i18n/目录下创建新的语言文件(如ja.ts) - 实现
Translations接口的所有翻译键 - 在
src/lib/i18n/index.ts中导入并注册新语言
完整的开发约定、分支与提交规则、测试要求和文档维护指南,请参阅:
- openspec/README.md - 规范文档索引(推荐从这里开始)
- openspec/PROJECT_GUIDELINES.md - 项目开发指南
- openspec/design/ui-design-system.md - UI 设计系统
- openspec/prototype-guide.md - 原型图说明
- openspec/design/design-review.md - 设计审查与优化建议
本项目支持以下部署平台:
- Vercel: 推荐部署平台,零配置自动部署
- EdgeOne Pages: 腾讯云边缘部署方案
部署指南见 环境配置。
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建功能分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'feat: add amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 创建 Pull Request
提交前请确保:
- 所有测试通过 (
npm run test) - Lint 检查通过 (
npm run lint) - 遵循 编码规范
当前版本:v4.2.0 最后更新:2026-07-18
详细变更记录见 CHANGELOG.md。
本项目采用 MIT License 开源协议。
详见 LICENSE 文件。