st-comp 0.0.268 → 0.0.269

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 (128) hide show
  1. package/components.d.ts +1 -0
  2. package/es/CustomFunction.cjs +1 -1
  3. package/es/CustomFunction.js +22 -22
  4. package/es/FactorWarning.cjs +1 -1
  5. package/es/FactorWarning.js +26 -26
  6. package/es/Kline.cjs +1 -1
  7. package/es/Kline.js +11 -11
  8. package/es/KlineBasic.cjs +1 -1
  9. package/es/KlineBasic.js +19 -19
  10. package/es/KlineConfig.cjs +1 -1
  11. package/es/KlineConfig.js +16 -16
  12. package/es/KlineNew.cjs +1 -1
  13. package/es/KlineNew.js +10 -10
  14. package/es/KlinePlus.cjs +1 -1
  15. package/es/KlinePlus.js +12 -12
  16. package/es/MonacoEditor.cjs +1 -1
  17. package/es/MonacoEditor.js +18 -18
  18. package/es/Pagination.cjs +1 -1
  19. package/es/Pagination.js +14 -14
  20. package/es/PasswordPrompt.cjs +1 -1
  21. package/es/PasswordPrompt.js +2 -2
  22. package/es/Table.cjs +1 -1
  23. package/es/Table.js +18 -18
  24. package/es/User.cjs +1 -1
  25. package/es/User.js +19 -19
  26. package/es/VarSelectDialog.cjs +1 -1
  27. package/es/VarSelectDialog.js +19 -19
  28. package/es/VarietyAiHelper.cjs +8 -3
  29. package/es/VarietyAiHelper.js +485 -307
  30. package/es/VarietyAutoComplete.cjs +1 -1
  31. package/es/VarietyAutoComplete.js +8 -8
  32. package/es/VarietySearch.cjs +1 -1
  33. package/es/VarietySearch.js +31 -31
  34. package/es/{VarietySelect-639a8d9a.cjs → VarietySelect-7da473c5.cjs} +1 -1
  35. package/es/{VarietySelect-1ac10ec2.js → VarietySelect-b01281d3.js} +3 -3
  36. package/es/VarietyTextCopy.cjs +1 -1
  37. package/es/VarietyTextCopy.js +10 -10
  38. package/es/VirtualTable.cjs +1 -1
  39. package/es/VirtualTable.js +66 -66
  40. package/es/{_initCloneObject-6b8c230e.js → _initCloneObject-6243b839.js} +2 -2
  41. package/es/{_initCloneObject-9eddcb0c.cjs → _initCloneObject-76e116d0.cjs} +1 -1
  42. package/es/aiTools-275c9799.cjs +4 -0
  43. package/es/aiTools-9c59a74a.js +149 -0
  44. package/es/aiTools.js +121 -27
  45. package/es/{config-provider-56193d47.js → config-provider-20b05e99.js} +3 -3
  46. package/es/{config-provider-ea286661.cjs → config-provider-4c784baf.cjs} +1 -1
  47. package/es/{dropdown-f30148cc.cjs → dropdown-33c19e56.cjs} +1 -1
  48. package/es/{dropdown-4e541d60.js → dropdown-f8d9fe56.js} +3 -3
  49. package/es/{el-autocomplete-4b521c83.js → el-autocomplete-3f34a1c3.js} +6 -6
  50. package/es/{el-autocomplete-3949e68c.cjs → el-autocomplete-525ca867.cjs} +1 -1
  51. package/es/{el-button-dd065de0.cjs → el-button-13dc915f.cjs} +1 -1
  52. package/es/{el-button-4f201000.js → el-button-cd144ee1.js} +3 -3
  53. package/es/{el-checkbox-02ce40f0.cjs → el-checkbox-95325acd.cjs} +1 -1
  54. package/es/{el-checkbox-33cb73db.js → el-checkbox-d6c883f4.js} +3 -3
  55. package/es/{el-dialog-6501a151.cjs → el-dialog-4056070b.cjs} +1 -1
  56. package/es/{el-dialog-1939f7c5.js → el-dialog-59a23c2b.js} +4 -4
  57. package/es/{el-form-item-316b35d8.cjs → el-form-item-3475aaad.cjs} +1 -1
  58. package/es/{el-form-item-ea11211d.js → el-form-item-a9556441.js} +5 -5
  59. package/es/{el-input-58786d42.js → el-input-1f14a6e2.js} +33 -33
  60. package/es/{el-input-094afbe2.cjs → el-input-c7bf8e44.cjs} +1 -1
  61. package/es/{el-input-number-a7971697.js → el-input-number-411ac93d.js} +12 -12
  62. package/es/{el-input-number-a609a5e3.cjs → el-input-number-9d810842.cjs} +1 -1
  63. package/es/{el-loading-d171ce64.cjs → el-loading-84dde1a8.cjs} +1 -1
  64. package/es/{el-loading-f3815921.js → el-loading-cbeb3b86.js} +1 -1
  65. package/es/{el-menu-item-3d1e0aff.cjs → el-menu-item-18d7d869.cjs} +1 -1
  66. package/es/{el-menu-item-a166b997.js → el-menu-item-77152904.js} +5 -5
  67. package/es/{el-message-box-f2b667e9.js → el-message-box-a26e3ed4.js} +9 -9
  68. package/es/{el-message-box-b8ffcf34.cjs → el-message-box-e4b8cc99.cjs} +1 -1
  69. package/es/{el-overlay-1dfe3675.js → el-overlay-465cd11e.js} +3 -3
  70. package/es/{el-overlay-a94f8a98.cjs → el-overlay-d26a1b98.cjs} +1 -1
  71. package/es/{el-popconfirm-70e2849c.cjs → el-popconfirm-12f6f35c.cjs} +1 -1
  72. package/es/{el-popconfirm-ca31ceea.js → el-popconfirm-289b3e89.js} +5 -5
  73. package/es/{el-popper-ce575c12.cjs → el-popper-c7648df6.cjs} +1 -1
  74. package/es/{el-popper-db6c599f.js → el-popper-f96fc206.js} +2 -2
  75. package/es/{el-segmented-741f2252.js → el-segmented-598b92b0.js} +2 -2
  76. package/es/{el-segmented-4d50b63f.cjs → el-segmented-f0bce6f2.cjs} +1 -1
  77. package/es/{el-select-086bcb6c.js → el-select-d47b5923.js} +9 -9
  78. package/es/{el-select-2ebc8380.cjs → el-select-f3cc464f.cjs} +1 -1
  79. package/es/{el-table-column-2f07fbdb.cjs → el-table-column-220ae131.cjs} +1 -1
  80. package/es/{el-table-column-8a15378a.js → el-table-column-f1017e75.js} +10 -10
  81. package/es/{el-tag-65a99986.js → el-tag-0a4197f5.js} +2 -2
  82. package/es/{el-tag-f48b1190.cjs → el-tag-51bd491c.cjs} +1 -1
  83. package/es/{el-text-33359f44.cjs → el-text-abf10fdf.cjs} +1 -1
  84. package/es/{el-text-cbb693f2.js → el-text-c3ee80fe.js} +1 -1
  85. package/es/{index-18565979.cjs → index-0986e373.cjs} +1 -1
  86. package/es/{index-4f900527.cjs → index-09ce1753.cjs} +1 -1
  87. package/es/{index-eeae573e.cjs → index-0ff5fe69.cjs} +2 -2
  88. package/es/{index-ca91ac68.js → index-1b97095f.js} +83 -68
  89. package/es/{index-ff26b1a6.js → index-3301d870.js} +2 -2
  90. package/es/{index-1e91e986.js → index-33430c9f.js} +1 -1
  91. package/es/{index-0f767104.cjs → index-3ed7914e.cjs} +1 -1
  92. package/es/index-476c4459.cjs +1 -0
  93. package/es/{index-072c4a65.js → index-499cf989.js} +5 -5
  94. package/es/{index-21e8d2bc.cjs → index-4b95bae1.cjs} +1 -1
  95. package/es/{index-8439d2f9.cjs → index-60c69dd1.cjs} +1 -1
  96. package/es/{index-57d82da0.js → index-67180968.js} +2 -2
  97. package/es/{index-bf98dd03.cjs → index-68798830.cjs} +1 -1
  98. package/es/{index-f2583ae9.js → index-89cc0265.js} +10 -10
  99. package/es/{index-1955f23d.js → index-8e88a0bd.js} +1 -1
  100. package/es/{index-a4e252a0.js → index-a17c90c5.js} +1 -1
  101. package/es/{index-b51915a2.js → index-afc4a1e5.js} +2 -2
  102. package/es/{index-7eb88616.cjs → index-cfcd60ca.cjs} +1 -1
  103. package/es/{index-5b546f7d.cjs → index-d2cfd4a3.cjs} +1 -1
  104. package/es/{index-7db02db7.js → index-d3e9a6f2.js} +2 -2
  105. package/es/{python-86a0735f.js → python-c00abcbd.js} +18 -18
  106. package/es/{python-18d44a7b.cjs → python-e528f42b.cjs} +1 -1
  107. package/es/style.css +1 -1
  108. package/es/{use-form-common-props-00ec25ac.cjs → use-form-common-props-02be4928.cjs} +1 -1
  109. package/es/{use-form-common-props-c14990b9.js → use-form-common-props-dd9617de.js} +12 -12
  110. package/es/{use-global-config-28efb416.cjs → use-global-config-31b3ec57.cjs} +1 -1
  111. package/es/{use-global-config-a01b5ce1.js → use-global-config-4dfc7236.js} +2 -2
  112. package/es/{validator-65de1caf.js → validator-029bfc98.js} +1 -1
  113. package/es/{validator-119fdaf4.cjs → validator-ea292506.cjs} +1 -1
  114. package/es/{zh-cn-9fb29a39.cjs → zh-cn-0edc7234.cjs} +1 -1
  115. package/es/{zh-cn-c1c28e70.js → zh-cn-89e434f9.js} +1 -1
  116. package/lib/aiTools.js +121 -27
  117. package/lib/bundle.js +1 -1
  118. package/lib/bundle.umd.cjs +217 -212
  119. package/lib/{index-8edd5697.js → index-8ba1607b.js} +22647 -22455
  120. package/lib/{python-5c07749c.js → python-16c6e601.js} +1 -1
  121. package/lib/style.css +1 -1
  122. package/package.json +1 -1
  123. package/packages/VarietyAiHelper/index.vue +326 -292
  124. package/public/aiTools.js +121 -27
  125. package/src/App.vue +14 -0
  126. package/es/aiTools-822859d6.cjs +0 -4
  127. package/es/aiTools-9a9c997f.js +0 -149
  128. package/es/index-3792552a.cjs +0 -1
