SnapCal 是一款基于 AI 技术的智能营养记录应用,通过拍照识别食物,自动分析营养成分,帮助用户轻松追踪每日卡路里和营养摄入。
🎯 关键词:AI 营养记录 | 卡路里追踪 | 食物识别 | 健康管理 | 营养分析 | 饮食记录 | Next.js | React | TypeScript | 移动端应用 | 中式饮食
SnapCal 是一个面向移动端的 AI 驱动的智能营养记录应用,支持通过拍照或上传食物图片,利用大语言模型(豆包 AI)自动识别食物并分析营养成分。应用以卡路里追踪和三大营养素(蛋白质、碳水化合物、脂肪)为核心,提供直观的可视化统计和趋势分析,帮助用户科学管理日常饮食。
- 🏃 健身人群:追踪每日蛋白质、碳水化合物和脂肪摄入
- 💪 减肥人群:监控卡路里摄入,控制热量缺口
- 🥗 健康管理:了解食物营养成分,做出更健康的饮食选择
- 📱 移动用户:随时随地记录饮食,无需手动输入
- 🍜 中式饮食:特别优化中式菜肴的营养分析
- 🤖 AI 智能识别:基于豆包大模型,精准识别食物类型和营养成分,支持中式菜肴识别
- 📱 移动端优先:专为移动设备设计的响应式 UI,支持触摸操作和手势交互
- 📊 可视化统计:直观的图表展示(Recharts),支持周/月营养趋势分析
- 🎯 精准计算:支持份量调整(0.5x-3.0x),实时计算卡路里和宏量营养素
- 🍜 中式优化:特别针对中式菜肴的营养分析优化(考虑油、盐含量)
- 🌙 深色模式:支持浅色/深色主题切换,保护眼睛
- ⚡ 实时更新:数据实时同步,响应迅速
- 🎨 现代 UI:基于 shadcn/ui 和 Tailwind CSS 的现代化界面设计
-
📸 食物扫描
- 支持相机拍照和图片上传
- 实时预览和裁剪
- 自动识别食物类型和份量
-
📊 营养分析
- 自动识别食物名称和置信度
- 卡路里计算(精确到整数)
- 三大营养素分析(蛋白质、碳水化合物、脂肪)
- 详细营养素展示(钠、膳食纤维、维生素等)
- 份量调整功能(0.5倍递增),实时联动计算
- 环形图 + 列表双重展示(克数与百分比)
-
📈 趋势分析
- 本周/上周/本月统计对比
- 卡路里和营养素趋势图表
- 日均摄入量分析
- 目标达成情况可视化
-
📱 移动端体验
- 底部导航栏快速切换
- 浮动扫描按钮(FAB)
- 响应式布局,适配各种屏幕尺寸
- 流畅的动画和交互效果
-
🌍 中文界面
- 全中文界面(zh-CN)
- 本地化日期和时间格式
- 符合中文用户使用习惯
- Next.js 16 - React 全栈框架(App Router)
- React 19.2 - UI 库
- TypeScript 5.6 - 类型安全
- Tailwind CSS v4.1 - 实用优先的 CSS 框架
- shadcn/ui - 高质量组件库 (Radix UI)
- lucide-react - 图标库
- next-themes - 主题切换支持
- React Hook Form - 表单处理
- Zod - 数据验证
- Supabase - 数据库、认证和存储
- PostgreSQL - 主数据库
- SWR - 数据获取和缓存
- Recharts - React 图表库
- date-fns - 日期处理
- 豆包 API (Doubao) - 字节跳动大语言模型 (doubao-seed-1-6-flash-250828)
- 自定义提示词工程 (135行优化提示词)
- JSON 结果校验与处理
- 图片哈希去重和缓存机制
- ESLint - 代码检查
- PostCSS - CSS 处理
- Autoprefixer - CSS 兼容性
- 环境变量验证 - lib/env-config.ts
- 安全头部配置 - CSP, XSS 防护等
- 文件验证中间件 - 图片安全检查
- 认证中间件 - JWT 令牌管理
- TypeScript 严格模式 - 构建时类型检查
- Vercel - 部署平台
- Vercel Analytics - 用户行为分析
SnapCal/
├── app/ # Next.js App Router 页面
│ ├── layout.tsx # 根布局(全局 HTML 和 metadata)
│ ├── page.tsx # 首页(每日营养概览)
│ ├── globals.css # 全局样式
│ ├── scan/ # 扫描页面
│ │ └── page.tsx # 相机/上传界面
│ ├── analysis/ # 分析结果页
│ │ └── page.tsx # 营养详情展示
│ ├── analytics/ # 趋势分析页
│ │ └── page.tsx # 统计图表
│ ├── profile/ # 个人中心
│ │ ├── page.tsx # 用户主页
│ │ ├── edit/ # 编辑资料
│ │ ├── goals/ # 目标设置
│ │ ├── achievements/ # 成就系统
│ │ ├── export/ # 导出数据
│ │ ├── privacy/ # 隐私设置
│ │ ├── notifications/ # 通知设置
│ │ ├── share/ # 分享功能
│ │ ├── about/ # 关于页面
│ │ └── help/ # 帮助页面
│ ├── meal/[id]/ # 餐食详情页
│ │ └── page.tsx # 动态餐食详情
│ ├── auth/ # 认证页面
│ │ └── page.tsx # 登录/注册
│ ├── admin/ # 管理后台
│ │ └── login-records/ # 登录记录管理
│ └── api/ # API 路由
│ ├── analyze/ # 食物分析接口
│ │ └── route.ts # POST /api/analyze
│ ├── meals/ # 餐食记录 CRUD
│ │ ├── route.ts # GET/POST /api/meals
│ │ └── [id]/route.ts # GET/PUT/DELETE /api/meals/[id]
│ ├── analytics/ # 营养分析统计
│ │ └── route.ts # GET /api/analytics
│ ├── analysis/[id]/ # 分析记录详情
│ │ └── route.ts # GET /api/analysis/[id]
│ └── auth/ # 认证相关接口
│ ├── login/ # 登录
│ ├── register/ # 注册
│ └── login-records/ # 登录记录
├── components/ # 组件库
│ ├── ui/ # shadcn/ui 组件
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── chart.tsx
│ │ └── ... # 其他 UI 组件
│ ├── bottom-nav.tsx # 底部导航栏
│ ├── fab-button.tsx # 浮动扫描按钮
│ ├── theme-provider.tsx # 主题提供者
│ ├── auth-guard.tsx # 认证守卫
│ ├── error-boundary.tsx # 错误边界
│ └── optimized-image.tsx # 优化图片组件
├── lib/ # 工具库
│ ├── ai-config.ts # AI 配置和提示词
│ ├── doubao-service.ts # 豆包 API 封装
│ ├── supabase.ts # Supabase 客户端和服务
│ ├── auth-manager.ts # 认证管理器
│ ├── analysis-service.ts # 分析服务
│ ├── env-config.ts # 环境变量验证
│ ├── auth-middleware.ts # 认证中间件
│ ├── validation-middleware.ts # 验证中间件
│ ├── error-handler.ts # 错误处理
│ ├── api-response.ts # API 响应格式化
│ ├── auth-error-handler.ts # 认证错误处理
│ ├── file-security.ts # 文件安全验证
│ ├── data-transform.ts # 数据转换
│ └── utils.ts # 工具函数(cn 等)
├── hooks/ # 自定义 Hooks
│ ├── use-mobile.ts # 移动端检测
│ ├── use-toast.ts # Toast 通知
│ ├── use-auth.ts # 认证状态
│ ├── use-loading-state.ts # 加载状态
│ └── use-persistent-state.ts # 持久化状态
├── types/ # TypeScript 类型定义
│ └── index.ts # 全局类型定义
├── middleware.ts # Next.js 中间件
├── public/ # 静态资源
│ ├── logo.png # 应用图标
│ └── ... # 其他资源
├── migrations/ # 数据库迁移
│ ├── add_nutrition_details.sql # 营养详情字段
│ └── create_logging_tables.sql # 日志表
├── supabase/migrations/ # Supabase 迁移
│ └── add_performance_indexes.sql # 性能索引
├── .env.template # 环境变量模板
├── .env.local # 本地环境变量(不提交)
├── package.json # 依赖配置
├── tsconfig.json # TypeScript 配置
├── tailwind.config.js # Tailwind 配置
├── next.config.mjs # Next.js 配置
└── README.md # 项目说明
- Node.js >= 18.0.0
- npm >= 9.0.0 或 pnpm >= 8.0.0
- 克隆项目
git clone https://github.com/your-username/SnapCal.git
cd SnapCal- 安装依赖
# 使用 npm
npm install
# 或使用 pnpm(推荐)
pnpm install- 配置环境变量
复制环境变量模板并创建 .env.local 文件:
cp .env.template .env.local编辑 .env.local 文件,填入必需的配置:
# ===========================================
# Supabase 配置 (必需)
# ===========================================
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key-here
# ===========================================
# AI 服务配置 (必需)
# ===========================================
DOUBAO_API_KEY=your-doubao-api-key-here
# ===========================================
# 开发配置 (可选)
# ===========================================
USE_MOCK_ANALYSIS=false # 开发调试用
NODE_ENV=development💡 获取配置值:
- Supabase: 访问 Supabase Dashboard
- 豆包 API: 访问 火山引擎控制台,开通豆包服务后创建 API Key
- 数据库设置
# 安装 Supabase CLI(如果尚未安装)
npm install -g supabase
# 推送数据库迁移
supabase db push
# 或直接执行 SQL 文件
psql -h <your-host> -U postgres -d postgres -f migrations/add_nutrition_details.sql- 验证环境变量
# 检查环境变量是否正确配置
npm run env:check- 启动开发服务器
npm run dev
# 或
pnpm dev- 访问应用
打开浏览器访问 http://localhost:3000
# 开发模式
npm run dev
# 类型检查
npm run type-check
# 构建并检查类型
npm run build:check
# 生产构建
npm run build
# 启动生产服务器
npm run start
# 代码检查
npm run lint
# 检查环境变量
npm run env:check用户拍照/上传图片
↓
图片转 Base64
↓
调用 /api/analyze 接口
↓
豆包 AI 分析(基于 FOOD_ANALYSIS_PROMPT)
↓
解析 JSON 结果
↓
数据校验和处理
↓
返回营养信息
项目使用了精心设计的提示词(lib/ai-config.ts),针对以下场景优化:
- ✅ 中式菜肴识别(考虑油、盐含量)
- ✅ 份量估算(一碗、一盘、一份等)
- ✅ 烹饪方式判断(清蒸、水煮、炒、煎、炸等)
- ✅ 营养数据准确性(基于标准营养数据库)
- ✅ 置信度评估(0-100分)
AI 返回的标准 JSON 格式:
{
"name": "番茄炒蛋",
"confidence": 95,
"description": "番茄和鸡蛋快炒,加少量油盐",
"calories": 180,
"protein": 12.5,
"carbs": 8.5,
"fats": 11.0,
"ingredients": ["番茄", "鸡蛋", "食用油", "盐", "葱"],
"nutrition": {
"sodium": 450,
"cholesterol": 320,
"vitaminC": 18,
"fiber": 2.1
}
}- 支持 0.5、1.0、1.5、2.0 等倍率调整
- 实时计算:
调整后值 = 原始值 × 倍率 - 同时更新卡路里和所有营养素
- 添加新页面
# 在 app/ 目录下创建新页面
mkdir app/new-page
touch app/new-page/page.tsx- 添加新组件
# 在 components/ 目录下创建组件
touch components/new-component.tsx- 添加新的 API 路由
# 在 app/api/ 目录下创建路由
mkdir app/api/new-endpoint
touch app/api/new-endpoint/route.ts编辑 lib/ai-config.ts 中的 FOOD_ANALYSIS_PROMPT:
export const FOOD_ANALYSIS_PROMPT = `
你的自定义提示词...
`编辑 app/globals.css 中的 CSS 变量:
:root {
--protein: #your-color;
--carbs: #your-color;
--fats: #your-color;
}-
连接 GitHub 仓库
- 访问 Vercel
- 点击 "New Project"
- 导入 SnapCal 仓库
-
配置环境变量
在 Vercel 项目设置中添加:
DOUBAO_API_KEY=your_doubao_api_key -
部署
- Vercel 会自动检测 Next.js 项目
- 点击 "Deploy" 完成部署
创建 Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]构建和运行:
docker build -t snapcal .
docker run -p 3000:3000 -e DOUBAO_API_KEY=your_key snapcal# 构建项目
pnpm build
# 启动生产服务器
pnpm start在 .env.local 中设置:
USE_MOCK_ANALYSIS=true这将使用内置的模拟数据,无需调用真实的 AI API。
- 启动开发服务器
- 访问
/scan页面 - 上传测试图片或使用相机拍照
- 查看分析结果
所有 API 路由都需要 JWT 认证(除了 /api/auth/login 和 /api/auth/register)。在请求头中包含:
Authorization: Bearer <your-jwt-token>
用户登录。
请求
// Content-Type: application/json
{
email: string
password: string
}响应
{
success: boolean
data: {
user: {
id: string
email: string
// 其他用户信息
}
session: {
access_token: string
refresh_token: string
}
}
}用户注册。
请求
// Content-Type: application/json
{
email: string
password: string
// 其他注册信息
}分析食物图片,返回营养信息。
请求
// Content-Type: multipart/form-data
FormData {
image: File // 图片文件(最大 5MB)
use_mock?: boolean // 可选:使用模拟数据
force_reanalyze?: boolean // 可选:强制重新分析
}响应
{
success: boolean
data: {
analysisId: string
data: {
name: string // 食物名称
confidence: number // 置信度 (0-100)
calories: number // 卡路里
protein: number // 蛋白质 (g)
carbs: number // 碳水化合物 (g)
fats: number // 脂肪 (g)
ingredients: string[] // 食材列表
nutrition?: { // 详细营养素(可选)
fiber?: number
sugar?: number
sodium?: number
calcium?: number
vitamin_c?: number
iron?: number
cholesterol?: number
saturated_fat?: number
trans_fat?: number
potassium?: number
vitamin_a?: number
vitamin_d?: number
vitamin_e?: number
}
image: string // Base64 图片
timestamp: string // 时间戳
analysis_duration?: number // 分析耗时 (ms)
}
file_warnings?: string[] // 文件警告信息
}
}获取用户的餐食记录。
查询参数
date: string (可选) - 指定日期,格式 YYYY-MM-DD
响应
{
success: boolean
data: {
profile: {
daily_calorie_goal: number
daily_protein_goal: number
daily_carbs_goal: number
daily_fats_goal: number
}
meals: Array<{
id: string
meal_name: string
meal_type: string
meal_date: string
meal_time: string
calories: number
protein: number
carbs: number
fats: number
// ... 详细营养素
}>
}
}创建新的餐食记录。
请求
// Content-Type: application/json
{
meal_name: string
meal_type: string // breakfast/lunch/dinner/snack
meal_date: string // YYYY-MM-DD
meal_time: string // HH:mm:ss
calories: number
protein: number
carbs: number
fats: number
image_url?: string
// 详细营养信息(可选)
fiber?: number
sugar?: number
sodium?: number
ingredients?: string[]
confidence?: number
}获取营养分析统计数据。
查询参数
timeframe: string (可选) - "本周" | "上周" | "本月",默认 "本周"
响应
{
success: boolean
data: {
timeframe: string
total_days: number
nutrition_summary: {
total_calories: number
avg_calories: number
total_protein: number
avg_protein: number
// ... 其他营养素统计
}
daily_data: Array<{
date: string
calories: number
protein: number
carbs: number
fats: number
}>
trends: {
calorie_change: number // 相比上期变化百分比
protein_change: number
// ... 其他趋势数据
}
}
}获取分析结果详情。
路径参数
id: string - 分析记录 ID
响应
{
success: boolean
data: {
id: string
user_id: string
food_name: string
confidence_score: number
// ... 完整的分析结果数据
created_at: string
analysis_status: string
}
}所有 API 返回统一的错误格式:
{
success: false
error: {
code: string // 错误代码
message: string // 错误信息
details?: any // 详细错误信息
}
}VALIDATION_ERROR- 请求参数验证失败AUTHENTICATION_ERROR- 认证失败AUTHORIZATION_ERROR- 权限不足FILE_TOO_LARGE- 文件过大UNSUPPORTED_FILE_TYPE- 不支持的文件类型AI_ANALYSIS_ERROR- AI 分析失败RATE_LIMIT_EXCEEDED- 请求频率超限
用户配置文件和目标设置
- id (uuid) - 主键
- user_id (uuid) - 关联 auth.users
- daily_calorie_goal (numeric) - 每日卡路里目标
- daily_protein_goal (numeric) - 每日蛋白质目标 (g)
- daily_carbs_goal (numeric) - 每日碳水目标 (g)
- daily_fats_goal (numeric) - 每日脂肪目标 (g)
- created_at (timestamptz) - 创建时间
- updated_at (timestamptz) - 更新时间用户餐食记录
- id (uuid) - 主键
- user_id (uuid) - 关联用户
- meal_name (text) - 食物名称
- meal_type (text) - 餐次类型
- meal_date (date) - 餐食日期
- meal_time (timestamptz) - 用餐时间
- calories (numeric) - 卡路里
- protein/carbs/fats (numeric) - 三大营养素
- fiber/sugar/sodium (numeric) - 膳食纤维、糖、钠
- calcium/vitamin_c/iron (numeric) - 钙、维C、铁
- cholesterol/saturated_fat (numeric) - 胆固醇、饱和脂肪
- ingredients (text[]) - 食材列表
- confidence (integer) - AI 置信度
- image_url (text) - 图片链接
- created_at (timestamptz) - 创建时间AI 分析结果缓存
- id (uuid) - 主键
- user_id (uuid) - 关联用户
- image_hash (text) - 图片哈希(去重用)
- raw_image_url (text) - 原始图片
- food_name (text) - 识别的食物名称
- confidence_score (integer) - 置信度分数
- calories/protein/carbohydrates/fats (numeric) - 营养信息
- analysis_duration (integer) - 分析耗时 (ms)
- model_version (text) - AI 模型版本
- analysis_status (text) - 分析状态
- created_at (timestamptz) - 创建时间登录记录日志
- id (uuid) - 主键
- user_id (uuid) - 用户ID
- email (text) - 登录邮箱
- ip_address (text) - IP地址
- user_agent (text) - 用户代理
- success (boolean) - 是否成功
- failure_reason (text) - 失败原因
- created_at (timestamptz) - 登录时间为优化查询性能,已添加以下索引:
-- user_meals 表索引
CREATE INDEX idx_user_meals_user_date ON user_meals(user_id, meal_date DESC);
CREATE INDEX idx_user_meals_date ON user_meals(meal_date DESC);
-- meal_analysis_results 表索引
CREATE INDEX idx_analysis_results_user_hash ON meal_analysis_results(user_id, image_hash);
CREATE INDEX idx_analysis_results_created ON meal_analysis_results(created_at DESC);
-- auth_login_records 表索引
CREATE INDEX idx_login_records_user ON auth_login_records(user_id, created_at DESC);
CREATE INDEX idx_login_records_email ON auth_login_records(email, created_at DESC);A:
- 确保图片清晰,光线充足
- 食物占图片主体位置
- 尝试重新拍摄或上传
- 检查豆包 API Key 是否有效
- 使用
USE_MOCK_ANALYSIS=true测试功能
A:
- AI 识别基于图片估算,可能存在误差
- 可通过份量调整功能手动校准(0.5x-3.0x)
- 建议结合实际情况调整
- 查看置信度分数,低置信度结果需谨慎参考
A:
- 运行
npm run env:check检查配置 - 确保所有必需变量都已设置
- 检查 Supabase URL 和 Key 的格式
- 验证豆包 API Key 权限
A:
- 检查 Supabase 项目是否运行正常
- 验证数据库迁移是否完成:
supabase db push - 确认 RLS (Row Level Security) 策略配置
- 检查网络连接和防火墙设置
A:
- 运行
npm run type-check检查类型错误 - 确保所有依赖已正确安装:
npm install - 检查环境变量是否完整:
npm run env:check - 使用
npm run build:check进行完整检查
A:
- 检查 Vercel 环境变量配置
- 查看 Vercel 函数日志排查错误
- 确认 API Key 权限和配额
- 检查 Supabase 域名是否已添加到 images.domains
我们欢迎所有形式的贡献!
- Fork 项目
- 创建特性分支
git checkout -b feature/AmazingFeature- 提交更改
git commit -m 'Add some AmazingFeature'- 推送到分支
git push origin feature/AmazingFeature- 开启 Pull Request
- 🐛 修复 Bug
- ✨ 添加新功能
- 📝 改进文档
- 🎨 UI/UX 优化
- ⚡ 性能优化
- 🌐 多语言支持
本项目采用 MIT 许可证。详情请查看 LICENSE 文件。
- Next.js - React 全栈框架
- shadcn/ui - 优秀组件库
- Tailwind CSS - 实用优先的 CSS 框架
- 豆包 AI - AI 能力支持
- Recharts - 图表库
- Lucide - 图标库
- 功能:每日营养概览和饮食记录
- 特性:
- 剩余卡路里显示(带动画效果)
- 三大营养素进度环(蛋白质、碳水化合物、脂肪)
- 按餐次分组的食物记录(早餐、午餐、晚餐)
- 周日期选择器
- 成就系统入口
- 功能:食物拍照和上传
- 特性:
- 相机实时预览
- 图片上传支持
- 拍照/上传切换
- 图片裁剪和预览
- AI 分析进度提示
- 功能:展示食物营养分析结果
- 特性:
- 食物名称和置信度显示
- 份量调整滑块(0.5x - 3.0x)
- 卡路里和三大营养素环形图
- 详细营养素列表(可展开/收起)
- 食材列表展示
- 保存到饮食记录
- 功能:营养摄入趋势统计
- 特性:
- 时间范围选择(本周/上周/本月)
- 卡路里趋势图表(柱状图)
- 营养素趋势图表(折线图)
- 平均摄入量统计
- 趋势对比(上升/下降百分比)
- 营养素分布饼图
- 功能:用户设置和个人信息
- 特性:
- 用户信息展示
- 连续打卡天数
- 成就系统
- 设置菜单(通知、隐私、应用设置)
- 分享功能
// 1. 打开扫描页面
navigate('/scan')
// 2. 选择拍照或上传
const image = await capturePhoto() // 或选择文件
// 3. 上传到 API
const response = await fetch('/api/analyze', {
method: 'POST',
body: formData
})
// 4. 获取分析结果
const { data } = await response.json()
// {
// name: "番茄炒蛋",
// calories: 180,
// protein: 12.5,
// ...
// }// 在分析页面调整份量
const multiplier = 1.5 // 1.5倍
const adjustedCalories = originalCalories * multiplier
const adjustedProtein = originalProtein * multiplier
const adjustedCarbs = originalCarbs * multiplier
const adjustedFats = originalFats * multiplier// 获取本周数据
const weeklyData = {
days: ['周一', '周二', ...],
calories: [1800, 2100, ...],
protein: [85, 95, ...],
// ...
}项目支持完整的主题定制,包括浅色和深色模式。
编辑 app/globals.css 修改主题颜色:
:root {
/* 营养素颜色 */
--protein: oklch(0.62 0.12 180); /* 蛋白质 - 青绿色 */
--carbs: oklch(0.7 0.18 50); /* 碳水化合物 - 橙色 */
--fats: oklch(0.6 0.2 240); /* 脂肪 - 蓝色 */
--success: oklch(0.65 0.18 140); /* 成功 - 绿色 */
/* 主题颜色 */
--background: oklch(1 0 0);
--foreground: oklch(0.15 0.01 240);
/* ... */
}项目已集成 next-themes,可以在任何组件中使用:
import { useTheme } from 'next-themes'
function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
切换主题
</button>
)
}-
图片优化
- Base64 编码压缩
- 自动裁剪和缩放
- 延迟加载(Lazy Loading)
-
代码分割
- Next.js 自动代码分割
- 动态导入(Dynamic Imports)
- 路由级别的代码分割
-
缓存策略
- API 响应缓存
- 静态资源缓存
- 浏览器缓存优化
-
渲染优化
- React 19 并发特性
- 虚拟滚动(如需要)
- 防抖和节流
- 添加 Service Worker 支持 PWA
- 实现图片 CDN 加速
- 添加数据库持久化
- 实现离线支持
- 添加数据预加载
- ✅ 使用环境变量存储敏感信息
- ✅
.env.local已添加到.gitignore - ✅ 不要在客户端代码中暴露 API Key
⚠️ 当前使用sessionStorage存储数据(临时)- 💡 建议:实现后端数据库存储
- 💡 建议:添加用户认证和授权
- 💡 建议:实现数据加密
- ✅ 客户端 Base64 编码
- ✅ 服务器端验证
⚠️ 建议:添加图片大小限制⚠️ 建议:添加文件类型验证
-
认证与授权
- ✅ JWT 令牌认证机制
- ✅ 自动令牌刷新
- ✅ 会话管理和超时处理
- ✅ Row Level Security (RLS) 策略
-
API 安全
- ✅ 请求速率限制 (100次/15分钟)
- ✅ 文件大小限制 (5MB)
- ✅ 文件类型验证
- ✅ 文件内容安全检查
- ✅ 统一错误处理
-
安全头部配置
- ✅ Content Security Policy (CSP)
- ✅ X-Content-Type-Options: nosniff
- ✅ X-Frame-Options: DENY
- ✅ X-XSS-Protection
- ✅ Strict-Transport-Security
-
数据保护
- ✅ 环境变量加密存储
- ✅ 敏感信息不暴露给客户端
- ✅ API 密钥安全配置
- ✅ 数据库连接加密
-
TypeScript 严格模式
- ✅ 构建时类型检查 (
ignoreBuildErrors: false) - ✅ 运行时数据验证 (Zod schemas)
- ✅ API 参数验证
- ✅ 构建时类型检查 (
-
图片处理安全
- ✅ 文件元数据清理
- ✅ 恶意内容检测
- ✅ 安全文件名生成
- ✅ Base64 编码验证
- 🔒 定期轮换 API 密钥
- 🔒 监控异常登录活动
- 🔒 使用强密码策略
- 🔒 定期备份重要数据
- 🔒 遵循最小权限原则
-
数据持久化
- ✅ 已解决:集成 Supabase 数据库
- 所有数据现在都持久化存储
-
用户系统
- ✅ 已解决:完整的用户认证系统
- 支持注册、登录、会话管理
-
AI 准确性
⚠️ AI 识别基于图片估算,可能存在误差- ✅ 已添加置信度分数和份量调整功能
- 💡 建议:用户可以手动调整数据
-
离线支持
- ❌ 仍需要网络连接才能使用 AI 分析
- 💡 计划:添加 PWA 支持和离线模式
- 用户认证系统
- 数据库持久化
- 多设备数据同步
- 导出数据功能(CSV/PDF)
- PWA 支持
- 离线模式
- 推送通知
- 社交分享功能
- 食物数据库扩展
- 自定义食物添加
- 饮食计划推荐
- 营养师咨询功能
- 多语言支持(英文、日文等)
- 健康数据集成(Apple Health、Google Fit)
- AI 营养建议
- 社区功能(分享食谱、打卡等)
我们欢迎所有形式的贡献!
- Fork 项目
- 创建特性分支
git checkout -b feature/AmazingFeature- 提交更改
git commit -m 'Add some AmazingFeature'- 推送到分支
git push origin feature/AmazingFeature- 开启 Pull Request
- 🐛 修复 Bug:发现并修复代码中的问题
- ✨ 添加新功能:实现新特性或改进现有功能
- 📝 改进文档:完善 README、代码注释等
- 🎨 UI/UX 优化:改进界面设计和用户体验
- ⚡ 性能优化:提升应用性能
- 🌐 多语言支持:添加新的语言支持
- 🧪 测试:添加单元测试和集成测试
- 使用 TypeScript 编写代码
- 遵循 ESLint 规则
- 保持代码格式一致(Prettier)
- 添加必要的注释
- 编写清晰的提交信息
- 项目主页: https://github.com/your-username/SnapCal
- 问题反馈: Issues
- 功能建议: Discussions
- Pull Request: Pull Requests
如果这个项目对你有帮助,欢迎 Star ⭐ 支持!
- ✨ 初始版本发布
- ✨ AI 食物识别功能
- ✨ 营养分析展示
- ✨ 趋势统计图表
- ✨ 移动端优化 UI
感谢以下项目和社区的支持:
- Next.js - React 全栈框架
- shadcn/ui - 优秀组件库
- Tailwind CSS - 实用优先的 CSS 框架
- 豆包 AI - AI 能力支持
- Recharts - 图表库
- Lucide - 图标库
- 所有贡献者和用户
本项目采用 MIT 许可证。详情请查看 LICENSE 文件。