新增项目详情与开发文档网页

This commit is contained in:
HapeLee
2026-05-27 01:00:58 +08:00
parent 65d5c84b56
commit b7826b54a7
35 changed files with 3499 additions and 15 deletions
+107
View File
@@ -0,0 +1,107 @@
# 首页模块 (Homepage Modules) 配置规范
[[toc]]
源的 `homepageModules` 字段允许开发者声明该源在首页展示的内容模块。这些模块通过 JSON
数组进行定义,支持高度自定义的布局和数据来源。
## 1. 数据结构 (Data Structure)
`homepageModules` 是一个包含多个模块定义对象的 JSON 数组。
### 模块通用字段
| 字段 | 类型 | 必须 | 说明 |
|:-----------------|:---------|:---|:-------------------------------------------|
| **key** | `String` | 是 | 模块唯一标识。建议使用 `[a-z0-9_]` 字符。用于保存用户的排序/显隐设置。 |
| **type** | `Enum` | 是 | 模块类型。定义了渲染方式和交互逻辑。 |
| **title** | `String` | 是 | 模块默认标题。用户可在本地自定义覆盖。 |
| **kindTitle** | `String` | 否 | 用于匹配源「发现」规则中的分类标题。匹配成功后自动继承其 URL 和规则。 |
| **url** | `String` | 否 | 显式指定数据接口 URL。优先级高于 `kindTitle`。支持变量替换。 |
| **args** | `String` | 否 | 附加参数。在 `buttonGroup` 类型中为 JSON 数组字符串。 |
| **layoutConfig** | `Object` | 否 | 布局配置对象,用于调整列数、行数、图标等。 |
## 2. 模块类型 (Module Types)
### 列表与轮播类
| 类型 | 描述 | 特点 |
|:----------|:------|:----------------------|
| `banner` | 横滑轮播图 | 适合展示高权重的精品推荐,使用大图封面 |
| `ranking` | 排行榜列表 | 垂直列表展示,带排名序号 |
| `card` | 推荐卡片 | 横向滑动的卡片流,同时显示封面、标题及简介 |
### 网格类
| 类型 | 描述 | 特点 |
|:---------------|:------|:-----------------|
| `grid` | 标准网格 | 最常用的展示形式,支持自定义行列 |
| `gridRanking` | 网格排行榜 | 多行多列的排行展示,横向翻页 |
| `infiniteGrid` | 无限网格 | 垂直滚动的网格流,无限加载 |
| `waterfall` | 错位瀑布流 | 垂直错位排列的书架流,无限加载 |
### 功能类
| 类型 | 描述 | 特点 |
|:--------------|:------|:-------------------------------------------|
| `buttonGroup` | 快捷按钮组 | 渲染为一组圆形/图标按钮,支持自动填充宽度与自动分列。通常用于放置常用分类或功能入口 |
## 3. 布局配置 (LayoutConfig)
通过 `layoutConfig` 对象,可以精细化控制模块的表现。
| 属性 | 类型 | 适用类型 | 默认值 | 说明 |
|:----------|:---------|:------------------------------------|:----|:----------------------------------------|
| `columns` | `Int` | `grid`, `waterfall`, `infiniteGrid` | 3 | 每行显示的列数 |
| `icon` | `String` | `buttonGroup` | - | 按钮组的默认统一图标 URL |
| `icons` | `Object` | `buttonGroup` | - | 图标映射表。例:`{"排行": "http://path/to/icon"}` |
## 4. 数据绑定逻辑 (Data Binding)
1. **自动匹配**:如果提供了 `kindTitle`,系统会遍历源 `exploreKinds()` 返回的列表。如果某个分类的
`title` 与之完全一致,该模块将自动使用该分类的 `url`
2. **静态指定**:如果提供了 `url`,系统将直接请求该 URL。
3. **降级逻辑**:若 `kindTitle` 未匹配且无 `url`,模块将回退至源的主 `exploreUrl`
## 5. 完整 JSON 示例
```json
[
{
"key": "top_banner",
"type": "banner",
"title": "精品强推",
"kindTitle": "首页推荐"
},
{
"key": "quick_nav",
"type": "buttonGroup",
"title": "分类导航",
"args": "[\"武侠\", \"仙侠\", \"都市\", \"历史\"]",
"layoutConfig": {
"icon": "https://example.com/icons/default.png",
"icons": {
"武侠": "https://example.com/icons/wuxia.png"
}
}
},
{
"key": "hot_rank",
"type": "ranking",
"title": "热门榜单",
"kindTitle": "排行榜",
"layoutConfig": {
"rows": 5
}
},
{
"key": "explore_waterfall",
"type": "waterfall",
"title": "发现更多",
"kindTitle": "全部",
"layoutConfig": {
"columns": 2
}
}
]
```
+5
View File
@@ -0,0 +1,5 @@
# 功能规范
- [首页模块配置](./homepage-modules) — `homepageModules` JSON 字段规范
- [关联书籍配置](./related-books) — `ruleBookInfo.relatedBooks` 字段规范
- [MIME 类型参考](./mime-types) — 支持的文件扩展名和 MIME 类型
+82
View File
@@ -0,0 +1,82 @@
# MIME 类型参考
以下是阅读支持的 MIME 类型(ContentType)参考表。
| 扩展名 | 描述 | MIME 类型 |
|:-------|:------------------------------|:--------------------------------------------------------------------------|
| acc | AAC 音频 | audio/aac |
| abw | AbiWord 文件 | application/x-abiword |
| arc | 存档文件 | application/x-freearc |
| avi | 音频视频交错格式 | video/x-msvideo |
| azw | 亚马逊 Kindle 电子书格式 | application/vnd.amazon.ebook |
| bin | 任何类型的二进制数据 | application/octet-stream |
| bmp | Windows OS / 2 位图图形 | image/bmp |
| bz | BZip 存档 | application/x-bzip |
| bz2 | BZip2 存档 | application/x-bzip2 |
| csh | C-Shell 脚本 | application/x-csh |
| css | 级联样式表(CSS | text/css |
| csv | 逗号分隔值(CSV | text/csv |
| doc | 微软 Word 文件 | application/msword |
| docx | Microsoft WordOpenXML | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| eot | MS Embedded OpenType 字体 | application/vnd.ms-fontobject |
| epub | 电子出版物(EPUB | application/epub+zip |
| gz | GZip 压缩档案 | application/gzip |
| gif | 图形交换格式(GIF) | image/gif |
| htm | 超文本标记语言(HTML) | text/html |
| html | 超文本标记语言(HTML) | text/html |
| ico | 图标格式 | image/vnd.microsoft.icon |
| ics | iCalendar 格式 | text/calendar |
| jar | Java 存档 | application/java-archive |
| jpeg | JPEG 图像 | image/jpeg |
| jpg | JPEG 图像 | image/jpeg |
| js | JavaScript | text/javascript |
| json | JSON 格式 | application/json |
| jsonld | JSON-LD 格式 | application/ld+json |
| mid | 乐器数字接口(MIDI | audio/midi |
| midi | 乐器数字接口(MIDI | audio/midi |
| mjs | JavaScript 模块 | text/javascript |
| mp3 | MP3 音频 | audio/mpeg |
| mpeg | MPEG 视频 | video/mpeg |
| mpkg | 苹果安装程序包 | application/vnd.apple.installer+xml |
| odp | OpenDocument 演示文稿文档 | application/vnd.oasis.opendocument.presentation |
| ods | OpenDocument 电子表格文档 | application/vnd.oasis.opendocument.spreadsheet |
| odt | OpenDocument 文字文件 | application/vnd.oasis.opendocument.text |
| oga | OGG 音讯 | audio/ogg |
| ogv | OGG 视频 | video/ogg |
| ogx | OGG | application/ogg |
| opus | OPUS 音频 | audio/opus |
| otf | otf 字体 | font/otf |
| png | 便携式网络图形 | image/png |
| pdf | Adobe 可移植文档格式(PDF | application/pdf |
| php | php | application/x-httpd-php |
| ppt | Microsoft PowerPoint | application/vnd.ms-powerpoint |
| pptx | Microsoft PowerPointOpenXML | application/vnd.openxmlformats-officedocument.presentationml.presentation |
| rar | RAR 档案 | application/vnd.rar |
| rtf | 富文本格式 | application/rtf |
| sh | Bourne Shell 脚本 | application/x-sh |
| svg | 可缩放矢量图形(SVG) | image/svg+xml |
| swf | 小型 Web 格式(SWF | application/x-shockwave-flash |
| tar | 磁带存档(TAR | application/x-tar |
| tif | 标记图像文件格式(TIFF) | image/tiff |
| tiff | 标记图像文件格式(TIFF) | image/tiff |
| ts | MPEG 传输流 | video/mp2t |
| ttf | ttf 字体 | font/ttf |
| txt | 文本 | text/plain |
| vsd | 微软 Visio | application/vnd.visio |
| wav | 波形音频格式 | audio/wav |
| weba | WEBM 音频 | audio/webm |
| webm | WEBM 视频 | video/webm |
| webp | WEBP 图像 | image/webp |
| woff | Web 开放字体格式(WOFF | font/woff |
| woff2 | Web 开放字体格式(WOFF | font/woff2 |
| xhtml | XHTML | application/xhtml+xml |
| xls | 微软 Excel | application/vnd.ms-excel |
| xlsx | 微软 ExcelOpenXML | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| xml | XML | application/xml |
| xul | XUL | application/vnd.mozilla.xul+xml |
| zip | ZIP | application/zip |
| 3gp | 3GPP 音视频容器 | video/3gpp |
| 3gp | 3GPP 纯音频 | audio/3gpp2 |
| 3g2 | 3GPP2 音视频容器 | video/3gpp2 |
| 3g2 | 3GPP2 纯音频 | audio/3gpp2 |
| 7z | 7-zip 存档 | application/x-7z-compressed |
+178
View File
@@ -0,0 +1,178 @@
# 关联书籍 (Related Books) 配置规范
[[toc]]
源的 `ruleBookInfo.relatedBooks`
字段允许开发者声明一组关联书籍模块,用于在书籍详情页底部展示「关联书籍」横滑轮播。支持配置多个模块,每个模块有独立的标题和数据来源,例如「同作者作品」、「读这本书的人还在读」等。
## 1. 字段位置
在源编辑器的 **详情页** 选项卡中,新增了 `relatedBooks` 字段。
```
详情页 → relatedBooks
```
对应 JSON 路径:`ruleBookInfo.relatedBooks`
## 2. 数据结构
`relatedBooks` 是一个包含多个模块定义对象的 JSON 数组。
### 模块字段
| 字段 | 类型 | 必须 | 说明 |
|:----------|:---------|:---|:------------------------------------------|
| **key** | `String` | 否 | 模块唯一标识。建议使用 `[a-z0-9_]` 字符。若未提供则使用 title。 |
| **title** | `String` | 是 | 模块标题,显示在轮播上方。如「同作者作品」。 |
| **url** | `String` | 是 | 数据接口 URL。支持模板变量替换。 |
## 3. 工作原理
1. 当用户打开某本书的详情页时,如果该源配置了 `relatedBooks`,系统会解析 JSON 数组。
2. 对每个模块,系统将 URL 中的模板变量替换为当前书籍的实际值,然后发起请求。
3. 返回的数据使用源的 **发现规则**`ruleExplore`)进行解析,获取书籍列表。
4. 解析后的书籍以横滑轮播的形式展示在详情页的操作按钮和书籍简介之间。
5. 当前查看的书籍会自动从结果中过滤掉,避免重复显示。
6. 如果某个模块请求失败或返回空列表,该模块会被静默跳过,不影响其他模块和详情页功能。
::: warning 注意
关联书籍的解析复用的是「发现」规则(`ruleExplore`),而非「详情页」规则(`ruleBookInfo`)。请确保源的发现规则已正确配置。
:::
## 4. URL 语法
URL 支持与 `exploreUrl` 相同的 JS 语法,包括 `@js:` 前缀、`<js></js>`
标签和 <code v-pre>{{...}}</code> 内嵌表达式。
### JS 上下文中的可用对象
| 对象 | 说明 | 示例属性 |
|:---------|:----------|:--------------------------------------------------------------------------------------|
| `book` | 当前书籍对象 | `book.name`, `book.author`, `book.kind`, `book.bookUrl`, `book.tocUrl`, `book.origin` |
| `source` | 当前源对象 | `source.bookSourceUrl`, `source.getVariable()` 等 |
| `cookie` | Cookie 存储 | `cookie.getKey(domain, key)` |
| `page` | 页码(固定为 1 | `page` |
| `java` | JS 扩展工具 | `java.ajax()`, `java.log()` 等 |
### 简单模板语法
对于简单的 URL,可以直接使用 <code v-pre>{{book.属性名}}</code> 语法,值会自动进行 URL 编码:
```
https://example.com/search?keyword={{book.author}}&name={{book.name}}
```
### `@js:` 表达式
对于需要逻辑处理的 URL,使用 `@js:` 前缀:
```
@js:"https://example.com/api/related?author=" + java.net.URLEncoder.encode(book.author, "UTF-8")
```
## 5. 完整 JSON 示例
```json
[
{
"key": "same_author",
"title": "同作者作品",
"url": "https://example.com/search?keyword={{book.author}}&type=author&page=1"
},
{
"key": "readers_also_read",
"title": "读这本书的人还在读",
"url": "https://example.com/api/related?book={{book.bookUrl}}&limit=20"
},
{
"key": "same_genre",
"title": "同类推荐",
"url": "https://example.com/category/{{book.kind}}?page=1"
}
]
```
以上配置会在详情页底部显示三行轮播:
```
┌─────────────────────────────────────────────┐
│ [操作按钮区域] │
├─────────────────────────────────────────────┤
│ 同作者作品 │
│ [封面1] [封面2] [封面3] [封面4] → │
│ │
│ 读这本书的人还在读 │
│ [封面1] [封面2] [封面3] [封面4] → │
│ │
│ 同类推荐 │
│ [封面1] [封面2] [封面3] [封面4] → │
├─────────────────────────────────────────────┤
│ [书籍简介区域] │
└─────────────────────────────────────────────┘
```
## 6. URL 示例
### 按作者查找相关书籍
```
https://example.com/search?keyword={{book.author}}&type=author
```
### 按书籍名称查找同系列
```
https://example.com/search?keyword={{book.name}}&type=related
```
### 按分类查找同类书籍
```
https://example.com/category/{{book.kind}}?page=1
```
### 使用 JS 表达式
**简单拼接:**
```
@js:"https://example.com/api/related?author=" + java.net.URLEncoder.encode(book.author, "UTF-8") + "&book_id=" + book.bookUrl.split("/").pop()
```
**带条件逻辑:**
```
@js:
var base = "https://example.com/api/related";
if (book.kind && book.kind.contains("玄幻")) {
base + "?genre=fantasy&author=" + java.net.URLEncoder.encode(book.author, "UTF-8")
} else {
base + "?author=" + java.net.URLEncoder.encode(book.author, "UTF-8")
}
```
## 7. 显示逻辑
| 条件 | 行为 |
|:----------------------|:-----------------|
| `relatedBooks` 为空或未配置 | 不显示关联书籍模块 |
| JSON 格式错误 | 静默跳过,不影响详情页其他内容 |
| 某个模块的 URL 请求失败 | 跳过该模块,其他模块正常显示 |
| 某个模块返回空列表 | 跳过该模块,其他模块正常显示 |
| 所有模块均无结果 | 不显示关联书籍区域 |
| 结果中包含当前书籍 | 自动过滤掉当前书籍 |
| 本地书籍(无源) | 不显示关联书籍模块 |
| 切换源时 | 清空关联书籍,重新加载新源的数据 |
## 8. 最佳实践
1. **合理设置模块数量**:建议 1-3 个模块,过多的轮播行会影响页面体验。
2. **使用有意义的标题**:标题应清晰描述推荐来源,如「同作者作品」比「推荐」更具引导性。
3. **优先使用作者或分类**:按作者查找是最常见的关联方式。
4. **避免过于宽泛的查询**:如果 URL 返回的结果与当前书籍关联性不强,用户体验会下降。
5. **确保发现规则兼容**URL 返回的数据必须能被 `ruleExplore` 正确解析。
6. **简单场景用模板,复杂场景用 JS**:简单的 <code v-pre>{{book.author}}</code>
替换直接用模板语法;需要条件判断等复杂逻辑时用 `@js:` 表达式。
7. **测试边界情况**:测试作者名包含特殊字符时 URL 是否正常工作。
8. **控制返回数量**:建议服务端限制返回数量(如 10-20 本)。