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.
Files changed (2) hide show
  1. package/lib/index.js +35 -35
  2. 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: #3b82f6;
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: 10px;
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: 12px 16px; }
316
- .header-table { border-collapse: collapse; table-layout: auto; width: 100%; }
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: 5px 10px; border-radius: 8px;
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; table-layout: auto; width: 100%; }
328
+ .main-table { border-collapse: collapse; width: 100%; }
329
329
  .main-table th, .main-table td {
330
- padding: 10px 16px;
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; left: 0; height: 100%; background-color: var(--accent-color); opacity: 0.1; }
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 `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
391
+ return date.toLocaleDateString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit" }).replace(/\//g, "-");
396
392
  }
397
393
  const timeUnits = [
398
- { unit: "月", ms: 30 * import_koishi2.Time.day },
399
- { unit: "天", ms: import_koishi2.Time.day },
400
- { unit: "时", ms: import_koishi2.Time.hour },
401
- { unit: "分", ms: import_koishi2.Time.minute }
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 { unit, ms } of timeUnits) {
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 result ? `${result}前` : "刚刚";
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 [user:user] 指定用户").option("guild", "-g [guildId:string] 指定群组").option("all", "-a 展示全局统计").action(async ({ session, options }) => {
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 [user:user] 指定用户").option("guild", "-g [guildId:string] 指定群组").option("type", "-t <type:string> 指定类型").option("all", "-a 展示全局统计").action(async ({ session, options }) => {
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 [guildId:string] 指定群组").option("all", "-a 展示全局统计").option("hours", "-h <hours:number> 指定时长", { fallback: 24 }).action(async ({ session, options }) => {
561
- let guildId = options.all ? void 0 : typeof options.guild === "string" ? options.guild : session.guildId;
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 (typeof options.user === "string") userId = import_koishi3.h.select(options.user, "user")[0]?.attrs.id;
593
- else if (options.user) userId = session.userId;
594
- if (typeof options.guild === "string") guildId = options.guild;
595
- else if (options.guild) {
596
- if (!session.guildId) return { error: "请指定群组 ID" };
597
- guildId = session.guildId;
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 (!guildId && !userId) return session.guildId ? { guildId: session.guildId } : { error: "请提供查询范围" };
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}的${options.timeRange}小时消息排行`;
647
- if (options.main === "消息" && options.subtype) return `${scopeText}"${options.subtype}"消息统计`;
648
- return `${scopeText}的${options.main}统计`;
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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-analyse",
3
3
  "description": "聊天记录分析",
4
- "version": "0.3.5",
4
+ "version": "0.3.6",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],