feat: expose acceptance Link AI aggregate data
This commit is contained in:
@@ -22,6 +22,7 @@ from crawler_client import (
|
||||
collect_keyword_sources,
|
||||
fetch_content_detail,
|
||||
get_wen_resources,
|
||||
match_feishu_notes,
|
||||
query_collection,
|
||||
schedule_xapi_screenshots,
|
||||
)
|
||||
@@ -965,3 +966,61 @@ def list_acceptance_notes(public_id: str) -> dict[str, Any]:
|
||||
item["parsed_data"] = json.loads(item.pop("raw_json")) if item.get("raw_json") else None
|
||||
items.append(item)
|
||||
return {"items": items, "total": len(items)}
|
||||
|
||||
|
||||
def get_acceptance_link_ai_data(public_id: str) -> dict[str, Any]:
|
||||
"""返回 Link AI 所需的笔记、AI 采集结果和逐关键词比对结果。"""
|
||||
with connection() as conn:
|
||||
task = conn.execute(
|
||||
"SELECT * FROM acceptance_tasks WHERE public_task_id=?", (public_id,),
|
||||
).fetchone()
|
||||
if not task:
|
||||
raise TaskError("ACCEPTANCE_TASK_NOT_FOUND", "验收任务不存在", 404)
|
||||
task_data = _task_dict(conn, task)
|
||||
rows = conn.execute(
|
||||
"""SELECT a.keyword,a.credential_id,a.attempt_number,a.crawler_task_id,
|
||||
a.result_json,a.completed_at
|
||||
FROM acceptance_cookie_attempts a
|
||||
WHERE a.task_id=? AND a.status='completed' AND a.result_json IS NOT NULL
|
||||
ORDER BY a.keyword,a.id""",
|
||||
(task["id"],),
|
||||
).fetchall()
|
||||
|
||||
ai_results = []
|
||||
for row in rows:
|
||||
try:
|
||||
result = json.loads(row["result_json"])
|
||||
except (TypeError, json.JSONDecodeError):
|
||||
continue
|
||||
ai_results.append({
|
||||
"keyword": row["keyword"],
|
||||
"credential_id": row["credential_id"],
|
||||
"attempt_number": row["attempt_number"],
|
||||
"crawler_task_id": row["crawler_task_id"],
|
||||
"completed_at": row["completed_at"],
|
||||
"result": result,
|
||||
})
|
||||
|
||||
comparisons = []
|
||||
for keyword in task_data["keywords"]:
|
||||
try:
|
||||
comparisons.append({
|
||||
"keyword": keyword,
|
||||
"status": "completed",
|
||||
"data": match_feishu_notes(keyword),
|
||||
})
|
||||
except Exception as exc:
|
||||
comparisons.append({
|
||||
"keyword": keyword,
|
||||
"status": "failed",
|
||||
"error": str(exc),
|
||||
"data": None,
|
||||
})
|
||||
|
||||
return {
|
||||
"task": task_data,
|
||||
"notes": list_acceptance_notes(public_id),
|
||||
"ai_results": {"items": ai_results, "total": len(ai_results)},
|
||||
"note_matches": {"items": comparisons, "total": len(comparisons)},
|
||||
"data_scope": "仅包含当前已完成并已入库的数据",
|
||||
}
|
||||
|
||||
8
app.py
8
app.py
@@ -18,6 +18,7 @@ from database import init_database
|
||||
from acceptance_service import (
|
||||
create_acceptance_task,
|
||||
get_acceptance_resources,
|
||||
get_acceptance_link_ai_data,
|
||||
get_acceptance_task,
|
||||
list_acceptance_notes,
|
||||
list_acceptance_tasks,
|
||||
@@ -286,6 +287,13 @@ def create_app() -> Flask:
|
||||
def get_project_acceptance_notes(task_id: str):
|
||||
return jsonify({"data": list_acceptance_notes(task_id), "request_id": g.request_id})
|
||||
|
||||
@app.route("/api/v1/acceptance-tasks/<task_id>/link-ai-data", methods=["GET"])
|
||||
def get_project_acceptance_link_ai_data(task_id: str):
|
||||
return jsonify({
|
||||
"data": get_acceptance_link_ai_data(task_id),
|
||||
"request_id": g.request_id,
|
||||
})
|
||||
|
||||
@app.route("/api/v1/acceptance-tasks/<task_id>/resume", methods=["POST"])
|
||||
def resume_project_acceptance_task(task_id: str):
|
||||
return jsonify({"data": resume_acceptance_task(task_id), "request_id": g.request_id})
|
||||
|
||||
@@ -338,6 +338,15 @@ def collect_keyword_sources(keyword: str, credential_id: str | None = None) -> d
|
||||
)
|
||||
|
||||
|
||||
def match_feishu_notes(keyword: str, task_limit: int = 100) -> dict[str, Any]:
|
||||
"""调用爬虫服务,比对飞书笔记和问一问采集来源。"""
|
||||
return _post(
|
||||
"/api/v1/xhs/feishu-notes/matches",
|
||||
{"keyword": keyword, "task_limit": task_limit},
|
||||
retry_transient=True,
|
||||
)
|
||||
|
||||
|
||||
def resume_collection(crawler_task_id: str) -> dict[str, Any]:
|
||||
"""沿用原爬虫任务 ID,从 framework 保存的检查点继续采集。"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user