koishi-plugin-group-analysis-mx 1.2.0 → 1.2.2

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.
@@ -824,6 +824,43 @@ class AnalysisService extends koishi_1.Service {
824
824
  }
825
825
  });
826
826
  }
827
+ // 昵称 → 原始昵称 / 头像 映射(金句、称号用),并对 emoji/空白做归一化以增强匹配。
828
+ // LLM 返回的 sender/name 常丢失 emoji,这里用真实昵称(含 emoji)替换显示。
829
+ const nicknameAvatarMap = new Map();
830
+ const nicknameMap = new Map();
831
+ for (const user of sortedUsers) {
832
+ if (user.nickname) {
833
+ const normalized = (0, utils_1.normalizeNickname)(user.nickname);
834
+ if (!nicknameMap.has(user.nickname))
835
+ nicknameMap.set(user.nickname, user.nickname);
836
+ if (normalized && !nicknameMap.has(normalized))
837
+ nicknameMap.set(normalized, user.nickname);
838
+ if (user.avatar) {
839
+ nicknameAvatarMap.set(user.nickname, user.avatar);
840
+ if (normalized && !nicknameAvatarMap.has(normalized))
841
+ nicknameAvatarMap.set(normalized, user.avatar);
842
+ }
843
+ }
844
+ }
845
+ // 金句:用真实昵称替换 LLM 生成的昵称(保留 emoji),并补全发送者头像
846
+ if (Array.isArray(goldenQuotes)) {
847
+ goldenQuotes.forEach((quote) => {
848
+ if (quote && quote.sender) {
849
+ const normalized = (0, utils_1.normalizeNickname)(quote.sender);
850
+ const realName = nicknameMap.get(quote.sender) ||
851
+ (normalized ? nicknameMap.get(normalized) : '') ||
852
+ '';
853
+ if (realName)
854
+ quote.sender = realName;
855
+ if (!quote.avatar) {
856
+ quote.avatar =
857
+ nicknameAvatarMap.get(quote.sender) ||
858
+ nicknameAvatarMap.get(normalized) ||
859
+ '';
860
+ }
861
+ }
862
+ });
863
+ }
827
864
  const overallActiveHours = users.reduce((acc, user) => {
828
865
  for (const hour in user.activeHours) {
829
866
  acc[hour] = (acc[hour] || 0) + user.activeHours[hour];
@@ -82,7 +82,8 @@ class MessageService extends koishi_1.Service {
82
82
  guildId: session.guildId || '0',
83
83
  userId: session.userId,
84
84
  avatarUrl: session.event.user?.avatar || '',
85
- username: session.username,
85
+ // 用户昵称可能存在事件缺失(如官方 QQ bot 作者未返回 username),做多级兜底
86
+ username: session.username || session.event?.user?.name || session.userId || '未知用户',
86
87
  content: session.content,
87
88
  timestamp: new Date(session.timestamp),
88
89
  messageId: session.messageId
@@ -40,7 +40,7 @@ class AnimeSkinRenderer {
40
40
  <div class="bubble">
41
41
  <div class="bubble-text">"${quote.content}"</div>
42
42
  <div class="bubble-meta">
43
- — ${quote.sender}
43
+ ${quote.avatar ? `<img src="${quote.avatar}" alt="avatar" style="width:24px;height:24px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:4px;">` : ''}— ${quote.sender}
44
44
  </div>
45
45
  </div>
46
46
  `)
package/lib/skins/art.js CHANGED
@@ -40,7 +40,7 @@ class ArtSkinRenderer {
40
40
  <div class="quote-card">
41
41
  <div class="quote-content">${quote.content}</div>
42
42
  <div class="quote-footer">
43
- <div class="quote-sender">— ${quote.sender}</div>
43
+ <div class="quote-sender">${quote.avatar ? `<img src="${quote.avatar}" alt="avatar" style="width:28px;height:28px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:6px;">` : ''}— ${quote.sender}</div>
44
44
  <div class="quote-reason">${quote.reason}</div>
45
45
  </div>
46
46
  </div>
package/lib/skins/md3.js CHANGED
@@ -40,7 +40,7 @@ class Md3SkinRenderer {
40
40
  <div class="quote-card">
41
41
  <div class="quote-content">"${quote.content}"</div>
42
42
  <div class="quote-footer">
43
- <span class="quote-sender">— ${quote.sender}</span>
43
+ <span class="quote-sender">${quote.avatar ? `<img src="${quote.avatar}" alt="avatar" style="width:28px;height:28px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:6px;">` : ''}— ${quote.sender}</span>
44
44
  <p class="quote-reason"><strong>逆天理由:</strong> ${quote.reason}</p>
45
45
  </div>
46
46
  </div>
@@ -42,7 +42,7 @@ class NewspaperSkinRenderer {
42
42
  <div class="news-snippet">
43
43
  <div class="snippet-content">“${quote.content}”</div>
44
44
  <div class="snippet-source">
45
- —— ${quote.sender} <span class="snippet-comment">(${quote.reason})</span>
45
+ ${quote.avatar ? `<img src="${quote.avatar}" alt="avatar" style="width:24px;height:24px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:4px;">` : ''}—— ${quote.sender} <span class="snippet-comment">(${quote.reason})</span>
46
46
  </div>
47
47
  </div>
48
48
  `)
@@ -27,6 +27,7 @@ class ScrapbookSkinRenderer {
27
27
  <div class="quote-wrapper">
28
28
  <div class="q-flex-container">
29
29
  <div class="q-user-col">
30
+ ${quote.avatar ? `<div class="q-avatar-box"><img src="${quote.avatar}" class="q-avatar" alt="头像"></div>` : ''}
30
31
  </div>
31
32
 
32
33
  <div class="q-content-col">
package/lib/utils.js CHANGED
@@ -5,6 +5,7 @@ exports.buildPersonaRecordId = buildPersonaRecordId;
5
5
  exports.generateTextReport = generateTextReport;
6
6
  exports.getAvatarUrl = getAvatarUrl;
7
7
  exports.resolveUserAvatar = resolveUserAvatar;
8
+ exports.normalizeNickname = normalizeNickname;
8
9
  exports.formatUserStats = formatUserStats;
9
10
  exports.formatGoldenQuotes = formatGoldenQuotes;
10
11
  exports.formatUserTitles = formatUserTitles;
@@ -159,6 +160,18 @@ function generateTextReport(result) {
159
160
  function getAvatarUrl(userId) {
160
161
  return `http://q1.qlogo.cn/g?b=qq&nk=${userId}&s=640`;
161
162
  }
163
+ /**
164
+ * 归一化昵称:去除 emoji、修饰符和空白,用于昵称匹配。
165
+ * 用户昵称常含 emoji,LLM 返回的发送者/称号名可能不带 emoji,归一化后可正确匹配头像。
166
+ */
167
+ function normalizeNickname(name) {
168
+ if (!name)
169
+ return '';
170
+ return String(name)
171
+ .replace(/[\u{1F1E6}-\u{1F1FF}\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}\u{FE0F}\u{200D}\u{2B00}-\u{2BFF}\u{1F000}-\u{1F02F}\u{2190}-\u{21FF}\u{2B00}-\u{2BFF}]/gu, '')
172
+ .replace(/\s+/g, '')
173
+ .trim();
174
+ }
162
175
  /**
163
176
  * 按平台解析用户头像 URL。
164
177
  * - onebot: 使用 QQ 号头像接口(q1.qlogo.cn)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-group-analysis-mx",
3
3
  "description": "群聊分析插件 - 生成精美群聊统计报告,支持 AI 话题总结(独立版,不依赖 ChatLuna)",
4
- "version": "1.2.0",
4
+ "version": "1.2.2",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
7
7
  "typings": "lib/index.d.ts",