Skip to content

wish-init/InkReader

Repository files navigation

InkReader

InkReader 是一款面向本地离线漫画收藏的桌面阅读器。它使用 Tauri 2、Vue 3、TypeScript、Rust 和 SQLite 构建,重点解决本地漫画仓库扫描、书架管理、压缩包阅读、阅读进度、收藏整理、元数据维护和数据备份等日常需求。

项目当前以 Windows 桌面使用为主要目标。应用只索引和读取用户选择的漫画文件,不会修改、移动或删除原始漫画文件。

主要功能

本地仓库

  • 添加本地漫画仓库目录。
  • 扫描仓库下的一层漫画文件夹和一层压缩包。
  • 支持手动重扫和启动后自动扫描。
  • 支持增量扫描,未变化的漫画会跳过深度扫描。
  • 扫描过程中显示进度、扫描阶段和持久化阶段。
  • 保存扫描历史、跳过条目、失败条目和重复漫画诊断。
  • 移除仓库记录时只删除 InkReader 索引,不删除原始漫画文件。

书架与检索

  • 后端分页加载书架,适合较大本地库。
  • 支持搜索标题、按仓库筛选、按作者筛选、按标签筛选、排除标签。
  • 支持阅读状态筛选:全部、未读、阅读中、已读。
  • 支持收藏状态筛选:全部、已收藏、未收藏。
  • 支持元数据缺失筛选:缺少简介、作者、标签、封面、发布时间。
  • 支持按标题、页数、创建时间、最近阅读、发布时间排序。
  • 支持网格、紧凑、列表三种书架布局。
  • 支持封面尺寸、作者显示、标签显示、标题行数和标题字号设置。

收藏与聚合

  • 支持默认收藏和自定义收藏夹。
  • 支持批量加入、移动、移出收藏夹。
  • 支持收藏夹名称、简介和封面维护。
  • 支持作者聚合页和标签聚合页,便于从人物或标签维度浏览漫画。

漫画详情与元数据

  • 显示标题、简介、作者、标签、章节数、页数、阅读进度等信息。
  • 支持自定义漫画标题,并可恢复扫描标题。
  • 支持编辑标题、简介、作者和标签。
  • 支持元数据健康检查,集中查看缺失元数据、缺失封面、无图片条目和重复漫画。

阅读器

  • 支持单页、双页、长条滚动阅读模式。
  • 支持从左到右和从右到左阅读方向。
  • 支持宽度适配、高度适配和原始尺寸。
  • 支持章节切换、页码跳转、上一页/下一页、上一章/下一章。
  • 自动保存阅读进度和最近阅读记录。
  • 支持标记已读、标记未读。
  • 支持书签创建、删除、检查和抽屉式跳转。
  • 支持亮度、对比度、背景色、翻页动画、空格滚动比例、长按空格滚动速度。
  • 支持自动滚动速度、启动延迟和手动滚动停止行为设置。
  • 支持有限图片预加载缓存,降低长章节阅读时的内存风险。

压缩包阅读

  • 支持将 zipcbzrarcbr 作为漫画条目扫描。
  • 支持文件夹漫画中把压缩包作为章节。
  • 支持按需读取压缩包内页面,不需要一次性解压整本漫画。
  • 提供 archive:// 自定义协议读取压缩包内图片。
  • 后端对压缩包页面字节做小型 LRU 缓存,改善连续阅读体验。

缓存、备份与设置

  • 自动生成和复用书架缩略图缓存。
  • 支持查看缩略图缓存统计。
  • 支持清理托管缩略图缓存。
  • 支持重建缺失缩略图。
  • 支持创建 SQLite 数据库备份。
  • 支持从备份恢复数据库,恢复前会生成回滚文件。
  • 支持阅读器设置、书架视图设置和单本阅读器设置。
  • 支持设置导出、设置导入和恢复默认设置。
  • 支持操作日志,记录备份、恢复、缓存维护等高影响操作。

下载

如果只想使用已构建版本,可以从 GitHub Releases 下载 Windows 安装包或便携包:

InkReader Releases

便携包可以直接运行 InkReader.exe。便携包的数据默认保存在可执行文件旁边的 data/ 目录中,适合放在非系统盘或随项目目录迁移。

技术栈

层级 技术
桌面框架 Tauri 2
前端 Vue 3、TypeScript、Vite
UI 组件 Naive UI
路由 Vue Router hash history
后端 Rust
数据库 SQLite via rusqlite
压缩包 zipunrar-ng
图片处理 image
排序 自然排序,适配 1.jpg2.jpg10.jpg

环境要求

  • Node.js LTS。
  • pnpm 10+,本项目锁定 pnpm@10.11.0
  • Rust stable,包含 rustccargo
  • Windows WebView2 Runtime。Windows 10/11 通常已自带。
  • Windows 构建 Tauri 时需要可用的 MSVC/Rust Windows 工具链。

检查本地开发环境:

pnpm check:env

快速开始

安装依赖:

pnpm install

启动桌面开发模式:

pnpm tauri:dev

也可以使用项目默认启动命令:

pnpm start

