读书上传+在线阅读+笔记导入:端上补齐三个入口 laoyang/FamilyBook#28

用户原话(2026-10-28):「鸿蒙端对齐网页端」。读书端上原来只有书架。

1) FbBookUploadSheet:上传电子书(选文件→服务端解析建书)+ 粘贴导入读书笔记
2) FbBookReadSheet:在线阅读(章节列表 + 单章正文,一次一章)
3) FbBookSheet 详情态加「在线阅读」入口(有章节时才显示);
   FbBooksPage 加「+上传/导入」入口 + 设置菜单「导入笔记」接上

编译 BUILD SUCCESSFUL;服务端冒烟 _i28_book_api.py 11/0 + 反证命中。
This commit is contained in:
2026-10-28 22:47:38 +08:00
parent f1f279f973
commit f5a979f5c8
6 changed files with 599 additions and 14 deletions
+31 -9
View File
@@ -13,18 +13,12 @@
* 🔴 用户 2026-10-20:「其他的功能也逐步完成……设置也没有任何的东西。」
* 读书页那时是**纯书架**:书行点不动、没有"加一本"、设置三项全灰。
*
* ⚠️⚠️ 两处**服务端能力边界**(写在这里,免得以后又摆出假入口):
* 1. `PATCH` **不能改书名/作者** —— `books()` 只从请求体取
* `status` / `current_page` / `rating`,其它键根本不读。
* (改书名要等接口扩,别在界面上放个"书名"输入框然后存不进去。)
* 2. `PATCH` 里的 `current_page` **不对应任何列** —— `books` 表只有
* `progress`(读到第几章),而 `Book::update()` 不读 `current_page`
* ⇒ 端上**不要**回写章节进度,只**显示**。
* 3. 上传电子书 / EPUB 解析 / 笔记导入 / 微信读书同步都在网页端,
* 移动端没有文件选择与解析链路(`BookParser`、`BookNoteImport` 只有网页在调)。
* 🔴 工单 #28(2026-10-28):上传解析 / 在线阅读 / 笔记导入补齐(服务端已给
* `upload` / `chapters` / `chapter` / `import_notes` 四个端点,模型早就有)。
*/
import { fbApi, FbApiResult, FbApiOptions } from './FbHttp';
import { fbUploadOne } from './FbUpload';
/**
* 加一本书。
@@ -85,3 +79,31 @@ export async function addBookNote(token: string, id: number, content: string,
const opts: FbApiOptions = { method: 'POST', token: token, body: body };
return await fbApi('/api/v1/books/' + id.toString() + '/notes', opts);
}
/** 上传一本电子书(EPUB/TXT),服务端解析并建书 + 章节(工单 #28) */
export async function uploadBook(token: string, uri: string): Promise<string> {
return await fbUploadOne('/api/v1/books/upload', 'file', uri, token);
}
/** 章节列表(工单 #28;`GET /books/<id>/chapters`) */
export async function fetchBookChapters(token: string, id: number): Promise<FbApiResult> {
const opts: FbApiOptions = { token: token, authProbe: true };
return await fbApi('/api/v1/books/' + id.toString() + '/chapters', opts);
}
/** 单章正文(工单 #28;`GET /books/<id>/chapter?seq=N`) */
export async function fetchBookChapter(token: string, id: number, seq: number): Promise<FbApiResult> {
const q: Record<string, string> = {};
q['seq'] = seq.toString();
const opts: FbApiOptions = { token: token, query: q, authProbe: true };
return await fbApi('/api/v1/books/' + id.toString() + '/chapter', opts);
}
/** 粘贴导入读书笔记(工单 #28;`POST /books/import_notes`) */
export async function importBookNotes(token: string, raw: string): Promise<FbApiResult> {
const body: Record<string, Object> = {};
body['raw'] = raw;
body['source'] = 'weread';
const opts: FbApiOptions = { method: 'POST', token: token, body: body };
return await fbApi('/api/v1/books/import_notes', opts);
}