st-comp 0.0.255 → 0.0.256

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.
@@ -8,6 +8,7 @@ import { UserFilled, Service, Promotion } from "@element-plus/icons-vue";
8
8
 
9
9
  const stConfig = inject("stConfig");
10
10
  const userData = reactive(getUserData());
11
+ const visible = ref(false);
11
12
  const emit = defineEmits(["callBack"]);
12
13
  const props = defineProps({
13
14
  defaultMessage: {
@@ -16,12 +17,13 @@ const props = defineProps({
16
17
  },
17
18
  });
18
19
 
19
- const visible = ref(false);
20
+ // loading状态
20
21
  const isSending = ref(false);
21
22
  const isThinking = ref(false);
22
23
 
24
+ // 消息队列
23
25
  const messageListRef = ref(null);
24
- const messages = ref([
26
+ const messageList = ref([
25
27
  {
26
28
  role: "assistant", // AI-assistant, 用户-user
27
29
  content: props.defaultMessage,
@@ -33,19 +35,64 @@ const messages = ref([
33
35
  firstPackageTime: 0, // 首包响应耗时
34
36
  },
35
37
  ]);
36
- const inputMessage = ref("");
37
38
 
38
- // 反馈弹窗相关
39
+ // 用户输入
40
+ const userInput = ref("");
41
+
42
+ // 反馈弹窗
39
43
  const feedbackDialogVisible = ref(false);
40
44
  const feedbackContent = ref("");
41
45
  const feedbackMessageIndex = ref({}); // 当前点击要反馈的message的索引
42
46
 
47
+ // 辅助函数:判断是否可JSON序列化
48
+ const isJSONSerializable = (str) => {
49
+ if (typeof str !== "string") return false;
50
+ try {
51
+ const parsed = JSON.parse(str);
52
+ return parsed !== null && typeof parsed === "object";
53
+ } catch {
54
+ return false;
55
+ }
56
+ };
57
+ // 辅助函数:解析并格式化JSON内容
58
+ const formatJSONContent = (content) => {
59
+ if (!isJSONSerializable(content)) return null;
60
+ try {
61
+ const jsonData = JSON.parse(content);
62
+ const { parsedConditions, ...webParams } = jsonData;
63
+ return {
64
+ parsedConditions: parsedConditions,
65
+ webParams,
66
+ };
67
+ } catch {
68
+ return null;
69
+ }
70
+ };
71
+ // 辅助函数:渲染JSON内容为HTML
72
+ const renderJSONContent = (jsonData) => {
73
+ if (!jsonData) return "";
74
+ let html = "";
75
+ // 渲染 parsedConditions
76
+ if (jsonData.parsedConditions?.length) {
77
+ html += '<div class="parsed-conditions">';
78
+ jsonData.parsedConditions.forEach((text) => {
79
+ html += `<div class="parsed-conditions-item">${text}</div>`;
80
+ });
81
+ html += "</div>";
82
+ }
83
+ // 渲染 webParams
84
+ // html += '<div class="web-params">';
85
+ // html += `<div>${JSON.stringify(jsonData.webParams)}</div>`;
86
+ // html += "</div>";
87
+ return html;
88
+ };
89
+
43
90
  // 反馈弹窗相关函数处理
44
91
  const handleFeedbackAction = async (action, messageIndex) => {
45
92
  switch (action) {
46
93
  // 窗口: 提交(满意)
47
94
  case "satisfied": {
48
- const message = messages.value[messageIndex];
95
+ const message = messageList.value[messageIndex];
49
96
  const params = {
50
97
  userName: userData.username,
51
98
  userContent: message.userContent,
@@ -57,7 +104,7 @@ const handleFeedbackAction = async (action, messageIndex) => {
57
104
  };
58
105
  await stConfig.request.post("/alarm/deliversign/addVarietyAiHelperLog", params);
59
106
  ElMessage.success("感谢您的评价!");
60
- messages.value[messageIndex].hasFeedback = true;
107
+ messageList.value[messageIndex].hasFeedback = true;
61
108
  break;
62
109
  }
63
110
  // 窗口: 打开
@@ -68,7 +115,7 @@ const handleFeedbackAction = async (action, messageIndex) => {
68
115
  }
69
116
  // 窗口: 提交(不满意)
70
117
  case "unsatisfied": {
71
- const message = messages.value[messageIndex];
118
+ const message = messageList.value[messageIndex];
72
119
  const params = {
73
120
  userName: userData.username,
74
121
  userContent: message.userContent,
@@ -82,12 +129,12 @@ const handleFeedbackAction = async (action, messageIndex) => {
82
129
  await stConfig.request.post("/alarm/deliversign/addVarietyAiHelperLog", params);
83
130
  ElMessage.success("感谢您的反馈!我们将持续跟踪并进行优化");
84
131
  feedbackDialogVisible.value = false;
85
- messages.value[messageIndex].hasFeedback = true;
132
+ messageList.value[messageIndex].hasFeedback = true;
86
133
  break;
87
134
  }
88
135
  // 自动提交记录跟踪日志
89
136
  case "default": {
90
- const message = messages.value[messageIndex];
137
+ const message = messageList.value[messageIndex];
91
138
  const params = {
92
139
  userName: userData.username,
93
140
  userContent: message.userContent,
@@ -102,24 +149,23 @@ const handleFeedbackAction = async (action, messageIndex) => {
102
149
  }
103
150
  }
104
151
  };
105
-
106
152
  // 发送消息
107
153
  const sendMessage = async () => {
108
- const content = inputMessage.value.trim();
154
+ const content = userInput.value.trim();
109
155
  if (!content) return ElMessage.warning("请输入消息内容");
110
156
  if (isSending.value) return;
111
157
 
112
158
  // 记录用户消息
113
- messages.value.push({
159
+ messageList.value.push({
114
160
  role: "user",
115
161
  content: content,
116
162
  createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
117
163
  });
118
- inputMessage.value = "";
164
+ userInput.value = "";
119
165
  await scrollToBottom();
120
166
 
121
167
  // 创建AI消息占位符,记录对应的用户输入
122
- messages.value.push({
168
+ messageList.value.push({
123
169
  role: "assistant",
124
170
  content: "",
125
171
  userContent: content,
@@ -150,10 +196,10 @@ const sendMessage = async () => {
150
196
  isSending.value = false;
151
197
 
152
198
  // 移除占位的AI消息
153
- messages.value.pop();
199
+ messageList.value.pop();
154
200
 
155
201
  // 添加错误提示消息
156
- messages.value.push({
202
+ messageList.value.push({
157
203
  role: "assistant",
158
204
  userContent: content,
159
205
  content: `❌ ${data}`,
@@ -163,7 +209,7 @@ const sendMessage = async () => {
163
209
  resTime: new Date().getTime() - resTime,
164
210
  firstPackageTime: 0,
165
211
  });
166
- handleFeedbackAction("default", messages.value.length - 1);
212
+ handleFeedbackAction("default", messageList.value.length - 1);
167
213
  scrollToBottom();
168
214
  return;
169
215
  }
@@ -171,7 +217,7 @@ const sendMessage = async () => {
171
217
  else if (type === "message") {
172
218
  fullResponse += data;
173
219
  // 直接更新最后一条AI消息
174
- const lastMessage = messages.value[messages.value.length - 1];
220
+ const lastMessage = messageList.value[messageList.value.length - 1];
175
221
  if (lastMessage && lastMessage.role === "assistant") {
176
222
  lastMessage.content = fullResponse;
177
223
  scrollToBottom();
@@ -185,18 +231,20 @@ const sendMessage = async () => {
185
231
  else if (type === "finish") {
186
232
  isThinking.value = false;
187
233
  isSending.value = false;
188
- const lastMessage = messages.value[messages.value.length - 1];
234
+ const lastMessage = messageList.value[messageList.value.length - 1];
189
235
 
190
236
  // 显示反馈按钮
191
237
  if (lastMessage && lastMessage.role === "assistant") {
192
238
  lastMessage.showFeedback = true;
193
239
  lastMessage.resTime = new Date().getTime() - resTime;
194
- handleFeedbackAction("default", messages.value.length - 1);
240
+ handleFeedbackAction("default", messageList.value.length - 1);
195
241
  }
196
242
 
197
243
  // 触发回调
198
244
  try {
199
245
  const jsonResponse = JSON.parse(fullResponse);
246
+ // 切割掉parsedConditions, 这个字段仅做AI提炼展示使用
247
+ delete jsonResponse.parsedConditions;
200
248
  emit("callBack", jsonResponse);
201
249
  } catch (error) {
202
250
  emit("callBack", fullResponse);
@@ -207,9 +255,9 @@ const sendMessage = async () => {
207
255
  } catch (error) {
208
256
  ElMessage.error(`AI响应异常: ${error}`);
209
257
  // 移除占位的AI消息
210
- messages.value.pop();
258
+ messageList.value.pop();
211
259
  // 添加错误提示消息
212
- messages.value.push({
260
+ messageList.value.push({
213
261
  role: "assistant",
214
262
  userContent: content,
215
263
  content: "❌ 抱歉,AI服务响应异常,请稍后重试。",
@@ -219,14 +267,14 @@ const sendMessage = async () => {
219
267
  resTime: new Date().getTime() - resTime,
220
268
  firstPackageTime: 0,
221
269
  });
222
- handleFeedbackAction("default", messages.value.length - 1);
270
+ handleFeedbackAction("default", messageList.value.length - 1);
223
271
  await scrollToBottom();
224
272
  isSending.value = false;
225
273
  isThinking.value = false;
226
274
  }
227
275
  };
228
276
 
229
- // 处理键盘事件:Ctrl+Enter 换行,Enter 发送
277
+ // 辅助函数: Ctrl+Enter 换行,Enter 发送
230
278
  const handleKeydown = (event) => {
231
279
  if (event.key === "Enter") {
232
280
  if (event.ctrlKey) {
@@ -235,7 +283,7 @@ const handleKeydown = (event) => {
235
283
  const textarea = event.target;
236
284
  const start = textarea.selectionStart;
237
285
  const end = textarea.selectionEnd;
238
- inputMessage.value = inputMessage.value.substring(0, start) + "\n" + inputMessage.value.substring(end);
286
+ userInput.value = userInput.value.substring(0, start) + "\n" + userInput.value.substring(end);
239
287
  // 将光标移动到新插入的换行符之后
240
288
  nextTick(() => {
241
289
  textarea.selectionStart = textarea.selectionEnd = start + 1;
@@ -247,8 +295,7 @@ const handleKeydown = (event) => {
247
295
  }
248
296
  }
249
297
  };
250
-
251
- // 滚动到底部
298
+ // 辅助函数: 滚动到底部
252
299
  const scrollToBottom = async () => {
253
300
  await nextTick();
254
301
  if (messageListRef.value) {
@@ -257,7 +304,7 @@ const scrollToBottom = async () => {
257
304
  };
258
305
 
259
306
  watch(
260
- () => messages.value,
307
+ () => messageList.value,
261
308
  () => {
262
309
  scrollToBottom();
263
310
  },
@@ -285,62 +332,72 @@ defineExpose({
285
332
  :modal="false"
286
333
  :modal-penetrable="true"
287
334
  >
288
- <div class="chat-container">
335
+ <div class="ai-dialog-body">
289
336
  <div
290
337
  ref="messageListRef"
291
338
  class="message-list"
292
339
  >
293
340
  <div
294
- v-for="(message, index) in messages"
341
+ v-for="(message, index) in messageList"
295
342
  :key="index"
296
- class="message-item-wrapper"
343
+ :class="message.role"
344
+ class="message-item"
297
345
  >
298
- <div
299
- class="message-item"
300
- :class="message.role"
301
- >
302
- <template v-if="message.content">
303
- <div class="avatar">
304
- <el-avatar
305
- :size="32"
306
- :icon="message.role === 'user' ? UserFilled : Service"
307
- />
346
+ <template v-if="message.content">
347
+ <!-- 消息头像 -->
348
+ <div class="avatar">
349
+ <el-avatar
350
+ :size="32"
351
+ :icon="message.role === 'user' ? UserFilled : Service"
352
+ />
353
+ </div>
354
+ <div class="message-content">
355
+ <!-- 判断是否为可JSON序列化的数据 -->
356
+ <div
357
+ v-if="isJSONSerializable(message.content)"
358
+ class="message-json"
359
+ v-html="renderJSONContent(formatJSONContent(message.content))"
360
+ ></div>
361
+ <!-- 普通文本展示 -->
362
+ <div
363
+ v-else
364
+ class="message-text"
365
+ >
366
+ {{ message.content }}
308
367
  </div>
309
- <div class="message-content">
310
- <div class="message-text">{{ message.content }}</div>
311
- <div class="message-createTime">{{ message.createTime }}</div>
312
- <!-- 反馈按钮(仅AI侧展示) -->
313
- <template v-if="message.role === 'assistant'">
314
- <template v-if="message.showFeedback && !message.hasFeedback">
315
- <div class="message-createTime">请问对本轮查询结果是否满意?</div>
316
- <div class="feedback-buttons">
317
- <button
318
- class="feedback-btn satisfied-btn"
319
- @click="handleFeedbackAction('satisfied', index)"
320
- >
321
- <span class="btn-emoji">👍</span>
322
- <span class="btn-text">满意</span>
323
- </button>
324
- <button
325
- class="feedback-btn unsatisfied-btn"
326
- @click="handleFeedbackAction('open', index)"
327
- >
328
- <span class="btn-emoji">👎</span>
329
- <span class="btn-text">不满意</span>
330
- </button>
331
- </div>
332
- </template>
333
- <template v-if="message.showFeedback && message.hasFeedback">
334
- <div class="message-createTime">感谢您进行的评价反馈</div>
335
- </template>
368
+ <div class="message-createTime">{{ message.createTime }}</div>
369
+ <!-- 反馈按钮(仅AI侧展示) -->
370
+ <template v-if="message.role === 'assistant'">
371
+ <template v-if="message.showFeedback && !message.hasFeedback">
372
+ <div class="message-createTime">请问对本轮查询结果是否满意?</div>
373
+ <div class="feedback-buttons">
374
+ <button
375
+ class="feedback-btn satisfied-btn"
376
+ @click="handleFeedbackAction('satisfied', index)"
377
+ >
378
+ <span class="btn-emoji">👍</span>
379
+ <span class="btn-text">满意</span>
380
+ </button>
381
+ <button
382
+ class="feedback-btn unsatisfied-btn"
383
+ @click="handleFeedbackAction('open', index)"
384
+ >
385
+ <span class="btn-emoji">👎</span>
386
+ <span class="btn-text">不满意</span>
387
+ </button>
388
+ </div>
336
389
  </template>
337
- </div>
338
- </template>
339
- </div>
390
+ <template v-if="message.showFeedback && message.hasFeedback">
391
+ <div class="message-createTime">感谢您进行的评价反馈</div>
392
+ </template>
393
+ </template>
394
+ </div>
395
+ </template>
340
396
  </div>
341
397
 
398
+ <!-- AI首包响应思考Loading -->
342
399
  <div
343
- v-if="isThinking && !messages[messages.length - 1]?.content"
400
+ v-if="isThinking && !messageList[messageList.length - 1]?.content"
344
401
  class="message-item assistant"
345
402
  >
346
403
  <div class="avatar">
@@ -362,7 +419,7 @@ defineExpose({
362
419
  <div class="input-area">
363
420
  <el-input
364
421
  class="message-input"
365
- v-model="inputMessage"
422
+ v-model="userInput"
366
423
  type="textarea"
367
424
  :rows="4"
368
425
  :autosize="{ minRows: 2, maxRows: 4 }"
@@ -418,223 +475,245 @@ defineExpose({
418
475
  </template>
419
476
 
420
477
  <style lang="scss" scoped>
421
- /* 样式保持不变,和之前一样 */
422
478
  .ai-dialog {
423
- :deep(.el-dialog) {
424
- border-radius: 24px;
425
- background: linear-gradient(135deg, #ffffff 0%, #f8f9ff 100%);
426
- box-shadow: 0 20px 35px -12px rgba(0, 0, 0, 0.15);
427
- overflow: hidden;
428
-
429
- .el-dialog__header {
430
- padding: 20px 24px 12px;
431
- margin: 0;
432
- border-bottom: 1px solid rgba(102, 126, 234, 0.1);
433
- background: rgba(255, 255, 255, 0.8);
434
- backdrop-filter: blur(10px);
435
-
436
- .el-dialog__title {
437
- font-size: 18px;
438
- font-weight: 600;
439
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
440
- background-clip: text;
441
- -webkit-background-clip: text;
442
- -webkit-text-fill-color: transparent;
479
+ .ai-dialog-body {
480
+ display: flex;
481
+ flex-direction: column;
482
+ height: 480px;
483
+ background: transparent;
484
+ .message-list {
485
+ flex: 1;
486
+ overflow-y: auto;
487
+ padding: 20px 24px;
488
+ &::-webkit-scrollbar {
489
+ width: 6px;
443
490
  }
444
- }
445
-
446
- .el-dialog__body {
447
- padding: 0;
448
- }
449
-
450
- .el-dialog__footer {
451
- display: none;
452
- }
453
- }
454
- }
455
-
456
- .chat-container {
457
- display: flex;
458
- flex-direction: column;
459
- height: 480px;
460
- background: transparent;
461
- }
462
-
463
- .message-list {
464
- flex: 1;
465
- overflow-y: auto;
466
- padding: 20px 24px;
467
- scroll-behavior: smooth;
468
-
469
- &::-webkit-scrollbar {
470
- width: 6px;
471
- }
472
-
473
- &::-webkit-scrollbar-track {
474
- background: rgba(0, 0, 0, 0.05);
475
- border-radius: 3px;
476
- }
477
-
478
- &::-webkit-scrollbar-thumb {
479
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
480
- border-radius: 3px;
481
-
482
- &:hover {
483
- background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
484
- }
485
- }
486
- }
487
-
488
- .message-item-wrapper {
489
- margin-bottom: 20px;
490
- }
491
-
492
- .message-item {
493
- display: flex;
494
- animation: fadeInUp 0.3s ease-out;
495
-
496
- &.user {
497
- flex-direction: row-reverse;
498
-
499
- .avatar {
500
- margin-left: 12px;
501
- margin-right: 0;
502
- }
503
-
504
- .message-content {
505
- align-items: flex-end;
506
-
507
- .message-text {
508
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
509
- color: white;
510
- border-radius: 18px 18px 4px 18px;
491
+ &::-webkit-scrollbar-track {
492
+ background: rgba(0, 0, 0, 0.05);
493
+ border-radius: 3px;
511
494
  }
495
+ &::-webkit-scrollbar-thumb {
496
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
497
+ border-radius: 3px;
512
498
 
513
- .message-createTime {
514
- text-align: right;
499
+ &:hover {
500
+ background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
501
+ }
515
502
  }
516
- }
517
- }
518
-
519
- &.assistant {
520
- .avatar {
521
- margin-right: 12px;
522
- }
523
-
524
- .message-content {
525
- align-items: flex-start;
526
-
527
- .message-text {
528
- background: white;
529
- color: #2c3e50;
530
- border-radius: 18px 18px 18px 4px;
531
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
532
- border: 1px solid rgba(102, 126, 234, 0.1);
503
+ // 消息公共样式
504
+ .message-item {
505
+ display: flex;
506
+ animation: fadeInUp 0.3s ease-out;
507
+ margin-bottom: 20px;
508
+ .avatar {
509
+ flex-shrink: 0;
510
+ :deep(.el-avatar) {
511
+ background: linear-gradient(135deg, #f0f2ff 0%, #e8ecff 100%);
512
+ color: #667eea;
513
+ svg {
514
+ width: 18px;
515
+ height: 18px;
516
+ }
517
+ }
518
+ }
519
+ .message-content {
520
+ display: flex;
521
+ flex-direction: column;
522
+ max-width: 70%;
523
+ .message-json,
524
+ .message-text {
525
+ padding: 10px 16px;
526
+ font-size: 14px;
527
+ line-height: 1.5;
528
+ word-wrap: break-word;
529
+ white-space: pre-wrap;
530
+ }
531
+ .message-createTime {
532
+ font-size: 11px;
533
+ color: #9ca3af;
534
+ margin-top: 6px;
535
+ }
536
+ .feedback-buttons {
537
+ display: flex;
538
+ gap: 12px;
539
+ margin-top: 12px;
540
+ .feedback-btn {
541
+ display: flex;
542
+ align-items: center;
543
+ gap: 6px;
544
+ padding: 4px 10px;
545
+ border: none;
546
+ border-radius: 20px;
547
+ font-size: 13px;
548
+ font-weight: 500;
549
+ cursor: pointer;
550
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
551
+ background: rgba(255, 255, 255, 0.9);
552
+ backdrop-filter: blur(10px);
553
+
554
+ .btn-emoji {
555
+ font-size: 16px;
556
+ transition: transform 0.2s ease;
557
+ }
558
+ .btn-text {
559
+ font-size: 13px;
560
+ }
561
+ &:hover {
562
+ transform: translateY(-2px);
563
+ .btn-emoji {
564
+ transform: scale(1.1);
565
+ }
566
+ }
567
+ &:active {
568
+ transform: translateY(0);
569
+ }
570
+ }
571
+ .satisfied-btn {
572
+ background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
573
+ color: #1890ff;
574
+ border: 1px solid rgba(24, 144, 255, 0.2);
575
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
576
+
577
+ &:hover {
578
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
579
+ border-color: #1890ff;
580
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
581
+ }
582
+ }
583
+ .unsatisfied-btn {
584
+ background: linear-gradient(135deg, #fff1f0 0%, #ffe7e5 100%);
585
+ color: #ff4d4f;
586
+ border: 1px solid rgba(255, 77, 79, 0.2);
587
+ box-shadow: 0 2px 8px rgba(255, 77, 79, 0.1);
588
+
589
+ &:hover {
590
+ background: linear-gradient(135deg, #ffe7e5 0%, #ffccc7 100%);
591
+ border-color: #ff4d4f;
592
+ box-shadow: 0 4px 12px rgba(255, 77, 79, 0.2);
593
+ }
594
+ }
595
+ }
596
+ }
533
597
  }
534
- }
535
- }
536
-
537
- .avatar {
538
- flex-shrink: 0;
539
-
540
- :deep(.el-avatar) {
541
- background: linear-gradient(135deg, #f0f2ff 0%, #e8ecff 100%);
542
- color: #667eea;
543
-
544
- svg {
545
- width: 18px;
546
- height: 18px;
598
+ // 用户消息
599
+ .user {
600
+ flex-direction: row-reverse;
601
+ .avatar {
602
+ margin-left: 12px;
603
+ margin-right: 0;
604
+ }
605
+ .message-content {
606
+ align-items: flex-end;
607
+ .message-text {
608
+ color: white;
609
+ border-radius: 18px 18px 4px 18px;
610
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
611
+ }
612
+ .message-createTime {
613
+ text-align: right;
614
+ }
615
+ }
616
+ }
617
+ // AI消息
618
+ .assistant {
619
+ .avatar {
620
+ margin-right: 12px;
621
+ }
622
+ .message-content {
623
+ align-items: flex-start;
624
+ .message-text {
625
+ background: white;
626
+ color: #2c3e50;
627
+ border-radius: 18px 18px 18px 4px;
628
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
629
+ border: 1px solid rgba(102, 126, 234, 0.1);
630
+ }
631
+ .message-json {
632
+ width: 100%;
633
+ background: white;
634
+ color: #2c3e50;
635
+ border-radius: 18px 18px 18px 4px;
636
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
637
+ border: 1px solid rgba(102, 126, 234, 0.1);
638
+ :deep(.parsed-conditions) {
639
+ margin-top: 10px;
640
+ .parsed-conditions-item {
641
+ text-align: center;
642
+ color: #f56c6c;
643
+ margin-bottom: 10px;
644
+ padding: 2px;
645
+ background-color: rgb(253, 226, 226);
646
+ border-radius: 4px;
647
+ }
648
+ }
649
+ }
650
+ }
547
651
  }
548
652
  }
549
- }
653
+ .input-area {
654
+ padding: 16px 24px 24px;
655
+ border-top: 1px solid rgba(102, 126, 234, 0.1);
656
+ background: rgba(255, 255, 255, 0.9);
657
+ backdrop-filter: blur(10px);
550
658
 
551
- .message-content {
552
- display: flex;
553
- flex-direction: column;
554
- max-width: 70%;
555
-
556
- .message-text {
557
- padding: 10px 16px;
558
- font-size: 14px;
559
- line-height: 1.5;
560
- word-wrap: break-word;
561
- white-space: pre-wrap;
562
- }
659
+ .message-input {
660
+ :deep(.el-textarea__inner) {
661
+ border-radius: 16px;
662
+ border: 1px solid rgba(102, 126, 234, 0.2);
663
+ background: #ffffff;
664
+ font-size: 14px;
665
+ padding: 12px 16px;
666
+ transition: all 0.3s ease;
667
+
668
+ &:focus {
669
+ border-color: #667eea;
670
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
671
+ }
563
672
 
564
- .message-createTime {
565
- font-size: 11px;
566
- color: #9ca3af;
567
- margin-top: 6px;
568
- padding: 0 4px;
569
- }
673
+ &::placeholder {
674
+ color: #cbd5e0;
675
+ }
676
+ }
677
+ }
570
678
 
571
- .feedback-buttons {
572
- display: flex;
573
- gap: 12px;
574
- margin-top: 12px;
575
- .feedback-btn {
679
+ .input-actions {
576
680
  display: flex;
681
+ justify-content: space-between;
577
682
  align-items: center;
578
- gap: 6px;
579
- padding: 4px 10px;
580
- border: none;
581
- border-radius: 20px;
582
- font-size: 13px;
583
- font-weight: 500;
584
- cursor: pointer;
585
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
586
- background: rgba(255, 255, 255, 0.9);
587
- backdrop-filter: blur(10px);
588
-
589
- .btn-emoji {
590
- font-size: 16px;
591
- transition: transform 0.2s ease;
592
- }
683
+ margin-top: 12px;
593
684
 
594
- .btn-text {
595
- font-size: 13px;
596
- }
597
-
598
- &:hover {
599
- transform: translateY(-2px);
685
+ .input-hint {
686
+ font-size: 12px;
687
+ color: #9ca3af;
600
688
 
601
- .btn-emoji {
602
- transform: scale(1.1);
689
+ span {
690
+ background: rgba(102, 126, 234, 0.1);
691
+ padding: 4px 8px;
692
+ border-radius: 12px;
693
+ font-size: 11px;
603
694
  }
604
695
  }
605
696
 
606
- &:active {
607
- transform: translateY(0);
608
- }
609
- }
610
- .satisfied-btn {
611
- background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
612
- color: #1890ff;
613
- border: 1px solid rgba(24, 144, 255, 0.2);
614
- box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
697
+ .send-btn {
698
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
699
+ border: none;
700
+ padding: 8px 20px;
701
+ font-weight: 500;
702
+ transition: all 0.3s ease;
615
703
 
616
- &:hover {
617
- background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
618
- border-color: #1890ff;
619
- box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
620
- }
621
- }
622
- .unsatisfied-btn {
623
- background: linear-gradient(135deg, #fff1f0 0%, #ffe7e5 100%);
624
- color: #ff4d4f;
625
- border: 1px solid rgba(255, 77, 79, 0.2);
626
- box-shadow: 0 2px 8px rgba(255, 77, 79, 0.1);
704
+ &:hover {
705
+ transform: translateY(-2px);
706
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
707
+ }
627
708
 
628
- &:hover {
629
- background: linear-gradient(135deg, #ffe7e5 0%, #ffccc7 100%);
630
- border-color: #ff4d4f;
631
- box-shadow: 0 4px 12px rgba(255, 77, 79, 0.2);
709
+ &:active {
710
+ transform: translateY(0);
711
+ }
632
712
  }
633
713
  }
634
714
  }
635
715
  }
636
716
  }
637
-
638
717
  .typing-indicator {
639
718
  display: flex;
640
719
  gap: 4px;
@@ -654,76 +733,11 @@ defineExpose({
654
733
  &:nth-child(1) {
655
734
  animation-delay: -0.32s;
656
735
  }
657
-
658
736
  &:nth-child(2) {
659
737
  animation-delay: -0.16s;
660
738
  }
661
739
  }
662
740
  }
663
-
664
- .input-area {
665
- padding: 16px 24px 24px;
666
- border-top: 1px solid rgba(102, 126, 234, 0.1);
667
- background: rgba(255, 255, 255, 0.9);
668
- backdrop-filter: blur(10px);
669
-
670
- .message-input {
671
- :deep(.el-textarea__inner) {
672
- border-radius: 16px;
673
- border: 1px solid rgba(102, 126, 234, 0.2);
674
- background: #ffffff;
675
- font-size: 14px;
676
- padding: 12px 16px;
677
- transition: all 0.3s ease;
678
-
679
- &:focus {
680
- border-color: #667eea;
681
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
682
- }
683
-
684
- &::placeholder {
685
- color: #cbd5e0;
686
- }
687
- }
688
- }
689
-
690
- .input-actions {
691
- display: flex;
692
- justify-content: space-between;
693
- align-items: center;
694
- margin-top: 12px;
695
-
696
- .input-hint {
697
- font-size: 12px;
698
- color: #9ca3af;
699
-
700
- span {
701
- background: rgba(102, 126, 234, 0.1);
702
- padding: 4px 8px;
703
- border-radius: 12px;
704
- font-size: 11px;
705
- }
706
- }
707
-
708
- .send-btn {
709
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
710
- border: none;
711
- padding: 8px 20px;
712
- font-weight: 500;
713
- transition: all 0.3s ease;
714
-
715
- &:hover {
716
- transform: translateY(-2px);
717
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
718
- }
719
-
720
- &:active {
721
- transform: translateY(0);
722
- }
723
- }
724
- }
725
- }
726
-
727
741
  .feedback-dialog-content {
728
742
  text-align: center;
729
743
  padding: 12px 0;
@@ -752,7 +766,6 @@ defineExpose({
752
766
  }
753
767
  }
754
768
  }
755
-
756
769
  @keyframes fadeInUp {
757
770
  from {
758
771
  opacity: 0;