feat: API Keys 支持数据库存储和 Web 界面管理

- database.py: 新增 get_api_key/set_api_key/delete_api_key/get_all_api_keys 函数
- qwen.py/deepseek.py/analyzer.py: 改用 db.get_api_key() 读取配置
- app.py: 新增管理员 API 接口 (/api/admin/api-keys)
- settings 页面: 管理员可见的 API 密钥配置区域

API Key 优先级: 数据库 > 环境变量

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 22:32:17 +08:00
parent dba052bb5e
commit eb88d2638f
5 changed files with 304 additions and 6 deletions

View File

@@ -31,8 +31,8 @@ class ClaudeFoodAnalyzer(FoodAnalyzer):
"""使用 Claude Vision API 的食物分析器"""
def __init__(self, api_key: Optional[str] = None):
import os
self.api_key = api_key or os.environ.get("ANTHROPIC_API_KEY")
from ..core import database as db
self.api_key = api_key or db.get_api_key("anthropic")
def analyze(self, image_path: Path) -> dict:
"""使用 Claude Vision 分析食物图片"""

View File

@@ -1,20 +1,20 @@
"""DeepSeek Vision API 适配器"""
import base64
import os
from pathlib import Path
from typing import Optional
import httpx
from ...core.calories import estimate_meal_calories
from ...core import database as db
class DeepSeekVisionAnalyzer:
"""DeepSeek Vision 食物识别分析器"""
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.environ.get("DEEPSEEK_API_KEY")
self.api_key = api_key or db.get_api_key("deepseek")
self.base_url = "https://api.deepseek.com/v1"
def analyze_image(self, image_path: Path) -> dict:

View File

@@ -1,20 +1,20 @@
"""Qwen VL (通义千问视觉) API 适配器"""
import base64
import os
from pathlib import Path
from typing import Optional
import httpx
from ...core.calories import estimate_meal_calories
from ...core import database as db
class QwenVisionAnalyzer:
"""Qwen VL 食物识别分析器"""
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.environ.get("DASHSCOPE_API_KEY")
self.api_key = api_key or db.get_api_key("dashscope")
# 阿里云百炼 OpenAI 兼容接口
self.base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"