nianjie/backend/qa.py

73 lines
1.8 KiB
Python

import json
import random
from functools import lru_cache
from typing import List, Dict, Any, Optional
from .config import QA_PATH, TOP_QUESTION_IDS
@lru_cache(maxsize=1)
def load_qa_data() -> List[Dict[str, Any]]:
try:
return json.loads(QA_PATH.read_text(encoding="utf-8"))
except Exception:
return []
def get_question_by_id(qid: int) -> Optional[Dict[str, Any]]:
for item in load_qa_data():
if item.get("id") == qid:
return item
return None
def get_questions_by_ids(ids: List[int]) -> List[Dict[str, Any]]:
items = []
for qid in ids:
item = get_question_by_id(qid)
if item:
items.append(item)
return items
def random_questions(limit: int = 10) -> List[Dict[str, Any]]:
data = load_qa_data()
if not data:
return []
if limit >= len(data):
return data.copy()
return random.sample(data, limit)
def search_questions(query: str, limit: int = 10) -> List[Dict[str, Any]]:
"""
简易检索:包含关键词的优先返回,不足则随机补齐。
"""
data = load_qa_data()
if not query:
return random_questions(limit)
q_lower = query.lower()
matched = [item for item in data if q_lower in item.get("question", "").lower()]
# 去重 + 截断
seen = set()
results = []
for item in matched:
if item["id"] in seen:
continue
results.append(item)
seen.add(item["id"])
if len(results) >= limit:
break
# 不足部分随机补齐
if len(results) < limit:
remaining = [x for x in data if x["id"] not in seen]
random.shuffle(remaining)
results.extend(remaining[: limit - len(results)])
return results[:limit]
def top_questions():
return get_questions_by_ids(TOP_QUESTION_IDS)