更新记录
1.9.2(2026-09-29)
1.9.2(2026-09-29)
UTS 电子书阅读内核|Android / iOS / 鸿蒙 Next|H5 轻量降级。
- 百搭阅读壳
<ebook-reader>:path / url / content 开箱阅读;点中央显隐菜单、左右翻页、捏合字号、目录/主题/Aa/书签/听书;simulation为 Canvas 贝塞尔卷曲 - 内核 API:
createReader→readerId全套能力(分页、选区、书签笔记、TTS、水印、访问策略、原生页、选书、下书、简繁、字体等) - 格式:txt / md / epub 文本层(封面、简介、图片
localPath);非完整 CSS 图文引擎 - 三端要点:Android TTS 媒体通知+音频焦点;iOS 后台音频会话;鸿蒙 CoreSpeechKit / 环境光;H5 仅 content 降级
- 增值 stub:手写 / AI 未装包时
8040004;实装见ebook-reader-handwrite、ebook-reader-ai - 修复:
downloadFont/ensureBuiltinFont返回命名类型FontInstallResult(UTS110111101)
平台兼容性
uni-app(3.8.4)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
ebook-reader
UTS 电子书阅读内核|Android / iOS / 鸿蒙 Next|H5 轻量降级。
当前版本 1.9.2:提供可嵌入宿主的 百搭阅读壳 <ebook-reader>(开箱阅读 UI)+ 完整内核 API(可完全自定义)。
适合谁
| 场景 | 怎么用 |
|---|---|
| 小说 / 网文 App | 挂载 <ebook-reader>,进度事件同步书架 |
| 教育 / 教材阅读 | 划线笔记 + TTS + 水印;可选 AI / 手写增值包 |
| 企业文档 / 内部分发 | content / url 打开 + 访问策略 + 水印 |
| 自研阅读 UI | 只用内核 API,自己画页面 |
增值模块(按需安装)
| 模块 | 目录 | 说明 |
|---|---|---|
| 手写批注 | ebook-reader-handwrite |
叠加层 + 官方端侧 OCR(Android Digital Ink / iOS Vision / 鸿蒙 Core Vision)+ 朗读 |
| AI 增强 | ebook-reader-ai |
划词释义 / 摘要 / 抽词 / 生词卡(业务 HTTP,不内置大模型) |
主包同名 API 为 stub:未安装对应包时 reject(8040004)。请从增值包 import,并用其 getHandwriteCapabilities / getAiCapabilities。
import { enableHandwrite } from '@/uni_modules/ebook-reader-handwrite'
import { configureAi, aiLookup } from '@/uni_modules/ebook-reader-ai'
规划中(未随主包发布):ebook-reader-pdf、ebook-reader-ancient、ebook-reader-secure。
安装
- 将本目录放入项目
uni_modules/ebook-reader - 选书(推荐):同时安装
ebook-select-files;鸿蒙再装ebook-select-files-harmony(主包也内置pickBookFile) - 制作自定义调试基座后运行(改
utssdk/必须重做基座) - Vue2 / Vue3、app-vue / app-nvue / app-uvue 均可;H5 仅
content试读降级
开箱即用(推荐)
easycom 会自动注册 components/ebook-reader/ebook-reader.vue。宿主页面只需:
<template>
<ebook-reader
:path="bookPath"
:title="bookTitle"
:show-back="true"
watermark="仅供内部阅读"
@progress=""
@back="onBack"
/>
</template>
<script>
export default {
data() {
return {
bookPath: '', // pickBookFile 后的稳定 path,或业务下发的本地路径
bookTitle: '我的书'
}
},
methods: {
(p) {
// 同步到自有书架:p.page / p.percent / p.position
},
onBack() {
uni.navigateBack()
}
}
}
</script>
插件内 index.vue 即为该壳的演示页(挂载阅读壳 + 试读样例),不再是 API 接线板。
书源(三选一)
| Prop | 说明 |
|---|---|
path |
本地沙盒路径(选书请 copyToCache: true) |
url |
网络下书后打开 |
content |
内存正文(任意端快速试读,含 H5) |
也可用 ref 命令式打开:
this.$refs.reader.open({ path: '/path/to/a.epub', bookId: 'b1' })
// 或
this.$refs.reader.open({ content: '第一章\n\n正文…', format: 'txt' })
this.$refs.reader.pickAndOpen()
this.$refs.reader.goNext()
this.$refs.reader.goPrev()
常用 Props
| Prop | 默认 | 说明 |
|---|---|---|
theme |
day |
day / night / eye / parchment(壳内主题名:冷纸 / 夜墨 / 青苔 / 旧笺) |
fontSize |
18 |
12–40 |
pageMode |
page |
page / scroll / simulation(仿真为 Canvas 贝塞尔卷曲) |
autoOpen |
true |
挂载后自动打开 props 书源 |
showBack |
true |
顶栏返回 |
showPick |
true |
空态/更多里选书 |
showDemo |
false |
空态「试读样例」(插件 demo 页为 true) |
chrome |
true |
初始是否显示菜单;阅读中点屏幕中央切换 |
enableToc / Theme / Font / Bookmark / Tts / PageMode / Script / Sound / Export |
true |
按需关掉底栏/更多能力 |
watermark |
'' |
非空则叠加水印 |
watermarkOpacity |
0.1 |
水印透明度 |
restoreProgress |
true |
打开时恢复上次进度 |
emptyTitle / emptyDesc |
— | 空态文案 |
事件
ready · open · progress · back · close · error · bookmark · tts · chrome-change
交互(阅读壳内置)
- 点中央:显隐顶/底栏
- 点左/右约 28% 或左右滑:翻页(
page模式) simulation:Canvas 贝塞尔仿真卷曲,跟手拖动翻页;可开翻页纸张音效- 双指捏合:调字号;上下滑:调亮度
- 长按:选区菜单(复制 / 划线 / 笔记 / 朗读)
- 底栏 / 更多:目录 · 主题 · Aa · 书签 · 听书 · 翻页模式 · 简繁 · 音效 · 导出
完全自定义(内核 API)
不需要内置 UI 时,直接调 API 自绘:
import {
createReader,
openBook,
getPageContent,
nextPage,
onReaderEvent,
getReaderCapabilities
} from '@/uni_modules/ebook-reader'
const caps = getReaderCapabilities()
const { readerId } = await createReader({
theme: 'day',
viewportWidth: 360,
viewportHeight: 640,
statsIntervalMs: 30000
})
onReaderEvent(readerId, 'progress', (p) => {
console.log(p.page, p.pageCount, p.percent)
})
await openBook(readerId, { path: '/path/to/book.txt', bookId: 'my_book' })
// 或 openBook(readerId, { path: 'content:第一章\n\n正文', format: 'txt' })
// 或 openBook(readerId, { url: 'https://cdn.example.com/a.epub' })
// 或 openBook(readerId, { bytesBase64: '...' })
const page = await getPageContent(readerId)
await nextPage(readerId)
桥接不回传带方法的 class:所有 API 以
readerId为第一参数(见utssdk/interface.uts)。
内核能力速查
| 分组 | API |
|---|---|
| 生命周期 | createReader / destroyReader / getReaderCapabilities |
| 书籍 | openBook / closeBook / getBookMeta / parseBookMeta / downloadBook / pickBookFile |
| 翻页 | setPageMode / nextPage / prevPage / gotoPosition / getProgress / getToc / getPageContent / getPagePreview |
| 原生页 | showNativeReader / hideNativeReader / isNativeReaderVisible |
| 样式 | setStyle / setFont / setTheme / downloadFont / ensureBuiltinFont / convertScript |
| 选区 | selectText / clearSelection / getSelection / selectionAction |
| 书签笔记 | addBookmark / updateBookmark / getBookmarks / addNote / addHighlight / exportNotes |
| TTS | ttsPlay / ttsPause / ttsResume / ttsStop / ttsNext / ttsPrev / setPauseMarksVisible |
| 体验 | setPageTurnSound / setWatermark / setBookAccessPolicy / setPocketMode / setEdgeGestureGuard / pinchZoom / adjustBrightness / enableAmbientLight |
事件名(onReaderEvent):ready · error · progress · relayout · tap · chapterChange · close · stats · ttsState · ttsProgress · selection · pageTurn · behavior · gesture · nativeView 等。
与选书
主包已内置 pickBookFile(阅读壳空态也会调)。仍可选用独立插件 ebook-select-files / ebook-select-files-harmony。
const res = await pickBookFile({ count: 1, extensions: ['txt', 'md', 'epub'], copyToCache: true })
if (res.ok) await openBook(readerId, { path: res.files[0].path })
用户取消:errCode = 8040001。
能力矩阵(1.9)
| 能力 | Android | iOS | 鸿蒙 | H5 |
|---|---|---|---|---|
百搭阅读壳 <ebook-reader> |
✅ | ✅ | ✅ | ✅(content) |
| 壳内 simulation 贝塞尔卷曲 | ✅(App-Vue) | ✅(App-Vue) | ✅(App-Vue) | ✅ |
| txt / md | ✅ | ✅ | ✅ | ✅(content:) |
| epub(文本层) | ✅ | ✅ | ✅ | ❌ |
| epub 封面 / 简介 | ✅ | ✅ | ✅ | ❌ |
epub 图片 images.localPath |
✅ | ✅ | ✅ | ❌ |
pickBookFile |
✅ | ✅ | ✅ | ❌ |
| 原生页 overlay | ✅ | ✅ | ✅(对话框) | ❌ |
| 原生页 embed | ✅(uni-app x) | ✅ | ❌ | ❌ |
| 原生页 simulation 轻动画 | ✅ | ✅ | — | — |
| bytesBase64 | ✅ | ✅ | ✅ | txt/md |
| 选区 / selectionAction | ✅ | ✅ | ✅ | ✅ |
| 手势 pinchZoom / 亮度 | ✅ | ✅ | ✅ | ✅ |
| TTS / fromSelection / Next·Prev | ✅ | ✅ | ✅ | ❌ |
| TTS 媒体通知 / 音频焦点 | ✅ | — | ❌ | ❌ |
| 后台 TTS 会话 | ✅(通知) | ✅ | ❌ | ❌ |
| downloadBook / url 打开 | ✅ | ✅ | ✅ | ❌ |
| downloadFont / ensureBuiltinFont | ✅ | ✅ | ✅ | ✅(temp) |
| 简繁转换 | ✅ | ✅ | ✅ | ✅ |
| 自定义字体(原生生效) | ✅ | ✅ | 标记 | 标记 |
theme: system 深色 |
✅ | ✅ | 降级 day | 降级 day |
| 翻页音效 | ✅ | ✅ | 事件 | 事件 |
| 断句 / 页预览 / 导出 | ✅ | ✅ | ✅ | ✅ |
| 环境光 | ✅ | ❌ | ✅ | ❌ |
| 口袋模式 | ✅ | ❌ | ✅ | ❌ |
| 水印 / 访问策略 | ✅ | ✅ | ✅ | ✅ |
| pdf 等增值 | ❌ | ❌ | ❌ | ❌ |
原生页 / 字体(进阶)
await showNativeReader(readerId, { mode: 'overlay' })
// embed:Android 需 uni-app x;iOS 容器 accessibilityIdentifier=containerId
await downloadFont({ url: 'https://example.com/SourceHanSans.otf', family: 'source-han-sans' })
await ensureBuiltinFont(readerId)
epub 说明
- 解析
META-INF/container.xml→ OPF manifest/spine → 章节 HTML 抽纯文本 - 图片以
[图 src="..." alt="..."]写入正文;PageContent.images提供src/alt/offset/localPath - 目录优先 NCX / nav,否则用文内首行
- 选书请加后缀
epub,并copyToCache: true - 非完整 CSS 图文混排引擎(后续大版本)
getReaderCapabilities() 可探测运行时能力。
错误码 8040xxx
完整定义见 utssdk/unierror.uts(勿与 keepalive-location 的 803xxxx、选书插件的 8020xxx 冲突)。
| code | 含义 |
|---|---|
| 8040001 | 用户取消(选书) |
| 8040002 | 参数非法 |
| 8040003 | 当前平台/版本不支持 |
| 8040004 | 增值模块未安装 |
| 8040100 | 文件不存在 |
| 8040101 | 打开失败 |
| 8040102 | 解析失败 |
| 8040103 | 下载失败 |
| 8040104 | 解密失败 |
| 8040105 | 书籍过大(默认上限约 20MB) |
| 8040106 | 书籍已过期 |
| 8040107 | 书籍禁止打开 |
| 8040200 | 阅读器未创建 / 原生页容器失败 |
| 8040201 | 未打开书籍 |
| 8040202 | 位置越界 |
| 8040300 | 字体加载/下载失败 |
| 8040400 | TTS 不可用 |
| 8040401 | TTS 播报失败 |
| 8040500 / 8040501 | 权限拒绝 / 受限 |
| 8040600 | 本地存储失败 |
| 8040700 / 8040701 | AI 未配置 / 请求失败 |
| 8040800 | 环境光/距离传感器不可用 |
| 8040900 | 内部错误 |
踩坑(必读)
完整清单见 PRD §15。开发时至少记住:
- 改原生后重做自定义基座
- 目录名 =
package.json的id=ebook-reader(ASCII-) - 禁止导出名为
init的函数(iOS/Swift 保留字会导致云打包失败) - Android Int:
(n).toInt();iOS 勿对已是 Int 的值再.toInt() - 选书务必
copyToCache: true,再用稳定 path 调openBook - 鸿蒙权限若后续增加,必须写
module.json5+$string:reason,只写config.json不进包 - UTS 禁止
Promise<{...}>匿名对象返回值,须用命名类型(如FontInstallResult) simulation:阅读壳走 Canvas 卷曲;原生页仍为轻量位移动画,二者不是同一套实现
隐私声明(市场)
- 权限:M1 无强制危险权限;选书权限随选书流程;按需网络下书、TTS 后台音频/通知、环境光/距离传感器
- 数据:默认仅本地存储进度 / 书签 / 笔记;行为事件只抛不传;AI 模块由业务配置服务端
- 广告:无

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 141
赞赏 0
下载 12649018
赞赏 1953
赞赏
京公网安备:11010802035340号