# 基于electron开发的小说阅读器 **Repository Path**: yaotingnb/novel-reader ## Basic Information - **Project Name**: 基于electron开发的小说阅读器 - **Description**: 烂番茄 — Electron + Vue 3 本地小说阅读器。支持 TXT/EPUB 导入、在线采集下载、AI 聊天、浏览器搜索、TTS 朗读。 - **Primary Language**: NodeJS - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: https://gitee.com/ujiygdvujiksadgbj - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-05-22 - **Last Updated**: 2026-06-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🍅 烂番茄 — 本地小说阅读器 基于 Electron + Vue 3 的跨平台本地小说阅读器,支持 TXT/EPUB 格式导入与在线阅读,内置**在线小说采集下载引擎**,提供沉浸式阅读体验。 ## 技术栈 | 层级 | 技术 | |------|------| | 框架 | Electron 31 + Vue 3 (Composition API) | | 状态管理 | Pinia + pinia-plugin-persistedstate | | UI 组件库 | Element Plus + 自定义毛玻璃主题 | | 数据库 | better-sqlite3 (WAL 模式) | | HTTP & 解析 | fetch + cheerio + iconv-lite (GBK/UTF-8 自适应) | | Markdown | marked + highlight.js (代码高亮 + 复制按钮) | | 导出 | archiver (EPUB 生成) | | 路由 | Vue Router 4 | | 构建 | Vite 5 + vite-plugin-electron + electron-builder | | 样式 | SCSS + CSS 变量 (明暗双主题) | ## 功能 ### 📚 书架管理 - 拖拽 / 选择文件导入 TXT/EPUB 小说 - 自动解析章节结构(支持中文/英文/纯数字等 10+ 种标题格式) - 智能编码检测(UTF-8/GBK/UTF-16 BOM) - 搜索、排序(最近阅读 / 按名称 / 按作者 / 按大小 / 按进度 / 按导入时间) - 标签分类与筛选 - 自定义封面渐变色 - 网格 / 列表双视图切换 ### 🕷️ 在线采集中心 - **多站点支持** — 自定义站点配置(域名、编码、CSS 选择器规则) - **小说搜索** — 在已配置站点中按书名/作者搜索 - **章节范围采集** — 支持全部章节或指定起止范围下载 - **下载任务管理** — 暂停/恢复/取消,支持断点续传 - **重试失败下载** — 一键重试失败章节 - **进度实时推送** — 主进程 → 渲染进程 IPC 实时更新进度条 - **并发控制** — 可配置最大并发数与请求间隔 - **内容清洗** — 自动去除广告关键词、HTML 实体解码 - **站点规则导入/导出** — JSON 格式批量导入导出站点配置 ### 📦 导出 - 采集完成后导出为 **TXT** 或 **EPUB** 格式 - EPUB 导出完整包含 `content.opf`、`toc.ncx` 目录结构 - 支持自定义导出路径 - 内置 EPUB 解析引擎(container.xml → content.opf → spine/manifest) ### 📖 阅读体验 - **滚动模式** — 连续滚动阅读,滚动到顶/底自动切换章节 - **翻页模式** — 仿纸质书分页,支持鼠标滚轮 / 左右点击 / 键盘方向键翻页 - 自动滚动 / 自动翻页(速率可调) - 右键菜单(复制 / 添加笔记 / 添加书签) - 返回顶部浮动按钮 - **目录搜索** — 在章节列表中按标题/序号搜索 - **TTS 语音朗读** — 使用 Web Speech API,支持中文/英文语音切换、语速/音调调节 - 朗读时实时高亮当前句子(蓝色渐变标记) - 随朗读进度自动滚动/翻页 - 章节读完后自动加载下一章继续朗读 ### 📝 笔记与书签 - 选中文本 → 右键添加笔记,支持富文本输入 - 笔记高亮显示在正文中(渐变标记) - 书签记录精确阅读位置 - 笔记 / 书签面板支持一键跳转 ### 🔍 全文搜索 - 跨章节全文搜索 - 搜索结果关键词高亮 - 点击结果跳转到对应位置 - 最多显示 50 条,超出提示精确搜索 ### 🎨 个性化设置 - 字体 / 字号 / 行间距 / 段落间距 - 7 种字体选择(默认、宋体、黑体、楷体、仿宋、思源黑体、霞鹜文楷) - 文本对齐(左对齐 / 居中 / 两端对齐) - 浅色 / 深色 / **自动**(跟随系统)/ 自定义主题 - 自定义背景色、背景图片(透明度可调) - 毛玻璃透明度滑块 - **关闭行为配置** — 点击关闭按钮时可选:每次都询问 / 最小化到托盘 / 直接退出 - **快捷键配置** — 全局快捷键可自定义录制 - **数据备份/恢复** — 一键导出导入全部数据(JSON 格式) ### 📊 阅读统计 - 今日 / 累计阅读时长 - 阅读天数 / 连续阅读天数 - 本周阅读时长柱状图 - 各书阅读进度列表 - **阅读目标** — 设定每日阅读时长目标,进度条可视化显示 ### 🤖 AI 聊天 - **多轮对话管理** — 新建/切换/删除对话,对话列表持久化 - **流式输出** — SSE 流式响应,打字机效果实时渲染 - **深度思考展示** — 支持 DeepSeek-R1 等推理模型的 `reasoning_content` 折叠展示 - **Markdown 渲染** — marked 引擎,支持代码块语法高亮 + 一键复制 - **模型配置** — 自定义 API Key / Base URL / 模型名称,兼容 OpenAI 格式 API - **参数调节** — Temperature 滑块、Max Tokens 输入、流式开关 - **连接测试** — 一键测试 API 配置有效性 - **超时保护** — 60s 无数据自动中断 + 取消生成按钮 ### 🌐 浏览器搜索 - **Yandex 搜索引擎** — 内嵌俄罗斯 Yandex 搜索,不受国内搜索引擎广告干扰 - **完整浏览器功能** — 后退/前进/刷新/主页导航按钮,实时地址栏显示 - **内嵌 Webview** — 基于 Electron `` 标签,在应用内直接浏览网页 - **新窗口拦截** — 搜索结果的 `target="_blank"` 自动转为当前窗口内导航 ### 🖥️ 桌面体验 - 系统托盘(显示/隐藏窗口、最近阅读列表) - 全局快捷键 `Ctrl+Shift+R` 显隐窗口 - 最小化到托盘(可配置默认行为) - 关闭时弹窗询问是否最小化到托盘 - `?` 键弹出快捷键提示面板 - 窗口状态持久化(位置、大小、最大化状态) ## 项目结构 ``` novel-reader/ ├── electron/ # Electron 主进程 │ ├── main.js # 主入口、窗口管理、托盘、全局快捷键 │ ├── preload.js # 预加载脚本 (contextBridge API) │ ├── database/ # 数据库层 │ │ ├── index.js # 数据库初始化、建表、Schema 迁移 │ │ ├── books.js # 书籍 CRUD、搜索、TXT/EPUB 解析 │ │ ├── epub.js # EPUB 解析引擎(container.xml → content.opf → XHTML) │ │ ├── chapters.js # 章节读取 │ │ ├── bookmarks.js # 书签管理 │ │ ├── notes.js # 笔记管理(选区位置、高亮颜色) │ │ └── stats.js # 阅读统计(会话时长、连续天数) │ └── scraper/ # 在线采集引擎 │ ├── index.js # IPC 注册入口 │ ├── downloader.js # 下载队列、并发控制、断点续传 │ ├── sites-db.js # 站点 CRUD、下载任务 CRUD │ ├── utils.js # HTTP 请求(编码自适应)、Cheerio DOM 提取 │ ├── cleaner.js # 正文清洗(去标签、去广告、HTML 实体解码) │ └── exporter.js # TXT/EPUB 导出(archiver 生成标准 EPUB2) ├── src/ # Vue 前端 │ ├── main.js # Vue 入口(Element Plus、Pinia、Router) │ ├── App.vue # 根组件(主题初始化、IPC 事件监听) │ ├── router/index.js # 路由配置(Hash 模式) │ ├── pinia/ # 状态管理 │ │ ├── index.js # Pinia 实例(persistedstate 持久化) │ │ └── modules/ │ │ ├── bookshelf.js # 书架状态(书籍列表、标签、视图) │ │ ├── reader.js # 阅读器状态(排版、主题、进度)✨ 持久化 │ │ ├── aichat.js # AI 聊天状态(对话列表、配置、流式控制)✨ 持久化 │ │ └── settings.js # 全局设置(明暗主题、背景图、毛玻璃)✨ 持久化 │ ├── utils/ │ │ └── ipc.js # IPC 通信封装(统一调用入口) │ ├── components/ │ │ ├── bookshelf/ # 书架组件 │ │ │ ├── BookCard.vue # 书籍卡片(封面渐变色、标签编辑) │ │ │ └── ImportDialog.vue # 导入确认弹窗 │ │ ├── reader/ # 阅读器组件 │ │ │ ├── ReaderContent.vue # 核心阅读区(滚动/翻页双模式、CJK 分页、笔记高亮、TTS 高亮) │ │ │ ├── ReaderToolbar.vue # 工具栏(目录/书签/笔记/搜索/设置/TTS入口) │ │ │ ├── ReaderSetting.vue # 阅读设置面板(字号/字体/主题/背景图) │ │ │ ├── ChapterNav.vue # 目录导航(支持搜索筛选) │ │ │ ├── BookmarkPanel.vue # 书签面板 │ │ │ ├── NotePanel.vue # 笔记面板 │ │ │ ├── SearchPanel.vue # 全文搜索面板 │ │ │ ├── ShortcutPanel.vue # 快捷键提示面板 │ │ │ ├── TTSPanel.vue # TTS 语音朗读面板 │ │ │ └── AutoScroll.vue # 自动滚屏控制 │ │ ├── layout/ # 布局组件 │ │ │ ├── Layout.vue # 主布局(TitleBar + Sidebar + router-view) │ │ │ ├── Sidebar.vue # 侧边导航栏(书架/AI聊天/搜索/采集/统计/设置/关于) │ │ │ └── TitleBar.vue # 自定义标题栏(窗口控制、置顶) │ │ ├── aichat/ # (预留) AI 聊天子组件 │ │ └── GlobalDialog/ │ │ └── Gdialog.vue # 统一弹窗组件(毛玻璃风格、可拖拽) │ ├── views/ │ │ ├── bookshelf/index.vue # 书架页 │ │ ├── collect/ # 采集中心 │ │ │ ├── index.vue # 采集页(搜索/站点管理/下载任务 Tab 切换) │ │ │ ├── SearchTab.vue # 搜索 Tab(站点选择、关键词搜索、范围确认) │ │ │ ├── SiteMgrTab.vue # 站点管理 Tab(站点 CRUD、CSS 规则配置、导入导出) │ │ │ └── TaskTab.vue # 下载任务 Tab(进度监控、暂停/恢复/重试/导出) │ │ ├── reader/index.vue # 阅读页(全屏独立路由) │ │ ├── aichat/index.vue # AI 聊天页(对话管理、流式渲染、Markdown、代码高亮) │ │ ├── search/index.vue # 浏览器搜索页(Yandex 搜索、webview 内嵌、新窗口拦截) │ │ ├── stats/index.vue # 统计页(今日/累计时长、周柱状图、进度列表、阅读目标) │ │ ├── settings/index.vue # 设置页(主题/背景/快捷键/关闭行为/数据备份) │ │ └── about/index.vue # 关于页(项目信息、技术栈、功能列表) │ └── assets/ │ ├── styles/ │ │ ├── variables.scss # CSS 变量 & 明暗双主题 & Element Plus 变量映射 │ │ ├── global.scss # 全局工具类 & 动画 │ │ └── reset.css # 样式重置 │ └── iconfont/ # 自定义图标字体 ├── public/ # 静态资源 │ ├── icon.png / icon.svg # 应用图标 │ └── backgroud/ # 9 张预设背景图 (bg-01 ~ bg-09.jpg) ├── electron-builder.json # 打包配置(NSIS 安装包) ├── vite.config.js # Vite 配置(别名、Electron 插件) └── package.json ``` ## 开发 ```bash # 安装依赖 npm install # 重新编译 native 模块(better-sqlite3) npm run rebuild # 启动开发模式(Vite HMR + Electron) npm run electron:dev # 仅启动前端(无 Electron) npm run dev # 打包 Windows 安装包(NSIS) npm run electron:build ``` ## 数据库 使用 better-sqlite3 (WAL 模式,外键约束),数据库文件位于: - Windows: `%APPDATA%/rotten-tomatoes/rotten-tomatoes.db` ### 表结构 | 表名 | 说明 | 核心字段 | |------|------|----------| | `books` | 书籍信息 | title, author, file_path, file_type, total_chapters, reading_progress, reading_mode, tags, coverColor, source_url, source_site_id | | `chapters` | 章节索引 | book_id, title, chapter_index, start_pos, end_pos | | `bookmarks` | 书签 | book_id, chapter_index, position, text_snippet | | `notes` | 笔记 | book_id, chapter_index, start_pos, end_pos, selected_text, content, highlight_color | | `reading_sessions` | 阅读时长 | book_id, date, duration_seconds(同天同书聚合) | | `source_sites` | 采集站点 | name, domain, encoding, search_url, search_list_rule, chapter_list_rule, content_rule, chapter_title_rule | | `download_tasks` | 下载任务 | book_id, source_site_id, source_book_name, status, total_chapters, downloaded_chapters, progress, range_start, range_end | ### 章节解析规则(TXT) 支持 10+ 种章节标题格式自动识别: - `第X章/回/节/部/集/卷/篇` — 中文数字 + 阿拉伯数字 - `Chapter 1` / `CHAPTER I` — 英文章节 - `序言/前言/楔子/尾声/后记/番外` — 特殊章节 - `一、/①/(一)/1.` — 纯数字序号 - `卷X/部X/篇X` — 卷部篇格式 编码自动检测:BOM 检测 → UTF-8 验证 → 回退 GBK ## 架构说明 ### IPC 通信流程 ``` 渲染进程 (Vue) 预加载 (preload.js) 主进程 (main.js) ───────────── ────────────────── ─────────────── window.electronAPI ──→ contextBridge ──→ ipcMain.handle() .getBooks() .invoke() book:getAll .searchNovel() scraper:search .startDownload() scraper:startDownload .testAiConnection() aichat:test .sendAiMessage() aichat:send .cancelAiMessage() aichat:cancel ipcRenderer.on() ←── mainWindow.webContents.send() .on('scraper:progress') sendProgress() .on('aichat:chunk') SSE 流式数据推送 .on('aichat:done') 流式完成通知 .on('aichat:error') 异常通知 ``` ### 下载引擎流程 ``` SearchTab downloader.js exporter.js ───────── ───────────── ─────────── 1. 搜索小说 ────→ searchSite() 2. 获取目录 ────→ fetchBookInfo() 3. 创建任务 ────→ addTask() 4. 启动下载 ────→ startDownloadTask() ├─ 获取章节列表 ├─ 应用 range_start / range_end 切片 ├─ processQueue() 并发队列 └─ downloadAllChapters() ├─ 逐章请求 + cleanContent() 清洗 ├─ appendFileSync() 渐进写入 .tmp └─ 完成 → renameSync() 最终文件 5. 导出 ←────────────────────────────────────→ exportBook() ├─ TXT: 直接拼接 └─ EPUB: archiver 打包 ``` ## 采集站点配置 在「采集中心 → 站点管理」中添加站点,需配置以下 CSS 选择器规则: | 字段 | 说明 | 示例 | |------|------|------| | `domain` | 站点域名 | `https://www.example.com` | | `encoding` | 页面编码 | `utf-8` / `gbk` | | `search_url` | 搜索 URL(`{keyword}` 占位) | `/search?q={keyword}` | | `search_list_rule` | 搜索结果容器选择器(可选,不填则全页提取) | `.result-list` | | `chapter_list_rule` | 目录页章节列表容器 | `#chapterlist` | | `content_rule` | 正文内容选择器 | `#content` | | `chapter_title_rule` | 书名提取规则(可选) | `h1` | ## 快捷键 | 按键 | 功能 | |------|------| | ← → ↑ ↓ | 翻页 / 滚动 | | 滚轮 | 翻页(翻页模式下) | | Esc | 关闭侧边栏 / 面板 / 快捷键提示 | | ? / Space | 快捷键提示 | | T | 打开 / 关闭 TTS 朗读面板 | | 左键点击左侧 | 上一页(翻页模式) | | 左键点击右侧 | 下一页(翻页模式) | | 右键 | 上下文菜单(复制 / 笔记 / 书签) | | Ctrl+Shift+R | 显示/隐藏窗口(全局) | ## 许可证 MIT License · Copyright © 2026 YaoTing