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

@@ -25,7 +25,7 @@ def _json_default(value):
raise TypeError(f"Object of type {type(value).__name__} is not JSON serializable")
def export_all_data_json(output_path: Path) -> None:
def export_all_data_json(output_path: Path, user_id: int = 1) -> None:
"""导出所有数据为 JSON"""
data = {
"version": "1.0",
@@ -34,7 +34,7 @@ def export_all_data_json(output_path: Path) -> None:
"meals": [m.to_dict() for m in db.get_meals()],
"sleep": [s.to_dict() for s in db.get_sleep_records()],
"weight": [w.to_dict() for w in db.get_weight_records()],
"config": db.get_config().to_dict(),
"config": db.get_config(user_id).to_dict(),
}
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(json.dumps(data, ensure_ascii=False, indent=2, default=_json_default), encoding="utf-8")
@@ -117,7 +117,7 @@ def export_to_csv(
writer.writerow(row)
def import_from_json(input_path: Path) -> dict[str, int]:
def import_from_json(input_path: Path, user_id: int = 1) -> dict[str, int]:
"""从 JSON 导入数据(最小实现:覆盖性导入,不做去重)"""
data = json.loads(input_path.read_text(encoding="utf-8"))
@@ -128,6 +128,7 @@ def import_from_json(input_path: Path) -> dict[str, int]:
if isinstance(config, dict):
# 仅持久化可写字段
db.save_config(
user_id,
UserConfig(
age=config.get("age"),
gender=config.get("gender"),