Files
WeReadBoard/.workbuddy/memory/2026-07-17.md
T

146 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-07-17 工作日志
## 微信读书数据展示网站
- 使用微信读书 API(weread-skills)拉取用户的阅读数据
- 数据采集脚本 `fetch_data.py`:拉取书架(404本)、阅读统计(overall+annually)、笔记本(32本1709条笔记)数据,存入本地 SQLite 数据库 `weread.db`
- Flask 后端 `app.py`(端口 8080),提供 8 个 API 接口:overview, yearly-trend, top-books, categories, authors, time-distribution, shelf, notebooks
- 前端页面:ECharts 图表(年度趋势柱状图、24h时段折线图、分类饼图、作者排行条形图)、书架网格(分页+筛选)、笔记概览
- 数据规模:累计阅读 339 小时 57 分钟、304 天阅读、404 本书架藏书、1709 条笔记
- 技术栈:Python Flask + SQLite + ECharts + 原生 HTML/CSS/JS
## 功能迭代(第二批)
- Git 仓库:dev 分支初版提交 + 功能迭代提交,master 分支 --no-ff 合并,遵循 conventional commits 规范
- 书籍详情弹窗:点击书架书籍实时调 /book/info + /book/getprogress API,展示详细信息+阅读进度,数据入库 book_details/book_progress 表
- 笔记详情弹窗:点击笔记书籍实时调 /book/bookmarklist + /review/list/mine API,划线按章节分组+想法/点评,数据入库 book_highlights/book_reviews/book_chapters 表
- 推荐页面:个性化推荐(/book/recommend)+ 关键词搜索(/store/search),数据入库 recommended_books/search_results 表
- 修复 Flask 中文 URL 参数编码问题(latin-1 -> utf-8 转码)
- MySQL 版本建表语句 schema_mysql.sql:18 张表完整 DDL,utf8mb4 字符集,含索引和字段注释
- 新增 7 张按需数据表:book_details, book_progress, book_highlights, book_chapters, book_reviews, recommended_books, search_results
## MySQL 迁移
- 启动本地 MySQL 5.7.31(通过 launchctl load com.oracle.oss.mysql.mysqld.plist)
- MySQL root 密码:258963
- 创建数据库 `weread_dashboard`(utf8mb4),执行 schema_mysql.sql 创建 18 张表
- 迁移脚本 `migrate_to_mysql.py`:SQLite -> MySQL 全量迁移,共 862 行数据
- 时间戳列自动转换(SQLite int -> MySQL TIMESTAMP)
- 中文内容 utf8mb4 完整保存,数据校验通过
- Flask 服务暂未切换至 MySQL(用户要求服务不重启)
## 第三批功能迭代(MySQL 切换 + 文档 + 告警)
- **数据源切换至 MySQL**:app.py 从 SQLite 全面切换到 PyMySQL,所有 API 读取 MySQL weread_dashboard 数据库
- **db_required 装饰器**:统一管理数据库连接和异常处理,MySQL 连接失败返回 HTTP 503
- **健康检查接口**:新增 /api/health,前端页面加载时优先检测 MySQL 连接状态
- **前端告警横幅**:MySQL 连接失败时显示黄色告警横幅,阻止后续数据加载
- **修复 fetched_at 兼容问题**:Unix 整数时间戳改为 MySQL TIMESTAMP 格式字符串
- **代码中文注释**:app.py 所有函数/API/工具函数添加完整中文文档注释;fetch_data.py 所有建表语句添加列级中文注释
- **技术文档** docs/TECHNICAL_DOC.md:项目概述、系统架构图、数据流设计、15 个 API 接口详情、部署指南
- **元数据文档** docs/METADATA_DOC.md:18 张表完整字段说明、索引设计、表关系 ER 图、数据类型规范
- Git 提交:dev 分支提交 → master 分支 --no-ff 合并
## 数据模型 v2.0 重构(第四批迭代)
- **官方 API 文档比对**:拉取 GitHub 上微信读书官方 8 份 API 文档(book.md, shelf.md, readdata.md, notes.md, discover.md, search.md, review.md, profile.md),逐字段对比发现 12 张缺失表、40+ 缺失字段
- **schema_mysql.sql 重写**:从 18 张表扩展到 31 张表,新增 shelf_albums, shelf_meta, prefer_publishers, prefer_cps, prefer_books, read_rank, medals, year_reports, book_best_bookmarks, book_underlines, public_reviews, similar_books, search_sessions
- **双列时间戳模式**:所有 INT UNSIGNED 时间戳字段均伴随 _dt TIMESTAMP 列(如 update_time ↔ update_time_dt)
- **审计列**:每张表统一维护 created_at + updated_at(MySQL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)
- **索引优化**:按实际查询模式设计复合索引、排序索引(如 idx_books_read_update_time DESC, uk_highlights_bookmark)
- **fetch_data.py 重写**:SKILL_VERSION 升级至 1.0.4,覆盖全部 31 张表数据采集,新增 ts_to_dt() 辅助函数
- **app.py 适配**:移除 ensure_tables(),新增 ts_to_dt_str(),所有 INSERT 语句适配新列名
- **migrate_to_mysql.py 重写**:支持 31 张表迁移
- **数据重建**:删除旧 weread.db + DROP MySQL 数据库,重建后采集 685 行数据(404 books, 32 notebooks, 20 publishers, 20 cps, 30 medals, 24 prefer_books 等)
- **文档更新**:TECHNICAL_DOC.md 版本升至 2.0.0,新增数据模型 v2.0 设计规范章节;METADATA_DOC.md 完整重写覆盖全部 31 张表
- **Git 历史**:dev 分支两次提交(refactor + docs),master 分支 --no-ff 合并(commit 9c32f69)
## 前端 UI 增强(第五批迭代)
- **封面图高清化**:新增 hdCover() 函数,将微信读书 CDN 封面 URL 从 t6_(低清~150px)升级到 t8_(高清~500px),7 处封面图片全部应用,三级回退机制(t8_→t6_→占位图)
- **阅读排行封面修复**:.top-book-cover 从固定 height:200px + object-fit:cover 改为 aspect-ratio:3/4,解决竖版书封面被裁切模糊问题
- **明亮/黑暗主题切换**:
- CSS 定义 [data-theme="dark"] 变量集(暖色深调,保持文学质感)
- 导航栏添加太阳/月亮图标切换按钮
- localStorage 持久化用户选择,首次访问跟随系统 prefers-color-scheme
- 防闪烁内联脚本在页面渲染前设置主题
- ECharts 图表通过 getChartColors() 读取 CSS 变量,主题切换时自动重绘
- 全局 0.3s 平滑过渡(背景、文字、边框、阴影)
- **整体样式优化**:
- Hero 渐变色从紫色改为暖棕/琥珀色,与全局 accent 色系统一
- 所有硬编码颜色替换为 CSS 变量(评分标签、徽章、排行标牌等)
- 推荐区封面改为 aspect-ratio:3/4 竖版展示
- 页脚数据存储标注从 SQLite 更新为 MySQL
- **Git 提交**:commit ae40ed9(master 分支)
- **Bug 修复:想法 star 值溢出**:红楼梦书评的 star 字段返回 100(微信读书 API 对书评返回的评分值,非 1-5 范围),导致 `"☆".repeat(5-100)` 抛出 RangeError: Invalid count value: -95。修复:用 `Math.max(0, Math.min(5, parseInt(r.star)||0))` 限制到 0-5 范围。commit 4d8cc2a
- **前端四大功能增强**(commit 7c91814):
1. 想法详情独立页面:从弹窗改为全页面视图,三类分类(划线/书评/想法),分类筛选标签,视觉标识(badge 颜色区分),章节分组,书评显示 abstract 原文引用
2. 标签页切换:总览/数据图表/读书排行/书架/笔记/推荐 从纵向滚动改为横向标签页切换,图表懒加载(首次切换到图表页时才初始化 ECharts)
3. 阅读排行竖向列表:从卡片网格改为横向排列列表,封面缩小至 48x64px 与书架一致,金/银/铜排名徽章
4. 回到顶部浮动按钮:滚动超过 400px 显示,平滑滚动回顶部
5. 书籍详情弹窗新增"查看想法"按钮,跳转到想法详情页
- **搜索封面修复 + 顶部搜索框 + 书架搜索优化**(commit 4c916ec):
1. hdCover() 升级:新增对 `s_` 前缀封面 URL 的高清升级(搜索结果用 s_ 前缀,比 t6_ 更模糊)
2. 顶部常驻搜索框:导航栏下方添加搜索输入框,回车自动切换到推荐页搜索子标签执行搜索
3. 书架搜索支持书名/作者:/api/shelf 新增 keyword 参数(title LIKE OR author LIKE),原 category 改为精确匹配
4. 分类标签栏:书架页显示所有分类的可点击标签(pill 样式),点击筛选对应分类
5. 微信读书 CDN 封面前缀:t6_=低清(~150px), s_=超低清(~90px,搜索结果用), t8_=高清(~500px)
## 12:27 移除分类排序按钮,默认按分类排序
- 用户反馈:分类排序不需要前端按钮,默认生效即可
- 删除 index.html 中的 shelfSortBtn 按钮
- app.js 中 shelfSortMode 默认值从 "default" 改为 "category"
- 删除 toggleShelfSort 函数和 .shelf-sort-btn CSS 样式
- 书架列表始终按分类分组渲染,无需手动切换
## 12:32 书架恢复横向网格展示,移除分类分组标题
- 用户反馈:不需要展示分类分组标题(如"历史-历史读物 3本"),恢复简单横向书架
- 删除 renderBooksGroupedByCategory 函数,loadShelf 始终用简单网格渲染
- 后端 sort=category 仍生效(按分类排序),但前端不显示分组
- 分类筛选标签(可折叠层级)保留不变
## 13:11 添加书架刷新按钮 + 后端服务保活方案
### 书架刷新按钮
- 书架筛选栏新增「↻ 刷新」按钮(shelfRefreshBtn)
- 新增 refreshShelf() 函数:点击后重新调用 loadShelfCategories() + loadShelf(1)
- 带 loading 状态:按钮禁用 + 文字变为"刷新中..."
### 后端服务频繁断掉的原因
- 之前用 Bash 工具 run_in_background 启动的进程,会随工具会话结束被回收
- nohup 启动的进程在沙箱环境中也可能被清理
### 保活方案
1. **start_server.sh** 脚本:支持 start/daemon/stop/restart/status 五种模式
- daemon 模式用 nohup 后台运行,记录 PID 到 .server.pid
2. **launchd 服务** (com.weread-dashboard.plist):
- 路径: ~/Library/LaunchAgents/com.weread-dashboard.plist
- KeepAlive=true: 崩溃自动重启
- RunAtLoad=true: 开机自动启动
- 需要用户在终端手动执行 launchctl load 加载
## 13:19 刷新按钮支持完整数据同步
### 问题
- 之前刷新按钮只从 MySQL 重新读取,数据不会变(用户新增书后看不到变化)
- 按钮宽度因文字变化抖动
### 解决方案
- app.py 新增 `/api/sync` POST 接口:
- 运行 fetch_data.py(微信读书API → SQLite)
- 运行 migrate_to_mysql.py(SQLite → MySQL)
- 返回每步结果和状态
- refreshShelf() 改为:先 POST /api/sync → 再 loadShelfCategories + loadShelf
- 按钮三阶段文案:同步中... → 加载中... → 刷新
- CSS min-width:96px 防止宽度抖动
- launchd plist 和 start_server.sh 均注入 WEREAD_API_KEY
### 数据流
微信读书API → fetch_data.py → weread.db(SQLite) → migrate_to_mysql.py → MySQL → app.py → 前端
### 测试验证
- /api/sync 返回 ok:true,406本书同步成功
## 13:25 Flask 静态文件缓存导致 CSS 不生效
- 现象:磁盘上 CSS 已更新(width:120px),但服务器仍返回旧版本
- 原因:Flask 开发服务器缓存静态文件,修改后需重启服务才能生效
- 解决:pkill + 重启 app.py
- 提示用户浏览器也要 Cmd+Shift+R 强制刷新清除缓存