feat: add book detail, notes detail, recommendation page and MySQL schema

新增功能:
- 书籍详情弹窗:点击书架书籍展示详细信息(书名、作者、出版社、ISBN、字数、评分、简介、阅读进度),数据实时从微信读书 API 获取并入库
- 笔记详情弹窗:点击有笔记的书展示划线和想法/点评,按章节分组展示,数据实时获取并入库
- 推荐页面:个性化推荐(为你推荐)+ 关键词搜索书籍,数据从微信读书 API 获取并入库
- 修复 Flask 中文 URL 参数编码问题

后端新增 API:
- GET /api/book/detail?book_id=xxx — 书籍详情
- GET /api/book/notes?book_id=xxx — 笔记详情(划线+想法)
- GET /api/recommend?maxIdx=0 — 个性化推荐
- GET /api/search?keyword=xxx — 搜索书籍

数据库新增表:
- book_details, book_progress, book_highlights, book_chapters
- book_reviews, recommended_books, search_results

MySQL 版本建表语句 schema_mysql.sql:
- 18 张表的完整 DDL,含索引、字符集 utf8mb4、字段注释
- 适用于后续从 SQLite 迁移至 MySQL
This commit is contained in:
admin committed 2026-07-17 10:07:05 +08:00
1 parent 1e9c537b86
commit ebfa3a1852
6 files changed
+1660 -4

No files matched your search

