feat: AI分析页支持按日期查看历史报告(?date=,兼容?data=)

This commit is contained in:
Sakurasan
2026-09-12 20:21:44 +08:00
parent e24b1a360b
commit 6c7d8fe4bc
4 changed files with 102 additions and 19 deletions
+2 -2
View File
@@ -334,7 +334,7 @@ function renderReports(list) {
document.getElementById('recentBody').innerHTML = list.map(r =>
`<tr>
<td>${r.trade_date}</td>
<td><a href="/ai-analysis" target="_blank" style="color:var(--primary);text-decoration:none">${r.title || '-'}</a></td>
<td><a href="/ai-analysis?date=${r.trade_date}" target="_blank" style="color:var(--primary);text-decoration:none">${r.title || '-'}</a></td>
<td>${r.tokens_used || 0}</td>
</tr>`
).join('') || '<tr><td colspan="3" style="color:var(--muted-foreground);text-align:center">暂无数据</td></tr>';
@@ -349,7 +349,7 @@ function renderAllReports(list) {
<td>${r.tokens_used || 0}</td>
<td>${r.created_at || '-'}</td>
<td style="white-space:nowrap">
<a href="/ai-analysis" target="_blank" class="btn btn-ghost btn-sm" style="padding:3px 10px;font-size:11px;text-decoration:none">查看</a>
<a href="/ai-analysis?date=${r.trade_date}" target="_blank" class="btn btn-ghost btn-sm" style="padding:3px 10px;font-size:11px;text-decoration:none">查看</a>
<button class="btn btn-destructive btn-sm" style="padding:3px 10px;font-size:11px" onclick="deleteReport(${r.id})">删除</button>
</td>
</tr>`
+23
View File
@@ -77,6 +77,29 @@ async def list_reports():
conn.close()
@router.get("/ai-analysis/by-date/{trade_date}", summary="按交易日获取 AI 分析报告")
async def get_report_by_date(trade_date: str):
try:
datetime.strptime(trade_date, "%Y-%m-%d")
except ValueError:
raise HTTPException(status_code=400, detail="日期格式错误,应为 YYYY-MM-DD")
conn = get_connection()
try:
row = conn.execute(
"""SELECT r.*,
(SELECT COUNT(*) FROM ai_reports WHERE trade_date <= r.trade_date) AS issue_number
FROM ai_reports r WHERE r.trade_date = ? AND r.report_type = 'daily' LIMIT 1""",
(trade_date,)
).fetchone()
if not row:
raise HTTPException(status_code=404, detail=f"{trade_date} 暂无分析报告")
item = dict_from_row(row)
item["toolsUsed"] = json.loads(item.pop("tools_used") or "[]")
return JSONResponse({"data": item}, headers=_NO_CACHE_HEADERS)
finally:
conn.close()
@router.get("/ai-analysis/{report_id}", summary="AI 分析报告详情")
async def get_report(report_id: int):
conn = get_connection()