AI 配置改为按用户独立存储

每个用户 AI 配置存 data/user_data/ai_settings/{username}.json,
读配置时用户级优先,无则回退到全局 secrets.json。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-06 14:10:32 +08:00
parent 9ecfc2bb71
commit c08e7f2c54
2 changed files with 86 additions and 20 deletions
+50
View File
@@ -94,3 +94,53 @@ def mask(key: str, prefix: int = 4, suffix: int = 4) -> str:
if len(key) <= prefix + suffix:
return "" * len(key)
return f"{key[:prefix]}{'' * 6}{key[-suffix:]}"
# ================================================================
# 按用户 AI 配置 (data/user_data/ai_settings/{username}.json)
# ================================================================
def _ai_config_path(username: str) -> Path:
from app.config import settings
p = settings.data_dir / "user_data" / "ai_settings" / f"{username}.json"
p.parent.mkdir(parents=True, exist_ok=True)
return p
def load_ai_config(username: str) -> dict:
"""加载指定用户的 AI 配置。用户不存在时返回空 dict。"""
p = _ai_config_path(username)
if p.exists():
try:
return json.loads(p.read_text(encoding="utf-8"))
except Exception as e: # noqa: BLE001
logger.warning("ai_settings/%s.json malformed: %s", username, e)
return {}
def save_ai_config(username: str, updates: dict) -> dict:
"""合并写入指定用户的 AI 配置。返回新内容。"""
current = load_ai_config(username)
current.update({k: v for k, v in updates.items() if v is not None})
p = _ai_config_path(username)
p.write_text(json.dumps(current, indent=2, ensure_ascii=False), encoding="utf-8")
try:
os.chmod(p, 0o600)
except OSError:
pass
return current
def clear_ai_config(username: str, *keys: str) -> dict:
"""清掉指定用户的 AI 配置字段。不传 keys 则删除整个文件。"""
p = _ai_config_path(username)
if not p.exists():
return {}
if not keys:
p.unlink()
return {}
current = load_ai_config(username)
for k in keys:
current.pop(k, None)
p.write_text(json.dumps(current, indent=2, ensure_ascii=False), encoding="utf-8")
return current