Files
skills/weread-skills/notes.md
T

273 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# notes — 笔记/划线
本文档区分两种口径:
- **统计口径**:笔记数 = 书签数 + 划线数 + 想法/点评数。这里的"想法/点评"对应后端 `reviewCount`,包含划线想法、书评想法/个人点评、书摘、非书籍想法等个人内容。
- **内容导出口径**:当前可导出的单本书笔记内容 = 划线内容 + 想法/点评内容。书签只在统计数量中体现,当前 `/book/bookmarklist` 已过滤书签,不能导出书签内容。
公开的他人点评不属于个人笔记,见 `review.md`
## 接口
### `/user/notebooks` — 笔记本概览(所有有笔记的书)
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `count` | int | 否 | 每页数量,默认 20 |
| `lastSort` | int | 否 | 翻页游标(上一页最后一条的 `sort` 值) |
**回包:**
| 字段 | 说明 |
|------|------|
| `totalBookCount` | 有笔记的书籍总数 |
| `totalNoteCount` | 笔记总条数,统计口径为 `reviewCount + noteCount + bookmarkCount` 的汇总 |
| `hasMore` | 是否有更多(1=有) |
| `books[].bookId` | 书籍 ID |
| `books[].book` | 书籍信息(title, author, cover 等) |
| `books[].reviewCount` | 想法/点评数:包含划线想法、书评想法/个人点评、书摘、非书籍想法等个人内容 |
| `books[].noteCount` | 划线数(高亮标注的原文条数) |
| `books[].bookmarkCount` | 书签数(标记阅读位置的条数;只作为数量统计,当前不导出书签内容) |
| `books[].readingProgress` | 阅读进度 |
| `books[].markedStatus` | 标记状态(1=读完, 0=在读) |
| `books[].sort` | 排序值(最近笔记时间,用于翻页) |
#### 概念解释
- 用户问“有多少笔记”时,使用统计口径:`reviewCount + noteCount + bookmarkCount`
- `noteCount` 字段名容易误读:它不是单本书总笔记数,而是划线/高亮原文条数;单本书总笔记数必须自行计算。
- `/user/notebooks` 不返回 `highlightCount` 字段;如果用户或上游说“高亮数/划线数”,对应字段是 `noteCount`
- `reviewCount` 已包含个人点评/书评想法,因此计算总笔记数时不要再额外加“点评数”,否则会重复计算。
- `/user/notebooks` 概览无法把 `reviewCount` 拆成“划线想法”和“个人点评”的独立数量;如需内容明细,需继续查询 `/review/list/mine`
#### 分页规则
- `/user/notebooks` 使用基于时间排序值的游标分页,不支持 `offset`/`limit` 分页。
- 第一次请求只传 `count`;如果 `hasMore` 为 1,取本页 `books` 最后一项的 `sort`,下一次作为 `lastSort` 传入。
- 所有业务参数必须平铺在 JSON body 顶层,和 `api_name``skill_version` 同级;不要包在 `params` 对象里。
- 不要传 `offset``limit``start``size`;这些参数不会被后端分页逻辑读取,可能导致重复第一页或结果不符合预期。
- 拉取完整列表时循环请求直到 `hasMore` 为 0,再按 `reviewCount + noteCount + bookmarkCount` 计算并降序排序。
#### 分页 few-shot
正确:首页请求,参数平铺。
```json
{"api_name":"/user/notebooks","count":20,"skill_version":"1.0.5"}
```
正确:下一页请求,`lastSort` 取上一页 `books` 最后一项的 `sort`
```json
{"api_name":"/user/notebooks","count":20,"lastSort":1778312777,"skill_version":"1.0.5"}
```
错误:不要使用 `params` 包裹业务参数,否则后端收不到 `count``lastSort`
```json
{"api_name":"/user/notebooks","params":{"count":20,"lastSort":1778312777},"skill_version":"1.0.5"}
```
错误:不要使用 `offset`/`limit`,这些字段不是本接口分页参数。
```json
{"api_name":"/user/notebooks","offset":20,"limit":20,"skill_version":"1.0.5"}
```
### `/book/bookmarklist` — 单本书的划线内容列表(不含书签内容)
> 自动过滤书签(type=0),只返回划线(type=1)。
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `bookId` | string | 是 | 书籍 ID |
**回包:**
| 字段 | 说明 |
|------|------|
| `updated` | 划线数组 |
| `updated[].bookmarkId` | 划线唯一 ID |
| `updated[].bookId` | 书籍 ID |
| `updated[].chapterUid` | 所在章节 UID |
| `updated[].markText` | 划线原文 |
| `updated[].createTime` | 创建时间(Unix 时间戳) |
| `updated[].type` | 类型 |
| `updated[].range` | 位置范围 |
| `updated[].colorStyle` | 划线颜色样式 |
| `chapters` | 章节信息数组(用于定位划线所属章节) |
| `chapters[].chapterUid` | 章节 UID |
| `chapters[].chapterIdx` | 章节序号 |
| `chapters[].title` | 章节标题 |
| `book` | 书籍信息 |
### `/review/list/mine` — 单本书的个人想法与点评
> 返回当前用户在该书上的所有个人内容,包括划线想法、章节点评和整本书评。
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `bookid` | string | 是 | 书籍 ID |
| `synckey` | int | 否 | 翻页游标,默认 0 |
| `count` | int | 否 | 每页数量,默认 20 |
**回包:**
| 字段 | 说明 |
|------|------|
| `reviews` | 想法/点评数组 |
| `reviews[].review.reviewId` | 唯一 ID |
| `reviews[].review.content` | 内容文本 |
| `reviews[].review.createTime` | 创建时间 |
| `reviews[].review.star` | 评分(0-5-1=无评分) |
| `reviews[].review.chapterName` | 所在章节名(章节点评时有值,书评为空) |
| `reviews[].review.isFinish` | 是否读完(书评时有值) |
| `totalCount` | 总条数 |
| `hasMore` | 是否有更多(1=有) |
| `synckey` | 翻页游标(下次请求传入) |
### `/book/underlines` — 章节划线热度统计
> 获取某章节每条划线的热度统计(人数/得分/类型),**不含划线文本**,主要用于阅读器内显示"X人划线"热度标签。
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `bookId` | string | 是 | 书籍 ID |
| `chapterUid` | int | 是 | 章节 UID(从 `/book/chapterinfo` 获取) |
| `synckey` | int | 否 | 增量同步 key,默认 0 |
**回包:**
| 字段 | 说明 |
|------|------|
| `bookId` | 书籍 ID |
| `chapterUid` | 章节 UID |
| `underlines` | 划线热度统计数组 |
| `underlines[].range` | 划线位置范围(如 "393-401" |
| `underlines[].count` | 划线人数 |
| `underlines[].score` | 热度分数 |
| `underlines[].type` | 划线类型 |
| `synckey` | 同步 key |
### `/book/bestbookmarks` — 书籍热门划线
> 获取全书的 Popular Highlights**包含划线原文和划线人数**,按热度排序。服务端固定返回前 20 条(`count=20, maxIdx=0`),不支持分页。
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `bookId` | string | 是 | 书籍 ID |
| `chapterUid` | int | 否 | 章节 UID0=全部章节,从 `/book/chapterinfo` 获取),默认 0 |
| `synckey` | int | 否 | 增量同步 key,默认 0 |
**回包:**
| 字段 | 说明 |
|------|------|
| `synckey` | 同步 key(数据版本号) |
| `totalCount` | 热门划线总数 |
| `items` | 热门划线数组 |
| `items[].bookId` | 书籍 ID |
| `items[].userVid` | 代表用户 VID |
| `items[].bookmarkId` | 划线唯一 ID |
| `items[].chapterUid` | 所在章节 UID |
| `items[].range` | 划线位置范围(如 "393-401" |
| `items[].markText` | 划线原文文本 |
| `items[].totalCount` | 划线人数 |
| `items[].simplifiedRange` | 简体书籍的 range(繁简体书专属) |
| `items[].traditionalRange` | 繁体书籍的 range(繁简体书专属) |
| `chapters` | 章节信息数组(用于定位划线所属章节) |
| `chapters[].bookId` | 书籍 ID |
| `chapters[].chapterUid` | 章节 UID |
| `chapters[].chapterIdx` | 章节序号 |
| `chapters[].title` | 章节标题 |
### `/book/readreviews` — 划线下的想法/评论
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `bookId` | string | 是 | 书籍 ID |
| `chapterUid` | int | 是 | 章节 UID |
| `reviews` | array | 是 | 要查询的划线范围数组 |
| `reviews[].range` | string | 是 | 划线位置范围(从 `/book/bestbookmarks` 获取) |
| `reviews[].maxIdx` | int | 否 | 翻页偏移,默认 0 |
| `reviews[].count` | int | 否 | 每页数量,服务端上限 20,超过自动截断 |
| `reviews[].synckey` | int | 否 | 翻页游标,默认 0 |
**回包:**
| 字段 | 说明 |
|------|------|
| `bookId` | 书籍 ID |
| `chapterUid` | 章节 UID |
| `reviews` | 每个 range 的想法列表 |
| `reviews[].range` | 划线范围 |
| `reviews[].totalCount` | 该范围下想法总数 |
| `reviews[].hasMore` | 是否有更多(1=有) |
| `reviews[].maxIdx` | 翻页偏移 |
| `reviews[].synckey` | 翻页游标 |
| `reviews[].pageReviews` | 想法数组 |
| `reviews[].pageReviews[].reviewId` | 想法 ID |
| `reviews[].pageReviews[].review` | 想法详情对象 |
| `reviews[].pageReviews[].review.abstract` | 划线原文(想法对应的划线内容) |
| `reviews[].pageReviews[].review.content` | 想法内容 |
| `reviews[].pageReviews[].review.range` | 划线位置范围 |
| `reviews[].pageReviews[].review.createTime` | 创建时间 |
| `reviews[].pageReviews[].review.author` | 作者信息 |
### `/review/single` — 单条想法详情
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `reviewId` | string | 是 | 想法/评论 ID |
| `commentsCount` | int | 否 | 拉取评论数量,默认 10 |
| `commentsDirection` | int | 否 | 评论排序方向:0=倒序, 1=正序 |
| `likesCount` | int | 否 | 拉取点赞数量,默认 10 |
| `likesDirection` | int | 否 | 点赞排序方向:0=倒序 |
| `synckey` | int | 否 | 增量同步 key,默认 0 |
**回包:**
| 字段 | 说明 |
|------|------|
| `reviewId` | 想法 ID |
| `review` | 想法详情对象(content, bookId, chapterUid, createTime, author 等) |
| `htmlContent` | 富文本内容 |
| `synckey` | 同步 key |
## 工作流
1. **无参数/问笔记数量排行**:调 `/user/notebooks` 展示笔记本概览;如需完整排行,必须按 `count` + `lastSort` 遍历到 `hasMore=0`,且所有分页参数平铺在 body 顶层;每本书笔记数按 `reviewCount + noteCount + bookmarkCount` 计算并排序。
2. **有 bookId 或书名,问单本书笔记内容**:同时调 `/book/bookmarklist`(划线内容)和 `/review/list/mine`(想法/点评内容),合并展示当前可导出的笔记内容。
3. **明确要求书签内容**:说明当前接口只在 `/user/notebooks` 提供书签数量,不能导出书签内容;不要把划线误当书签。
4. 用户从概览中选择某本书后,同样调上述两个接口。
5. 通过 `chapters` 中的 `chapterUid`/`title` 将划线按章节分组。
6. 翻页(notebooks):只使用顶层平铺的 `count` + `lastSort` 游标分页;`hasMore` 为 1 时,用最后一条的 `sort` 值作为下一页 `lastSort`;禁止使用 `params` 嵌套或 `offset`/`limit`
7. **查看书籍热门划线及想法**
-`/book/bestbookmarks` 获取热门划线列表(含划线原文和人数)
-`/book/underlines` 获取章节内划线热度统计(人数/得分,无文本,用于展示"X人划线"标签)
-`/book/bestbookmarks` 返回的 `range` 值调 `/book/readreviews` 获取每条划线下的想法
- 如需查看单条想法完整详情(含评论/点赞),调 `/review/single`
## 输出格式
- 笔记本概览:编号列表,每本书显示书名、作者、总笔记数、想法/点评数、划线数、书签数、阅读进度
- 单本笔记内容:按章节分组展示当前可导出的内容
- 划线:用引用格式 `>` 标注原文
- 想法/点评:区分划线想法、章节点评、整本书评;能关联划线时放在对应划线下方,不能关联时单独列出
- 书签:只展示数量(来自 `/user/notebooks``bookmarkCount`),不展示内容
## 概念理清
- **统计笔记数 = `reviewCount + noteCount + bookmarkCount`**;不要把 `noteCount` 单独当作总笔记数。
- **内容导出 = 划线内容 + 想法/点评内容**;当前不能导出书签内容。
- `reviewCount` 已包含个人点评/书评想法,计算总笔记数时不要再额外加“点评数”。
- 当用户说“所有笔记内容”时,必须同时查询 `/book/bookmarklist``/review/list/mine`,不能只返回划线。