koishi-plugin-group-analysis-mx 1.0.1

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 (94) hide show
  1. package/lib/config.d.ts +53 -0
  2. package/lib/config.d.ts.map +1 -0
  3. package/lib/config.js +376 -0
  4. package/lib/config.js.map +1 -0
  5. package/lib/cron.d.ts +8 -0
  6. package/lib/cron.d.ts.map +1 -0
  7. package/lib/cron.js +62 -0
  8. package/lib/cron.js.map +1 -0
  9. package/lib/index.d.ts +6 -0
  10. package/lib/index.d.ts.map +1 -0
  11. package/lib/index.js +51 -0
  12. package/lib/index.js.map +1 -0
  13. package/lib/onebot/cqcode.d.ts +14 -0
  14. package/lib/onebot/cqcode.d.ts.map +1 -0
  15. package/lib/onebot/cqcode.js +92 -0
  16. package/lib/onebot/cqcode.js.map +1 -0
  17. package/lib/plugin.d.ts +4 -0
  18. package/lib/plugin.d.ts.map +1 -0
  19. package/lib/plugin.js +41 -0
  20. package/lib/plugin.js.map +1 -0
  21. package/lib/plugins/command.d.ts +9 -0
  22. package/lib/plugins/command.d.ts.map +1 -0
  23. package/lib/plugins/command.js +196 -0
  24. package/lib/plugins/command.js.map +1 -0
  25. package/lib/service/analysis.d.ts +48 -0
  26. package/lib/service/analysis.d.ts.map +1 -0
  27. package/lib/service/analysis.js +714 -0
  28. package/lib/service/analysis.js.map +1 -0
  29. package/lib/service/llm.d.ts +43 -0
  30. package/lib/service/llm.d.ts.map +1 -0
  31. package/lib/service/llm.js +160 -0
  32. package/lib/service/llm.js.map +1 -0
  33. package/lib/service/message.d.ts +55 -0
  34. package/lib/service/message.d.ts.map +1 -0
  35. package/lib/service/message.js +527 -0
  36. package/lib/service/message.js.map +1 -0
  37. package/lib/service/renderer.d.ts +23 -0
  38. package/lib/service/renderer.d.ts.map +1 -0
  39. package/lib/service/renderer.js +298 -0
  40. package/lib/service/renderer.js.map +1 -0
  41. package/lib/skins/anime.d.ts +19 -0
  42. package/lib/skins/anime.d.ts.map +1 -0
  43. package/lib/skins/anime.js +138 -0
  44. package/lib/skins/anime.js.map +1 -0
  45. package/lib/skins/art.d.ts +19 -0
  46. package/lib/skins/art.d.ts.map +1 -0
  47. package/lib/skins/art.js +146 -0
  48. package/lib/skins/art.js.map +1 -0
  49. package/lib/skins/index.d.ts +50 -0
  50. package/lib/skins/index.d.ts.map +1 -0
  51. package/lib/skins/index.js +84 -0
  52. package/lib/skins/index.js.map +1 -0
  53. package/lib/skins/md3.d.ts +19 -0
  54. package/lib/skins/md3.d.ts.map +1 -0
  55. package/lib/skins/md3.js +147 -0
  56. package/lib/skins/md3.js.map +1 -0
  57. package/lib/skins/newspaper.d.ts +19 -0
  58. package/lib/skins/newspaper.d.ts.map +1 -0
  59. package/lib/skins/newspaper.js +141 -0
  60. package/lib/skins/newspaper.js.map +1 -0
  61. package/lib/skins/scrapbook.d.ts +20 -0
  62. package/lib/skins/scrapbook.d.ts.map +1 -0
  63. package/lib/skins/scrapbook.js +207 -0
  64. package/lib/skins/scrapbook.js.map +1 -0
  65. package/lib/skins/types.d.ts +69 -0
  66. package/lib/skins/types.d.ts.map +1 -0
  67. package/lib/skins/types.js +12 -0
  68. package/lib/skins/types.js.map +1 -0
  69. package/lib/types.d.ts +170 -0
  70. package/lib/types.d.ts.map +1 -0
  71. package/lib/types.js +3 -0
  72. package/lib/types.js.map +1 -0
  73. package/lib/utils.d.ts +55 -0
  74. package/lib/utils.d.ts.map +1 -0
  75. package/lib/utils.js +334 -0
  76. package/lib/utils.js.map +1 -0
  77. package/package.json +48 -0
  78. package/resources/anime/css/template_group.css +470 -0
  79. package/resources/anime/images/decoration_br.svg +19 -0
  80. package/resources/anime/images/decoration_tl.svg +24 -0
  81. package/resources/anime/template_group.html +108 -0
  82. package/resources/anime/template_user.html +99 -0
  83. package/resources/art/css/template_group.css +484 -0
  84. package/resources/art/template_group.html +77 -0
  85. package/resources/art/template_user.html +63 -0
  86. package/resources/md3/css/template_group.css +880 -0
  87. package/resources/md3/template_group.html +189 -0
  88. package/resources/md3/template_user.html +175 -0
  89. package/resources/newspaper/css/template_group.css +568 -0
  90. package/resources/newspaper/template_group.html +133 -0
  91. package/resources/newspaper/template_user.html +119 -0
  92. package/resources/scrapbook/css/style.css +1094 -0
  93. package/resources/scrapbook/template_group.html +115 -0
  94. package/resources/scrapbook/template_user.html +119 -0
