feat: 手动上传绕防爬、下载错误诊断与健康检查工具;模块化重构 API 与批量同步

后端:
  - 将 handlers.rs (1338行) 拆分为 helpers/papers/notes/sync 四模块
  - 将 batch_sync.rs 拆分为 batch/{mod,meta,asset} 三模块
  - 新增 POST /api/upload 多部件文件上传接口
  - 新增 POST /api/no_resource 标记文献"无全文资源"
  - 新增 GET/POST /api/active_bibcode 追踪活跃文献
  - StandardPaper 结构体扩展 pdf_error / html_error 错误诊断字段
  - download.rs 记录下载失败详情至数据库
  - 新增 health_check 二进制工具,支持只读扫描与 --fix 自动修复
  - 移除 scratch/ 目录、recovered_handlers.rs 及调试日志

  前端:
  - 新建 CustomSelect 可复用组件,替换全部原生 select
  - LibraryPanel:同步按钮反馈动画、下载失败/无资源状态筛选与计数、
    文献类型筛选、状态优先排序、搜索一键清空
  - 详情弹窗:错误诊断展示、手动 PDF/HTML 上传区、无资源标记/恢复
  - SearchPanel:扩展文献类型徽章、下载失败状态提示
  - SyncPanel:同步启动乐观 UI 更新、日志容器内自动滚动
  - Tab 状态 localStorage 持久化、弹窗 z-index 修复
