mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
355 lines
15 KiB
Markdown
355 lines
15 KiB
Markdown
# 微信读书数据展示网站 - 技术文档
|
||
|
||
> 版本:2.0.0 | 更新时间:2026-07-17 | 作者:WorkBuddy | 数据模型版本:v2.0(31 表)
|
||
|
||
---
|
||
|
||
## 1. 项目概述
|
||
|
||
### 1.1 项目简介
|
||
|
||
本项目是一个个人读书数据展示网站,数据来源于微信读书。通过微信读书 API 拉取用户的阅读数据(书架、阅读统计、笔记等),存入本地数据库,并通过 Web 仪表盘进行可视化展示。
|
||
|
||
### 1.2 核心功能
|
||
|
||
| 模块 | 功能说明 |
|
||
|------|----------|
|
||
| 数据采集 | 从微信读书 API 拉取书架、阅读统计、笔记本数据,存入本地数据库 |
|
||
| 总览仪表盘 | 累计阅读时长、阅读天数、藏书量、笔记数等核心指标 |
|
||
| 数据图表 | 年度阅读趋势(柱状图)、24h 时段分布(折线图)、偏好分类(饼图)、偏好作者(条形图) |
|
||
| 读书排行 | 阅读时长最久的 20 本书卡片展示 |
|
||
| 书架 | 404 本书的网格展示,支持分类筛选和"仅看已读完" |
|
||
| 笔记概览 | 有笔记的书籍列表,点击查看划线和想法详情 |
|
||
| 书籍详情 | 点击书架书籍弹出详情(书名、作者、出版社、ISBN、评分、阅读进度) |
|
||
| 笔记详情 | 点击笔记书籍查看划线(按章节分组)和想法/点评 |
|
||
| 推荐页面 | 个性化推荐书籍 + 关键词搜索,数据入库 |
|
||
|
||
### 1.3 技术栈
|
||
|
||
| 层级 | 技术 | 说明 |
|
||
|------|------|------|
|
||
| 前端 | HTML5 + CSS3 + 原生 JavaScript | 无框架依赖,轻量高效 |
|
||
| 图表 | ECharts 5.5.0 | 年度趋势、时段分布、分类饼图、作者排行 |
|
||
| 后端 | Python Flask | 轻量级 Web 框架,提供 RESTful API |
|
||
| 数据库 | MySQL 5.7+(主)/ SQLite(采集) | MySQL 为生产数据库,31 张表完整覆盖官方 API,SQLite 用于数据采集中间存储 |
|
||
| 数据采集 | 微信读书 Agent Gateway API | 通过 weread-skills 技能提供的 API 接口,覆盖 8 份官方 API 文档 |
|
||
| 版本控制 | Git | dev 分支开发,master 分支发布,遵循 Conventional Commits |
|
||
|
||
---
|
||
|
||
## 2. 系统架构
|
||
|
||
### 2.1 整体架构图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 用户浏览器(前端) │
|
||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||
│ │ 总览仪表盘│ │ 数据图表 │ │ 书架列表 │ │ 推荐搜索 │ │
|
||
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
|
||
│ │ │ │ │ │
|
||
│ └───────────┴─────┬─────┴───────────┘ │
|
||
│ │ │
|
||
│ ┌────────▼────────┐ │
|
||
│ │ 健康检查模块 │ │
|
||
│ │ (MySQL 连接检测) │ │
|
||
│ └────────┬────────┘ │
|
||
└─────────────────────────┼───────────────────────────────┘
|
||
│ HTTP / RESTful API
|
||
┌─────────────────────────┼───────────────────────────────┐
|
||
│ Flask 后端服务 │
|
||
│ │ │
|
||
│ ┌──────────────────────▼──────────────────────┐ │
|
||
│ │ API 路由层 │ │
|
||
│ │ /api/overview /api/shelf /api/book/detail │ │
|
||
│ │ /api/recommend /api/search /api/health ... │ │
|
||
│ └──────────────────────┬──────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────▼──────────────────────┐ │
|
||
│ │ db_required 装饰器 │ │
|
||
│ │ (连接管理 + 错误处理 + 503 告警) │ │
|
||
│ └──────────────────────┬──────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────▼──────────────────────┐ │
|
||
│ │ PyMySQL 数据访问层 │ │
|
||
│ └───────────┬──────────────────┬──────────────┘ │
|
||
│ │ │ │
|
||
│ ┌───────────▼─────┐ ┌────────▼─────────┐ │
|
||
│ │ MySQL 数据库 │ │ 微信读书 API 代理 │ │
|
||
│ │ weread_dashboard│ │ (按需获取+入库) │ │
|
||
│ └─────────────────┘ └──────────────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
│
|
||
┌─────────────────────────┼───────────────────────────────┐
|
||
│ 数据采集层(独立运行) │
|
||
│ ┌──────────────────────▼──────────────────────┐ │
|
||
│ │ fetch_data.py 采集脚本 │ │
|
||
│ │ 拉取书架/统计/笔记 → SQLite → migrate_to_mysql│ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.2 数据流设计
|
||
|
||
```
|
||
微信读书 API
|
||
│
|
||
▼
|
||
fetch_data.py(采集脚本)
|
||
│
|
||
▼
|
||
weread.db(SQLite 中间存储)
|
||
│
|
||
▼
|
||
migrate_to_mysql.py(迁移脚本)
|
||
│
|
||
▼
|
||
MySQL weread_dashboard(生产数据库)
|
||
│
|
||
▼
|
||
Flask app.py(后端服务,端口 8080)
|
||
│
|
||
▼
|
||
前端页面(ECharts 可视化)
|
||
```
|
||
|
||
**按需数据流**(用户点击书籍/笔记时):
|
||
|
||
```
|
||
用户点击 → Flask API → 微信读书 API(实时获取)→ 入库 MySQL → 返回前端
|
||
↓(API 失败时)
|
||
从 MySQL 读取缓存数据 → 返回前端
|
||
```
|
||
|
||
### 2.3 目录结构
|
||
|
||
```
|
||
weread-dashboard/
|
||
├── app.py # Flask 后端服务(MySQL 数据源)
|
||
├── fetch_data.py # 数据采集脚本(SQLite)
|
||
├── migrate_to_mysql.py # SQLite → MySQL 数据迁移脚本
|
||
├── schema_mysql.sql # MySQL 建表语句(含中文注释)
|
||
├── requirements.txt # Python 依赖
|
||
├── weread.db # SQLite 数据库文件(采集中间存储)
|
||
├── README.md # 项目说明
|
||
├── docs/ # 文档目录
|
||
│ ├── TECHNICAL_DOC.md # 技术文档(本文件)
|
||
│ └── METADATA_DOC.md # 元数据文档
|
||
├── templates/
|
||
│ └── index.html # 前端页面
|
||
└── static/
|
||
├── css/
|
||
│ └── style.css # 样式文件
|
||
└── js/
|
||
└── app.js # 前端逻辑
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 后端 API 设计
|
||
|
||
### 3.1 API 接口列表
|
||
|
||
| 接口 | 方法 | 说明 | 数据来源 |
|
||
|------|------|------|----------|
|
||
| `/api/health` | GET | 健康检查(MySQL 连接状态) | MySQL |
|
||
| `/api/overview` | GET | 总览数据(核心指标) | MySQL |
|
||
| `/api/yearly-trend` | GET | 年度阅读时长时间序列 | MySQL |
|
||
| `/api/top-books` | GET | 阅读时长排行 TOP 20 | MySQL |
|
||
| `/api/categories` | GET | 偏好分类 | MySQL |
|
||
| `/api/authors` | GET | 偏好作者 TOP 20 | MySQL |
|
||
| `/api/time-distribution` | GET | 24 小时时段分布 | MySQL |
|
||
| `/api/shelf` | GET | 书架列表(分页) | MySQL |
|
||
| `/api/notebooks` | GET | 笔记本概览 | MySQL |
|
||
| `/api/read-stats` | GET | 阅读统计摘要 | MySQL |
|
||
| `/api/archives` | GET | 书单列表 | MySQL |
|
||
| `/api/book/detail` | GET | 书籍详情(按需) | 微信读书 API + MySQL |
|
||
| `/api/book/notes` | GET | 笔记详情(按需) | 微信读书 API + MySQL |
|
||
| `/api/recommend` | GET | 个性化推荐(按需) | 微信读书 API + MySQL |
|
||
| `/api/search` | GET | 搜索书籍(按需) | 微信读书 API + MySQL |
|
||
|
||
### 3.2 接口详情
|
||
|
||
#### 3.2.1 健康检查
|
||
|
||
```
|
||
GET /api/health
|
||
```
|
||
|
||
**响应(正常)**:
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"database": "connected",
|
||
"message": "MySQL 连接正常"
|
||
}
|
||
```
|
||
|
||
**响应(异常,HTTP 503)**:
|
||
```json
|
||
{
|
||
"status": "error",
|
||
"database": "disconnected",
|
||
"message": "MySQL 连接失败: ..."
|
||
}
|
||
```
|
||
|
||
#### 3.2.2 总览数据
|
||
|
||
```
|
||
GET /api/overview
|
||
```
|
||
|
||
**响应**:
|
||
```json
|
||
{
|
||
"total_read_time": 1223850,
|
||
"total_read_time_str": "339小时57分钟",
|
||
"read_days": 304,
|
||
"year_read_time": 849029,
|
||
"year_read_time_str": "235小时50分钟",
|
||
"year_read_days": 198,
|
||
"shelf_count": 404,
|
||
"finished_count": 12,
|
||
"notebook_count": 32,
|
||
"total_notes": 1709,
|
||
"regist_time": "2024-03-15",
|
||
"last_read_time": "2026-07-17",
|
||
"fetch_time": "2026-07-17 09:50:00"
|
||
}
|
||
```
|
||
|
||
#### 3.2.3 书架列表(分页)
|
||
|
||
```
|
||
GET /api/shelf?page=1&per_page=60&category=文学&finished=1
|
||
```
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
|------|------|--------|------|
|
||
| page | int | 1 | 页码 |
|
||
| per_page | int | 60 | 每页数量 |
|
||
| category | string | "" | 分类筛选(模糊匹配) |
|
||
| finished | string | "0" | "1"=只看已读完 |
|
||
|
||
#### 3.2.4 书籍详情(按需)
|
||
|
||
```
|
||
GET /api/book/detail?book_id=34615967
|
||
```
|
||
|
||
实时调用微信读书 `/book/info` + `/book/getprogress` API,入库后返回。API 失败时回退到数据库缓存。
|
||
|
||
#### 3.2.5 错误处理
|
||
|
||
所有 API 接口在 MySQL 连接失败时统一返回:
|
||
|
||
```
|
||
HTTP 503 Service Unavailable
|
||
{
|
||
"error": "数据库连接失败",
|
||
"detail": "具体错误信息",
|
||
"alert": "MySQL 数据库无法连接,请检查 MySQL 服务是否已启动。"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 关键设计决策
|
||
|
||
### 4.1 数据库选择
|
||
|
||
- **生产环境使用 MySQL**:支持并发访问、事务管理、完善的权限体系
|
||
- **采集层使用 SQLite**:轻量级,无需额外服务,适合单机数据采集
|
||
- **迁移脚本桥接**:`migrate_to_mysql.py` 负责 SQLite → MySQL 的数据同步
|
||
|
||
### 4.2 按需获取策略
|
||
|
||
书籍详情、笔记详情、推荐、搜索等数据采用**按需获取**策略:
|
||
- 用户点击时实时调用微信读书 API
|
||
- 获取成功后入库 MySQL 缓存
|
||
- API 调用失败时自动回退到数据库缓存
|
||
- 避免初始化时大量 API 调用,提升用户体验
|
||
|
||
### 4.3 健康检查与告警机制
|
||
|
||
- 后端提供 `/api/health` 接口检测 MySQL 连接状态
|
||
- 前端页面加载时首先调用健康检查
|
||
- 连接失败时显示固定告警横幅,阻止后续数据加载
|
||
- 使用 `db_required` 装饰器统一处理数据库连接异常
|
||
|
||
### 4.4 数据模型 v2.0 设计规范
|
||
|
||
基于微信读书官方 8 份 API 文档的完整字段分析,数据模型 v2.0 遵循以下设计规范:
|
||
|
||
**双列时间戳模式**:所有整型 Unix 时间戳字段(`INT UNSIGNED`)均伴随一个 `_dt TIMESTAMP` 列,例如 `update_time` ↔ `update_time_dt`。便于直接查询展示,同时保留原始时间戳用于排序和计算。
|
||
|
||
**审计列**:每张表统一维护 `created_at`(创建时间)和 `updated_at`(更新时间),使用 MySQL `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` 自动维护。
|
||
|
||
**索引设计原则**:
|
||
- 主键:业务主键优先(如 `book_id`),无自然主键时使用 `BIGINT AUTO_INCREMENT`
|
||
- 唯一约束:防止重复数据(如 `uk_highlights_bookmark(book_id, bookmark_id)`)
|
||
- 复合索引:按实际查询模式设计(如 `idx_highlights_chapter(book_id, chapter_uid)`)
|
||
- 排序索引:常用排序字段加 `DESC`(如 `idx_books_read_update_time(read_update_time DESC)`)
|
||
|
||
**表覆盖范围**:31 张表完整覆盖 8 份官方 API 文档:
|
||
- shelf.md → books, shelf_albums, shelf_meta, archives
|
||
- readdata.md → reading_stats, read_times, read_longest, read_stat_items, prefer_categories, prefer_authors, prefer_publishers, prefer_cps, prefer_books, prefer_time, read_rank, medals, year_reports
|
||
- notes.md → notebooks, book_highlights, book_chapters, book_reviews, book_best_bookmarks, book_underlines, public_reviews
|
||
- book.md → book_details, book_progress
|
||
- discover.md → recommended_books, similar_books
|
||
- search.md → search_sessions, search_results
|
||
- fetch_meta → 系统元信息
|
||
|
||
### 4.5 Git 分支策略
|
||
|
||
- **dev 分支**:日常开发,功能迭代
|
||
- **master 分支**:稳定发布版本,通过 `--no-ff` 合并 dev
|
||
- 提交信息遵循 **Conventional Commits** 规范(`feat:` / `fix:` / `merge:`)
|
||
|
||
---
|
||
|
||
## 5. 部署与运行
|
||
|
||
### 5.1 环境要求
|
||
|
||
- Python 3.13+
|
||
- MySQL 5.7+
|
||
- 微信读书 API Key(通过 `WEREAD_API_KEY` 环境变量配置)
|
||
|
||
### 5.2 启动步骤
|
||
|
||
```bash
|
||
# 1. 设置微信读书 API Key
|
||
export WEREAD_API_KEY=wrk-xxxxxxxx
|
||
|
||
# 2. 安装 Python 依赖
|
||
pip install flask pymysql
|
||
|
||
# 3. 启动 MySQL 服务
|
||
sudo /usr/local/mysql/support-files/mysql.server start
|
||
|
||
# 4. 创建数据库并建表
|
||
mysql -u root -p < schema_mysql.sql
|
||
|
||
# 5. 采集数据(首次)
|
||
python fetch_data.py
|
||
|
||
# 6. 迁移数据到 MySQL
|
||
python migrate_to_mysql.py
|
||
|
||
# 7. 启动 Web 服务
|
||
python app.py
|
||
# 访问 http://127.0.0.1:8080
|
||
```
|
||
|
||
### 5.3 数据更新
|
||
|
||
```bash
|
||
# 重新采集最新数据
|
||
python fetch_data.py
|
||
|
||
# 同步到 MySQL
|
||
python migrate_to_mysql.py
|
||
```
|