st-comp 0.0.268 → 0.0.270

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 +487 -309
  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-2dd72fda.js} +22650 -22458
  120. package/lib/{python-5c07749c.js → python-126b61c5.js} +1 -1
  121. package/lib/style.css +1 -1
  122. package/package.json +1 -1
  123. package/packages/VarietyAiHelper/index.vue +284 -293
  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,36 +389,35 @@ 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"
407
+ :class="{ 'result-animation': index === messageList.length - 1 && showFinalResult }"
440
408
  v-html="renderJSONContent(formatJSONContent(message.content))"
441
409
  ></div>
442
- <!-- 普通文本 -->
410
+
443
411
  <div
444
412
  v-else-if="message.content"
445
413
  class="message-text"
414
+ :class="{ 'result-animation': index === messageList.length - 1 && showFinalResult }"
446
415
  >
447
416
  {{ message.content }}
448
417
  </div>
449
418
 
450
- <!-- 消息时间 -->
451
419
  <div class="message-createTime">{{ message.createTime }}</div>
452
420
 
453
- <!-- 反馈按钮(仅AI消息) -->
454
421
  <template v-if="message.role === 'assistant'">
455
422
  <template v-if="message.showFeedback && !message.hasFeedback">
456
423
  <div class="message-createTime">请问对本轮查询结果是否满意?</div>