@@ -0,0 +1,99 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>用户画像报告</title>
7
+ <link rel="stylesheet" href="./css/template_group.css" />
8
+ </head>
9
+ <body class="${theme}-theme">
10
+
11
+ <div class="nahida-container">
12
+ <!-- Decorations -->
13
+ <img src="./images/decoration_tl.svg" class="deco-tl" alt="" />
14
+ <img src="./images/decoration_br.svg" class="deco-br" alt="" />
15
+
16
+ <!-- Header -->
17
+ <div class="header-area">
18
+ <div class="header-title">
19
+ <h1>用户画像</h1>
20
+ <div class="subtitle">User Persona Report</div>
21
+ </div>
22
+ <div class="header-meta">
23
+ <div class="date">${analysisDate}</div>
24
+ <div class="group-id">ID: ${username}</div>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="main-content">
29
+
30
+ <!-- Profile Hero -->
31
+ <div class="profile-hero">
32
+ <img src="${avatar}" alt="User Avatar" class="profile-avatar-lg" />
33
+ <div class="profile-name">${username}</div>
34
+ <div class="tag-container" style="margin-top: 10px;">
35
+ <span class="tag">生成于 ${analysisDate}</span>
36
+ </div>
37
+ </div>
38
+
39
+ <!-- Summary -->
40
+ <div class="section-header">
41
+ <div class="section-icon">A</div>
42
+ <h2 class="section-title">个性摘要</h2>
43
+ </div>
44
+ <div class="bubble">
45
+ <div class="bubble-text">${summary}</div>
46
+ </div>
47
+
48
+ <!-- Traits -->
49
+ <div class="section-header">
50
+ <div class="section-icon">B</div>
51
+ <h2 class="section-title">核心特质</h2>
52
+ </div>
53
+ <div class="tag-container">
54
+ ${keyTraits}
55
+ </div>
56
+
57
+ <!-- Interests -->
58
+ <div class="section-header">
59
+ <div class="section-icon">C</div>
60
+ <h2 class="section-title">兴趣领域</h2>
61
+ </div>
62
+ <div class="tag-container">
63
+ ${interests}
64
+ </div>
65
+
66
+ <!-- Communication -->
67
+ <div class="section-header">
68
+ <div class="section-icon">D</div>
69
+ <h2 class="section-title">沟通风格</h2>
70
+ </div>
71
+ <div class="bubble">
72
+ <div class="bubble-text">${communicationStyle}</div>
73
+ </div>
74
+
75
+ <!-- Evidence -->
76
+ <div class="section-header">
77
+ <div class="section-icon">E</div>
78
+ <h2 class="section-title">事实依据</h2>
79
+ </div>
80
+ <div class="evidence-list-container">
81
+ ${evidence}
82
+ </div>
83
+
84
+ <div class="footer">
85
+ Generated by Koishi Group Analysis | Nahida Theme Ver. 3.0
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <script>
91
+ const body = document.body;
92
+ if (!body.className.includes('theme') || body.className.includes('auto')) {
93
+ const hour = new Date().getHours();
94
+ body.classList.remove('auto-theme');
95
+ body.classList.add(hour >= 19 || hour < 6 ? 'dark-theme' : 'light-theme');
96
+ }
97
+ </script>
98
+ </body>
99
+ </html>
@@ -0,0 +1,484 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Lato:wght@300;400;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap');
2
+
3
+ :root {
4
+ /* Light Theme - Darkened for better visibility */
5
+ --art-bg: #fdfbf7;
6
+ --art-text: #000000;
7
+ --art-border: #000000;
8
+ --art-accent: #000000;
9
+ --art-secondary: #333333;
10
+ --art-surface: #ffffff;
11
+ --art-surface-alt: #f4f1ea;
12
+ }
13
+
14
+ body.dark-theme {
15
+ /* Dark Theme - Lightened for better visibility */
16
+ --art-bg: #000000;
17
+ --art-text: #ffffff;
18
+ --art-border: #ffffff;
19
+ --art-accent: #ffffff;
20
+ --art-secondary: #cccccc;
21
+ --art-surface: #121212;
22
+ --art-surface-alt: #1e1e1e;
23
+ }
24
+
25
+ * {
26
+ margin: 0;
27
+ padding: 0;
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ body {
32
+ font-family: 'Lato', 'Noto Sans SC', sans-serif;
33
+ background-color: var(--art-bg);
34
+ color: var(--art-text);
35
+ line-height: 1.6;
36
+ display: flex;
37
+ justify-content: center;
38
+ min-height: 100vh;
39
+ transition: background-color 0.3s, color 0.3s;
40
+ font-weight: 500; /* Base weight increased */
41
+ }
42
+
43
+ .container {
44
+ width: 900px;
45
+ padding: 40px;
46
+ background-color: var(--art-surface);
47
+ border-left: 2px solid var(--art-border); /* Thicker border */
48
+ border-right: 2px solid var(--art-border); /* Thicker border */
49
+ min-height: 100vh;
50
+ position: relative;
51
+ }
52
+
53
+ /* Decorative corner lines */
54
+ .container::before {
55
+ content: '';
56
+ position: absolute;
57
+ top: 20px;
58
+ left: 20px;
59
+ width: 20px;
60
+ height: 20px;
61
+ border-top: 2px solid var(--art-border); /* Thicker */
62
+ border-left: 2px solid var(--art-border); /* Thicker */
63
+ }
64
+
65
+ .container::after {
66
+ content: '';
67
+ position: absolute;
68
+ top: 20px;
69
+ right: 20px;
70
+ width: 20px;
71
+ height: 20px;
72
+ border-top: 2px solid var(--art-border); /* Thicker */
73
+ border-right: 2px solid var(--art-border); /* Thicker */
74
+ }
75
+
76
+ .header {
77
+ text-align: center;
78
+ padding: 60px 0 40px;
79
+ border-bottom: 2px solid var(--art-border); /* Thicker */
80
+ margin-bottom: 40px;
81
+ position: relative;
82
+ }
83
+
84
+ .header h1 {
85
+ font-family: 'Cinzel', serif;
86
+ font-size: 46px; /* Increased size */
87
+ font-weight: 700; /* Bold */
88
+ letter-spacing: 2px;
89
+ margin-bottom: 12px;
90
+ text-transform: uppercase;
91
+ }
92
+
93
+ .header .sub-title {
94
+ font-family: 'Cinzel', serif;
95
+ font-size: 18px; /* Increased size */
96
+ font-weight: 600; /* Increased weight */
97
+ color: var(--art-secondary);
98
+ letter-spacing: 1px;
99
+ }
100
+
101
+ .summary {
102
+ display: grid;
103
+ grid-template-columns: repeat(4, 1fr);
104
+ gap: 20px;
105
+ margin-bottom: 60px;
106
+ border: 2px solid var(--art-border); /* Thicker */
107
+ padding: 20px;
108
+ }
109
+
110
+ .summary-item {
111
+ text-align: center;
112
+ padding: 10px;
113
+ }
114
+
115
+ .summary-item:not(:last-child) {
116
+ border-right: 2px solid var(--art-border); /* Thicker */
117
+ }
118
+
119
+ .summary-item .label {
120
+ font-family: 'Cinzel', serif;
121
+ font-size: 16px; /* Increased size */
122
+ font-weight: 700; /* Bold */
123
+ color: var(--art-secondary);
124
+ margin-bottom: 8px;
125
+ text-transform: uppercase;
126
+ }
127
+
128
+ .summary-item .value {
129
+ font-family: 'Lato', sans-serif;
130
+ font-size: 28px; /* Increased size */
131
+ font-weight: 600; /* Increased weight */
132
+ }
133
+
134
+ .section-title {
135
+ font-family: 'Cinzel', serif;
136
+ font-size: 32px; /* Increased size */
137
+ font-weight: 700; /* Bold */
138
+ margin: 40px 0 20px;
139
+ padding-bottom: 10px;
140
+ border-bottom: 2px solid var(--art-border); /* Thicker */
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: space-between;
144
+ }
145
+
146
+ .section-title::after {
147
+ content: '§';
148
+ font-size: 24px; /* Increased size */
149
+ font-weight: bold;
150
+ color: var(--art-secondary);
151
+ }
152
+
153
+ .card-grid {
154
+ display: grid;
155
+ gap: 20px;
156
+ margin-bottom: 40px;
157
+ }
158
+
159
+ .card-grid.two-columns {
160
+ grid-template-columns: 1fr 1fr;
161
+ }
162
+
163
+ /* Cards */
164
+ .user-stat-card, .title-card, .topic-card, .quote-card {
165
+ border: 2px solid var(--art-border); /* Thicker */
166
+ padding: 20px;
167
+ background: transparent;
168
+ transition: transform 0.2s;
169
+ }
170
+
171
+ .user-stat-card:hover, .title-card:hover, .topic-card:hover, .quote-card:hover {
172
+ transform: translateY(-2px);
173
+ background-color: var(--art-surface-alt);
174
+ }
175
+
176
+ .user-stat-card {
177
+ display: flex;
178
+ align-items: center;
179
+ }
180
+
181
+ .avatar {
182
+ width: 64px; /* Increased size */
183
+ height: 64px;
184
+ border: 2px solid var(--art-border); /* Thicker */
185
+ border-radius: 0;
186
+ margin-right: 20px;
187
+ object-fit: cover;
188
+ padding: 2px;
189
+ }
190
+
191
+ .user-details, .title-details {
192
+ flex-grow: 1;
193
+ }
194
+
195
+ .nickname {
196
+ font-family: 'Cinzel', serif;
197
+ font-size: 20px; /* Increased size */
198
+ font-weight: 800; /* Extra Bold */
199
+ margin-bottom: 8px;
200
+ }
201
+
202
+ .stats-grid {
203
+ display: grid;
204
+ grid-template-columns: 1fr 1fr;
205
+ gap: 4px 16px;
206
+ font-size: 15px; /* Increased size */
207
+ font-weight: 500; /* Increased weight */
208
+ color: var(--art-secondary);
209
+ }
210
+
211
+ .stats-grid strong {
212
+ color: var(--art-text);
213
+ font-weight: 700; /* Bold */
214
+ }
215
+
216
+ /* Titles */
217
+ .title-card {
218
+ display: flex;
219
+ align-items: flex-start;
220
+ }
221
+
222
+ .title-badge {
223
+ display: inline-block;
224
+ border: 2px solid var(--art-border); /* Thicker */
225
+ padding: 4px 10px; /* Increased padding */
226
+ font-size: 15px; /* Increased size */
227
+ font-weight: 700; /* Bold */
228
+ font-family: 'Cinzel', serif;
229
+ margin-bottom: 8px;
230
+ background-color: var(--art-surface-alt);
231
+ }
232
+
233
+ .title-reason {
234
+ font-size: 15px; /* Increased size */
235
+ font-weight: 500; /* Increased weight */
236
+ color: var(--art-secondary);
237
+ font-style: italic;
238
+ }
239
+
240
+ /* Topics */
241
+ .topic-card .topic-title {
242
+ font-family: 'Cinzel', serif;
243
+ font-size: 22px; /* Increased size */
244
+ font-weight: 700; /* Bold */
245
+ margin-bottom: 8px;
246
+ border-bottom: 2px solid var(--art-border); /* Thicker */
247
+ padding-bottom: 4px;
248
+ display: inline-block;
249
+ }
250
+
251
+ .topic-contributors {
252
+ font-size: 13px; /* Increased size */
253
+ font-weight: 600; /* Increased weight */
254
+ color: var(--art-secondary);
255
+ text-transform: uppercase;
256
+ margin-bottom: 12px;
257
+ letter-spacing: 1px;
258
+ }
259
+
260
+ .topic-detail {
261
+ font-size: 17px; /* Increased size */
262
+ line-height: 1.8;
263
+ font-weight: 500; /* Increased weight */
264
+ }
265
+
266
+ /* Quotes */
267
+ .quote-card {
268
+ text-align: center;
269
+ position: relative;
270
+ }
271
+
272
+ .quote-content {
273
+ font-family: 'Cinzel', serif;
274
+ font-size: 28px; /* Increased size */
275
+ font-weight: 600; /* Increased weight */
276
+ margin-bottom: 16px;
277
+ line-height: 1.4;
278
+ }
279
+
280
+ .quote-content::before {
281
+ content: '“';
282
+ font-size: 48px; /* Increased size */
283
+ line-height: 0;
284
+ vertical-align: -10px;
285
+ margin-right: 10px;
286
+ color: var(--art-secondary);
287
+ font-weight: bold;
288
+ }
289
+
290
+ .quote-content::after {
291
+ content: '”';
292
+ font-size: 48px; /* Increased size */
293
+ line-height: 0;
294
+ vertical-align: -10px;
295
+ margin-left: 10px;
296
+ color: var(--art-secondary);
297
+ font-weight: bold;
298
+ }
299
+
300
+ .quote-footer {
301
+ margin-top: 20px;
302
+ padding-top: 16px;
303
+ border-top: 2px solid var(--art-border); /* Thicker */
304
+ display: flex;
305
+ flex-direction: column;
306
+ gap: 12px;
307
+ }
308
+
309
+ .quote-sender {
310
+ font-weight: 800; /* Extra Bold */
311
+ font-size: 18px; /* Increased size */
312
+ align-self: flex-end;
313
+ text-align: right;
314
+ font-family: 'Cinzel', serif;
315
+ }
316
+
317
+ .quote-reason {
318
+ font-size: 16px; /* Increased size */
319
+ font-weight: 500; /* Increased weight */
320
+ color: var(--art-secondary);
321
+ text-align: left;
322
+ padding-left: 16px;
323
+ border-left: 2px solid var(--art-secondary); /* Thicker */
324
+ font-style: italic;
325
+ }
326
+
327
+ /* Activity Chart */
328
+ .activity-chart-container {
329
+ border: 2px solid var(--art-border); /* Thicker */
330
+ padding: 20px;
331
+ }
332
+
333
+ .activity-chart {
334
+ display: flex;
335
+ align-items: flex-end;
336
+ gap: 4px;
337
+ height: 200px;
338
+ padding-bottom: 20px;
339
+ border-bottom: 2px solid var(--art-border); /* Thicker */
340
+ }
341
+
342
+ .activity-bar {
343
+ flex: 1;
344
+ display: flex;
345
+ flex-direction: column;
346
+ align-items: center;
347
+ justify-content: flex-end;
348
+ height: 100%;
349
+ }
350
+
351
+ .activity-bar-bar {
352
+ width: 100%;
353
+ background-color: var(--art-text);
354
+ transition: height 0.5s ease;
355
+ }
356
+
357
+ .activity-bar-count {
358
+ font-size: 13px; /* Increased size */
359
+ font-weight: 700; /* Bold */
360
+ margin-bottom: 4px;
361
+ color: var(--art-text);
362
+ opacity: 0;
363
+ transition: opacity 0.2s;
364
+ }
365
+
366
+ .activity-bar:hover .activity-bar-count {
367
+ opacity: 1;
368
+ }
369
+
370
+ .activity-bar-label {
371
+ font-size: 11px; /* Increased size */
372
+ font-weight: 700; /* Bold */
373
+ margin-top: 8px;
374
+ color: var(--art-secondary);
375
+ }
376
+
377
+ .chart-legend {
378
+ text-align: right;
379
+ margin-top: 10px;
380
+ font-size: 13px; /* Increased size */
381
+ font-weight: 600; /* Increased weight */
382
+ color: var(--art-secondary);
383
+ font-style: italic;
384
+ }
385
+
386
+ /* Empty State */
387
+ .empty-state {
388
+ padding: 40px;
389
+ text-align: center;
390
+ border: 2px dashed var(--art-border); /* Thicker */
391
+ color: var(--art-secondary);
392
+ font-family: 'Cinzel', serif;
393
+ font-size: 18px; /* Increased size */
394
+ font-weight: 600;
395
+ }
396
+
397
+ /* Footer */
398
+ footer {
399
+ text-align: center;
400
+ margin-top: 60px;
401
+ padding-top: 20px;
402
+ border-top: 4px double var(--art-border); /* Thicker */
403
+ font-size: 14px; /* Increased size */
404
+ font-weight: 700; /* Bold */
405
+ color: var(--art-secondary);
406
+ text-transform: uppercase;
407
+ letter-spacing: 2px;
408
+ }
409
+
410
+ /* User Persona Styles */
411
+ .user-header {
412
+ text-align: center;
413
+ }
414
+
415
+ .avatar-large {
416
+ width: 120px; /* Increased size */
417
+ height: 120px;
418
+ border: 2px solid var(--art-border); /* Thicker */
419
+ padding: 4px;
420
+ margin-bottom: 20px;
421
+ border-radius: 0;
422
+ }
423
+
424
+ .persona-summary {
425
+ font-size: 20px; /* Increased size */
426
+ line-height: 1.8;
427
+ font-weight: 500; /* Increased weight */
428
+ border-left: 3px solid var(--art-text); /* Thicker */
429
+ padding-left: 20px;
430
+ margin-bottom: 40px;
431
+ font-style: italic;
432
+ }
433
+
434
+ .tag-container {
435
+ display: flex;
436
+ flex-wrap: wrap;
437
+ gap: 12px;
438
+ margin-bottom: 40px;
439
+ }
440
+
441
+ .tag, .chip {
442
+ border: 2px solid var(--art-border); /* Thicker */
443
+ background: transparent;
444
+ color: var(--art-text);
445
+ padding: 8px 18px; /* Increased padding */
446
+ font-size: 15px; /* Increased size */
447
+ font-weight: 700; /* Bold */
448
+ font-family: 'Cinzel', serif;
449
+ border-radius: 0;
450
+ }
451
+
452
+ .persona-block {
453
+ font-size: 17px; /* Increased size */
454
+ line-height: 1.8;
455
+ font-weight: 500; /* Increased weight */
456
+ margin-bottom: 40px;
457
+ }
458
+
459
+ .persona-block ul {
460
+ list-style-type: none;
461
+ padding-left: 0;
462
+ }
463
+
464
+ .persona-block li {
465
+ margin-bottom: 10px;
466
+ padding-left: 20px;
467
+ position: relative;
468
+ }
469
+
470
+ .persona-block li::before {
471
+ content: '—';
472
+ position: absolute;
473
+ left: 0;
474
+ color: var(--art-secondary);
475
+ font-weight: bold;
476
+ }
477
+
478
+ .card.outlined-card {
479
+ border: 2px solid var(--art-border); /* Thicker */
480
+ padding: 16px;
481
+ margin-bottom: 16px;
482
+ background: var(--art-surface-alt);
483
+ border-radius: 0;
484
+ }
@@ -0,0 +1,77 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>群聊分析报告</title>
7
+ <link rel="stylesheet" href="./css/template_group.css" />
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="header">
12
+ <h1>群聊分析报告</h1>
13
+ <div class="sub-title">${groupName} | ${analysisDate}</div>
14
+ </div>
15
+
16
+ <div class="summary">
17
+ <div class="summary-item">
18
+ <div class="label">总消息数</div>
19
+ <div class="value">${totalMessages}</div>
20
+ </div>
21
+ <div class="summary-item">
22
+ <div class="label">参与人数</div>
23
+ <div class="value">${totalParticipants}</div>
24
+ </div>
25
+ <div class="summary-item">
26
+ <div class="label">总字数</div>
27
+ <div class="value">${totalChars}</div>
28
+ </div>
29
+ <div class="summary-item">
30
+ <div class="label">最活跃时段</div>
31
+ <div class="value">${mostActivePeriod}</div>
32
+ </div>
33
+ </div>
34
+
35
+ <div class="section-title">龙王榜</div>
36
+ <div class="card-grid two-columns">${userStats}</div>
37
+
38
+ <div class="section-title">群友称号</div>
39
+ <div class="card-grid two-columns">${userTitles}</div>
40
+
41
+ <div class="section-title">热门话题</div>
42
+ <div class="card-grid">${topics}</div>
43
+
44
+ <div class="section-title">本群圣经</div>
45
+ <div class="card-grid">${goldenQuotes}</div>
46
+
47
+ <div class="section-title">24小时活跃分布</div>
48
+ ${activeHoursChart}
49
+
50
+ <footer>由 Koishi 强力驱动</footer>
51
+ </div>
52
+
53
+ <script>
54
+ // Simple theme handler
55
+ const themeSetting = '${theme}'
56
+ const body = document.body
57
+
58
+ function applyTheme(theme) {
59
+ if (theme === 'dark') {
60
+ body.classList.add('dark-theme')
61
+ body.classList.remove('light-theme')
62
+ } else {
63
+ body.classList.add('light-theme')
64
+ body.classList.remove('dark-theme')
65
+ }
66
+ }
67
+
68
+ if (themeSetting === 'auto') {
69
+ const hour = new Date().getHours()
70
+ const isDark = hour >= 19 || hour < 6
71
+ applyTheme(isDark ? 'dark' : 'light')
72
+ } else {
73
+ applyTheme(themeSetting)
74
+ }
75
+ </script>
76
+ </body>
77
+ </html>