@@ -2,8 +2,8 @@
2
2
  import dayjs from "dayjs";
3
3
  import { ElMessage } from "element-plus";
4
4
  import { getUserData, getToken } from "st-func";
5
- import { inject, ref, nextTick, watch, reactive, onMounted } from "vue";
6
- import { sendToBaiLianWorkflowStreaming } from "../../public/aiTools";
5
+ import { inject, ref, nextTick, watch, reactive, computed } from "vue";
6
+ import { sendToNodeVarietyAiHelper } from "../../public/aiTools";
7
7
  import { UserFilled, Service, Promotion, Refresh, SuccessFilled } from "@element-plus/icons-vue";
8
8
 
9
9
  // ==================== 基础配置 ====================
@@ -20,12 +20,10 @@ const props = defineProps({
20
20
  });
21
21
 
22
22
  // ==================== 响应式数据 ====================
23
- const isSending = ref(false); // 是否正在发送消息
24
- const isThinking = ref(false); // AI是否正在思考(首包到达前)
25
- const nodeProgressList = ref([]); // 工作流节点执行进度列表
26
- const showFinalResult = ref(false); // 是否展示最终结果
27
-
28
- // ==================== 消息队列 ====================
23
+ const isSending = ref(false);
24
+ const isThinking = ref(false);
25
+ const nodeProgressList = ref([]);
26
+ const showFinalResult = ref(false);
29
27
  const messageListRef = ref(null);
