koishi-plugin-chat-analyse 0.3.5 → 0.3.6
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.js +35 -35
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -298,13 +298,13 @@ var Renderer = class {
|
|
|
298
298
|
<style>
|
|
299
299
|
:root {
|
|
300
300
|
--card-bg: #ffffff; --text-color: #111827; --header-color: #111827;
|
|
301
|
-
--sub-text-color: #6b7280; --border-color: #e5e7eb; --accent-color: #
|
|
301
|
+
--sub-text-color: #6b7280; --border-color: #e5e7eb; --accent-color: #4a6ee0;
|
|
302
302
|
--chip-bg: #f3f4f6; --stripe-bg: #f9fafb; --gold: #f59e0b; --silver: #9ca3af; --bronze: #a16207;
|
|
303
303
|
}
|
|
304
304
|
body {
|
|
305
305
|
display: inline-block; /* Crucial for shrink-wrapping */
|
|
306
306
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
307
|
-
background: transparent; margin: 0; padding:
|
|
307
|
+
background: transparent; margin: 0; padding: 8px;
|
|
308
308
|
-webkit-font-smoothing: antialiased;
|
|
309
309
|
}
|
|
310
310
|
.container {
|
|
@@ -312,22 +312,22 @@ var Renderer = class {
|
|
|
312
312
|
border-radius: 12px; padding: 0; overflow: hidden;
|
|
313
313
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
|
314
314
|
}
|
|
315
|
-
.header { padding:
|
|
316
|
-
.header-table { border-collapse: collapse;
|
|
315
|
+
.header { padding: 10px 14px; }
|
|
316
|
+
.header-table { border-collapse: collapse; width: 100%; }
|
|
317
317
|
.header-table-left, .header-table-right { width: 1%; white-space: nowrap; }
|
|
318
318
|
.header-table-left { text-align: left; }
|
|
319
319
|
.header-table-center { text-align: center; }
|
|
320
320
|
.header-table-right { text-align: right; }
|
|
321
321
|
.title-text { font-size: 18px; font-weight: 600; color: var(--header-color); margin: 0; }
|
|
322
322
|
.stat-chip, .time-label {
|
|
323
|
-
display: inline-flex; align-items: baseline; padding:
|
|
323
|
+
display: inline-flex; align-items: baseline; padding: 4px 8px; border-radius: 8px;
|
|
324
324
|
background: var(--chip-bg); font-size: 13px; color: var(--sub-text-color);
|
|
325
325
|
}
|
|
326
326
|
.stat-chip span { font-weight: 600; color: var(--text-color); margin-left: 4px; }
|
|
327
327
|
.table-container { border-top: 1px solid var(--border-color); }
|
|
328
|
-
.main-table { border-collapse: collapse;
|
|
328
|
+
.main-table { border-collapse: collapse; width: 100%; }
|
|
329
329
|
.main-table th, .main-table td {
|
|
330
|
-
padding:
|
|
330
|
+
padding: 8px 14px;
|
|
331
331
|
vertical-align: middle;
|
|
332
332
|
}
|
|
333
333
|
.main-table th {
|
|
@@ -336,10 +336,7 @@ var Renderer = class {
|
|
|
336
336
|
}
|
|
337
337
|
.main-table td { font-size: 14px; color: var(--text-color); }
|
|
338
338
|
.main-table tbody tr:nth-child(even) { background-color: var(--stripe-bg); }
|
|
339
|
-
.main-table .name-cell, .main-table .name-header {
|
|
340
|
-
text-align: left;
|
|
341
|
-
white-space: normal;
|
|
342
|
-
}
|
|
339
|
+
.main-table .name-cell, .main-table .name-header { text-align: left; }
|
|
343
340
|
.main-table .rank-cell, .main-table .count-cell, .main-table .date-cell, .main-table .percent-cell, .main-table .header-right-align {
|
|
344
341
|
text-align: right;
|
|
345
342
|
white-space: nowrap;
|
|
@@ -355,7 +352,7 @@ var Renderer = class {
|
|
|
355
352
|
.rank-silver { color: var(--silver) !important; }
|
|
356
353
|
.rank-bronze { color: var(--bronze) !important; }
|
|
357
354
|
.percent-cell { position: relative; }
|
|
358
|
-
.percent-bar { position: absolute; top: 0;
|
|
355
|
+
.percent-bar { position: absolute; top: 0; right: 0; height: 100%; background-color: var(--accent-color); opacity: 0.15; }
|
|
359
356
|
.percent-text { position: relative; z-index: 1; }
|
|
360
357
|
</style>
|
|
361
358
|
</head>
|
|
@@ -373,7 +370,6 @@ var Renderer = class {
|
|
|
373
370
|
return await page.screenshot({ type: "png", fullPage: true, omitBackground: true });
|
|
374
371
|
} catch (error) {
|
|
375
372
|
this.ctx.logger.error("图片渲染出错:", error);
|
|
376
|
-
throw new Error(`图片渲染出错: ${error.message || "未知错误"}`);
|
|
377
373
|
} finally {
|
|
378
374
|
if (page) await page.close().catch(() => {
|
|
379
375
|
});
|
|
@@ -392,17 +388,17 @@ var Renderer = class {
|
|
|
392
388
|
const diff = Date.now() - date.getTime();
|
|
393
389
|
if (diff < import_koishi2.Time.minute) return "刚刚";
|
|
394
390
|
if (diff > 365 * import_koishi2.Time.day) {
|
|
395
|
-
return
|
|
391
|
+
return date.toLocaleDateString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit" }).replace(/\//g, "-");
|
|
396
392
|
}
|
|
397
393
|
const timeUnits = [
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
394
|
+
["月", 30 * import_koishi2.Time.day],
|
|
395
|
+
["天", import_koishi2.Time.day],
|
|
396
|
+
["时", import_koishi2.Time.hour],
|
|
397
|
+
["分", import_koishi2.Time.minute]
|
|
402
398
|
];
|
|
403
399
|
let remainingDiff = diff;
|
|
404
400
|
const parts = [];
|
|
405
|
-
for (const
|
|
401
|
+
for (const [unit, ms] of timeUnits) {
|
|
406
402
|
if (remainingDiff >= ms) {
|
|
407
403
|
const value = Math.floor(remainingDiff / ms);
|
|
408
404
|
parts.push(`${value}${unit}`);
|
|
@@ -410,7 +406,7 @@ var Renderer = class {
|
|
|
410
406
|
}
|
|
411
407
|
}
|
|
412
408
|
const result = parts.slice(0, 2).join("");
|
|
413
|
-
return
|
|
409
|
+
return `${result}前`;
|
|
414
410
|
}
|
|
415
411
|
/**
|
|
416
412
|
* @public
|
|
@@ -514,7 +510,7 @@ var Stat = class {
|
|
|
514
510
|
*/
|
|
515
511
|
registerCommands(analyse) {
|
|
516
512
|
if (this.config.enableCmdStat) {
|
|
517
|
-
analyse.subcommand(".cmd", "命令使用统计").option("user", "-u
|
|
513
|
+
analyse.subcommand(".cmd", "命令使用统计").option("user", "-u <user:string> 指定用户").option("guild", "-g <guildId:string> 指定群组").option("all", "-a 展示全局统计").action(async ({ session, options }) => {
|
|
518
514
|
const scope = this.parseQueryScope(session, options);
|
|
519
515
|
if (scope.error) return scope.error;
|
|
520
516
|
try {
|
|
@@ -531,7 +527,7 @@ var Stat = class {
|
|
|
531
527
|
});
|
|
532
528
|
}
|
|
533
529
|
if (this.config.enableMsgStat) {
|
|
534
|
-
analyse.subcommand(".msg", "消息发送统计").option("user", "-u
|
|
530
|
+
analyse.subcommand(".msg", "消息发送统计").option("user", "-u <user:string> 指定用户").option("guild", "-g <guildId:string> 指定群组").option("type", "-t <type:string> 指定类型").option("all", "-a 展示全局统计").action(async ({ session, options }) => {
|
|
535
531
|
const scope = this.parseQueryScope(session, options);
|
|
536
532
|
if (scope.error) return scope.error;
|
|
537
533
|
try {
|
|
@@ -557,9 +553,8 @@ var Stat = class {
|
|
|
557
553
|
});
|
|
558
554
|
}
|
|
559
555
|
if (this.config.enableRankStat) {
|
|
560
|
-
analyse.subcommand(".rank", "用户发言排行").option("guild", "-g
|
|
561
|
-
|
|
562
|
-
if (!session.guildId) return "请指定群组 ID";
|
|
556
|
+
analyse.subcommand(".rank", "用户发言排行").option("guild", "-g <guildId:string> 指定群组").option("all", "-a 展示全局统计").option("hours", "-h <hours:number> 指定时长", { fallback: 24 }).action(async ({ session, options }) => {
|
|
557
|
+
const guildId = options.all ? void 0 : options.guild || session.guildId;
|
|
563
558
|
if (!guildId && !options.all) return "请提供查询范围";
|
|
564
559
|
try {
|
|
565
560
|
const stats = await this.getActiveUserStats(options.hours, guildId);
|
|
@@ -589,15 +584,20 @@ var Stat = class {
|
|
|
589
584
|
*/
|
|
590
585
|
parseQueryScope(session, options) {
|
|
591
586
|
let userId, guildId;
|
|
592
|
-
if (
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
587
|
+
if (options.user) {
|
|
588
|
+
const atElements = import_koishi3.h.select(options.user, "at");
|
|
589
|
+
if (atElements.length > 0) {
|
|
590
|
+
userId = atElements[0].attrs.id;
|
|
591
|
+
} else {
|
|
592
|
+
userId = options.user.trim();
|
|
593
|
+
}
|
|
598
594
|
}
|
|
595
|
+
if (options.guild) guildId = options.guild;
|
|
599
596
|
if (options.all) return { userId, guildId: void 0 };
|
|
600
|
-
if (!
|
|
597
|
+
if (!userId && !guildId) {
|
|
598
|
+
if (session.guildId) return { guildId: session.guildId };
|
|
599
|
+
return { error: "请提供查询范围" };
|
|
600
|
+
}
|
|
601
601
|
return { userId, guildId };
|
|
602
602
|
}
|
|
603
603
|
/**
|
|
@@ -643,9 +643,9 @@ var Stat = class {
|
|
|
643
643
|
const guild = await this.ctx.database.get("analyse_user", { channelId: guildId }, ["channelName"]);
|
|
644
644
|
scopeText = guild[0]?.channelName || guildId;
|
|
645
645
|
}
|
|
646
|
-
if (options.main === "排行") return `${scopeText}
|
|
647
|
-
if (options.main === "消息" && options.subtype) return `${scopeText}
|
|
648
|
-
return `${scopeText}
|
|
646
|
+
if (options.main === "排行") return `${scopeText}${options.timeRange}小时消息排行`;
|
|
647
|
+
if (options.main === "消息" && options.subtype) return `${scopeText}"${options.subtype}"消息统计`;
|
|
648
|
+
return `${scopeText}${options.main}统计`;
|
|
649
649
|
}
|
|
650
650
|
/**
|
|
651
651
|
* @private
|