koishi-plugin-onebot-info-image 0.0.1-alpha.2 → 0.2.0-alpha.3
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/lib/index.d.ts +27 -0
- package/lib/index.js +1567 -0
- package/lib/renderAdminList.d.ts +3 -0
- package/lib/renderUserInfo.d.ts +14 -0
- package/lib/type.d.ts +157 -0
- package/lib/utils.d.ts +27 -0
- package/package.json +10 -7
- package/readme.md +30 -2
package/lib/index.js
ADDED
|
@@ -0,0 +1,1567 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name2 in all)
|
|
8
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
Config: () => Config,
|
|
24
|
+
apply: () => apply,
|
|
25
|
+
inject: () => inject,
|
|
26
|
+
name: () => name,
|
|
27
|
+
usage: () => usage
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(src_exports);
|
|
30
|
+
var import_koishi = require("koishi");
|
|
31
|
+
var import_fs2 = require("fs");
|
|
32
|
+
var import_path2 = require("path");
|
|
33
|
+
|
|
34
|
+
// src/type.ts
|
|
35
|
+
var IMAGE_STYLES = {
|
|
36
|
+
SOURCE_HAN_SERIF_SC: "思源宋体SourceHanSerifSC",
|
|
37
|
+
LXGW_WENKAI: "落霞孤鹜文楷LXGWWenKai"
|
|
38
|
+
};
|
|
39
|
+
var FONT_FILES = {
|
|
40
|
+
[IMAGE_STYLES.SOURCE_HAN_SERIF_SC]: "SourceHanSerifSC-Medium.otf",
|
|
41
|
+
[IMAGE_STYLES.LXGW_WENKAI]: "LXGWWenKaiMono-Regular.ttf"
|
|
42
|
+
};
|
|
43
|
+
var IMAGE_TYPES = {
|
|
44
|
+
PNG: "png",
|
|
45
|
+
JPEG: "jpeg",
|
|
46
|
+
WEBP: "webp"
|
|
47
|
+
};
|
|
48
|
+
var ONEBOT_IMPL_NAME = {
|
|
49
|
+
LAGRNAGE: "Lagrange",
|
|
50
|
+
NAPCAT: "NapCat"
|
|
51
|
+
// LLONEBOT: "LLOneBot" //todo
|
|
52
|
+
};
|
|
53
|
+
function convertToUnifiedUserInfo(userInfo, onebotImplName) {
|
|
54
|
+
const baseInfo = {
|
|
55
|
+
user_id: userInfo.user_id || userInfo.userId,
|
|
56
|
+
nickname: userInfo.nickname || "",
|
|
57
|
+
sex: userInfo.sex || "unknown",
|
|
58
|
+
age: userInfo.age || 0,
|
|
59
|
+
avatar: userInfo.avatar || ""
|
|
60
|
+
};
|
|
61
|
+
if (onebotImplName === ONEBOT_IMPL_NAME.LAGRNAGE) {
|
|
62
|
+
return {
|
|
63
|
+
...baseInfo,
|
|
64
|
+
card: userInfo.card === null ? "" : userInfo.card || "",
|
|
65
|
+
level: String(userInfo.level || 0),
|
|
66
|
+
role: userInfo.role || "member",
|
|
67
|
+
join_time: userInfo.join_time ? userInfo.join_time * 1e3 : 0,
|
|
68
|
+
last_sent_time: userInfo.last_sent_time ? userInfo.last_sent_time * 1e3 : 0,
|
|
69
|
+
title: userInfo.title || "",
|
|
70
|
+
title_expire_time: userInfo.title_expire_time || 0,
|
|
71
|
+
unfriendly: userInfo.unfriendly || false,
|
|
72
|
+
card_changeable: userInfo.card_changeable || false,
|
|
73
|
+
// Lagrange 特有字段
|
|
74
|
+
sign: userInfo.sign || "",
|
|
75
|
+
q_id: userInfo.q_id || "",
|
|
76
|
+
RegisterTime: userInfo.RegisterTime || "",
|
|
77
|
+
Business: userInfo.Business || [],
|
|
78
|
+
status: userInfo.status || {},
|
|
79
|
+
group_level: userInfo.group_level || userInfo.level || "0"
|
|
80
|
+
};
|
|
81
|
+
} else if (onebotImplName === ONEBOT_IMPL_NAME.NAPCAT) {
|
|
82
|
+
return {
|
|
83
|
+
...baseInfo,
|
|
84
|
+
card: userInfo.card || "",
|
|
85
|
+
level: String(userInfo.level || 0),
|
|
86
|
+
qq_level: userInfo.qq_level || 0,
|
|
87
|
+
role: userInfo.role || "member",
|
|
88
|
+
join_time: userInfo.join_time ? userInfo.join_time * 1e3 : 0,
|
|
89
|
+
last_sent_time: userInfo.last_sent_time ? userInfo.last_sent_time * 1e3 : 0,
|
|
90
|
+
title: userInfo.title || "",
|
|
91
|
+
title_expire_time: userInfo.title_expire_time || 0,
|
|
92
|
+
unfriendly: userInfo.unfriendly || false,
|
|
93
|
+
card_changeable: userInfo.card_changeable || false,
|
|
94
|
+
is_robot: userInfo.is_robot || false,
|
|
95
|
+
shut_up_timestamp: userInfo.shut_up_timestamp || 0,
|
|
96
|
+
// NapCat 特有字段
|
|
97
|
+
uid: userInfo.uid || "",
|
|
98
|
+
uin: userInfo.uin || "",
|
|
99
|
+
nick: userInfo.nick || "",
|
|
100
|
+
remark: userInfo.remark || "",
|
|
101
|
+
constellation: userInfo.constellation || 0,
|
|
102
|
+
shengXiao: userInfo.shengXiao || 0,
|
|
103
|
+
kBloodType: userInfo.kBloodType || 0,
|
|
104
|
+
homeTown: userInfo.homeTown || "",
|
|
105
|
+
makeFriendCareer: userInfo.makeFriendCareer || 0,
|
|
106
|
+
pos: userInfo.pos || "",
|
|
107
|
+
college: userInfo.college || "",
|
|
108
|
+
country: userInfo.country || "",
|
|
109
|
+
province: userInfo.province || "",
|
|
110
|
+
city: userInfo.city || "",
|
|
111
|
+
postCode: userInfo.postCode || "",
|
|
112
|
+
address: userInfo.address || "",
|
|
113
|
+
RegisterTime: userInfo.reg_time ? Number(userInfo.reg_time) * 1e3 : 0,
|
|
114
|
+
//注册时间, napcat是秒级的unix时间戳
|
|
115
|
+
interest: userInfo.interest || "",
|
|
116
|
+
labels: userInfo.labels || [],
|
|
117
|
+
qqLevel: userInfo.qqLevel || 0,
|
|
118
|
+
qid: userInfo.qid || "",
|
|
119
|
+
longNick: userInfo.longNick || "",
|
|
120
|
+
sign: userInfo.long_nick || "",
|
|
121
|
+
// 个性签名
|
|
122
|
+
birthday_year: userInfo.birthday_year || 0,
|
|
123
|
+
birthday_month: userInfo.birthday_month || 0,
|
|
124
|
+
birthday_day: userInfo.birthday_day || 0,
|
|
125
|
+
eMail: userInfo.eMail || "",
|
|
126
|
+
phoneNum: userInfo.phoneNum || "",
|
|
127
|
+
categoryId: userInfo.categoryId || 0,
|
|
128
|
+
richTime: userInfo.richTime || 0,
|
|
129
|
+
richBuffer: userInfo.richBuffer || {},
|
|
130
|
+
topTime: userInfo.topTime || "0",
|
|
131
|
+
isBlock: userInfo.isBlock || false,
|
|
132
|
+
isMsgDisturb: userInfo.isMsgDisturb || false,
|
|
133
|
+
isSpecialCareOpen: userInfo.isSpecialCareOpen || false,
|
|
134
|
+
isSpecialCareZone: userInfo.isSpecialCareZone || false,
|
|
135
|
+
ringId: userInfo.ringId || "",
|
|
136
|
+
isBlocked: userInfo.isBlocked || false,
|
|
137
|
+
recommendImgFlag: userInfo.recommendImgFlag || 0,
|
|
138
|
+
disableEmojiShortCuts: userInfo.disableEmojiShortCuts || 0,
|
|
139
|
+
qidianMasterFlag: userInfo.qidianMasterFlag || 0,
|
|
140
|
+
qidianCrewFlag: userInfo.qidianCrewFlag || 0,
|
|
141
|
+
qidianCrewFlag2: userInfo.qidianCrewFlag2 || 0,
|
|
142
|
+
isHideQQLevel: userInfo.isHideQQLevel || 0,
|
|
143
|
+
isHidePrivilegeIcon: userInfo.isHidePrivilegeIcon || 0,
|
|
144
|
+
status: userInfo.status || 0,
|
|
145
|
+
extStatus: userInfo.extStatus || 0,
|
|
146
|
+
batteryStatus: userInfo.batteryStatus || 0,
|
|
147
|
+
termType: userInfo.termType || 0,
|
|
148
|
+
netType: userInfo.netType || 0,
|
|
149
|
+
iconType: userInfo.iconType || 0,
|
|
150
|
+
customStatus: userInfo.customStatus || null,
|
|
151
|
+
setTime: userInfo.setTime || "0",
|
|
152
|
+
specialFlag: userInfo.specialFlag || 0,
|
|
153
|
+
abiFlag: userInfo.abiFlag || 0,
|
|
154
|
+
eNetworkType: userInfo.eNetworkType || 0,
|
|
155
|
+
showName: userInfo.showName || "",
|
|
156
|
+
termDesc: userInfo.termDesc || "",
|
|
157
|
+
musicInfo: userInfo.musicInfo || { buf: {} },
|
|
158
|
+
extOnlineBusinessInfo: userInfo.extOnlineBusinessInfo || { buf: {}, customStatus: null, videoBizInfo: { cid: "", tvUrl: "", synchType: "" }, videoInfo: { name: "" } },
|
|
159
|
+
extBuffer: userInfo.extBuffer || { buf: {} },
|
|
160
|
+
is_vip: userInfo.is_vip || false,
|
|
161
|
+
is_years_vip: userInfo.is_years_vip || false,
|
|
162
|
+
vip_level: userInfo.vip_level || 0,
|
|
163
|
+
login_days: userInfo.login_days || 0,
|
|
164
|
+
group_level: userInfo.group_level || userInfo.level || "0"
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return baseInfo;
|
|
168
|
+
}
|
|
169
|
+
__name(convertToUnifiedUserInfo, "convertToUnifiedUserInfo");
|
|
170
|
+
function convertToUnifiedAdminInfo(adminInfo, onebotImplName) {
|
|
171
|
+
const baseInfo = {
|
|
172
|
+
user_id: adminInfo.user_id || adminInfo.userId,
|
|
173
|
+
nickname: adminInfo.nickname || "",
|
|
174
|
+
role: adminInfo.role || "admin",
|
|
175
|
+
avatar: adminInfo.avatar || ""
|
|
176
|
+
};
|
|
177
|
+
if (onebotImplName === ONEBOT_IMPL_NAME.LAGRNAGE) {
|
|
178
|
+
return {
|
|
179
|
+
...baseInfo,
|
|
180
|
+
card: adminInfo.card === null ? "" : adminInfo.card || "",
|
|
181
|
+
sex: adminInfo.sex || "",
|
|
182
|
+
age: adminInfo.age || 0,
|
|
183
|
+
area: adminInfo.area || "",
|
|
184
|
+
level: String(adminInfo.level || 0),
|
|
185
|
+
join_time: adminInfo.join_time || 0,
|
|
186
|
+
last_sent_time: adminInfo.last_sent_time || 0,
|
|
187
|
+
title: adminInfo.title || "",
|
|
188
|
+
title_expire_time: adminInfo.title_expire_time || 0,
|
|
189
|
+
unfriendly: adminInfo.unfriendly || false,
|
|
190
|
+
card_changeable: adminInfo.card_changeable || false
|
|
191
|
+
};
|
|
192
|
+
} else if (onebotImplName === ONEBOT_IMPL_NAME.NAPCAT) {
|
|
193
|
+
return {
|
|
194
|
+
...baseInfo,
|
|
195
|
+
card: adminInfo.card || "",
|
|
196
|
+
sex: adminInfo.sex || "unknown",
|
|
197
|
+
age: adminInfo.age || 0,
|
|
198
|
+
area: adminInfo.area || "",
|
|
199
|
+
level: String(adminInfo.level || 0),
|
|
200
|
+
qq_level: adminInfo.qq_level || 0,
|
|
201
|
+
join_time: adminInfo.join_time ? adminInfo.join_time * 1e3 : 0,
|
|
202
|
+
last_sent_time: adminInfo.last_sent_time ? adminInfo.last_sent_time * 1e3 : 0,
|
|
203
|
+
title: adminInfo.title || "",
|
|
204
|
+
title_expire_time: adminInfo.title_expire_time || 0,
|
|
205
|
+
unfriendly: adminInfo.unfriendly || false,
|
|
206
|
+
card_changeable: adminInfo.card_changeable || false,
|
|
207
|
+
is_robot: adminInfo.is_robot || false,
|
|
208
|
+
shut_up_timestamp: adminInfo.shut_up_timestamp || 0
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return baseInfo;
|
|
212
|
+
}
|
|
213
|
+
__name(convertToUnifiedAdminInfo, "convertToUnifiedAdminInfo");
|
|
214
|
+
function convertToUnifiedContextInfo(contextInfo, onebotImplName) {
|
|
215
|
+
return {
|
|
216
|
+
isGroup: contextInfo.isGroup !== void 0 ? contextInfo.isGroup : true,
|
|
217
|
+
groupId: contextInfo.groupId || contextInfo.group_id,
|
|
218
|
+
groupName: contextInfo.groupName || contextInfo.group_name || "未知群聊",
|
|
219
|
+
memberCount: contextInfo.memberCount || contextInfo.member_count || 0,
|
|
220
|
+
maxMemberCount: contextInfo.maxMemberCount || contextInfo.max_member_count || 0,
|
|
221
|
+
groupAvatarUrl: contextInfo.groupAvatarUrl || contextInfo.group_avatar_url || ""
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
__name(convertToUnifiedContextInfo, "convertToUnifiedContextInfo");
|
|
225
|
+
var NAPCAT_QQ_STATUS_MAP = {
|
|
226
|
+
// 主状态码-扩展状态码
|
|
227
|
+
"10-0": "在线",
|
|
228
|
+
"60-0": "Q我吧",
|
|
229
|
+
"30-0": "离开",
|
|
230
|
+
"50-0": "忙碌",
|
|
231
|
+
"70-0": "请勿打扰",
|
|
232
|
+
"40-0": "隐身",
|
|
233
|
+
"10-1028": "听歌中",
|
|
234
|
+
"10-2037": "春日限定",
|
|
235
|
+
"10-2025": "一起元梦",
|
|
236
|
+
"10-2026": "求星搭子",
|
|
237
|
+
"10-2014": "被掏空",
|
|
238
|
+
"10-1030": "今日天气",
|
|
239
|
+
"10-2019": "我crash了",
|
|
240
|
+
"10-2006": "爱你",
|
|
241
|
+
"10-1051": "恋爱中",
|
|
242
|
+
"10-1071": "好运锦鲤",
|
|
243
|
+
"10-1201": "水逆退散",
|
|
244
|
+
"10-1056": "嗨到飞起",
|
|
245
|
+
"10-1058": "元气满满",
|
|
246
|
+
"10-1070": "宝宝认证",
|
|
247
|
+
"10-1063": "一言难尽",
|
|
248
|
+
"10-2001": "难得糊涂",
|
|
249
|
+
"10-1401": "emo中",
|
|
250
|
+
"10-1062": "我太难了",
|
|
251
|
+
"10-2013": "我想开了",
|
|
252
|
+
"10-1052": "我没事",
|
|
253
|
+
"10-1061": "想静静",
|
|
254
|
+
"10-1059": "悠哉哉",
|
|
255
|
+
"10-2015": "去旅行",
|
|
256
|
+
"10-1011": "信号弱",
|
|
257
|
+
"10-2003": "出去浪",
|
|
258
|
+
"10-2012": "肝作业",
|
|
259
|
+
"10-1018": "学习中",
|
|
260
|
+
"10-2023": "搬砖中",
|
|
261
|
+
"10-1300": "摸鱼中",
|
|
262
|
+
"10-1060": "无聊中",
|
|
263
|
+
"10-1027": "timi中",
|
|
264
|
+
"10-1016": "睡觉中",
|
|
265
|
+
"10-1032": "熬夜中",
|
|
266
|
+
"10-1021": "追剧中"
|
|
267
|
+
};
|
|
268
|
+
function getNapcatQQStatusText(status, ext_status) {
|
|
269
|
+
const key = `${status}-${ext_status}`;
|
|
270
|
+
return NAPCAT_QQ_STATUS_MAP[key] || "未知状态";
|
|
271
|
+
}
|
|
272
|
+
__name(getNapcatQQStatusText, "getNapcatQQStatusText");
|
|
273
|
+
|
|
274
|
+
// src/utils.ts
|
|
275
|
+
var import_fs = require("fs");
|
|
276
|
+
var import_path = require("path");
|
|
277
|
+
function generateTimestamp() {
|
|
278
|
+
const now = /* @__PURE__ */ new Date();
|
|
279
|
+
const year = now.getFullYear();
|
|
280
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
281
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
282
|
+
const hours = String(now.getHours()).padStart(2, "0");
|
|
283
|
+
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
284
|
+
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
285
|
+
return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
|
|
286
|
+
}
|
|
287
|
+
__name(generateTimestamp, "generateTimestamp");
|
|
288
|
+
async function getGroupAvatarBase64(ctx, groupId) {
|
|
289
|
+
try {
|
|
290
|
+
const groupAvatarUrl = `https://p.qlogo.cn/gh/${groupId}/${groupId}/640/`;
|
|
291
|
+
const response = await ctx.http.get(groupAvatarUrl, { responseType: "arraybuffer" });
|
|
292
|
+
return Buffer.from(response).toString("base64");
|
|
293
|
+
} catch (error) {
|
|
294
|
+
ctx.logger.warn(`获取群头像失败: ${error.message}`);
|
|
295
|
+
return "";
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
__name(getGroupAvatarBase64, "getGroupAvatarBase64");
|
|
299
|
+
async function getFontBase64(ctx, imageStyle) {
|
|
300
|
+
try {
|
|
301
|
+
const fontFileName = FONT_FILES[imageStyle];
|
|
302
|
+
const fontPath = (0, import_path.join)(__dirname, "..", "assets", fontFileName);
|
|
303
|
+
const fontBuffer = (0, import_fs.readFileSync)(fontPath);
|
|
304
|
+
return fontBuffer.toString("base64");
|
|
305
|
+
} catch (error) {
|
|
306
|
+
ctx.logger.warn(`获取字体文件失败: ${error.message}`);
|
|
307
|
+
return "";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
__name(getFontBase64, "getFontBase64");
|
|
311
|
+
async function validateFonts(ctx) {
|
|
312
|
+
const assetsDir = (0, import_path.join)(__dirname, "..", "assets");
|
|
313
|
+
if (!(0, import_fs.existsSync)(assetsDir)) {
|
|
314
|
+
(0, import_fs.mkdirSync)(assetsDir, { recursive: true });
|
|
315
|
+
}
|
|
316
|
+
const fontConfigs = [
|
|
317
|
+
{
|
|
318
|
+
filename: "LXGWWenKaiMono-Regular.ttf",
|
|
319
|
+
downloadUrl: "https://gitee.com/vincent-zyu/koishi-plugin-onebot-image/releases/download/font/LXGWWenKaiMono-Regular.ttf"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
filename: "SourceHanSerifSC-Medium.otf",
|
|
323
|
+
downloadUrl: "https://gitee.com/vincent-zyu/koishi-plugin-onebot-image/releases/download/font/SourceHanSerifSC-Medium.otf"
|
|
324
|
+
}
|
|
325
|
+
];
|
|
326
|
+
for (const fontConfig of fontConfigs) {
|
|
327
|
+
const fontPath = (0, import_path.join)(assetsDir, fontConfig.filename);
|
|
328
|
+
if (!(0, import_fs.existsSync)(fontPath)) {
|
|
329
|
+
ctx.logger.info(`字体文件 ${fontConfig.filename} 不存在,开始下载...`);
|
|
330
|
+
try {
|
|
331
|
+
const response = await ctx.http.get(fontConfig.downloadUrl, { responseType: "arraybuffer" });
|
|
332
|
+
const fontBuffer = Buffer.from(response);
|
|
333
|
+
(0, import_fs.writeFileSync)(fontPath, fontBuffer);
|
|
334
|
+
ctx.logger.info(`字体文件 ${fontConfig.filename} 下载完成`);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
ctx.logger.error(`下载字体文件 ${fontConfig.filename} 失败: ${error.message}`);
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
ctx.logger.debug(`字体文件 ${fontConfig.filename} 已存在`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
__name(validateFonts, "validateFonts");
|
|
344
|
+
|
|
345
|
+
// src/renderUserInfo.ts
|
|
346
|
+
var formatMsTimestamp = /* @__PURE__ */ __name((timestamp) => {
|
|
347
|
+
if (!timestamp) return '<span class="unknown">未知</span>';
|
|
348
|
+
const date = new Date(timestamp);
|
|
349
|
+
return date.toLocaleString("zh-CN");
|
|
350
|
+
}, "formatMsTimestamp");
|
|
351
|
+
var getSourceHanSerifSCStyleUserInfoHtmlStr = /* @__PURE__ */ __name(async (userInfo, contextInfo, avatarBase64, groupAvatarBase64, fontBase64, enableDarkMode) => {
|
|
352
|
+
const timestamp = generateTimestamp();
|
|
353
|
+
const backgroundStyle = avatarBase64 ? `background-image: url(data:image/jpeg;base64,${avatarBase64});` : `background-color: #f0f2f5;`;
|
|
354
|
+
const getValue = /* @__PURE__ */ __name((value, fallback = '<span class="unknown">未知</span>') => value && value !== "-" ? value : fallback, "getValue");
|
|
355
|
+
const getSex = /* @__PURE__ */ __name((sex) => sex === "male" ? "男" : sex === "female" ? "女" : '<span class="unknown">未知</span>', "getSex");
|
|
356
|
+
const getShengXiao = /* @__PURE__ */ __name((num) => {
|
|
357
|
+
const shengXiaoMap = ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"];
|
|
358
|
+
return shengXiaoMap[num - 1] || "";
|
|
359
|
+
}, "getShengXiao");
|
|
360
|
+
const getConstellation = /* @__PURE__ */ __name((num) => {
|
|
361
|
+
const constellationMap = ["水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"];
|
|
362
|
+
return constellationMap[num - 1] || "";
|
|
363
|
+
}, "getConstellation");
|
|
364
|
+
const getBloodType = /* @__PURE__ */ __name((num) => {
|
|
365
|
+
const bloodTypeMap = ["O", "A", "B", "AB"];
|
|
366
|
+
const type = bloodTypeMap[num];
|
|
367
|
+
return type ? `${type}型` : "";
|
|
368
|
+
}, "getBloodType");
|
|
369
|
+
const getLocationString = /* @__PURE__ */ __name((userInfo2) => {
|
|
370
|
+
const locationParts = [userInfo2.country, userInfo2.province, userInfo2.city, userInfo2.postCode].filter((part) => part && part !== "0" && part !== "-");
|
|
371
|
+
let locationStr = locationParts.length > 0 ? locationParts.join("-") : "";
|
|
372
|
+
if (userInfo2.address && userInfo2.address !== locationStr) {
|
|
373
|
+
locationStr = locationStr ? `${locationStr} ${userInfo2.address}` : userInfo2.address;
|
|
374
|
+
}
|
|
375
|
+
return getValue(locationStr);
|
|
376
|
+
}, "getLocationString");
|
|
377
|
+
const getBirthday = /* @__PURE__ */ __name((userInfo2) => {
|
|
378
|
+
if (userInfo2.birthday_year && userInfo2.birthday_month && userInfo2.birthday_day) {
|
|
379
|
+
return `${userInfo2.birthday_year}年${userInfo2.birthday_month}月${userInfo2.birthday_day}日`;
|
|
380
|
+
}
|
|
381
|
+
return '<span class="unknown">未知</span>';
|
|
382
|
+
}, "getBirthday");
|
|
383
|
+
const getInfoItem = /* @__PURE__ */ __name((label, value, fullWidth = false) => `
|
|
384
|
+
<div class="info-item${fullWidth ? " full-width" : ""}">
|
|
385
|
+
<div class="info-label">${label}</div>
|
|
386
|
+
<div class="info-value">${value}</div>
|
|
387
|
+
</div>
|
|
388
|
+
`, "getInfoItem");
|
|
389
|
+
const getGroupInfoItem = /* @__PURE__ */ __name((label, value, className = "") => `
|
|
390
|
+
<div class="info-item ${className}">
|
|
391
|
+
<div class="info-label">${label}</div>
|
|
392
|
+
<div class="info-value">${value}</div>
|
|
393
|
+
</div>
|
|
394
|
+
`, "getGroupInfoItem");
|
|
395
|
+
const infoItems = [
|
|
396
|
+
getInfoItem("QQ昵称", getValue(userInfo.nickname)),
|
|
397
|
+
getInfoItem("性别", getSex(userInfo.sex)),
|
|
398
|
+
getInfoItem("年龄", getValue(userInfo.age)),
|
|
399
|
+
getInfoItem("QQ等级", getValue(userInfo.qq_level || userInfo.level)),
|
|
400
|
+
getInfoItem("QID", getValue(userInfo.q_id)),
|
|
401
|
+
getInfoItem("注册时间", formatMsTimestamp(userInfo.RegisterTime)),
|
|
402
|
+
getInfoItem("个性签名", getValue(userInfo.sign || userInfo.longNick), true),
|
|
403
|
+
getInfoItem("邮箱", getValue(userInfo.eMail || userInfo.email)),
|
|
404
|
+
getInfoItem("电话", getValue(userInfo.phoneNum || userInfo.phone)),
|
|
405
|
+
getInfoItem("地址信息", getLocationString(userInfo), true),
|
|
406
|
+
`
|
|
407
|
+
<div class="two-column-row">
|
|
408
|
+
<div class="info-item">
|
|
409
|
+
<div class="info-label">生肖</div>
|
|
410
|
+
<div class="info-value">${getValue(getShengXiao(userInfo.shengXiao))}</div>
|
|
411
|
+
</div>
|
|
412
|
+
<div class="info-item">
|
|
413
|
+
<div class="info-label">星座</div>
|
|
414
|
+
<div class="info-value">${getValue(getConstellation(userInfo.constellation))}</div>
|
|
415
|
+
</div>
|
|
416
|
+
</div>
|
|
417
|
+
`,
|
|
418
|
+
getInfoItem("生日", getBirthday(userInfo), true),
|
|
419
|
+
getInfoItem("VIP信息", `VIP: ${userInfo.is_vip ? "是" : "否"} | 年费VIP: ${userInfo.is_years_vip ? "是" : "否"} | VIP等级: ${userInfo.vip_level || 0}`, true),
|
|
420
|
+
getInfoItem("状态", getValue(userInfo.status && userInfo.status.message), true)
|
|
421
|
+
];
|
|
422
|
+
const groupSpecificHtml = contextInfo.isGroup ? `
|
|
423
|
+
<div class="group-info-container">
|
|
424
|
+
<div class="group-info-header">
|
|
425
|
+
<div class="group-avatar-wrapper">
|
|
426
|
+
${groupAvatarBase64 ? `<img class="group-avatar" src="data:image/jpeg;base64,${groupAvatarBase64}" alt="Group Avatar">` : ""}
|
|
427
|
+
<div class="group-name-and-count">
|
|
428
|
+
<div class="group-name">群名: ${contextInfo.groupName || "未知群名"}</div>
|
|
429
|
+
<div class="group-id">群号: ${contextInfo.groupId}</div>
|
|
430
|
+
${contextInfo.memberCount && contextInfo.maxMemberCount ? `<div class="group-member-count">群人数: ${contextInfo.memberCount}/${contextInfo.maxMemberCount}</div>` : contextInfo.memberCount ? `<div class="group-member-count">群人数: ${contextInfo.memberCount}</div>` : ""}
|
|
431
|
+
</div>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="group-info-body">
|
|
435
|
+
${getGroupInfoItem("群名片", getValue(userInfo.card), "full-width")}
|
|
436
|
+
<div class="group-level-role-row">
|
|
437
|
+
${getGroupInfoItem("群等级", getValue(userInfo.group_level || userInfo.level), "group-level-item")}
|
|
438
|
+
${getGroupInfoItem("群角色", userInfo.role === "owner" ? "群主" : userInfo.role === "admin" ? "管理员" : userInfo.role === "member" ? "成员" : '<span class="unknown">未知</span>', "group-role-item")}
|
|
439
|
+
</div>
|
|
440
|
+
${getGroupInfoItem("专属头衔", getValue(userInfo.title), "full-width")}
|
|
441
|
+
<div class="group-time-row">
|
|
442
|
+
${getGroupInfoItem("加群时间", formatMsTimestamp(userInfo.join_time), "join-time-item")}
|
|
443
|
+
${getGroupInfoItem("最后发言", formatMsTimestamp(userInfo.last_sent_time || userInfo.lastSentTime || userInfo.last_speak_time), "last-speak-item")}
|
|
444
|
+
</div>
|
|
445
|
+
</div>
|
|
446
|
+
</div>
|
|
447
|
+
` : "";
|
|
448
|
+
return `<!DOCTYPE html>
|
|
449
|
+
<html>
|
|
450
|
+
<head>
|
|
451
|
+
<style>
|
|
452
|
+
${fontBase64 ? `@font-face{font-family:'SourceHanSerifSC-Medium';src:url('data:font/truetype;charset=utf-8;base64,${fontBase64}') format('truetype');font-weight:normal;font-style:normal;font-display:swap;}` : ""}
|
|
453
|
+
body{font-family:${fontBase64 ? "'SourceHanSerifSC-Medium'," : ""}-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";margin:0;padding:0;width:999px;height:999px;display:flex;align-items:center;justify-content:center;${backgroundStyle}background-size:cover;background-position:center center;background-repeat:no-repeat;position:relative;box-sizing:border-box;overflow:hidden;}
|
|
454
|
+
.card{background:rgba(255,255,255,.13);backdrop-filter:blur(13px) saturate(130%);-webkit-backdrop-filter:blur(13px) saturate(130%);border-radius:32px;box-shadow:0 16px 48px rgba(0,0,0,.3),0 0 0 1px rgba(255,255,255,.25),inset 0 2px 0 rgba(255,255,255,.4);padding:40px;width:920px;height:920px;box-sizing:border-box;border:1px solid rgba(255,255,255,.3);color:#212121;position:relative;z-index:2;display:flex;}
|
|
455
|
+
.card-content{display:flex;width:100%;height:100%;}
|
|
456
|
+
.user-profile{flex:0 0 320px;display:flex;flex-direction:column;align-items:center;text-align:center;padding-right:25px;border-right:1px solid rgba(255,255,255,.3);position:relative;justify-content:space-between;padding-bottom:20px;}
|
|
457
|
+
.avatar-section{display:flex;flex-direction:column;align-items:center;margin-bottom:15px;}
|
|
458
|
+
.avatar{width:270px;height:270px;border-radius:50%;object-fit:cover;margin-bottom:20px;border:5px solid rgba(255,255,255,.8);box-shadow:0 12px 28px rgba(0,0,0,.35),0 0 0 3px rgba(255,255,255,.3);transition:transform .3s cubic-bezier(.25,.8,.25,1);}
|
|
459
|
+
.avatar:hover{transform:scale(1.08);}
|
|
460
|
+
.nickname{font-size:36px;font-weight:800;margin-bottom:12px;color:#111;word-break:break-word;text-shadow:0 3px 6px rgba(255,255,255,.7);background:rgba(255,255,255,.25);padding:14px 28px;border-radius:20px;border:1px solid rgba(255,255,255,.5);letter-spacing:.5px;}
|
|
461
|
+
.userid{font-size:20px;color:#555;background:rgba(255,255,255,.4);padding:12px 20px;border-radius:16px;border:1px solid rgba(255,255,255,.6);margin-bottom:18px;font-weight:600;text-shadow:0 1px 2px rgba(255,255,255,.8);}
|
|
462
|
+
.group-info-container{width:100%;padding:10px 10px;display:flex;flex-direction:column;align-items:center;gap:5px;background:rgba(255,255,255,.2);border-top:1px solid rgba(255,255,255,.3);border-bottom-left-radius:25px;border-bottom-right-radius:25px;box-sizing:border-box;min-height:100px;margin-top:auto;}
|
|
463
|
+
.group-info-header{display:flex;align-items:center;gap:15px;margin-bottom:10px;}
|
|
464
|
+
.group-avatar-wrapper{display:flex;align-items:center;gap:10px;}
|
|
465
|
+
.group-avatar{width:80px;height:80px;border-radius:12px;object-fit:cover;border:3px solid rgba(255,255,255,.7);box-shadow:0 6px 16px rgba(0,0,0,.2);}
|
|
466
|
+
.group-name-and-count{display:flex;flex-direction:column;align-items:flex-start;gap:5px;}
|
|
467
|
+
.group-id, .group-name {font-size:15px;color:#333;background:rgba(255,255,255,.6);padding:6px 12px;border-radius:10px;border:1px solid rgba(255,255,255,.6);font-weight:800;text-shadow:0 1px 3px rgba(255,255,255,.9);line-height:1.02;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;}
|
|
468
|
+
.group-member-count{font-size:13px;color:#007bff;font-weight:bold;background:rgba(0,123,255,.1);border:1px solid rgba(0,123,255,.3);border-radius:8px;padding:4px 8px;margin-top:2px;}
|
|
469
|
+
.group-info-body{width:100%;display:flex;flex-direction:column;gap:5px;}
|
|
470
|
+
.group-info-container .info-item{width:100%;box-sizing:border-box;padding:4px 7px;background:rgba(255,255,255,.5);border-radius:10px;white-space:normal;overflow:visible;text-overflow:visible;min-height:auto;}
|
|
471
|
+
.group-info-container .info-label{margin-bottom:2px;font-size:10px;color:#666;font-weight:500;text-shadow:0 1px 2px rgba(255,255,255,.9);}
|
|
472
|
+
.group-info-container .info-value{font-size:13px;line-height:1.3;color:#212121;color:rgb(3,3,3,.9);word-break:break-all;text-shadow:0 1px 2px rgba(255,255,255,.8);line-height:1.3;}
|
|
473
|
+
.group-level-role-row,.group-time-row{display:flex;gap:6px;width:100%;}
|
|
474
|
+
.group-level-item,.group-role-item,.join-time-item,.last-speak-item{flex:1;margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
475
|
+
.group-info-container .info-item.title-item-row,.group-info-container .info-item.join-time-item-row,.group-info-container .info-item.last-speak-item-row{width:100%;}
|
|
476
|
+
.info-container{flex:1;display:flex;flex-direction:column;gap:15px;padding:0 10px 0 10px;}
|
|
477
|
+
.info-title{font-size:36px;font-weight:700;color:#111;margin-bottom:8px;text-align:center;position:relative;background:rgba(255,255,255,.25);padding:12px 28px;border-radius:18px;border:1px solid rgba(255,255,255,.5);text-shadow:0 3px 6px rgba(255,255,255,.7);}
|
|
478
|
+
.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;flex-grow:1;align-content:start;overflow:visible;}
|
|
479
|
+
.three-column-row{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;grid-column:1/-1;}
|
|
480
|
+
.two-column-row{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;grid-column:1/-1;}
|
|
481
|
+
.info-grid .three-column-row .info-item{grid-column:span 1;}
|
|
482
|
+
.info-grid .two-column-row .info-item{grid-column:span 1;}
|
|
483
|
+
.info-item{background:rgba(255,255,255,.5);border-radius:10px;padding:7px 9px;border:1px solid rgba(255,255,255,.8);transition:all .3s cubic-bezier(.25,.8,.25,1);box-shadow:3px 3px 9px rgba(0,0,0,0.3);}
|
|
484
|
+
.info-item.full-width{grid-column:1/-1;}
|
|
485
|
+
.info-label{font-size:14px;font-weight:500;color:#666;margin-bottom:2px;}
|
|
486
|
+
.info-value{font-size:16px;font-weight:bold;color:#212121;line-height:1.4;}
|
|
487
|
+
.unknown{color:#999;font-style:italic;}
|
|
488
|
+
.timestamp-watermark{position:fixed;top:1.3px;left:1.3px;font-size:13px;color:rgba(128,128,128,.6);font-family:'Courier New',monospace;z-index:9999;pointer-events:none;text-shadow:0 0 2px rgba(255,255,255,.8);}
|
|
489
|
+
body.dark .card{background:rgba(0,0,0,.7);backdrop-filter:blur(15px) saturate(180%);-webkit-backdrop-filter:blur(15px) saturate(180%);border:1px solid rgba(70,70,70,.6);color:#f0f0f0;box-shadow:0 20px 60px rgba(0,0,0,.95),0 0 0 1px rgba(70,70,70,.4),inset 0 3px 0 rgba(120,120,120,.5);}
|
|
490
|
+
body.dark .user-profile{border-right:2px solid #444;background:linear-gradient(135deg,rgba(0,0,0,.3),rgba(60,60,60,.2));}
|
|
491
|
+
body.dark .avatar{border:6px solid #555;box-shadow:0 18px 40px rgba(0,0,0,.7),0 0 0 3px rgba(220,220,220,.9),inset 0 0 25px rgba(0,0,0,.3);}
|
|
492
|
+
body.dark .nickname{color:#f0f0f0;text-shadow:0 3px 5px rgba(0,0,0,.9);background:linear-gradient(135deg,rgba(50,50,50,.8),rgba(30,30,30,.7));border:2px solid rgba(120,120,120,.4);box-shadow:0 10px 25px rgba(0,0,0,.6);}
|
|
493
|
+
body.dark .userid{color:#ccc;background:rgba(70,70,70,.8);border:2px solid #888;box-shadow:0 5px 15px rgba(0,0,0,.4);}
|
|
494
|
+
body.dark .group-info-container{background:linear-gradient(135deg,rgba(50,50,50,.8),rgba(30,30,30,.7));border-top:2px solid #555;box-shadow:0 8px 20px rgba(0,0,0,.3);}
|
|
495
|
+
body.dark .group-avatar{border:3px solid #666;box-shadow:0 8px 20px rgba(0,0,0,.6);}
|
|
496
|
+
body.dark .group-id,body.dark .group-name{color:#ddd;background:rgba(70,70,70,.8);border:2px solid #888;box-shadow:0 4px 10px rgba(0,0,0,.4);}
|
|
497
|
+
body.dark .group-member-count{color:#82c6ff;background:rgba(0,123,255,.15);border:2px solid rgba(0,123,255,.4);box-shadow:0 3px 8px rgba(0,0,0,.4);}
|
|
498
|
+
body.dark .group-info-container .info-label{color:#ccc;}
|
|
499
|
+
body.dark .group-info-container .info-value{color:#eee;}
|
|
500
|
+
body.dark .info-title{background:linear-gradient(135deg,rgba(50,50,50,.8),rgba(30,30,30,.7));color:#f0f0f0;text-shadow:0 3px 5px rgba(0,0,0,.9);border-bottom:3px solid #aaa;box-shadow:0 8px 20px rgba(0,0,0,.6);}
|
|
501
|
+
body.dark .info-item{background:rgba(70,70,70,.85);border:2px solid #888;box-shadow:0 5px 15px rgba(0,0,0,.5);}
|
|
502
|
+
body.dark .info-item:hover{background:rgba(90,90,90,.98);border-color:#777;box-shadow:0 10px 28px rgba(0,0,0,.7);}
|
|
503
|
+
body.dark .info-label{color:#ddd;text-shadow:0 1px 2px rgba(0,0,0,.4);}
|
|
504
|
+
body.dark .info-value{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.3);}
|
|
505
|
+
body.dark .timestamp-watermark{color:rgba(160,160,160,.5);text-shadow:0 0 2px rgba(0,0,0,.8);}
|
|
506
|
+
</style>
|
|
507
|
+
</head>
|
|
508
|
+
<body class="${enableDarkMode ? "dark" : ""}">
|
|
509
|
+
<div class="card">
|
|
510
|
+
<div class="card-content">
|
|
511
|
+
<div class="user-profile">
|
|
512
|
+
<div class="avatar-section">
|
|
513
|
+
${avatarBase64 ? `<img class="avatar" src="data:image/jpeg;base64,${avatarBase64}" alt="User Avatar">` : ""}
|
|
514
|
+
<div class="nickname">${userInfo.nickname || "未知昵称"}</div>
|
|
515
|
+
<div class="userid">QQ号: ${userInfo.user_id}</div>
|
|
516
|
+
</div>
|
|
517
|
+
${groupSpecificHtml}
|
|
518
|
+
</div>
|
|
519
|
+
<div class="info-container">
|
|
520
|
+
<div class="info-title">${contextInfo.isGroup ? "成员详细信息" : "用户信息"}</div>
|
|
521
|
+
<div class="info-grid">
|
|
522
|
+
${infoItems.join("")}
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
<div class="timestamp-watermark">${timestamp}</div>
|
|
528
|
+
</body>
|
|
529
|
+
</html>`;
|
|
530
|
+
}, "getSourceHanSerifSCStyleUserInfoHtmlStr");
|
|
531
|
+
var getLXGWWenKaiUserInfoHtmlStr = /* @__PURE__ */ __name(async (userInfo, contextInfo, avatarBase64, groupAvatarBase64, fontBase64, enableDarkMode) => {
|
|
532
|
+
const isGroup = contextInfo.isGroup;
|
|
533
|
+
const isDarkMode = enableDarkMode;
|
|
534
|
+
const timestamp = (/* @__PURE__ */ new Date()).toLocaleString("zh-CN", {
|
|
535
|
+
year: "numeric",
|
|
536
|
+
month: "2-digit",
|
|
537
|
+
day: "2-digit",
|
|
538
|
+
hour: "2-digit",
|
|
539
|
+
minute: "2-digit",
|
|
540
|
+
second: "2-digit",
|
|
541
|
+
hour12: false
|
|
542
|
+
});
|
|
543
|
+
const getShengXiao = /* @__PURE__ */ __name((num) => ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"][num] || "", "getShengXiao");
|
|
544
|
+
const getConstellation = /* @__PURE__ */ __name((num) => ["摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座"][num - 1] || "", "getConstellation");
|
|
545
|
+
const getBloodType = /* @__PURE__ */ __name((num) => ["O", "A", "B", "AB"][num] || "", "getBloodType");
|
|
546
|
+
const formatAddress = /* @__PURE__ */ __name((user) => {
|
|
547
|
+
const parts = [user.country, user.province, user.city, user.postCode].filter((part) => part && part !== "0" && part !== "-");
|
|
548
|
+
let locationStr = parts.length > 0 ? parts.join("-") : "";
|
|
549
|
+
if (user.address && user.address !== locationStr) {
|
|
550
|
+
locationStr = locationStr ? `${locationStr} ${user.address}` : user.address;
|
|
551
|
+
}
|
|
552
|
+
return locationStr || '<span class="unknown">未知</span>';
|
|
553
|
+
}, "formatAddress");
|
|
554
|
+
const getGroupRole = /* @__PURE__ */ __name((role) => {
|
|
555
|
+
switch (role) {
|
|
556
|
+
case "owner":
|
|
557
|
+
return "群主";
|
|
558
|
+
case "admin":
|
|
559
|
+
return "管理员";
|
|
560
|
+
case "member":
|
|
561
|
+
return "成员";
|
|
562
|
+
default:
|
|
563
|
+
return '<span class="unknown">未知</span>';
|
|
564
|
+
}
|
|
565
|
+
}, "getGroupRole");
|
|
566
|
+
return `<!DOCTYPE html><html><head><style>
|
|
567
|
+
body{font-family:${fontBase64 ? "'LXGWWenKai'," : ""} "SimSun","FangSong","KaiTi",serif;margin:0;padding:0;width:999px;height:999px;display:flex;align-items:center;justify-content:center;${avatarBase64 ? `background-image:linear-gradient(45deg,rgba(245,240,230,.8),rgba(250,245,235,.8)),linear-gradient(to bottom,rgba(245,240,230,.05),rgba(250,245,235,.95)),url(data:image/jpeg;base64,${avatarBase64});` : `background:linear-gradient(45deg,#f5f0e6,#faf5eb);`}background-size:cover;background-position:center;background-repeat:no-repeat;position:relative;box-sizing:border-box;overflow:hidden;color:#3a2f2a;}
|
|
568
|
+
body::before{content:'';position:absolute;top:20px;left:20px;right:20px;bottom:20px;border:3px solid #d4af37;border-radius:20px;background:linear-gradient(135deg,rgba(212,175,55,.1) 0%,rgba(184,134,11,.05) 50%,rgba(212,175,55,.1) 100%);box-shadow:inset 0 0 20px rgba(212,175,55,.3),0 0 30px rgba(212,175,55,.2);z-index:1;}
|
|
569
|
+
.corner-decoration{position:absolute;font-size:24px;color:#d4af37;z-index:2;text-shadow:0 0 10px rgba(212,175,55,.5);}
|
|
570
|
+
.corner-decoration.top-left{top:35px;left:35px;}
|
|
571
|
+
.corner-decoration.top-right{top:35px;right:35px;}
|
|
572
|
+
.corner-decoration.bottom-left{bottom:35px;left:35px;}
|
|
573
|
+
.corner-decoration.bottom-right{bottom:35px;right:35px;}
|
|
574
|
+
.main-container{width:920px;height:920px;position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;padding:50px 40px 30px 40px;box-sizing:border-box;}
|
|
575
|
+
.title-section{text-align:center;margin-bottom:30px;}
|
|
576
|
+
.main-title{font-size:36px;font-weight:700;color:#8b4513;margin-bottom:10px;text-shadow:2px 2px 4px rgba(139,69,19,.3);letter-spacing:4px;}
|
|
577
|
+
.subtitle{font-size:18px;color:#a0522d;letter-spacing:2px;}
|
|
578
|
+
.content-area{display:flex;width:100%;flex:1;gap:30px;}
|
|
579
|
+
.avatar-section{flex:0 0 300px;display:flex;flex-direction:column;align-items:center;text-align:center;}
|
|
580
|
+
.avatar-frame{position:relative;margin-bottom:18px;}
|
|
581
|
+
.avatar{width:200px;height:200px;border-radius:50%;object-fit:cover;border:4px solid #d4af37;box-shadow:0 0 20px rgba(212,175,55,.4),inset 0 0 20px rgba(255,255,255,.2);}
|
|
582
|
+
.avatar-decoration{position:absolute;top:-15px;left:50%;transform:translateX(-50%);font-size:30px;color:#d4af37;text-shadow:0 0 10px rgba(212,175,55,.6);}
|
|
583
|
+
.user-name{font-size:36px;font-weight:700;color:#8b4513;margin-bottom:8px;text-shadow:1px 1px 2px rgba(139,69,19,.3);}
|
|
584
|
+
.user-id{font-size:20px;color:#a0522d;background:rgba(212,175,55,.1);padding:6px 16px;border-radius:20px;border:1px solid rgba(212,175,55,.3);margin-bottom:10px;}
|
|
585
|
+
.group-section{width:100%;background:rgba(212,175,55,.08);border:1px solid rgba(212,175,55,.2);border-radius:15px;padding:15px;text-align:center;margin-top:15px;}
|
|
586
|
+
.group-header{display:flex;align-items:center;gap:15px;margin-bottom:15px;}
|
|
587
|
+
.group-avatar{width:80px;height:80px;border-radius:12px;object-fit:cover;border:2px solid #d4af37;flex-shrink:0;}
|
|
588
|
+
.group-info{display:flex;flex-direction:column;align-items:flex-start;text-align:left;flex-grow:1;}
|
|
589
|
+
.group-id{font-size:16px;color:#8b4513;font-weight:700;}
|
|
590
|
+
.group-name{font-size:16px;color:#8b4513;background:rgba(212,175,55,.15);border:1px solid rgba(212,175,55,.3);border-radius:8px;padding:4px 8px;font-weight:700;margin-top:5px;}
|
|
591
|
+
.group-member-count{font-size:14px;color:#a0522d;margin-top:5px;}
|
|
592
|
+
.info-section{flex-grow:1;display:flex;flex-direction:column;}
|
|
593
|
+
.info-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px 10px;margin:0;align-items:start;}
|
|
594
|
+
.info-card{background:rgba(255,255,255,.2);border:1px solid rgba(212,175,55,.3);border-radius:12px;padding:8px 10px;box-shadow:0 4px 12px rgba(0,0,0,.09);transition:all .3s ease;display:flex;flex-direction:column;justify-content:center;min-height:45px;}
|
|
595
|
+
.info-card:hover{transform:translateY(-2px);box-shadow:0 6px 20px rgba(212,175,55,.2);}
|
|
596
|
+
.info-card.full-width{grid-column:1/-1;}
|
|
597
|
+
.info-label{font-size:15px;color:#8b4513;margin-bottom:2px;font-weight:700;letter-spacing:1px;flex-shrink:0;}
|
|
598
|
+
.info-value{font-size:17px;color:#3a2f2a;line-height:1.2;word-break:break-all;flex:1;min-height:0;display:flex;align-items:center;}
|
|
599
|
+
.unknown{color:#999;font-style:italic;}
|
|
600
|
+
.group-info-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:15px;}
|
|
601
|
+
.group-info-card{background:rgba(212,175,55,.1);border:1px solid rgba(212,175,55,.25);border-radius:10px;padding:6px 10px;}
|
|
602
|
+
.group-info-card.full-width{grid-column:1/-1;}
|
|
603
|
+
.group-info-card .info-label{font-size:13px;color:#8b4513;margin-bottom:2px;font-weight:700;letter-spacing:.5px;}
|
|
604
|
+
.group-info-card .info-value{font-size:15px;color:#3a2f2a;line-height:1.1;word-break:break-all;text-align:center;display:flex;justify-content:center;align-items:center;min-height:2em;}
|
|
605
|
+
.group-info-card .time-value{font-size:13px;}
|
|
606
|
+
.multi-info-row{display:flex;justify-content:space-between;align-items:center;gap:10px;}
|
|
607
|
+
.multi-info-item{flex:1;display:flex;flex-direction:column;}
|
|
608
|
+
.multi-info-item .info-label{font-size:13px;color:#a0522d;font-weight:700;margin-bottom:2px;}
|
|
609
|
+
.multi-info-item .info-value{font-size:15px;color:#3a2f2a;line-height:1.2;}
|
|
610
|
+
.timestamp-watermark{position:fixed;top:1.3px;left:1.3px;font-size:13px;color:rgba(139,69,19,.5);font-family:'Courier New',monospace;z-index:9999;pointer-events:none;text-shadow:0 0 2px rgba(245,240,230,.8);}
|
|
611
|
+
${isDarkMode ? `body{background:linear-gradient(45deg,#2c2416,#3a2f1f);color:#e6d7c3;}body::before{border-color:#b8860b;background:linear-gradient(135deg,rgba(184,134,11,.15) 0%,rgba(139,69,19,.1) 50%,rgba(184,134,11,.15) 100%);box-shadow:inset 0 0 20px rgba(184,134,11,.4),0 0 30px rgba(184,134,11,.3);}body .main-title{color:#daa520;}body .subtitle{color:#cd853f;}body .user-name{color:#daa520;}body .user-id{color:#cd853f;background:rgba(184,134,11,.2);border-color:rgba(184,134,11,.4);}body .info-card{background:rgba(0,0,0,.3);border-color:rgba(184,134,11,.4);}body .info-label{color:#daa520;}body .info-value{color:#e6d7c3;}body .group-section{background:rgba(184,134,11,.15);border-color:rgba(184,134,11,.3);}body .group-member-count{color:#daa520;background:rgba(184,134,11,.25);border-color:rgba(184,134,11,.4);}body .group-info-card{background:rgba(184,134,11,.2);border-color:rgba(184,134,11,.35);}body .timestamp-watermark{color:rgba(205,133,63,.4);text-shadow:0 0 2px rgba(0,0,0,.8);}` : ""}
|
|
612
|
+
${fontBase64 ? `@font-face{font-family:'LXGWWenKai';src:url('data:font/truetype;charset=utf-8;base64,${fontBase64}') format('truetype');font-weight:400;font-style:normal;font-display:swap;}` : ""}
|
|
613
|
+
</style></head><body class="${isDarkMode ? "dark" : ""}">
|
|
614
|
+
<div class="corner-decoration top-left">◆</div>
|
|
615
|
+
<div class="corner-decoration top-right">◆</div>
|
|
616
|
+
<div class="corner-decoration bottom-left">◆</div>
|
|
617
|
+
<div class="corner-decoration bottom-right">◆</div>
|
|
618
|
+
<div class="main-container">
|
|
619
|
+
<div class="title-section">
|
|
620
|
+
<div class="main-title">「 ${isGroup ? "群员信息" : "用户信息"} 」</div>
|
|
621
|
+
<div class="subtitle">—— 详细资料 ——</div>
|
|
622
|
+
</div>
|
|
623
|
+
<div class="content-area">
|
|
624
|
+
<div class="avatar-section">
|
|
625
|
+
<div class="avatar-frame"><div class="avatar-decoration">❀</div>${avatarBase64 ? `<img class="avatar" src="data:image/jpeg;base64,${avatarBase64}" alt="用户头像">` : '<div class="avatar" style="background:linear-gradient(45deg,#d4af37,#b8860b);"></div>'}</div>
|
|
626
|
+
<div class="user-name">${userInfo.nickname || "未知昵称"}</div>
|
|
627
|
+
<div class="user-id">QQ号: ${userInfo.user_id}</div>
|
|
628
|
+
${isGroup ? `
|
|
629
|
+
<div class="group-section">
|
|
630
|
+
<div class="group-header">
|
|
631
|
+
${groupAvatarBase64 ? `<img class="group-avatar" src="data:image/jpeg;base64,${groupAvatarBase64}" alt="群头像">` : ""}
|
|
632
|
+
<div class="group-info">
|
|
633
|
+
<div class="group-id">群号: ${contextInfo.groupId}</div>
|
|
634
|
+
<div class="group-name">群名: ${contextInfo.groupName || "未知群名"}</div>
|
|
635
|
+
${contextInfo.memberCount ? `<div class="group-member-count">群人数: ${contextInfo.memberCount}${contextInfo.maxMemberCount ? `/${contextInfo.maxMemberCount}` : ""}</div>` : ""}
|
|
636
|
+
</div>
|
|
637
|
+
</div>
|
|
638
|
+
<div class="group-info-grid">
|
|
639
|
+
<div class="group-info-card full-width"><div class="info-label">群名片</div><div class="info-value">${userInfo.card || '<span class="unknown">未知</span>'}</div></div>
|
|
640
|
+
<div class="group-info-card"><div class="info-label">群等级</div><div class="info-value">${userInfo.group_level || '<span class="unknown">未知</span>'}</div></div>
|
|
641
|
+
<div class="group-info-card"><div class="info-label">群角色</div><div class="info-value">${getGroupRole(userInfo.role)}</div></div>
|
|
642
|
+
<div class="group-info-card full-width"><div class="info-label">专属头衔</div><div class="info-value">${userInfo.title || '<span class="unknown">未获取</span>'}</div></div>
|
|
643
|
+
<div class="group-info-card"><div class="info-label">加群时间</div><div class="info-value time-value">${userInfo.join_time ? new Date(userInfo.join_time).toLocaleString("zh-CN") : '<span class="unknown">未知</span>'}</div></div>
|
|
644
|
+
<div class="group-info-card"><div class="info-label">最后发言</div><div class="info-value time-value">${userInfo.last_sent_time ? new Date(userInfo.last_sent_time).toLocaleString("zh-CN") : '<span class="unknown">未知</span>'}</div></div>
|
|
645
|
+
</div>
|
|
646
|
+
</div>` : ""}
|
|
647
|
+
</div>
|
|
648
|
+
<div class="info-section">
|
|
649
|
+
<div class="info-grid">
|
|
650
|
+
<div class="info-card"><div class="info-label">性别</div><div class="info-value">${userInfo.sex === "male" ? "男" : userInfo.sex === "female" ? "女" : "未知"}</div></div>
|
|
651
|
+
<div class="info-card"><div class="info-label">年龄</div><div class="info-value">${userInfo.age || '<span class="unknown">未知</span>'}</div></div>
|
|
652
|
+
<div class="info-card"><div class="info-label">QQ等级</div><div class="info-value">${userInfo.qq_level || userInfo.level || '<span class="unknown">未知</span>'}</div></div>
|
|
653
|
+
<div class="info-card"><div class="info-label">QID</div><div class="info-value">${userInfo.q_id || '<span class="unknown">未知</span>'}</div></div>
|
|
654
|
+
${userInfo.sign || userInfo.longNick ? `<div class="info-card full-width"><div class="info-label">个性签名</div><div class="info-value">${userInfo.sign || userInfo.longNick}</div></div>` : ""}
|
|
655
|
+
${userInfo.RegisterTime ? `<div class="info-card full-width"><div class="info-label">注册时间</div><div class="info-value">${new Date(userInfo.RegisterTime).toLocaleString("zh-CN")}</div></div>` : ""}
|
|
656
|
+
<div class="info-card"><div class="info-label">邮箱</div><div class="info-value">${(userInfo.eMail || userInfo.email) && userInfo.eMail !== "-" ? userInfo.eMail || userInfo.email : '<span class="unknown">未知</span>'}</div></div>
|
|
657
|
+
<div class="info-card"><div class="info-label">电话</div><div class="info-value">${userInfo.phoneNum && userInfo.phoneNum !== "-" ? userInfo.phoneNum : '<span class="unknown">未知</span>'}</div></div>
|
|
658
|
+
<div class="info-card full-width"><div class="info-label">地址信息</div><div class="info-value">${formatAddress(userInfo)}</div></div>
|
|
659
|
+
<div class="info-card full-width"><div class="info-label">个人特征</div><div class="info-value multi-info-row">
|
|
660
|
+
<div class="multi-info-item"><div class="info-label">生肖</div><div class="info-value">${getShengXiao(userInfo.shengXiao) || '<span class="unknown">未知</span>'}</div></div>
|
|
661
|
+
<div class="multi-info-item"><div class="info-label">星座</div><div class="info-value">${getConstellation(userInfo.constellation) || '<span class="unknown">未知</span>'}</div></div>
|
|
662
|
+
<div class="multi-info-item"><div class="info-label">血型</div><div class="info-value">${getBloodType(userInfo.kBloodType) ? `${getBloodType(userInfo.kBloodType)}型` : '<span class="unknown">未知</span>'}</div></div>
|
|
663
|
+
</div></div>
|
|
664
|
+
<div class="info-card full-width"><div class="info-label">生日</div><div class="info-value">${userInfo.birthday_year && userInfo.birthday_month && userInfo.birthday_day ? `${userInfo.birthday_year}年${userInfo.birthday_month}月${userInfo.birthday_day}日` : '<span class="unknown">未知</span>'}</div></div>
|
|
665
|
+
<div class="info-card full-width"><div class="info-label">VIP信息</div><div class="info-value multi-info-row">
|
|
666
|
+
<div class="multi-info-item"><div class="info-label">VIP</div><div class="info-value">${userInfo.is_vip ? "是" : "否"}</div></div>
|
|
667
|
+
<div class="multi-info-item"><div class="info-label">年费VIP</div><div class="info-value">${userInfo.is_years_vip ? "是" : "否"}</div></div>
|
|
668
|
+
<div class="multi-info-item"><div class="info-label">VIP等级</div><div class="info-value">${userInfo.vip_level || 0}</div></div>
|
|
669
|
+
</div></div>
|
|
670
|
+
<div class="info-card full-width"><div class="info-label">状态</div><div class="info-value">${userInfo.status && userInfo.status.message || '<span class="unknown">未知</span>'}</div></div>
|
|
671
|
+
</div>
|
|
672
|
+
</div>
|
|
673
|
+
</div>
|
|
674
|
+
</div>
|
|
675
|
+
<div class="timestamp-watermark">${timestamp}</div>
|
|
676
|
+
</body></html>`;
|
|
677
|
+
}, "getLXGWWenKaiUserInfoHtmlStr");
|
|
678
|
+
async function renderUserInfo(ctx, userInfo, contextInfo, imageStyle, enableDarkMode, imageType, screenshotQuality) {
|
|
679
|
+
const browserPage = await ctx.puppeteer.page();
|
|
680
|
+
let avatarBase64;
|
|
681
|
+
let groupAvatarBase64;
|
|
682
|
+
let fontBase64;
|
|
683
|
+
try {
|
|
684
|
+
fontBase64 = await getFontBase64(ctx, imageStyle);
|
|
685
|
+
if (userInfo.avatar) {
|
|
686
|
+
try {
|
|
687
|
+
const avatarBuffer = await ctx.http.file(userInfo.avatar);
|
|
688
|
+
avatarBase64 = Buffer.from(avatarBuffer.data).toString("base64");
|
|
689
|
+
} catch (error) {
|
|
690
|
+
ctx.logger.warn(`Failed to fetch user avatar from ${userInfo.avatar}: ${error.message}`);
|
|
691
|
+
avatarBase64 = void 0;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (contextInfo.isGroup && contextInfo.groupId) {
|
|
695
|
+
groupAvatarBase64 = await getGroupAvatarBase64(ctx, contextInfo.groupId.toString());
|
|
696
|
+
}
|
|
697
|
+
if (!avatarBase64) {
|
|
698
|
+
ctx.logger.info("Using empty avatarBase64 or fallback for background.");
|
|
699
|
+
}
|
|
700
|
+
let htmlContent;
|
|
701
|
+
if (imageStyle === IMAGE_STYLES.SOURCE_HAN_SERIF_SC) {
|
|
702
|
+
htmlContent = await getSourceHanSerifSCStyleUserInfoHtmlStr(userInfo, contextInfo, avatarBase64 || "", groupAvatarBase64 || "", fontBase64 || "", enableDarkMode);
|
|
703
|
+
} else if (imageStyle === IMAGE_STYLES.LXGW_WENKAI) {
|
|
704
|
+
htmlContent = await getLXGWWenKaiUserInfoHtmlStr(userInfo, contextInfo, avatarBase64 || "", groupAvatarBase64 || "", fontBase64 || "", enableDarkMode);
|
|
705
|
+
}
|
|
706
|
+
await browserPage.setViewport({
|
|
707
|
+
width: 999,
|
|
708
|
+
height: 999,
|
|
709
|
+
deviceScaleFactor: 1
|
|
710
|
+
});
|
|
711
|
+
await browserPage.setContent(htmlContent);
|
|
712
|
+
await browserPage.waitForSelector("body", { timeout: 15e3 });
|
|
713
|
+
await browserPage.evaluate(async () => {
|
|
714
|
+
const images = Array.from(document.querySelectorAll("img"));
|
|
715
|
+
await Promise.all(images.map((img) => {
|
|
716
|
+
if (img.complete) return;
|
|
717
|
+
return new Promise((resolve2, reject) => {
|
|
718
|
+
img.addEventListener("load", resolve2);
|
|
719
|
+
img.addEventListener("error", reject);
|
|
720
|
+
});
|
|
721
|
+
}));
|
|
722
|
+
});
|
|
723
|
+
const screenshotBuffer = await browserPage.screenshot({
|
|
724
|
+
encoding: "base64",
|
|
725
|
+
type: imageType,
|
|
726
|
+
// quality: screenshotQuality,
|
|
727
|
+
...imageType !== "png" && { quality: screenshotQuality },
|
|
728
|
+
clip: {
|
|
729
|
+
x: 0,
|
|
730
|
+
y: 0,
|
|
731
|
+
width: 999,
|
|
732
|
+
height: 999
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
return screenshotBuffer;
|
|
736
|
+
} catch (error) {
|
|
737
|
+
ctx.logger.error(`Error rendering user info image: ${error}`);
|
|
738
|
+
throw new Error(`Failed to render user info image: ${error.message}`);
|
|
739
|
+
} finally {
|
|
740
|
+
await browserPage.close();
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
__name(renderUserInfo, "renderUserInfo");
|
|
744
|
+
|
|
745
|
+
// src/renderAdminList.ts
|
|
746
|
+
var generateAdminListItems = /* @__PURE__ */ __name((admins) => {
|
|
747
|
+
return admins.map((admin, index) => `
|
|
748
|
+
<div class="admin-item">
|
|
749
|
+
<div class="admin-column-1">
|
|
750
|
+
<div class="admin-number">${(index + 1).toString().padStart(2, "0")}</div>
|
|
751
|
+
<div class="admin-avatar">
|
|
752
|
+
<img src="${admin.avatar || `https://q1.qlogo.cn/g?b=qq&nk=${admin.user_id}&s=640`}" alt="头像" />
|
|
753
|
+
</div>
|
|
754
|
+
</div>
|
|
755
|
+
<div class="admin-column-2">
|
|
756
|
+
<div class="admin-name">${admin.nickname || "未知"}</div>
|
|
757
|
+
<div class="admin-id"><span class="qq-label">QQ:</span> <span class="qq-number">${admin.user_id}</span></div>
|
|
758
|
+
</div>
|
|
759
|
+
<div class="admin-column-3">
|
|
760
|
+
${admin.card ? `<div class="admin-card"><span class="card-label">群昵称:</span><br><span class="card-content">${admin.card}</span></div>` : '<div class="admin-card-empty">无群昵称</div>'}
|
|
761
|
+
</div>
|
|
762
|
+
<div class="admin-role ${admin.role}">${admin.role === "owner" ? "群 主" : "管理员"}</div>
|
|
763
|
+
</div>
|
|
764
|
+
`).join("");
|
|
765
|
+
}, "generateAdminListItems");
|
|
766
|
+
var getSourceHanSerifSCStyleAdminListHtmlStr = /* @__PURE__ */ __name(async (admins, contextInfo, groupAvatarBase64, fontBase64, enableDarkMode) => {
|
|
767
|
+
const backgroundStyle = groupAvatarBase64 ? `background-image: radial-gradient(circle at center, rgba(255,255,255,0.15), rgba(0,0,0,0.1)), url(data:image/jpeg;base64,${groupAvatarBase64}); background-size: cover; background-position: center center; background-repeat: no-repeat;` : "background: linear-gradient(135deg, #f8f9fa, #e9ecef);";
|
|
768
|
+
const timestamp = generateTimestamp();
|
|
769
|
+
return `<!DOCTYPE html>
|
|
770
|
+
<html>
|
|
771
|
+
<head>
|
|
772
|
+
<style>
|
|
773
|
+
${fontBase64 ? `@font-face { font-family: 'SourceHanSerifSC-Medium'; src: url('data:font/opentype;charset=utf-8;base64,${fontBase64}') format('opentype'); font-weight: normal; font-style: normal; font-display: swap; }` : ""}
|
|
774
|
+
|
|
775
|
+
html, body { margin: 0; padding: 0; width: 100%; height: auto; min-height: 100vh; }
|
|
776
|
+
body {
|
|
777
|
+
font-family: ${fontBase64 ? "'SourceHanSerifSC-Medium'," : ""} -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
778
|
+
width: 800px;
|
|
779
|
+
height: auto;
|
|
780
|
+
min-height: 100vh; /* 确保在内容少时也有足够的背景区域 */
|
|
781
|
+
display: flex;
|
|
782
|
+
align-items: center;
|
|
783
|
+
justify-content: center;
|
|
784
|
+
${backgroundStyle}
|
|
785
|
+
background-repeat: no-repeat;
|
|
786
|
+
position: relative;
|
|
787
|
+
box-sizing: border-box;
|
|
788
|
+
overflow: visible; /* 移除溢出隐藏 */
|
|
789
|
+
color: #333;
|
|
790
|
+
padding: 25px; /* 增加body padding */
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
.card {
|
|
794
|
+
width: 700px;
|
|
795
|
+
height: auto;
|
|
796
|
+
min-height: 400px; /* 可以设置一个最小高度 */
|
|
797
|
+
background: rgba(255, 255, 255, 0.25);
|
|
798
|
+
backdrop-filter: blur(20px) saturate(180%);
|
|
799
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
800
|
+
border-radius: 24px;
|
|
801
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
|
802
|
+
position: relative;
|
|
803
|
+
overflow: visible; /* 移除溢出隐藏 */
|
|
804
|
+
display: flex;
|
|
805
|
+
flex-direction: column;
|
|
806
|
+
padding: 32px;
|
|
807
|
+
box-sizing: border-box;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
.group-header { display: flex; align-items: center; margin-bottom: 20px; padding: 18px; background: rgba(255,255,255,0.3); border: 1px solid rgba(255,255,255,0.4); border-radius: 18px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
|
|
811
|
+
|
|
812
|
+
.group-avatar { width: 75px; height: 75px; border-radius: 50%; margin-right: 16px; border: 3px solid rgba(255,255,255,0.6); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
|
813
|
+
|
|
814
|
+
.group-info { flex: 1; }
|
|
815
|
+
|
|
816
|
+
.group-name { font-size: 30px; font-weight: 700; color: #1a1a1a; margin-bottom: 4px; text-shadow: 0 1px 2px rgba(0,0,0,0.1); }
|
|
817
|
+
|
|
818
|
+
.group-details { font-size: 20px; color: #4a4a4a; line-height: 1.3; font-weight: 500; }
|
|
819
|
+
|
|
820
|
+
.title { font-size: 50px; font-weight: 700; margin-bottom: 16px; color: #1a1a1a; text-shadow: 0 2px 4px rgba(0,0,0,0.1); text-align: center; }
|
|
821
|
+
|
|
822
|
+
.admin-list { width: 100%; display: flex; flex-direction: column; gap: 8px; /* flex: 1; overflow-y: auto; */ } /* 移除 flex: 1 和 overflow-y: auto */
|
|
823
|
+
|
|
824
|
+
.admin-item { background: rgba(255,255,255,0.6); border: 1px solid rgba(255,255,255,0.5); border-radius: 14px; padding: 16px; display: flex; align-items: center; box-shadow: 0 3px 10px rgba(0,0,0,0.08); transition: all 0.3s ease; backdrop-filter: blur(10px); min-height: 70px; }
|
|
825
|
+
|
|
826
|
+
.admin-item:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(0,0,0,0.12); background: rgba(255,255,255,0.7); }
|
|
827
|
+
|
|
828
|
+
.admin-column-1 { display: flex; flex-direction: row; align-items: center; margin-right: 15px; min-width: 60px; text-align: left; }
|
|
829
|
+
|
|
830
|
+
.admin-avatar { margin-bottom: 4px; }
|
|
831
|
+
|
|
832
|
+
.admin-avatar img { width: 90px; height: 90px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.8); box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
|
833
|
+
|
|
834
|
+
.admin-number { font-size: 25px; margin: 0 10px 0 0; font-weight: 700; color: #666; text-align: left; }
|
|
835
|
+
|
|
836
|
+
.admin-column-2 { flex: 1; margin-right: 16px; text-align: left; }
|
|
837
|
+
|
|
838
|
+
.admin-name { font-size: 20px; color: #1a1a1a; font-weight: 600; margin-bottom: 4px; text-align: left; }
|
|
839
|
+
|
|
840
|
+
.admin-id { font-size: 15px; margin-bottom: 2px; text-align: left; }
|
|
841
|
+
|
|
842
|
+
.qq-label { color: #666; font-weight: 500; }
|
|
843
|
+
|
|
844
|
+
.qq-number { color: #1a1a1a; font-weight: 600; font-family: 'Courier New', monospace; }
|
|
845
|
+
|
|
846
|
+
.admin-column-3 { flex: 1; margin-right: 16px; text-align: left; }
|
|
847
|
+
|
|
848
|
+
.admin-card { font-size: 20px; line-height: 1.3; text-align: left; }
|
|
849
|
+
|
|
850
|
+
.card-label { color: #666; font-weight: 500; font-size: 18px; }
|
|
851
|
+
|
|
852
|
+
.card-content { color: #1a1a1a; font-weight: 600; font-size: 20px; }
|
|
853
|
+
|
|
854
|
+
.admin-card-empty { font-size: 20px; color: #999; font-style: italic; text-align: left; }
|
|
855
|
+
|
|
856
|
+
.admin-role { font-size: 20px; font-weight: 700; min-width: 60px; text-align: left; padding: 3px 6px; border-radius: 8px; }
|
|
857
|
+
.admin-role.owner { color: #ff8c00; background: rgba(255,140,0,0.15); }
|
|
858
|
+
.admin-role.admin { color: #007bff; background: rgba(0,123,255,0.1); }
|
|
859
|
+
|
|
860
|
+
.timestamp-watermark { position: fixed; top: 1.3px; left: 1.3px; font-size: 13px; color: rgba(128, 128, 128, 0.6); font-family: 'Courier New', monospace; z-index: 9999; pointer-events: none; text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); }
|
|
861
|
+
|
|
862
|
+
body.dark { color: #e0e0e0; }
|
|
863
|
+
body.dark .card { background: rgba(20,20,20,0.4); box-shadow: 0 20px 60px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1), inset 0 1px 0 rgba(255,255,255,0.15); }
|
|
864
|
+
body.dark .group-header { background: rgba(0,0,0,0.3); border-color: rgba(255,255,255,0.15); }
|
|
865
|
+
body.dark .group-name { color: #ffffff; }
|
|
866
|
+
body.dark .group-details { color: #b0b0b0; }
|
|
867
|
+
body.dark .title { color: #ffffff; text-shadow: 0 2px 4px rgba(0,0,0,0.4); }
|
|
868
|
+
body.dark .admin-item { background: rgba(40,40,40,0.6); border-color: rgba(255,255,255,0.1); box-shadow: 0 3px 10px rgba(0,0,0,0.2); }
|
|
869
|
+
body.dark .admin-item:hover { box-shadow: 0 6px 20px rgba(0,0,0,0.3); background: rgba(50,50,50,0.7); }
|
|
870
|
+
body.dark .admin-number { color: #a0a0a0; }
|
|
871
|
+
body.dark .admin-name { color: #ffffff; }
|
|
872
|
+
body.dark .qq-label { color: #b0b0b0; }
|
|
873
|
+
body.dark .qq-number { color: #ffffff; }
|
|
874
|
+
body.dark .card-label { color: #b0b0b0; }
|
|
875
|
+
body.dark .card-content { color: #ffffff; }
|
|
876
|
+
body.dark .admin-card-empty { color: #666; }
|
|
877
|
+
body.dark .admin-role.owner { color: #ffa07a; background: rgba(255,160,122,0.2); }
|
|
878
|
+
body.dark .admin-role.admin { color: #4da6ff; background: rgba(77,166,255,0.15); }
|
|
879
|
+
body.dark .timestamp-watermark { color: rgba(160, 160, 160, 0.5); text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); }
|
|
880
|
+
</style>
|
|
881
|
+
</head>
|
|
882
|
+
<body class="${enableDarkMode ? "dark" : ""}">
|
|
883
|
+
<div class="card">
|
|
884
|
+
<div class="group-header">
|
|
885
|
+
<img src="data:image/jpeg;base64,${groupAvatarBase64}" alt="群头像" class="group-avatar" />
|
|
886
|
+
<div class="group-info">
|
|
887
|
+
<div class="group-name">${contextInfo.groupName || "未知群聊"}</div>
|
|
888
|
+
<div class="group-details">
|
|
889
|
+
群号: ${contextInfo.groupId}<br>
|
|
890
|
+
成员数: ${contextInfo.memberCount}/${contextInfo.maxMemberCount}
|
|
891
|
+
</div>
|
|
892
|
+
</div>
|
|
893
|
+
</div>
|
|
894
|
+
<div class="title">群管理员列表 (${admins.length}人)</div>
|
|
895
|
+
<div class="admin-list">
|
|
896
|
+
${generateAdminListItems(admins)}
|
|
897
|
+
</div>
|
|
898
|
+
</div>
|
|
899
|
+
<div class="timestamp-watermark">${timestamp}</div>
|
|
900
|
+
</body>
|
|
901
|
+
</html>`;
|
|
902
|
+
}, "getSourceHanSerifSCStyleAdminListHtmlStr");
|
|
903
|
+
var getLXGWWenKaiAdminListHtmlStr = /* @__PURE__ */ __name(async (admins, contextInfo, groupAvatarBase64, fontBase64, enableDarkMode) => {
|
|
904
|
+
const backgroundStyle = groupAvatarBase64 ? `background-image: linear-gradient(45deg, rgba(245,240,230,0.85), rgba(250,245,235,0.85)), url(data:image/jpeg;base64,${groupAvatarBase64}); background-size: cover; background-position: center center; background-repeat: no-repeat;` : `background: linear-gradient(45deg, #f5f0e6, #faf5eb);`;
|
|
905
|
+
const timestamp = generateTimestamp();
|
|
906
|
+
return `<!DOCTYPE html>
|
|
907
|
+
<html>
|
|
908
|
+
<head>
|
|
909
|
+
<style>
|
|
910
|
+
${fontBase64 ? `@font-face { font-family: 'LXGWWenKai'; src: url('data:font/truetype;charset=utf-8;base64,${fontBase64}') format('truetype'); font-weight: normal; font-style: normal; font-display: swap; }` : ""}
|
|
911
|
+
|
|
912
|
+
html, body { margin: 0; padding: 0; width: 100%; /* height: 100%; */ }
|
|
913
|
+
body {
|
|
914
|
+
font-family: ${fontBase64 ? "'LXGWWenKai'," : ""} "SimSun", "FangSong", "KaiTi", serif;
|
|
915
|
+
width: 800px;
|
|
916
|
+
display: flex;
|
|
917
|
+
align-items: center;
|
|
918
|
+
justify-content: center;
|
|
919
|
+
${backgroundStyle}
|
|
920
|
+
background-repeat: no-repeat;
|
|
921
|
+
position: relative;
|
|
922
|
+
box-sizing: border-box;
|
|
923
|
+
/* overflow: hidden; <-- 移除溢出隐藏 */
|
|
924
|
+
color: #3a2f2a;
|
|
925
|
+
min-height: 100vh; /* 确保在内容少时也有足够的背景区域 */
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
body::before { content: ''; position: absolute; top: 16px; left: 16px; right: 16px; bottom: 16px; border: 3px solid #d4af37; border-radius: 20px; background: linear-gradient(135deg, rgba(212,175,55,0.12) 0%, rgba(184,134,11,0.06) 50%, rgba(212,175,55,0.12) 100%); box-shadow: inset 0 0 25px rgba(212,175,55,0.35), 0 0 35px rgba(212,175,55,0.25); z-index: 1; }
|
|
929
|
+
|
|
930
|
+
body::after { content: '◆'; position: absolute; top: 30px; left: 30px; font-size: 26px; color: #d4af37; z-index: 2; text-shadow: 0 0 12px rgba(212,175,55,0.6); }
|
|
931
|
+
|
|
932
|
+
.corner-decoration { position: absolute; font-size: 26px; color: #d4af37; z-index: 2; text-shadow: 0 0 12px rgba(212,175,55,0.6); }
|
|
933
|
+
.corner-decoration.top-right { top: 30px; right: 30px; }
|
|
934
|
+
.corner-decoration.bottom-left { bottom: 30px; left: 30px; }
|
|
935
|
+
.corner-decoration.bottom-right { bottom: 30px; right: 30px; }
|
|
936
|
+
|
|
937
|
+
.main-container {
|
|
938
|
+
width: 720px;
|
|
939
|
+
min-height: 400px; /* 可以设置一个最小高度 */
|
|
940
|
+
position: relative;
|
|
941
|
+
z-index: 3;
|
|
942
|
+
display: flex;
|
|
943
|
+
flex-direction: column;
|
|
944
|
+
padding: 32px 28px;
|
|
945
|
+
box-sizing: border-box;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.group-header { display: flex; align-items: center; margin-bottom: 18px; padding: 16px; background: rgba(255,255,255,0.2); border: 1px solid rgba(212,175,55,0.4); border-radius: 16px; box-shadow: 0 4px 16px rgba(212,175,55,0.15); }
|
|
949
|
+
|
|
950
|
+
.group-avatar { width: 64px; height: 64px; border-radius: 9%; margin-right: 14px; border: 3px solid #d4af37; box-shadow: 0 4px 12px rgba(212,175,55,0.3); }
|
|
951
|
+
|
|
952
|
+
.group-info { flex: 1; }
|
|
953
|
+
|
|
954
|
+
.group-name { font-size: 25px; font-weight: bold; color: #8b4513; margin-bottom: 4px; text-shadow: 1px 1px 2px rgba(139,69,19,0.2); }
|
|
955
|
+
|
|
956
|
+
.group-details { font-size: 20px; color: #a0522d; line-height: 1.4; font-weight: 500; }
|
|
957
|
+
|
|
958
|
+
.title-section { text-align: center; margin-bottom: 14px; }
|
|
959
|
+
|
|
960
|
+
.main-title { font-size: 50px; font-weight: bold; color: #8b4513; margin-bottom: 6px; text-shadow: 2px 2px 4px rgba(139,69,19,0.3); letter-spacing: 2px; }
|
|
961
|
+
|
|
962
|
+
.admin-list { width: 100%; display: flex; flex-direction: column; gap: 6px; /* flex: 1; overflow-y: auto; */ } /* 移除 flex: 1 和 overflow-y: auto */
|
|
963
|
+
|
|
964
|
+
.admin-item { background: rgba(255,255,255,0.25); border: 1px solid rgba(212,175,55,0.4); border-radius: 12px; padding: 14px; display: flex; align-items: center; box-shadow: 0 3px 10px rgba(0,0,0,0.08); transition: all 0.3s ease; backdrop-filter: blur(5px); min-height: 65px; }
|
|
965
|
+
|
|
966
|
+
.admin-item:hover { transform: translateY(-1px); box-shadow: 0 5px 18px rgba(212,175,55,0.25); background: rgba(255,255,255,0.3); }
|
|
967
|
+
|
|
968
|
+
.admin-column-1 { display: flex; flex-direction: row; align-items: center; margin-right: 14px; min-width: 55px; text-align: left; }
|
|
969
|
+
|
|
970
|
+
.admin-avatar { margin-bottom: 4px; }
|
|
971
|
+
|
|
972
|
+
.admin-avatar img { width: 75px; height: 75px; border-radius: 50%; border: 2px solid #d4af37; box-shadow: 0 2px 6px rgba(212,175,55,0.2); }
|
|
973
|
+
|
|
974
|
+
.admin-number { font-size: 36px; margin: 5px 15px 5px 5px; font-weight: bold; color: #8b4513; text-align: left; }
|
|
975
|
+
|
|
976
|
+
.admin-column-2 { flex: 1; margin-right: 10px; text-align: left; }
|
|
977
|
+
|
|
978
|
+
.admin-name { font-size: 18px; color: #3a2f2a; font-weight: bold; margin-bottom: 3px; text-align: left; }
|
|
979
|
+
|
|
980
|
+
.admin-id { font-size: 15px; margin-bottom: 2px; text-align: left; }
|
|
981
|
+
|
|
982
|
+
.qq-label { color: #a0522d; font-weight: 500; }
|
|
983
|
+
|
|
984
|
+
.qq-number { color: #3a2f2a; font-weight: bold; font-family: 'Courier New', monospace; }
|
|
985
|
+
|
|
986
|
+
.admin-column-3 { flex: 1; margin-right: 10px; text-align: left; }
|
|
987
|
+
|
|
988
|
+
.admin-card { font-size: 15px; line-height: 1.3; text-align: left; }
|
|
989
|
+
|
|
990
|
+
.card-label { color: #a0522d; font-weight: 500; font-size: 13px; }
|
|
991
|
+
|
|
992
|
+
.card-content { color: #3a2f2a; font-weight: bold; font-size: 15px; }
|
|
993
|
+
|
|
994
|
+
.admin-card-empty { font-size: 15px; color: #8b7355; font-style: italic; text-align: left; }
|
|
995
|
+
|
|
996
|
+
.admin-role { font-size: 20px; color: #8b4513; font-weight: bold; min-width: 50px; text-align: left; padding: 2px 5px; background: rgba(212,175,55,0.15); border-radius: 6px; border: 1px solid rgba(212,175,55,0.3); }
|
|
997
|
+
|
|
998
|
+
.timestamp-watermark { position: fixed; top: 1.3px; left: 1.3px; font-size: 13px; color: rgba(139, 69, 19, 0.4); font-family: 'Courier New', monospace; z-index: 9999; pointer-events: none; text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); }
|
|
999
|
+
|
|
1000
|
+
body.dark { background: linear-gradient(45deg, #2c2416, #3a2f1f); color: #e6d7c3; }
|
|
1001
|
+
body.dark::before { border-color: #b8860b; background: linear-gradient(135deg, rgba(184,134,11,0.18) 0%, rgba(139,69,19,0.12) 50%, rgba(184,134,11,0.18) 100%); box-shadow: inset 0 0 25px rgba(184,134,11,0.45), 0 0 35px rgba(184,134,11,0.35); }
|
|
1002
|
+
body.dark .group-header { background: rgba(0,0,0,0.3); border-color: rgba(184,134,11,0.5); }
|
|
1003
|
+
body.dark .group-name { color: #daa520; text-shadow: 1px 1px 2px rgba(218,165,32,0.3); }
|
|
1004
|
+
body.dark .group-details { color: #cd853f; }
|
|
1005
|
+
body.dark .main-title { color: #daa520; text-shadow: 2px 2px 4px rgba(218,165,32,0.4); }
|
|
1006
|
+
body.dark .admin-item { background: rgba(0,0,0,0.35); border-color: rgba(184,134,11,0.5); }
|
|
1007
|
+
body.dark .admin-item:hover { box-shadow: 0 5px 18px rgba(184,134,11,0.35); background: rgba(0,0,0,0.4); }
|
|
1008
|
+
body.dark .admin-number { color: #daa520; }
|
|
1009
|
+
body.dark .admin-name { color: #e6d7c3; }
|
|
1010
|
+
body.dark .qq-label { color: #cd853f; }
|
|
1011
|
+
body.dark .qq-number { color: #e6d7c3; }
|
|
1012
|
+
body.dark .card-label { color: #cd853f; }
|
|
1013
|
+
body.dark .card-content { color: #e6d7c3; }
|
|
1014
|
+
body.dark .admin-card-empty { color: #8b7355; }
|
|
1015
|
+
body.dark .admin-role { color: #daa520; background: rgba(184,134,11,0.2); border-color: rgba(184,134,11,0.4); }
|
|
1016
|
+
body.dark .timestamp-watermark { color: rgba(218, 165, 32, 0.4); text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); }
|
|
1017
|
+
</style>
|
|
1018
|
+
</head>
|
|
1019
|
+
<body class="${enableDarkMode ? "dark" : ""}">
|
|
1020
|
+
<div class="corner-decoration top-right">◆</div>
|
|
1021
|
+
<div class="corner-decoration bottom-left">◆</div>
|
|
1022
|
+
<div class="corner-decoration bottom-right">◆</div>
|
|
1023
|
+
<div class="main-container">
|
|
1024
|
+
<div class="group-header">
|
|
1025
|
+
<img src="data:image/jpeg;base64,${groupAvatarBase64}" alt="群头像" class="group-avatar" />
|
|
1026
|
+
<div class="group-info">
|
|
1027
|
+
<div class="group-name">${contextInfo.groupName || "未知群聊"}</div>
|
|
1028
|
+
<div class="group-details">
|
|
1029
|
+
群号: ${contextInfo.groupId} | 成员: ${contextInfo.memberCount}/${contextInfo.maxMemberCount}
|
|
1030
|
+
</div>
|
|
1031
|
+
</div>
|
|
1032
|
+
</div>
|
|
1033
|
+
<div class="title-section">
|
|
1034
|
+
<div class="main-title">「 群管理员列表 (${admins.length}人) 」</div>
|
|
1035
|
+
</div>
|
|
1036
|
+
<div class="admin-list">
|
|
1037
|
+
${generateAdminListItems(admins)}
|
|
1038
|
+
</div>
|
|
1039
|
+
</div>
|
|
1040
|
+
<div class="timestamp-watermark">${timestamp}</div>
|
|
1041
|
+
</body>
|
|
1042
|
+
</html>`;
|
|
1043
|
+
}, "getLXGWWenKaiAdminListHtmlStr");
|
|
1044
|
+
async function renderAdminList(ctx, admins, contextInfo, imageStyle, enableDarkMode, imageType, screenshotQuality) {
|
|
1045
|
+
const browserPage = await ctx.puppeteer.page();
|
|
1046
|
+
admins.sort((a, b) => {
|
|
1047
|
+
if (a.role === "owner") return -1;
|
|
1048
|
+
if (b.role === "owner") return 1;
|
|
1049
|
+
const nameA = a.card || a.nickname;
|
|
1050
|
+
const nameB = b.card || b.nickname;
|
|
1051
|
+
return nameA.localeCompare(nameB, "zh-Hans-CN", { sensitivity: "base" });
|
|
1052
|
+
});
|
|
1053
|
+
try {
|
|
1054
|
+
const groupAvatarBase64 = contextInfo.groupId ? await getGroupAvatarBase64(ctx, contextInfo.groupId.toString()) : "";
|
|
1055
|
+
const fontBase64 = await getFontBase64(ctx, imageStyle);
|
|
1056
|
+
let htmlContent;
|
|
1057
|
+
if (imageStyle === IMAGE_STYLES.SOURCE_HAN_SERIF_SC) {
|
|
1058
|
+
htmlContent = await getSourceHanSerifSCStyleAdminListHtmlStr(
|
|
1059
|
+
admins,
|
|
1060
|
+
contextInfo,
|
|
1061
|
+
groupAvatarBase64,
|
|
1062
|
+
fontBase64,
|
|
1063
|
+
enableDarkMode
|
|
1064
|
+
);
|
|
1065
|
+
} else if (imageStyle === IMAGE_STYLES.LXGW_WENKAI) {
|
|
1066
|
+
htmlContent = await getLXGWWenKaiAdminListHtmlStr(
|
|
1067
|
+
admins,
|
|
1068
|
+
contextInfo,
|
|
1069
|
+
groupAvatarBase64,
|
|
1070
|
+
fontBase64,
|
|
1071
|
+
enableDarkMode
|
|
1072
|
+
);
|
|
1073
|
+
} else {
|
|
1074
|
+
throw new Error(`不支持的图片样式: ${imageStyle}`);
|
|
1075
|
+
}
|
|
1076
|
+
await browserPage.setContent(htmlContent);
|
|
1077
|
+
await browserPage.waitForSelector("body", { timeout: 15e3 });
|
|
1078
|
+
await browserPage.evaluate(() => {
|
|
1079
|
+
const images = Array.from(document.querySelectorAll("img"));
|
|
1080
|
+
return Promise.all(images.filter((img) => !img.complete).map((img) => new Promise((resolve2) => {
|
|
1081
|
+
img.onload = img.onerror = resolve2;
|
|
1082
|
+
})));
|
|
1083
|
+
});
|
|
1084
|
+
const bodyElement = await browserPage.$("body");
|
|
1085
|
+
const boundingBox = await bodyElement.boundingBox();
|
|
1086
|
+
const screenshotBuffer = await browserPage.screenshot({
|
|
1087
|
+
encoding: "base64",
|
|
1088
|
+
type: "png",
|
|
1089
|
+
clip: {
|
|
1090
|
+
x: boundingBox.x,
|
|
1091
|
+
y: boundingBox.y,
|
|
1092
|
+
width: boundingBox.width,
|
|
1093
|
+
height: boundingBox.height
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
return screenshotBuffer;
|
|
1097
|
+
} catch (error) {
|
|
1098
|
+
ctx.logger.error(`渲染管理员列表图片失败: ${error}`);
|
|
1099
|
+
throw error;
|
|
1100
|
+
} finally {
|
|
1101
|
+
await browserPage.close();
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
__name(renderAdminList, "renderAdminList");
|
|
1105
|
+
|
|
1106
|
+
// src/index.ts
|
|
1107
|
+
var name = "onebot-info-image";
|
|
1108
|
+
var inject = {
|
|
1109
|
+
required: ["puppeteer", "http"]
|
|
1110
|
+
};
|
|
1111
|
+
var pkg = JSON.parse(
|
|
1112
|
+
(0, import_fs2.readFileSync)((0, import_path2.resolve)(__dirname, "../package.json"), "utf-8")
|
|
1113
|
+
);
|
|
1114
|
+
var usage = `
|
|
1115
|
+
<h1>Koishi 插件:onebot-info-image 获取群员信息 渲染成图像</h1>
|
|
1116
|
+
<h2>🎯 插件版本:v${pkg.version}</h2>
|
|
1117
|
+
<p>插件使用问题 / Bug反馈 / 插件开发交流,欢迎加入QQ群:<b>259248174</b></p>
|
|
1118
|
+
|
|
1119
|
+
目前仅仅适配了Lagrange 和 Napcat 协议
|
|
1120
|
+
<br>
|
|
1121
|
+
Napcat能拿到的东西更多, 为了更好的使用体验,推荐使用Napcat
|
|
1122
|
+
|
|
1123
|
+
<hr>
|
|
1124
|
+
|
|
1125
|
+
<p>📦 插件仓库地址:</p>
|
|
1126
|
+
<ul>
|
|
1127
|
+
<li><a href="https://gitee.com/vincent-zyu/koishi-plugin-onebot-image">Gitee</a></li>
|
|
1128
|
+
<li><a href="https://github.com/VincentZyu233/koishi-plugin-onebot-image">GitHub</a></li>
|
|
1129
|
+
</ul>
|
|
1130
|
+
|
|
1131
|
+
<hr>
|
|
1132
|
+
|
|
1133
|
+
<h3>字体使用声明</h3>
|
|
1134
|
+
<p>本插件使用以下开源字体进行图像渲染:</p>
|
|
1135
|
+
<ul>
|
|
1136
|
+
<li><b>思源宋体(Source Han Serif SC)</b> - 由 Adobe 与 Google 联合开发,遵循 <a href="https://openfontlicense.org">SIL Open Font License 1.1</a> 协议。</li>
|
|
1137
|
+
<li><b>霞鹜文楷(LXGW WenKai)</b> - 由 LXGW 开发并维护,遵循 <a href="https://openfontlicense.org">SIL Open Font License 1.1</a> 协议。</li>
|
|
1138
|
+
</ul>
|
|
1139
|
+
<p>两者均为自由字体,可在本项目中自由使用、修改与发布。若你也在开发相关插件或项目,欢迎一同使用这些优秀的字体。</p>
|
|
1140
|
+
|
|
1141
|
+
<hr>
|
|
1142
|
+
|
|
1143
|
+
<h3>插件许可声明</h3>
|
|
1144
|
+
<p>本插件为开源免费项目,基于 MIT 协议开放。欢迎修改、分发、二创。</p>
|
|
1145
|
+
<p>如果你觉得插件好用,欢迎在 GitHub 上 Star 或通过其他方式给予支持(例如提供服务器、API Key 或直接赞助)!</p>
|
|
1146
|
+
<p>感谢所有开源字体与项目的贡献者 ❤️</p>
|
|
1147
|
+
`;
|
|
1148
|
+
var Config = import_koishi.Schema.intersect([
|
|
1149
|
+
import_koishi.Schema.object({
|
|
1150
|
+
onebotImplName: import_koishi.Schema.union([
|
|
1151
|
+
import_koishi.Schema.const(ONEBOT_IMPL_NAME.LAGRNAGE).description("Lagrange"),
|
|
1152
|
+
import_koishi.Schema.const(ONEBOT_IMPL_NAME.NAPCAT).description("NapCat")
|
|
1153
|
+
// Schema.const(ONEBOT_IMPL_NAME.LLONEBOT).description('LLOneBot'),
|
|
1154
|
+
]).role("radio").default(ONEBOT_IMPL_NAME.LAGRNAGE).description("【重要】OneBot 的具体实现名称(选错了会导致获取到的内容会变少)")
|
|
1155
|
+
}).description("你的OneBot具体实现平台 是哪一个捏?"),
|
|
1156
|
+
import_koishi.Schema.object({
|
|
1157
|
+
enableUserInfoCommand: import_koishi.Schema.boolean().default(true).description("ℹ️ 是否启用用户信息命令。"),
|
|
1158
|
+
userinfoCommandName: import_koishi.Schema.string().default("用户信息").description("🔍 用户信息命令名称。"),
|
|
1159
|
+
enableGroupAdminListCommand: import_koishi.Schema.boolean().default(false).description("👥 是否启用群管理员列表命令。"),
|
|
1160
|
+
groupAdminListCommandName: import_koishi.Schema.string().default("群管理列表").description("👥 群管理员列表命令名称。")
|
|
1161
|
+
}).description("基础配置 ⚙️"),
|
|
1162
|
+
import_koishi.Schema.object({
|
|
1163
|
+
sendText: import_koishi.Schema.boolean().default(false).description("💬 是否启用文本回复。"),
|
|
1164
|
+
enableQuoteWithText: import_koishi.Schema.boolean().default(false).description("↩️ 回复文本的时候,是否带引用触发指令的消息。")
|
|
1165
|
+
}).description("发送 文本 配置 📝"),
|
|
1166
|
+
import_koishi.Schema.object({
|
|
1167
|
+
sendImage: import_koishi.Schema.boolean().default(true).description("🖼️ 是否启用 Puppeteer 渲染图片。"),
|
|
1168
|
+
enableQuoteWithImage: import_koishi.Schema.boolean().default(false).description("📸 回复图片的时候,是否带引用触发指令的消息。"),
|
|
1169
|
+
imageStyle: import_koishi.Schema.union([
|
|
1170
|
+
import_koishi.Schema.const(IMAGE_STYLES.SOURCE_HAN_SERIF_SC).description("✨ 现代风格,使用SourceHanSerifSC 思源宋体"),
|
|
1171
|
+
import_koishi.Schema.const(IMAGE_STYLES.LXGW_WENKAI).description("📜 简洁古风,使用LXGWWenKai 字体")
|
|
1172
|
+
]).role("radio").default(IMAGE_STYLES.SOURCE_HAN_SERIF_SC).description("🎨 渲染图片的风格与字体。"),
|
|
1173
|
+
enableDarkMode: import_koishi.Schema.boolean().default(false).description("🌙 是否启用暗黑模式。"),
|
|
1174
|
+
imageType: import_koishi.Schema.union([
|
|
1175
|
+
import_koishi.Schema.const(IMAGE_TYPES.PNG).description(`🖼️ ${IMAGE_TYPES.PNG}, ❌ 不支持调整quality`),
|
|
1176
|
+
import_koishi.Schema.const(IMAGE_TYPES.JPEG).description(`🌄 ${IMAGE_TYPES.JPEG}, ✅ 支持调整quality`),
|
|
1177
|
+
import_koishi.Schema.const(IMAGE_TYPES.WEBP).description(`🌐 ${IMAGE_TYPES.WEBP}, ✅ 支持调整quality`)
|
|
1178
|
+
]).role("radio").default(IMAGE_TYPES.PNG).description("📤 渲染图片的输出类型。"),
|
|
1179
|
+
screenshotQuality: import_koishi.Schema.number().min(0).max(100).step(1).default(80).description("📏 Puppeteer 截图质量 (0-100)。")
|
|
1180
|
+
}).description("发送 Puppeteer渲染的图片 配置 🎨"),
|
|
1181
|
+
import_koishi.Schema.object({
|
|
1182
|
+
sendForward: import_koishi.Schema.boolean().default(false).description("➡️ 是否启用转发消息。")
|
|
1183
|
+
}).description("发送 onebot转发消息 配置 ✉️"),
|
|
1184
|
+
import_koishi.Schema.object({
|
|
1185
|
+
verboseSessionOutput: import_koishi.Schema.boolean().default(false).description("🗣️ 是否在会话中输出详细信息。(生产环境别开,东西很多)"),
|
|
1186
|
+
verboseConsoleOutput: import_koishi.Schema.boolean().default(false).description("💻 是否在控制台输出详细信息。")
|
|
1187
|
+
}).description("调试 (Debug) 配置 🐞")
|
|
1188
|
+
]);
|
|
1189
|
+
function apply(ctx, config) {
|
|
1190
|
+
validateFonts(ctx).catch((error) => {
|
|
1191
|
+
ctx.logger.error(`字体文件验证失败: ${error.message}`);
|
|
1192
|
+
});
|
|
1193
|
+
const responseHint = [
|
|
1194
|
+
config.sendText && "文本消息",
|
|
1195
|
+
config.sendImage && "图片消息",
|
|
1196
|
+
config.sendForward && "合并转发消息"
|
|
1197
|
+
].filter(Boolean).join("、");
|
|
1198
|
+
if (config.enableUserInfoCommand)
|
|
1199
|
+
ctx.command(config.userinfoCommandName, `获取用户信息, 发送${responseHint}`).alias("aui").alias("awa_user_info").action(async ({ session }) => {
|
|
1200
|
+
if (!session.onebot)
|
|
1201
|
+
return session.send("[error]当前会话不支持onebot协议。");
|
|
1202
|
+
let targetUserId = session.userId;
|
|
1203
|
+
for (const e of session.event.message.elements) {
|
|
1204
|
+
if (e.type === "at") {
|
|
1205
|
+
targetUserId = e.attrs.id;
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
const userObj = await session.bot.getUser(targetUserId);
|
|
1210
|
+
let userObjMsg = `userObj =
|
|
1211
|
+
${JSON.stringify(userObj)}`;
|
|
1212
|
+
const userAvatarUrl = userObj.avatar;
|
|
1213
|
+
let userInfoArg = {
|
|
1214
|
+
status: null
|
|
1215
|
+
};
|
|
1216
|
+
let contextInfo = {
|
|
1217
|
+
isGroup: false,
|
|
1218
|
+
groupId: null,
|
|
1219
|
+
groupName: null,
|
|
1220
|
+
groupAvatarUrl: null,
|
|
1221
|
+
memberCount: null,
|
|
1222
|
+
maxMemberCount: null
|
|
1223
|
+
};
|
|
1224
|
+
try {
|
|
1225
|
+
const strangerInfoObj = await session.onebot.getStrangerInfo(targetUserId);
|
|
1226
|
+
let strangerInfoObjMsg = `strangerInfoObj =
|
|
1227
|
+
${JSON.stringify(strangerInfoObj)}`;
|
|
1228
|
+
if (config.verboseSessionOutput) await session.send(strangerInfoObjMsg);
|
|
1229
|
+
if (config.verboseConsoleOutput) ctx.logger.info(strangerInfoObjMsg);
|
|
1230
|
+
if (session.guildId) {
|
|
1231
|
+
const groupMemberInfoObj = await session.onebot.getGroupMemberInfo(session.guildId, targetUserId);
|
|
1232
|
+
let groupMemberInfoObjMsg = `groupMemberInfoObj =
|
|
1233
|
+
${JSON.stringify(groupMemberInfoObj)}`;
|
|
1234
|
+
if (config.verboseSessionOutput) await session.send(groupMemberInfoObjMsg);
|
|
1235
|
+
if (config.verboseConsoleOutput) ctx.logger.info(groupMemberInfoObjMsg);
|
|
1236
|
+
const groupInfoObj = await session.onebot.getGroupInfo(session.guildId);
|
|
1237
|
+
let groupInfoObjMsg = `groupInfoObj =
|
|
1238
|
+
${JSON.stringify(groupInfoObj)}`;
|
|
1239
|
+
if (config.verboseSessionOutput) await session.send(groupInfoObjMsg);
|
|
1240
|
+
if (config.verboseConsoleOutput) ctx.logger.info(groupInfoObjMsg);
|
|
1241
|
+
userInfoArg = {
|
|
1242
|
+
...groupMemberInfoObj,
|
|
1243
|
+
...strangerInfoObj,
|
|
1244
|
+
// @ts-ignore - strangerInfoObj 实际包含 age 字段,但类型定义中缺失
|
|
1245
|
+
age: strangerInfoObj.age,
|
|
1246
|
+
// @ts-ignore - strangerInfoObj 实际包含 level 字段,但类型定义中缺失 (here ↓)
|
|
1247
|
+
// node_modules/koishi-plugin-adapter-onebot/lib/types.d.ts: export interface StrangerInfo ...
|
|
1248
|
+
level: strangerInfoObj.level,
|
|
1249
|
+
sex: strangerInfoObj.sex,
|
|
1250
|
+
card: groupMemberInfoObj.card,
|
|
1251
|
+
role: groupMemberInfoObj.role,
|
|
1252
|
+
join_time: groupMemberInfoObj.join_time,
|
|
1253
|
+
last_sent_time: groupMemberInfoObj.last_sent_time,
|
|
1254
|
+
group_level: groupMemberInfoObj.level,
|
|
1255
|
+
title: groupMemberInfoObj.title,
|
|
1256
|
+
avatar: userObj.avatar
|
|
1257
|
+
};
|
|
1258
|
+
contextInfo = {
|
|
1259
|
+
isGroup: true,
|
|
1260
|
+
groupId: session.guildId,
|
|
1261
|
+
//@ts-ignore - groupInfoObj 在lagrange中 实际包含 GroupName 字段,但类型定义中缺失
|
|
1262
|
+
groupName: groupInfoObj.GroupName || groupInfoObj.group_name,
|
|
1263
|
+
groupAvatarUrl: `https://p.qlogo.cn/gh/${session.guildId}/${session.guildId}/640/`,
|
|
1264
|
+
memberCount: groupInfoObj.member_count || 0,
|
|
1265
|
+
maxMemberCount: groupInfoObj.max_member_count || 0
|
|
1266
|
+
};
|
|
1267
|
+
} else {
|
|
1268
|
+
userInfoArg = {
|
|
1269
|
+
...strangerInfoObj,
|
|
1270
|
+
// @ts-ignore - userObj 确实有avatar字段
|
|
1271
|
+
avatar: userObj.avatar
|
|
1272
|
+
};
|
|
1273
|
+
contextInfo = {
|
|
1274
|
+
isGroup: false,
|
|
1275
|
+
groupId: null,
|
|
1276
|
+
groupName: null,
|
|
1277
|
+
groupAvatarUrl: null,
|
|
1278
|
+
memberCount: null,
|
|
1279
|
+
maxMemberCount: null
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
if (config.onebotImplName === ONEBOT_IMPL_NAME.LAGRNAGE) {
|
|
1283
|
+
} else if (config.onebotImplName === ONEBOT_IMPL_NAME.NAPCAT) {
|
|
1284
|
+
const ncUserStatusObj = await session.onebot._request("nc_get_user_status", { user_id: targetUserId });
|
|
1285
|
+
userInfoArg.status = {
|
|
1286
|
+
napcat_origin: ncUserStatusObj,
|
|
1287
|
+
message: getNapcatQQStatusText(ncUserStatusObj?.data.status, ncUserStatusObj?.data.ext_status)
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
let userInfoArgMsg = `userInfoArg =
|
|
1291
|
+
${JSON.stringify(userInfoArg)}`;
|
|
1292
|
+
let contextInfoMsg = `contextInfo =
|
|
1293
|
+
${JSON.stringify(contextInfo)}`;
|
|
1294
|
+
if (config.verboseSessionOutput) {
|
|
1295
|
+
await session.send(userInfoArgMsg);
|
|
1296
|
+
await session.send(contextInfoMsg);
|
|
1297
|
+
}
|
|
1298
|
+
if (config.verboseConsoleOutput) {
|
|
1299
|
+
await ctx.logger.info(userInfoArgMsg);
|
|
1300
|
+
await ctx.logger.info(contextInfoMsg);
|
|
1301
|
+
}
|
|
1302
|
+
const unifiedUserInfo = convertToUnifiedUserInfo(userInfoArg, config.onebotImplName);
|
|
1303
|
+
const unifiedContextInfo = convertToUnifiedContextInfo(contextInfo, config.onebotImplName);
|
|
1304
|
+
let unifiedUserInfoMsg = `unifiedUserInfo =
|
|
1305
|
+
${JSON.stringify(unifiedUserInfo)}`;
|
|
1306
|
+
let unifiedContextInfoMsg = `unifiedContextInfo =
|
|
1307
|
+
${JSON.stringify(unifiedContextInfo)}`;
|
|
1308
|
+
if (config.verboseSessionOutput) {
|
|
1309
|
+
await session.send(unifiedUserInfoMsg);
|
|
1310
|
+
await session.send(unifiedContextInfoMsg);
|
|
1311
|
+
}
|
|
1312
|
+
if (config.verboseConsoleOutput) {
|
|
1313
|
+
await ctx.logger.info(unifiedUserInfoMsg);
|
|
1314
|
+
await ctx.logger.info(unifiedContextInfoMsg);
|
|
1315
|
+
}
|
|
1316
|
+
if (config.sendText) {
|
|
1317
|
+
ctx.logger.info("text");
|
|
1318
|
+
const formattedText = formatUserInfoDirectText(unifiedUserInfo, unifiedContextInfo);
|
|
1319
|
+
session.send(`${config.enableQuoteWithText ? import_koishi.h.quote(session.messageId) : ""}${formattedText}`);
|
|
1320
|
+
}
|
|
1321
|
+
if (config.sendImage) {
|
|
1322
|
+
const waitTipMsgId = await session.send(`${import_koishi.h.quote(session.messageId)}🔄正在渲染用户信息图片,请稍候⏳...`);
|
|
1323
|
+
const userInfoimageBase64 = await renderUserInfo(ctx, unifiedUserInfo, unifiedContextInfo, config.imageStyle, config.enableDarkMode, config.imageType, config.screenshotQuality);
|
|
1324
|
+
await session.send(`${config.enableQuoteWithImage ? import_koishi.h.quote(session.messageId) : ""}${import_koishi.h.image(`data:image/png;base64,${userInfoimageBase64}`)}`);
|
|
1325
|
+
await session.bot.deleteMessage(session.guildId, String(waitTipMsgId));
|
|
1326
|
+
}
|
|
1327
|
+
if (config.sendForward) {
|
|
1328
|
+
const forwardMessageContent = formatUserInfoForwardText(session.bot, unifiedUserInfo, unifiedContextInfo);
|
|
1329
|
+
session.send(import_koishi.h.unescape(forwardMessageContent));
|
|
1330
|
+
}
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
ctx.logger.error(`获取用户信息或渲染图片失败:
|
|
1333
|
+
error=${error}
|
|
1334
|
+
error.stack=${error.stack}`);
|
|
1335
|
+
await session.send(`[error]获取用户信息或渲染图片失败:
|
|
1336
|
+
error.message=${error.message}`);
|
|
1337
|
+
}
|
|
1338
|
+
});
|
|
1339
|
+
if (config.enableGroupAdminListCommand)
|
|
1340
|
+
ctx.command(config.groupAdminListCommandName, `获取群管理员列表, 发送${responseHint}`).alias("al").alias("awa_group_admin_list").action(async ({ session, options }) => {
|
|
1341
|
+
if (!session.onebot)
|
|
1342
|
+
return session.send("[error]当前会话不支持onebot协议。");
|
|
1343
|
+
if (!session.guildId)
|
|
1344
|
+
return session.send("[error]当前会话不在群聊中。");
|
|
1345
|
+
try {
|
|
1346
|
+
const groupMemberListObj = await session.onebot.getGroupMemberList(session.guildId);
|
|
1347
|
+
const groupInfoObj = await session.onebot.getGroupInfo(session.guildId);
|
|
1348
|
+
const groupAdminMemberListObj = groupMemberListObj.filter((m) => m.role === "admin" || m.role === "owner");
|
|
1349
|
+
let groupAdminMemberListObjMsg = `groupAdminMemberListObj =
|
|
1350
|
+
${JSON.stringify(groupAdminMemberListObj)}`;
|
|
1351
|
+
if (config.verboseSessionOutput) await session.send(groupAdminMemberListObjMsg);
|
|
1352
|
+
if (config.verboseConsoleOutput) ctx.logger.info(groupAdminMemberListObjMsg);
|
|
1353
|
+
if (groupAdminMemberListObj.length === 0) {
|
|
1354
|
+
return session.send("该群没有管理员。");
|
|
1355
|
+
}
|
|
1356
|
+
const adminListArg = [];
|
|
1357
|
+
for (const member of groupAdminMemberListObj) {
|
|
1358
|
+
try {
|
|
1359
|
+
const userObj = await session.bot.getUser(member.user_id);
|
|
1360
|
+
const rawAdminInfo = {
|
|
1361
|
+
user_id: member.user_id,
|
|
1362
|
+
nickname: member.nickname,
|
|
1363
|
+
card: member.card,
|
|
1364
|
+
role: member.role,
|
|
1365
|
+
level: member.level,
|
|
1366
|
+
join_time: member.join_time,
|
|
1367
|
+
last_sent_time: member.last_sent_time,
|
|
1368
|
+
title: member.title,
|
|
1369
|
+
avatar: userObj.avatar || ""
|
|
1370
|
+
};
|
|
1371
|
+
adminListArg.push(convertToUnifiedAdminInfo(rawAdminInfo, config.onebotImplName));
|
|
1372
|
+
} catch (error) {
|
|
1373
|
+
ctx.logger.error(`获取管理员列表信息失败: ${error}`);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
adminListArg.sort((a, b) => {
|
|
1377
|
+
if (a.role === "owner" && b.role !== "owner") return -1;
|
|
1378
|
+
if (a.role !== "owner" && b.role === "owner") return 1;
|
|
1379
|
+
const cardA = a.card || "";
|
|
1380
|
+
const cardB = b.card || "";
|
|
1381
|
+
return cardB.localeCompare(cardA, "zh");
|
|
1382
|
+
});
|
|
1383
|
+
const contextInfo = {
|
|
1384
|
+
isGroup: true,
|
|
1385
|
+
groupId: parseInt(session.guildId),
|
|
1386
|
+
groupName: groupInfoObj.group_name || "未知群聊",
|
|
1387
|
+
memberCount: groupInfoObj.member_count || 0,
|
|
1388
|
+
maxMemberCount: groupInfoObj.max_member_count || 0,
|
|
1389
|
+
groupAvatarUrl: `https://p.qlogo.cn/gh/${session.guildId}/${session.guildId}/640/`
|
|
1390
|
+
};
|
|
1391
|
+
if (config.sendText) {
|
|
1392
|
+
const unifiedContextInfo = convertToUnifiedContextInfo(contextInfo, config.onebotImplName);
|
|
1393
|
+
const formattedText = formatAdminListDirectText(adminListArg, unifiedContextInfo);
|
|
1394
|
+
await session.send(`${config.enableQuoteWithText ? import_koishi.h.quote(session.messageId) : ""}${formattedText}`);
|
|
1395
|
+
}
|
|
1396
|
+
if (config.sendImage) {
|
|
1397
|
+
ctx.logger.info(`context info = ${JSON.stringify(contextInfo)}`);
|
|
1398
|
+
const waitTipMsgId = await session.send(`${import_koishi.h.quote(session.messageId)}🔄正在渲染群管理员列表图片,请稍候⏳...`);
|
|
1399
|
+
const unifiedContextInfo = convertToUnifiedContextInfo(contextInfo, config.onebotImplName);
|
|
1400
|
+
const adminListImageBase64 = await renderAdminList(ctx, adminListArg, unifiedContextInfo, config.imageStyle, config.enableDarkMode, config.imageType, config.screenshotQuality);
|
|
1401
|
+
await session.send(`${config.enableQuoteWithImage ? import_koishi.h.quote(session.messageId) : ""}${import_koishi.h.image(`data:image/png;base64,${adminListImageBase64}`)}`);
|
|
1402
|
+
await session.bot.deleteMessage(session.guildId, String(waitTipMsgId));
|
|
1403
|
+
}
|
|
1404
|
+
if (config.sendForward) {
|
|
1405
|
+
const unifiedContextInfo = convertToUnifiedContextInfo(contextInfo, config.onebotImplName);
|
|
1406
|
+
const forwardMessageContent = formatAdminListForwardText(adminListArg, unifiedContextInfo);
|
|
1407
|
+
await session.send(import_koishi.h.unescape(forwardMessageContent));
|
|
1408
|
+
}
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
ctx.logger.error(`获取群管理员列表失败: ${error}`);
|
|
1411
|
+
await session.send(`[error]获取群管理员列表失败: ${error.message}`);
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
function formatUserInfoDirectText(userInfo, contextInfo) {
|
|
1415
|
+
let output = "";
|
|
1416
|
+
output += `----- 用户信息 (UserInfo) -----
|
|
1417
|
+
`;
|
|
1418
|
+
output += `QQ号 (UserID): ${userInfo.user_id}
|
|
1419
|
+
`;
|
|
1420
|
+
if (userInfo.nickname) output += `昵称 (Nickname): ${userInfo.nickname}
|
|
1421
|
+
`;
|
|
1422
|
+
if (userInfo.card) output += `群昵称 (GroupCard): ${userInfo.card}
|
|
1423
|
+
`;
|
|
1424
|
+
if (userInfo.sex) output += `性别 (Gender): ${userInfo.sex === "male" ? "男 (Male)" : userInfo.sex === "female" ? "女 (Female)" : "未知 (Unknown)"}
|
|
1425
|
+
`;
|
|
1426
|
+
if (userInfo.age) output += `年龄 (Age): ${userInfo.age}
|
|
1427
|
+
`;
|
|
1428
|
+
if (userInfo.level) output += `等级 (Level): ${userInfo.level}
|
|
1429
|
+
`;
|
|
1430
|
+
if (userInfo.sign) output += `个性签名 (Signature): ${userInfo.sign}
|
|
1431
|
+
`;
|
|
1432
|
+
if (userInfo.role) output += `群角色 (GroupRole): ${userInfo.role === "owner" ? "群主 (Owner)" : userInfo.role === "admin" ? "管理员 (Admin)" : "成员 (Member)"}
|
|
1433
|
+
`;
|
|
1434
|
+
if (userInfo.join_time) output += `入群时间 (JoinTime): ${new Date(userInfo.join_time).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}
|
|
1435
|
+
`;
|
|
1436
|
+
if (userInfo.RegisterTime) output += `注册时间 (RegTime): ${new Date(userInfo.RegisterTime).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}
|
|
1437
|
+
`;
|
|
1438
|
+
output += `
|
|
1439
|
+
--- 会话信息 (ContextInfo) ---
|
|
1440
|
+
`;
|
|
1441
|
+
output += `是否群聊 (IsGroupChat): ${contextInfo.isGroup ? "是 (Yes)" : "否 (No)"}
|
|
1442
|
+
`;
|
|
1443
|
+
if (contextInfo.isGroup && contextInfo.groupId) output += `群号 (GroupID): ${contextInfo.groupId}
|
|
1444
|
+
`;
|
|
1445
|
+
return output;
|
|
1446
|
+
}
|
|
1447
|
+
__name(formatUserInfoDirectText, "formatUserInfoDirectText");
|
|
1448
|
+
function formatUserInfoForwardText(botSelf, userInfo, contextInfo) {
|
|
1449
|
+
let messages = "";
|
|
1450
|
+
const addMessageBlock = /* @__PURE__ */ __name((authorId, authorName, value) => {
|
|
1451
|
+
messages += `
|
|
1452
|
+
<message>
|
|
1453
|
+
<author ${authorId ? `id="${authorId}"` : ``} ${authorName ? `name="${authorName}"` : ``}/>
|
|
1454
|
+
${value}
|
|
1455
|
+
</message>`;
|
|
1456
|
+
}, "addMessageBlock");
|
|
1457
|
+
addMessageBlock(void 0, "当前时间 (CurrentTime):", `${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}`);
|
|
1458
|
+
addMessageBlock(void 0, "信息类型 (InfoType):", "用户信息 (User Info)");
|
|
1459
|
+
addMessageBlock(userInfo.user_id, void 0, `QQ号 (UserID): ${userInfo.user_id}`);
|
|
1460
|
+
if (userInfo.nickname) addMessageBlock(userInfo.user_id, void 0, `昵称 (Nickname): ${userInfo.nickname}`);
|
|
1461
|
+
if (userInfo.card) addMessageBlock(userInfo.user_id, void 0, `群昵称 (GroupCard): ${userInfo.card}`);
|
|
1462
|
+
if (userInfo.sex) addMessageBlock(userInfo.user_id, void 0, `性别 (Gender): ${userInfo.sex === "male" ? "男 (Male)" : userInfo.sex === "female" ? "女 (Female)" : "未知 (Unknown)"}`);
|
|
1463
|
+
if (userInfo.age !== void 0 && userInfo.age !== null) addMessageBlock(userInfo.user_id, void 0, `年龄 (Age): ${userInfo.age}`);
|
|
1464
|
+
if (userInfo.level) addMessageBlock(userInfo.user_id, void 0, `等级 (Level): ${userInfo.level}`);
|
|
1465
|
+
if (userInfo.sign) addMessageBlock(userInfo.user_id, void 0, `个性签名 (Signature): ${userInfo.sign}`);
|
|
1466
|
+
if (userInfo.role) addMessageBlock(userInfo.user_id, void 0, `群角色 (GroupRole): ${userInfo.role === "owner" ? "群主 (Owner)" : userInfo.role === "admin" ? "管理员 (Admin)" : "成员 (Member)"}`);
|
|
1467
|
+
if (userInfo.join_time) addMessageBlock(userInfo.user_id, void 0, `入群时间 (JoinTime): ${new Date(userInfo.join_time).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}`);
|
|
1468
|
+
if (userInfo.RegisterTime) addMessageBlock(userInfo.user_id, void 0, `注册时间 (RegTime): ${new Date(userInfo.RegisterTime).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}`);
|
|
1469
|
+
addMessageBlock(botSelf.userId, "信息类型 (Info Type):", "会话信息 (Context Info)");
|
|
1470
|
+
addMessageBlock(botSelf.userId, "是否群聊 (Is Group Chat):", `${contextInfo.isGroup ? "是 (Yes)" : "否 (No)"}`);
|
|
1471
|
+
if (contextInfo.isGroup && contextInfo.groupId) addMessageBlock(botSelf.userId, "群号 (Group ID):", `${contextInfo.groupId}`);
|
|
1472
|
+
return `<message forward>
|
|
1473
|
+
${messages}
|
|
1474
|
+
</message>`;
|
|
1475
|
+
}
|
|
1476
|
+
__name(formatUserInfoForwardText, "formatUserInfoForwardText");
|
|
1477
|
+
function formatAdminListDirectText(adminListArg, contextInfo) {
|
|
1478
|
+
let output = "";
|
|
1479
|
+
output += `当前时间 (Current Time): ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}
|
|
1480
|
+
`;
|
|
1481
|
+
output += `===== 群管理员列表 (Group Admin List) =====
|
|
1482
|
+
`;
|
|
1483
|
+
output += `群名称 (Group Name): ${contextInfo.groupName || "未知群聊"}
|
|
1484
|
+
`;
|
|
1485
|
+
output += `群号 (Group ID): ${contextInfo.groupId}
|
|
1486
|
+
`;
|
|
1487
|
+
output += `成员数 (Member Count): ${contextInfo.memberCount}/${contextInfo.maxMemberCount}
|
|
1488
|
+
`;
|
|
1489
|
+
output += `管理员数量 (Admin Count): ${adminListArg.length}
|
|
1490
|
+
|
|
1491
|
+
`;
|
|
1492
|
+
adminListArg.forEach((admin, index) => {
|
|
1493
|
+
output += `-----No. ${index + 1}. ${admin.role === "owner" ? "群主" : "管理员"} (${admin.role === "owner" ? "Owner" : "Admin"})-----
|
|
1494
|
+
`;
|
|
1495
|
+
output += ` QQ号 (User ID): ${admin.user_id}
|
|
1496
|
+
`;
|
|
1497
|
+
output += ` 昵称 (Nickname): ${admin.nickname || "未知"}
|
|
1498
|
+
`;
|
|
1499
|
+
if (admin.card) output += ` 群名片 (Group Card): ${admin.card}
|
|
1500
|
+
`;
|
|
1501
|
+
if (admin.level) output += ` 等级 (Level): ${admin.level}
|
|
1502
|
+
`;
|
|
1503
|
+
if (admin.join_time) output += ` 入群时间 (Join Time): ${new Date(admin.join_time * 1e3).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}
|
|
1504
|
+
`;
|
|
1505
|
+
if (admin.title) output += ` 头衔 (Title): ${admin.title}
|
|
1506
|
+
`;
|
|
1507
|
+
output += "\n";
|
|
1508
|
+
});
|
|
1509
|
+
return output;
|
|
1510
|
+
}
|
|
1511
|
+
__name(formatAdminListDirectText, "formatAdminListDirectText");
|
|
1512
|
+
function formatAdminListForwardText(adminListArg, contextInfo) {
|
|
1513
|
+
let messages = "";
|
|
1514
|
+
const addMessageBlock = /* @__PURE__ */ __name((authorId, authorName, adminUsrInfoStr) => {
|
|
1515
|
+
messages += `
|
|
1516
|
+
<message>
|
|
1517
|
+
<author ${authorId ? `id="${authorId}"` : ``} name="${authorName}"/>
|
|
1518
|
+
${adminUsrInfoStr}
|
|
1519
|
+
</message>`;
|
|
1520
|
+
}, "addMessageBlock");
|
|
1521
|
+
addMessageBlock(
|
|
1522
|
+
void 0,
|
|
1523
|
+
"群聊基本信息",
|
|
1524
|
+
[
|
|
1525
|
+
`当前时间: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}`,
|
|
1526
|
+
`=========群聊信息=========`,
|
|
1527
|
+
`群名称: ${contextInfo.groupName || "未知群聊"}`,
|
|
1528
|
+
`群号: ${contextInfo.groupId}`,
|
|
1529
|
+
`成员数: ${contextInfo.memberCount}/${contextInfo.maxMemberCount}`,
|
|
1530
|
+
`管理员数量: ${adminListArg.length}`
|
|
1531
|
+
].join("\n")
|
|
1532
|
+
);
|
|
1533
|
+
for (let i = 0; i < adminListArg.length; i++) {
|
|
1534
|
+
const admin = adminListArg[i];
|
|
1535
|
+
const authorName = admin.card || admin.nickname || `QQ: ${admin.user_id}`;
|
|
1536
|
+
const adminDetails = [
|
|
1537
|
+
`---------No. ${i + 1}---------`,
|
|
1538
|
+
`QQ号: ${admin.user_id}`,
|
|
1539
|
+
`昵称: ${admin.nickname}`,
|
|
1540
|
+
`角色: ${admin.role === "owner" ? "群主" : "管理员"}`,
|
|
1541
|
+
admin.card ? `群昵称: ${admin.card}` : "",
|
|
1542
|
+
admin.level ? `等级: ${admin.level}` : "",
|
|
1543
|
+
admin.title ? `群头衔: ${admin.title}` : "",
|
|
1544
|
+
admin.join_time ? `加入本群时间: ${new Date(admin.join_time * 1e3).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}` : "",
|
|
1545
|
+
admin.last_sent_time ? `最后发言时间: ${new Date(admin.last_sent_time * 1e3).toLocaleString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" })}` : ""
|
|
1546
|
+
].filter(Boolean).join("\n");
|
|
1547
|
+
addMessageBlock(
|
|
1548
|
+
admin.user_id.toString(),
|
|
1549
|
+
authorName,
|
|
1550
|
+
adminDetails
|
|
1551
|
+
);
|
|
1552
|
+
}
|
|
1553
|
+
return `<message forward>
|
|
1554
|
+
${messages}
|
|
1555
|
+
</message>`;
|
|
1556
|
+
}
|
|
1557
|
+
__name(formatAdminListForwardText, "formatAdminListForwardText");
|
|
1558
|
+
}
|
|
1559
|
+
__name(apply, "apply");
|
|
1560
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1561
|
+
0 && (module.exports = {
|
|
1562
|
+
Config,
|
|
1563
|
+
apply,
|
|
1564
|
+
inject,
|
|
1565
|
+
name,
|
|
1566
|
+
usage
|
|
1567
|
+
});
|