只启动 Vite 前端开发服务器:

pnpm dev

前端开发服务器地址由 Tauri 配置为:

http://127.0.0.1:1420

常用命令

pnpm check:env              # 检查 Node.js、pnpm、rustc、cargo
pnpm dev                    # 仅启动 Vite 前端开发服务器
pnpm start                  # 检查环境并启动 Tauri 开发模式
pnpm tauri:dev              # 检查环境并启动 Tauri 开发模式
pnpm typecheck              # TypeScript 类型检查
pnpm build                  # 前端类型检查和 Vite 构建
pnpm tauri:build            # 构建 Windows NSIS 安装包
pnpm tauri:build:installer  # 构建 Windows NSIS 安装包
pnpm tauri:build:portable   # 构建 Windows 便携包和 zip

Rust 常用检查:

cargo fmt --manifest-path src-tauri/Cargo.toml
cargo check --manifest-path src-tauri/Cargo.toml
cargo test --manifest-path src-tauri/Cargo.toml

打包输出

构建安装包:

pnpm tauri:build:installer

构建便携包:

pnpm tauri:build:portable

便携包输出位置:

src-tauri/target/release/portable/InkReader-portable-<version>-windows-x64/
  InkReader.exe
  data/
  README-portable.txt

同目录还会生成对应的 .zip 文件。

支持的漫画结构

InkReader 会把仓库目录下的一层文件夹或一层受支持压缩包识别为漫画入口。

多章节文件夹漫画

漫画仓库/
  漫画 A/
    元数据.json
    cover.jpg
    第 1 话/
      0001.jpg
      0002.jpg
    第 2 话/
      0001.jpg
      0002.jpg

单层图片目录

单层图片目录会被识别为一本漫画,并自动生成名为 正文 的章节:

漫画仓库/
  漫画 B/
    cover.jpg
    0001.jpg
    0002.jpg
    0003.jpg

压缩包漫画

漫画仓库/
  漫画 C.cbz
  漫画 D.zip
  漫画 E.cbr
  漫画 F.rar

压缩包章节

文件夹漫画中也可以把压缩包作为章节:

漫画仓库/
  漫画 G/
    cover.jpg
    cbz/
      第 1 话.cbz
      第 2 话.cbz

扫描规则

  • 仓库只扫描一层文件夹和一层压缩包作为漫画入口。
  • 支持的图片页格式为 jpgjpegpngwebp
  • 支持的压缩包格式为 zipcbzrarcbr
  • 图片和章节使用自然排序。
  • 文件夹漫画优先使用根目录 cover.jpg 作为封面。
  • 没有 cover.jpg 时,使用第一张正文图片作为封面候选。
  • 压缩包漫画优先使用包内 cover.jpg,否则使用包内第一张图片。
  • 漫画目录存在 元数据.json 时,优先使用其中的标题、作者、标签、简介和章节顺序。
  • 单本漫画解析失败不会修改原始文件,错误会记录到扫描诊断中。
  • 重扫会基于路径、修改时间、大小等签名跳过未变化条目,并尽量保留阅读进度、收藏、书签和自定义标题。

元数据格式

元数据.json 使用 camelCase 字段。示例:

{
  "id": "comic-001",
  "name": "漫画标题",
  "addtime": "2026-01-01T00:00:00Z",
  "description": "漫画简介",
  "author": ["作者 A", "作者 B"],
  "tags": ["动作", "冒险"],
  "chapterInfos": [
    {
      "chapterId": "chapter-001",
      "chapterTitle": "第 1 话",
      "order": 1
    }
  ]
}

字段说明:

  • id:来源 ID,可用于辅助识别来源。
  • name:书架显示标题。
  • addtime:来源发布时间或添加时间,会映射为发布时间。
  • description:漫画简介。
  • author:作者列表。
  • tags:标签列表。
  • chapterInfos[].chapterTitle:章节标题,通常与章节目录名匹配。
  • chapterInfos[].order:章节排序值。

数据存储

InkReader 的运行数据保存在可执行文件所在目录旁边的 data/ 中:

<InkReader.exe 所在目录>/data/inkreader.sqlite3
<InkReader.exe 所在目录>/data/thumbs/

开发模式下,可执行文件通常位于:

src-tauri/target/debug/

因此开发数据通常位于:

src-tauri/target/debug/data/inkreader.sqlite3

注意事项:

  • 应用目录需要可写,否则数据库和缩略图缓存无法创建。
  • 从旧版本升级时,如果新位置没有数据库,应用会尝试从系统应用数据目录迁移旧数据库。
  • 删除仓库记录只删除 InkReader 索引,不删除漫画源文件。
  • 缩略图缓存只保存应用生成的缓存文件,可以通过应用内缓存维护功能重建。

项目结构

src/                              Vue 前端源码
src/api/                          Tauri command 调用封装和共享类型
src/components/common/            应用外壳和通用组件
src/components/library/           书架列表、卡片和视图设置组件
src/components/reader/            阅读器工具栏、视口、章节和书签抽屉
src/composables/library/          书架列表、选择、上下文菜单、缩略图水合逻辑
src/composables/reader/           阅读器导航、键盘、进度、预加载、缩放、自动滚动逻辑
src/pages/                        页面级组件
src/router/                       前端路由
src/styles/                       全局样式和主题变量
src/utils/                        纯工具函数和默认设置

