Files
yu-zhi-ran/platform/backend/app/api/search_providers.py
T
Yuzhiran Dev f6e5e90736 feat: Wave 3 - Dashboard redesign + RBAC + AI assistant updates
- Redesign index.html from system-monitor to user-centric workspace
  (welcome banner, summary cards, 今日待办, AI 智能建议, collapsible admin section)
- Add fetchTodos/fetchSuggestions/getPriorityClass/isOverdue methods
- Update uni-nav current-page from 'dashboard' to 'workspace'
- Add require_role to 10 admin router imports (RBAC foundation)
- Update ai-assistant.js: add factory/insights pages, org_id in chat requests
2026-06-17 18:24:57 +08:00

132 lines
5.4 KiB
Python

import logging
import sys
import json
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime, timezone
from ..database import get_db
from ..models import SearchProvider
from .auth import get_current_admin, require_role
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/search-providers", tags=["search_providers"])
@router.get("")
def list_providers(db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
providers = db.query(SearchProvider).order_by(SearchProvider.priority).all()
return [p.to_dict() for p in providers]
@router.post("")
def create_provider(data: dict, db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
p = SearchProvider(
name=data.get("name", ""),
provider_type=data.get("provider_type", ""),
api_key=data.get("api_key", ""),
api_url=data.get("api_url", ""),
console_url=data.get("console_url", ""),
priority=data.get("priority", 99),
enabled=data.get("enabled", True),
daily_limit=data.get("daily_limit", 1500),
extra_config=data.get("extra_config", {}),
)
db.add(p)
db.commit()
db.refresh(p)
return p.to_dict()
@router.put("/{provider_id}")
def update_provider(provider_id: int, data: dict, db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
p = db.query(SearchProvider).filter(SearchProvider.id == provider_id).first()
if not p:
raise HTTPException(status_code=404, detail="Provider not found")
for key in ("name", "provider_type", "api_key", "api_url", "console_url", "priority", "enabled", "daily_limit"):
if key in data:
setattr(p, key, data[key])
if "extra_config" in data:
p.extra_config = data["extra_config"]
p.updated_at = datetime.now(timezone.utc)
db.commit()
db.refresh(p)
return p.to_dict()
@router.delete("/{provider_id}")
def delete_provider(provider_id: int, db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
p = db.query(SearchProvider).filter(SearchProvider.id == provider_id).first()
if not p:
raise HTTPException(status_code=404, detail="Provider not found")
db.delete(p)
db.commit()
return {"ok": True}
@router.post("/{provider_id}/test")
def test_provider(provider_id: int, data: dict = {}, db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
p = db.query(SearchProvider).filter(SearchProvider.id == provider_id).first()
if not p:
raise HTTPException(status_code=404, detail="Provider not found")
query = data.get("query", "测试搜索")
try:
test_key = data.get("api_key") or p.api_key
test_url = data.get("api_url") or p.api_url
if p.provider_type == "baidu":
import requests
resp = requests.post(
test_url,
headers={"Authorization": f"Bearer {test_key}", "Content-Type": "application/json"},
json={"messages": [{"role": "user", "content": query}], "search_source": "baidu_search_v2", "resource_type_filter": [{"type": "web", "top_k": 3}]},
timeout=15
)
if resp.status_code != 200:
return {"ok": False, "error": f"HTTP {resp.status_code}: {resp.text[:200]}"}
return {"ok": True, "results": resp.json().get("results", [])[:3]}
elif p.provider_type == "qiniu":
import requests
resp = requests.post(
test_url,
headers={"Authorization": f"Bearer {test_key}", "Content-Type": "application/json"},
json={"query": query, "max_results": 3, "search_type": "web"},
timeout=15
)
if resp.status_code != 200:
return {"ok": False, "error": f"HTTP {resp.status_code}: {resp.text[:200]}"}
return {"ok": True, "results": resp.json().get("results", resp.json().get("data", []))[:3]}
elif p.provider_type == "tinyfish":
import requests
resp = requests.get(
test_url,
params={"query": query, "max_results": 3},
headers={"X-API-Key": test_key},
timeout=15
)
if resp.status_code != 200:
return {"ok": False, "error": f"HTTP {resp.status_code}: {resp.text[:200]}"}
return {"ok": True, "results": resp.json().get("results", resp.json().get("data", []))[:3]}
elif p.provider_type == "bing":
import requests
resp = requests.get(
test_url,
params={"q": query, "count": 3, "mkt": "zh-CN"},
headers={"Ocp-Apim-Subscription-Key": test_key},
timeout=15
)
if resp.status_code != 200:
return {"ok": False, "error": f"HTTP {resp.status_code}: {resp.text[:200]}"}
return {"ok": True, "results": resp.json().get("webPages", {}).get("value", [])[:3]}
return {"ok": False, "error": f"Unknown provider_type: {p.provider_type}"}
except Exception as e:
return {"ok": False, "error": str(e)}
@router.post("/reset-usage")
def reset_usage(db: Session = Depends(get_db), current_user=Depends(get_current_admin)):
db.query(SearchProvider).update({SearchProvider.usage_today: 0})
db.commit()
return {"ok": True}