feat: add compare, trends routes, embedder service, and phase5 tests
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
"""论文对比页路由 — 多篇论文结构化字段并排对比。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from app.database import get_db
|
||||
from app.models import Paper
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
|
||||
@router.get("/compare")
|
||||
def compare_page(
|
||||
request: Request,
|
||||
ids: str = Query(default="", description="逗号分隔的 arxiv_id,最多 5 篇"),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""论文对比页面。GET /compare?ids=id1,id2,id3"""
|
||||
if not ids:
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"compare.html",
|
||||
{
|
||||
"page_title": "论文对比",
|
||||
"papers": [],
|
||||
"error": None,
|
||||
},
|
||||
)
|
||||
|
||||
arxiv_ids = [i.strip() for i in ids.split(",") if i.strip()]
|
||||
|
||||
# 最多 5 篇
|
||||
if len(arxiv_ids) > 5:
|
||||
arxiv_ids = arxiv_ids[:5]
|
||||
|
||||
if not arxiv_ids:
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"compare.html",
|
||||
{
|
||||
"page_title": "论文对比",
|
||||
"papers": [],
|
||||
"error": "请提供有效的论文 ID",
|
||||
},
|
||||
)
|
||||
|
||||
papers = (
|
||||
db.query(Paper)
|
||||
.filter(Paper.arxiv_id.in_(arxiv_ids))
|
||||
.options(
|
||||
joinedload(Paper.authors),
|
||||
joinedload(Paper.tags),
|
||||
joinedload(Paper.summary),
|
||||
joinedload(Paper.summary_status),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
|
||||
# 按请求顺序排列
|
||||
id_order = {aid: idx for idx, aid in enumerate(arxiv_ids)}
|
||||
papers.sort(key=lambda p: id_order.get(p.arxiv_id, 999))
|
||||
|
||||
# 构建对比数据
|
||||
compare_fields = [
|
||||
("title_zh", "中文标题"),
|
||||
("title_en", "英文标题"),
|
||||
("one_line", "一句话摘要"),
|
||||
("difficulty", "难度"),
|
||||
("motivation_problem", "研究问题"),
|
||||
("motivation_goal", "研究目标"),
|
||||
("motivation_gap", "研究差距"),
|
||||
("method_overview", "方法概述"),
|
||||
("method_key_idea", "关键思路"),
|
||||
("method_novelty", "新颖性"),
|
||||
("results", "实验结果"),
|
||||
("limitations", "局限与改进"),
|
||||
]
|
||||
|
||||
rows = []
|
||||
for field_key, field_label in compare_fields:
|
||||
cells = []
|
||||
for paper in papers:
|
||||
if field_key in ("title_zh", "title_en"):
|
||||
val = getattr(paper, field_key, None) or ""
|
||||
elif paper.summary:
|
||||
val = getattr(paper.summary, field_key, None) or ""
|
||||
# JSON 字段直接展示
|
||||
if field_key == "results" and not val:
|
||||
val = paper.summary.results_main_json or ""
|
||||
if field_key == "limitations" and not val:
|
||||
val = paper.summary.limitations_json or ""
|
||||
else:
|
||||
val = ""
|
||||
cells.append(val)
|
||||
rows.append({"key": field_key, "label": field_label, "cells": cells})
|
||||
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"compare.html",
|
||||
{
|
||||
"page_title": "论文对比",
|
||||
"papers": papers,
|
||||
"rows": rows,
|
||||
"ids_param": ids,
|
||||
"error": None,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user