mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-05 08:55:28 +08:00
184 lines
6.4 KiB
Python
184 lines
6.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""Admin 配置管理模块 - 配置、API Keys、账号管理"""
|
||
import os
|
||
|
||
from fastapi import APIRouter, HTTPException, Request, Depends
|
||
from fastapi.responses import JSONResponse
|
||
|
||
from core.config import CONFIG, save_config, logger
|
||
from core.auth import init_account_queue, get_queue_status, get_account_identifier
|
||
from core.deepseek import login_deepseek_via_account
|
||
|
||
from .auth import verify_admin
|
||
|
||
router = APIRouter()
|
||
|
||
# Vercel 预配置
|
||
VERCEL_TOKEN = os.getenv("VERCEL_TOKEN", "")
|
||
VERCEL_PROJECT_ID = os.getenv("VERCEL_PROJECT_ID", "")
|
||
VERCEL_TEAM_ID = os.getenv("VERCEL_TEAM_ID", "")
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# Vercel 预配置信息
|
||
# ----------------------------------------------------------------------
|
||
@router.get("/vercel/config")
|
||
async def get_vercel_config(_: bool = Depends(verify_admin)):
|
||
"""获取预配置的 Vercel 信息(脱敏)"""
|
||
return JSONResponse(content={
|
||
"has_token": bool(VERCEL_TOKEN),
|
||
"project_id": VERCEL_PROJECT_ID,
|
||
"team_id": VERCEL_TEAM_ID or None,
|
||
})
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 配置管理
|
||
# ----------------------------------------------------------------------
|
||
@router.get("/config")
|
||
async def get_config(_: bool = Depends(verify_admin)):
|
||
"""获取当前配置(密码脱敏)"""
|
||
safe_config = {
|
||
"keys": CONFIG.get("keys", []),
|
||
"accounts": [],
|
||
"claude_mapping": CONFIG.get("claude_mapping", {}),
|
||
}
|
||
|
||
for acc in CONFIG.get("accounts", []):
|
||
safe_acc = {
|
||
"email": acc.get("email", ""),
|
||
"mobile": acc.get("mobile", ""),
|
||
"has_password": bool(acc.get("password")),
|
||
"has_token": bool(acc.get("token")),
|
||
"token_preview": acc.get("token", "")[:20] + "..." if acc.get("token") else "",
|
||
}
|
||
safe_config["accounts"].append(safe_acc)
|
||
|
||
return JSONResponse(content=safe_config)
|
||
|
||
|
||
@router.post("/config")
|
||
async def update_config(request: Request, _: bool = Depends(verify_admin)):
|
||
"""更新完整配置"""
|
||
data = await request.json()
|
||
|
||
if "keys" in data:
|
||
CONFIG["keys"] = data["keys"]
|
||
|
||
if "accounts" in data:
|
||
# 保留原有密码和 token
|
||
existing = {get_account_identifier(a): a for a in CONFIG.get("accounts", [])}
|
||
for acc in data["accounts"]:
|
||
acc_id = get_account_identifier(acc)
|
||
if acc_id in existing:
|
||
if not acc.get("password"):
|
||
acc["password"] = existing[acc_id].get("password", "")
|
||
if not acc.get("token"):
|
||
acc["token"] = existing[acc_id].get("token", "")
|
||
CONFIG["accounts"] = data["accounts"]
|
||
init_account_queue()
|
||
|
||
if "claude_mapping" in data:
|
||
CONFIG["claude_mapping"] = data["claude_mapping"]
|
||
|
||
save_config(CONFIG)
|
||
return JSONResponse(content={"success": True, "message": "配置已更新"})
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# API Keys 管理
|
||
# ----------------------------------------------------------------------
|
||
@router.post("/keys")
|
||
async def add_key(request: Request, _: bool = Depends(verify_admin)):
|
||
"""添加 API Key"""
|
||
data = await request.json()
|
||
key = data.get("key", "").strip()
|
||
|
||
if not key:
|
||
raise HTTPException(status_code=400, detail="Key 不能为空")
|
||
|
||
if key in CONFIG.get("keys", []):
|
||
raise HTTPException(status_code=400, detail="Key 已存在")
|
||
|
||
if "keys" not in CONFIG:
|
||
CONFIG["keys"] = []
|
||
CONFIG["keys"].append(key)
|
||
save_config(CONFIG)
|
||
|
||
return JSONResponse(content={"success": True, "total_keys": len(CONFIG["keys"])})
|
||
|
||
|
||
@router.delete("/keys/{key}")
|
||
async def delete_key(key: str, _: bool = Depends(verify_admin)):
|
||
"""删除 API Key"""
|
||
if key not in CONFIG.get("keys", []):
|
||
raise HTTPException(status_code=404, detail="Key 不存在")
|
||
|
||
CONFIG["keys"].remove(key)
|
||
save_config(CONFIG)
|
||
return JSONResponse(content={"success": True, "total_keys": len(CONFIG["keys"])})
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 账号管理
|
||
# ----------------------------------------------------------------------
|
||
@router.post("/accounts")
|
||
async def add_account(request: Request, _: bool = Depends(verify_admin)):
|
||
"""添加账号"""
|
||
data = await request.json()
|
||
email = data.get("email", "").strip()
|
||
mobile = data.get("mobile", "").strip()
|
||
password = data.get("password", "").strip()
|
||
token = data.get("token", "").strip()
|
||
|
||
if not email and not mobile:
|
||
raise HTTPException(status_code=400, detail="需要 email 或 mobile")
|
||
|
||
# 检查是否已存在
|
||
for acc in CONFIG.get("accounts", []):
|
||
if email and acc.get("email") == email:
|
||
raise HTTPException(status_code=400, detail="邮箱已存在")
|
||
if mobile and acc.get("mobile") == mobile:
|
||
raise HTTPException(status_code=400, detail="手机号已存在")
|
||
|
||
new_account = {}
|
||
if email:
|
||
new_account["email"] = email
|
||
if mobile:
|
||
new_account["mobile"] = mobile
|
||
if password:
|
||
new_account["password"] = password
|
||
if token:
|
||
new_account["token"] = token
|
||
|
||
if "accounts" not in CONFIG:
|
||
CONFIG["accounts"] = []
|
||
CONFIG["accounts"].append(new_account)
|
||
init_account_queue()
|
||
save_config(CONFIG)
|
||
|
||
return JSONResponse(content={"success": True, "total_accounts": len(CONFIG["accounts"])})
|
||
|
||
|
||
@router.delete("/accounts/{identifier}")
|
||
async def delete_account(identifier: str, _: bool = Depends(verify_admin)):
|
||
"""删除账号(通过 email 或 mobile)"""
|
||
accounts = CONFIG.get("accounts", [])
|
||
for i, acc in enumerate(accounts):
|
||
if acc.get("email") == identifier or acc.get("mobile") == identifier:
|
||
accounts.pop(i)
|
||
init_account_queue()
|
||
save_config(CONFIG)
|
||
return JSONResponse(content={"success": True, "total_accounts": len(accounts)})
|
||
|
||
raise HTTPException(status_code=404, detail="账号不存在")
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 账号队列状态
|
||
# ----------------------------------------------------------------------
|
||
@router.get("/queue/status")
|
||
async def get_account_queue_status(_: bool = Depends(verify_admin)):
|
||
"""获取账号轮询队列状态"""
|
||
return JSONResponse(content=get_queue_status())
|