# 报告导出接口
**本文档引用的文件**
- [backend/app/api/reports.py](file://backend/app/api/reports.py)
- [backend/app/services/citation.py](file://backend/app/services/citation.py)
- [backend/app/models/citation_record.py](file://backend/app/models/citation_record.py)
- [backend/app/models/query.py](file://backend/app/models/query.py)
- [backend/app/models/query_task.py](file://backend/app/models/query_task.py)
- [backend/app/workers/citation_engine.py](file://backend/app/workers/citation_engine.py)
- [backend/app/workers/scheduler.py](file://backend/app/workers/scheduler.py)
- [backend/app/workers/platforms/base.py](file://backend/app/workers/platforms/base.py)
- [backend/app/main.py](file://backend/app/main.py)
- [frontend/lib/api.ts](file://frontend/lib/api.ts)
- [frontend/app/(dashboard)/dashboard/reports/page.tsx](file://frontend/app/(dashboard)/dashboard/reports/page.tsx)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“报告导出系统”的使用者与维护者,提供完整的CSV格式数据导出API文档。内容涵盖:
- 导出流程与参数配置
- 报告生成触发机制(手动触发、定时触发)
- 数据筛选条件与输出格式选项
- 导出进度监控、错误处理与文件下载
- 报告模板定制、数据格式转换与性能优化建议
## 项目结构
后端采用FastAPI + SQLAlchemy异步ORM,前端基于Next.js。导出能力通过独立的报告路由暴露,并由服务层负责数据聚合与CSV生成。
```mermaid
graph TB
subgraph "前端"
FE_API["前端API封装
frontend/lib/api.ts"]
FE_PAGE["报告页面
frontend/app/(dashboard)/dashboard/reports/page.tsx"]
end
subgraph "后端"
MAIN["应用入口
backend/app/main.py"]
ROUTER["报告路由
backend/app/api/reports.py"]
SERVICE["导出服务
backend/app/services/citation.py"]
MODELS["模型定义
models/*.py"]
WORKERS["工作流与调度
workers/*.py"]
end
FE_PAGE --> FE_API
FE_API --> ROUTER
ROUTER --> SERVICE
SERVICE --> MODELS
WORKERS --> MODELS
MAIN --> ROUTER
MAIN --> WORKERS
```
图表来源
- [backend/app/main.py:13-48](file://backend/app/main.py#L13-L48)
- [backend/app/api/reports.py:1-47](file://backend/app/api/reports.py#L1-L47)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
- [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95)
- [frontend/lib/api.ts:51-57](file://frontend/lib/api.ts#L51-L57)
- [frontend/app/(dashboard)/dashboard/reports/page.tsx:49-93](file://frontend/app/(dashboard)/dashboard/reports/page.tsx#L49-L93)
章节来源
- [backend/app/main.py:13-48](file://backend/app/main.py#L13-L48)
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
- [frontend/app/(dashboard)/dashboard/reports/page.tsx:1-198](file://frontend/app/(dashboard)/dashboard/reports/page.tsx#L1-L198)
## 核心组件
- 报告导出路由:提供CSV导出接口,接收查询词ID并返回流式CSV响应。
- 导出服务:验证用户与查询所有权,查询引用记录并生成CSV字符串。
- 数据模型:查询、引用记录、查询任务等,支撑筛选与统计。
- 引擎与调度:定时检查到期查询并执行,支持手动触发。
- 前端集成:提供查询词选择、导出按钮与下载逻辑。
章节来源
- [backend/app/api/reports.py:16-47](file://backend/app/api/reports.py#L16-L47)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
- [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95)
- [frontend/lib/api.ts:51-57](file://frontend/lib/api.ts#L51-L57)
- [frontend/app/(dashboard)/dashboard/reports/page.tsx:49-93](file://frontend/app/(dashboard)/dashboard/reports/page.tsx#L49-L93)
## 架构总览
下图展示从前端发起导出请求到后端生成CSV并返回下载的完整链路。
```mermaid
sequenceDiagram
participant FE as "前端页面
page.tsx"
participant API as "前端API封装
lib/api.ts"
participant FAST as "报告路由
reports.py"
participant SVC as "导出服务
services/citation.py"
participant DB as "数据库
SQLAlchemy"
FE->>API : "调用导出接口"
API->>FAST : "GET /api/v1/reports/export/csv?query_id=..."
FAST->>SVC : "export_citations_csv(db, user_id, query_id)"
SVC->>DB : "查询引用记录"
DB-->>SVC : "返回记录集合"
SVC-->>FAST : "返回CSV字符串"
FAST-->>API : "StreamingResponse(csv)"
API-->>FE : "下载CSV文件"
```
图表来源
- [frontend/app/(dashboard)/dashboard/reports/page.tsx:49-93](file://frontend/app/(dashboard)/dashboard/reports/page.tsx#L49-L93)
- [frontend/lib/api.ts:51-57](file://frontend/lib/api.ts#L51-L57)
- [backend/app/api/reports.py:16-47](file://backend/app/api/reports.py#L16-L47)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
## 详细组件分析
### 报告导出接口(CSV)
- 接口路径:/api/v1/reports/export/csv
- 方法:GET
- 认证:需要Bearer Token
- 参数
- query_id: UUID,必填,指定导出的查询词
- format: 字符串,默认csv,当前版本仅支持csv
- 成功响应
- Content-Type: text/csv
- Content-Disposition: attachment; filename="geo-report-YYYYMMDD.csv"
- 响应体:CSV字符串(流式传输)
- 错误处理
- format非csv:400 Bad Request
- 查询不存在或无权限:404 Not Found
- 其他异常:500 Internal Server Error
章节来源
- [backend/app/api/reports.py:16-47](file://backend/app/api/reports.py#L16-L47)
### 导出服务与数据筛选
- 权限校验:仅允许导出当前用户拥有的查询词下的数据
- 数据筛选
- query_id:限定到具体查询词
- 时间范围:通过引用记录的查询时间字段进行过滤(服务层支持start_date/end_date参数)
- 输出字段(CSV列头)
- 日期、平台、是否引用、引用位置、引用文本、竞争品牌
- 性能特性
- 使用StringIO构建CSV,避免中间文件
- 支持流式返回,降低内存峰值
章节来源
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
### 报告生成触发机制
- 手动导出
- 前端选择查询词后点击导出,直接调用导出接口
- 后端即时查询数据库并返回CSV
- 定时导出
- 调度器每小时扫描到期查询(status=active且next_query_at<=now)
- 对每个到期查询执行引擎,生成引用记录
- 导出接口可读取这些最新记录
- 手动触发查询
- 服务层提供立即触发方法,创建查询任务并返回首个任务信息
```mermaid
flowchart TD
Start(["定时检查"]) --> Scan["扫描到期查询"]
Scan --> HasDue{"存在到期查询?"}
HasDue -- 否 --> Wait["等待下一小时"] --> Scan
HasDue -- 是 --> Exec["执行查询引擎"]
Exec --> Save["保存引用记录"]
Save --> Update["更新查询时间字段"]
Update --> Export["导出接口可读取最新数据"]
```
图表来源
- [backend/app/workers/scheduler.py:51-84](file://backend/app/workers/scheduler.py#L51-L84)
- [backend/app/workers/citation_engine.py:159-234](file://backend/app/workers/citation_engine.py#L159-L234)
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
章节来源
- [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95)
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
- [backend/app/services/citation.py:204-234](file://backend/app/services/citation.py#L204-L234)
### 数据模型与关系
```mermaid
erDiagram
QUERIES {
uuid id PK
uuid user_id FK
string keyword
string target_brand
jsonb brand_aliases
jsonb platforms
string frequency
string status
datetime last_queried_at
datetime next_query_at
}
CITATION_RECORDS {
uuid id PK
uuid query_id FK
string platform
boolean cited
integer citation_position
text citation_text
jsonb competitor_brands
text raw_response
datetime queried_at
}
QUERY_TASKS {
uuid id PK
uuid query_id FK
string platform
string status
text error_message
datetime scheduled_at
datetime started_at
datetime completed_at
}
QUERIES ||--o{ CITATION_RECORDS : "拥有"
QUERIES ||--o{ QUERY_TASKS : "拥有"
```
图表来源
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
章节来源
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
### 前端集成与下载
- 前端页面提供查询词下拉选择与导出按钮
- 导出时通过原生fetch请求后端接口,接收blob并触发浏览器下载
- 成功/失败状态提示与加载态管理
章节来源
- [frontend/app/(dashboard)/dashboard/reports/page.tsx:49-93](file://frontend/app/(dashboard)/dashboard/reports/page.tsx#L49-L93)
- [frontend/lib/api.ts:51-57](file://frontend/lib/api.ts#L51-L57)
## 依赖关系分析
- 报告路由依赖导出服务
- 导出服务依赖查询与引用记录模型
- 引擎与调度器依赖平台适配器基类
- 应用入口在生命周期内启动调度器
```mermaid
graph LR
Reports["reports.py"] --> ExportSvc["services/citation.py"]
ExportSvc --> Models["models/*.py"]
Scheduler["workers/scheduler.py"] --> Engine["workers/citation_engine.py"]
Engine --> Platforms["workers/platforms/base.py"]
Main["main.py"] --> Reports
Main --> Scheduler
```
图表来源
- [backend/app/api/reports.py:11](file://backend/app/api/reports.py#L11)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
- [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95)
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
- [backend/app/workers/platforms/base.py:4-18](file://backend/app/workers/platforms/base.py#L4-L18)
- [backend/app/main.py:13-48](file://backend/app/main.py#L13-L48)
章节来源
- [backend/app/api/reports.py:11](file://backend/app/api/reports.py#L11)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
- [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95)
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
- [backend/app/workers/platforms/base.py:4-18](file://backend/app/workers/platforms/base.py#L4-L18)
- [backend/app/main.py:13-48](file://backend/app/main.py#L13-L48)
## 性能考虑
- 流式响应:后端以流式方式返回CSV,避免一次性加载全部数据至内存
- 索引优化:引用记录表对query_id、queried_at、platform建立索引,提升筛选与排序性能
- 分页与限制:服务层支持skip/limit,前端可结合分页控件控制导出规模
- 导出粒度:优先按查询词导出,避免全量导出导致的I/O压力
- 并发与队列:查询任务表支持多平台并发执行,导出时可按需筛选时间段
章节来源
- [backend/app/services/citation.py:24-74](file://backend/app/services/citation.py#L24-L74)
- [backend/app/models/citation_record.py:37-41](file://backend/app/models/citation_record.py#L37-L41)
## 故障排查指南
- 400 Bad Request:format参数非csv
- 检查前端传参或接口调用是否正确
- 404 Not Found:查询不存在或无权限
- 确认query_id归属当前用户,查询状态为active
- 下载失败或文件为空
- 检查该查询词是否存在引用记录;确认导出时间范围内是否有数据
- 导出耗时过长
- 缩小时间范围或按查询词导出;检查数据库索引是否生效
- 定时任务未执行
- 检查调度器是否启动;核对查询状态与next_query_at字段
章节来源
- [backend/app/api/reports.py:23-35](file://backend/app/api/reports.py#L23-L35)
- [backend/app/services/citation.py:242-244](file://backend/app/services/citation.py#L242-L244)
- [backend/app/workers/scheduler.py:30-40](file://backend/app/workers/scheduler.py#L30-L40)
## 结论
本报告导出系统以清晰的职责分离实现:前端负责交互与下载,后端路由负责鉴权与转发,服务层负责数据筛选与CSV生成,调度器负责周期性任务执行。当前版本聚焦CSV导出,后续可扩展为多格式与批量导出,同时建议引入任务队列与进度回调以增强用户体验。
## 附录
### API定义(CSV导出)
- 路径:/api/v1/reports/export/csv
- 方法:GET
- 认证:Bearer Token
- 查询参数
- query_id: UUID,必填
- format: 字符串,可选,默认csv
- 响应
- 200 OK:text/csv,Content-Disposition为附件下载
- 400 Bad Request:format非法
- 404 Not Found:查询不存在或无权限
- 500 Internal Server Error:内部异常
章节来源
- [backend/app/api/reports.py:16-47](file://backend/app/api/reports.py#L16-L47)
### 输出字段说明(CSV)
- 日期:引用记录的查询时间
- 平台:执行查询的AI平台名称
- 是否引用:布尔值(是/否)
- 引用位置:品牌首次出现的段落序号(若未命中则为空)
- 引用文本:截取后的上下文片段(若未命中则为空)
- 竞争品牌:检测到的其他品牌列表(逗号分隔)
章节来源
- [backend/app/services/citation.py:256-268](file://backend/app/services/citation.py#L256-L268)
### 报告模板定制建议
- 列顺序与标题:可在导出服务中调整writer的列头顺序与本地化标题
- 过滤条件:扩展服务层参数(如平台、起止时间),并在导出服务中拼接SQL条件
- 格式转换:如需Excel,可在前端接收CSV后转为xlsx,或在后端生成xlsx流
章节来源
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)
### 批量导出与定时导出模式
- 批量导出:前端逐项选择查询词后分别导出;或在后端增加“全部查询”聚合导出(需扩展服务层)
- 定时导出:通过调度器周期性执行查询并生成记录,随后即可导出
- 手动导出:前端点击即刻触发查询任务,完成后导出
章节来源
- [backend/app/workers/scheduler.py:51-84](file://backend/app/workers/scheduler.py#L51-L84)
- [backend/app/services/citation.py:204-234](file://backend/app/services/citation.py#L204-L234)
### 进度监控与错误处理
- 进度监控:查询任务表包含状态与时间戳,可用于前端轮询或WebSocket推送
- 错误处理:平台适配器异常会写入任务错误信息与记录,导出接口保持幂等与健壮
章节来源
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
- [backend/app/workers/citation_engine.py:211-227](file://backend/app/workers/citation_engine.py#L211-L227)