novel · 小说
import { NovelDomain } from '@hfyidu/api/novel'小说领域覆盖书架管理、分类/榜单、目录、阅读(IAP 付费解锁模式 / IAA 广告解锁模式两套阅读接口)、章节解锁、搜索、阅读记录等能力,服务前缀 novel。其中阅读页插入的广告位复用 ad 领域 的 PlayListDto 类型,本文不重复定义,直接跳转查看。
用例总览
| 用例 | 说明 | 请求方式 |
|---|---|---|
NovelDomain.cases.bookshelf | 获取书架列表(分页) | GET novel/bookshelves |
NovelDomain.cases.classify | 获取小说分类 | GET novel/classify |
NovelDomain.cases.classList | 获取分类下小说列表(分页) | GET novel/class/list |
NovelDomain.cases.search | 搜索小说(分页) | GET novel/search |
NovelDomain.cases.hotsearch | 获取热搜数据 | GET novel/hotSearch |
NovelDomain.cases.bags | 获取书架书包推荐数据 | GET novel/bags |
NovelDomain.cases.rankList | 获取榜单列表(分页) | GET novel/list |
NovelDomain.cases.adCatalogues | 获取 IAA 模式小说目录(分页) | GET novel/ad/catalogues |
NovelDomain.cases.adUnlock | IAA 模式解锁章节 | PUT novel/ad/unlock |
NovelDomain.cases.read | IAP 模式阅读章节 | GET novel/read |
NovelDomain.cases.adRead | IAA 模式阅读章节 | GET novel/ad/read |
NovelDomain.cases.catalogues | 获取 IAP 模式小说目录(分页) | GET novel/catalogues |
NovelDomain.cases.detail | 获取小说详情 | GET novel/detail |
NovelDomain.cases.unlock | IAP 模式解锁章节 | PUT novel/unlock |
NovelDomain.cases.reading | 上报阅读时长 | POST novel/reading |
NovelDomain.cases.delBookshelf | 从书架移除小说 | DELETE novel/bookshelf |
NovelDomain.cases.addBookshelf | 添加小说到书架 | PUT novel/bookshelf |
NovelDomain.cases.reads | 获取阅读记录(分页) | GET novel/reads |
NovelDomain.cases.delRead | 删除阅读记录 | DELETE novel/read |
NovelDomain.cases.rankSingle | 获取单个榜单详情(分页) | GET novel/list |
NovelDomain.cases.cataloguesAll | 获取全量小说目录(分页) | GET novel/cataloguesAll |
bookshelf · 获取书架列表(分页)
这是分页列表用例,返回结构为 { list: NovelBookshelfDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。该用例覆写了 pageSize 为 30(默认分页大小与其他分页用例不同)。
const bookshelf = NovelDomain.cases.bookshelf // 只 new 一次,缓存到变量
await bookshelf.refresh({ page: 1, limit: 30 })
console.log(bookshelf.list) // NovelBookshelfDto[]
console.log(bookshelf.hasMore)请求参数 NovelBookshelfQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
page | number | 是 | 页码 |
limit | number | 是 | 每页条数 |
响应 { list: NovelBookshelfDto[] }
NovelBookshelfDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 小说 ID,必填 |
bookCover | string | book_cover | 封面图,默认 '' |
thumb | string | thumbnail_cover_url | 缩略封面图,默认 '' |
bookName | string | book_name | 书名,默认 '' |
wechatBookId | string | wechat_book_id | 微信小说 ID,默认 '' |
desc | string | introduce | 简介,默认 '暂无简介' |
author | string | author | 作者,默认 '佚名' |
browse | number | browse_num | 浏览量,默认 0 |
freeChapters | number | free_chapter | 免费章节数,默认 20 |
deputy | string | deputy_cover_url | 副封面图,默认 '' |
keywords | string | keywords | 关键词,默认 '' |
lead_name | string | — | 领读人名称,默认 '' |
score | number | score | 评分,默认 80 |
sort | number | sort | 排序权重,默认 0 |
totalChapters | number | total_chapters | 总章节数,默认 0 |
totalWords | number | total_words | 总字数,默认 0 |
status | BookUpdateStatus | update_status | 更新状态,默认 BookUpdateStatus.COMPLETED |
book_source_type | number | — | 小说来源类型原始数值,默认 99 |
bookSourceType | BookSourceType | book_source_type | 小说来源类型,默认 BookSourceType.OTHER |
selectImage | boolean | — | 是否处于选中状态(业务态字段),默认 false |
near | NovelClassListNearChapterDto | near_chapter | 最近阅读章节信息,默认新建一个 NovelClassListNearChapterDto 实例 |
bookId | Identity | — | getter,等价于 id |
book_id | Identity | — | getter,等价于 id |
words | string | — | getter,totalWords 格式化后的展示文案 |
updateAt | number | — | getter,根据 near.updateAt 计算出的时间戳,无记录时为 0 |
NovelClassListNearChapterDto(嵌套 DTO,见 NovelClassListNearChapterDto 小节)
classify · 获取小说分类
const { data } = await NovelDomain.cases.classify.run({
channel: 1,
source: 1,
copyright_id: 0,
})
console.log(data) // NovelClassifyDto[]请求参数 NovelClassifyQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | Identity(string | number) | 是 | 频道 |
source | number | 是 | 来源 |
copyright_id | number | 是 | 版权方 ID |
响应 NovelClassifyDto[]
NovelClassifyDto(不可变,@Freeze)
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | id | 分类 ID,必填 |
text | string | class_name | 分类名称,默认 '' |
cp | number | copyright_id | 版权方 ID,默认 0 |
sort | number | sort | 排序权重,默认 0 |
channel | number | channel | 频道,默认 0 |
copyright_id | number | copyright_id | 版权方 ID(原始字段名同时保留),默认 0 |
classList · 获取分类下小说列表(分页)
这是分页列表用例,返回结构为 { list: NovelClassListDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。
const classList = NovelDomain.cases.classList
await classList.refresh({
channel: 1,
update_status: 0,
class_id: 10,
})
console.log(classList.list) // NovelClassListDto[]请求参数 NovelClassListQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | number | 是 | 频道 |
update_status | number | 是 | 更新状态 |
class_id | number | 是 | 分类 ID |
page | number | 否 | 页码(分页用例内部自动维护,一般无需手动传) |
limit | number | 否 | 每页条数(分页用例内部自动维护,一般无需手动传) |
响应 { list: NovelClassListDto[] }
NovelClassListDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | string | id | 小说 ID,必填 |
title | string | book_name | 书名,默认 '暂无书名' |
desc | string | introduce | 简介,默认 '暂无简介' |
cover | string | book_cover | 封面图,默认 '' |
thumb | string | thumbnail_cover_url | 缩略封面图,默认 '' |
author | string | author | 作者,默认 '佚名' |
score | number | score | 评分,默认 80 |
freeChapters | number | free_chapter | 免费章节数,默认 20 |
totalChapters | number | total_chapters | 总章节数,默认 0 |
words | number | total_words | 总字数,默认 0 |
update_status | number | update_status | 更新状态原始数值,默认 2 |
bookSourceType | BookSourceType | book_source_type | 小说来源类型,默认 BookSourceType.SWTJ |
updateAt | string | updated_at | 更新时间,默认 '' |
browse | number | browse_num | 浏览量,默认 0 |
classifyName | string | class_name | 分类名称,默认 '' |
classifyId | number | class_id | 分类 ID,默认 0 |
classify | NovelClassListClassifyDto | — | 分类详情,默认新建一个 NovelClassListClassifyDto 实例 |
near | NovelClassListNearChapterDto | — | 最近阅读章节信息,默认新建一个 NovelClassListNearChapterDto 实例 |
formatWords | string | — | getter,words 格式化后的展示文案 |
status | string | — | getter,'连载中' / '已完结' |
getAuthor | string | — | getter,author 为空时兜底 '佚名' |
getDesc | string | — | getter,desc 为空时兜底随机文案 |
getClassifyName | string | — | getter,classifyName 为空时兜底 '无分类' |
NovelClassListClassifyDto(不可变,@Freeze)
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 分类 ID |
channel | number | channel | 频道,默认 0 |
copyright_id | number | copyright_id | 版权方 ID,默认 0 |
sort | number | sort | 排序权重,默认 0 |
updateAt | string | updated_at | 更新时间,默认 '' |
text | string | class_name | 分类名称,默认 '' |
NovelClassListNearChapterDto 最近阅读章节
不可变(@Freeze),被 NovelBookshelfDto.near、NovelClassListDto.near 共同引用。
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 章节 ID |
book_id | number | book_id | 小说 ID,默认 0 |
book_name | string | title | 小说名称,默认 '' |
number | number | number | 章节序号,默认 0 |
isCharge | number | is_charge | 是否付费章节,默认 0 |
title | string | title | 章节标题,默认 '无章节标题' |
amount | number | unlock_coin | 解锁所需金币,默认 0 |
words | number | word_num | 字数,默认 0 |
updateAt | string | read_time | 最近阅读时间,默认 '' |
hasRead | boolean | — | getter,updateAt 不为空即返回 true |
search · 搜索小说(分页)
这是分页列表用例,返回结构为 { list: NovelSearchDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。
const search = NovelDomain.cases.search
await search.refresh({ channel: 1, keyword: '斗破苍穹' })
console.log(search.list) // NovelSearchDto[]请求参数 NovelSearchQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | number | 是 | 频道 |
keyword | string | 是 | 搜索关键词 |
响应 { list: NovelSearchDto[] }
NovelSearchDto(不可变,@Freeze)
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | id | 小说 ID,必填 |
cover | string | book_cover | 封面图,默认 '' |
name | string | book_name | 书名,默认 '暂无书名' |
bookSourceType | BookSourceType | book_source_type | 小说来源类型,默认 BookSourceType.FL |
browse | number | browse_num | 浏览量,默认 100 |
channel_id | number | channel | 频道,默认 1 |
classify | string | class_name | 分类名称,默认 '' |
classifyId | number | — | 分类 ID,默认 0 |
free_chapter | number | free_chapter | 免费章节数,默认 20 |
describe | string | introduce | 简介,默认 '暂无简介' |
chapters | number | total_chapters | 总章节数,默认 0 |
words | number | total_words | 总字数,默认 0 |
score | number | score | 评分,默认 80 |
update_status | number | update_status | 更新状态原始数值,默认 1 |
updatedAt | string | updated_at | 更新时间 |
createdAt | string | created_at | 创建时间 |
status | string | undefined | — | getter,BookUpdateStatus 反查得到的中文文案 |
channel | string | undefined | — | getter,BookChannel 反查得到的中文文案 |
hotsearch · 获取热搜数据
const { data } = await NovelDomain.cases.hotsearch.run(null)
console.log(data) // NovelHotsearchDto请求参数 NovelHotsearchQueryParams
无请求参数,固定传 null。
响应 NovelHotsearchDto
NovelHotsearchDto(不可变,@Freeze)
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 必填 |
bags · 获取书架书包推荐数据
const { data } = await NovelDomain.cases.bags.run({
spread_id: '1001',
})
console.log(data) // NovelBagsDto请求参数 NovelBagsQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
spread_id | string | number | 否 | 推广 ID |
响应 NovelBagsDto
NovelBagsDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 小说 ID |
bookCover | string | book_cover | 封面图,默认 '' |
thumb | string | thumbnail_cover_url | 缩略封面图,默认 '' |
bookName | string | book_name | 书名,默认 '' |
desc | string | introduce | 简介,默认 '' |
author | string | author | 作者,默认 '佚名' |
freeChapters | number | free_chapter | 免费章节数,默认 20 |
keywords | string | keywords | 关键词,默认 '' |
leadName | string | lead_name | 领读人名称,默认 '' |
updateAt | string | updated_at | 更新时间,默认 '' |
score | number | score | 评分,默认 80 |
totalChapters | number | total_chapters | 总章节数,默认 0 |
totalWords | number | total_words | 总字数,默认 0 |
updateStatus | BookUpdateStatus | update_status | 更新状态,默认 BookUpdateStatus.COMPLETED |
bookSourceType | BookSourceType | book_source_type | 小说来源类型,默认 BookSourceType.OTHER |
star | number | — | getter,500 ~ 1000 之间的随机展示数值 |
formatAuthor | string | — | getter,'{author}•著' 或 '佚名' |
chapters | string | — | getter,'共{totalChapters}章' |
status | string | — | getter,'连载中' / '已完结' |
scoreName | string | null | — | getter,score >= 80 时返回 '畅销',否则 null |
words | string | — | getter,totalWords 格式化后的展示文案 |
getDesc | string | — | getter,desc 为空时兜底随机文案 |
rankList · 获取榜单列表(分页)
这是分页列表用例,返回结构为 { list: NovelRankListDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。每一项 NovelRankListDto 代表一个榜单,其内部 list 字段是该榜单下的小说数据。
const rankList = NovelDomain.cases.rankList
await rankList.refresh({ channel: 1 })
console.log(rankList.list) // NovelRankListDto[]请求参数 NovelRankListQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | number(0|1|2 或其他数值) | 是 | 频道:0 通用,1 男频,2 女频 |
list_name | string | 否 | 榜单名称,指定后只返回该榜单 |
page | number | 否 | 页码(分页用例内部自动维护) |
limit | number | 否 | 每页条数(分页用例内部自动维护) |
响应 { list: NovelRankListDto[] }
NovelRankListDto
| 字段 | 类型 | 说明 |
|---|---|---|
info | NovelRankListInfoDto | 榜单信息,默认新建一个 NovelRankListInfoDto 实例 |
list | NovelRankListDataDto[] | 榜单下的小说数据,默认 [] |
data | NovelRankListDataDto[] | getter,按 sort 字段排序后的 list |
upList | NovelRankListDataDto[] | getter,按 score 升序排序后的 list |
downList | NovelRankListDataDto[] | getter,按 score 降序排序后的 list |
groupToThree | NovelRankListDataDto[][] | getter,list 每 3 条分为一组 |
sliceToSix | NovelRankListDataDto[] | getter,list 前 6 条 |
sliceToFour | NovelRankListDataDto[] | getter,list 前 4 条 |
sliceToFive | NovelRankListDataDto[] | getter,list 前 5 条 |
sliceToSeven | NovelRankListDataDto[] | getter,list 前 7 条 |
NovelRankListDataDto 榜单小说数据
被 NovelRankListDto.list 与 rankSingle 共同引用。
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | id | 小说 ID,必填,默认 0 |
title | string | book_name | 书名,默认 '暂无书名' |
wechatBookId | string | wechat_book_id | 微信小说 ID,默认 '' |
desc | string | introduce | 简介,默认 '暂无简介' |
cover | string | book_cover | 封面图,默认 '' |
thumb | string | thumbnail_cover_url | 缩略封面图,默认 '' |
author | string | author | 作者,默认 '佚名' |
score | number | score | 评分,默认 80 |
freeChapters | number | free_chapter | 免费章节数,默认 20 |
totalChapters | number | total_chapters | 总章节数,默认 0 |
words | number | total_words | 总字数,默认 0 |
update_status | number | update_status | 更新状态原始数值,默认 2 |
bookSourceType | BookSourceType | book_source_type | 小说来源类型,默认 BookSourceType.SWTJ |
updateAt | string | updated_at | 更新时间,默认 '' |
browse | number | browse_num | 浏览量,默认 0 |
classifyName | string | class_name | 分类名称,默认 '' |
classifyId | number | class_id | 分类 ID,默认 0 |
sort | number | sort | 排序权重,默认 0 |
star | number | — | getter,500 ~ 1000 之间的随机展示数值 |
getBrowse | number | — | getter,100 ~ 10000 之间的随机展示数值 |
status | string | — | getter,'连载中' / '已完结' |
getAuthor | string | — | getter,author 为空时兜底 '佚名' |
getDesc | string | — | getter,desc 为空时兜底随机文案 |
getClassifyName | string | — | getter,classifyName 为空时兜底 '无分类' |
NovelRankListInfoDto 榜单信息
不可变(@Freeze),被 NovelRankListDto.info 与 NovelRankSingleDto.info 共同引用。
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 榜单 ID |
title | string | title | 榜单名称,默认 '热门榜单' |
channel | number | channel | 频道,默认 1 |
code | string | code | 榜单代码,默认 '' |
desc | string | describe | 榜单描述,默认 '' |
numbers | number | book_number | 榜单收录小说数,默认 0 |
sort | number | sort | 排序权重 |
adCatalogues · 获取 IAA 模式小说目录(分页)
这是分页列表用例,返回结构为 { list: NovelAdCataloguesDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。
const adCatalogues = NovelDomain.cases.adCatalogues
await adCatalogues.refresh({ book_id: 1001 })
console.log(adCatalogues.list) // NovelAdCataloguesDto[]请求参数 NovelAdCataloguesQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | number | string | 是 | 小说 ID |
响应 { list: NovelAdCataloguesDto[] }
NovelAdCataloguesDto
| 字段 | 类型 | 说明 |
|---|---|---|
id | Identity(string | number) | 章节 ID,必填 |
amount | number | 解锁所需金币/广告次数,默认 0 |
is_unlock | boolean | 是否已解锁,默认 false |
number | number | 章节序号,默认 1 |
title | string | 章节标题,默认 '' |
adUnlock · IAA 模式解锁章节
const { data } = await NovelDomain.cases.adUnlock.run({
book_id: 1001,
chapter_id: 2001,
spread_id: '3001',
scene: 0,
ad_confirmed: 1,
is_auto: 0,
})
console.log(data) // NovelAdUnlockDto请求参数 NovelAdUnlockBodyParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | Identity(number | string) | 是 | 小说 ID |
chapter_id | Identity | 是 | 章节 ID |
spread_id | Identity | 是 | 推广 ID |
scene | DualState(0 | 1) | 是 | 解锁场景标记 |
ad_confirmed | DualState | 是 | 是否已完成广告观看确认 |
is_auto | DualState | 是 | 是否自动解锁 |
响应 NovelAdUnlockDto
NovelAdUnlockDto
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 必填 |
read · IAP 模式阅读章节
用于付费(IAP)小说的章节阅读接口。当后台返回错误码 417001 / 417002(表示该章节尚未解锁)时,该用例不会抛出异常,而是用错误响应体中的 data 构造一个 NovelReadDto 正常返回,供业务方拿到章节的基础信息(如价格、字数)后引导用户解锁;其他错误码则正常抛出。
const { data } = await NovelDomain.cases.read.run({
book_id: 1001,
chapter_id: 2001,
})
console.log(data) // NovelReadDto请求参数 NovelReadQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | number | 是 | 小说 ID |
chapter_id | number | 否 | 章节 ID,缺省时后台按上下文推断(如首章/续读) |
响应 NovelReadDto
NovelReadDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | id | 章节 ID,必填 |
book_id | number | book_id | 小说 ID,默认 0 |
book | any | book | 小说附加信息(后台透传,未做类型化) |
pid | number | undefined | prev_id | 上一章 ID |
nid | number | undefined | next_id | 下一章 ID |
book_title | string | book_title | 小说名称,默认 '' |
title | string | title | 章节标题,默认 '' |
content | string | content | 章节正文原始文本,默认 '' |
book_introduce | string | book_introduce | 小说简介,默认 '' |
book_cover_url | string | book_cover_url | 小说封面图,默认 '' |
total_chapters | number | total_chapters | 总章节数,默认 0 |
word_num | number | word_num | 本章字数,默认 0 |
amount | number | amount | 解锁所需金币,默认 0 |
unlock_coin | number | unlock_coin | 解锁所需金币,默认 0 |
number | number | number | 章节序号,默认 1 |
is_auto | number | is_auto | 是否自动解锁,默认 0 |
is_unlock | boolean | is_unlock | 是否已解锁,默认 false |
isCharge | boolean | is_charge | 是否付费章节,默认 false |
bookshelfStatus | boolean | is_bookshelf | 是否已加入书架,默认 false |
contents | Array<NovelViewItem> | — | 排版后的阅读区可视内容,初始为 [],由 formatMultiPages/formatSinglePage 生成 |
turnPageFormatedContent | TurnPageContentViewProps | — | 手动翻页模式下排版后的内容,由 formatTurnPage 生成 |
formatMultiPages | (sizes: ContentFormatSizes, option: ContentFormatOption) => void | — | 方法,按可视区尺寸将 content 分页写入 contents(多页/滚动模式) |
formatSinglePage | (option: ContentFormatOption) => void | — | 方法,将 content 整章排版为单页写入 contents |
formatTurnPage | () => void | — | 方法,将 content 排版为手动翻页格式写入 turnPageFormatedContent |
paragraph | () => string[] | — | 方法,将 content 按段落切分为字符串数组 |
排版相关方法用到的辅助类型:
| 类型 | 定义 | 说明 |
|---|---|---|
ContentFormatSizes | { words: number; lines: number } | 可视区可容纳的字数/行数 |
ContentFormatOption | { lineHeight: number; fontSize: number; fontName: string } | 排版所需的行高/字号/字体 |
NovelViewItem | { type: NovelViewType; content: NovelContentItem[]; title: string; number: number; amount: number; ad?: PlayListDto } | 阅读区一页的可视内容,type 见 NovelViewType;ad 为文中插入的广告位,类型为 ad 领域的 PlayListDto |
NovelContentItem | { type: NovelContentType; word: string; className: string; style: string; fontName: string; fontStyle: string } | 一页中的一个内容片段,type 见 NovelContentType |
TurnPageContentViewProps | { type: TurnPageType; content: TurnPageContentViewItemProps[]; title: string; number: number; amount: number; words: number } | 手动翻页模式下一章的渲染内容,type 见 TurnPageType |
TurnPageContentViewItemProps | { type: TurnPageContentViewItemType; content: string | null; show: boolean } | 手动翻页模式下一页的渲染片段,type 见 TurnPageContentViewItemType |
adRead · IAA 模式阅读章节
用于广告解锁(IAA)小说的章节阅读接口。当后台返回错误码 417001 / 417002(章节未解锁)时,该用例会抛出一个 Error,并在其上挂载 code(错误码)与 data(用 NovelReadDto.fromJson 转换后的章节基础信息)两个附加属性,供业务方捕获后引导用户看广告解锁;其他错误则原样抛出。
try {
const { data } = await NovelDomain.cases.adRead.run({
book_id: 1001,
chapter_id: 2001,
spread_id: '3001',
scene: 0,
force_auto_unlock: 0,
not_record: 0,
book_source_type: 1,
})
console.log(data) // NovelAdReadDto
} catch (error: any) {
if (error.code === 417001 || error.code === 417002) {
console.log(error.data) // NovelReadDto,章节未解锁时的基础信息
}
}请求参数 NovelAdReadQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | Identity(string | number) | 是 | 小说 ID |
chapter_id | Identity | 是 | 章节 ID |
spread_id | Identity | 是 | 推广 ID |
scene | DualState(0 | 1) | 是 | 阅读场景标记 |
force_auto_unlock | DualState | 是 | 是否强制自动解锁 |
not_record | DualState | 是 | 是否跳过阅读记录 |
book_source_type | number | 是 | 小说来源类型(数值,对应 BookSourceType) |
响应 NovelAdReadDto
NovelAdReadDto
字段结构、排版方法与 NovelReadDto 基本一致,差异仅在于 id/pid/nid 使用 Identity(string \| number)类型,且没有 book/book_introduce/book_cover_url/total_chapters/unlock_coin 等字段:
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 章节 ID,必填 |
book_id | number | book_id | 小说 ID |
pid | Identity | undefined | prev_id | 上一章 ID |
nid | Identity | undefined | next_id | 下一章 ID |
title | string | title | 章节标题,默认 '' |
word_num | number | word_num | 本章字数,默认 0 |
amount | number | amount | 解锁所需金币,默认 0 |
number | number | number | 章节序号,默认 1 |
is_auto | number | is_auto | 是否自动解锁,默认 0 |
is_unlock | boolean | is_unlock | 是否已解锁,默认 false |
isCharge | boolean | is_charge | 是否付费章节,默认 false |
bookshelfStatus | boolean | is_bookshelf | 是否已加入书架,默认 false |
contents | Array<NovelViewItem> | — | 排版后的阅读区可视内容,用法同 NovelReadDto |
turnPageFormatedContent | TurnPageContentViewProps | — | 手动翻页模式下排版后的内容,用法同 NovelReadDto |
formatMultiPages / formatSinglePage / formatTurnPage / paragraph | 同 NovelReadDto | — | 排版辅助方法,用法一致 |
catalogues · 获取 IAP 模式小说目录(分页)
这是分页列表用例,返回结构为 { list: NovelCataloguesDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。
const catalogues = NovelDomain.cases.catalogues
await catalogues.refresh({ book_id: 1001, page: 1, limit: 50 })
console.log(catalogues.list) // NovelCataloguesDto[]请求参数 NovelCataloguesQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | string | number | 是 | 小说 ID |
page | number | 是 | 页码 |
limit | number | 是 | 每页条数 |
响应 { list: NovelCataloguesDto[] }
NovelCataloguesDto
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | number | 章节 ID,必填 |
amount | number | 解锁所需金币,默认 0 |
is_unlock | boolean | 是否已解锁,默认 false |
number | number | 章节序号,默认 1 |
title | string | 章节标题,默认 '' |
detail · 获取小说详情
const { data } = await NovelDomain.cases.detail.run({
book_id: 1001,
scene: 0,
})
console.log(data) // NovelDetailDto请求参数 NovelDetailQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | string | number | 是 | 小说 ID |
scene | number | 是 | 场景标记 |
响应 NovelDetailDto
NovelDetailDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | Identity(string | number) | id | 小说 ID,必填 |
is_auto | 0 | 1 | is_auto | 是否自动解锁,默认 0 |
bookshelfStatus | boolean | is_bookshelf | 是否已加入书架,默认 false |
book_cover | string | book_cover | 封面图,默认给定占位图 URL |
thumb | string | thumbnail_cover_url | 缩略封面图,默认 '' |
author | string | author | 作者,默认 '佚名' |
book_name | string | book_name | 书名,默认 '暂无书名' |
desc | string | introduce | 简介,默认 '暂无介绍' |
total_chapters | number | total_chapters | 总章节数,默认 1 |
total_words | number | total_words | 总字数,默认 0 |
browse_num | number | browse_num | 浏览量,默认 1 |
score | number | score | 评分,默认 0 |
update_status | number | update_status | 更新状态原始数值,默认 0 |
class_name | string | class_name | 分类名称,默认 '' |
class_id | number | class_id | 分类 ID,默认 0 |
keywords | string | keywords | 关键词,默认 '' |
leadName | string | lead_name | 领读人名称,默认 '' |
near | NovelDetailNearDto | near_chapter | 最近阅读章节信息,默认新建一个 NovelDetailNearDto 实例 |
formatAuthor | string | — | getter,'{author}•著' 或 '佚名' |
words | string | — | getter,'{格式化后的 total_words}字' |
chapters | string | — | getter,'共{total_chapters}章' |
status | string | — | getter,'连载中' / '已完结' |
scoreName | string | null | — | getter,score >= 80 时返回 '畅销',否则 null |
NovelDetailNearDto 详情页最近阅读章节
不可变(@Freeze)。
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
bookId | number | — | 小说 ID,默认 0 |
chapterTitle | string | title | 章节标题,默认 '' |
number | number | number | 章节序号,默认 1 |
amount | number | unlock_coin | 解锁所需金币,默认 0 |
words | number | word_num | 字数,默认 0 |
chapterId | number | id | 章节 ID,默认 0 |
isCharge | boolean | is_charge | 是否付费章节,默认 false |
unlock · IAP 模式解锁章节
解锁成功后返回该章节的完整阅读内容(与 read 用例返回同一种 DTO)。
const { data } = await NovelDomain.cases.unlock.run({
book_id: 1001,
chapter_id: 2001,
spread_id: '3001',
scene: 0,
ad_confirmed: 0,
is_auto: 0,
})
console.log(data) // NovelReadDto请求参数 NovelUnlockBodyParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | Identity(number | string) | 是 | 小说 ID |
chapter_id | Identity | 是 | 章节 ID |
spread_id | Identity | 是 | 推广 ID |
scene | DualState(0 | 1) | 是 | 解锁场景标记 |
ad_confirmed | DualState | 是 | 是否已完成广告观看确认 |
is_auto | DualState | 是 | 是否自动解锁 |
响应 NovelReadDto
字段定义见 read 用例的 NovelReadDto。
reading · 上报阅读时长
await NovelDomain.cases.reading.run({ duration: 30 })请求参数 NovelReadingBodyParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
duration | number | 是 | 本次上报的阅读时长(秒) |
响应
无格式化 DTO,直接透传后台原始返回。
delBookshelf · 从书架移除小说
await NovelDomain.cases.delBookshelf.run({ book_id: 1001 })请求参数 NovelDelBookshelfBodyParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | string | number | 是 | 小说 ID |
响应
无格式化 DTO,直接透传后台原始返回。
addBookshelf · 添加小说到书架
该用例继承自 ModuleUseCase(而非 BaseUseCase),额外提供响应式的 status(ShallowRef<ModuleUseCaseStatus | null>,取值 running/success/failure)与 error(失败时的错误信息字符串),便于在模板中直接绑定加载态,无需额外维护 loading 变量:
const addBookshelf = NovelDomain.cases.addBookshelf
await addBookshelf.run({ book_id: 1001 })
console.log(addBookshelf.status.value) // 'success' | 'failure' | 'running'
console.log(addBookshelf.data) // 等价于 run() 返回的 data请求参数 NovelAddBookshelfQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | string | number | 是 | 小说 ID |
响应
无格式化 DTO,直接透传后台原始返回(NovelAddBookshelfDto 实体虽已定义但当前未被此用例使用)。
reads · 获取阅读记录(分页)
这是分页列表用例,返回结构为 { list: NovelReadsDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。
const reads = NovelDomain.cases.reads
await reads.refresh({ page: 1, limit: 20 })
console.log(reads.list) // NovelReadsDto[]请求参数 NovelReadsQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
page | number | 是 | 页码 |
limit | number | 是 | 每页条数 |
响应 { list: NovelReadsDto[] }
NovelReadsDto
| 字段 | 类型 | 后台原始字段 | 说明 |
|---|---|---|---|
id | number | id | 阅读记录 ID,必填 |
book_id | number | book_id | 小说 ID,默认 0 |
appId | number | app_id | 应用 ID |
bookCover | string | book_cover | 封面图,默认 '' |
bookTitle | string | book_title | 小说名称,默认 '' |
created_at | string | created_at | 创建时间,默认 '' |
isAuto | number | — | 是否自动解锁,默认 0 |
wechatBookId | string | wechat_book_id | 微信小说 ID,默认 '' |
isBookshelf | boolean | is_bookshelf | 是否已加入书架,默认 false |
read_chapter_id | number | read_chapter_id | 最近阅读章节 ID,默认 0 |
read_chapter_name | string | read_chapter_name | 最近阅读章节标题,默认 '' |
read_chapter_number | number | read_chapter_number | 最近阅读章节序号,默认 0 |
uid | number | uid | 用户 ID,默认 0 |
updated_at | string | updated_at | 更新时间,默认 '' |
delRead · 删除阅读记录
await NovelDomain.cases.delRead.run({ read_id: 5001 })请求参数 NovelDelReadBodyParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
read_id | string | number | 是 | 阅读记录 ID |
响应
无格式化 DTO,直接透传后台原始返回。
rankSingle · 获取单个榜单详情(分页)
这是分页列表用例,返回结构为 { list: NovelRankListDataDto[] }(分页遍历的是该榜单下的小说数据,与 rankList 分页遍历"多个榜单"不同),建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。请求路径与 rankList 相同(GET novel/list),但响应格式化器不同:内部先用 NovelRankSingleDto.fromJson 解析出单个榜单对象,再把其 list 字段包装为分页结果返回。
const rankSingle = NovelDomain.cases.rankSingle
await rankSingle.refresh({ channel: 1, list_name: '新书榜' })
console.log(rankSingle.list) // NovelRankListDataDto[]请求参数 NovelRankSingleQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
channel | number | 是 | 频道 |
list_name | string | 是 | 榜单名称 |
响应 { list: NovelRankListDataDto[] }
NovelRankListDataDto 字段定义见 rankList 用例中的 NovelRankListDataDto。
补充:中间态的 NovelRankSingleDto(不可变,@Freeze,仅用于内部解析,不直接作为 run() 的返回值)结构如下:
| 字段 | 类型 | 说明 |
|---|---|---|
info | NovelRankListInfoDto | 榜单信息,默认新建一个 NovelRankListInfoDto 实例 |
list | NovelRankListDataDto[] | 榜单下的小说数据,默认 [] |
cataloguesAll · 获取全量小说目录(分页)
这是分页列表用例,返回结构为 { list: NovelCataloguesAllDto[] },建议参考快速开始 · 分页列表请求的用法只 new 一次并复用实例。与 catalogues 不同,该接口不分页拉取而是一次性返回全量目录,且响应未经过 DTO 格式化器转换,直接透传后台原始返回并按 PagedResultDto 类型断言包装。
const cataloguesAll = NovelDomain.cases.cataloguesAll
await cataloguesAll.refresh({ book_id: 1001 })
console.log(cataloguesAll.list) // 后台原始返回,类型标注为 NovelCataloguesAllDto[],但运行时未做字段转换请求参数 NovelCataloguesAllQueryParams
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
book_id | number | 是 | 小说 ID |
响应 { list: NovelCataloguesAllDto[] }
NovelCataloguesAllDto(不可变,@Freeze;如前所述,该仓储方法实际未接入此 DTO 的转换器,仅作为类型标注)
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 必填 |
枚举
BookChannel 小说频道
| 枚举成员 | value | code | 说明 |
|---|---|---|---|
GENERAL | 0 | general | 通频 |
MALE | 1 | male | 男频 |
FEMALE | 2 | female | 女频 |
ALL | 3 | all | 不区分频道 |
BookSourceType 小说来源类型
| 枚举成员 | value | code | 说明 |
|---|---|---|---|
WTDJ | 1 | wtdj | 外推小说 |
WTGB | 2 | wtgb | 外推挂包 |
NT | 3 | nt | 内推 |
SWTJ | 4 | swtj | 首位推荐 |
BDTJ | 5 | bdtj | 榜单推荐 |
FL | 6 | fl | 分类 |
SEARCH | 7 | search | 搜索 |
XTTS | 8 | xtts | 系统推送 |
XSMF | 9 | xsmf | 限时免费 |
SHARE | 10 | share | 分享 |
OTHER | 99 | other | 其他 |
BookUpdateStatus 小说更新状态
| 枚举成员 | value | code | 说明 |
|---|---|---|---|
ALL | 0 | all | 全部 |
SERIALIZED | 1 | serialized | 连载中 |
COMPLETED | 2 | completed | 已完结 |
以下四个是原生 TypeScript enum(非 BaseEnumeration,无 code/text,仅用于 NovelReadDto/NovelAdReadDto 排版辅助类型的内部标记),只列出成员名与数值:
NovelViewType 阅读区可视内容类型
| 枚举成员 | 数值 | 说明 |
|---|---|---|
content | 0 | 正文内容 |
ad | 1 | 广告位 |
locked | 2 | 未解锁遮罩 |
NovelContentType 正文内容片段类型
| 枚举成员 | 数值 | 说明 |
|---|---|---|
block | 0 | 段落块 |
title | 1 | 标题 |
head | 2 | 页首 |
tail | 3 | 页尾 |
mid | 4 | 中间态 |
txt | 5 | 普通文本 |
footer | 6 | 页脚 |
TurnPageType 手动翻页章节类型
| 枚举成员 | 数值 | 说明 |
|---|---|---|
content | 0 | 正文内容 |
ad | 1 | 隔章广告 |
locked | 2 | 未解锁遮罩 |
TurnPageContentViewItemType 手动翻页内容片段类型
| 枚举成员 | 数值 | 说明 |
|---|---|---|
title | 0 | 标题 |
ad | 1 | 章内文中广告 |
txt | 2 | 普通文本 |
end | 3 | 章节结尾(固定文案"--本章结束--",可按需修改) |
menu | 4 | 菜单 |
others | 5 | 其他 |