+325
View File
@@ -0,0 +1,325 @@
-- ============================================================
-- 微信读书数据展示网站 - MySQL 版本建表语句
-- 适用于后续从 SQLite 迁移至 MySQL
-- 字符集: utf8mb4 (支持完整 Unicode,包括 emoji)
-- ============================================================
CREATE DATABASE IF NOT EXISTS `weread_dashboard`
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE `weread_dashboard`;
-- ============================================================
-- 1. 书架书籍表
-- ============================================================
CREATE TABLE IF NOT EXISTS `books` (
`book_id` VARCHAR(64) NOT NULL COMMENT '书籍唯一标识',
`title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '书名',
`author` VARCHAR(255) DEFAULT NULL COMMENT '作者',
`cover` VARCHAR(512) DEFAULT NULL COMMENT '封面图 URL',
`category` VARCHAR(128) DEFAULT NULL COMMENT '分类',
`finish_reading` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否读完 (1=读完)',
`read_update_time` INT UNSIGNED DEFAULT NULL COMMENT '最近阅读时间 (Unix 时间戳)',
`secret` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否私密 (1=私密)',
`is_top` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否置顶 (1=置顶)',
`update_time` INT UNSIGNED DEFAULT NULL COMMENT '书籍更新时间 (Unix 时间戳)',
`deep_link` VARCHAR(512) DEFAULT NULL COMMENT '深度链接',
PRIMARY KEY (`book_id`),
INDEX `idx_books_category` (`category`),
INDEX `idx_books_finish_reading` (`finish_reading`),
INDEX `idx_books_read_update_time` (`read_update_time` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='书架书籍信息';
-- ============================================================
-- 2. 阅读统计概要表
-- ============================================================
CREATE TABLE IF NOT EXISTS `reading_stats` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL COMMENT '统计维度: overall/annually/monthly/weekly',
`period` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '周期标识',
`total_read_time` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '总阅读时长 (秒)',
`read_days` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '有效阅读天数',
`day_average_read_time` DOUBLE DEFAULT 0 COMMENT '日均阅读时长 (秒)',
`regist_time` INT UNSIGNED DEFAULT NULL COMMENT '用户注册时间 (Unix 时间戳)',
`raw_json` LONGTEXT DEFAULT NULL COMMENT '原始 API 返回 JSON',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
PRIMARY KEY (`id`),
INDEX `idx_reading_stats_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='阅读统计概要';
-- ============================================================
-- 3. 阅读时长时间序列(按年/月/日分桶)
-- ============================================================
CREATE TABLE IF NOT EXISTS `read_times` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(30) NOT NULL COMMENT '统计维度 (含_daily后缀)',
`period` VARCHAR(20) NOT NULL DEFAULT '',
`bucket_timestamp` INT UNSIGNED NOT NULL COMMENT '分桶起始时间戳',
`duration` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读时长 (秒)',
PRIMARY KEY (`id`),
INDEX `idx_read_times_mode_period` (`mode`, `period`),
INDEX `idx_read_times_bucket` (`bucket_timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='阅读时长时间序列';
-- ============================================================
-- 4. 阅读时长最久的书籍排行
-- ============================================================
CREATE TABLE IF NOT EXISTS `read_longest` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL,
`period` VARCHAR(20) NOT NULL DEFAULT '',
`book_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) DEFAULT NULL,
`author` VARCHAR(255) DEFAULT NULL,
`cover` VARCHAR(512) DEFAULT NULL,
`read_time` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读时长 (秒)',
`tags` VARCHAR(512) DEFAULT NULL COMMENT '标签 JSON 数组',
PRIMARY KEY (`id`),
INDEX `idx_read_longest_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='阅读时长排行';
-- ============================================================
-- 5. 偏好分类
-- ============================================================
CREATE TABLE IF NOT EXISTS `prefer_categories` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL,
`period` VARCHAR(20) NOT NULL DEFAULT '',
`category_id` INT UNSIGNED DEFAULT NULL,
`category_title` VARCHAR(128) DEFAULT NULL,
`parent_category_title` VARCHAR(128) DEFAULT NULL,
`val` DOUBLE DEFAULT 0 COMMENT '偏好权重',
`reading_time` INT UNSIGNED DEFAULT 0 COMMENT '该分类阅读时长 (秒)',
`reading_count` INT UNSIGNED DEFAULT 0 COMMENT '该分类阅读本数',
PRIMARY KEY (`id`),
INDEX `idx_prefer_cat_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='偏好阅读分类';
-- ============================================================
-- 6. 偏好作者
-- ============================================================
CREATE TABLE IF NOT EXISTS `prefer_authors` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL,
`period` VARCHAR(20) NOT NULL DEFAULT '',
`author_id` INT UNSIGNED DEFAULT NULL,
`name` VARCHAR(255) DEFAULT NULL,
`count` INT UNSIGNED DEFAULT 0 COMMENT '阅读该作者的书本数',
`read_time` VARCHAR(64) DEFAULT NULL COMMENT '阅读时长 (格式化字符串)',
PRIMARY KEY (`id`),
INDEX `idx_prefer_author_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='偏好作者';
-- ============================================================
-- 7. 24小时阅读时段分布
-- ============================================================
CREATE TABLE IF NOT EXISTS `prefer_time` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL,
`period` VARCHAR(20) NOT NULL DEFAULT '',
`hour_index` TINYINT UNSIGNED NOT NULL COMMENT '小时 (0-23)',
`duration` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读时长 (秒)',
PRIMARY KEY (`id`),
INDEX `idx_prefer_time_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='24小时阅读时段分布';
-- ============================================================
-- 8. 笔记本概览
-- ============================================================
CREATE TABLE IF NOT EXISTS `notebooks` (
`book_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) DEFAULT NULL,
`author` VARCHAR(255) DEFAULT NULL,
`cover` VARCHAR(512) DEFAULT NULL,
`review_count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '想法/点评数',
`note_count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '划线数',
`bookmark_count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '书签数',
`reading_progress` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读进度 (0-100)',
`marked_status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '标记状态 (1=读完)',
`sort` BIGINT DEFAULT NULL COMMENT '排序值',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='笔记本概览';
-- ============================================================
-- 9. 阅读统计摘要项
-- ============================================================
CREATE TABLE IF NOT EXISTS `read_stat_items` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`mode` VARCHAR(20) NOT NULL,
`period` VARCHAR(20) NOT NULL DEFAULT '',
`stat_name` VARCHAR(64) DEFAULT NULL COMMENT '统计项名称 (读过/读完/阅读/笔记)',
`counts` VARCHAR(64) DEFAULT NULL COMMENT '统计值文案',
`scheme` VARCHAR(512) DEFAULT NULL COMMENT 'App 跳转链接',
PRIMARY KEY (`id`),
INDEX `idx_read_stat_items_mode` (`mode`, `period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='阅读统计摘要项';
-- ============================================================
-- 10. 书单/归档
-- ============================================================
CREATE TABLE IF NOT EXISTS `archives` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL COMMENT '书单名称',
`book_ids` LONGTEXT DEFAULT NULL COMMENT 'bookId 列表 JSON 数组',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='书单/归档';
-- ============================================================
-- 11. 数据采集元信息
-- ============================================================
CREATE TABLE IF NOT EXISTS `fetch_meta` (
`key` VARCHAR(64) NOT NULL,
`value` TEXT DEFAULT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='数据采集元信息';
-- ============================================================
-- 12. 书籍详细信息(按需获取,来自 /book/info)
-- ============================================================
CREATE TABLE IF NOT EXISTS `book_details` (
`book_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) DEFAULT NULL,
`author` VARCHAR(255) DEFAULT NULL,
`translator` VARCHAR(255) DEFAULT NULL COMMENT '译者',
`cover` VARCHAR(512) DEFAULT NULL,
`intro` LONGTEXT DEFAULT NULL COMMENT '简介',
`category` VARCHAR(128) DEFAULT NULL,
`publisher` VARCHAR(255) DEFAULT NULL,
`publish_time` VARCHAR(32) DEFAULT NULL COMMENT '出版时间',
`isbn` VARCHAR(32) DEFAULT NULL,
`word_count` INT UNSIGNED DEFAULT 0 COMMENT '总字数',
`new_rating` DECIMAL(5,1) DEFAULT 0 COMMENT '评分 (百分制)',
`new_rating_count` INT UNSIGNED DEFAULT 0 COMMENT '评分人数',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '获取时间',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='书籍详细信息';
-- ============================================================
-- 13. 阅读进度(按需获取,来自 /book/getprogress)
-- ============================================================
CREATE TABLE IF NOT EXISTS `book_progress` (
`book_id` VARCHAR(64) NOT NULL,
`progress` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '阅读进度百分比 (0-100)',
`chapter_uid` INT UNSIGNED DEFAULT NULL COMMENT '当前阅读章节 UID',
`chapter_offset` INT UNSIGNED DEFAULT NULL COMMENT '当前章节内偏移',
`update_time` INT UNSIGNED DEFAULT NULL COMMENT '最后阅读时间 (Unix 时间戳)',
`record_reading_time` INT UNSIGNED DEFAULT 0 COMMENT '累计阅读时长 (秒)',
`finish_time` INT UNSIGNED DEFAULT NULL COMMENT '读完时间 (Unix 时间戳)',
`is_start_reading` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已开始阅读',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='阅读进度';
-- ============================================================
-- 14. 划线内容(按需获取,来自 /book/bookmarklist)
-- ============================================================
CREATE TABLE IF NOT EXISTS `book_highlights` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`book_id` VARCHAR(64) NOT NULL,
`bookmark_id` VARCHAR(64) DEFAULT NULL COMMENT '划线唯一 ID',
`chapter_uid` INT UNSIGNED DEFAULT NULL COMMENT '所在章节 UID',
`mark_text` LONGTEXT DEFAULT NULL COMMENT '划线原文',
`create_time` INT UNSIGNED DEFAULT NULL COMMENT '创建时间 (Unix 时间戳)',
`type` TINYINT DEFAULT NULL COMMENT '类型',
`range_text` VARCHAR(64) DEFAULT NULL COMMENT '位置范围',
`color_style` TINYINT DEFAULT NULL COMMENT '划线颜色样式',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_highlights_book_id` (`book_id`),
INDEX `idx_highlights_chapter` (`book_id`, `chapter_uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='划线内容';
-- ============================================================
-- 15. 章节信息(来自 /book/bookmarklist 的 chapters)
-- ============================================================
CREATE TABLE IF NOT EXISTS `book_chapters` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`book_id` VARCHAR(64) NOT NULL,
`chapter_uid` INT UNSIGNED NOT NULL,
`chapter_idx` INT UNSIGNED DEFAULT NULL COMMENT '章节序号',
`title` VARCHAR(255) DEFAULT NULL COMMENT '章节标题',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_book_chapter` (`book_id`, `chapter_uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='章节信息';
-- ============================================================
-- 16. 个人想法/点评(按需获取,来自 /review/list/mine)
-- ============================================================
CREATE TABLE IF NOT EXISTS `book_reviews` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`book_id` VARCHAR(64) NOT NULL,
`review_id` VARCHAR(64) DEFAULT NULL COMMENT '想法唯一 ID',
`content` LONGTEXT DEFAULT NULL COMMENT '内容文本',
`create_time` INT UNSIGNED DEFAULT NULL COMMENT '创建时间 (Unix 时间戳)',
`star` TINYINT DEFAULT -1 COMMENT '评分 (0-5, -1=无评分)',
`chapter_name` VARCHAR(255) DEFAULT NULL COMMENT '所在章节名',
`is_finish` TINYINT(1) DEFAULT 0 COMMENT '是否书评',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_reviews_book_id` (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='个人想法/点评';
-- ============================================================
-- 17. 推荐书籍(按需获取,来自 /book/recommend)
-- ============================================================
CREATE TABLE IF NOT EXISTS `recommended_books` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`book_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) DEFAULT NULL,
`author` VARCHAR(255) DEFAULT NULL,
`cover` VARCHAR(512) DEFAULT NULL,
`intro` TEXT DEFAULT NULL,
`category` VARCHAR(128) DEFAULT NULL,
`reason` VARCHAR(512) DEFAULT NULL COMMENT '推荐理由',
`reading_count` INT UNSIGNED DEFAULT 0 COMMENT '在读人数',
`new_rating` DECIMAL(5,1) DEFAULT 0 COMMENT '评分 (百分制)',
`new_rating_count` INT UNSIGNED DEFAULT 0 COMMENT '评分人数',
`rating_title` VARCHAR(32) DEFAULT NULL COMMENT '评分标签 (神作/力荐等)',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_recommended_book_id` (`book_id`),
INDEX `idx_recommended_fetched` (`fetched_at` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='推荐书籍';
-- ============================================================
-- 18. 搜索结果(按需获取,来自 /store/search)
-- ============================================================
CREATE TABLE IF NOT EXISTS `search_results` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`keyword` VARCHAR(255) NOT NULL COMMENT '搜索关键词',
`book_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) DEFAULT NULL,
`author` VARCHAR(255) DEFAULT NULL,
`cover` VARCHAR(512) DEFAULT NULL,
`intro` TEXT DEFAULT NULL,
`publisher` VARCHAR(255) DEFAULT NULL,
`category` VARCHAR(128) DEFAULT NULL,
`reading_count` INT UNSIGNED DEFAULT 0,
`new_rating` DECIMAL(5,1) DEFAULT 0,
`new_rating_count` INT UNSIGNED DEFAULT 0,
`rating_title` VARCHAR(32) DEFAULT NULL,
`search_idx` INT UNSIGNED DEFAULT 0 COMMENT '搜索序号',
`fetched_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_search_keyword` (`keyword`),
INDEX `idx_search_book_id` (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='搜索结果';