@cja123/ai-content-generator 1.0.0

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/index.html +1019 -0
  2. package/package.json +22 -0
package/index.html ADDED
@@ -0,0 +1,1019 @@
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>AI内容生成工具</title>
7
+ <style>
8
+ :root {
9
+ --primary-color: #007AFF;
10
+ --background-color: #F5F5F7;
11
+ --card-background: #FFFFFF;
12
+ --text-primary: #1D1D1F;
13
+ --text-secondary: #86868B;
14
+ --border-color: #E5E5EA;
15
+ --hover-color: #F2F2F7;
16
+ --error-color: #FF3B30;
17
+ --success-color: #34C759;
18
+ }
19
+
20
+ * {
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
+ }
25
+
26
+ body {
27
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
28
+ background-color: var(--background-color);
29
+ color: var(--text-primary);
30
+ line-height: 1.5;
31
+ }
32
+
33
+ .app-container {
34
+ display: flex;
35
+ height: 100vh;
36
+ }
37
+
38
+ /* 左侧边栏 */
39
+ .sidebar {
40
+ width: 280px;
41
+ background-color: var(--card-background);
42
+ border-right: 1px solid var(--border-color);
43
+ display: flex;
44
+ flex-direction: column;
45
+ padding: 20px;
46
+ }
47
+
48
+ .sidebar-header {
49
+ margin-bottom: 20px;
50
+ }
51
+
52
+ .logo {
53
+ font-size: 18px;
54
+ font-weight: 600;
55
+ color: var(--primary-color);
56
+ margin-bottom: 20px;
57
+ }
58
+
59
+ .new-chat-btn {
60
+ width: 100%;
61
+ padding: 12px;
62
+ background-color: var(--primary-color);
63
+ color: white;
64
+ border: none;
65
+ border-radius: 10px;
66
+ font-size: 14px;
67
+ font-weight: 500;
68
+ cursor: pointer;
69
+ transition: background-color 0.3s ease;
70
+ }
71
+
72
+ .new-chat-btn:hover {
73
+ background-color: #0056b3;
74
+ }
75
+
76
+ .chat-history {
77
+ flex: 1;
78
+ overflow-y: auto;
79
+ margin-bottom: 20px;
80
+ }
81
+
82
+ .chat-history-item {
83
+ padding: 12px 16px;
84
+ border-radius: 10px;
85
+ cursor: pointer;
86
+ margin-bottom: 8px;
87
+ transition: background-color 0.3s ease;
88
+ border: 1px solid transparent;
89
+ }
90
+
91
+ .chat-history-item:hover {
92
+ background-color: var(--hover-color);
93
+ }
94
+
95
+ .chat-history-item.active {
96
+ background-color: rgba(0, 122, 255, 0.1);
97
+ border-color: var(--primary-color);
98
+ }
99
+
100
+ .chat-title {
101
+ font-size: 14px;
102
+ font-weight: 500;
103
+ margin-bottom: 4px;
104
+ white-space: nowrap;
105
+ overflow: hidden;
106
+ text-overflow: ellipsis;
107
+ }
108
+
109
+ .chat-time {
110
+ font-size: 12px;
111
+ color: var(--text-secondary);
112
+ }
113
+
114
+ .sidebar-footer {
115
+ border-top: 1px solid var(--border-color);
116
+ padding-top: 16px;
117
+ }
118
+
119
+ .sidebar-footer-item {
120
+ display: flex;
121
+ align-items: center;
122
+ padding: 8px 12px;
123
+ border-radius: 8px;
124
+ cursor: pointer;
125
+ margin-bottom: 8px;
126
+ transition: background-color 0.3s ease;
127
+ }
128
+
129
+ .sidebar-footer-item:hover {
130
+ background-color: var(--hover-color);
131
+ }
132
+
133
+ .sidebar-footer-item i {
134
+ margin-right: 12px;
135
+ color: var(--text-secondary);
136
+ }
137
+
138
+ /* 主聊天区 */
139
+ .chat-main {
140
+ flex: 1;
141
+ display: flex;
142
+ flex-direction: column;
143
+ position: relative;
144
+ }
145
+
146
+ .chat-header {
147
+ padding: 20px 30px;
148
+ border-bottom: 1px solid var(--border-color);
149
+ background-color: var(--card-background);
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ }
154
+
155
+ .chat-title-main {
156
+ font-size: 16px;
157
+ font-weight: 600;
158
+ }
159
+
160
+ .chat-actions {
161
+ display: flex;
162
+ gap: 12px;
163
+ }
164
+
165
+ .action-btn {
166
+ background: none;
167
+ border: none;
168
+ color: var(--text-secondary);
169
+ cursor: pointer;
170
+ padding: 8px;
171
+ border-radius: 8px;
172
+ transition: background-color 0.3s ease;
173
+ }
174
+
175
+ .action-btn:hover {
176
+ background-color: var(--hover-color);
177
+ }
178
+
179
+ /* 消息区域 */
180
+ .chat-messages {
181
+ flex: 1;
182
+ overflow-y: auto;
183
+ padding: 30px;
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: 20px;
187
+ }
188
+
189
+ .message {
190
+ max-width: 80%;
191
+ margin-bottom: 20px;
192
+ }
193
+
194
+ .user-message {
195
+ align-self: flex-end;
196
+ }
197
+
198
+ .ai-message {
199
+ align-self: flex-start;
200
+ }
201
+
202
+ .message-content {
203
+ padding: 16px 20px;
204
+ border-radius: 18px;
205
+ line-height: 1.6;
206
+ }
207
+
208
+ .user-message .message-content {
209
+ background-color: var(--primary-color);
210
+ color: white;
211
+ border-bottom-right-radius: 4px;
212
+ }
213
+
214
+ .ai-message .message-content {
215
+ background-color: var(--card-background);
216
+ color: var(--text-primary);
217
+ border-bottom-left-radius: 4px;
218
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
219
+ }
220
+
221
+ .message-header {
222
+ display: flex;
223
+ align-items: center;
224
+ margin-bottom: 8px;
225
+ }
226
+
227
+ .ai-avatar {
228
+ width: 32px;
229
+ height: 32px;
230
+ border-radius: 50%;
231
+ background-color: var(--primary-color);
232
+ color: white;
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: center;
236
+ font-weight: 600;
237
+ margin-right: 12px;
238
+ font-size: 14px;
239
+ }
240
+
241
+ .ai-name {
242
+ font-size: 14px;
243
+ font-weight: 600;
244
+ color: var(--text-primary);
245
+ }
246
+
247
+ .message-time {
248
+ font-size: 12px;
249
+ color: var(--text-secondary);
250
+ margin-left: 12px;
251
+ }
252
+
253
+ /* 输入区域 */
254
+ .chat-input-area {
255
+ padding: 20px 30px;
256
+ border-top: 1px solid var(--border-color);
257
+ background-color: var(--card-background);
258
+ }
259
+
260
+ .input-container {
261
+ position: relative;
262
+ max-width: 800px;
263
+ margin: 0 auto;
264
+ }
265
+
266
+ .input-toolbar {
267
+ display: flex;
268
+ gap: 12px;
269
+ margin-bottom: 12px;
270
+ flex-wrap: wrap;
271
+ }
272
+
273
+ .toolbar-btn {
274
+ background: none;
275
+ border: 1px solid var(--border-color);
276
+ color: var(--text-secondary);
277
+ padding: 6px 12px;
278
+ border-radius: 16px;
279
+ font-size: 12px;
280
+ cursor: pointer;
281
+ transition: all 0.3s ease;
282
+ }
283
+
284
+ .toolbar-btn:hover {
285
+ background-color: var(--hover-color);
286
+ border-color: var(--primary-color);
287
+ color: var(--primary-color);
288
+ }
289
+
290
+ .input-wrapper {
291
+ position: relative;
292
+ }
293
+
294
+ .chat-input {
295
+ width: 100%;
296
+ min-height: 120px;
297
+ padding: 16px 50px 16px 16px;
298
+ border: 1px solid var(--border-color);
299
+ border-radius: 12px;
300
+ resize: vertical;
301
+ font-family: inherit;
302
+ font-size: 14px;
303
+ line-height: 1.5;
304
+ transition: border-color 0.3s ease;
305
+ }
306
+
307
+ .chat-input:focus {
308
+ outline: none;
309
+ border-color: var(--primary-color);
310
+ }
311
+
312
+ .send-btn {
313
+ position: absolute;
314
+ bottom: 12px;
315
+ right: 12px;
316
+ width: 36px;
317
+ height: 36px;
318
+ border-radius: 50%;
319
+ background-color: var(--primary-color);
320
+ color: white;
321
+ border: none;
322
+ cursor: pointer;
323
+ display: flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ transition: background-color 0.3s ease;
327
+ }
328
+
329
+ .send-btn:hover {
330
+ background-color: #0056b3;
331
+ }
332
+
333
+ .send-btn:disabled {
334
+ background-color: var(--text-secondary);
335
+ cursor: not-allowed;
336
+ }
337
+
338
+ /* 加载状态 */
339
+ .loading {
340
+ display: flex;
341
+ align-items: center;
342
+ padding: 20px;
343
+ color: var(--text-secondary);
344
+ }
345
+
346
+ .loading-spinner {
347
+ width: 20px;
348
+ height: 20px;
349
+ border: 2px solid var(--border-color);
350
+ border-top: 2px solid var(--primary-color);
351
+ border-radius: 50%;
352
+ animation: spin 1s linear infinite;
353
+ margin-right: 12px;
354
+ }
355
+
356
+ .loading-dots {
357
+ display: flex;
358
+ align-items: center;
359
+ gap: 4px;
360
+ }
361
+
362
+ .loading-dot {
363
+ width: 6px;
364
+ height: 6px;
365
+ background-color: var(--primary-color);
366
+ border-radius: 50%;
367
+ animation: pulse 1.5s infinite ease-in-out;
368
+ }
369
+
370
+ .loading-dot:nth-child(2) {
371
+ animation-delay: 0.2s;
372
+ }
373
+
374
+ .loading-dot:nth-child(3) {
375
+ animation-delay: 0.4s;
376
+ }
377
+
378
+ @keyframes spin {
379
+ 0% { transform: rotate(0deg); }
380
+ 100% { transform: rotate(360deg); }
381
+ }
382
+
383
+ @keyframes pulse {
384
+ 0%, 100% { opacity: 1; }
385
+ 50% { opacity: 0.5; }
386
+ }
387
+
388
+ /* 空状态 */
389
+ .empty-state {
390
+ flex: 1;
391
+ display: flex;
392
+ flex-direction: column;
393
+ align-items: center;
394
+ justify-content: center;
395
+ padding: 60px 20px;
396
+ text-align: center;
397
+ }
398
+
399
+ .empty-state h2 {
400
+ font-size: 24px;
401
+ font-weight: 600;
402
+ margin-bottom: 12px;
403
+ color: var(--text-primary);
404
+ }
405
+
406
+ .empty-state p {
407
+ font-size: 16px;
408
+ color: var(--text-secondary);
409
+ margin-bottom: 30px;
410
+ max-width: 400px;
411
+ }
412
+
413
+ .get-started-btn {
414
+ padding: 12px 24px;
415
+ background-color: var(--primary-color);
416
+ color: white;
417
+ border: none;
418
+ border-radius: 8px;
419
+ font-size: 14px;
420
+ font-weight: 500;
421
+ cursor: pointer;
422
+ transition: background-color 0.3s ease;
423
+ }
424
+
425
+ .get-started-btn:hover {
426
+ background-color: #0056b3;
427
+ }
428
+
429
+ /* 控制台 */
430
+ .console-container {
431
+ margin-top: 20px;
432
+ border-top: 1px solid var(--border-color);
433
+ overflow: hidden;
434
+ transition: max-height 0.3s ease;
435
+ max-height: 0;
436
+ }
437
+
438
+ .console-header {
439
+ background-color: #2d2d2d;
440
+ color: white;
441
+ padding: 10px 15px;
442
+ display: flex;
443
+ align-items: center;
444
+ justify-content: space-between;
445
+ cursor: pointer;
446
+ }
447
+
448
+ .console-header h3 {
449
+ font-size: 14px;
450
+ font-weight: 500;
451
+ }
452
+
453
+ .console-toggle {
454
+ background: none;
455
+ border: none;
456
+ color: white;
457
+ cursor: pointer;
458
+ font-size: 12px;
459
+ }
460
+
461
+ .console-content {
462
+ background-color: #1e1e1e;
463
+ color: #d4d4d4;
464
+ padding: 15px;
465
+ font-family: 'Courier New', Courier, monospace;
466
+ font-size: 12px;
467
+ line-height: 1.4;
468
+ max-height: 300px;
469
+ overflow-y: auto;
470
+ }
471
+
472
+ .console-container.expanded {
473
+ max-height: 400px;
474
+ }
475
+
476
+ /* 错误提示 */
477
+ .error-message {
478
+ background-color: rgba(255, 59, 48, 0.1);
479
+ color: var(--error-color);
480
+ padding: 16px;
481
+ border-radius: 8px;
482
+ margin-bottom: 20px;
483
+ border-left: 4px solid var(--error-color);
484
+ }
485
+
486
+ /* 响应式设计 */
487
+ @media (max-width: 768px) {
488
+ .sidebar {
489
+ width: 240px;
490
+ position: fixed;
491
+ left: -240px;
492
+ top: 0;
493
+ height: 100vh;
494
+ z-index: 1000;
495
+ transition: left 0.3s ease;
496
+ }
497
+
498
+ .sidebar.open {
499
+ left: 0;
500
+ }
501
+
502
+ .chat-main {
503
+ width: 100%;
504
+ }
505
+
506
+ .chat-messages {
507
+ padding: 20px;
508
+ }
509
+
510
+ .message {
511
+ max-width: 90%;
512
+ }
513
+ }
514
+
515
+ /* 代码块样式 */
516
+ .code-block {
517
+ background-color: #f6f8fa;
518
+ border-radius: 6px;
519
+ padding: 12px;
520
+ margin: 10px 0;
521
+ overflow-x: auto;
522
+ font-family: 'Courier New', Courier, monospace;
523
+ font-size: 13px;
524
+ line-height: 1.5;
525
+ }
526
+
527
+ /* 质量检测 */
528
+ .quality-metrics {
529
+ display: flex;
530
+ gap: 20px;
531
+ margin-top: 16px;
532
+ padding-top: 16px;
533
+ border-top: 1px solid var(--border-color);
534
+ flex-wrap: wrap;
535
+ }
536
+
537
+ .metric-item {
538
+ flex: 1;
539
+ min-width: 120px;
540
+ }
541
+
542
+ .metric-value {
543
+ font-size: 18px;
544
+ font-weight: 600;
545
+ color: var(--primary-color);
546
+ }
547
+
548
+ .metric-label {
549
+ font-size: 12px;
550
+ color: var(--text-secondary);
551
+ margin-top: 4px;
552
+ }
553
+ </style>
554
+ </head>
555
+ <body>
556
+ <div class="app-container">
557
+ <!-- 左侧边栏 -->
558
+ <div class="sidebar">
559
+ <div class="sidebar-header">
560
+ <div class="logo">AI内容生成工具</div>
561
+ <button class="new-chat-btn" onclick="newChat()">+ 新建对话</button>
562
+ </div>
563
+
564
+ <div class="chat-history" id="chat-history">
565
+ <!-- 历史对话将通过JavaScript动态生成 -->
566
+ </div>
567
+
568
+ <div class="sidebar-footer">
569
+ <div class="sidebar-footer-item" onclick="switchPanel('settings')">
570
+ <i>⚙️</i>
571
+ <span>设置</span>
572
+ </div>
573
+ <div class="sidebar-footer-item" onclick="switchPanel('about')">
574
+ <i>ℹ️</i>
575
+ <span>关于</span>
576
+ </div>
577
+ </div>
578
+ </div>
579
+
580
+ <!-- 主聊天区 -->
581
+ <div class="chat-main">
582
+ <!-- 聊天头部 -->
583
+ <div class="chat-header">
584
+ <div class="chat-title-main" id="current-chat-title">新对话</div>
585
+ <div class="chat-actions">
586
+ <button class="action-btn" title="清空对话">🗑</button>
587
+ <button class="action-btn" title="分享">📤</button>
588
+ <button class="action-btn" title="更多">⋮</button>
589
+ </div>
590
+ </div>
591
+
592
+ <!-- 消息区域 -->
593
+ <div class="chat-messages" id="chat-messages">
594
+ <!-- 空状态 -->
595
+ <div class="empty-state" id="empty-state">
596
+ <h2>你好!我是AI内容生成工具</h2>
597
+ <p>我可以帮你生成各种类型的内容,包括文案、作文、报告、邮件、演讲稿、代码和总结。</p>
598
+ <button class="get-started-btn" onclick="startChat()">开始使用</button>
599
+ </div>
600
+
601
+ <!-- 消息将通过JavaScript动态生成 -->
602
+ </div>
603
+
604
+ <!-- 输入区域 -->
605
+ <div class="chat-input-area">
606
+ <div class="input-container">
607
+ <div class="input-toolbar">
608
+ <button class="toolbar-btn" onclick="insertTemplate('copywriting')">文案</button>
609
+ <button class="toolbar-btn" onclick="insertTemplate('essay')">作文</button>
610
+ <button class="toolbar-btn" onclick="insertTemplate('report')">报告</button>
611
+ <button class="toolbar-btn" onclick="insertTemplate('email')">邮件</button>
612
+ <button class="toolbar-btn" onclick="insertTemplate('speech')">演讲稿</button>
613
+ <button class="toolbar-btn" onclick="insertTemplate('code')">代码</button>
614
+ <button class="toolbar-btn" onclick="insertTemplate('summary')">总结</button>
615
+ </div>
616
+
617
+ <div class="input-wrapper">
618
+ <textarea
619
+ class="chat-input"
620
+ id="chat-input"
621
+ placeholder="请输入你的需求..."
622
+ onkeydown="handleKeyDown(event)"
623
+ ></textarea>
624
+ <button class="send-btn" id="send-btn" onclick="sendMessage()">
625
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
626
+ <line x1="22" y1="2" x2="11" y2="13"></line>
627
+ <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
628
+ </svg>
629
+ </button>
630
+ </div>
631
+ </div>
632
+ </div>
633
+
634
+ <!-- 控制台 -->
635
+ <div class="console-container" id="console-container">
636
+ <div class="console-header" onclick="toggleConsole()">
637
+ <h3>AI 思考过程</h3>
638
+ <button class="console-toggle" id="console-toggle">👁 展开</button>
639
+ </div>
640
+ <div class="console-content" id="console-content">
641
+ <!-- 控制台日志将通过JavaScript动态生成 -->
642
+ </div>
643
+ </div>
644
+ </div>
645
+ </div>
646
+
647
+ <script>
648
+ // 全局配置
649
+ const CONFIG = {
650
+ model: "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B",
651
+ apiUrl: "http://localhost:3000/api/chat"
652
+ };
653
+
654
+ // 全局状态
655
+ let currentChatId = null;
656
+ let chats = JSON.parse(localStorage.getItem('ai-content-chats') || '[]');
657
+ let currentMessages = [];
658
+ let isGenerating = false;
659
+
660
+ // DOM 元素
661
+ const chatInput = document.getElementById('chat-input');
662
+ const sendBtn = document.getElementById('send-btn');
663
+ const chatMessages = document.getElementById('chat-messages');
664
+ const emptyState = document.getElementById('empty-state');
665
+ const chatHistory = document.getElementById('chat-history');
666
+ const currentChatTitle = document.getElementById('current-chat-title');
667
+ const consoleContainer = document.getElementById('console-container');
668
+ const consoleContent = document.getElementById('console-content');
669
+ const consoleToggle = document.getElementById('console-toggle');
670
+
671
+ // 初始化
672
+ function init() {
673
+ renderChatHistory();
674
+ if (chats.length > 0) {
675
+ loadChat(chats[0].id);
676
+ }
677
+ }
678
+
679
+ // 渲染聊天历史
680
+ function renderChatHistory() {
681
+ if (chats.length === 0) {
682
+ chatHistory.innerHTML = '<div style="text-align: center; color: #86868B; padding: 20px;">暂无历史对话</div>';
683
+ return;
684
+ }
685
+
686
+ chatHistory.innerHTML = chats.map(chat => `
687
+ <div class="chat-history-item ${chat.id === currentChatId ? 'active' : ''}" onclick="loadChat(${chat.id})">
688
+ <div class="chat-title">${chat.title}</div>
689
+ <div class="chat-time">${new Date(chat.timestamp).toLocaleString()}</div>
690
+ </div>
691
+ `).join('');
692
+ }
693
+
694
+ // 加载聊天
695
+ function loadChat(chatId) {
696
+ const chat = chats.find(c => c.id === chatId);
697
+ if (!chat) return;
698
+
699
+ currentChatId = chatId;
700
+ currentMessages = chat.messages || [];
701
+ currentChatTitle.textContent = chat.title;
702
+
703
+ renderMessages();
704
+ renderChatHistory();
705
+ emptyState.style.display = 'none';
706
+ }
707
+
708
+ // 新建对话
709
+ function newChat() {
710
+ const newChat = {
711
+ id: Date.now(),
712
+ title: '新对话',
713
+ messages: [],
714
+ timestamp: Date.now()
715
+ };
716
+
717
+ chats.unshift(newChat);
718
+ saveChats();
719
+ loadChat(newChat.id);
720
+ }
721
+
722
+ // 开始聊天
723
+ function startChat() {
724
+ emptyState.style.display = 'none';
725
+ newChat();
726
+ chatInput.focus();
727
+ }
728
+
729
+ // 保存聊天
730
+ function saveChats() {
731
+ localStorage.setItem('ai-content-chats', JSON.stringify(chats));
732
+ }
733
+
734
+ // 渲染消息
735
+ function renderMessages() {
736
+ if (currentMessages.length === 0) {
737
+ chatMessages.innerHTML = '';
738
+ emptyState.style.display = 'flex';
739
+ return;
740
+ }
741
+
742
+ emptyState.style.display = 'none';
743
+
744
+ chatMessages.innerHTML = currentMessages.map((message, index) => {
745
+ if (message.role === 'user') {
746
+ return `
747
+ <div class="message user-message">
748
+ <div class="message-content">${message.content}</div>
749
+ <div class="message-time">${new Date(message.timestamp).toLocaleTimeString()}</div>
750
+ </div>
751
+ `;
752
+ } else {
753
+ return `
754
+ <div class="message ai-message">
755
+ <div class="message-header">
756
+ <div class="ai-avatar">AI</div>
757
+ <div class="ai-name">AI助手</div>
758
+ <div class="message-time">${new Date(message.timestamp).toLocaleTimeString()}</div>
759
+ </div>
760
+ <div class="message-content">${formatMessageContent(message.content)}</div>
761
+ ${message.qualityMetrics ? `
762
+ <div class="quality-metrics">
763
+ <div class="metric-item">
764
+ <div class="metric-value">${message.qualityMetrics.wordCount}</div>
765
+ <div class="metric-label">字数</div>
766
+ </div>
767
+ <div class="metric-item">
768
+ <div class="metric-value">${message.qualityMetrics.repetition}</div>
769
+ <div class="metric-label">重复率</div>
770
+ </div>
771
+ <div class="metric-item">
772
+ <div class="metric-value">${message.qualityMetrics.readability}</div>
773
+ <div class="metric-label">可读性</div>
774
+ </div>
775
+ </div>
776
+ ` : ''}
777
+ </div>
778
+ `;
779
+ }
780
+ }).join('');
781
+
782
+ // 滚动到底部
783
+ chatMessages.scrollTop = chatMessages.scrollHeight;
784
+ }
785
+
786
+ // 格式化消息内容
787
+ function formatMessageContent(content) {
788
+ // 处理代码块
789
+ content = content.replace(/```([\s\S]*?)```/g, '<div class="code-block">$1</div>');
790
+ // 处理换行
791
+ content = content.replace(/\n/g, '<br>');
792
+ return content;
793
+ }
794
+
795
+ // 发送消息
796
+ async function sendMessage() {
797
+ const content = chatInput.value.trim();
798
+ if (!content || isGenerating) return;
799
+
800
+ // 清空输入框
801
+ chatInput.value = '';
802
+
803
+ // 添加用户消息
804
+ const userMessage = {
805
+ role: 'user',
806
+ content: content,
807
+ timestamp: Date.now()
808
+ };
809
+
810
+ currentMessages.push(userMessage);
811
+ renderMessages();
812
+
813
+ // 更新聊天标题
814
+ if (currentMessages.length === 1) {
815
+ const chat = chats.find(c => c.id === currentChatId);
816
+ if (chat) {
817
+ chat.title = content.substring(0, 30) + (content.length > 30 ? '...' : '');
818
+ currentChatTitle.textContent = chat.title;
819
+ saveChats();
820
+ renderChatHistory();
821
+ }
822
+ }
823
+
824
+ // 显示 AI 正在生成
825
+ const loadingMessage = {
826
+ role: 'assistant',
827
+ content: '',
828
+ timestamp: Date.now(),
829
+ isLoading: true
830
+ };
831
+
832
+ currentMessages.push(loadingMessage);
833
+ renderMessages();
834
+
835
+ try {
836
+ isGenerating = true;
837
+ sendBtn.disabled = true;
838
+
839
+ // 展开控制台
840
+ consoleContainer.classList.add('expanded');
841
+ consoleToggle.textContent = '👁 收起';
842
+
843
+ // 调用后端 API
844
+ const response = await fetch(CONFIG.apiUrl, {
845
+ method: 'POST',
846
+ headers: {
847
+ 'Content-Type': 'application/json'
848
+ },
849
+ body: JSON.stringify({
850
+ messages: [{ role: 'user', content: content }],
851
+ model: CONFIG.model
852
+ })
853
+ });
854
+
855
+ if (!response.ok) {
856
+ throw new Error(`API 请求失败: ${response.status}`);
857
+ }
858
+
859
+ // 移除加载消息
860
+ currentMessages.pop();
861
+
862
+ // 添加 AI 消息
863
+ const aiMessage = {
864
+ role: 'assistant',
865
+ content: '',
866
+ timestamp: Date.now()
867
+ };
868
+
869
+ currentMessages.push(aiMessage);
870
+ renderMessages();
871
+
872
+ // 处理流式响应
873
+ const reader = response.body.getReader();
874
+ const decoder = new TextDecoder();
875
+
876
+ while (true) {
877
+ const { done, value } = await reader.read();
878
+ if (done) break;
879
+
880
+ const chunk = decoder.decode(value);
881
+ const lines = chunk.split('\n').filter(line => line.trim());
882
+
883
+ for (const line of lines) {
884
+ if (line.startsWith('data: ')) {
885
+ const data = line.slice(6);
886
+ if (data === '[DONE]') continue;
887
+ try {
888
+ const json = JSON.parse(data);
889
+ const content = json.choices[0]?.delta?.content || '';
890
+ if (content) {
891
+ aiMessage.content += content;
892
+ renderMessages();
893
+ }
894
+ } catch (e) {
895
+ console.error('解析数据失败:', e);
896
+ }
897
+ }
898
+ }
899
+ }
900
+
901
+ // 计算质量指标
902
+ aiMessage.qualityMetrics = calculateQualityMetrics(aiMessage.content);
903
+
904
+ // 保存聊天
905
+ const chat = chats.find(c => c.id === currentChatId);
906
+ if (chat) {
907
+ chat.messages = currentMessages;
908
+ chat.timestamp = Date.now();
909
+ saveChats();
910
+ }
911
+
912
+ // 生成完成后折叠控制台
913
+ setTimeout(() => {
914
+ consoleContainer.classList.remove('expanded');
915
+ consoleToggle.textContent = '👁 展开';
916
+ }, 2000);
917
+
918
+ } catch (error) {
919
+ // 移除加载消息
920
+ currentMessages.pop();
921
+
922
+ // 添加错误消息
923
+ const errorMessage = {
924
+ role: 'assistant',
925
+ content: `生成失败:${error.message}`,
926
+ timestamp: Date.now()
927
+ };
928
+
929
+ currentMessages.push(errorMessage);
930
+ renderMessages();
931
+ } finally {
932
+ isGenerating = false;
933
+ sendBtn.disabled = false;
934
+ }
935
+ }
936
+
937
+ // 生成模拟内容
938
+ function generateMockContent(prompt) {
939
+ const responses = {
940
+ '春天': '春天来了,万物复苏,大地一片生机盎然。嫩绿的新芽从枝头冒出,花朵绽放出绚丽的色彩,小鸟在枝头欢快地歌唱。春风拂面,带来阵阵花香,让人感受到生命的活力和希望。春天是一个充满梦想和希望的季节,它象征着新的开始和无限的可能。',
941
+ '文案': '【春日限定】\n在这个充满生机的季节,我们为您精心准备了一系列春季新品,让您的生活充满春天的气息。从清新的服装到精致的家居用品,每一件都经过精心挑选,为您带来最美好的春日体验。现在购买还可享受限时优惠,让春天的美好与您相伴!',
942
+ '作文': '《春天的赞歌》\n春天,是大自然最美丽的馈赠。当第一缕春风拂过大地,沉睡的万物渐渐苏醒,开始了新的生命旅程。\n\n看,那嫩绿的小草从土壤中探出头来,好奇地打量着这个世界;那鲜艳的花朵在枝头绽放,向人们展示着它们的美丽;那欢快的小鸟在天空中飞翔,唱着动听的歌曲。\n\n春天不仅是季节的更替,更是希望的象征。在这个充满生机的季节里,我们也应该像大自然一样,焕发出新的活力,为自己的梦想而努力奋斗。\n\n让我们一起拥抱春天,感受生命的美好吧!',
943
+ '报告': '【市场调研报告】\n\n一、调研背景\n随着经济的发展和消费者需求的变化,我们对市场进行了全面的调研,以了解当前市场的现状和未来发展趋势。\n\n二、调研方法\n本次调研采用了问卷调查、深度访谈和数据分析等多种方法,确保调研结果的准确性和可靠性。\n\n三、调研结果\n1. 消费者需求分析\n2. 市场竞争格局\n3. 产品趋势预测\n\n四、结论与建议\n基于调研结果,我们提出以下建议:\n1. 优化产品结构\n2. 加强品牌建设\n3. 提升服务质量\n\n五、结语\n通过本次调研,我们对市场有了更全面的了解,为企业的发展提供了有力的支持。',
944
+ '邮件': '尊敬的[收件人],\n\n您好!\n\n我是[发件人姓名],[公司名称]的[职位]。我写这封邮件是想[说明目的]。\n\n[详细内容]\n\n如果您有任何疑问或需要进一步的信息,请随时联系我。\n\n期待您的回复!\n\n祝好,\n[发件人姓名]\n[联系方式]',
945
+ '演讲稿': '尊敬的各位领导、亲爱的同事们:\n\n大家好!\n\n今天,我非常荣幸能够站在这里,和大家分享[演讲主题]。\n\n[演讲内容]\n\n最后,我想对大家说:[结束语]。\n\n谢谢大家!',
946
+ '代码': '// JavaScript 示例代码\nfunction calculateSum(numbers) {\n return numbers.reduce((sum, num) => sum + num, 0);\n}\n\n// 使用示例\nconst numbers = [1, 2, 3, 4, 5];\nconst sum = calculateSum(numbers);\nconsole.log(`The sum is: ${sum}`);',
947
+ '总结': '本次会议主要讨论了以下内容:\n1. 项目进展情况\n2. 遇到的问题及解决方案\n3. 下一步工作计划\n\n通过本次会议,我们明确了工作目标,制定了详细的实施计划,为项目的顺利进行奠定了基础。'
948
+ };
949
+
950
+ // 查找关键词
951
+ for (const [keyword, response] of Object.entries(responses)) {
952
+ if (prompt.includes(keyword)) {
953
+ return response;
954
+ }
955
+ }
956
+
957
+ // 默认响应
958
+ return `这是一个模拟的AI响应。您输入的内容是:"${prompt}"\n\n由于跨域限制,无法直接调用硅基流动API。在实际部署环境中,您需要设置后端代理来解决跨域问题。\n\n建议:\n1. 在服务器端部署API代理\n2. 或使用服务器端渲染\n3. 或配置CORS策略`;
959
+ }
960
+
961
+ // 计算质量指标
962
+ function calculateQualityMetrics(content) {
963
+ // 计算字数
964
+ const wordCount = content.length;
965
+
966
+ // 简单的重复率计算(模拟)
967
+ const repetition = Math.floor(Math.random() * 10) + 1 + '%';
968
+
969
+ // 简单的可读性评分(模拟)
970
+ const readability = Math.floor(Math.random() * 30) + 70;
971
+
972
+ return {
973
+ wordCount: wordCount,
974
+ repetition: repetition,
975
+ readability: readability
976
+ };
977
+ }
978
+
979
+ // 处理按键事件
980
+ function handleKeyDown(event) {
981
+ if (event.key === 'Enter' && !event.shiftKey) {
982
+ event.preventDefault();
983
+ sendMessage();
984
+ }
985
+ }
986
+
987
+ // 插入模板
988
+ function insertTemplate(type) {
989
+ const templates = {
990
+ copywriting: '请帮我写一段关于[主题]的文案,风格[风格],长度[长度]',
991
+ essay: '请帮我写一篇关于[主题]的作文,要求[要求]',
992
+ report: '请帮我写一份关于[主题]的报告,包括[内容]',
993
+ email: '请帮我写一封给[收件人]的邮件,内容是[内容]',
994
+ speech: '请帮我写一篇关于[主题]的演讲稿,面向[ audience]',
995
+ code: '请帮我写一段[语言]代码,实现[功能]',
996
+ summary: '请帮我总结以下内容:[内容]'
997
+ };
998
+
999
+ chatInput.value = templates[type] || '';
1000
+ chatInput.focus();
1001
+ }
1002
+
1003
+ // 切换面板
1004
+ function switchPanel(panel) {
1005
+ // 这里可以添加面板切换逻辑
1006
+ console.log('切换到面板:', panel);
1007
+ }
1008
+
1009
+ // 切换控制台
1010
+ function toggleConsole() {
1011
+ consoleContainer.classList.toggle('expanded');
1012
+ consoleToggle.textContent = consoleContainer.classList.contains('expanded') ? '👁 收起' : '👁 展开';
1013
+ }
1014
+
1015
+ // 页面加载完成后初始化
1016
+ document.addEventListener('DOMContentLoaded', init);
1017
+ </script>
1018
+ </body>
1019
+ </html>
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@cja123/ai-content-generator",
3
+ "version": "1.0.0",
4
+ "description": "专业级 AI 内容创作助手",
5
+ "main": "index.html",
6
+ "scripts": {
7
+ "start": "npx http-server -p 8080",
8
+ "dev": "npx http-server -p 8080 -o",
9
+ "build": "mkdir -p dist && cp index.html dist/"
10
+ },
11
+ "keywords": [
12
+ "ai",
13
+ "content",
14
+ "generator",
15
+ "siliconflow"
16
+ ],
17
+ "author": "",
18
+ "license": "MIT",
19
+ "devDependencies": {
20
+ "http-server": "^14.1.1"
21
+ }
22
+ }