feat: 用户配置隔离与食物智能识别

1. Config 表用户隔离
   - 添加 user_id 字段,复合主键 (user_id, key)
   - 现有数据归属 ID=1 用户
   - 所有 get_config/save_config 调用传入 user_id

2. 食物文字智能识别
   - 本地数据库优先匹配(快速)
   - 识别失败时自动调用通义千问 AI(准确)
   - 有配置 API Key 才调用,否则返回本地结果

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 11:32:17 +08:00
parent afc6d2fb5e
commit 0f11e8ad56
7 changed files with 215 additions and 29 deletions

View File

@@ -20,6 +20,7 @@ from ..core.auth import hash_password, verify_password, create_token, decode_tok
# 初始化数据库
db.init_db()
db.migrate_auth_fields() # 迁移认证字段
db.migrate_config_add_user_id() # 迁移 config 表添加 user_id
app = FastAPI(
@@ -887,7 +888,9 @@ async def settings_page():
@app.get("/api/config", response_model=ConfigResponse)
async def get_config():
"""获取用户配置"""
config = db.get_config()
active_user = db.get_active_user()
user_id = active_user.id if active_user else 1
config = db.get_config(user_id)
return ConfigResponse(
age=config.age,
gender=config.gender,
@@ -909,7 +912,7 @@ async def get_today_summary():
raise HTTPException(status_code=400, detail="没有激活的用户")
today = date.today()
config = db.get_config()
config = db.get_config(active_user.id)
# 获取今日数据
exercises = db.get_exercises(start_date=today, end_date=today, user_id=active_user.id)
@@ -1187,7 +1190,7 @@ async def add_exercise_api(data: ExerciseInput):
raise HTTPException(status_code=400, detail="日期格式应为 YYYY-MM-DD") from exc
from ..core.calories import estimate_exercise_calories
config = db.get_config()
config = db.get_config(active_user.id)
weight_kg = config.weight or 70
calories = data.calories if data.calories is not None else estimate_exercise_calories(
data.type, data.duration, weight_kg
@@ -1579,7 +1582,9 @@ async def get_weight_records(
@app.get("/api/weight/goal")
async def get_weight_goal():
"""获取目标体重(基于用户配置推断)"""
config = db.get_config()
active_user = db.get_active_user()
user_id = active_user.id if active_user else 1
config = db.get_config(user_id)
if not config.weight:
return {"goal_weight": None}