├── .github
└── workflows
│ └── frontend-dispatch.yml
├── .gitignore
├── LICENSE
├── README.md
├── Timeline.md
├── api.yaml
├── index.html
├── 人物.md
├── 图片.md
├── 条目.md
├── 用户.md
├── 用户收藏.md
├── 编辑历史.md
├── 角色.md
└── 讨论贴.md
/.github/workflows/frontend-dispatch.yml:
--------------------------------------------------------------------------------
1 | name: Fronend Dispatch
2 | on:
3 | push:
4 | paths: [ 'api.yaml' ]
5 |
6 | jobs:
7 | dispatch:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Repository Dispatch
11 | uses: peter-evans/repository-dispatch@v2
12 | with:
13 | token: ${{ secrets.REPO_ACCESS_TOKEN }}
14 | repository: bangumi/frontend
15 | event-type: update-types
16 | client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vscode/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Bangumi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 开发文档
2 |
3 | 本仓库包含开发文档和 meta issue (如 [roadmap](https://github.com/bangumi/dev-docs/issues/1))。
4 |
5 | ## 仓库说明
6 |
7 | - 现有API相关
8 | - [`bangumi/server`](https://github.com/bangumi/server) 仓库为目前 bangumi 网站运作的新 api 后端,基于 Go,实现现有的公开 api。
9 | - 新网站相关
10 | - [`bangumi/frontend`](https://github.com/bangumi/frontend) 仓库为新网站的前端。
11 | - [`bangumi/server-private`](https://github.com/bangumi/server-private) 仓库为新网站 api 后端,基于 TypeScript,实现私有 API,专为新网站前端使用。
12 | - 开发相关
13 | - [`bangumi/dev-env`](https://github.com/bangumi/dev-env) 仓库包含配置文件(docker-compose)和开发数据,用于后端开发和测试使用。
14 | - [`bangumi/api`](https://github.com/bangumi/api) 仓库包括 API 文档,用于第三方开发者查看。
15 | - 微服务
16 | - [`bangumi/img-proxy`](https://github.com/bangumi/img-proxy) 切图服务器。
17 | - 其他
18 | - [`bangumi/wiki-syntax-spec`](https://github.com/bangumi/wiki-syntax-spec) 为 wiki 语法的定义,用于未来扩展 wiki 功能。
19 | - [`bangumi/common`](https://github.com/bangumi/common) 仓库包括 relation, platform, staff 等常量对应关系的 yaml 文件。
20 |
21 | 不同的仓库拥有更具体的贡献要求,请阅读相关仓库的说明和贡献指南。
22 |
23 | ## API
24 |
25 | ### 现有公开 API
26 |
27 | 目前 bangumi 网站实际提供的了两套 API
28 |
29 | 1. 旧的公开 API
30 |
31 | 这套 API 是 bangumi 最老也是最开始提供的 API,由 sai 编写,未开源。目前此 API 已停止维护(修 BUG 加功能得找 sai,但 sai 精力有限)。
32 |
33 | `https://api.bgm.tv/subject/100` 这种 API 路径中没有 `/v0/` 版本信息的 API 就是旧有 API。
34 |
35 | 很多有一点历史的第三方开源项目仍在使用此 API。出于兼容考虑旧 API 依旧能访问但已不推荐使用,相关 API 文档已隐藏。
36 | 2. 新的公开 API
37 |
38 | 为了取代旧的公开 API,目前 bangumi 提供了另一套 API。`https://api.bgm.tv/v0/subject/100` 这种路径以 `/v0/` 开头的即新的公开API。
39 |
40 | 此 API 代码开源,由 Go 编写任何人都可参与项目,代码仓库为 [`bangumi/server`](https://github.com/bangumi/server)。在使用 API 时如遇到BUG 或有新需求可提 issue,也欢迎提 PR 贡献代码。但因为新的公开 API 已经发布,需要保证兼容性,所以即便有功能变动也不会引入 break change。
41 |
42 | 新公开 API 使用 access token 进行用户认证,GET 请求支持跨域。
43 |
44 | | | 信息 |
45 | | ------------------------------------------------ | ---------------------------------------------- |
46 | | OpenAPI 文档 | https://bangumi.github.io/api/ |
47 | | OpenAPI 文档仓库 | [`bangumi/api`](https://github.com/bangumi/api) |
48 | | 生产环境Domain | `api.bgm.tv` |
49 | | 开发环境Domain``(仅支持路径 `/v0/` 下的路由) | `api.bgm38.tv` |
50 |
51 |
52 | > 开发环境使用仓库 [`bangumi/dev-env`](https://github.com/bangumi/dev-env) 中包含的数据,不定时会进行重置
53 | >
54 |
55 | ### 新网站和私有 API
56 |
57 | 目前 bangumi 正在进行新网站的开发,基于 React/TypeScript/Vite。新网站也开源,前端仓库位于 [`bangumi/frontend`](https://github.com/bangumi/frontend),欢迎提交代码。
58 |
59 | 新网站前端使用 API 与后端通信,前端所使用的 API 被称为私有 API。私有 API 与现有公开 API 不同,专为新网站前端使用而开发。使用 cookies session 进行用户认证,目前仍处于开发阶段,无兼容性保证,不支持跨域。仓库位于 [`bangumi/server-private`](https://github.com/bangumi/server-private) 。
60 |
61 | | | 信息 |
62 | | -------------- | ----------------------------------------------------------------------- |
63 | | OpenAPI 文档 | https://bangumi.github.io/dev-docs/ https://next.bgm38.com/p1/ |
64 | | 生产环境Domain | `next.bgm.tv` |
65 | | 开发环境Domain | `next.bgm38.tv` |
66 |
67 | 开发环境使用仓库 [`bangumi/dev-env`](https://github.com/bangumi/dev-env) 中包含的数据,不定时会进行重置。开发环境 `bangumi/dev-env` 所包含的账号如下:
68 |
69 | | uid | 昵称 | 邮箱 | 密码 | 备注 |
70 | | :--------: | :------------: | :-------------------------: | :--------------: | :----------------: |
71 | | `2` | `nickname 2` | `2@bgm38.com` | `lovemeplease` | 拥有 wiki 编辑权限 |
72 | | `382951` | `树洞1` | `treeholechan@gmail.com` | `lovemeplease` | |
73 | | `318250` | `树洞2` | `treeholechan2@gmail.com` | `lovemeplease` | |
74 |
75 | ## 公开 API 和私有 API 的关系
76 |
77 | 公开 API 主要为 APP 等客户端而开发,今后新网站发布后也依旧会持续维护和使用。 私有 API 专为新网站前端开发,为网站前端专用。今后新网站发布后将会同时存在两套 API 。
78 |
--------------------------------------------------------------------------------
/Timeline.md:
--------------------------------------------------------------------------------
1 | # Timeline
2 |
3 | # Data Structure
4 |
5 | ```sql
6 | CREATE TABLE IF NOT EXISTS `chii_timeline` (
7 | `tml_id` int unsigned NOT NULL AUTO_INCREMENT,
8 | `tml_uid` mediumint unsigned NOT NULL DEFAULT '0',
9 | `tml_cat` smallint unsigned NOT NULL,
10 | `tml_type` smallint unsigned NOT NULL DEFAULT '0',
11 | `tml_related` char(255) NOT NULL DEFAULT '0',
12 | `tml_memo` mediumtext NOT NULL,
13 | `tml_img` mediumtext NOT NULL,
14 | `tml_batch` tinyint unsigned NOT NULL,
15 | `tml_source` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '更新来源',
16 | `tml_replies` mediumint unsigned NOT NULL COMMENT '回复数',
17 | `tml_dateline` int unsigned NOT NULL DEFAULT '0',
18 | PRIMARY KEY (`tml_id`)
19 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
20 | ```
21 |
22 | - `tml_cat` 一级分类
23 | - `tml_type` 二级类型
24 | - `tml_related` 直接关联 ID
25 | - `tml_memo` 关联数据
26 | - `tml_img` 关联图片数据(封面、头像、小组图标等,v2 将废弃)
27 | - `tml_batch` 是否为批量数据
28 |
29 | # Constants
30 |
31 | ## Category
32 |
33 | ```yaml
34 | CAT_DAILY = 1 #日常行为
35 | CAT_WIKI = 2 #维基操作
36 | CAT_SBJ_COLLECT = 3 #收藏
37 | CAT_BGM_PROGRESS = 4 #进度管理
38 | CAT_STATUS = 5 #吐槽
39 | CAT_BLOG = 6 #日志
40 | CAT_INDEX = 7 #目录
41 | CAT_MONO = 8 #人物
42 | ```
43 |
44 | ## Type
45 |
46 | 不同 Category 对应二级的 Type
47 |
48 | - CAT_DAILY
49 |
50 | ```yaml
51 | 注册 = 1
52 | 添加好友 = 2
53 | 加入小组 = 3
54 | 创建小组 = 4
55 | 加入乐园 = 5
56 | ```
57 |
58 | - CAT_BGM_PROGRESS
59 |
60 | ```yaml
61 | TYPE_BGM_PROGRESS_BATCH = 0
62 | TYPE_BGM_PROGRESS_SINGLE = 1
63 | ```
64 |
65 | - CAT_STATUS
66 |
67 | ```yaml
68 | TYPE_STATUS_SIGN = 0
69 | TYPE_STATUS_TSUKKOMI = 1
70 | TYPE_STATUS_NICKNAME = 2
71 | ```
72 |
73 | - CAT_SBJ_COLLECT 根据条目类型与收藏动作类型进行 Mapping,用于对于不同收藏动作
74 |
75 | ```yaml
76 | #subject_type: { collect_type: tml_type }
77 | 1: {1: 1, 2: 5, 3: 9, 4: 13, 5: 14}
78 | 2: {1: 2, 2: 6, 3: 10, 4: 13, 5: 14}
79 | 3: {1: 3, 2: 7, 3: 11, 4: 13, 5: 14}
80 | 4: {1: 4, 2: 8, 3: 12, 4: 13, 5: 14}
81 | 6: {1: 2, 2: 6, 3: 10, 4: 13, 5: 14}
82 | ```
83 |
84 | ```yaml
85 | 1 = 想读
86 | 2 = 想看
87 | 3 = 想听
88 | 4 = 想玩
89 | 5 = 读过
90 | 6 = 看过
91 | 7 = 听过
92 | 8 = 玩过
93 | 9 = 在读
94 | 10 = 在看
95 | 11 = 在听
96 | 12 = 在玩
97 | 13 = 搁置了
98 | 14 = 抛弃了
99 | ```
100 |
101 |
102 | # V2 tml_memo
103 |
104 | php serialize 存储,未来迁移到 json 格式
105 |
106 | v2 起,在 `tml_memo` 与中不再存储关联条目详细数据,展示 Timeline 时动态获取条目信息。
107 |
108 | - `tml_memo` 中只存储关联条目 id,在展示时通过 `subject_id` 、`ep_id` 等查询对应条目详细信息
109 | - `tml_img` 废弃,不存储图片信息
110 |
111 | 目前 v2 支持的类型:
112 |
113 | - CAT_WIKI
114 | - CAT_SBJ_COLLECT
115 | - CAT_BGM_PROGRESS
116 |
117 | ### CAT_WIKI 维基编辑
118 |
119 | - subject_id
120 |
121 | ### CAT_SBJ_COLLECT 条目收藏
122 |
123 | - `subject_id` 条目 ID
124 | - `collect_id` 收藏 ID
125 | - `collect_comment` 收藏时的吐槽,需要进行 html 转义
126 | - `collect_rate` 收藏时的评分
127 |
128 | 如:
129 |
130 | ```json
131 | {
132 | "subject_id": 2,
133 | "collect_id": 12346,
134 | "collect_comment": "Amazing",
135 | "collect_rate": 1
136 | }
137 | ```
138 |
139 | **同类收藏合并**
140 |
141 | 如用户 10 分钟内有同样的收藏类型与动作,则相同类型与动作的 Timeline `tml_batch` 标记为 1,将 `tml_memo` 合并存储
142 |
143 | `{ #subject_id: {}, #subject_id: {} }` 结构。
144 |
145 | 如:
146 |
147 | ```json
148 | {
149 | "2":{
150 | "subject_id": 2,
151 | "collect_id": 12346,
152 | "collect_comment": "Amazing",
153 | "collect_rate": 1
154 | },
155 | "975":{
156 | "subject_id": 975,
157 | "collect_id": 12347
158 | }
159 | }
160 | ```
161 |
162 | ### CAT_BGM_PROGRESS 进度管理
163 |
164 | - TYPE_BGM_PROGRESS_BATCH 批量进度
165 | - `subject_id` 条目 ID
166 | - `eps_total` 总章节
167 | - `eps_update` 当前章节
168 | - `vols_total` 总卷数
169 | - `vols_update` 当前卷数
170 | - TYPE_BGM_PROGRESS_SINGLE 单条进度
171 | - `ep_id` 章节 ID
172 | - `subject_id` 条目 ID
173 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bangumi Private API
6 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/人物.md:
--------------------------------------------------------------------------------
1 | ## 基础信息
2 |
3 | ```sql
4 | CREATE TABLE IF NOT EXISTS `chii_persons` (
5 | `prsn_id` mediumint(8) unsigned NOT NULL,
6 | `prsn_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
7 | `prsn_type` tinyint(4) unsigned NOT NULL COMMENT '个人,公司,组合',
8 | `prsn_infobox` mediumtext COLLATE utf8_unicode_ci NOT NULL,
9 | `prsn_producer` tinyint(1) NOT NULL,
10 | `prsn_mangaka` tinyint(1) NOT NULL,
11 | `prsn_artist` tinyint(1) NOT NULL,
12 | `prsn_seiyu` tinyint(1) NOT NULL,
13 | `prsn_writer` tinyint(4) NOT NULL DEFAULT '0' COMMENT '作家',
14 | `prsn_illustrator` tinyint(4) NOT NULL DEFAULT '0' COMMENT '绘师',
15 | `prsn_actor` tinyint(1) NOT NULL COMMENT '演员',
16 | `prsn_summary` mediumtext COLLATE utf8_unicode_ci NOT NULL,
17 | `prsn_img` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
18 | `prsn_img_anidb` varchar(255) CHARACTER SET utf8 NOT NULL,
19 | `prsn_comment` mediumint(9) unsigned NOT NULL,
20 | `prsn_collects` mediumint(8) unsigned NOT NULL,
21 | `prsn_dateline` int(10) unsigned NOT NULL,
22 | `prsn_lastpost` int(11) unsigned NOT NULL,
23 | `prsn_lock` tinyint(4) NOT NULL,
24 | `prsn_anidb_id` mediumint(8) unsigned NOT NULL,
25 | `prsn_ban` tinyint(3) unsigned NOT NULL DEFAULT '0',
26 | `prsn_redirect` int(10) unsigned NOT NULL DEFAULT '0',
27 | `prsn_nsfw` tinyint(1) unsigned NOT NULL
28 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='(现实)人物表';
29 | ```
30 |
31 | `prsn_img_anidb` 为废弃字段,`prsn_dateline`没有使用。
32 |
33 | `prsn_producer`,`prsn_mangaka`,`prsn_artist`,`prsn_seiyu`,`prsn_writer`,`prsn_illustrator`,`prsn_actor` 字段为编辑页面的职业勾选框。
34 |
35 | `prsn_lastpost` 为最近的用户评论日期。
36 |
37 | ## 关联条目
38 |
39 | 人物参与的条目在`chii_person_cs_index`表中。
40 |
41 | ```sql
42 | CREATE TABLE IF NOT EXISTS `chii_person_cs_index` (
43 | `prsn_type` enum('prsn','crt') COLLATE utf8_unicode_ci NOT NULL,
44 | `prsn_id` mediumint(9) unsigned NOT NULL,
45 | `prsn_position` smallint(5) unsigned NOT NULL COMMENT '监督,原案,脚本,..',
46 | `subject_id` mediumint(9) unsigned NOT NULL,
47 | `subject_type_id` tinyint(4) unsigned NOT NULL,
48 | `summary` mediumtext COLLATE utf8_unicode_ci NOT NULL,
49 | `prsn_appear_eps` mediumtext COLLATE utf8_unicode_ci NOT NULL COMMENT '可选,人物参与的章节'
50 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='subjects'' credits/creator & staff (c&s)index';
51 | ```
52 |
53 | 此表中的`prsn_type`必定为`"prsn"`可以忽略。
54 |
55 | 需要从此表中查出 `subject_type_id` 和 `prsn_position`,然后在预先定义的变量中查找具体职位内容。https://github.com/bangumi/server/blob/c72c7a4704565500af54d411550ce15af92fa2ed/pol/db/_const.py#L11
56 |
57 | ## 额外字段
58 |
59 | `chii_person_fields`表为现实人物和虚拟角色的 wiki 解析字段。
60 |
61 | ```sql
62 | CREATE TABLE IF NOT EXISTS `chii_person_fields` (
63 | `prsn_cat` enum('prsn','crt') COLLATE utf8_unicode_ci NOT NULL,
64 | `prsn_id` int(8) unsigned NOT NULL,
65 | `gender` tinyint(4) unsigned NOT NULL,
66 | `bloodtype` tinyint(4) unsigned NOT NULL,
67 | `birth_year` year(4) NOT NULL,
68 | `birth_mon` tinyint(2) unsigned NOT NULL,
69 | `birth_day` tinyint(2) unsigned NOT NULL
70 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
71 | ```
72 |
73 | 表的主键为`('prsn_cat', 'prsn_id')`
74 |
75 | 此表中的`prsn_cat`可能为`"prsn"`或`"crt"`。查询时通过`psrn_cat`和`prsn_id`进行查询
76 |
--------------------------------------------------------------------------------
/图片.md:
--------------------------------------------------------------------------------
1 | 数据库中保存了图片的基础路径,类似于 `a6/e8/1_prsn_ZdFfp.jpg?r=1597241889`
2 |
3 | 不同分类,不同尺寸的图片有不同的前缀,前缀+尺寸+图片基础路径拼接成了最终的 HTTP URL
4 |
5 | 人物的图片前缀为 `https://lain.bgm.tv/pic/crt/` 有`l`,`m`,`s`和`g`四种尺寸,一共有四种尺寸的图片
6 |
7 | ```json
8 | {
9 | "images": {
10 | "large": "https://lain.bgm.tv/pic/crt/l/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
11 | "medium": "https://lain.bgm.tv/pic/crt/m/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
12 | "small": "https://lain.bgm.tv/pic/crt/s/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
13 | "grid": "https://lain.bgm.tv/pic/crt/g/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889"
14 | }
15 | }
16 | ```
17 |
18 | 条目的图片前缀为 `https://lain.bgm.tv/pic/cover/`, 有 `l`,`m`,`s`,`c`和`g`五种尺寸。
19 |
20 | ```json
21 | {
22 | "images": {
23 | "large": "https://lain.bgm.tv/pic/cover/l/a8/7f/4_cMMK5.jpg",
24 | "common": "https://lain.bgm.tv/pic/cover/c/a8/7f/4_cMMK5.jpg",
25 | "medium": "https://lain.bgm.tv/pic/cover/m/a8/7f/4_cMMK5.jpg",
26 | "small": "https://lain.bgm.tv/pic/cover/s/a8/7f/4_cMMK5.jpg",
27 | "grid": "https://lain.bgm.tv/pic/cover/g/a8/7f/4_cMMK5.jpg"
28 | }
29 | }
30 | ```
31 |
--------------------------------------------------------------------------------
/条目.md:
--------------------------------------------------------------------------------
1 | # 条目
2 |
3 | 条目目前用到的有三个表 (还有`chii_subject_alias`表,但是因为目前没有提供搜索功能,所以没有用到)
4 |
5 | ```sql
6 | CREATE TABLE IF NOT EXISTS `chii_subjects` (
7 | `subject_id` mediumint(8) unsigned NOT NULL,
8 | `subject_type_id` smallint(6) unsigned NOT NULL DEFAULT '0',
9 | `subject_name` varchar(80) NOT NULL,
10 | `subject_name_cn` varchar(80) NOT NULL,
11 | `subject_uid` varchar(20) NOT NULL COMMENT 'isbn / imdb',
12 | `subject_creator` mediumint(8) unsigned NOT NULL,
13 | `subject_dateline` int(10) unsigned NOT NULL DEFAULT '0',
14 | `subject_image` varchar(255) NOT NULL,
15 | `subject_platform` smallint(6) unsigned NOT NULL DEFAULT '0',
16 | `field_infobox` mediumtext NOT NULL,
17 | `field_summary` mediumtext NOT NULL COMMENT 'summary',
18 | `field_5` mediumtext NOT NULL COMMENT 'author summary',
19 | `field_volumes` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '卷数',
20 | `field_eps` mediumint(8) unsigned NOT NULL DEFAULT '0',
21 | `subject_wish` mediumint(8) unsigned NOT NULL DEFAULT '0',
22 | `subject_collect` mediumint(8) unsigned NOT NULL DEFAULT '0',
23 | `subject_doing` mediumint(8) unsigned NOT NULL DEFAULT '0',
24 | `subject_on_hold` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '搁置人数',
25 | `subject_dropped` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '抛弃人数',
26 | `subject_series` tinyint(1) unsigned NOT NULL DEFAULT '0',
27 | `subject_series_entry` mediumint(8) unsigned NOT NULL DEFAULT '0',
28 | `subject_idx_cn` varchar(1) NOT NULL,
29 | `subject_airtime` tinyint(1) unsigned NOT NULL,
30 | `subject_nsfw` tinyint(1) NOT NULL,
31 | `subject_ban` tinyint(1) unsigned NOT NULL DEFAULT '0'
32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
33 | ```
34 |
35 | 条目主表。
36 |
37 | `subject_series` 和 `subject_series_entry` 用于书籍条目的主系列功能。其他的基本上通过字段名就能判断出来。单行本和系列的信息在条目关联表中也有保存。
38 |
39 | `subject_idx_cn` 是中文名的第一个字的拼音首字母。
40 |
41 | ```sql
42 | CREATE TABLE IF NOT EXISTS `chii_subject_fields` (
43 | `field_sid` mediumint(8) unsigned NOT NULL,
44 | `field_tid` smallint(6) unsigned NOT NULL DEFAULT '0',
45 | `field_tags` mediumtext NOT NULL,
46 | `field_rate_1` mediumint(8) unsigned NOT NULL DEFAULT '0',
47 | `field_rate_2` mediumint(8) unsigned NOT NULL DEFAULT '0',
48 | `field_rate_3` mediumint(8) unsigned NOT NULL DEFAULT '0',
49 | `field_rate_4` mediumint(8) unsigned NOT NULL DEFAULT '0',
50 | `field_rate_5` mediumint(8) unsigned NOT NULL DEFAULT '0',
51 | `field_rate_6` mediumint(8) unsigned NOT NULL DEFAULT '0',
52 | `field_rate_7` mediumint(8) unsigned NOT NULL DEFAULT '0',
53 | `field_rate_8` mediumint(8) unsigned NOT NULL DEFAULT '0',
54 | `field_rate_9` mediumint(8) unsigned NOT NULL DEFAULT '0',
55 | `field_rate_10` mediumint(8) unsigned NOT NULL DEFAULT '0',
56 | `field_airtime` tinyint(1) unsigned NOT NULL,
57 | `field_rank` int(10) unsigned NOT NULL DEFAULT '0',
58 | `field_year` year(4) NOT NULL COMMENT '放送年份',
59 | `field_mon` tinyint(2) NOT NULL COMMENT '放送月份',
60 | `field_week_day` tinyint(1) NOT NULL COMMENT '放送日(星期X)',
61 | `field_date` date NOT NULL COMMENT '放送日期',
62 | `field_redirect` mediumint(8) unsigned NOT NULL DEFAULT '0'
63 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
64 | ```
65 |
66 | `field_sid` 是条目 id。
67 |
68 | `field_rate_*` 是各个分数的打分人数。目前的最终分数计算为简单地平均值。
69 |
70 | `field_tags` 保存的是 php serlize 序列化过的 tag 信息,大概这样:
71 |
72 | ```python
73 | [
74 | {"tag_name": Optional[str], "result": int},
75 | {"tag_name": Optional[str], "result": int},
76 | ]
77 | ```
78 |
79 | ```sql
80 | CREATE TABLE IF NOT EXISTS `chii_subject_relations` (
81 | `rlt_subject_id` mediumint(8) unsigned NOT NULL COMMENT '关联主 ID',
82 | `rlt_subject_type_id` tinyint(3) unsigned NOT NULL,
83 | `rlt_relation_type` smallint(5) unsigned NOT NULL COMMENT '关联类型',
84 | `rlt_related_subject_id` mediumint(8) unsigned NOT NULL COMMENT '关联目标 ID',
85 | `rlt_related_subject_type_id` tinyint(3) unsigned NOT NULL COMMENT '关联目标类型',
86 | `rlt_vice_versa` tinyint(1) unsigned NOT NULL,
87 | `rlt_order` tinyint(3) unsigned NOT NULL COMMENT '关联排序'
88 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='条目关联表';
89 | ```
90 |
91 | 对于 `改编` 关联,会 fallback 到对应条目的类型。比如 `动画 改编 书籍` 对应的关联信息为书籍。
92 |
93 | # 章节
94 |
95 | 章节定义在 `chii_episodes` 表中。
96 |
97 | ```sql
98 | CREATE TABLE IF NOT EXISTS `chii_episodes` (
99 | `ep_id` mediumint(8) unsigned NOT NULL,
100 | `ep_subject_id` mediumint(8) unsigned NOT NULL,
101 | `ep_sort` float unsigned NOT NULL DEFAULT '0',
102 | `ep_type` tinyint(1) unsigned NOT NULL,
103 | `ep_disc` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '碟片数',
104 | `ep_name` varchar(80) NOT NULL,
105 | `ep_name_cn` varchar(80) NOT NULL,
106 | `ep_rate` tinyint(3) NOT NULL,
107 | `ep_duration` varchar(80) NOT NULL,
108 | `ep_airdate` varchar(80) NOT NULL,
109 | `ep_online` mediumtext NOT NULL,
110 | `ep_comment` mediumint(8) unsigned NOT NULL,
111 | `ep_resources` mediumint(8) unsigned NOT NULL,
112 | `ep_desc` mediumtext NOT NULL,
113 | `ep_dateline` int(10) unsigned NOT NULL,
114 | `ep_lastpost` int(10) unsigned NOT NULL,
115 | `ep_lock` tinyint(3) unsigned NOT NULL DEFAULT '0',
116 | `ep_ban` tinyint(3) unsigned NOT NULL DEFAULT '0'
117 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
118 | ```
119 |
120 | `ep_desc` 章节简介。
121 |
122 | `ep_disc` 仅在此表中出现,为音乐条目的碟片数,条目表中没有总碟片数。
123 |
124 | `ep_online` `ep_resources` 是废弃字段,曾经存相关网站的资源,后来放弃了。
125 |
126 | `ep_ban` 表示章节被锁定,在 api 响应中应当隐藏。
127 |
--------------------------------------------------------------------------------
/用户.md:
--------------------------------------------------------------------------------
1 | 用户有几个相关的表:
2 |
3 | ```SQL
4 | CREATE TABLE IF NOT EXISTS chii_members
5 | (
6 | uid mediumint unsigned auto_increment primary key,
7 | username char(15) charset utf8 default '' not null,
8 | nickname varchar(30) not null,
9 | avatar varchar(255) charset utf8 not null,
10 | groupid smallint(6) unsigned default 0 not null, # 用户权限组
11 | regdate int unsigned default 0 not null, # 注册日期
12 | lastvisit int unsigned default 0 not null, # 最后访问
13 | lastactivity int unsigned default 0 not null, # 最后活动
14 | lastpost int unsigned default 0 not null, # 最后发帖
15 | dateformat char(10) charset utf8 default '' not null, # 没用
16 | timeformat tinyint(1) default 0 not null, # 没用
17 | timeoffset char(4) charset utf8 default '' not null, # 没用
18 | newpm tinyint(1) default 0 not null,
19 | new_notify smallint(6) unsigned default 0 not null comment '新提醒',
20 | sign varchar(255) charset utf8 not null,
21 | constraint username unique (username)
22 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
23 | ```
24 |
25 | `dateformat` `timeformat`,`timeoffset` 都是废弃字段。
26 |
27 | ```SQL
28 | CREATE TABLE IF NOT EXISTS `chii_oauth_access_tokens` (
29 | `access_token` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
30 | `client_id` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
31 | `user_id` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
32 | `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
33 | `scope` varchar(4000) COLLATE utf8_unicode_ci DEFAULT NULL
34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
35 | ```
36 |
37 | `user_id` 记得转成 int 再作为`uid`查询
38 |
39 | 目前数据库中 `scope` 为 null
40 |
41 | 存储具体权限的表 usr_grp_id 为用户表中的 group id
42 |
43 | ```SQL
44 | CREATE TABLE IF NOT EXISTS `chii_usergroup` (
45 | `usr_grp_id` mediumint(8) unsigned NOT NULL,
46 | `usr_grp_name` varchar(255) CHARACTER SET utf8 NOT NULL,
47 | `usr_grp_perm` mediumtext CHARACTER SET utf8 NOT NULL,
48 | `usr_grp_dateline` int(10) unsigned NOT NULL
49 | ) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
50 | ```
51 |
--------------------------------------------------------------------------------
/用户收藏.md:
--------------------------------------------------------------------------------
1 | # 条目收藏
2 |
3 | https://github.com/bangumi/dev-env/blob/master/sql/schema/chii_subject_interests.sql
4 |
5 | ```SQL
6 | CREATE TABLE IF NOT EXISTS `chii_subject_interests` (
7 | `interest_id` int(10) unsigned NOT NULL,
8 | `interest_uid` mediumint(8) unsigned NOT NULL,
9 | `interest_subject_id` mediumint(8) unsigned NOT NULL,
10 | `interest_subject_type` smallint(6) unsigned NOT NULL DEFAULT '0',
11 | `interest_rate` tinyint(3) unsigned NOT NULL DEFAULT '0',
12 | `interest_type` tinyint(1) unsigned NOT NULL DEFAULT '0',
13 | `interest_has_comment` tinyint(1) unsigned NOT NULL,
14 | `interest_comment` mediumtext NOT NULL,
15 | `interest_tag` mediumtext NOT NULL,
16 | `interest_ep_status` mediumint(8) unsigned NOT NULL DEFAULT '0',
17 | `interest_vol_status` mediumint(8) unsigned NOT NULL COMMENT '卷数',
18 | `interest_wish_dateline` int(10) unsigned NOT NULL,
19 | `interest_doing_dateline` int(10) unsigned NOT NULL,
20 | `interest_collect_dateline` int(10) unsigned NOT NULL,
21 | `interest_on_hold_dateline` int(10) unsigned NOT NULL,
22 | `interest_dropped_dateline` int(10) unsigned NOT NULL,
23 | `interest_lasttouch` int(10) unsigned NOT NULL DEFAULT '0',
24 | `interest_private` tinyint(1) unsigned NOT NULL
25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
26 | ```
27 |
28 | # 章节收藏
29 |
30 | https://github.com/bangumi/dev-env/blob/master/sql/schema/chii_ep_status.sql
31 |
32 | ```SQL
33 | CREATE TABLE IF NOT EXISTS `chii_ep_status` (
34 | `ep_stt_id` mediumint(8) unsigned NOT NULL,
35 | `ep_stt_uid` mediumint(8) unsigned NOT NULL,
36 | `ep_stt_sid` mediumint(8) unsigned NOT NULL,
37 | `ep_stt_on_prg` tinyint(1) unsigned NOT NULL DEFAULT '0',
38 | `ep_stt_status` mediumtext NOT NULL,
39 | `ep_stt_lasttouch` int(10) unsigned NOT NULL
40 | ) ENGINE = MyISAM DEFAULT CHARSET = utf8;
41 | ```
42 |
43 | `ep_stt_status` 字段经过了 php 序列化。
44 |
45 | 数据结构,解析后的数据结构大约如下:(使用 TypeScript 表示)
46 |
47 | ```golang
48 | type EpisodeID = number
49 | enum EpisodeCollectionType {
50 | watched = 1, // 想看
51 | done = 2, // 看过
52 | dropped = 3, // 抛弃
53 | }
54 |
55 | type EpStatus = {
56 | [episode_id: EpisodeID]: {
57 | eid: string // EpisodeID in string
58 | stat: EpisodeCollectionType
59 | }
60 | }
61 | ```
62 |
63 | # 人物收藏
64 |
65 | https://github.com/bangumi/dev-env/blob/master/sql/schema/chii_person_collects.sql
66 |
67 | ```SQL
68 | CREATE TABLE IF NOT EXISTS
69 | `chii_person_collects` (
70 | `prsn_clt_id` MEDIUMINT(8) UNSIGNED NOT NULL,
71 | `prsn_clt_cat` ENUM('prsn', 'crt') NOT NULL,
72 | `prsn_clt_mid` MEDIUMINT(8) UNSIGNED NOT NULL,
73 | `prsn_clt_uid` MEDIUMINT(8) UNSIGNED NOT NULL,
74 | `prsn_clt_dateline` INT(10) UNSIGNED NOT NULL
75 | ) ENGINE = MyISAM DEFAULT CHARSET = utf8 COMMENT = '人物收藏';
76 | ```
77 |
--------------------------------------------------------------------------------
/编辑历史.md:
--------------------------------------------------------------------------------
1 | # 人物与角色的编辑历史
2 |
3 | ```sql
4 | CREATE TABLE IF NOT EXISTS `chii_rev_history` (
5 | `rev_id` mediumint(8) unsigned NOT NULL,
6 | `rev_type` tinyint(3) unsigned NOT NULL COMMENT '条目,角色,人物',
7 | `rev_mid` mediumint(8) unsigned NOT NULL COMMENT '对应条目,人物的ID',
8 | `rev_text_id` mediumint(9) unsigned NOT NULL,
9 | `rev_dateline` int(10) unsigned NOT NULL,
10 | `rev_creator` mediumint(8) unsigned NOT NULL,
11 | `rev_edit_summary` varchar(200) COLLATE utf8_unicode_ci NOT NULL
12 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
13 | ```
14 | `rev_text_id`:编辑信息的`id`
15 | `rev_edit_summary`:编辑注释
16 | `rev_creator`:编辑用户的`id`
17 | `rev_dateline`:编辑时间
18 |
19 | ## 编辑信息
20 |
21 | ```sql
22 | CREATE TABLE IF NOT EXISTS `chii_rev_text` (
23 | `rev_text_id` mediumint(9) unsigned NOT NULL,
24 | `rev_text` mediumblob NOT NULL
25 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
26 | ```
27 |
28 | `rev_text`:经`DEFLATE`算法压缩的`PHP`序列化的字符串,解序列化后为以`rev_id`为`key`,人物与角色各字段的更新数据为`value`的`Map`
29 |
30 | # 条目编辑历史
31 |
32 | ```sql
33 | CREATE TABLE IF NOT EXISTS `chii_subject_revisions` (
34 | `rev_id` mediumint(8) unsigned NOT NULL,
35 | `rev_type` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '修订类型',
36 | `rev_subject_id` mediumint(8) unsigned NOT NULL,
37 | `rev_type_id` smallint(6) unsigned NOT NULL DEFAULT '0',
38 | `rev_creator` mediumint(8) unsigned NOT NULL,
39 | `rev_dateline` int(10) unsigned NOT NULL DEFAULT '0',
40 | `rev_name` varchar(80) NOT NULL,
41 | `rev_name_cn` varchar(80) NOT NULL,
42 | `rev_field_infobox` mediumtext NOT NULL,
43 | `rev_field_summary` mediumtext NOT NULL,
44 | `rev_vote_field` mediumtext NOT NULL,
45 | `rev_field_eps` mediumint(8) unsigned NOT NULL,
46 | `rev_edit_summary` varchar(200) NOT NULL,
47 | `rev_platform` smallint(6) unsigned NOT NULL
48 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
49 | ```
50 |
51 | `rev_type_id`:条目类型
52 | `rev_field_summary`:条目概述
53 | `rev_field_infobox`:[`Infobox`格式](https://en.wikipedia.org/wiki/Infobox)的条目信息
--------------------------------------------------------------------------------
/角色.md:
--------------------------------------------------------------------------------
1 | ## 基础信息
2 |
3 | ```sql
4 | CREATE TABLE IF NOT EXISTS `chii_characters` (
5 | `crt_id` mediumint(8) unsigned NOT NULL,
6 | `crt_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
7 | `crt_role` tinyint(4) unsigned NOT NULL COMMENT '角色,机体,组织。。',
8 | `crt_infobox` mediumtext COLLATE utf8_unicode_ci NOT NULL,
9 | `crt_summary` mediumtext COLLATE utf8_unicode_ci NOT NULL,
10 | `crt_img` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
11 | `crt_comment` mediumint(9) unsigned NOT NULL DEFAULT '0',
12 | `crt_collects` mediumint(8) unsigned NOT NULL,
13 | `crt_dateline` int(10) unsigned NOT NULL,
14 | `crt_lastpost` int(11) unsigned NOT NULL,
15 | `crt_lock` tinyint(4) NOT NULL DEFAULT '0',
16 | `crt_img_anidb` varchar(255) CHARACTER SET utf8 NOT NULL,
17 | `crt_anidb_id` mediumint(8) unsigned NOT NULL,
18 | `crt_ban` tinyint(3) unsigned NOT NULL DEFAULT '0',
19 | `crt_redirect` int(10) unsigned NOT NULL DEFAULT '0',
20 | `crt_nsfw` tinyint(1) unsigned NOT NULL
21 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
22 | ```
23 |
24 | 角色主表
25 |
26 | `crt_img_anidb` 为废弃字段。
27 |
28 | `crt_lastpost` 为最近的用户评论日期。
29 |
30 | ## 关联条目
31 |
32 | 角色参与的条目在`chii_crt_subject_index`表中。
33 |
34 | ```sql
35 | CREATE TABLE IF NOT EXISTS `chii_crt_subject_index` (
36 | `crt_id` mediumint(9) unsigned NOT NULL,
37 | `subject_id` mediumint(9) unsigned NOT NULL,
38 | `subject_type_id` tinyint(4) unsigned NOT NULL,
39 | `crt_type` tinyint(4) unsigned NOT NULL COMMENT '主角,配角',
40 | `ctr_appear_eps` mediumtext COLLATE utf8_unicode_ci NOT NULL COMMENT '可选,角色出场的的章节',
41 | `crt_order` tinyint(3) unsigned NOT NULL
42 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
43 | ```
44 |
45 | `ctr_appear_eps` 目前为空,没用到。
46 |
47 | `crt_type` 只有三种,跟条目类型无关。
48 |
49 | ```php
50 | $typeList = array(
51 | 1 => '主角',
52 | 2 => '配角',
53 | 3 => '客串',
54 | );
55 | ```
56 |
57 | ## 额外字段
58 |
59 | `chii_person_fields`表为现实人物和虚拟角色的 wiki 解析字段。
60 |
61 | ```sql
62 | CREATE TABLE IF NOT EXISTS `chii_person_fields` (
63 | `prsn_cat` enum('prsn','crt') COLLATE utf8_unicode_ci NOT NULL,
64 | `prsn_id` int(8) unsigned NOT NULL,
65 | `gender` tinyint(4) unsigned NOT NULL,
66 | `bloodtype` tinyint(4) unsigned NOT NULL,
67 | `birth_year` year(4) NOT NULL,
68 | `birth_mon` tinyint(2) unsigned NOT NULL,
69 | `birth_day` tinyint(2) unsigned NOT NULL
70 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
71 | ```
72 |
73 | 表的主键为`('prsn_cat', 'prsn_id')`
74 |
75 | 此表中的`prsn_cat`可能为`"prsn"`或`"crt"`。查询时通过`psrn_cat`和`prsn_id`进行查询。查询角色信息的时候使用`prsn_cat = "crt"`
76 |
--------------------------------------------------------------------------------
/讨论贴.md:
--------------------------------------------------------------------------------
1 | 以小组为例,条目讨论贴和小组评论几乎相同。
2 |
3 | 小组帖子:
4 |
5 | ```sql
6 | CREATE TABLE IF NOT EXISTS `chii_group_topics` (
7 | `grp_tpc_id` MEDIUMINT(8) UNSIGNED NOT NULL,
8 | `grp_tpc_gid` MEDIUMINT(8) UNSIGNED NOT NULL,
9 | `grp_tpc_uid` MEDIUMINT(8) UNSIGNED NOT NULL,
10 | `grp_tpc_title` VARCHAR(80) NOT NULL,
11 | `grp_tpc_dateline` INT(10) UNSIGNED NOT NULL DEFAULT '0',
12 | `grp_tpc_lastpost` INT(10) UNSIGNED NOT NULL DEFAULT '0',
13 | `grp_tpc_replies` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
14 | `grp_tpc_state` TINYINT(1) UNSIGNED NOT NULL,
15 | `grp_tpc_display` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1'
16 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
17 | ```
18 |
19 | ```sql
20 | CREATE TABLE IF NOT EXISTS `chii_group_posts` (
21 | `grp_pst_id` MEDIUMINT(8) UNSIGNED NOT NULL,
22 | `grp_pst_mid` MEDIUMINT(8) UNSIGNED NOT NULL,
23 | `grp_pst_uid` MEDIUMINT(8) UNSIGNED NOT NULL,
24 | `grp_pst_related` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0' COMMENT '关联回复ID',
25 | `grp_pst_content` MEDIUMTEXT NOT NULL,
26 | `grp_pst_state` TINYINT(1) UNSIGNED NOT NULL,
27 | `grp_pst_dateline` INT(10) UNSIGNED NOT NULL DEFAULT '0'
28 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
29 | ```
30 |
31 | `_tpc_state` 是一个 enum,不一定是用户评论,可能是管理员操作了
32 |
33 | ```
34 | StateNone = 0 // 正常
35 | StateClosed = 1 // 管理员关闭主题 https://bgm.tv/subject/topic/12629#post_108127
36 | StateReopen = 2 // 重开
37 | StatePin = 3 // 置顶
38 | StateMerge = 4 // 合并
39 | StateSilent = 5 // 管理员下沉主题 https://bgm.tv/subject/topic/18784#post_160402
40 | StateDelete = 6 // 自行删除
41 | StatePrivate = 7 // 管理员删除
42 | ```
43 |
44 | 管理员的 `1` `5` 操作会添加一条相同 state 的评论,同时把帖子的 `grp_tpc_state` 设置为对应的值。
45 |
46 | `grp_pst_mid` 是帖子的 id。
47 |
48 | `grp_pst_related` 决定帖子是否二级回复。
49 |
--------------------------------------------------------------------------------