This commit is contained in:
fmq
2026-06-11 22:56:36 +08:00
parent cd6af4f995
commit 8cc2b74abc
43 changed files with 4512 additions and 3879 deletions
+184 -15
View File
@@ -25,6 +25,9 @@ export interface StandardPaper {
is_downloaded: boolean;
has_markdown: boolean;
has_translation: boolean;
doctype: string;
pdf_error?: string; // PDF 下载失败诊断信息(如存在)
html_error?: string; // HTML 下载失败诊断信息(如存在)
}
// 笔记记录
@@ -37,8 +40,35 @@ export interface NoteRecord {
selected_text: string;
created_at: string;
}
// 引文网络
export interface CitationNetwork {
bibcode: string;
title: string;
citation_count: number;
reference_count: number;
references: string[];
citations: string[];
citation_counts?: Record<string, number>;
}
// 已保存的同步检索条件
export interface SavedSyncQuery {
id: number;
query: string;
source: string;
limit_count: number;
last_run: string;
}
```
### 1.1 错误诊断字段说明
`pdf_error``html_error` 字段用于传递文献下载失败的具体原因:
- 当数据库中对应的 `pdf_path``html_path``error:` 前缀存储时,前端会自动提取前缀后的内容作为诊断信息。
- 特殊值 `no_resource`:表示用户手动标记了该文献为"无有效全文资源",后续批量下载任务将自动跳过此文献。
- 其他值:为系统自动检测到的下载失败原因(如网络超时、Cloudflare 拦截、404 等)。
---
## 2. 接口分模块详述 (API Endpoints)
@@ -94,7 +124,7 @@ export interface NoteRecord {
#### 2.2.1 获取馆藏文献列表
- **Endpoint**: `GET /api/library`
- **Description**: 查询本地 SQLite 数据库中已收藏入库的所有文献列表,后端会自动**实时感应物理文件是否存在**来修正 `is_downloaded` / `has_markdown` 等布尔状态。
- **Description**: 查询本地 SQLite 数据库中已收藏入库的所有文献列表,后端会自动**实时感应物理文件是否存在**来修正 `is_downloaded` / `has_markdown` 等布尔状态。同时读取并返回 `pdf_error` / `html_error` 诊断字段。
- **Response Schema (`Vec<StandardPaper>`)**:
- HTTP `200 OK`
- **cURL 示例**:
@@ -104,7 +134,7 @@ export interface NoteRecord {
#### 2.2.2 触发并行文献下载
- **Endpoint**: `POST /api/download`
- **Description**: 触发后台线程拉取文献的 PDF 及 HTML。如果是 arXiv 来源优先官方 HTML 兜底 ar5iv,并支持强制更新。
- **Description**: 触发后台线程拉取文献的 PDF 及 HTML。如果是 arXiv 来源优先官方 HTML 兜底 ar5iv,并支持强制更新。下载失败时会在数据库中以 `error:` 前缀记录具体原因。
- **Request Body**:
```json
{
@@ -112,7 +142,7 @@ export interface NoteRecord {
"force": false
}
```
- **Response Schema (`StandardPaper`)**: Returns the updated paper structure with `is_downloaded: true`.
- **Response Schema (`StandardPaper`)**: Returns the updated paper structure with `is_downloaded: true` (on success) or `pdf_error`/`html_error` populated (on failure).
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/download" \
@@ -120,7 +150,49 @@ export interface NoteRecord {
-d '{"bibcode": "2024arXiv241011663H", "force": true}'
```
#### 2.2.3 触发文献结构化解析
#### 2.2.3 手动上传文献物理文件
- **Endpoint**: `POST /api/upload`
- **Description**: 手动上传用户离线下载的 HTML 或 PDF 物理文件,以便系统进行结构化解析和双语翻译。此接口常用于前端手动上传或浏览器书签直推同步,支持绕过防爬与验证码限制。上传时会自动进行文件格式校验(PDF 校验 `%PDF` 文件头),并支持通过 DOI 或 arXiv ID 自动匹配 Bibcode。
- **Request Body (Multipart Form Data)**:
- `bibcode` (string, required): 文献唯一标识符(Bibcode)、DOI 或 arXiv ID。
- `type` (string, required): 文件类别,取值为 `pdf` | `html`。
- `file` (file binary, required): 上传的 PDF 或 HTML 文件。
- **Response Schema (`StandardPaper`)**: 返回已更新下载状态(`is_downloaded: true`)的文献标准化元数据。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/upload" \
-F "bibcode=2024arXiv241011663H" \
-F "type=pdf" \
-F "file=@/path/to/downloaded.pdf"
```
#### 2.2.4 标记/取消"无有效全文资源"
- **Endpoint**: `POST /api/no_resource`
- **Description**: 将文献标记为"无有效全文资源"或清除该标记。标记后,后续批量下载/解析任务将自动跳过此文献。此操作会将数据库中的 `pdf_path` 和 `html_path` 设置为(或清除)`error:no_resource`。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H",
"clear": false
}
```
- `bibcode` (string, required): 文献唯一标识符。
- `clear` (boolean, optional): 设为 `true` 清除标记(恢复自动下载),默认 `false`(标记无资源)。
- **Response Schema (`StandardPaper`)**: 返回更新后的文献标准化元数据。
- **cURL 示例**:
```bash
# 标记为无资源
curl -X POST "http://localhost:8000/api/no_resource" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H"}'
# 清除标记(恢复自动下载)
curl -X POST "http://localhost:8000/api/no_resource" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H", "clear": true}'
```
#### 2.2.5 触发文献结构化解析
- **Endpoint**: `POST /api/parse`
- **Description**: 将本地下载的 HTML/PDF 清洗为 Markdown。支持 `force` 强制重新执行。
- **Request Body**:
@@ -205,7 +277,8 @@ export interface NoteRecord {
"citation_count": 12,
"reference_count": 48,
"references": ["bibcode1", "bibcode2"],
"citations": ["bibcode3", "bibcode4"]
"citations": ["bibcode3", "bibcode4"],
"citation_counts": { "bibcode3": 5, "bibcode4": 120 }
}
```
- **cURL 示例**:
@@ -226,7 +299,7 @@ export interface NoteRecord {
"bibcode": "2024arXiv241011663H",
"paragraph_index": 12,
"note_text": "这是一个重要的物理模型",
"highlight_color": "yellow", // 'yellow' | 'green' | 'blue' | 'pink'
"highlight_color": "yellow",
"selected_text": "the standard model of galaxy formation"
}
```
@@ -291,7 +364,7 @@ export interface NoteRecord {
#### 2.6.2 启动后台元数据同步
- **Endpoint**: `POST /api/sync/meta/run`
- **Description**: 后台异步启动对指定关键词的文献元数据的大批量增量检索与同步入库。
- **Description**: 后台异步启动对指定关键词的文献元数据的大批量增量检索与同步入库。若当前已有同步任务在运行中,将返回 `409 Conflict`。
- **Request Body**:
```json
{
@@ -300,7 +373,7 @@ export interface NoteRecord {
"limit": 200
}
```
- **Response Schema**: Returns HTTP `200 OK` (plain text success message).
- **Response Schema**: Returns HTTP `200 OK` (plain text success message) 或 `409 Conflict` (已有任务运行)。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/sync/meta/run" \
@@ -328,15 +401,21 @@ export interface NoteRecord {
#### 2.6.4 启动后台文献资源批量下载/解析
- **Endpoint**: `POST /api/sync/asset/run`
- **Description**: 后台异步启动文献物理资源 (PDF/HTML) 的批量下载及结构化 Markdown 转换任务。
- **Description**: 后台异步启动文献物理资源 (PDF/HTML) 的批量下载及结构化 Markdown 转换任务。支持按文献 Bibcode 列表或按状态范围筛选处理目标。
- **Request Body**:
```json
{
"action": "all", // "all" (下载并解析) | "download" (仅下载) | "parse" (仅解析)
"scope": "undownloaded" // "all" (全部) | "undownloaded" (仅未下载) | "unparsed" (仅未解析)
"action": "all",
"scope": "undownloaded",
"sort_order": "default",
"limit_count": 50
}
```
- **Response Schema**: Returns HTTP `200 OK` (plain text success message).
- `action` (string): `"all"` (下载并解析) | `"download"` (仅下载) | `"parse"` (仅解析) | `"translate"` (仅翻译)。
- `scope` (string): `"all"` (全部) | `"undownloaded"` (仅未下载) | `"unparsed"` (仅未解析)。
- `sort_order` (string, optional): `"default"` | `"pub_year_desc"` | `"created_at_desc"`。
- `limit_count` (number, optional): 批量处理上限,默认处理全部匹配文献。
- **Response Schema**: Returns HTTP `200 OK` (plain text success message) 或 `409 Conflict` (已有任务运行)。
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/sync/asset/run" \
@@ -355,7 +434,7 @@ export interface NoteRecord {
#### 2.6.6 查询批量处理任务状态与日志
- **Endpoint**: `GET /api/sync/asset/status`
- **Description**: 获取当前后台批量下载与解析任务的状态、总匹配文献数、已下载数、已解析数、当前处理的 Bibcode,以及实时流转的终端日志(最多保留最新 1000 行)。
- **Description**: 获取当前后台批量下载与解析任务的状态、总匹配文献数、已下载数、已解析数、失败数、当前处理的 Bibcode,以及实时流转的终端日志(最多保留最新 100)。
- **Response Schema**:
```json
{
@@ -363,6 +442,8 @@ export interface NoteRecord {
"total": 12,
"downloaded": 12,
"parsed": 12,
"download_failed": 0,
"parse_failed": 0,
"current_bibcode": "2020A&A...635A..38C",
"logs": [
"[INFO] 批量处理任务初始化成功",
@@ -377,14 +458,102 @@ export interface NoteRecord {
curl "http://localhost:8000/api/sync/asset/status"
```
#### 2.6.7 获取已保存的同步检索条件
- **Endpoint**: `GET /api/sync/queries`
- **Description**: 获取用户保存的所有同步检索条件列表,用于快速重新同步。
- **Response Schema (`Vec<SavedSyncQuery>`)**:
- HTTP `200 OK`
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/sync/queries"
```
#### 2.6.8 删除已保存的同步检索条件
- **Endpoint**: `DELETE /api/sync/queries/:id`
- **Description**: 删除指定 ID 的已保存同步检索条件。
- **Path Parameters**:
- `id` (number, required): 同步检索条件的唯一自增 ID。
- **Response Schema**: Returns HTTP `200 OK` (plain text success message).
- **cURL 示例**:
```bash
curl -X DELETE "http://localhost:8000/api/sync/queries/1"
```
---
## 3. 常见 HTTP 状态码与异常处理 (Error Codes)
### 2.7 活跃文献追踪 (Active Bibcode Tracking)
#### 2.7.1 获取当前活跃文献
- **Endpoint**: `GET /api/active_bibcode`
- **Description**: 获取当前用户正在查看/操作的文献 Bibcode。前端在用户点击文献外部链接(如 ADS、DOI、arXiv)时自动上报。
- **Response Schema**:
```json
{
"bibcode": "2024arXiv241011663H"
}
```
若无活跃文献,`bibcode` 为 `null`。
- **cURL 示例**:
```bash
curl "http://localhost:8000/api/active_bibcode"
```
#### 2.7.2 设置当前活跃文献
- **Endpoint**: `POST /api/active_bibcode`
- **Description**: 设置当前正在查看的文献 Bibcode,用于浏览器书签直推等场景。
- **Request Body**:
```json
{
"bibcode": "2024arXiv241011663H"
}
```
- **Response Schema**: Returns HTTP `200 OK`.
- **cURL 示例**:
```bash
curl -X POST "http://localhost:8000/api/active_bibcode" \
-H "Content-Type: application/json" \
-d '{"bibcode": "2024arXiv241011663H"}'
```
---
## 3. 完整路由表 (Route Summary)
| 方法 | 路径 | 说明 |
|:---|:---|:---|
| `GET` | `/api/search` | 跨源文献统一搜索 |
| `POST` | `/api/download` | 触发文献下载 |
| `POST` | `/api/upload` | 手动上传文献文件 |
| `POST` | `/api/no_resource` | 标记/取消"无有效全文资源" |
| `POST` | `/api/parse` | 触发文献结构化解析 |
| `POST` | `/api/translate` | 触发 LLM 对照翻译 |
| `GET` | `/api/citations` | 查询引文拓扑网络 |
| `GET` | `/api/paper` | 获取文献阅读详情 |
| `GET` | `/api/library` | 获取馆藏文献列表 |
| `POST` | `/api/export` | 批量 BibTeX 导出 |
| `POST` | `/api/notes` | 创建笔记与高亮 |
| `GET` | `/api/notes` | 获取文献笔记列表 |
| `DELETE` | `/api/notes` | 删除笔记 |
| `GET` | `/api/sync/meta/count` | 预估元数据同步总量 |
| `POST` | `/api/sync/meta/run` | 启动元数据同步 |
| `GET` | `/api/sync/meta/status` | 查询元数据同步状态 |
| `POST` | `/api/sync/asset/run` | 启动资源批量处理 |
| `POST` | `/api/sync/asset/stop` | 停止资源批量处理 |
| `GET` | `/api/sync/asset/status` | 查询资源处理状态 |
| `GET` | `/api/sync/queries` | 获取已保存检索条件 |
| `DELETE` | `/api/sync/queries/:id` | 删除已保存检索条件 |
| `GET` | `/api/active_bibcode` | 获取当前活跃文献 |
| `POST` | `/api/active_bibcode` | 设置当前活跃文献 |
---
## 4. 常见 HTTP 状态码与异常处理 (Error Codes)
系统基于标准的 HTTP Status Codes 返回错误原因,响应的 Response Body 中通常为纯文本提示(String):
| 状态码 | 错误类型 | 触发常见场景及原因说明 |
| :--- | :--- | :--- |
| **`400 Bad Request`** | 业务请求不合规 | - 文献未下载/解析却直接调用 `translate`。<br>- 未在 `.env` 中提供 `ADS_API_KEY` 时调用 `export`。 |
| **`400 Bad Request`** | 业务请求不合规 | - 文献未下载/解析却直接调用 `translate`。<br>- 上传文件格式不合法(如 PDF 文件头校验失败)。<br>- 缺少必需参数(如 `bibcode` 为空)。 |
| **`404 Not Found`** | 资源未找到 | - 数据库中没有该 Bibcode 的收藏记录。 |
| **`409 Conflict`** | 状态冲突 | - 已有批量同步任务在后台运行中,重复启动时触发。 |
| **`500 Internal Error`**| 服务器内部错误 | - 第三方 LLM / ADS 接口通信超时或返回异常。<br>- 本地磁盘 IO 失败(如写入文件权限受阻)。<br>- 数据库查询异常。 |
+126 -66
View File
@@ -1,6 +1,6 @@
# AstroResearch Architecture / 架构设计
AstroResearch 是一个集成了天文学文献检索、通道下载、结构化解析、中英学术对比翻译以及引文星系图谱的天文科研辅助系统。
AstroResearch 是一个集成了天文学文献检索、通道下载(含防爬绕过与手动上传)、下载错误诊断、结构化解析、中英学术对比翻译引文星系图谱以及馆藏健康度诊断的天文科研辅助系统。
## 1. 整体架构 (Overall Architecture)
@@ -12,17 +12,29 @@ graph TD
UI[仪表盘 UI / ReaderPanel]
Canvas[引文 Canvas 拓扑图]
API_Client[Axum API 客户端]
CustomSelect[CustomSelect 可复用组件]
end
subgraph Backend ["Rust Axum 后端 (Port 8000)"]
Router[Axum 路由与中间件]
Handlers[业务处理器 api/handlers.rs]
Sync[同步器 services/batch_sync.rs]
Parser[解析器 services/parser.rs]
Downloader[下载器 services/download.rs]
Translator[翻译器 services/translation.rs]
Qiniu[七牛云客户端 clients/qiniu.rs]
Logging[日志记录器 services/logging.rs]
subgraph API ["API 层 (模块化)"]
Helpers[helpers.rs 格式转换与数据库工具]
Papers[papers.rs 文献检索/下载/上传/解析/翻译/引文/导出]
Notes[notes.rs 笔记 CRUD]
Sync[sync.rs 批量同步控制]
end
subgraph Services ["服务层"]
Batch[batch/ 批量同步引擎]
BatchMeta[batch/meta.rs 元数据采集]
BatchAsset[batch/asset.rs 资源处理]
Parser[parser.rs HTML/PDF 解析]
Downloader[download.rs 多通道下载器]
Translator[translation.rs LLM 翻译器]
Logging[logging.rs 日志系统]
end
DB[("SQLite / astro_research.db")]
end
@@ -36,28 +48,31 @@ graph TD
UI -->|用户操作| API_Client
API_Client -->|RESTful APIs| Router
Router --> Handlers
Router --> API
Handlers -->|查询/保存元数据| DB
Handlers -->|文献下载/解析/翻译| Handlers
Handlers -->|批量操作| Sync
Papers -->|查询/保存元数据| DB
Papers -->|文献下载| Downloader
Papers -->|文件上传| Papers
Papers -->|正文解析| Parser
Papers -->|学术翻译| Translator
Sync -->|批量操作| Batch
Sync -->|元数据同步| ADS
Sync -->|元数据同步| arXiv
Sync -->|批量文件下载| Downloader
Sync -->|批量正文解析| Parser
Sync -->|写库记录| DB
BatchMeta -->|元数据同步| ADS
BatchMeta -->|元数据同步| arXiv
BatchAsset -->|批量文件下载| Downloader
BatchAsset -->|批量正文解析| Parser
BatchAsset -->|批量翻译| Translator
Batch -->|写库记录| DB
Downloader -->|代理请求| ADS
Downloader -->|直连或 ar5iv| arXiv
Parser -->|图文降级解析| MinerU
Parser -->|托管插图| Qiniu
Qiniu -->|上传图片| QiniuCDN
Parser -->|托管插图| QiniuCDN
Translator -->|天文术语翻译| LLM
Canvas -->|引文网络请求| Handlers
Canvas -->|引文网络请求| Papers
```
---
@@ -66,12 +81,12 @@ graph TD
### 2.1 文献下载流程 (Download Flow)
本流程实现了文献的通道流式下载,支持多级回退以及安全反爬防线绕过,其详细步骤与交互如下
本流程实现了文献的通道流式下载,支持多级回退、错误诊断记录以及安全反爬防线绕过:
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant H as 处理器 (papers.rs)
participant D as 下载器 (download.rs)
participant DB as 本地数据库 (SQLite)
@@ -101,9 +116,15 @@ sequenceDiagram
D->>D: 6e. CrossRef 兜底:请求 CrossRef API 获取 PDF URL 并直连下载
end
D-->>H: 7. 返回下载好的本地物理 PDF & HTML 路径
H->>DB: 8. 更新 pdf_path & html_path 记录
H-->>U: 9. 返回最新文献状态 (is_downloaded: true)
alt 下载成功
D-->>H: 7a. 返回下载好的本地物理 PDF & HTML 路径
H->>DB: 8a. 更新 pdf_path & html_path 记录
H-->>U: 9a. 返回最新文献状态 (is_downloaded: true)
else 下载失败
D-->>H: 7b. 返回失败原因
H->>DB: 8b. 以 error: 前缀记录诊断信息
H-->>U: 9b. 返回文献状态 (pdf_error / html_error 已填充)
end
```
#### 详细下载说明:
@@ -112,17 +133,43 @@ sequenceDiagram
3. **内容完整性校验**
- 对 PDF 严格校验前四个字节(必须是 `%PDF`)以及尾部检索(必须包含 `%%EOF` 终止符),排查登录墙、错误页伪装成 PDF 导致下载坏文件的问题。
- 对 HTML 文本利用 `detect_anti_bot` 流水线过滤 "cloudflare"、"captcha"、"robot check" 等拦截特征。
4. **错误诊断记录**:下载失败时,系统会将具体的失败原因(如 "Cloudflare 拦截"、"404 Not Found" 等)以 `error:` 前缀存入数据库的 `pdf_path` / `html_path` 字段。前端通过 `pdf_error` / `html_error` 字段读取并向用户展示。
---
### 2.2 文献解析流程 (Parse Flow)
### 2.2 手动上传流程 (Upload Flow)
本流程负责将本地下载的 HTML 或 PDF 转换为高保真的 Markdown。其详细步骤与交互如下
当自动下载受防爬或人机验证阻碍时,用户可手动上传文献文件
```mermaid
sequenceDiagram
participant U as 用户 (React 前端 / 浏览器书签)
participant H as 处理器 (papers.rs)
participant DB as 本地数据库 (SQLite)
participant FS as 本地文件系统
U->>H: 1. 上传文件 (POST /api/upload, Multipart: bibcode + type + file)
H->>H: 2. 解析 Multipart 字段
alt bibcode 未直接匹配数据库
H->>DB: 3a. 尝试通过 DOI 匹配
H->>DB: 3b. 尝试通过 arXiv ID 匹配(自动去除版本号)
end
H->>H: 4. 校验文件格式 (PDF 校验 %PDF 文件头)
H->>FS: 5. 写入物理文件 (library/PDF/ 或 library/HTML/)
H->>DB: 6. 更新 pdf_path / html_path,清除 error: 诊断记录
H-->>U: 7. 返回更新后的文献元数据 (is_downloaded: true)
```
---
### 2.3 文献解析流程 (Parse Flow)
本流程负责将本地下载的 HTML 或 PDF 转换为高保真的 Markdown
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant H as 处理器 (papers.rs)
participant P as 解析器 (parser.rs)
participant M as MinerU (PDF解析服务)
participant Q as 七牛云 (对象存储)
@@ -164,22 +211,18 @@ sequenceDiagram
H-->>U: 11. 返回标准 Markdown 内容渲染展示
```
#### 详细解析说明:
1. **HTML 转换为 Markdown 保护公式**:由于 MathJax/LaTeX 在 Markdown 转换中极易被当成普通字符进行转义(例如 `_` 倾斜或 `\` 换行失效),解析器在 HTML 解析前,通过正则将 `$` / `$$``\(` / `\[` 中的内容全部替换为特定的 UUID 占位符,转换为标准 Markdown 之后,再反向替换恢复公式,确保 LaTeX 渲染无损。
2. **PDF 复杂排版降级与大文件直传**:遇到无法直接提取 HTML 的老文献时,调用 MinerU 进行布局分析与公式提取。为避免在上传大型 PDF 时触发 API 网关的 `413 Payload Too Large` 错误,系统弃用了传统的 Multipart 表单直接 POST 请求,转而采用**两阶段直传机制**:先请求预签名上传 URL,随后使用 HTTP `PUT` 直接流式传输二进制数据至存储服务,最后通过后台任务轮询 `extract-results` 获取转换完毕的 ZIP 并自动托管插图至七牛云。
---
### 2.3 智能对照翻译流程 (Translation Flow)
### 2.4 智能对照翻译流程 (Translation Flow)
本流程实现了基于天文学专属词汇表的 LLM 专业对比翻译,其详细步骤与交互如下
本流程实现了基于天文学专属词汇表的 LLM 专业对比翻译:
```mermaid
sequenceDiagram
participant U as 用户 (React 前端)
participant H as 处理器 (handlers.rs)
participant H as 处理器 (papers.rs)
participant T as 翻译器 (translation.rs)
participant D as 天文词典 (dictionary.rs)
participant D as 天文词典 (Trie 树)
participant L as 大模型 (LLM API)
participant DB as 本地数据库 (SQLite)
@@ -196,7 +239,7 @@ sequenceDiagram
T->>D: 7. 加载本地 dictionary.txt 并初始化 Trie 树结构
T->>D: 8. 执行英文 Markdown 文本分词匹配
D->>D: 9a. 进行前缀匹配检索
D->>D: 9b. 遵循最长匹配优先原则,过滤子词去重
D->>D: 9b. 遵循"最长匹配优先"原则,过滤子词去重
D-->>T: 10. 返回该篇文献提取出的天文学名词对照 (Glossary)
loop 针对英文 Markdown 进行段落分块 (Token 长度控制)
@@ -211,37 +254,54 @@ sequenceDiagram
H-->>U: 16. 返回翻译后 Markdown 渲染展示
```
#### 详细步骤说明:
1. **分级翻译缓存机制**
- 第一级缓存:若未开启 `force` 且本地物理磁盘已存在对应翻译文件,直接读取并返回,避免不必要的 LLM API 调用消耗。
- 第二级缓存:必须先完成英文 Markdown 的结构化解析,否则接口返回 `400` 错误,引导用户先进行正文解析。
2. **基于 Trie 树的天文学名词提取**
- 字典类 `Dictionary` 会加载包含数十万词条的本地天文词表 `dictionary.txt`
- 为防止短词覆盖长词(如 `Hertzsprung` 覆盖 `Hertzsprung-Russell diagram`),分词匹配采用 Trie 树的最长前缀匹配。若匹配到长词,自动忽略其包含的子词。
- 最终只保留文献中真实出现的名词并去重,以 JSON 的形式构建为专有提示词(Glossary)注入 LLM 提示中。
3. **LLM 强约束 Prompt 设计**
- 在向大模型发送请求时,利用 System Prompt 声明其“天文学专业翻译家”的角色。
- 强制约定格式要求:所有的 LaTeX 公式(`$` / `$$`)必须原封不动保留,Markdown 的标题(`#`)、列表(`-`)、加粗(`**`)等语法严禁破坏,使前端可以无缝解析双语结构并左右对齐渲染。
---
## 3. 核心模块说明
- **[src/api/handlers.rs](../src/api/handlers.rs)**:
- 处理 Axum API 路由分发与业务逻辑,包括统一检索、笔记管理、划词高亮及翻译。
- **[src/services/batch_sync.rs](../src/services/batch_sync.rs)**:
- 核心后台大批量文献元数据采集 (`MetaSync`) 与文献物理资源批量处理 (`AssetSync`) 的业务同步引擎。
- **[src/services/download.rs](../src/services/download.rs)**:
- 包含浏览器头伪装与请求延迟控制。
- 处理 ADS Link Gateway 路由重定向追踪与 `validate.perfdrive.com` 防护解码绕过。
- 实现官方 `arxiv.org/html` 优先及 `ar5iv` 兜底,自动去除版本号后缀。
- **[src/services/parser.rs](../src/services/parser.rs)**:
- 实现 HTML 语法树向 GFM Markdown 的逆向转换,使用占位符保护机制防止 MathJax/LaTeX 公式被误解析。
- 统一相对图表链接,并集成 MinerU PDF 解析。
- **[src/services/translation.rs](../src/services/translation.rs)**:
- 利用本地千万字级别的天文学双语词典对原文进行分词匹配,注入系统提示词让 LLM 实现学术级精细翻译。
- **[src/services/logging.rs](../src/services/logging.rs)**:
- 全局日志记录系统,基于 `tracing-subscriber` 实现了控制台美化日志输出与基于时间的每日滚动日志文件写出,使用上海时区 (+08:00) 格式化时间。
- **[dashboard/src/components/CitationGalaxyCanvas.tsx](../dashboard/src/components/CitationGalaxyCanvas.tsx)**:
- 基于原生 HTML5 Canvas 开发的轻量级、高性能力导向图星系物理引擎,用于文献引文网络拓扑结构的可视化渲染。
### 3.1 API 层 (`src/api/`)
| 模块文件 | 职责 |
|:---|:---|
| **[mod.rs](../src/api/mod.rs)** | 定义全局共享状态 `AppState`(含 `active_bibcode` 追踪)和统一文献格式 `StandardPaper`(含 `pdf_error` / `html_error` 诊断字段),通过 `pub mod handlers` 保持向后兼容命名空间。 |
| **[helpers.rs](../src/api/helpers.rs)** | 共享工具函数:`convert_ads_doc_to_standard``convert_arxiv_to_standard``save_paper_to_db``get_paper_from_db``check_paper_paths_in_db`。负责数据库 CRUD 和 `error:` 前缀诊断信息的读取与解析。 |
| **[papers.rs](../src/api/papers.rs)** | 文献相关核心处理器:统一检索 (`search_papers`)、下载 (`download_paper`)、**手动上传 (`upload_paper_file`)**、**无资源标记 (`mark_no_resource`)**、解析 (`parse_paper`)、翻译 (`translate_paper`)、引文拓扑 (`get_citation_network`)、文献详情 (`get_paper_detail`)、馆藏列表 (`get_library`)、BibTeX 导出 (`export_citations`)、**活跃文献追踪 (`get/set_active_bibcode`)**。 |
| **[notes.rs](../src/api/notes.rs)** | 笔记 CRUD 处理器:创建 (`create_note`)、查询 (`get_notes`)、删除 (`delete_note`)。 |
| **[sync.rs](../src/api/sync.rs)** | 批量同步控制处理器:元数据同步启动/状态/计数、资源同步启动/停止/状态、检索条件管理。 |
### 3.2 服务层 (`src/services/`)
| 模块文件 | 职责 |
|:---|:---|
| **[batch/mod.rs](../src/services/batch/mod.rs)** | 批量同步引擎公共导出模块。 |
| **[batch/meta.rs](../src/services/batch/meta.rs)** | 元数据大批量采集引擎 (`MetaSync`):分页检索 ADS/arXiv 并增量入库。 |
| **[batch/asset.rs](../src/services/batch/asset.rs)** | 物理资源批量处理引擎 (`AssetSync`):后台异步执行下载/解析/翻译流水线,记录 `download_failed` / `parse_failed` 计数,保留最新 100 条日志。 |
| **[download.rs](../src/services/download.rs)** | 多通道下载器:浏览器头伪装与请求延迟控制、ADS Link Gateway 重定向追踪与 `validate.perfdrive.com` 防护解码绕过、官方 `arxiv.org/html` 优先及 `ar5iv` 兜底、**下载失败时以 `error:` 前缀记录诊断信息至数据库**。 |
| **[parser.rs](../src/services/parser.rs)** | HTML 语法树向 GFM Markdown 逆向转换,使用占位符保护 LaTeX 公式;统一图表链接;集成 MinerU PDF 解析。 |
| **[translation.rs](../src/services/translation.rs)** | 基于本地天文双语词典的 Trie 树最长匹配分词,注入 Glossary 系统提示词让 LLM 实现学术级精细翻译。 |
| **[query_parser.rs](../src/services/query_parser.rs)** | 高级检索语法解析器,将前端组合条件(AND/OR/NOT + 字段限定)转换为 ADS API 查询语法。 |
| **[logging.rs](../src/services/logging.rs)** | 全局日志记录系统,基于 `tracing-subscriber` 实现控制台美化日志输出与基于时间的每日滚动日志文件写出,使用上海时区 (+08:00) 格式化时间。 |
### 3.3 客户端层 (`src/clients/`)
| 模块文件 | 职责 |
|:---|:---|
| **[ads.rs](../src/clients/ads.rs)** | NASA ADS API 客户端:文献检索、元数据获取、BibTeX 导出。 |
| **[arxiv.rs](../src/clients/arxiv.rs)** | arXiv Atom XML API 客户端:解析 XML Feed 提取文献元数据。 |
| **[qiniu.rs](../src/clients/qiniu.rs)** | 七牛云对象存储客户端:PDF 插图上传与 CDN 外链生成。 |
### 3.4 独立工具 (`src/bin/`)
| 文件 | 职责 |
|:---|:---|
| **[health_check.rs](../src/bin/health_check.rs)** | 馆藏健康度诊断与修复工具:检测损坏文件、丢失文件、`error:` 报错记录和孤立 Markdown`--fix` 模式自动清理并重置数据库状态。 |
### 3.5 前端核心组件 (`dashboard/src/`)
| 组件文件 | 职责 |
|:---|:---|
| **[App.tsx](../dashboard/src/App.tsx)** | 全局状态管理:Tab 持久化、手动上传处理、无资源标记、活跃文献追踪、详情弹窗(含错误诊断和上传区)。 |
| **[components/CustomSelect.tsx](../dashboard/src/components/CustomSelect.tsx)** | 可复用下拉选择组件:统一视觉风格、点击外部关闭、选中高亮。 |
| **[components/CitationGalaxyCanvas.tsx](../dashboard/src/components/CitationGalaxyCanvas.tsx)** | 基于 HTML5 Canvas 的自研力导向引文星系图谱引擎:节点排斥力、中心引力、拖拽阻尼、双击多层级衍生。 |
| **[features/library/LibraryPanel.tsx](../dashboard/src/features/library/LibraryPanel.tsx)** | 馆藏管理面板:同步反馈、下载失败/无资源状态筛选、文献类型筛选(13 种)、状态优先排序。 |
| **[features/search/SearchPanel.tsx](../dashboard/src/features/search/SearchPanel.tsx)** | 跨源检索面板:高级组合条件、排序分页、下载失败状态提示、文献类型徽章(16 种)。 |
| **[features/sync/SyncPanel.tsx](../dashboard/src/features/sync/SyncPanel.tsx)** | 批量同步控制台:乐观 UI 更新、容器内日志自动滚动。 |
+40 -3
View File
@@ -30,21 +30,43 @@
---
## 2. 编码规范 (Coding Style Guidelines)
## 2. 项目结构约定 (Project Structure Conventions)
### 后端模块化架构
后端代码已从单文件架构重构为模块化架构:
- **API 层** (`src/api/`):按职责拆分为 `papers.rs`(文献相关)、`notes.rs`(笔记相关)、`sync.rs`(同步相关)、`helpers.rs`(共享工具),通过 `mod.rs` 统一暴露 `AppState`、`StandardPaper` 和向后兼容的 `handlers` 命名空间。
- **服务层** (`src/services/`):批量同步引擎从单文件 `batch_sync.rs` 拆分为 `batch/mod.rs` + `meta.rs` + `asset.rs`,同时通过 `pub mod batch_sync` 保持路径兼容。
- **独立工具** (`src/bin/`)`health_check.rs` 作为独立二进制程序,可直接运行。
### 前端组件化架构
- **可复用组件** (`components/`)`CustomSelect` 替代所有原生 `<select>`,保持视觉一致性。
- **功能模块** (`features/`):按功能域划分(search、library、reader、citation、sync、settings)。
- **类型定义** (`types.ts`):集中管理所有接口类型,与后端 `StandardPaper` 结构体保持同步。
---
## 3. 编码规范 (Coding Style Guidelines)
### Rust 规范 (Backend)
- 遵循 Rust 官方标准样式,提交前必须执行 `cargo fmt` 与 `cargo clippy`。
- 注释和系统日志建议统一使用中文,便于开发者追踪 and 阅读。
- 注释和系统日志建议统一使用中文,便于开发者追踪阅读。
- API handlers 中的异常信息请使用 `anyhow` 或 `thiserror` 进行结构化抛出。
- **模块化原则**:API 层按职责拆分文件(papers / notes / sync / helpers),避免单文件过大(目标 <800 行)。
- **错误诊断约定**:下载失败时使用 `error:` 前缀存入 `pdf_path` / `html_path`,便于前端和 `health_check` 工具解析。
### React & TypeScript 规范 (Frontend)
- 严格遵循 `React 18/19` 函数式组件写法,使用 React Hooks 维护状态。
- 为保证生产编译成功,务必开启类型安全限制(如在导入纯类型时显式使用 `import type { ... }`)。
- CSS 层面使用 Tailwind CSS 统一的高对比度浅色纯中文控制台风格,所有布局、间距、颜色需遵循实边框、高对比度黑白字及高雅按钮样式(`.btn-console` 等),以保障学术沉浸与阅读的高保真性。
- **下拉选择器统一使用 `CustomSelect` 组件**,不要使用原生 `<select>`。
- **新增 API 字段**:后端 `StandardPaper` 新增字段时,必须同步更新 `dashboard/src/types.ts` 中的 `StandardPaper` 接口。
---
## 3. 测试与验证 (Testing)
## 4. 测试与验证 (Testing)
### 运行后端单元测试
系统为各个下载、解析、词典分词、接口提取等模块设计了健全的测试。运行测试命令:
@@ -58,3 +80,18 @@ cd dashboard
npm run build # 运行 TypeScript 类型检查及 Vite 打包编译
```
确保无编译 Error 或 Warn 警告后方可提交 PR。
### 运行健康检查工具
提交前建议对本地馆藏运行健康检查,确保功能正常:
```bash
cargo run --bin health_check
```
---
## 5. 数据库迁移 (Database Migrations)
添加新的数据库字段或表时,需在 `migrations/` 目录下创建新的迁移脚本:
1. 文件命名格式:`YYYYMMDDHHMMSS_description.sql`
2. 迁移脚本会在 `cargo run` 启动时自动执行
3. 新增字段需同时在后端 `StandardPaper` 结构体和前端 `types.ts` 中同步更新
+45 -7
View File
@@ -1,6 +1,6 @@
# AstroResearch Database Schema / 数据库设计
AstroResearch 使用轻量级、零配置的 **SQLite** 数据库作为持久化存储。数据库文件默认保存在项目根目录下的 `astro_research.db`,由 Rust 中的 `sqlx` 驱动管理并自动执行迁移。
AstroResearch 使用轻量级、零配置的 **SQLite** 数据库作为持久化存储。数据库文件默认保存在项目根目录下的 `astro_research.db`(可通过 `.env` 中的 `DATABASE_URL` 配置),由 Rust 中的 `sqlx` 驱动管理并自动执行迁移。
---
@@ -20,10 +20,11 @@ erDiagram
text arxiv_id
integer citation_count
integer reference_count
text pdf_path
text html_path
text markdown_path
text translation_path
text doctype "文献类型"
text pdf_path "PDF 物理路径 或 error:诊断"
text html_path "HTML 物理路径 或 error:诊断"
text markdown_path "Markdown 物理路径"
text translation_path "翻译文件物理路径"
datetime created_at
}
@@ -42,6 +43,16 @@ erDiagram
text target_bibcode PK
}
SYNC_QUERIES {
integer id PK
text query "检索关键词"
text source "数据源"
integer limit_count "拉取上限"
datetime last_run "最近运行时间"
datetime created_at "创建时间"
UNIQUE_query_source_limit "唯一去重约束"
}
PAPERS ||--o{ NOTES : "has"
PAPERS ||--o{ CITATIONS_REFERENCES : "cites / cited_by"
```
@@ -52,6 +63,9 @@ erDiagram
### 2.1 papers 表 (文献元数据)
存储文献的核心元数据和本地物理存储路径。
- **特殊字段说明**
- `pdf_path` / `html_path`:正常情况下存储相对路径(如 `library/PDF/2024arXiv.pdf`)。当下载失败时,会以 `error:` 前缀存储诊断信息(如 `error:Cloudflare 拦截`)。特殊值 `error:no_resource` 表示用户手动标记了"无有效全文资源"。
- `doctype`:文献类型标识,如 `article``eprint``proceedings``phdthesis``catalog``software``circular``book` 等。
- **索引**
- `idx_papers_doi` -> 基于 `doi`
- `idx_papers_arxiv_id` -> 基于 `arxiv_id`
@@ -69,9 +83,33 @@ erDiagram
- **索引**
- `idx_notes_bibcode` -> 优化单篇文献的笔记列表查询。
### 2.4 sync_queries 表 (同步检索条件)
存储用户保存的批量同步检索条件,支持快速重新同步。
- **唯一约束**`UNIQUE(query, source, limit_count)` 确保相同条件的检索不会重复保存。
---
## 3. 数据库迁移说明
迁移脚本存放在 `migrations/` 下,服务启动时(`src/main.rs`)会自动调用 `sqlx::migrate!().run(&pool).await` 自动部署:
1. `20260608000000_init.sql`:初始化 `papers``citations_references` 结构。
2. `20260608000001_notes.sql`:添加 `notes` 笔记高亮表,并为关联建立级联删除。
| 迁移文件 | 说明 |
|:---|:---|
| `20260608000000_init.sql` | 初始化 `papers``citations_references` 结构。 |
| `20260608000001_notes.sql` | 添加 `notes` 笔记高亮表,并为关联建立级联删除。 |
| `20260608000002_add_doctype.sql` | 为 `papers` 表新增 `doctype` 文献类型字段。 |
| `20260608000003_sync_features.sql` | 添加 `sync_queries` 同步检索条件表,支持唯一去重。 |
---
## 4. 错误诊断存储约定
系统使用 `papers` 表的 `pdf_path``html_path` 字段的双重语义来同时存储正常路径和错误诊断:
| 字段值模式 | 含义 | 前端展示 |
|:---|:---|:---|
| `NULL` | 尚未尝试下载 | 琥珀色"未下载"角标 |
| `library/PDF/xxx.pdf` | 下载成功,正常物理路径 | 蓝色"已下载"角标 |
| `error:具体原因` | 下载失败,原因为前缀后的文本 | 红色"下载失败"角标,悬浮显示原因 |
| `error:no_resource` | 用户手动标记为无有效全文资源 | 灰色"无资源"角标 |
`health_check` 工具在 `--fix` 模式下会清理损坏文件并将路径重置为 `NULL`,但**不会**清除 `error:` 前缀的记录(以保留诊断线索)。
+43
View File
@@ -32,6 +32,13 @@ cargo build --release
```
编译产物位于 `target/release/astroresearch`
### 步骤 3(可选):编译健康检查工具
如需在目标服务器上运行馆藏健康度诊断与修复:
```bash
cargo build --release --bin health_check
```
编译产物位于 `target/release/health_check`
---
## 3. 服务部署与启动 (Running in Production)
@@ -44,3 +51,39 @@ cargo build --release
./astroresearch
```
5. 进程将默认在后台启动并监听 `http://localhost:8000` 端口。你可以通过 Nginx 将此端口反向代理到公网 80/443 端口。
---
## 4. 环境变量配置 (Environment Variables)
| 变量名 | 必需 | 默认值 | 说明 |
|:---|:---|:---|:---|
| `DATABASE_URL` | 否 | `sqlite://library/astro_research.db` | SQLite 数据库连接 URL |
| `ADS_API_KEY` | 是 | - | NASA ADS API 访问 Token |
| `LLM_API_KEY` | 是 | - | 大语言模型 API Key |
| `LLM_API_BASE` | 否 | `https://api.openai.com/v1` | 大语言模型 API 基础地址 |
| `LLM_MODEL` | 否 | `gpt-4o-mini` | 翻译大模型名称 |
| `QINIU_AK` | 否 | - | 七牛云 Access Key |
| `QINIU_SK` | 否 | - | 七牛云 Secret Key |
| `QINIU_BUCKET` | 否 | - | 七牛云存储空间名 |
| `QINIU_DOMAIN` | 否 | - | 七牛云外链 CDN 域名 |
| `MINERU_API_URL` | 否 | - | MinerU PDF 解析远程 API 地址 |
| `MINERU_API_KEY` | 否 | - | MinerU API Token |
| `LIBRARY_DIR` | 否 | `./library` | 本地文献馆藏根目录 |
| `PORT` | 否 | `8000` | 后端服务监听端口 |
---
## 5. 健康检查与维护 (Health Check)
部署后可定期运行健康检查工具排查馆藏一致性问题:
```bash
# 只读扫描(不修改任何数据)
./health_check
# 自动修复(清理损坏文件、重置无效路径)
./health_check -- --fix
```
详见 [排障指南 §4.2](troubleshooting.md#42-馆藏文献健康度检查工具-health_check)。
+56 -1
View File
@@ -1,6 +1,6 @@
# AstroResearch Design Systems / 设计系统与交互体验
AstroResearch 的前端界面设计坚持未来科技感与学术沉浸的理念,结合了现代网页设计的高级质感。
AstroResearch 的前端界面设计坚持"未来科技感与学术沉浸"的理念,结合了现代网页设计的高级质感。
---
@@ -15,6 +15,40 @@ AstroResearch 前端目前重构并统一为**高对比度浅色纯中文学术
| **主背景** | 纯净冷灰白 (`#f1f5f9`) | 深石板灰/接近纯黑 (`#0f172a`) | 控制台按钮 (`.btn-console` / `.btn-console-primary`) | 扁平极简实边框设计 |
| **卡片/容器** | 纯白背景 (`#ffffff`),实线灰色边框 (`#e2e8f0`) | 辅助灰 (`#64748b`) | 指示灯:深宝石绿 (就绪) / 灰石色 (未解析) | 微卡片投影效果 |
### 1.2 文献状态色彩编码
馆藏面板中的文献卡片使用统一的角标色彩编码来区分不同状态:
| 状态 | 背景色 | 文本色 | 含义 |
|:---|:---|:---|:---|
| **已翻译** | 翡翠绿 `bg-emerald-50` | `text-emerald-700` | 文献已解析并完成中英对照翻译 |
| **已解析** | 天蓝 `bg-sky-50` | `text-sky-700` | 文献正文已解析为 Markdown |
| **已下载** | 靛蓝 `bg-indigo-50` | `text-indigo-700` | PDF/HTML 物理文件已下载 |
| **未下载** | 琥珀 `bg-amber-50` | `text-amber-700` | 尚未开始下载 |
| **下载失败** | 玫瑰红 `bg-rose-50` | `text-rose-700` | 自动下载失败,悬浮显示原因 |
| **无资源** | 石板灰 `bg-slate-100` | `text-slate-600` | 用户手动标记为无全文资源 |
### 1.3 文献类型徽章
检索与馆藏面板中的文献类型徽章采用差异化色彩编码,当前支持 16 种文献类型:
| 类型 | 中文标签 | 色彩 |
|:---|:---|:---|
| article | 期刊文章 | 天蓝 |
| eprint | 预印本 | 紫色 |
| proceedings / inproceedings | 会议论文/集 | 橙色 |
| proposal | 观测提案 | 玫瑰红 |
| abstract | 会议摘要 | 石板灰 |
| catalog / dataset | 星表数据 | 靛蓝 |
| software | 软件代码 | 青绿 |
| phdthesis / mastersthesis | 博士/硕士论文 | 青色 |
| circular | 天文电报 | 橙色 |
| book / inbook | 学术专著/图书章节 | 翡翠绿 |
| editorial | 期刊社论 | 石板灰 |
| erratum | 勘误说明 | 红色 |
| techreport | 技术报告 | 青色 |
| 其他 | 其他文献 | 默认灰 |
---
## 2. 核心交互组件 (Key Interactive Components)
@@ -42,3 +76,24 @@ graph LR
- **结构化排版**:中英文双栏段落基准对齐,完美融合 `rehype-katex` 数学公式渲染和 `html2md` 图片嵌入。
- **划词标注与高亮**:鼠标选中阅读器任意段落词句,即刻浮现气泡菜单(支持 4 种高亮配色)。
- **浮动词汇浮屠**:检测到英文正文中含有天文学专业词汇时,自动显示下划线,悬浮可阅读中文释义对照。
### 2.3 CustomSelect 可复用下拉组件
- **替代原生 `<select>`**:所有下拉选择器(状态筛选、类型筛选、排序方式、检索条件组合、分页条数等)统一使用自研 `CustomSelect` 组件。
- **交互特性**
- 点击外部区域自动关闭
- 选中项高亮显示
- 展开/收起过渡动画
- 与 Tailwind CSS 控制台风格完全融合
- 支持禁用状态
### 2.4 馆藏管理面板 (Library Panel)
- **多维度筛选**:支持按任务状态(全部/已下载/已解析/已翻译/未下载/下载失败/无资源)、文献类型(13 种)及高级元数据(作者/年份/期刊)组合筛选。
- **状态优先排序**:默认排序按处理状态降序(已翻译 > 已解析 > 已下载 > 其他),状态相同时按导入时间排列。
- **同步反馈**:点击"重新同步馆藏"按钮后显示加载动画和成功/失败反馈条。
- **搜索一键清空**:检索输入框右侧提供清空按钮。
### 2.5 文献详情弹窗 (Paper Detail Dialog)
- **下载错误诊断**:当文献存在下载失败记录时,弹窗底部展示红色诊断区域,分别显示 PDF 和 HTML 的具体失败原因。
- **无资源标记**:当文献被标记为"无有效全文资源"时,显示琥珀色提示区域,并提供"恢复自动下载"按钮。
- **手动文件上传区**:底部提供 PDF 和 HTML 两个拖拽/点击上传区域,支持绕过防爬限制手动导入文献文件。
- **外链活跃追踪**:点击 Bibcode/DOI/arXiv 外部链接时自动上报活跃文献 Bibcode,用于浏览器书签直推场景。
+45 -3
View File
@@ -12,11 +12,25 @@
1. 系统目前已经实现每两次请求间随机延迟 `maybe_delay()` (500ms~2000ms),以防行为过于机械化。
2. 若拦截频繁,可以尝试在本地配置代理;或者检查 `.env` 中的 `LIBRARY_DIR` 路径是否正确。
3. 对于 ADS Link Gateway 路由,若跳转至 `validate.perfdrive.com`,下载器内置了解码 `ssc` 提取直链的策略,该过程自动进行,如果由于其加密机制变更导致提取失效,系统控制台会输出 `warn` 日志。
4. 下载失败后,系统会在数据库中自动记录以 `error:` 前缀的诊断信息。前端文献卡片会以红色角标标识"下载失败",鼠标悬浮可查看具体失败原因。
### 1.2 官方 HTML (arxiv.org/html) 下载返回 404
- **原因**arXiv 官方 HTML 正文服务仅在 **2023年12月** 之后提交的论文中默认提供。对于老文献,直接请求官方 HTML 会返回 404。
- **解决机制**AstroResearch 的 `download_arxiv_html_with_fallback` 会在官方 HTML 请求失败时,**自动无缝降级回退**到 `ar5iv.labs.arxiv.org` 服务进行拉取。
### 1.3 通过手动上传或浏览器书签直推绕过 Cloudflare 防爬
- **原因**:部分出版商对自动化脚本下载防范严密,直接通过后台任务下载容易导致获取失败(并在数据库中存入带有 `error:` 前缀的报错描述)。
- **解决方法**
1. **方案 A (详情弹窗手动上传)**:在文献详情弹窗中,点击文献直链(系统会使用您本人的真实浏览器和网络环境打开源站),手动下载 PDF 或 HTML,然后拖拽/上传至详情弹窗对应的上传区。
2. **方案 B (书签直推导入)**:在批量同步面板底部,点击"添加导入书签"按钮,或将其直接拖拽至您的浏览器书签栏(书签名为"导入AstroResearch")。当您使用真实浏览器访问文献源站(如 arXiv 页面)时,点击该书签,在弹出的窗口中确认 Bibcode,即可直接将解析后的内容通过 API 直推同步到本地。
### 1.4 标记文献为"无有效全文资源"
- **原因**:部分文献(如会议摘要、天文电报、观测提案等)本身不存在可下载的全文 PDF/HTML,反复尝试下载会浪费时间。
- **解决方法**
1. 在文献详情弹窗底部,点击"标记为无有效全文资源"按钮。
2. 标记后,文献卡片角标变为灰色"无资源"状态,后续批量下载/解析任务将自动跳过此文献。
3. 若需恢复,再次点击"恢复自动下载状态"按钮即可清除标记。
---
## 2. 文献解析与翻译问题 (Parse & Translation Issues)
@@ -39,11 +53,18 @@
### 3.1 无法通过特定的 arXiv ID 或 DOI 检索到已导入的文献
- **原因**:历史版本前端本地检索仅匹配了文献的标题、作者、摘要和 `bibcode`,未对 `arxiv_id``doi` 进行全局检测过滤。
- **排障/解决**:现已在馆藏过滤逻辑中追加了 `arxiv_id``doi` 的字段检索。如果遇到由于升级导致的缓存错乱,可点击顶部的 重新同步馆藏 刷新本地缓存状态。
- **排障/解决**:现已在馆藏过滤逻辑中追加了 `arxiv_id``doi` 的字段检索。如果遇到由于升级导致的缓存错乱,可点击顶部的 "重新同步馆藏" 刷新本地缓存状态。
### 3.2 文献详情页的 BIBCODE 与 ARXIV ID 显示完全相同的值(如均显示 '0710.0600'
- **原因**:当文献通过 arXiv 单独直接导入时,后端处理器无法预知其关联的 ADS Bibcode。为确保数据一致,系统在 SQLite 中临时将 `bibcode``arxiv_id` 均用 arXiv ID 填充,直到后续 ADS 元数据同步匹配成功将其升级
- **解决机制**:前端已实现了防重与标识规整机制。如果检测到 `bibcode === arxiv_id`,卡片页将前缀格式化为 `arXiv:xxxx.xxxx` 形式,而文献元数据详情弹窗中 `BIBCODE` 则会直接优雅呈现为 **暂无** 状态,避免视觉歧义。
- **原因**:当文献通过 arXiv 单独直接导入时,后端处理器无法预知其关联的 ADS Bibcode。为确保数据一致,系统在 SQLite 中临时将 `bibcode``arxiv_id` 均用 arXiv ID 填充,直到后续 ADS 元数据同步匹配成功将其"升级"
- **解决机制**:前端已实现了防重与标识规整机制。如果检测到 `bibcode === arxiv_id`,卡片页将前缀格式化为 `arXiv:xxxx.xxxx` 形式,而文献元数据详情弹窗中 `BIBCODE` 则会直接优雅呈现为 **"暂无"** 状态,避免视觉歧义。
### 3.3 馆藏面板"重新同步馆藏"按钮点击后没有反馈
- **原因**:早期版本中同步操作是异步静默执行的,用户无法感知操作进度。
- **解决机制**:当前版本已增加同步反馈机制:
- 点击按钮后显示加载动画(旋转图标 + "正在同步..." 文字)。
- 同步完成后弹出绿色成功提示条(显示馆藏数量),或红色错误提示条。
- 反馈信息 3 秒后自动消失。
---
@@ -54,3 +75,24 @@
- **解决方法**
1. 备份并临时删除根目录下的 `astro_research.db` 数据库文件。
2. 重新启动服务:`cargo run`,系统将重新执行 `migrations/` 下的全部 SQL 迁移脚本以建立最新库结构。
### 4.2 馆藏文献健康度检查工具 (health_check)
- **原因**:大批量文献下载、解析或手动增删物理文件后,可能存在数据库状态与物理文件不一致的情况。
- **排障与修复步骤**
1. **只读扫描**:运行 `cargo run --bin health_check`。此操作将扫描本地物理文件并验证它们是否损坏,检测数据库是否有丢失物理文件、报错记录(以 `error:` 开头)或孤立 Markdown 的文献。
2. **一键修复**:运行 `cargo run --bin health_check -- --fix` 执行修复:
- 系统将自动**删除磁盘上损坏的 PDF/HTML 物理文件**,并在数据库中将其重置为 `NULL` 以便后续重新触发下载。
- 系统将自动**删除孤立的 Markdown 物理文件**并将其重置为 `NULL`
- **特别注意**:对于数据库中已存入的 `error:` 报错诊断信息,为了保留报错排障的有用线索,**修复程序不会删除这些报错记录**(即不会重置为 `NULL`),以便您后续查看与手动上传修复。
---
## 5. 前端界面问题 (Frontend UI Issues)
### 5.1 下拉选择框样式与浏览器原生样式不一致
- **原因**:系统使用自研的 `CustomSelect` 组件替代了原生 `<select>` 元素,以实现统一的视觉风格和交互体验。
- **说明**:所有下拉框(状态筛选、文献类型筛选、排序方式、检索条件组合等)均已统一使用 `CustomSelect` 组件,支持点击外部自动关闭、选中项高亮等交互。
### 5.2 同步面板日志自动滚动干扰全页浏览
- **原因**:早期版本中日志自动滚动使用 `scrollIntoView` 会影响整个页面。
- **解决机制**:当前版本改为仅滚动日志容器内部元素,并增加了 80px 的阈值判断,只有当用户处于接近底部的阅读位置时才自动滚动追踪最新日志。