@@ -479,28 +446,14 @@ defineExpose({
479
446
  </template>
480
447
  </div>
481
448
 
482
- <!-- 首包响应前的思考动画 -->
483
449
  <div
484
450
  v-if="isThinking && nodeProgressList.length === 0 && !messageList[messageList.length - 1]?.content"
485
- class="message-item assistant"
451
+ class="thinking-placeholder"
486
452
  >
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>
453
+ 🤔 正在分析您的需求...
500
454
  </div>
501
455
  </div>
502
456
 
503
- <!-- 输入区域 -->
504
457
  <div class="input-area">
505
458
  <el-input
506
459
  class="message-input"
@@ -530,7 +483,6 @@ defineExpose({
530
483
  </div>
531
484
  </el-dialog>
532
485
 
533
- <!-- ==================== 反馈弹窗 ==================== -->
534
486
  <el-dialog
535
487
  v-model="feedbackDialogVisible"
536
488
  title="📝 反馈意见"
@@ -567,13 +519,11 @@ defineExpose({
567
519
  height: 480px;
568
520
  background: transparent;
569
521
 
570
- // ========== 消息列表 ==========
571
522
  .message-list {
572
523
  flex: 1;
573
524
  overflow-y: auto;
574
525
  padding: 20px 24px;
575
526
 
576
- // 滚动条
577
527
  &::-webkit-scrollbar {
578
528
  width: 6px;
579
529
  }
@@ -589,10 +539,8 @@ defineExpose({
589
539
  }
590
540
  }
591
541
 
592
- // 单条消息
593
542
  .message-item {
594
543
  display: flex;
595
- animation: fadeInUp 0.3s ease-out;
596
544
  margin-bottom: 20px;
597
545
 
598
546
  .avatar {
@@ -611,138 +559,9 @@ defineExpose({
611
559
  display: flex;
612
560
  flex-direction: column;
613
561
  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
562
  }
743
563
  }
744
564
 
745
- // 用户消息靠右
746
565
  .user {
747
566
  flex-direction: row-reverse;
748
567
  .avatar {
@@ -762,42 +581,231 @@ defineExpose({
762
581
  }
763
582
  }
764
583
 
765
- // AI消息靠左
766
584
  .assistant {
767
585
  .avatar {
768
586
  margin-right: 12px;
769
587
  }
770
588
  .message-content {
771
589
  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);
590
+ }
591
+ }
592
+ }
593
+
594
+ .node-progress {
595
+ background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
596
+ border: 1px solid rgba(102, 126, 234, 0.15);
597
+ border-radius: 16px;
598
+ padding: 12px 16px;
599
+ margin-bottom: 8px;
600
+ min-width: 200px;
601
+ animation: breathe 2s ease-in-out infinite;
602
+
603
+ .node-progress-item {
604
+ display: flex;
605
+ align-items: center;
606
+ gap: 10px;
607
+ padding: 6px 0;
608
+ position: relative;
609
+ animation: slideIn 0.3s ease-out;
610
+
611
+ &:not(:last-child)::after {
612
+ content: "";
613
+ position: absolute;
614
+ left: 9px;
615
+ top: 28px;
616
+ width: 2px;
617
+ height: calc(100% - 8px);
618
+ background: linear-gradient(to bottom, #c7d2fe, transparent);
619
+ }
620
+
621
+ .node-status-icon {
622
+ position: relative;
623
+ z-index: 1;
624
+ border-radius: 50%;
625
+ width: 20px;
626
+ height: 20px;
627
+ display: inline-flex;
628
+ align-items: center;
629
+ justify-content: center;
630
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
631
+ }
632
+
633
+ .node-icon {
634
+ font-size: 12px;
635
+ &.done {
636
+ color: #22c55e;
776
637
  }
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
- }
638
+ &.running {
639
+ color: #667eea;
640
+ animation: spin 0.6s linear infinite;
641
+ }
642
+ &.waiting {
643
+ color: #d1d5db;
644
+ animation: spin 0.8s linear infinite;
645
+ }
646
+ }
647
+
648
+ .node-name {
649
+ font-size: 13px;
650
+ color: #6b7280;
651
+ line-height: 20px;
652
+ }
653
+
654
+ &:has(.running) .node-name {
655
+ font-weight: 500;
656
+ color: #667eea;
657
+ }
658
+ }
659
+
660
+ .progress-footer {
661
+ margin-top: 12px;
662
+ padding-top: 8px;
663
+ border-top: 1px solid rgba(102, 126, 234, 0.1);
664
+
665
+ :deep(.el-progress) {
666
+ margin-bottom: 6px;
667
+ }
668
+
669
+ .progress-text {
670
+ font-size: 11px;
671
+ color: #9ca3af;
672
+ display: block;
673
+ text-align: center;
674
+ }
675
+ }
676
+ }
677
+
678
+ .thinking-placeholder {
679
+ display: inline-flex;
680
+ align-items: center;
681
+ gap: 8px;
682
+ padding: 10px 16px;
683
+ background: rgba(102, 126, 234, 0.08);
684
+ border-radius: 18px;
685
+ font-size: 13px;
686
+ color: #667eea;
687
+ width: fit-content;
688
+
689
+ &::before {
690
+ content: "";
691
+ width: 14px;
692
+ height: 14px;
693
+ border: 2px solid #667eea;
694
+ border-top-color: transparent;
695
+ border-radius: 50%;
696
+ animation: spin 0.8s linear infinite;
697
+ }
698
+ }
699
+
700
+ .message-json,
701
+ .message-text {
702
+ padding: 12px 16px;
703
+ font-size: 14px;
704
+ line-height: 1.6;
705
+ word-wrap: break-word;
706
+ white-space: pre-wrap;
707
+ border-radius: 18px 18px 18px 4px;
708
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
709
+ border: 1px solid rgba(102, 126, 234, 0.2);
710
+ transition: all 0.3s ease;
711
+ }
712
+
713
+ .message-json {
714
+ width: 100%;
715
+ overflow: hidden;
716
+
717
+ :deep(.parsed-conditions) {
718
+ margin: 0;
719
+ padding: 0;
720
+
721
+ .parsed-conditions-item {
722
+ text-align: center;
723
+ color: #f56c6c;
724
+ margin-bottom: 8px;
725
+ padding: 8px 12px;
726
+ background: linear-gradient(135deg, #ffebeb 0%, #ffe0e0 100%);
727
+ border-radius: 12px;
728
+ font-weight: 500;
729
+ transition: all 0.2s ease;
730
+ &:last-child {
731
+ margin-bottom: 0;
795
732
  }
796
733
  }
797
734
  }
798
735
  }
799
736
 
800
- // ========== 输入区域 ==========
737
+ .result-animation {
738
+ animation: resultAppear 0.5s cubic-bezier(0.2, 0.9, 0.4, 1.1);
739
+ }
740
+
741
+ .message-createTime {
742
+ font-size: 11px;
743
+ color: #9ca3af;
744
+ margin-top: 6px;
745
+ }
746
+
747
+ .feedback-buttons {
748
+ display: flex;
749
+ gap: 12px;
750
+ margin-top: 12px;
751
+
752
+ .feedback-btn {
753
+ display: flex;
754
+ align-items: center;
755
+ gap: 6px;
756
+ padding: 4px 10px;
757
+ border: none;
758
+ border-radius: 20px;
759
+ font-size: 13px;
760
+ font-weight: 500;
761
+ cursor: pointer;
762
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
763
+ background: rgba(255, 255, 255, 0.9);
764
+ backdrop-filter: blur(10px);
765
+
766
+ .btn-emoji {
767
+ font-size: 16px;
768
+ transition: transform 0.2s ease;
769
+ }
770
+ .btn-text {
771
+ font-size: 13px;
772
+ }
773
+ &:hover {
774
+ transform: translateY(-2px);
775
+ .btn-emoji {
776
+ transform: scale(1.1);
777
+ }
778
+ }
779
+ &:active {
780
+ transform: translateY(0);
781
+ }
782
+ }
783
+
784
+ .satisfied-btn {
785
+ background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
786
+ color: #1890ff;
787
+ border: 1px solid rgba(24, 144, 255, 0.2);
788
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
789
+ &:hover {
790
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
791
+ border-color: #1890ff;
792
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
793
+ }
794
+ }
795
+
796
+ .unsatisfied-btn {
797
+ background: linear-gradient(135deg, #fff1f0 0%, #ffe7e5 100%);
798
+ color: #ff4d4f;
799
+ border: 1px solid rgba(255, 77, 79, 0.2);
800
+ box-shadow: 0 2px 8px rgba(255, 77, 79, 0.1);
801
+ &:hover {
802
+ background: linear-gradient(135deg, #ffe7e5 0%, #ffccc7 100%);
803
+ border-color: #ff4d4f;
804
+ box-shadow: 0 4px 12px rgba(255, 77, 79, 0.2);
805
+ }
806
+ }
807
+ }
808
+
801
809
  .input-area {
802
810
  padding: 16px 24px 24px;
803
811
  backdrop-filter: blur(10px);
@@ -846,32 +854,46 @@ defineExpose({
846
854
  }
847
855
  }
848
856
 
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
- }
857
+ @keyframes slideIn {
858
+ from {
859
+ opacity: 0;
860
+ transform: translateX(-8px);
861
+ }
862
+ to {
863
+ opacity: 1;
864
+ transform: translateX(0);
865
+ }
866
+ }
867
+
868
+ @keyframes spin {
869
+ to {
870
+ transform: rotate(360deg);
871
+ }
872
+ }
873
+
874
+ @keyframes breathe {
875
+ 0%,
876
+ 100% {
877
+ border-color: rgba(102, 126, 234, 0.15);
878
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.05);
879
+ }
880
+ 50% {
881
+ border-color: rgba(102, 126, 234, 0.35);
882
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.12);
883
+ }
884
+ }
885
+
886
+ @keyframes resultAppear {
887
+ 0% {
888
+ opacity: 0;
889
+ transform: scale(0.95);
890
+ }
891
+ 100% {
892
+ opacity: 1;
893
+ transform: scale(1);
871
894
  }
872
895
  }
873
896
 
874
- // ========== 反馈弹窗 ==========
875
897
  .feedback-dialog-content {
876
898
  text-align: center;
877
899
  padding: 12px 0;
@@ -899,31 +921,6 @@ defineExpose({
899
921
  }
900
922
  }
901
923
 
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
924
  @keyframes shake {
928
925
  0%,
929
926
  100% {
@@ -936,10 +933,4 @@ defineExpose({
936
933
  transform: translateX(5px);
937
934
  }
938
935
  }
939
-
940
- @keyframes spin {
941
- to {
942
- transform: rotate(360deg);
943
- }
944
- }
945
936
  </style>