30
28
  const messageList = ref([
31
29
  {
@@ -40,16 +38,21 @@ const messageList = ref([
40
38
  },
41
39
  ]);
42
40
 
43
- const userInput = ref(""); // 用户输入内容
44
-
45
- // ==================== 反馈弹窗 ====================
41
+ const userInput = ref("");
46
42
  const feedbackDialogVisible = ref(false);
47
43
  const feedbackContent = ref("");
48
44
  const feedbackMessageIndex = ref({});
49
45
 
50
- // ==================== 工具函数 ====================
46
+ // ==================== 计算属性 ====================
47
+ const completedCount = computed(() => nodeProgressList.value.filter((n) => n.status === "success").length);
48
+ const totalCount = computed(() => nodeProgressList.value.length);
49
+ const progressPercent = computed(() => (totalCount.value ? (completedCount.value / totalCount.value) * 100 : 0));
50
+ const currentStepName = computed(() => {
51
+ const running = nodeProgressList.value.find((n) => n.status === "executing");
52
+ return running ? running.name : "处理中";
53
+ });
51
54
 
52
- // 判断字符串是否可解析为 JSON 对象
55
+ // ==================== 工具函数 ====================
53
56
  const isJSONSerializable = (str) => {
54
57
  if (typeof str !== "string") return false;
55
58
  try {
@@ -60,7 +63,6 @@ const isJSONSerializable = (str) => {
60
63
  }
61
64
  };
62
65
 
63
- // 将 JSON 字符串解析为展示数据(parsedConditions + 其他参数)
64
66
  const formatJSONContent = (content) => {
65
67
  if (!isJSONSerializable(content)) return null;
66
68
  try {
@@ -72,7 +74,6 @@ const formatJSONContent = (content) => {
72
74
  }
73
75
  };
74
76
 
75
- // 将解析后的数据渲染为 HTML 字符串
76
77
  const renderJSONContent = (jsonData) => {
77
78
  if (!jsonData) return "";
78
79
  let html = "";
@@ -87,8 +88,6 @@ const renderJSONContent = (jsonData) => {
87
88
  };
88
89
 
89
90
  // ==================== 反馈处理 ====================
90
-
91
- // 处理用户反馈操作(满意 / 不满意 / 默认记录)
92
91
  const handleFeedbackAction = async (action, messageIndex) => {
93
92
  switch (action) {
94
93
  case "satisfied": {
@@ -151,20 +150,14 @@ const handleFeedbackAction = async (action, messageIndex) => {
151
150
  };
152
151
 
153
152
  // ==================== 消息发送 ====================
154
-
155
- // ==================== 消息发送 ====================
156
-
157
- // 发送消息到工作流
158
153
  const sendMessage = async () => {
159
154
  const content = userInput.value.trim();
160
155
  if (!content) return ElMessage.warning("请输入消息内容");
161
156
  if (isSending.value) return;
162
157
 
163
- // 重置状态
164
158
  nodeProgressList.value = [];
165
159
  showFinalResult.value = false;
166
160
 
167
- // 添加用户消息
168
161
  messageList.value.push({
169
162
  role: "user",
170
163
  content: content,
@@ -173,7 +166,6 @@ const sendMessage = async () => {
173
166
  userInput.value = "";
174
167
  await scrollToBottom();
175
168
 
176
- // 添加 AI 占位消息
177
169
  messageList.value.push({
178
170
  role: "assistant",
179
171
  content: "",
@@ -191,19 +183,14 @@ const sendMessage = async () => {
191
183
 
192
184
  let fullResponse = "";
193
185
  let resTime = new Date().getTime();
194
- let firstNodeReceived = false; // 标记是否已收到首个节点推送
186
+ let firstNodeReceived = false;
195
187
 
196
188
  try {
197
- const appId = "1977602b357e4dab9d0b74899d5323b3";
198
- const apiKey = "sk-d995eb26a4334bdeb2ccb4cbfaf51de8";
199
- await sendToBaiLianWorkflowStreaming({
200
- mode: stConfig.env.MODE,
201
- appId,
202
- apiKey,
189
+ await sendToNodeVarietyAiHelper({
190
+ baseUrl: stConfig.env.VITE_BASE_URL,
203
191
  token: getToken(),
204
192
  value: content,
205
193
  callback: (type, data) => {
206
- // 工作流返回错误
207
194
  if (type === "error") {
208
195
  isThinking.value = false;
209
196
  isSending.value = false;
@@ -223,11 +210,10 @@ const sendMessage = async () => {
223
210
  return;
224
211
  }
225
212
 
226
- // 节点执行进度更新
227
213
  if (type === "node") {
228
- // 首个节点推送时记录首包响应时间
229
214
  if (!firstNodeReceived) {
230
215
  firstNodeReceived = true;
216
+ isThinking.value = false;
231
217
  const lastMessage = messageList.value[messageList.value.length - 1];
232
218
  if (lastMessage && lastMessage.role === "assistant" && lastMessage.firstPackageTime === 0) {
233
219
  lastMessage.firstPackageTime = new Date().getTime() - resTime;
@@ -244,7 +230,6 @@ const sendMessage = async () => {
244
230
  return;
245
231
  }
246
232
 
247
- // 最终结果(工作流结束时一次性推送)
248
233
  if (type === "message") {
249
234
  fullResponse = data;
250
235
  const lastMessage = messageList.value[messageList.value.length - 1];
@@ -254,9 +239,7 @@ const sendMessage = async () => {
254
239
  }
255
240
  }
256
241
 
257
- // 流式结束,展示反馈按钮并触发回调
258
242
  if (type === "finish") {
259
- isThinking.value = false;
260
243
  isSending.value = false;
261
244
  showFinalResult.value = true;
262
245
  const lastMessage = messageList.value[messageList.value.length - 1];
@@ -267,7 +250,6 @@ const sendMessage = async () => {
267
250
  handleFeedbackAction("default", messageList.value.length - 1);
268
251
  }
269
252
 
270
- // 解析最终结果并回调父组件
271
253
  try {
272
254
  const jsonResponse = JSON.parse(fullResponse);
273
255
  if (jsonResponse.parsedConditions) {
@@ -281,7 +263,6 @@ const sendMessage = async () => {
281
263
  },
282
264
  });
283
265
  } catch (error) {
284
- // 网络异常处理
285
266
  ElMessage.error(`AI响应异常: ${error}`);
286
267
  messageList.value.pop();
287
268
  messageList.value.push({
@@ -302,8 +283,6 @@ const sendMessage = async () => {
302
283
  };
303
284
 
304
285
  // ==================== 键盘事件 ====================
305
-
306
- // Enter 发送,Ctrl+Enter 换行
307
286
  const handleKeydown = (event) => {
308
287
  if (event.key === "Enter") {
309
288
  if (event.ctrlKey) {
@@ -323,8 +302,6 @@ const handleKeydown = (event) => {
323
302
  };
324
303
 
325
304
  // ==================== 滚动 & 初始化 ====================
326
-
327
- // 自动滚动到消息列表底部
328
305
  const scrollToBottom = async () => {
329
306
  await nextTick();
330
307
  if (messageListRef.value) {
@@ -332,7 +309,6 @@ const scrollToBottom = async () => {
332
309
  }
333
310
  };
334
311
 
335
- // 监听消息队列变化,自动滚动
336
312
  watch(
337
313
  () => messageList.value,
338
314
  () => {
@@ -341,7 +317,6 @@ watch(
341
317
  { deep: true },
342
318
  );
343
319
 
344
- // 关闭反馈弹窗时清空内容
345
320
  watch(
346
321
  () => feedbackDialogVisible.value,
347
322
  (newValue) => {
@@ -349,7 +324,6 @@ watch(
349
324
  },
350
325
  );
351
326
 
352
- // 暴露 open 方法供父组件调用
353
327
  defineExpose({
354
328
  open: () => {
355
329
  visible.value = true;
@@ -361,7 +335,6 @@ defineExpose({
361
335
  </script>
362
336
 
363
337
  <template>
364
- <!-- ==================== 主对话框 ==================== -->
365
338
  <el-dialog
366
339
  class="ai-dialog"
367
340
  v-model="visible"
@@ -374,7 +347,6 @@ defineExpose({
374
347
  :modal-penetrable="true"
375
348
  >
376
349
  <div class="ai-dialog-body">
377
- <!-- 消息列表 -->
378
350
  <div
379
351
  ref="messageListRef"
380
352
  class="message-list"
@@ -385,9 +357,7 @@ defineExpose({
385
357
  :class="message.role"
386
358
  class="message-item"
387
359
  >
388
- <!-- 有内容 或 是最后一条AI消息且有节点进度时,渲染消息气泡 -->
389
360
  <template v-if="message.content || (index === messageList.length - 1 && message.role === 'assistant' && nodeProgressList.length > 0)">
390
- <!-- 头像 -->
391
361
  <div class="avatar">
392
362
  <el-avatar
393
363
  :size="32"
@@ -396,12 +366,10 @@ defineExpose({
396
366
  </div>
397
367
 
398
368
  <div class="message-content">
399
- <!-- 节点执行进度(仅最新AI消息 & 未完成时展示) -->
400
369
  <div
401
370
  v-if="index === messageList.length - 1 && message.role === 'assistant' && nodeProgressList.length > 0 && !showFinalResult"
402
371
  class="node-progress"
403
372
  >
404
- <!-- 已完成/执行中节点 -->
405
373
  <div
406
374
  v-for="node in nodeProgressList"
407
375
  :key="node.name"
@@ -421,25 +389,24 @@ defineExpose({
421
389
  </span>
422
390
  <span class="node-name">{{ node.name }}</span>
423
391
  </div>
424
- <!-- 所有节点完成,等待下一步 -->
425
- <div
426
- v-if="nodeProgressList.length > 0 && nodeProgressList.every((n) => n.status === 'success') && !showFinalResult"
427
- class="node-progress-item next-step"
428
- >
429
- <span class="node-status-icon">
430
- <el-icon class="node-icon waiting"><Refresh /></el-icon>
431
- </span>
432
- <span class="node-name">正在执行下一步...</span>
392
+
393
+ <div class="progress-footer">
394
+ <el-progress
395
+ :percentage="progressPercent"
396
+ :show-text="false"
397
+ :stroke-width="4"
398
+ color="#667eea"
399
+ />
400
+ <span class="progress-text">第 {{ completedCount }}/{{ totalCount }} 步 · {{ currentStepName }}</span>
433
401
  </div>
434
402
  </div>
435
403
 
436
- <!-- JSON 结果渲染 -->
437
404
  <div
438
405
  v-if="isJSONSerializable(message.content)"
439
406
  class="message-json"
440
407
  v-html="renderJSONContent(formatJSONContent(message.content))"
441
408
  ></div>
442
- <!-- 普通文本 -->
409
+
443
410
  <div
444
411
  v-else-if="message.content"
445
412
  class="message-text"
@@ -447,10 +414,8 @@ defineExpose({
447
414
  {{ message.content }}
448
415
  </div>
449
416
 
450
- <!-- 消息时间 -->
451
417
  <div class="message-createTime">{{ message.createTime }}</div>
452
418
 
453
- <!-- 反馈按钮(仅AI消息) -->
454
419
  <template v-if="message.role === 'assistant'">
455
420
  <template v-if="message.showFeedback && !message.hasFeedback">
456
421
  <div class="message-createTime">请问对本轮查询结果是否满意?</div>
@@ -479,28 +444,14 @@ defineExpose({
479
444
  </template>
480
445
  </div>
481
446
 
482
- <!-- 首包响应前的思考动画 -->
483
447
  <div
484
448
  v-if="isThinking && nodeProgressList.length === 0 && !messageList[messageList.length - 1]?.content"
485
- class="message-item assistant"
449
+ class="thinking-placeholder"
486
450
  >
487
- <div class="avatar">
488
- <el-avatar
489
- :size="32"
490
- :icon="Service"
491
- />
492
- </div>
493
- <div class="message-content">
494
- <div class="typing-indicator">
495
- <span></span>
496
- <span></span>
497
- <span></span>
498
- </div>
499
- </div>
451
+ 🤔 正在分析您的需求...
500
452
  </div>
501
453
  </div>
502
454
 
503
- <!-- 输入区域 -->
504
455
  <div class="input-area">
505
456
  <el-input
506
457
  class="message-input"
@@ -530,7 +481,6 @@ defineExpose({
530
481
  </div>
531
482
  </el-dialog>
532
483
 
533
- <!-- ==================== 反馈弹窗 ==================== -->
534
484
  <el-dialog
535
485
  v-model="feedbackDialogVisible"
536
486
  title="📝 反馈意见"
@@ -567,13 +517,11 @@ defineExpose({
567
517
  height: 480px;
568
518
  background: transparent;
569
519
 
570
- // ========== 消息列表 ==========
571
520
  .message-list {
572
521
  flex: 1;
573
522
  overflow-y: auto;
574
523
  padding: 20px 24px;
575
524
 
576
- // 滚动条
577
525
  &::-webkit-scrollbar {
578
526
  width: 6px;
579
527
  }
@@ -589,12 +537,24 @@ defineExpose({
589
537
  }
590
538
  }
591
539
 
592
- // 单条消息
593
540
  .message-item {
594
541
  display: flex;
595
542
  animation: fadeInUp 0.3s ease-out;
596
543
  margin-bottom: 20px;
597
544
 
545
+ &:nth-child(1) {
546
+ animation-delay: 0.05s;
547
+ }
548
+ &:nth-child(2) {
549
+ animation-delay: 0.1s;
550
+ }
551
+ &:nth-child(3) {
552
+ animation-delay: 0.15s;
553
+ }
554
+ &:nth-child(4) {
555
+ animation-delay: 0.2s;
556
+ }
557
+
598
558
  .avatar {
599
559
  flex-shrink: 0;
600
560
  :deep(.el-avatar) {
@@ -611,138 +571,9 @@ defineExpose({
611
571
  display: flex;
612
572
  flex-direction: column;
613
573
  max-width: 70%;
614
-
615
- // 节点进度卡片
616
- .node-progress {
617
- padding: 12px 16px;
618
- border-radius: 12px;
619
- margin-bottom: 8px;
620
- border: 1px solid rgba(102, 126, 234, 0.1);
621
-
622
- .node-progress-item {
623
- display: flex;
624
- align-items: center;
625
- gap: 8px;
626
- padding: 4px 0;
627
- font-size: 13px;
628
- color: #6b7280;
629
-
630
- .node-status-icon {
631
- display: flex;
632
- align-items: center;
633
- justify-content: center;
634
- width: 18px;
635
- flex-shrink: 0;
636
- }
637
-
638
- .node-icon {
639
- font-size: 16px;
640
- &.done {
641
- color: #22c55e;
642
- } // 完成:绿色
643
- &.running {
644
- color: #667eea;
645
- animation: spin 1.2s linear infinite;
646
- } // 执行中:旋转
647
- &.waiting {
648
- color: #d1d5db;
649
- animation: spin 1.2s linear infinite;
650
- } // 等待中:灰色旋转
651
- }
652
-
653
- .node-name {
654
- white-space: nowrap;
655
- overflow: hidden;
656
- text-overflow: ellipsis;
657
- }
658
- }
659
-
660
- .next-step .node-name {
661
- color: #9ca3af;
662
- }
663
- }
664
-
665
- .message-json,
666
- .message-text {
667
- padding: 10px 16px;
668
- font-size: 14px;
669
- line-height: 1.5;
670
- word-wrap: break-word;
671
- white-space: pre-wrap;
672
- }
673
-
674
- .message-createTime {
675
- font-size: 11px;
676
- color: #9ca3af;
677
- margin-top: 6px;
678
- }
679
-
680
- // 反馈按钮
681
- .feedback-buttons {
682
- display: flex;
683
- gap: 12px;
684
- margin-top: 12px;
685
-
686
- .feedback-btn {
687
- display: flex;
688
- align-items: center;
689
- gap: 6px;
690
- padding: 4px 10px;
691
- border: none;
692
- border-radius: 20px;
693
- font-size: 13px;
694
- font-weight: 500;
695
- cursor: pointer;
696
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
697
- background: rgba(255, 255, 255, 0.9);
698
- backdrop-filter: blur(10px);
699
-
700
- .btn-emoji {
701
- font-size: 16px;
702
- transition: transform 0.2s ease;
703
- }
704
- .btn-text {
705
- font-size: 13px;
706
- }
707
- &:hover {
708
- transform: translateY(-2px);
709
- .btn-emoji {
710
- transform: scale(1.1);
711
- }
712
- }
713
- &:active {
714
- transform: translateY(0);
715
- }
716
- }
717
-
718
- .satisfied-btn {
719
- background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
720
- color: #1890ff;
721
- border: 1px solid rgba(24, 144, 255, 0.2);
722
- box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
723
- &:hover {
724
- background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
725
- border-color: #1890ff;
726
- box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
727
- }
728
- }
729
-
730
- .unsatisfied-btn {
731
- background: linear-gradient(135deg, #fff1f0 0%, #ffe7e5 100%);
732
- color: #ff4d4f;
733
- border: 1px solid rgba(255, 77, 79, 0.2);
734
- box-shadow: 0 2px 8px rgba(255, 77, 79, 0.1);
735
- &:hover {
736
- background: linear-gradient(135deg, #ffe7e5 0%, #ffccc7 100%);
737
- border-color: #ff4d4f;
738
- box-shadow: 0 4px 12px rgba(255, 77, 79, 0.2);
739
- }
740
- }
741
- }
742
574
  }
743
575
  }
744
576
 
745
- // 用户消息靠右
746
577
  .user {
747
578
  flex-direction: row-reverse;
748
579
  .avatar {
@@ -762,42 +593,240 @@ defineExpose({
762
593
  }
763
594
  }
764
595
 
765
- // AI消息靠左
766
596
  .assistant {
767
597
  .avatar {
768
598
  margin-right: 12px;
769
599
  }
770
600
  .message-content {
771
601
  align-items: flex-start;
772
- .message-text {
773
- border-radius: 18px 18px 18px 4px;
774
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
775
- border: 1px solid rgba(102, 126, 234, 0.2);
602
+ }
603
+ }
604
+ }
605
+
606
+ .node-progress {
607
+ background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
608
+ border: 1px solid rgba(102, 126, 234, 0.15);
609
+ border-radius: 16px;
610
+ padding: 12px 16px;
611
+ margin-bottom: 8px;
612
+ min-width: 200px;
613
+ animation: breathe 2s ease-in-out infinite;
614
+
615
+ .node-progress-item {
616
+ display: flex;
617
+ align-items: center;
618
+ gap: 10px;
619
+ padding: 6px 0;
620
+ position: relative;
621
+ animation: slideIn 0.3s ease-out;
622
+
623
+ &:not(:last-child)::after {
624
+ content: "";
625
+ position: absolute;
626
+ left: 9px;
627
+ top: 28px;
628
+ width: 2px;
629
+ height: calc(100% - 8px);
630
+ background: linear-gradient(to bottom, #c7d2fe, transparent);
631
+ }
632
+
633
+ .node-status-icon {
634
+ position: relative;
635
+ z-index: 1;
636
+ background: white;
637
+ border-radius: 50%;
638
+ width: 20px;
639
+ height: 20px;
640
+ display: inline-flex;
641
+ align-items: center;
642
+ justify-content: center;
643
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
644
+ }
645
+
646
+ .node-icon {
647
+ font-size: 12px;
648
+ &.done {
649
+ color: #22c55e;
776
650
  }
777
- .message-json {
778
- width: 100%;
779
- border-radius: 18px 18px 18px 4px;
780
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
781
- border: 1px solid rgba(102, 126, 234, 0.2);
782
-
783
- // 解析条件高亮卡片
784
- :deep(.parsed-conditions) {
785
- margin-top: 10px;
786
- .parsed-conditions-item {
787
- text-align: center;
788
- color: #f56c6c;
789
- margin-bottom: 10px;
790
- padding: 2px;
791
- background-color: rgb(253, 226, 226);
792
- border-radius: 4px;
793
- }
794
- }
651
+ &.running {
652
+ color: #667eea;
653
+ animation: spin 0.6s linear infinite;
654
+ }
655
+ &.waiting {
656
+ color: #d1d5db;
657
+ animation: spin 0.8s linear infinite;
658
+ }
659
+ }
660
+
661
+ .node-name {
662
+ font-size: 13px;
663
+ color: #6b7280;
664
+ line-height: 20px;
665
+ }
666
+
667
+ &:has(.running) .node-name {
668
+ font-weight: 500;
669
+ color: #667eea;
670
+ }
671
+ }
672
+
673
+ .progress-footer {
674
+ margin-top: 12px;
675
+ padding-top: 8px;
676
+ border-top: 1px solid rgba(102, 126, 234, 0.1);
677
+
678
+ :deep(.el-progress) {
679
+ margin-bottom: 6px;
680
+ }
681
+
682
+ .progress-text {
683
+ font-size: 11px;
684
+ color: #9ca3af;
685
+ display: block;
686
+ text-align: center;
687
+ }
688
+ }
689
+ }
690
+
691
+ .thinking-placeholder {
692
+ display: inline-flex;
693
+ align-items: center;
694
+ gap: 8px;
695
+ padding: 10px 16px;
696
+ background: rgba(102, 126, 234, 0.08);
697
+ border-radius: 18px;
698
+ font-size: 13px;
699
+ color: #667eea;
700
+ width: fit-content;
701
+
702
+ &::before {
703
+ content: "";
704
+ width: 14px;
705
+ height: 14px;
706
+ border: 2px solid #667eea;
707
+ border-top-color: transparent;
708
+ border-radius: 50%;
709
+ animation: spin 0.8s linear infinite;
710
+ }
711
+ }
712
+
713
+ .message-json,
714
+ .message-text {
715
+ padding: 12px 16px;
716
+ font-size: 14px;
717
+ line-height: 1.6;
718
+ word-wrap: break-word;
719
+ white-space: pre-wrap;
720
+ border-radius: 18px 18px 18px 4px;
721
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
722
+ border: 1px solid rgba(102, 126, 234, 0.2);
723
+ background: white;
724
+ transition: all 0.3s ease;
725
+ }
726
+
727
+ .message-text {
728
+ animation: messageAppear 0.3s ease-out;
729
+ }
730
+
731
+ .message-json {
732
+ width: 100%;
733
+ overflow: hidden;
734
+ animation: resultAppear 0.5s cubic-bezier(0.2, 0.9, 0.4, 1.1);
735
+
736
+ :deep(.parsed-conditions) {
737
+ margin: 0;
738
+ padding: 0;
739
+
740
+ .parsed-conditions-item {
741
+ text-align: center;
742
+ color: #f56c6c;
743
+ margin-bottom: 8px;
744
+ padding: 8px 12px;
745
+ background: linear-gradient(135deg, #fff5f5 0%, #ffebeb 100%);
746
+ border-radius: 12px;
747
+ font-weight: 500;
748
+ transition: all 0.2s ease;
749
+
750
+ &:hover {
751
+ transform: translateX(4px);
752
+ background: linear-gradient(135deg, #ffebeb 0%, #ffe0e0 100%);
753
+ }
754
+
755
+ &:last-child {
756
+ margin-bottom: 0;
795
757
  }
796
758
  }
797
759
  }
798
760
  }
799
761
 
800
- // ========== 输入区域 ==========
762
+ .message-createTime {
763
+ font-size: 11px;
764
+ color: #9ca3af;
765
+ margin-top: 6px;
766
+ }
767
+
768
+ .feedback-buttons {
769
+ display: flex;
770
+ gap: 12px;
771
+ margin-top: 12px;
772
+
773
+ .feedback-btn {
774
+ display: flex;
775
+ align-items: center;
776
+ gap: 6px;
777
+ padding: 4px 10px;
778
+ border: none;
779
+ border-radius: 20px;
780
+ font-size: 13px;
781
+ font-weight: 500;
782
+ cursor: pointer;
783
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
784
+ background: rgba(255, 255, 255, 0.9);
785
+ backdrop-filter: blur(10px);
786
+
787
+ .btn-emoji {
788
+ font-size: 16px;
789
+ transition: transform 0.2s ease;
790
+ }
791
+ .btn-text {
792
+ font-size: 13px;
793
+ }
794
+ &:hover {
795
+ transform: translateY(-2px);
796
+ .btn-emoji {
797
+ transform: scale(1.1);
798
+ }
799
+ }
800
+ &:active {
801
+ transform: translateY(0);
802
+ }
803
+ }
804
+
805
+ .satisfied-btn {
806
+ background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
807
+ color: #1890ff;
808
+ border: 1px solid rgba(24, 144, 255, 0.2);
809
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
810
+ &:hover {
811
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
812
+ border-color: #1890ff;
813
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
814
+ }
815
+ }
816
+
817
+ .unsatisfied-btn {
818
+ background: linear-gradient(135deg, #fff1f0 0%, #ffe7e5 100%);
819
+ color: #ff4d4f;
820
+ border: 1px solid rgba(255, 77, 79, 0.2);
821
+ box-shadow: 0 2px 8px rgba(255, 77, 79, 0.1);
822
+ &:hover {
823
+ background: linear-gradient(135deg, #ffe7e5 0%, #ffccc7 100%);
824
+ border-color: #ff4d4f;
825
+ box-shadow: 0 4px 12px rgba(255, 77, 79, 0.2);
826
+ }
827
+ }
828
+ }
829
+
801
830
  .input-area {
802
831
  padding: 16px 24px 24px;
803
832
  backdrop-filter: blur(10px);
@@ -846,32 +875,68 @@ defineExpose({
846
875
  }
847
876
  }
848
877
 
849
- // ========== 思考动画(三个跳动点) ==========
850
- .typing-indicator {
851
- display: flex;
852
- gap: 4px;
853
- padding: 10px 16px;
854
- background: white;
855
- border-radius: 18px;
856
- border: 1px solid rgba(102, 126, 234, 0.1);
857
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
858
-
859
- span {
860
- width: 6px;
861
- height: 6px;
862
- border-radius: 50%;
863
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
864
- animation: typing 1.4s infinite ease-in-out;
865
- &:nth-child(1) {
866
- animation-delay: -0.32s;
867
- }
868
- &:nth-child(2) {
869
- animation-delay: -0.16s;
870
- }
878
+ @keyframes fadeInUp {
879
+ from {
880
+ opacity: 0;
881
+ transform: translateY(10px);
882
+ }
883
+ to {
884
+ opacity: 1;
885
+ transform: translateY(0);
886
+ }
887
+ }
888
+
889
+ @keyframes slideIn {
890
+ from {
891
+ opacity: 0;
892
+ transform: translateX(-8px);
893
+ }
894
+ to {
895
+ opacity: 1;
896
+ transform: translateX(0);
897
+ }
898
+ }
899
+
900
+ @keyframes spin {
901
+ to {
902
+ transform: rotate(360deg);
903
+ }
904
+ }
905
+
906
+ @keyframes breathe {
907
+ 0%,
908
+ 100% {
909
+ border-color: rgba(102, 126, 234, 0.15);
910
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.05);
911
+ }
912
+ 50% {
913
+ border-color: rgba(102, 126, 234, 0.35);
914
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.12);
915
+ }
916
+ }
917
+
918
+ @keyframes messageAppear {
919
+ from {
920
+ opacity: 0;
921
+ transform: translateY(8px);
922
+ }
923
+ to {
924
+ opacity: 1;
925
+ transform: translateY(0);
926
+ }
927
+ }
928
+
929
+ @keyframes resultAppear {
930
+ 0% {
931
+ opacity: 0;
932
+ transform: scale(0.95);
933
+ }
934
+ 100% {
935
+ opacity: 1;
936
+ transform: scale(1);
871
937
  }
872
938
  }
873
939
 
874
- // ========== 反馈弹窗 ==========
875
940
  .feedback-dialog-content {
876
941
  text-align: center;
877
942
  padding: 12px 0;
@@ -899,31 +964,6 @@ defineExpose({
899
964
  }
900
965
  }
901
966
 
902
- // ========== 动画关键帧 ==========
903
- @keyframes fadeInUp {
904
- from {
905
- opacity: 0;
906
- transform: translateY(10px);
907
- }
908
- to {
909
- opacity: 1;
910
- transform: translateY(0);
911
- }
912
- }
913
-
914
- @keyframes typing {
915
- 0%,
916
- 60%,
917
- 100% {
918
- transform: translateY(0);
919
- opacity: 0.4;
920
- }
921
- 30% {
922
- transform: translateY(-8px);
923
- opacity: 1;
924
- }
925
- }
926
-
927
967
  @keyframes shake {
928
968
  0%,
929
969
  100% {
@@ -936,10 +976,4 @@ defineExpose({
936
976
  transform: translateX(5px);
937
977
  }
938
978
  }
939
-
940
- @keyframes spin {
941
- to {
942
- transform: rotate(360deg);
943
- }
944
- }
945
979
  </style>