diff --git a/backend/app/api/data_routes.py b/backend/app/api/data_routes.py index 7bacfeb..406dc13 100644 --- a/backend/app/api/data_routes.py +++ b/backend/app/api/data_routes.py @@ -309,10 +309,13 @@ async def get_available_sources(market: str): @router.get("/recent", response_model=List[dict]) async def get_recent_companies( - data_source: str = "Bloomberg", + data_source: str = None, db: AsyncSession = Depends(get_db) ): - """获取最近更新的公司列表""" + """获取最近更新的公司列表 + + 如果不指定 data_source,将返回所有数据源的最近更新。 + """ return await data_fetcher_service.get_recent_companies( data_source=data_source, db=db, diff --git a/backend/app/services/data_fetcher_service.py b/backend/app/services/data_fetcher_service.py index 2e8c32d..07f4bd7 100644 --- a/backend/app/services/data_fetcher_service.py +++ b/backend/app/services/data_fetcher_service.py @@ -492,24 +492,28 @@ def get_available_data_sources(market: str) -> List[Dict]: return sources async def get_recent_companies( - data_source: str, + data_source: Optional[str], db: AsyncSession, limit: int = 20 ) -> List[Dict]: - """获取指定数据源下最近更新的公司""" + """获取最近更新的公司列表 + + Args: + data_source: 可选的数据源过滤。如果为None,则返回所有数据源的最近更新。 + db: 数据库会话 + limit: 返回数量限制 + """ query = ( - select(Company, DataUpdate.completed_at) + select(Company, DataUpdate.completed_at, DataUpdate.data_source) .join(DataUpdate, Company.id == DataUpdate.company_id) - .where( - and_( - DataUpdate.data_source == data_source, - DataUpdate.status == 'completed' - ) - ) + .where(DataUpdate.status == 'completed') .order_by(DataUpdate.completed_at.desc()) - .limit(limit * 3) # Fetch more to handle duplicates + .limit(limit * 5) # Fetch more to handle duplicates ) + if data_source: + query = query.where(DataUpdate.data_source == data_source) + result = await db.execute(query) rows = result.all() @@ -517,13 +521,14 @@ async def get_recent_companies( companies = [] for row in rows: - company, completed_at = row + company, completed_at, source = row if company.id not in seen_ids: seen_ids.add(company.id) companies.append({ "market": company.market, "symbol": company.symbol, "company_name": company.company_name, + "data_source": source, "last_update": completed_at.strftime('%Y-%m-%d %H:%M') if completed_at else "" }) if len(companies) >= limit: diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 1a5cee3..ee4bb45 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -116,7 +116,7 @@ export default function Home() { {/* 历史记录 */} -
+
diff --git a/frontend/src/components/history-list.tsx b/frontend/src/components/history-list.tsx index d9fdfb0..c01a46c 100644 --- a/frontend/src/components/history-list.tsx +++ b/frontend/src/components/history-list.tsx @@ -1,10 +1,8 @@ -"use client" - import { useEffect, useState } from "react" -import { getReports } from "@/lib/api" +import { getRecentCompanies } from "@/lib/api" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" -import { Loader2 } from "lucide-react" +import { Loader2, Database } from "lucide-react" import type { SearchResult } from "@/lib/types" interface HistoryListProps { @@ -12,59 +10,50 @@ interface HistoryListProps { } export function HistoryList({ onSelect }: HistoryListProps) { - const [reports, setReports] = useState([]) + const [companies, setCompanies] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { - getReports().then(setReports).catch(console.error).finally(() => setLoading(false)) + getRecentCompanies().then(setCompanies).catch(console.error).finally(() => setLoading(false)) }, []) if (loading) return - if (reports.length === 0) return
没有找到历史记录。
+ if (companies.length === 0) return
没有找到最近的数据记录。
return ( -
- {reports.map((report: any) => ( +
+ {companies.map((company: any, index: number) => ( { if (onSelect) { onSelect({ - symbol: report.symbol, - market: report.market, - company_name: report.company_name - }, report.data_source) + symbol: company.symbol, + market: company.market, + company_name: company.company_name + }, company.data_source) } }} > - - {report.company_name} + +
+ {company.company_name} + {company.market} +
- {report.market} {report.symbol} + {company.symbol}
-
- - {new Date(report.created_at).toLocaleString('zh-CN')} - - - {report.status === "completed" ? "已完成" : - report.status === "in_progress" ? "进行中" : - report.status === "failed" ? "失败" : "待处理"} - -
- {report.ai_model && ( -
- 模型: {report.ai_model} +
+ {company.last_update} +
+ + {company.data_source}
- )} +
))} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 71e5f65..34ae225 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -163,6 +163,19 @@ export async function getAnalysisHistory( return res.json() } +/** + * 获取最近更新的公司列表 + */ +export async function getRecentCompanies(dataSource?: string): Promise { + let url = `${API_BASE}/data/recent` + if (dataSource) { + url += `?data_source=${dataSource}` + } + const res = await fetch(url) + if (!res.ok) throw new Error("Failed to fetch recent companies") + return res.json() +} + // ========== 兼容性函数 ========== /** * 获取所有分析报告(兼容旧API)