# 报告导出接口 **本文档引用的文件** - [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)