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.
- package/es/MonacoEditor.cjs +1 -1
- package/es/MonacoEditor.js +1 -1
- package/es/VarietyAiHelper.cjs +5 -5
- package/es/VarietyAiHelper.js +311 -279
- package/es/VarietySearch.cjs +1 -1
- package/es/VarietySearch.js +1 -1
- package/es/{index-5befc414.cjs → index-40f05e2c.cjs} +2 -2
- package/es/{index-8f9d0d17.js → index-8a54ceeb.js} +2 -2
- package/es/{python-27ece6fa.cjs → python-02c3937a.cjs} +1 -1
- package/es/{python-656db04f.js → python-99011a53.js} +1 -1
- package/es/style.css +1 -1
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +82 -82
- package/lib/{index-73a5aa87.js → index-00866046.js} +3363 -3331
- package/lib/{python-8821365d.js → python-a25c0b5b.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/VarietyAiHelper/index.vue +344 -331
|
@@ -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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
132
|
+
messageList.value[messageIndex].hasFeedback = true;
|
|
86
133
|
break;
|
|
87
134
|
}
|
|
88
135
|
// 自动提交记录跟踪日志
|
|
89
136
|
case "default": {
|
|
90
|
-
const message =
|
|
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 =
|
|
154
|
+
const content = userInput.value.trim();
|
|
109
155
|
if (!content) return ElMessage.warning("请输入消息内容");
|
|
110
156
|
if (isSending.value) return;
|
|
111
157
|
|
|
112
158
|
// 记录用户消息
|
|
113
|
-
|
|
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
|
-
|
|
164
|
+
userInput.value = "";
|
|
119
165
|
await scrollToBottom();
|
|
120
166
|
|
|
121
167
|
// 创建AI消息占位符,记录对应的用户输入
|
|
122
|
-
|
|
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
|
-
|
|
199
|
+
messageList.value.pop();
|
|
154
200
|
|
|
155
201
|
// 添加错误提示消息
|
|
156
|
-
|
|
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",
|
|
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 =
|
|
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 =
|
|
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",
|
|
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
|
-
|
|
258
|
+
messageList.value.pop();
|
|
211
259
|
// 添加错误提示消息
|
|
212
|
-
|
|
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",
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
() =>
|
|
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="
|
|
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
|
|
341
|
+
v-for="(message, index) in messageList"
|
|
295
342
|
:key="index"
|
|
296
|
-
class="message
|
|
343
|
+
:class="message.role"
|
|
344
|
+
class="message-item"
|
|
297
345
|
>
|
|
298
|
-
<
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
<
|
|
315
|
-
<
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
>
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
>
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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 && !
|
|
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="
|
|
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
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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
|
-
|
|
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
|
-
|
|
514
|
-
|
|
499
|
+
&:hover {
|
|
500
|
+
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
|
|
501
|
+
}
|
|
515
502
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
673
|
+
&::placeholder {
|
|
674
|
+
color: #cbd5e0;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
570
678
|
|
|
571
|
-
|
|
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
|
-
|
|
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
|
-
.
|
|
595
|
-
font-size:
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
&:hover {
|
|
599
|
-
transform: translateY(-2px);
|
|
685
|
+
.input-hint {
|
|
686
|
+
font-size: 12px;
|
|
687
|
+
color: #9ca3af;
|
|
600
688
|
|
|
601
|
-
|
|
602
|
-
|
|
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
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
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
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
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
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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;
|