73 lines
1.8 KiB
Python
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)
|