src-tauri/                        Tauri/Rust 工程
src-tauri/src/lib.rs              Tauri builder、AppState、archive 协议和 command 注册
src-tauri/src/commands/           Tauri command 入口
src-tauri/src/db/                 SQLite 初始化、迁移、查询、备份、缓存维护
src-tauri/src/metadata/           元数据 JSON 解析
src-tauri/src/models/             Rust 与前端共享的序列化模型
src-tauri/src/scanner/            仓库、文件夹、压缩包、图片、自然排序扫描逻辑
src-tauri/src/thumbnail.rs        缩略图生成

scripts/                          环境检查和便携包脚本
docs/performance/                 大库和长章节性能基线

前端页面

当前路由:

路径 页面
/library 书架
/books/:bookId 漫画详情
/reader/:bookId 阅读器
/favorites 收藏
/authors 作者聚合
/tags 标签聚合
/history 阅读记录
/health 元数据健康
/repositories 仓库管理
/settings 设置

后端职责

Rust 后端负责:

  • 本地路径校验。
  • 仓库扫描和增量扫描。
  • 文件夹漫画和压缩包漫画识别。
  • 元数据.json 解析。
  • 图片页过滤、自然排序和 URI 生成。
  • SQLite 迁移、读写、事务和索引维护。
  • 阅读进度、历史、书签、收藏和设置持久化。
  • 缩略图生成、清理和重建。
  • 数据库备份与恢复。
  • archive 协议读取压缩包内图片。

前端负责:

  • 页面展示和用户交互。
  • 调用 src/api/ 中的 Tauri command 封装。
  • 管理页面状态、筛选条件、阅读器设置和本地 UI 偏好。
  • 展示错误、扫描诊断、缓存维护结果和备份恢复结果。

性能基线

项目包含大库和长章节性能基线文档:

docs/performance/large-library-baseline.md

该文档覆盖:

  • 1000 本和 5000 本本地库测试方法。
  • 500 页长章节测试方法。
  • 30 分钟长条滚动稳定性检查。
  • 缩略图水合检查。
  • SQLite 索引盘点和查询计划检查流程。

涉及扫描、书架分页、缩略图、阅读器预加载、SQLite 索引的改动,建议按该文档记录前后数据。

开发约定

  • 前端 Tauri 类型集中在 src/api/tauri.ts
  • 具体 API 模块通过共享 call<T>() 封装调用 Tauri command。
  • Rust 暴露给前端的模型使用 #[serde(rename_all = "camelCase")]
  • 后端列表 API 负责筛选、排序、分页和总数,前端不应自行修正总数。
  • 修改字段名、command 名、设置 key、路由或枚举选项前,先用 rg 搜索镜像位置。
  • 数据库多表写入应通过事务保持一致性。
  • 任何仓库、缓存、备份、恢复功能都必须避免影响用户原始漫画文件。

推荐检查

文档或前端类型改动:

pnpm typecheck

前端构建检查:

pnpm build

Rust 改动:

cargo fmt --manifest-path src-tauri/Cargo.toml
cargo test --manifest-path src-tauri/Cargo.toml

完整桌面构建:

pnpm tauri:build:portable

常见问题

启动失败或白屏

先确认环境:

pnpm check:env

然后重新启动:

pnpm tauri:dev

无法创建数据库

确认 InkReader.exe 所在目录可写。便携包建议解压到普通用户目录或非系统盘,不要放在需要管理员权限写入的位置。

仓库扫描不到漫画

检查仓库结构是否满足以下条件之一:

  • 仓库一层子目录中包含图片页或章节目录。
  • 仓库一层存在 zipcbzrarcbr 文件。
  • 图片扩展名是 jpgjpegpngwebp

压缩包无法读取

确认压缩包未损坏、未加密,并且扩展名是 zipcbzrarcbr。如果单个压缩包失败,扫描诊断中会保留失败路径和原因。

缩略图缺失

可以在设置或缓存维护入口中重建缺失缩略图。缩略图缓存缺失不会影响漫画源文件。

想迁移数据

优先使用应用内数据库备份功能创建备份文件,再在目标环境中恢复。便携版也可以整体迁移包含 InkReader.exedata/ 的目录。

贡献

提交改动前建议至少运行与改动范围匹配的检查。涉及界面变化时建议附截图或说明主要交互路径。涉及扫描、阅读器、缓存或数据库性能时,建议补充可复现数据集和性能基线记录。

许可证

本项目基于 MIT License 开源,详见 LICENSE

About

InkReader 是一款基于 Tauri、Vue 和 Rust 构建的本地离线漫画桌面阅读器,支持漫画仓库扫描、压缩包阅读、书签、收藏、元数据编辑和 SQLite 阅读进度管理。

Topics

Resources

License

Stars

1 star

Watchers

1 watching

Forks

Packages

 
 
 

Contributors