koishi-plugin-kkk 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/docs/upstream-audit-2026-10.md +257 -0
- package/lib/build-metadata.json +5 -5
- package/lib/karin/module/db/douyin.js +53 -26
- package/lib/karin/module/utils/QqPanel.js +43 -23
- package/lib/karin/module/utils/Render/index.js +14 -2
- package/lib/karin/platform/bilibili/bilibili.js +6 -8
- package/lib/karin/platform/bilibili/dynamic-text.js +49 -1
- package/lib/karin/platform/bilibili/push.js +1 -3
- package/lib/karin/platform/douyin/push/favorite.js +2 -2
- package/lib/karin/platform/douyin/push/recommend.js +2 -2
- package/lib/karin/platform/douyin/push/render.js +3 -3
- package/lib/karin/platform/douyin/push.js +18 -16
- package/lib/karin/platform/kuaishou/kuaishou.js +2 -1
- package/lib/karin/platform/xiaohongshu/xiaohongshu.js +6 -4
- package/lib/ktr/template/bilibili/comment/components/Comment.js +4 -4
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.js +2 -2
- package/lib/ktr/template/bilibili/userlist/components/UserList.js +2 -2
- package/lib/ktr/template/bilibili/videoInfo/components/videoInfo.js +2 -2
- package/lib/ktr/template/components/DefaultLayout.js +1 -1
- package/lib/ktr/template/douyin/article-work/components/ArticleWork.js +9 -9
- package/lib/ktr/template/douyin/favorite-list/components/FavoriteList.js +1 -1
- package/lib/ktr/template/douyin/image-work/components/ImageWork.js +9 -9
- package/lib/ktr/template/douyin/live/components/Live.js +3 -3
- package/lib/ktr/template/douyin/recommend-list/components/RecommendList.js +1 -1
- package/lib/ktr/template/douyin/userlist/components/UserList.js +2 -2
- package/lib/ktr/template/douyin/video-work/components/VideoWork.js +10 -10
- package/lib/ktr/template/kuaishou/comment/components/Comment.js +2 -2
- package/lib/ktr/template/other/changelog/components/changelog.js +2 -2
- package/lib/ktr/template/other/handlerError/components/handlerError.js +6 -6
- package/lib/ktr/template/other/help/components/Help.js +4 -4
- package/lib/ktr/template/other/live-photo-tip/components/LivePhotoTip.js +56 -56
- package/lib/ktr/template/other/qrlogin/components/qrlogin.js +3 -3
- package/lib/ktr/template/other/runtime/components/runtime.js +5 -5
- package/lib/ktr/template/other/version_warning/components/VersionWarning.js +3 -3
- package/lib/ktr/template/statistics/components/ChartCard.js +1 -1
- package/lib/ktr/template/statistics/components/KpiCard.js +1 -1
- package/lib/ktr/template/statistics/components/PlatformTable.js +1 -1
- package/lib/ktr/template/statistics/components/RankList.js +1 -1
- package/lib/ktr/template/statistics/global/components/GlobalStatistics.js +2 -2
- package/lib/ktr/template/statistics/group/components/GroupStatistics.js +2 -2
- package/lib/ktr/template/xiaohongshu/comment/components/Comment.js +2 -2
- package/lib/ktr/template/xiaohongshu/noteInfo/components/noteInfo.js +5 -5
- package/package.json +2 -1
- package/resources/template/extra-utilities.css +272 -0
- package/scripts/fixtures/avatar-probe.png +0 -0
- package/scripts/make-probe-png.cjs +54 -0
- package/scripts/probe-aweme-ttl.cjs +157 -0
- package/scripts/probe-bili-desc.cjs +278 -0
- package/scripts/probe-dy-user-info.cjs +154 -0
- package/scripts/probe-font-weight.cjs +142 -0
- package/scripts/probe-live-photo-tip.cjs +94 -0
- package/scripts/probe-qrcode-avatar.cjs +154 -0
- package/scripts/probe-template-css.cjs +100 -0
- package/scripts/sync-template-css.mjs +316 -0
- package/scripts/verify-changelog-range.cjs +20 -1
- package/src/karin/module/db/douyin.ts +878 -850
- package/src/karin/module/utils/QqPanel.ts +48 -23
- package/src/karin/module/utils/Render/index.ts +13 -2
- package/src/karin/platform/bilibili/bilibili.ts +2936 -2938
- package/src/karin/platform/bilibili/dynamic-text.ts +50 -1
- package/src/karin/platform/bilibili/push.ts +2 -4
- package/src/karin/platform/douyin/push/favorite.ts +97 -97
- package/src/karin/platform/douyin/push/recommend.ts +96 -96
- package/src/karin/platform/douyin/push/render.ts +768 -768
- package/src/karin/platform/douyin/push.ts +1244 -1242
- package/src/karin/platform/kuaishou/kuaishou.ts +261 -260
- package/src/karin/platform/xiaohongshu/comments.ts +230 -227
- package/src/karin/platform/xiaohongshu/xiaohongshu.ts +901 -899
- package/src/ktr/template/bilibili/comment/components/Comment.tsx +663 -657
- package/src/ktr/template/bilibili/comment/components/types.ts +28 -26
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.tsx +264 -264
- package/src/ktr/template/bilibili/userlist/components/UserList.tsx +246 -246
- package/src/ktr/template/bilibili/videoInfo/components/videoInfo.tsx +217 -217
- package/src/ktr/template/components/DefaultLayout.tsx +166 -166
- package/src/ktr/template/douyin/article-work/components/ArticleWork.tsx +301 -301
- package/src/ktr/template/douyin/favorite-list/components/FavoriteList.tsx +201 -201
- package/src/ktr/template/douyin/image-work/components/ImageWork.tsx +437 -437
- package/src/ktr/template/douyin/live/components/Live.tsx +229 -229
- package/src/ktr/template/douyin/recommend-list/components/RecommendList.tsx +201 -201
- package/src/ktr/template/douyin/userlist/components/UserList.tsx +229 -229
- package/src/ktr/template/douyin/video-work/components/VideoWork.tsx +398 -398
- package/src/ktr/template/kuaishou/comment/components/Comment.tsx +213 -207
- package/src/ktr/template/kuaishou/comment/components/types.ts +49 -47
- package/src/ktr/template/other/changelog/components/changelog.tsx +411 -411
- package/src/ktr/template/other/handlerError/components/handlerError.tsx +1097 -1097
- package/src/ktr/template/other/help/components/Help.tsx +249 -249
- package/src/ktr/template/other/live-photo-tip/components/LivePhotoTip.tsx +352 -295
- package/src/ktr/template/other/qrlogin/components/qrlogin.tsx +295 -295
- package/src/ktr/template/other/runtime/components/runtime.tsx +347 -347
- package/src/ktr/template/other/version_warning/components/VersionWarning.tsx +392 -392
- package/src/ktr/template/statistics/components/ChartCard.tsx +40 -40
- package/src/ktr/template/statistics/components/KpiCard.tsx +39 -39
- package/src/ktr/template/statistics/components/PlatformTable.tsx +83 -83
- package/src/ktr/template/statistics/components/RankList.tsx +127 -127
- package/src/ktr/template/statistics/global/components/GlobalStatistics.tsx +597 -597
- package/src/ktr/template/statistics/group/components/GroupStatistics.tsx +468 -468
- package/src/ktr/template/xiaohongshu/comment/components/Comment.tsx +270 -264
- package/src/ktr/template/xiaohongshu/comment/components/types.ts +130 -119
- package/src/ktr/template/xiaohongshu/noteInfo/components/noteInfo.tsx +271 -271
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## 3.13.0
|
|
4
|
+
|
|
5
|
+
这一版把上游最近一批改动搬了过来,另外修了几处只有真用起来才会碰到的显示问题。
|
|
6
|
+
|
|
7
|
+
### 修:实况照片提示卡整张崩了
|
|
8
|
+
|
|
9
|
+
那张卡(「这是一张实况照片」的提示)在群里显示成一坨:文字挤在一起、间距全没、
|
|
10
|
+
一排品牌图标只剩零星两三个。
|
|
11
|
+
|
|
12
|
+
原因是卡片的样式是**跟着模板按需生成**的,模板更新后新用到的样式没跟着补上。
|
|
13
|
+
这类问题最坑的地方是**页面不报错**,只是悄悄少样式 —— 光看日志什么都看不出来。
|
|
14
|
+
|
|
15
|
+
现在补了一套「和上游样式逐条对齐」的机制,并加了守卫脚本,
|
|
16
|
+
以后模板再更新不会再漏。顺带修好了 B站评论卡的字体,以及群统计卡缺掉的一段间距。
|
|
17
|
+
|
|
18
|
+
### 修:抖音会重复推一遍历史作品
|
|
19
|
+
|
|
20
|
+
喜欢 / 推荐列表的去重记录以前是「固定有效期」:一条作品记下之后,时间一到就作废,
|
|
21
|
+
哪怕它还在你列表里,也会被当成新作品再推一次。
|
|
22
|
+
|
|
23
|
+
现在改成**跟着列表走**:每轮推送都把当前列表里所有作品的有效期一起往后延,
|
|
24
|
+
只有**真正离开列表**的作品才会被清掉。清理的时机也跟着挪了 ——
|
|
25
|
+
这两件事必须同时生效,否则升级的那一刻老记录会先被清掉,反而多推一轮。
|
|
26
|
+
|
|
27
|
+
### 新:评论卡片的二维码中间带上作者头像
|
|
28
|
+
|
|
29
|
+
B站 / 快手 / 小红书三张评论卡片,右下角那个二维码以前是纯黑白码,
|
|
30
|
+
现在把作者头像嵌在正中间(和抖音那张卡的样子统一),深色模式也一起处理了。
|
|
31
|
+
|
|
32
|
+
### 修:B站卡片的简介(这次修的是 QQ 面板那张)
|
|
33
|
+
|
|
34
|
+
上一版修的是「解析出来那张卡」。但 QQ 上开着解析面板的时候,
|
|
35
|
+
**解析卡其实是不发的** —— 群里那一张是面板自己画的,它的简介从出生起就是空的,
|
|
36
|
+
所以修完看起来毫无变化。现在两张卡走同一份简介逻辑,单行、多行、带 @ 和链接的都正常。
|
|
37
|
+
|
|
38
|
+
### 其它
|
|
39
|
+
|
|
40
|
+
- **修**:小红书评论里「回复的图片」以前按一串网址处理,接口其实给的是带宽高的对象,
|
|
41
|
+
现在按真实结构解析;
|
|
42
|
+
- **修**:抖音推送图里「谁在喜欢 / 谁推荐」那行取不到人,会退回显示作品作者,现在正常了;
|
|
43
|
+
- **改**:一批卡片标题和数字的字重从最粗降到次粗(B站、抖音、小红书、单张统计卡都覆盖了),
|
|
44
|
+
小尺寸下不再糊成一团。
|
|
45
|
+
|
|
46
|
+
## 3.12.1
|
|
47
|
+
|
|
48
|
+
### 修:B站卡片的简介没了
|
|
49
|
+
|
|
50
|
+
有一批 B 站视频解析出来的卡片,标题下面直接跳到播放数据,**视频简介整块不见了**。
|
|
51
|
+
不是渲染糊了,是压根没画上去。
|
|
52
|
+
|
|
53
|
+
原因是 B 站接口有时会把简介放在「分段简介」里、有时只放在普通简介字段里,
|
|
54
|
+
之前的代码碰上第一种情况以外的数据会算出一份空简介,然后把「空的」当成「有内容」画出来,
|
|
55
|
+
结果整块简介反而被吃掉了。
|
|
56
|
+
|
|
57
|
+
现在两个字段都试,哪个真的有内容就用哪个 —— 单行简介、多行简介、带 @ 和链接的简介
|
|
58
|
+
都能正常显示出来。
|
|
59
|
+
|
|
60
|
+
顺手还修了一处:接口返回的简介字段是空的时候不会再让解析报错。
|
|
61
|
+
|
|
3
62
|
## 3.12.0
|
|
4
63
|
|
|
5
64
|
### 新:提取图片的按钮只能点一次
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# 上游 karin-plugin-kkk 变更对照审查
|
|
2
|
+
|
|
3
|
+
对照对象:`ikenxuan/karin-plugin-kkk` 的 8 个 commit(2026-09-16 ~ 2026-09-22)
|
|
4
|
+
对照基准:本地 `E:/devkoishi/plugins/koishi-plugin-kkk`(v3.12.1)
|
|
5
|
+
审查方式:GitHub API 逐个取 commit 的文件清单与 patch,再在本地源码里逐条核对
|
|
6
|
+
|
|
7
|
+
> 说明:上游是 `packages/core` monorepo,本地是 Koishi 单包移植版,
|
|
8
|
+
> 路径前缀 `packages/core/` 对应本地根目录,`packages/core/ktr/` 对应本地 `src/ktr/`,
|
|
9
|
+
> `packages/core/src/` 对应本地 `src/karin/`。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 结论速览
|
|
14
|
+
|
|
15
|
+
| # | commit | 标题 | 本地状态 |
|
|
16
|
+
|---|--------|------|----------|
|
|
17
|
+
| 1 | `ff54ba5` | 优化作品缓存管理,新增续期去重记录功能并调整清理逻辑 | ❌ **未移植**(改动最大,含一个真实 bug 修复) |
|
|
18
|
+
| 2 | `677e213` | 评论/笔记二维码统一补作者头像并修复深色模式 | ❌ **未移植**(B站/快手/小红书三张评论卡) |
|
|
19
|
+
| 3 | `0659c2b` | fix: xhs comments | ❌ **未移植**(子评论 pictures 类型 + amagi 类型名) |
|
|
20
|
+
| 4 | `2fa299a` | ui: 优化部分字体粗细 | ❌ **未移植**(`font-black` → `font-bold`) |
|
|
21
|
+
| 5 | `f4b5312` | fix(dy): 修复推送图片获取用户信息的逻辑 | ⚠️ **部分**(拉取路径已是新写法,但缺一层兜底) |
|
|
22
|
+
| 6 | `ee22474` | ui: 重写 live phtot tip | ➖ **不适用**(本地这张卡是自研的,跟上游结构不同) |
|
|
23
|
+
| 7 | `049eb2f` | deps: update amagi | ➖ **不适用**(本地已用更新的 `7.0.0-beta.5`) |
|
|
24
|
+
| 8 | `85088c7` | fix: alias | ➖ **不适用**(上游 monorepo 的 vite alias / workspace 配置) |
|
|
25
|
+
|
|
26
|
+
**有实际价值的是 1~4 号,其中 1 号除了功能还修了一个会「重推历史作品」的 bug。**
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. `ff54ba5` 缓存续期去重 —— ❌ 未移植(最值得搬)
|
|
31
|
+
|
|
32
|
+
### 上游改了什么
|
|
33
|
+
|
|
34
|
+
把抖音喜欢/推荐列表的去重记录从「**固定 TTL**」改成「**滑动 TTL**」:
|
|
35
|
+
|
|
36
|
+
- 新增 `DouyinDBBase.touchAwemeCache(sec_uid, pushType, aweme_ids)`:
|
|
37
|
+
每轮推送把「当前列表里全部作品的 `updatedAt`」刷新到当前时间;
|
|
38
|
+
- `cleanOldAwemeCache` 的判据从 `createdAt < cutoff` 改成 **`updatedAt < cutoff`**;
|
|
39
|
+
- `favorite.ts` / `recommend.ts` 里原来调的 `updateListSnapshot` 换成 `touchAwemeCache`;
|
|
40
|
+
- **`push.ts` 里清理的时机从「拉列表之前」挪到「拉列表之后」**。
|
|
41
|
+
|
|
42
|
+
### 为什么时机也要挪(上游注释写得很清楚)
|
|
43
|
+
|
|
44
|
+
> 若放在续期之前,升级后旧记录的 `updatedAt` 偏早,会在续期前被按 `updatedAt` 清理掉,
|
|
45
|
+
> 导致仍在列表中的历史作品被当作新作品重推一次。
|
|
46
|
+
|
|
47
|
+
也就是说:**单独改判据而不挪时机,升级的那一刻会把老记录全清掉 → 全量重推一次。**
|
|
48
|
+
这两件事必须一起改。
|
|
49
|
+
|
|
50
|
+
### 本地现状
|
|
51
|
+
|
|
52
|
+
- `src/karin/module/db/douyin.ts:694` `cleanOldAwemeCache` 仍按 **`createdAt`** 清理;
|
|
53
|
+
- 本地有 `updateListSnapshot`(写 `TABLE.douyinListSnapshot`,**另一张表**),
|
|
54
|
+
上游已把它换成 `touchAwemeCache`;
|
|
55
|
+
- 本地 `src/karin/platform/douyin/push.ts:85` 清理**仍在** `getDynamicList` 之前;
|
|
56
|
+
- `favorite.ts:90` / `recommend.ts:89` 仍调 `updateListSnapshot`。
|
|
57
|
+
|
|
58
|
+
### 移植要点(本地)
|
|
59
|
+
|
|
60
|
+
1. `douyin.ts` 加 `touchAwemeCache`;本地是 Koishi 原生 db,写法要用 `this.db.update(...)` 而非原生 SQL 的 `IN (...)`;
|
|
61
|
+
2. `cleanOldAwemeCache` 判据 `createdAt` → `updatedAt`;
|
|
62
|
+
3. `favorite.ts` / `recommend.ts` 的 `updateListSnapshot` → `touchAwemeCache`;
|
|
63
|
+
4. `push.ts` 把清理块挪到 `const data = await this.getDynamicList(...)` **之后**;
|
|
64
|
+
5. `updateListSnapshot` 是否保留需确认(本地 `douyinListSnapshot` 表还有没有别的读取方)。
|
|
65
|
+
|
|
66
|
+
⚠️ 迁移期风险:老记录 `createdAt` 早、`updatedAt` 也早,第一次跑如果先清理后续期,
|
|
67
|
+
会重推一轮。所以第 4 点必须和第 2 点同批上线。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2. `677e213` 评论二维码头像 + 深色模式 —— ❌ 未移植
|
|
72
|
+
|
|
73
|
+
### 上游改了什么
|
|
74
|
+
|
|
75
|
+
三张评论卡片(B站/快手/小红书)的二维码从 `generateQRCode()` 换成 `<QRCodeWithAvatar>`,
|
|
76
|
+
把作者头像放到二维码正中;`Comment.tsx` 的 types 各加一个 `AuthorAvatar?: string`;
|
|
77
|
+
三个平台对应的 `.ts` 在渲染评论卡时把头像传进去。
|
|
78
|
+
另外小红书 `noteInfo.tsx` 也补了 `avatarUrl={data.author.avatar}`。
|
|
79
|
+
|
|
80
|
+
### 本地现状
|
|
81
|
+
|
|
82
|
+
- ✅ `src/ktr/template/components/QRCodeWithAvatar.tsx` **已存在**(1737 字节),
|
|
83
|
+
抖音评论卡 + 小红书 noteInfo 已经在用;
|
|
84
|
+
- ❌ `bilibili/comment`、`kuaishou/comment`、`xiaohongshu/comment` 三处**仍用**
|
|
85
|
+
`import { generateQRCode }` + `<img src={generateQRCode(...)}>`;
|
|
86
|
+
- ❌ 这三个 `types.ts` 里**没有** `AuthorAvatar`;
|
|
87
|
+
- ❌ `xiaohongshu/noteInfo/components/noteInfo.tsx` 的 `QRCodeWithAvatar` **没传** `avatarUrl`。
|
|
88
|
+
|
|
89
|
+
### 移植要点(本地)
|
|
90
|
+
|
|
91
|
+
改 3 张卡的 `Comment.tsx`(换组件)+ 3 个 `types.ts`(加字段)+ 3 个平台 `.ts`(传值)
|
|
92
|
+
+ `noteInfo.tsx`(补 `avatarUrl`)。字段名上游统一叫 `AuthorAvatar`,本地照抄即可。
|
|
93
|
+
小红书那处的头像来源是 `NoteData.data.data.items[0].note_card.user.avatar`。
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 3. `0659c2b` xhs comments —— ❌ 未移植
|
|
98
|
+
|
|
99
|
+
### 上游改了什么
|
|
100
|
+
|
|
101
|
+
- `xiaohongshu/comments.ts` 和 `xiaohongshu.ts` 的类型从 `NoteComments`
|
|
102
|
+
换成 **`XiaohongshuNoteCommentsResponse`**(amagi 换名);
|
|
103
|
+
- `xiaohongshu/comment/components/types.ts` 里 **子评论** 的 `pictures` 从 `string[]`
|
|
104
|
+
换成结构化对象数组(`height/width/url_pre/url_default/info_list`)。
|
|
105
|
+
|
|
106
|
+
### 本地现状
|
|
107
|
+
|
|
108
|
+
- ❌ 仍在用 `NoteComments`(`comments.ts:1`、`xiaohongshu.ts:7`);
|
|
109
|
+
- ⚠️ `types.ts:54` 的**主评论** `pictures` **已经是**结构化数组了 —— 上游这次改的是
|
|
110
|
+
**子评论**(`types.ts:102` 仍是 `string[]`),本地正好漏的就是这一处;
|
|
111
|
+
- ✅ 依赖没问题:本地 amagi `7.0.0-beta.5` **已经导出** `XiaohongshuNoteCommentsResponse`
|
|
112
|
+
(在 `dist/default/index.d.ts` 和 `dist/exports/compat.d.ts` 里都能找到),**不用升依赖**。
|
|
113
|
+
|
|
114
|
+
### 移植要点(本地)
|
|
115
|
+
|
|
116
|
+
改 2 处 import/注解 + 1 处子评论 `pictures` 类型。风险低。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 4. `2fa299a` 字体粗细 —— ❌ 未移植
|
|
121
|
+
|
|
122
|
+
上游把模板里一批 `font-black` 降成 `font-bold`(30 个文件,主要是各卡片的标题/数字)。
|
|
123
|
+
|
|
124
|
+
本地抽样核对:
|
|
125
|
+
|
|
126
|
+
| 文件 | 行 | 现况 |
|
|
127
|
+
|------|-----|------|
|
|
128
|
+
| `bilibili/videoInfo/components/videoInfo.tsx` | 90 | `font-black`(弹幕) |
|
|
129
|
+
| 同上 | 125 | `font-black`(标题 h1) |
|
|
130
|
+
| `components/DefaultLayout.tsx` | 85 | `font-black` |
|
|
131
|
+
| 同上 | 137 | `font-black` |
|
|
132
|
+
|
|
133
|
+
即本地仍是旧的 `font-black`。这属于纯视觉微调,**30 个文件**搬运量不小、收益很小
|
|
134
|
+
(本地还有自研改动,比如 `poweredBy` 那块跟上游已经不一样了),
|
|
135
|
+
建议**按需挑几个用户最常看到的卡片改**,不必全量跟。
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 5. `f4b5312` dy 推送图片用户信息 —— ⚠️ 部分已覆盖
|
|
140
|
+
|
|
141
|
+
上游改的是 `douyin/push/render.ts:527`:
|
|
142
|
+
|
|
143
|
+
```diff
|
|
144
|
+
- const user = Detail_Data.user_info?.data?.user ?? Detail_Data.author
|
|
145
|
+
+ const user = Detail_Data.user_info?.user ?? Detail_Data.author
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
即去掉中间那层 `.data`。本地 `render.ts:527` **已经是新写法**(`user_info?.user`),
|
|
149
|
+
说明这个修复本地已经通过别的方式跟上了。
|
|
150
|
+
|
|
151
|
+
但本地同文件 **54 行**还留着老写法:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
src/karin/platform/douyin/push/render.ts:54
|
|
155
|
+
const subscriber: DouyinUserLike = Detail_Data.user_info?.data?.user ?? Detail_Data.author
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
以及 374 行的 `Detail_Data.user_info?.data?.user?.ip_location`。
|
|
159
|
+
这两处是「订阅者/推荐者」那条路径,**上游这次没动**,但如果 amagi 已经把
|
|
160
|
+
`user_info.data.user` 收成 `user_info.user`,这两处也会取不到值 —— **建议顺手核一下**。
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 6~8. 不适用说明
|
|
165
|
+
|
|
166
|
+
- **`ee22474` 重写 live photo tip**:上游把 `LivePhotoTip.tsx` 从 223 行重写成 280+,
|
|
167
|
+
并重构了 `DefaultLayout` 的页脚(新增 `GlowIcon`/`GlowText` 的 Design By 署名区)。
|
|
168
|
+
本地 `LivePhotoTip.tsx` 是 **295 行自研版**,且 `DefaultLayout` 页脚已经改成
|
|
169
|
+
maimai 自己的署名(「构建工具信息整块去掉:ROLLDOWN / VITE 都不要了」)。
|
|
170
|
+
**上游的页脚署名区对本地无意义**;LivePhotoTip 若要跟,得逐行比对,价值待定。
|
|
171
|
+
- **`049eb2f` update amagi**:上游从 `pkg.pr.new` 的临时构建换回 `7.0.0-beta.4`;
|
|
172
|
+
本地已是 **`7.0.0-beta.5`**,更新,无需处理。
|
|
173
|
+
- **`85088c7` fix: alias**:删掉 `vite.config.ts` 里指向本地 `../amagi/packages/core/src`
|
|
174
|
+
的 alias、把 `node-karin` override 升到 `1.16.3`。都是上游 monorepo 的内部构建配置,
|
|
175
|
+
**本地单包结构没有对应物**。
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 建议的搬运顺序
|
|
180
|
+
|
|
181
|
+
如果决定搬,建议按这个顺序、分批发版:
|
|
182
|
+
|
|
183
|
+
1. **`ff54ba5`(缓存续期)** —— 唯一含真实 bug 修复,单独发一版(patch)。注意判据+时机必须同批。
|
|
184
|
+
2. **`677e213`(二维码头像)** —— 用户能直接看到,改动集中在模板层,风险低,可发 minor。
|
|
185
|
+
3. **`0659c2b`(xhs 子评论 pictures 类型)** —— 改动小,可并进 2 里一起发。
|
|
186
|
+
4. **`2fa299a`(字体粗细)** —— 纯视觉,建议只挑常用卡片改,或干脆不做。
|
|
187
|
+
5. **`f4b5312` 的 54/374 行** —— 顺手核实即可,确认有问题再改。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 附:核对证据
|
|
192
|
+
|
|
193
|
+
- 上游 8 个 commit 的 SHA 均能在 `ikenxuan/karin-plugin-kkk` 上解析到,时间戳 2026-09-16 ~ 2026-09-22;
|
|
194
|
+
- patch 明细来自 GitHub API `GET /repos/ikenxuan/karin-plugin-kkk/commits/<sha>`(含 `files[].patch`);
|
|
195
|
+
- 本地对照全部用现网源码逐行 grep 确认,涉及文件:
|
|
196
|
+
`src/karin/module/db/douyin.ts`、`src/karin/platform/douyin/push.ts`、
|
|
197
|
+
`src/karin/platform/douyin/push/{favorite,recommend,render}.ts`、
|
|
198
|
+
`src/ktr/template/{bilibili,kuaishou,xiaohongshu}/comment/components/{Comment.tsx,types.ts}`、
|
|
199
|
+
`src/ktr/template/xiaohongshu/noteInfo/components/noteInfo.tsx`、
|
|
200
|
+
`src/ktr/template/components/DefaultLayout.tsx`、
|
|
201
|
+
`src/ktr/template/bilibili/videoInfo/components/videoInfo.tsx`、
|
|
202
|
+
`src/karin/platform/xiaohongshu/{comments.ts,xiaohongshu.ts}`。
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 移植结果(2026-10-04,commit `7f1d705`,未发版)
|
|
207
|
+
|
|
208
|
+
用户确认「1~6 全部搬过来」,第 7、8 条不适用。以下为实际落点,并**订正本报告前面两处误判**。
|
|
209
|
+
|
|
210
|
+
| commit | 是否搬 | 落点 | 验证 |
|
|
211
|
+
|---|---|---|---|
|
|
212
|
+
| `ff54ba5` 缓存续期 | ✅ 全搬 | `module/db/douyin.ts` 新增 `touchAwemeCache`,清理判据 `createdAt`→`updatedAt`;`platform/douyin/push.ts` 清理时机挪到 `getDynamicList` 之后;`push/favorite.ts`、`push/recommend.ts` 换成续期调用 | `probe-aweme-ttl.cjs` 21/21 |
|
|
213
|
+
| `677e213` 二维码头像 | ✅ 全搬 | 三张评论卡改 `QRCodeWithAvatar` + `AuthorAvatar`;三份 `types.ts` 加字段;xhs `noteInfo.tsx` 补 `avatarUrl`;B站/快手/小红书平台层传值 | `probe-qrcode-avatar.cjs` 25/25 |
|
|
214
|
+
| `0659c2b` xhs 类型 | ✅ 全搬 | `comments.ts` / `xiaohongshu.ts` 的 `NoteComments` → `XiaohongshuNoteCommentsResponse`;子评论 `pictures` 改结构化数组 | 无专用探针,靠 tsc:**160 → 159** |
|
|
215
|
+
| `2fa299a` 字体 | ✅ 全搬 | 25 个模板文件、136 行按上游 patch 逐行映射;另含本地 `DefaultLayout` 的 `By maimai` 署名行(上游无对应物,class 结构同型) | `probe-font-weight.cjs` 16/16 |
|
|
216
|
+
| `f4b5312` 用户信息 | ✅ 且**扩大到 3 处** | `push/render.ts` 的 527 / 54 / 374 行 `user_info?.data?.user` → `user_info?.user` | `probe-dy-user-info.cjs` 12/12 |
|
|
217
|
+
| `ee22474` 实况图 | ⚠️ 部分 | `LivePhotoTip.tsx` **全量替换**;`DefaultLayout.tsx` **不搬**(上游是给 ikenxuan 加署名,本地已有自己的页脚并写明「ROLLDOWN / VITE 整块去掉」),只取同 commit 里的分隔条对比度微调 | `probe-live-photo-tip.cjs` 20/20 |
|
|
218
|
+
|
|
219
|
+
### 订正一:`f4b5312` 的 54/374 行不是「顺手核实」,是同一个真实缺陷
|
|
220
|
+
|
|
221
|
+
本报告前面写「本地主路径已是新写法(`user_info?.user`)……建议顺手核实 54 行和 374 行」——
|
|
222
|
+
结论对(确实要改),但**依据写反了**:本地 527 行**也还是**旧写法,上游只改了那一处。
|
|
223
|
+
|
|
224
|
+
口径是怎么定死的:`DouyinUserProfileResponse` = amagi 的 `UserProfile_V0`,
|
|
225
|
+
带 `[property: string]: any` 索引签名 ⇒ `.data` 与 `.user` **在类型上都能过**(tsc 帮不上忙)。
|
|
226
|
+
只能看运行时 —— 本地 **15 处**一致用法(`comments.ts:132` 的 `userInfo.data.user.nickname`、
|
|
227
|
+
`douyin.ts:1215` 的 `UserData.data.user.avatar_larger`、`push/live.ts:39`、
|
|
228
|
+
`push.ts:829/1193`、`testPush.ts` 多处)证明 `fetchUserProfile()` 返回**信封**;
|
|
229
|
+
而各推送流程传的是 `userinfo.data`(`push.ts:893`、`favorite.ts:66`、`testPush.ts:110/152`),
|
|
230
|
+
所以 `user_info` 顶层就是 `.user`,没有 `.data`。三处 `.data?.user` 全部恒 `undefined`,
|
|
231
|
+
静默兜底成「作品作者」/「作品自带 ip_location」。
|
|
232
|
+
|
|
233
|
+
`probe-dy-user-info.cjs` 里用「用户资料 重庆 vs 作品自带 北京」制造冲突来断言,
|
|
234
|
+
旧代码会明确给出「北京」。
|
|
235
|
+
|
|
236
|
+
### 订正二:`ee22474` 不是「本地已有 295 行自研版」
|
|
237
|
+
|
|
238
|
+
本报告前面写「本地 `LivePhotoTip.tsx` 是 295 行自研版,需逐行比对后决定合并方式」——
|
|
239
|
+
**这是错的**。把上游改前版本(`2fa299a`)拉下来 `diff -u` 后发现,
|
|
240
|
+
本地那份与上游改前**逐字节一致**,只差两行品牌名(`karin-plugin-kkk`→`koishi-plugin-kkk`、
|
|
241
|
+
`KARIN-PLUGIN`→`KOISHI-PLUGIN`)。
|
|
242
|
+
|
|
243
|
+
所以可以直接整套替换。`DefaultLayout` 才是真正分叉的那块:本地页脚已经换成了
|
|
244
|
+
自己的署名(`By maimai` + QQ 头像)并明确删掉了构建工具区,
|
|
245
|
+
上游 `ee22474` 给 DefaultLayout 加的是「Design By ikenxuan」+ Rolldown/Vite 两行堆叠 ——
|
|
246
|
+
**与本地已有的决定冲突,故不搬**。
|
|
247
|
+
|
|
248
|
+
### 回归
|
|
249
|
+
|
|
250
|
+
- 探针 10 个全绿(含本报告上表 5 个新探针 + `probe-bili-desc` / `probe-extract-once` /
|
|
251
|
+
`probe-extract-buttons` / `probe-group-file-name` / `probe-md-image-size`);
|
|
252
|
+
- `smoke-koishi-commands` 46/46、`smoke-render` 36/36 路由、
|
|
253
|
+
`smoke-comments` / `smoke-commands` / `smoke-md-image` / `smoke-imports` 通过;
|
|
254
|
+
- **tsc 159**(基线 160);
|
|
255
|
+
- `smoke-douyin.cjs` 的「抖音接口被风控时的提示」失败 —— 已用 `git stash` + 重建 HEAD 对照,
|
|
256
|
+
在 `837a222` 上同样失败,**属预先存在的问题**,与本批无关;
|
|
257
|
+
- `deploy.mjs` 已同步本地镜像(326 文件 / 2.83MB),宿主重启后生效。
|
package/lib/build-metadata.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.
|
|
3
|
-
"buildTime": "2026-10-
|
|
4
|
-
"buildTimestamp":
|
|
2
|
+
"version": "3.13.0",
|
|
3
|
+
"buildTime": "2026-10-04T03:01:39.157Z",
|
|
4
|
+
"buildTimestamp": 1791082899161,
|
|
5
5
|
"name": "koishi-plugin-kkk",
|
|
6
6
|
"description": "抖音 / B站 / 快手 / 小红书 视频解析与动态推送,带 QQ 交互面板与弹幕烧录(karin-plugin-kkk 的 Koishi 移植版)",
|
|
7
7
|
"homepage": "https://github.com/maimai993/koishi-plugin-kkk#readme",
|
|
8
|
-
"commitHash": "
|
|
9
|
-
"shortCommitHash": "
|
|
8
|
+
"commitHash": "4d322db76de3637eeb155bf556cbd771e4cedf7b",
|
|
9
|
+
"shortCommitHash": "4d322db"
|
|
10
10
|
}
|
|
@@ -444,35 +444,35 @@ class DouyinDBBase {
|
|
|
444
444
|
return false; // 如果没有 sec_uid,默认不过滤
|
|
445
445
|
}
|
|
446
446
|
const { filterMode, filterWords, filterTags } = await this.getFilterConfig(sec_uid);
|
|
447
|
-
node_karin_1.logger.debug(`
|
|
448
|
-
获取用户${PushItem.remark}(${PushItem.sec_uid})的过滤配置:
|
|
449
|
-
过滤模式:${filterMode}
|
|
450
|
-
过滤词:${filterWords}
|
|
451
|
-
过滤标签:${filterTags}
|
|
447
|
+
node_karin_1.logger.debug(`
|
|
448
|
+
获取用户${PushItem.remark}(${PushItem.sec_uid})的过滤配置:
|
|
449
|
+
过滤模式:${filterMode}
|
|
450
|
+
过滤词:${filterWords}
|
|
451
|
+
过滤标签:${filterTags}
|
|
452
452
|
`);
|
|
453
453
|
const desc = PushItem.Detail_Data.desc ?? '';
|
|
454
454
|
// 检查内容中是否包含过滤词
|
|
455
455
|
const hasFilterWord = filterWords.some((word) => desc.includes(word));
|
|
456
456
|
// 检查标签中是否包含过滤标签
|
|
457
457
|
const hasFilterTag = filterTags.some((filterTag) => tags.some((tag) => tag === filterTag));
|
|
458
|
-
node_karin_1.logger.debug(`
|
|
459
|
-
作者:${PushItem.remark}
|
|
460
|
-
检查内容:${desc}
|
|
461
|
-
命中词:[${filterWords.join('], [')}]
|
|
462
|
-
命中标签:[${filterTags.join('], [')}]
|
|
463
|
-
过滤模式:${filterMode}
|
|
464
|
-
是否过滤:${hasFilterWord || hasFilterTag ? node_karin_1.logger.red(`${hasFilterWord || hasFilterTag}`) : node_karin_1.logger.green(`${hasFilterWord || hasFilterTag}`)}
|
|
465
|
-
作品地址:${node_karin_1.logger.green(`https://www.douyin.com/video/${PushItem.Detail_Data.aweme_id}`)}
|
|
458
|
+
node_karin_1.logger.debug(`
|
|
459
|
+
作者:${PushItem.remark}
|
|
460
|
+
检查内容:${desc}
|
|
461
|
+
命中词:[${filterWords.join('], [')}]
|
|
462
|
+
命中标签:[${filterTags.join('], [')}]
|
|
463
|
+
过滤模式:${filterMode}
|
|
464
|
+
是否过滤:${hasFilterWord || hasFilterTag ? node_karin_1.logger.red(`${hasFilterWord || hasFilterTag}`) : node_karin_1.logger.green(`${hasFilterWord || hasFilterTag}`)}
|
|
465
|
+
作品地址:${node_karin_1.logger.green(`https://www.douyin.com/video/${PushItem.Detail_Data.aweme_id}`)}
|
|
466
466
|
`);
|
|
467
467
|
// 根据过滤模式决定是否过滤
|
|
468
468
|
if (filterMode === 'blacklist') {
|
|
469
469
|
// 黑名单模式:如果包含过滤词或过滤标签,则过滤
|
|
470
470
|
if (hasFilterWord || hasFilterTag) {
|
|
471
|
-
node_karin_1.logger.warn(`
|
|
472
|
-
作品内容命中黑名单规则,已过滤该作品不再推送
|
|
473
|
-
作品地址:${node_karin_1.logger.yellow(PushItem.Detail_Data.share_url)}
|
|
474
|
-
命中的黑名单词:[${filterWords.join('], [')}]
|
|
475
|
-
命中的黑名单标签:[${filterTags.join('], [')}]
|
|
471
|
+
node_karin_1.logger.warn(`
|
|
472
|
+
作品内容命中黑名单规则,已过滤该作品不再推送
|
|
473
|
+
作品地址:${node_karin_1.logger.yellow(PushItem.Detail_Data.share_url)}
|
|
474
|
+
命中的黑名单词:[${filterWords.join('], [')}]
|
|
475
|
+
命中的黑名单标签:[${filterTags.join('], [')}]
|
|
476
476
|
`);
|
|
477
477
|
return true;
|
|
478
478
|
}
|
|
@@ -487,28 +487,55 @@ class DouyinDBBase {
|
|
|
487
487
|
if (hasFilterWord || hasFilterTag) {
|
|
488
488
|
return false; // 不过滤
|
|
489
489
|
}
|
|
490
|
-
node_karin_1.logger.warn(`
|
|
491
|
-
作品内容未命中白名单规则,已过滤该作品不再推送
|
|
492
|
-
作品地址:${node_karin_1.logger.yellow(PushItem.Detail_Data.share_url)}
|
|
493
|
-
命中的黑名单词:[${filterWords.join('], [')}]
|
|
494
|
-
命中的黑名单标签:[${filterTags.join('], [')}]
|
|
490
|
+
node_karin_1.logger.warn(`
|
|
491
|
+
作品内容未命中白名单规则,已过滤该作品不再推送
|
|
492
|
+
作品地址:${node_karin_1.logger.yellow(PushItem.Detail_Data.share_url)}
|
|
493
|
+
命中的黑名单词:[${filterWords.join('], [')}]
|
|
494
|
+
命中的黑名单标签:[${filterTags.join('], [')}]
|
|
495
495
|
`);
|
|
496
496
|
return true;
|
|
497
497
|
}
|
|
498
498
|
}
|
|
499
499
|
/**
|
|
500
|
-
*
|
|
501
|
-
*
|
|
500
|
+
* 清理过期的作品缓存记录
|
|
501
|
+
*
|
|
502
|
+
* 判据用 `updatedAt`(最后一次仍出现在列表中的时间)而非 `createdAt`:喜欢/推荐列表会长期返回
|
|
503
|
+
* 同一批作品,只要作品还在列表里,每轮推送都会通过 {@link touchAwemeCache} 续期,其去重记录就不会
|
|
504
|
+
* 被清理,从而避免过往作品被反复重推;一旦作品掉出列表、不再续期,超过保留期后即回收,保证缓存表
|
|
505
|
+
* 规模有界。作品列表(post)/直播(live)从不续期,行为与旧逻辑一致(且 post 另有 24h 闸门兜底)。
|
|
506
|
+
* @param days 保留最近几天内仍出现过的记录
|
|
502
507
|
* @returns 删除的记录数量
|
|
503
508
|
*/
|
|
504
509
|
async cleanOldAwemeCache(days = 7) {
|
|
505
510
|
const cutoffDate = new Date();
|
|
506
511
|
cutoffDate.setDate(cutoffDate.getDate() - days);
|
|
507
512
|
const result = await this.db.remove(model_1.TABLE.douyinAwemeCache, {
|
|
508
|
-
|
|
513
|
+
updatedAt: { $lt: cutoffDate.toISOString() }
|
|
509
514
|
});
|
|
510
515
|
return result.removed ?? 0;
|
|
511
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* 为「仍在列表中」的作品续期去重记录(滑动 TTL)
|
|
519
|
+
*
|
|
520
|
+
* 喜欢/推荐列表每轮都用当前返回的全部 aweme_id 调用此方法,把这些记录的 `updatedAt` 刷新到当前
|
|
521
|
+
* 时间。配合 {@link cleanOldAwemeCache} 按 `updatedAt` 清理:仍在列表里的作品永不过期(不会重推),
|
|
522
|
+
* 掉出列表的作品因不再续期而在保留期后被回收(缓存表规模有界)。
|
|
523
|
+
* @param sec_uid 抖音用户sec_uid
|
|
524
|
+
* @param pushType 推送类型
|
|
525
|
+
* @param aweme_ids 当前列表中的全部作品ID
|
|
526
|
+
*/
|
|
527
|
+
async touchAwemeCache(sec_uid, pushType, aweme_ids) {
|
|
528
|
+
const ids = [...new Set(aweme_ids)];
|
|
529
|
+
if (ids.length === 0)
|
|
530
|
+
return;
|
|
531
|
+
await this.db.set(model_1.TABLE.douyinAwemeCache, {
|
|
532
|
+
sec_uid,
|
|
533
|
+
pushType,
|
|
534
|
+
aweme_id: { $in: ids }
|
|
535
|
+
}, {
|
|
536
|
+
updatedAt: now()
|
|
537
|
+
});
|
|
538
|
+
}
|
|
512
539
|
/** 为了向后兼容,保留groupRepository和awemeCacheRepository属性 */
|
|
513
540
|
get groupRepository() {
|
|
514
541
|
return {
|
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.buildImageMessageFor = exports.buildMarkdownImageMessage = exports.toMarkdownImage = exports.sendParseTip = exports.EXTRACT_COMMENT_COMMAND = exports.EXTRACT_COVER_COMMAND = exports.supportsMarkdown = void 0;
|
|
39
|
+
exports.buildImageMessageFor = exports.buildMarkdownImageMessage = exports.toMarkdownImage = exports.sendParseTip = exports.buildBilibiliPanelCardData = exports.EXTRACT_COMMENT_COMMAND = exports.EXTRACT_COVER_COMMAND = exports.supportsMarkdown = void 0;
|
|
40
40
|
exports.rememberPanelRequest = rememberPanelRequest;
|
|
41
41
|
exports.resolvePanelQualitySize = resolvePanelQualitySize;
|
|
42
42
|
exports.resolvePanelToken = resolvePanelToken;
|
|
@@ -98,7 +98,7 @@ const CardImageCache_1 = require("../../module/utils/CardImageCache");
|
|
|
98
98
|
const Render_1 = require("../../module/utils/Render");
|
|
99
99
|
const imageSize_1 = require("../../../compat/imageSize");
|
|
100
100
|
const danmaku_1 = require("../../platform/bilibili/danmaku");
|
|
101
|
-
// 头像框 / 昵称颜色要从 UP
|
|
101
|
+
// 头像框 / 昵称颜色要从 UP 主页接口拿,和解析结果保持一致;简介同样走解析那边的统一口径
|
|
102
102
|
const dynamic_text_1 = require("../../platform/bilibili/dynamic-text");
|
|
103
103
|
// 抖音卡片复用推送那套构建器(保真度最高)
|
|
104
104
|
const render_1 = require("../../platform/douyin/push/render");
|
|
@@ -979,6 +979,46 @@ const panelCardInfo = (buffer, url) => {
|
|
|
979
979
|
}
|
|
980
980
|
return { url, width: size.width, height: size.height };
|
|
981
981
|
};
|
|
982
|
+
/**
|
|
983
|
+
* 面板卡片的 B 站数据(`bilibili/videoInfo` 模板吃的那份)。
|
|
984
|
+
*
|
|
985
|
+
* ## 单独抽成函数,是为了「这张卡也得有简介」这件事能被离线测到
|
|
986
|
+
*
|
|
987
|
+
* 这份对象以前是内联在 {@link uploadPanelCard} 里的,其中 `desc` 被写死成 `''`。
|
|
988
|
+
* 于是出现一个很隐蔽的现象:**解析卡片有简介、面板卡片永远没有**,
|
|
989
|
+
* 而 QQ 上开着面板时解析卡片是**不发**的(见 bilibili.ts 的 `fromPanel` 分支),
|
|
990
|
+
* 用户实际看到的每一张卡都是面板这张 —— 修了解析那边的简介,
|
|
991
|
+
* 用户这边「标题下面还是没有简介」。(见 scripts/probe-bili-desc.cjs)
|
|
992
|
+
*
|
|
993
|
+
* 简介和解析那边走**同一个** {@link buildVideoDescRichText}:接口有时把简介放在
|
|
994
|
+
* `desc_v2` 里、有时只在 `desc` 里,口径收在一处才不会两边不一致。
|
|
995
|
+
*
|
|
996
|
+
* @param detail 稿件对象(`fetchVideoInfo` 的 `data.data`,含 desc / desc_v2)
|
|
997
|
+
* @param fallbackId 稿件对象里没有 bvid 时用的作品 ID(面板请求里的那个)
|
|
998
|
+
* @param hotDanmaku 热门弹幕,卡片顶部飘过的那几条(和解析结果一致)
|
|
999
|
+
* @param ownerCard UP 主页卡片(头像框 / 昵称颜色),拉失败传 null
|
|
1000
|
+
*/
|
|
1001
|
+
const buildBilibiliPanelCardData = (detail, fallbackId, hotDanmaku = [], ownerCard = null) => ({
|
|
1002
|
+
share_url: bilibiliShareUrl(String(detail?.bvid ?? fallbackId)),
|
|
1003
|
+
title: detail?.title,
|
|
1004
|
+
desc: (0, dynamic_text_1.buildVideoDescRichText)(detail?.desc_v2, detail?.desc),
|
|
1005
|
+
stat: detail?.stat,
|
|
1006
|
+
bvid: detail?.bvid ?? fallbackId,
|
|
1007
|
+
ctime: detail?.ctime,
|
|
1008
|
+
pic: detail?.pic,
|
|
1009
|
+
hotDanmaku,
|
|
1010
|
+
/**
|
|
1011
|
+
* 头像框和粉名都来自 UP 主页(userCard)—— 面板只拉了视频信息,
|
|
1012
|
+
* 之前直接传 detail.owner 就少了 frame / usernameMeta 两个字段,
|
|
1013
|
+
* 于是卡片上「没有头像框、名字也不是粉色」。这里和解析那边用同一份构造。
|
|
1014
|
+
*/
|
|
1015
|
+
owner: {
|
|
1016
|
+
...detail?.owner,
|
|
1017
|
+
usernameMeta: ownerCard ? (0, dynamic_text_1.getUsernameMetadata)(ownerCard) : undefined,
|
|
1018
|
+
frame: ownerCard?.pendant?.image || ''
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
exports.buildBilibiliPanelCardData = buildBilibiliPanelCardData;
|
|
982
1022
|
/**
|
|
983
1023
|
* 渲染面板卡片(和解析结果同一套模板)并上传到 assets,拿到 QQ markdown 能用的图片地址。
|
|
984
1024
|
*
|
|
@@ -1029,27 +1069,7 @@ async function uploadPanelCard(e, request, detail, hotDanmaku = []) {
|
|
|
1029
1069
|
}
|
|
1030
1070
|
const route = 'bilibili/videoInfo';
|
|
1031
1071
|
const cardData = request.platform === 'bilibili'
|
|
1032
|
-
?
|
|
1033
|
-
share_url: bilibiliShareUrl(String(detail.bvid ?? request.id)),
|
|
1034
|
-
title: detail.title,
|
|
1035
|
-
desc: '',
|
|
1036
|
-
stat: detail.stat,
|
|
1037
|
-
bvid: detail.bvid ?? request.id,
|
|
1038
|
-
ctime: detail.ctime,
|
|
1039
|
-
pic: detail.pic,
|
|
1040
|
-
// 和解析结果一致:带热门弹幕,卡片顶部就有弹幕飘过
|
|
1041
|
-
hotDanmaku,
|
|
1042
|
-
/**
|
|
1043
|
-
* 头像框和粉名都来自 UP 主页(userCard)—— 面板只拉了视频信息,
|
|
1044
|
-
* 之前直接传 detail.owner 就少了 frame / usernameMeta 两个字段,
|
|
1045
|
-
* 于是卡片上「没有头像框、名字也不是粉色」。这里和解析那边用同一份构造。
|
|
1046
|
-
*/
|
|
1047
|
-
owner: {
|
|
1048
|
-
...detail.owner,
|
|
1049
|
-
usernameMeta: ownerCard ? (0, dynamic_text_1.getUsernameMetadata)(ownerCard) : undefined,
|
|
1050
|
-
frame: ownerCard?.pendant?.image || ''
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1072
|
+
? (0, exports.buildBilibiliPanelCardData)(detail, request.id, hotDanmaku, ownerCard)
|
|
1053
1073
|
: {
|
|
1054
1074
|
// 抖音卡片的数据结构由模板决定,这里先不做卡片,交给兜底面板
|
|
1055
1075
|
};
|
|
@@ -44,8 +44,20 @@ function loadTemplateCss() {
|
|
|
44
44
|
if (cachedCss !== null)
|
|
45
45
|
return cachedCss;
|
|
46
46
|
try {
|
|
47
|
-
const
|
|
48
|
-
|
|
47
|
+
const dir = node_path_1.default.resolve(utils_1.Root.pluginPath, 'resources', 'template');
|
|
48
|
+
let raw = node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'style.css'), 'utf8');
|
|
49
|
+
/**
|
|
50
|
+
* style.css 是 tailwind v4 的**按需产物**,只含构建那一刻扫描到的类。
|
|
51
|
+
* 模板跟着上游更新后,新引入的工具类不会自动出现 —— 页面不报错,只是静默掉间距、
|
|
52
|
+
* 掉尺寸、图标塌成 0 宽(实况照片提示卡就这么崩过)。
|
|
53
|
+
* scripts/sync-template-css.mjs 把上游产物里对应的规则抽到 extra-utilities.css,这里追加。
|
|
54
|
+
*/
|
|
55
|
+
try {
|
|
56
|
+
raw += '\n' + node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'extra-utilities.css'), 'utf8');
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// 没有这个文件就是没同步过,按原样用 style.css
|
|
60
|
+
}
|
|
49
61
|
cachedCss = raw.replace(/url\("?http:\/\/localhost:\d+\/config\/commonResource\//g, 'url("./template-fonts/');
|
|
50
62
|
}
|
|
51
63
|
catch (error) {
|
|
@@ -344,9 +344,7 @@ class Bilibili extends utils_1.Base {
|
|
|
344
344
|
const img = await (0, utils_1.Render)(this.e, 'bilibili/videoInfo', {
|
|
345
345
|
share_url: 'https://b23.tv/' + infoData.data.data.bvid,
|
|
346
346
|
title: infoData.data.data.title,
|
|
347
|
-
desc: infoData.data.data.desc_v2
|
|
348
|
-
? (0, dynamic_text_1.buildBilibiliVideoDescRichText)(infoData.data.data.desc_v2)
|
|
349
|
-
: (0, dynamic_text_1.buildBilibiliDynamicRichText)(infoData.data.data.desc || '', []),
|
|
347
|
+
desc: (0, dynamic_text_1.buildVideoDescRichText)(infoData.data.data.desc_v2, infoData.data.data.desc),
|
|
350
348
|
stat: infoData.data.data.stat,
|
|
351
349
|
bvid: infoData.data.data.bvid,
|
|
352
350
|
ctime: infoData.data.data.ctime,
|
|
@@ -572,7 +570,8 @@ class Bilibili extends utils_1.Base {
|
|
|
572
570
|
shareurl: 'https://b23.tv/' + infoData.data.data.bvid,
|
|
573
571
|
Resolution: useAnonymousQuality
|
|
574
572
|
? null
|
|
575
|
-
: `${playUrlData.data.data.dash.video[0].width} x ${playUrlData.data.data.dash.video[0].height}
|
|
573
|
+
: `${playUrlData.data.data.dash.video[0].width} x ${playUrlData.data.data.dash.video[0].height}`,
|
|
574
|
+
AuthorAvatar: infoData.data.data.owner?.face
|
|
576
575
|
});
|
|
577
576
|
// 评论卡可能极长(实测 2880x40000),交给切片+md 拼接发送,避免 QQ 拒收
|
|
578
577
|
/** 评论区那张长图也记下来,「提取评论区图片」按钮点的是它 */
|
|
@@ -1187,9 +1186,7 @@ class Bilibili extends utils_1.Base {
|
|
|
1187
1186
|
img = await (0, utils_1.Render)(this.e, 'bilibili/dynamic/DYNAMIC_TYPE_AV', {
|
|
1188
1187
|
image_url: INFODATA.data.data.pic,
|
|
1189
1188
|
text: (0, dynamic_text_1.buildBilibiliDynamicRichText)(INFODATA.data.data.title, []),
|
|
1190
|
-
desc: INFODATA.data.data.desc_v2
|
|
1191
|
-
? (0, dynamic_text_1.buildBilibiliVideoDescRichText)(INFODATA.data.data.desc_v2)
|
|
1192
|
-
: (0, dynamic_text_1.buildBilibiliDynamicRichText)(INFODATA.data.data.desc || '', []),
|
|
1189
|
+
desc: (0, dynamic_text_1.buildVideoDescRichText)(INFODATA.data.data.desc_v2, INFODATA.data.data.desc),
|
|
1193
1190
|
dynamic_text: dynamicText,
|
|
1194
1191
|
dianzan: (0, utils_1.Count)(INFODATA.data.data.stat.like),
|
|
1195
1192
|
pinglun: (0, utils_1.Count)(INFODATA.data.data.stat.reply),
|
|
@@ -1358,7 +1355,8 @@ class Bilibili extends utils_1.Base {
|
|
|
1358
1355
|
: `https://t.bilibili.com/${dynamicInfo.data.data.item.id_str}`,
|
|
1359
1356
|
ImageLength: dynamicInfo.data.data.item.modules?.module_dynamic?.major?.draw?.items?.length ?? 0,
|
|
1360
1357
|
shareurl: '动态分享链接',
|
|
1361
|
-
Resolution: null
|
|
1358
|
+
Resolution: null,
|
|
1359
|
+
AuthorAvatar: dynamicInfo.data.data.item.modules?.module_author?.face
|
|
1362
1360
|
});
|
|
1363
1361
|
/** 动态评论区下面只带「提取评论区图片」,封面那个归动态卡片 */
|
|
1364
1362
|
(0, CardImageCache_1.rememberCardImages)(dynamicCardKey, { comment: (0, CardImageCache_1.imageSourcesOf)(img) });
|