Pārlūkot izejas kodu

[Mod 0000]AI智能聊天助手功能修改完善

wangkeyi 1 dienu atpakaļ
vecāks
revīzija
5a9b81b390
39 mainītis faili ar 723 papildinājumiem un 856 dzēšanām
  1. 7 9
      src/assets/images/ventAI/chatModalBlue/1-10.svg
  2. 7 9
      src/assets/images/ventAI/chatModalBlue/1-11.svg
  3. 5 8
      src/assets/images/ventAI/chatModalBlue/1-12.svg
  4. 2 8
      src/assets/images/ventAI/chatModalBlue/1-13.svg
  5. BIN
      src/assets/images/ventAI/chatModalBlue/1-14.png
  6. 0 10
      src/assets/images/ventAI/chatModalBlue/1-14.svg
  7. BIN
      src/assets/images/ventAI/chatModalBlue/1-15.png
  8. 0 10
      src/assets/images/ventAI/chatModalBlue/1-15.svg
  9. BIN
      src/assets/images/ventAI/chatModalBlue/1-3.png
  10. BIN
      src/assets/images/ventAI/chatModalBlue/1-4.png
  11. BIN
      src/assets/images/ventAI/chatModalBlue/1-7.png
  12. 4 0
      src/assets/images/ventAI/chatModalBlue/1-7.svg
  13. 4 0
      src/assets/images/ventAI/chatModalBlue/1-8.svg
  14. 3 0
      src/assets/images/ventAI/chatModalBlue/1-9.svg
  15. 3 0
      src/assets/images/ventAI/chatModalBlue/2-1.svg
  16. 0 0
      src/assets/images/ventAI/chatModalBlue/2-2.svg
  17. 11 0
      src/assets/images/ventAI/chatModalBlue/2-3.svg
  18. 3 0
      src/assets/images/ventAI/chatModalBlue/2-4.svg
  19. 1 0
      src/assets/images/ventAI/chatModalBlue/2-5.svg
  20. BIN
      src/assets/images/ventAI/chatModalBlue/2-6.png
  21. 3 0
      src/assets/images/ventAI/chatModalBlue/2-6.svg
  22. BIN
      src/assets/images/ventAI/chatModalBlue/3-1.png
  23. BIN
      src/assets/images/ventAI/chatModalBlue/3-2.png
  24. BIN
      src/assets/images/ventAI/chatModalBlue/3-5.png
  25. BIN
      src/assets/images/ventAI/chatModalBlue/3-6.png
  26. 2 6
      src/assets/images/ventAI/chatModalBlue/3-7.svg
  27. 1 0
      src/assets/images/ventAI/chatModalBlue/4-5.svg
  28. 1 0
      src/assets/images/ventAI/chatModalBlue/4-6.svg
  29. BIN
      src/assets/images/ventAI/chatModalBlue/5-1.png
  30. 28 23
      src/design/themify/deepblue.less
  31. 24 20
      src/design/themify/default.less
  32. 285 83
      src/views/ventAI/manageAssistent/components/AiAssistantModal.vue
  33. 4 4
      src/views/ventAI/manageAssistent/components/chatModal/ChatInputArea.vue
  34. 239 173
      src/views/ventAI/manageAssistent/components/chatModal/ChatMessages.vue
  35. 2 2
      src/views/ventAI/manageAssistent/components/chatModal/FilePreviewPanel.vue
  36. 76 87
      src/views/ventAI/manageAssistent/components/chatModal/TaskListPanel.vue
  37. 0 397
      src/views/ventAI/manageAssistent/components/chatModal/ThinkingPanel.vue
  38. 1 0
      src/views/ventAI/manageAssistent/components/chatModal/types.ts
  39. 7 7
      src/views/ventAI/manageAssistent/components/chatModal/utils.ts

+ 7 - 9
src/assets/images/ventAI/chatModalBlue/1-10.svg

@@ -1,10 +1,8 @@
-<svg id="组_16756" data-name="组 16756" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.442" height="12.482" viewBox="0 0 12.442 12.482">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#659ebc"/>
-      <stop offset="1" stop-color="#207aab"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_57050" data-name="路径 57050" d="M6.37,0A4.74,4.74,0,1,1,1.63,4.74,4.741,4.741,0,0,1,6.37,0Zm0,1.435a3.305,3.305,0,1,0,3.3,3.305,3.305,3.305,0,0,0-3.3-3.305ZM9.653,8.888c-.113.082-.14.11-.054.222.666.871,1.386,1.8,2.049,2.665,1.4,1.827,3.541-.293,1.73-1.71-.86-.673-1.777-1.4-2.64-2.08-.111-.087-.138-.06-.222.052a3.921,3.921,0,0,1-.862.852Z" transform="translate(-1.63)" fill="url(#linear-gradient)"/>
-  <path id="路径_57051" data-name="路径 57051" d="M195.648,194.975h4.522a.12.12,0,0,1,.12.12v1.043a.12.12,0,0,1-.12.12h-4.522a.12.12,0,0,1-.12-.12v-1.043a.12.12,0,0,1,.12-.12Z" transform="translate(-193.143 -190.863)" fill="url(#linear-gradient)"/>
+<svg xmlns="http://www.w3.org/2000/svg" width="15.753" height="13.602" viewBox="0 0 15.753 13.602">
+  <g id="组_16862" data-name="组 16862" transform="translate(-683.624 -454.698)">
+    <g id="组_16817" data-name="组 16817" transform="translate(12014.351 18447.115)">
+      <path id="路径_58150" data-name="路径 58150" d="M65.85,122.88H52.3a1.12,1.12,0,0,0,0,2.24H65.85a1.112,1.112,0,0,0,1.1-1.12A1.1,1.1,0,0,0,65.85,122.88Zm-9.494,5.512H52.3a1.112,1.112,0,0,0-1.1,1.12,1.123,1.123,0,0,0,1.1,1.12h4.054a1.112,1.112,0,0,0,1.1-1.12A1.1,1.1,0,0,0,56.356,128.392Zm0,5.512H52.3a1.112,1.112,0,0,0-1.1,1.12,1.123,1.123,0,0,0,1.1,1.12h4.089a1.063,1.063,0,0,0,.765-.32,1.086,1.086,0,0,0,.32-.8A1.127,1.127,0,0,0,56.356,133.9Z" transform="translate(-11381.927 -18115.297)" fill="#fff"/>
+      <path id="路径_58151" data-name="路径 58151" d="M4.054,6.881,8.125,0H0Z" transform="translate(-11322.851 -17978.814) rotate(-90)" fill="#fff"/>
+    </g>
+  </g>
 </svg>

+ 7 - 9
src/assets/images/ventAI/chatModalBlue/1-11.svg

@@ -1,10 +1,8 @@
-<svg id="组_16759" data-name="组 16759" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.442" height="12.482" viewBox="0 0 12.442 12.482">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#bce8ff"/>
-      <stop offset="1" stop-color="#28a6ea"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_57050" data-name="路径 57050" d="M6.37,0A4.74,4.74,0,1,1,1.63,4.74,4.741,4.741,0,0,1,6.37,0Zm0,1.435a3.305,3.305,0,1,0,3.3,3.305,3.305,3.305,0,0,0-3.3-3.305ZM9.653,8.888c-.113.082-.14.11-.054.222.666.871,1.386,1.8,2.049,2.665,1.4,1.827,3.541-.293,1.73-1.71-.86-.673-1.777-1.4-2.64-2.08-.111-.087-.138-.06-.222.052a3.921,3.921,0,0,1-.862.852Z" transform="translate(-1.63)" fill="url(#linear-gradient)"/>
-  <path id="路径_57051" data-name="路径 57051" d="M195.648,194.975h4.522a.12.12,0,0,1,.12.12v1.043a.12.12,0,0,1-.12.12h-4.522a.12.12,0,0,1-.12-.12v-1.043a.12.12,0,0,1,.12-.12Z" transform="translate(-193.143 -190.863)" fill="url(#linear-gradient)"/>
+<svg xmlns="http://www.w3.org/2000/svg" width="15.753" height="13.602" viewBox="0 0 15.753 13.602">
+  <g id="组_16858" data-name="组 16858" transform="translate(-683.624 -454.698)">
+    <g id="组_16817" data-name="组 16817" transform="translate(12014.351 18447.115)">
+      <path id="路径_58150" data-name="路径 58150" d="M65.85,122.88H52.3a1.12,1.12,0,0,0,0,2.24H65.85a1.112,1.112,0,0,0,1.1-1.12A1.1,1.1,0,0,0,65.85,122.88Zm-9.494,5.512H52.3a1.112,1.112,0,0,0-1.1,1.12,1.123,1.123,0,0,0,1.1,1.12h4.054a1.112,1.112,0,0,0,1.1-1.12A1.1,1.1,0,0,0,56.356,128.392Zm0,5.512H52.3a1.112,1.112,0,0,0-1.1,1.12,1.123,1.123,0,0,0,1.1,1.12h4.089a1.063,1.063,0,0,0,.765-.32,1.086,1.086,0,0,0,.32-.8A1.127,1.127,0,0,0,56.356,133.9Z" transform="translate(-11381.927 -18115.297)" fill="#fff"/>
+      <path id="路径_58151" data-name="路径 58151" d="M63.13,128.978l4.071,6.881H59.076Z" transform="translate(-11451.829 -17919.738) rotate(-90)" fill="#fff"/>
+    </g>
+  </g>
 </svg>

+ 5 - 8
src/assets/images/ventAI/chatModalBlue/1-12.svg

@@ -1,9 +1,6 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.442" height="12.414" viewBox="0 0 12.442 12.414">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#659ebc"/>
-      <stop offset="1" stop-color="#207aab"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58051" data-name="路径 58051" d="M114.815,184.972a5.445,5.445,0,0,0-.124,1,4.328,4.328,0,0,0,4.355,4.355,3.757,3.757,0,0,0,1.866-.436v2.364a1.673,1.673,0,0,1-1.68,1.68h-2.551l-.933,1.12a.532.532,0,0,1-.809.062.061.061,0,0,1-.062-.062l-.933-1.12h-2.551a1.673,1.673,0,0,1-1.68-1.68v-5.6a1.673,1.673,0,0,1,1.68-1.68Zm4.23,4.106a3.111,3.111,0,1,1,3.111-3.111A3.08,3.08,0,0,1,119.045,189.078Zm.373-3.484v-1.306a.378.378,0,1,0-.747,0v1.618a.229.229,0,0,0,.062.187.342.342,0,0,0,.311.187h1.12a.378.378,0,1,0,0-.747h-.747Z" transform="translate(-109.713 -182.857)" fill="url(#linear-gradient)"/>
+<svg xmlns="http://www.w3.org/2000/svg" width="12.804" height="10.613" viewBox="0 0 12.804 10.613">
+  <g id="组_16862" data-name="组 16862" transform="translate(-463.598 -140.692)">
+    <path id="路径_58188" data-name="路径 58188" d="M60.746,133.265,64,127.76H57.5Z" transform="translate(412.398 17.813)" fill="#fff"/>
+    <path id="路径_58189" data-name="路径 58189" d="M62.922,122.88H52.082a.9.9,0,0,0,0,1.793h10.84a.89.89,0,0,0,.882-.9A.881.881,0,0,0,62.922,122.88Zm-7.6,4.41H52.082a.89.89,0,0,0-.882.9.9.9,0,0,0,.882.9h3.244a.89.89,0,0,0,.882-.9A.881.881,0,0,0,55.326,127.29Zm0,4.41H52.082a.89.89,0,0,0-.882.9.9.9,0,0,0,.882.9h3.272a.85.85,0,0,0,.612-.256.869.869,0,0,0,.256-.64A.9.9,0,0,0,55.326,131.7Z" transform="translate(412.398 17.813)" fill="#fff"/>
+  </g>
 </svg>

+ 2 - 8
src/assets/images/ventAI/chatModalBlue/1-13.svg

@@ -1,9 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.442" height="12.414" viewBox="0 0 12.442 12.414">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#bce8ff"/>
-      <stop offset="1" stop-color="#28a6ea"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58052" data-name="路径 58052" d="M114.815,184.972a5.445,5.445,0,0,0-.124,1,4.328,4.328,0,0,0,4.355,4.355,3.757,3.757,0,0,0,1.866-.436v2.364a1.673,1.673,0,0,1-1.68,1.68h-2.551l-.933,1.12a.532.532,0,0,1-.809.062.061.061,0,0,1-.062-.062l-.933-1.12h-2.551a1.673,1.673,0,0,1-1.68-1.68v-5.6a1.673,1.673,0,0,1,1.68-1.68Zm4.23,4.106a3.111,3.111,0,1,1,3.111-3.111A3.08,3.08,0,0,1,119.045,189.078Zm.373-3.484v-1.306a.378.378,0,1,0-.747,0v1.618a.229.229,0,0,0,.062.187.342.342,0,0,0,.311.187h1.12a.378.378,0,1,0,0-.747h-.747Z" transform="translate(-109.713 -182.857)" fill="url(#linear-gradient)"/>
+<svg xmlns="http://www.w3.org/2000/svg" width="12.804" height="10.613" viewBox="0 0 12.804 10.613">
+  <path id="路径_58187" data-name="路径 58187" d="M62.922,122.88H52.082a.9.9,0,0,0,0,1.793h10.84a.89.89,0,0,0,.882-.9A.881.881,0,0,0,62.922,122.88Zm-7.6,4.41H52.082a.89.89,0,0,0-.882.9.9.9,0,0,0,.882.9h3.244a.89.89,0,0,0,.882-.9A.881.881,0,0,0,55.326,127.29Zm0,4.41H52.082a.89.89,0,0,0-.882.9.9.9,0,0,0,.882.9h3.272a.85.85,0,0,0,.612-.256.869.869,0,0,0,.256-.64A.9.9,0,0,0,55.326,131.7Zm5.42-3.941L64,133.265H57.5Z" transform="translate(-51.2 -122.88)" fill="#fff"/>
 </svg>

BIN
src/assets/images/ventAI/chatModalBlue/1-14.png


+ 0 - 10
src/assets/images/ventAI/chatModalBlue/1-14.svg

@@ -1,10 +0,0 @@
-<svg id="组_16757" data-name="组 16757" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="13.901" height="13.9" viewBox="0 0 13.901 13.9">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#659ebc"/>
-      <stop offset="1" stop-color="#207aab"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58006" data-name="路径 58006" d="M464.881,147.213a.881.881,0,0,1-.881-.881V134.193a.881.881,0,0,1,1.762,0v12.139A.881.881,0,0,1,464.881,147.213Z" transform="translate(-457.931 -133.312)" fill="url(#linear-gradient)"/>
-  <path id="路径_58007" data-name="路径 58007" d="M146.332,465.762H134.193a.881.881,0,0,1,0-1.762h12.139a.881.881,0,1,1,0,1.762Z" transform="translate(-133.312 -457.931)" fill="url(#linear-gradient)"/>
-</svg>

BIN
src/assets/images/ventAI/chatModalBlue/1-15.png


+ 0 - 10
src/assets/images/ventAI/chatModalBlue/1-15.svg

@@ -1,10 +0,0 @@
-<svg id="组_16758" data-name="组 16758" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="13.901" height="13.9" viewBox="0 0 13.901 13.9">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#bce8ff"/>
-      <stop offset="1" stop-color="#28a6ea"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58006" data-name="路径 58006" d="M464.881,147.213a.881.881,0,0,1-.881-.881V134.193a.881.881,0,0,1,1.762,0v12.139A.881.881,0,0,1,464.881,147.213Z" transform="translate(-457.931 -133.312)" fill="url(#linear-gradient)"/>
-  <path id="路径_58007" data-name="路径 58007" d="M146.332,465.762H134.193a.881.881,0,0,1,0-1.762h12.139a.881.881,0,1,1,0,1.762Z" transform="translate(-133.312 -457.931)" fill="url(#linear-gradient)"/>
-</svg>

BIN
src/assets/images/ventAI/chatModalBlue/1-3.png


BIN
src/assets/images/ventAI/chatModalBlue/1-4.png


BIN
src/assets/images/ventAI/chatModalBlue/1-7.png


+ 4 - 0
src/assets/images/ventAI/chatModalBlue/1-7.svg

@@ -0,0 +1,4 @@
+<svg id="组_16862" data-name="组 16862" xmlns="http://www.w3.org/2000/svg" width="12.021" height="12.021" viewBox="0 0 12.021 12.021">
+  <path id="路径_58006" data-name="路径 58006" d="M464.762,145.333a.762.762,0,0,1-.762-.762v-10.5a.762.762,0,1,1,1.524,0v10.5A.762.762,0,0,1,464.762,145.333Z" transform="translate(-458.751 -133.312)" fill="#fff"/>
+  <path id="路径_58007" data-name="路径 58007" d="M144.571,465.524h-10.5a.762.762,0,1,1,0-1.524h10.5a.762.762,0,1,1,0,1.524Z" transform="translate(-133.312 -458.751)" fill="#fff"/>
+</svg>

+ 4 - 0
src/assets/images/ventAI/chatModalBlue/1-8.svg

@@ -0,0 +1,4 @@
+<svg id="组_16862" data-name="组 16862" xmlns="http://www.w3.org/2000/svg" width="10.382" height="10.415" viewBox="0 0 10.382 10.415">
+  <path id="路径_57050" data-name="路径 57050" d="M5.584,0A3.955,3.955,0,1,1,1.63,3.955,3.955,3.955,0,0,1,5.584,0Zm0,1.2A2.758,2.758,0,1,0,8.342,3.955,2.758,2.758,0,0,0,5.584,1.2Zm2.74,6.218c-.094.069-.117.092-.045.185.556.727,1.156,1.5,1.709,2.223,1.165,1.525,2.955-.244,1.443-1.427-.718-.562-1.483-1.171-2.2-1.735-.093-.073-.115-.05-.186.043a3.271,3.271,0,0,1-.719.711Z" transform="translate(-1.63)" fill="#fff"/>
+  <path id="路径_57051" data-name="路径 57051" d="M195.629,194.975H199.4a.1.1,0,0,1,.1.1v.87a.1.1,0,0,1-.1.1h-3.773a.1.1,0,0,1-.1-.1v-.87a.1.1,0,0,1,.1-.1Z" transform="translate(-193.539 -191.544)" fill="#fff"/>
+</svg>

+ 3 - 0
src/assets/images/ventAI/chatModalBlue/1-9.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12.037" height="11.144" viewBox="0 0 12.037 11.144">
+  <path id="路径_58133" data-name="路径 58133" d="M11.037,6.232a.4.4,0,0,1-.4.4h-.8v.8a.4.4,0,0,1-.8,0v-.8h-.8a.4.4,0,1,1,0-.8h.8v-.8a.4.4,0,0,1,.8,0v.8h.8A.4.4,0,0,1,11.037,6.232Zm-9.2-4.2h.6v.6a.4.4,0,1,0,.8,0v-.6h.6a.4.4,0,0,0,0-.8h-.6v-.6a.4.4,0,1,0-.8,0v.6h-.6a.4.4,0,1,0,0,.8Zm6,6.2h-.4v-.4a.4.4,0,0,0-.8,0v.4h-.4a.4.4,0,1,0,0,.8h.4v.4a.4.4,0,1,0,.8,0v-.4h.4a.4.4,0,0,0,0-.8ZM7.721,4.517,2.4,9.832a.795.795,0,0,1-1.13,0L.236,8.8a.795.795,0,0,1,0-1.13L7.671.231a.805.805,0,0,1,1.13,0L9.837,1.267a.8.8,0,0,1,0,1.13L7.721,4.518ZM6.4,2.631,7.436,3.667,9.272,1.831,8.237.8Z" transform="translate(0.5 0.576)" fill="#fff" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1"/>
+</svg>

+ 3 - 0
src/assets/images/ventAI/chatModalBlue/2-1.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="18.926" height="19.755" viewBox="0 0 18.926 19.755">
+  <path id="路径_58149" data-name="路径 58149" d="M3.158,1.858H6.5A.878.878,0,0,0,7.432.929.878.878,0,0,0,6.5,0H.743C.557,0,.372.185.186.371A.683.683,0,0,0,0,.929V6.5a.878.878,0,0,0,.929.929A.878.878,0,0,0,1.858,6.5V3.158L6.874,8.174a.92.92,0,0,0,1.3-1.3ZM18,12.323a.878.878,0,0,0-.929.929V16.6L15.4,14.924,12.052,11.58a.92.92,0,0,0-1.3,1.3L14.1,16.225,15.767,17.9H12.423a.929.929,0,1,0,0,1.858H18a.878.878,0,0,0,.929-.929V13.252A.878.878,0,0,0,18,12.323Z" transform="translate(0 0)" fill="#9fdcfd"/>
+</svg>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
src/assets/images/ventAI/chatModalBlue/2-2.svg


+ 11 - 0
src/assets/images/ventAI/chatModalBlue/2-3.svg

@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12.465" height="12.465" viewBox="0 0 12.465 12.465">
+  <g id="组_16834" data-name="组 16834" transform="translate(-76.8 -76.8)">
+    <path id="路径_58166" data-name="路径 58166" d="M205.865,80.759a.135.135,0,0,1-.11-.037,2.017,2.017,0,1,1,2.676-1.906.367.367,0,0,1-.733,0,1.283,1.283,0,1,0-2.566,0,1.268,1.268,0,0,0,.843,1.21.381.381,0,0,1,.22.477A.352.352,0,0,1,205.865,80.759Zm2.2,3.3h0a.377.377,0,0,1-.367-.4,1.438,1.438,0,0,0-.147-.66,1.359,1.359,0,0,0-.733-.623,1.331,1.331,0,0,0-.99.073.377.377,0,1,1-.367-.66,2.045,2.045,0,0,1,1.54-.147,1.959,1.959,0,0,1,1.173.99,1.805,1.805,0,0,1,.22,1.063A.319.319,0,0,1,208.065,84.059Zm-1.65,5.206a2,2,0,0,1-1.43-.587,2.07,2.07,0,0,1-.4-2.31.361.361,0,0,1,.66.293,1.3,1.3,0,1,0,2.09-.367.363.363,0,0,1,.513-.513,2.059,2.059,0,0,1,0,2.859A1.9,1.9,0,0,1,206.415,89.265Z" transform="translate(-125.766 0)" fill="#fff"/>
+    <path id="路径_58167" data-name="路径 58167" d="M78.816,184.332a2.016,2.016,0,0,1,0-4.033,1.712,1.712,0,0,1,.623.11.371.371,0,0,1-.257.7,1.56,1.56,0,0,0-.4-.073,1.283,1.283,0,1,0,0,2.566.346.346,0,0,1,.367.367C79.146,184.186,79.036,184.332,78.816,184.332Zm3.483,4.4a.394.394,0,0,1-.367-.367v-8.8a.394.394,0,0,1,.367-.367.367.367,0,0,1,.367.367v8.8A.367.367,0,0,1,82.3,188.732Z" transform="translate(0 -100.934)" fill="#fff"/>
+    <path id="路径_58168" data-name="路径 58168" d="M207.754,715.7a1.945,1.945,0,0,1-1.65-.88,2.04,2.04,0,0,1,.037-2.346.387.387,0,0,1,.513-.073.353.353,0,0,1,.073.513,1.265,1.265,0,0,0,0,1.5,1.292,1.292,0,0,0,2.126-1.467.371.371,0,0,1,.623-.4,2.051,2.051,0,0,1-.513,2.823A2.507,2.507,0,0,1,207.754,715.7Z" transform="translate(-127.104 -626.434)" fill="#fff"/>
+    <path id="路径_58169" data-name="路径 58169" d="M78.816,86.7a2.016,2.016,0,1,1,0-4.033.367.367,0,0,1,0,.733A1.283,1.283,0,1,0,80.1,84.682a.367.367,0,0,1,.733,0A2.034,2.034,0,0,1,78.816,86.7Zm7.149-5.939a.352.352,0,0,1-.33-.257.381.381,0,0,1,.22-.477,1.268,1.268,0,0,0,.843-1.21,1.283,1.283,0,1,0-2.566,0,.367.367,0,0,1-.733,0,2.016,2.016,0,1,1,2.676,1.906C86.038,80.723,86,80.759,85.965,80.759Zm-2.2,3.3a.362.362,0,0,1-.367-.33,2.136,2.136,0,0,1,.22-1.063,1.958,1.958,0,0,1,1.173-.99,2.045,2.045,0,0,1,1.54.147.377.377,0,1,1-.367.66,1.318,1.318,0,0,0-.99-.073,1.243,1.243,0,0,0-.733.623,1.438,1.438,0,0,0-.147.66c.037.147-.11.33-.33.367Zm1.65,5.206a2,2,0,0,1-1.43-.587,2.059,2.059,0,0,1,0-2.86.363.363,0,0,1,.513.513,1.3,1.3,0,0,0,1.833,1.833,1.35,1.35,0,0,0,.257-1.466.361.361,0,1,1,.66-.293,2.019,2.019,0,0,1-.4,2.31A2.121,2.121,0,0,1,85.415,89.265Z" transform="translate(0 0)" fill="#fff"/>
+    <path id="路径_58170" data-name="路径 58170" d="M541.449,184.332a.367.367,0,0,1,0-.733,1.283,1.283,0,1,0,0-2.566,1.318,1.318,0,0,0-.4.073.371.371,0,1,1-.257-.7,1.861,1.861,0,0,1,.623-.11,2.034,2.034,0,0,1,2.016,2.016A2,2,0,0,1,541.449,184.332Zm-3.483,4.4a.394.394,0,0,0,.367-.367v-8.8a.394.394,0,0,0-.367-.367.367.367,0,0,0-.367.367v8.8A.367.367,0,0,0,537.967,188.732Z" transform="translate(-454.201 -100.934)" fill="#fff"/>
+    <path id="路径_58171" data-name="路径 58171" d="M540.534,713.175a1.833,1.833,0,0,1-1.137-.367,2.045,2.045,0,0,1-.513-2.823.371.371,0,0,1,.623.4,1.291,1.291,0,1,0,2.126,1.466,1.393,1.393,0,0,0,0-1.5.367.367,0,0,1,.587-.44,2.038,2.038,0,0,1,.037,2.346A2.16,2.16,0,0,1,540.534,713.175Z" transform="translate(-455.119 -623.91)" fill="#fff"/>
+    <path id="路径_58172" data-name="路径 58172" d="M667.616,490.433a2.034,2.034,0,0,1-2.016-2.016.367.367,0,0,1,.733,0,1.283,1.283,0,1,0,1.283-1.283.367.367,0,1,1,0-.733,2.016,2.016,0,0,1,0,4.033Z" transform="translate(-580.368 -403.734)" fill="#fff"/>
+  </g>
+</svg>

+ 3 - 0
src/assets/images/ventAI/chatModalBlue/2-4.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.577" height="14.275" viewBox="0 0 15.577 14.275">
+  <path id="路径_58175" data-name="路径 58175" d="M231.4,213.675a1.222,1.222,0,0,1,.651,2.254v.761h4.041l.087,0a.846.846,0,0,1,.759.841V226.1a.846.846,0,0,1-.845.846h-9.384a.846.846,0,0,1-.846-.846v-8.568a.846.846,0,0,1,.846-.846h4.041v-.761a1.221,1.221,0,0,1,.651-2.254Zm-4.236,11.974h8.471v-7.658h-8.471v7.658Zm-2.386-6.107a.651.651,0,0,1,.651.651v3.258a.651.651,0,0,1-1.3,0v-3.258a.651.651,0,0,1,.651-.651Zm13.276,0a.651.651,0,0,1,.651.651v3.258a.651.651,0,0,1-1.3,0v-3.258a.651.651,0,0,1,.651-.651Zm-8.795,1.1a1.313,1.313,0,1,1-1.313,1.313A1.313,1.313,0,0,1,229.257,220.644Zm4.313,0a1.314,1.314,0,1,1-1.314,1.314,1.314,1.314,0,0,1,1.314-1.314Z" transform="translate(-223.625 -213.175)" fill="#cdeeff" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" opacity="0.5"/>
+</svg>

+ 1 - 0
src/assets/images/ventAI/chatModalBlue/2-5.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1784697577869" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5688" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M416.832 798.08c-16.192 0-32.32-6.208-44.672-18.56L119.424 525.76c-24.64-24.768-24.64-64.96 0-89.728 24.704-24.768 64.704-24.768 89.344 0l208.064 208.896L814.4 245.76c24.64-24.832 64.64-24.832 89.344 0 24.64 24.768 24.64 64.896 0 89.664L461.504 779.52c-12.352 12.352-28.544 18.56-44.672 18.56z" fill="#1AB394" p-id="5689"></path></svg>

BIN
src/assets/images/ventAI/chatModalBlue/2-6.png


+ 3 - 0
src/assets/images/ventAI/chatModalBlue/2-6.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.966" height="17.738" viewBox="0 0 15.966 17.738">
+  <path id="路径_58128" data-name="路径 58128" d="M17.29,8.475c.6-.272.6-.712,0-.985L1.089.1A.705.705,0,0,0,.007.785L0,6.121,13.122,7.982,0,9.844.007,15.18a.7.7,0,0,0,1.082.687Z" transform="translate(0 17.738) rotate(-90)" fill="#fff"/>
+</svg>

BIN
src/assets/images/ventAI/chatModalBlue/3-1.png


BIN
src/assets/images/ventAI/chatModalBlue/3-2.png


BIN
src/assets/images/ventAI/chatModalBlue/3-5.png


BIN
src/assets/images/ventAI/chatModalBlue/3-6.png


+ 2 - 6
src/assets/images/ventAI/chatModalBlue/3-7.svg

@@ -1,7 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="41.266" height="48.044" viewBox="0 0 41.266 48.044">
-  <g id="组_16767" data-name="组 16767" transform="translate(-102.4 -34.133)">
-    <path id="路径_58014" data-name="路径 58014" d="M296.429,342.194H271.378a3.442,3.442,0,0,1-3.432-3.432V312.338a3.442,3.442,0,0,1,3.432-3.432h25.051a3.442,3.442,0,0,1,3.432,3.432v26.424A3.442,3.442,0,0,1,296.429,342.194Z" transform="translate(-157.225 -260.96)" fill="#1e6f9f" opacity="0.3"/>
-    <path id="路径_58015" data-name="路径 58015" d="M138.947,82.177H107.033a4.614,4.614,0,0,1-4.633-4.633V38.766a4.614,4.614,0,0,1,4.633-4.633h32a4.614,4.614,0,0,1,4.633,4.633V77.458a4.7,4.7,0,0,1-4.719,4.719Zm-31.915-45.47a2.107,2.107,0,0,0-2.145,2.059V77.458a2.088,2.088,0,0,0,2.059,2.059h32a2.088,2.088,0,0,0,2.059-2.059V38.766a1.981,1.981,0,0,0-2.059-2.059H107.033Z" transform="translate(0)" fill="#1e6f9f"/>
-    <path id="路径_58016" data-name="路径 58016" d="M311.82,233.17H294.834a1.287,1.287,0,0,1,0-2.574H311.82a1.287,1.287,0,0,1,0,2.574Zm-8.493,6.863h-8.493a1.287,1.287,0,0,1,0-2.574h8.493a1.287,1.287,0,0,1,0,2.574Zm6.778-15.614H296.549a3.04,3.04,0,0,1-3-3v-8.493a3.04,3.04,0,0,1,3-3H310.1a3.04,3.04,0,0,1,3,3v8.493A3.04,3.04,0,0,1,310.1,224.419Zm-13.555-11.925a.405.405,0,0,0-.429.429v8.493a.405.405,0,0,0,.429.429H310.1a.405.405,0,0,0,.429-.429v-8.493a.405.405,0,0,0-.429-.429Z" transform="translate(-181.538 -166.95)" fill="#1e6f9f"/>
-  </g>
+<svg xmlns="http://www.w3.org/2000/svg" width="16.192" height="13.886" viewBox="0 0 16.192 13.886">
+  <path id="路径_58152" data-name="路径 58152" d="M69.385,132a1.527,1.527,0,0,1,1.023.393l2.048,1.849a.509.509,0,0,0,.341.131h3.244a1.526,1.526,0,0,1,1.526,1.526v1.7h.1a1.526,1.526,0,0,1,1.394,2.147l-1.889,4.239a1.526,1.526,0,0,1-1.394.905H65.526A1.526,1.526,0,0,1,64,143.36v-9.834A1.526,1.526,0,0,1,65.526,132Zm8.28,6.612h-9.7a.509.509,0,0,0-.465.3l-1.889,4.239a.509.509,0,0,0,.465.716h9.7a.509.509,0,0,0,.465-.3l1.889-4.239a.509.509,0,0,0-.465-.716Zm-8.28-5.6H65.526a.509.509,0,0,0-.509.509v8.454l1.55-3.48a1.526,1.526,0,0,1,1.394-.905h8.588v-1.7a.509.509,0,0,0-.509-.509H72.8A1.527,1.527,0,0,1,71.775,135l-2.048-1.849A.509.509,0,0,0,69.385,133.017Z" transform="translate(-63.5 -131.5)" fill="#fff" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1"/>
 </svg>

+ 1 - 0
src/assets/images/ventAI/chatModalBlue/4-5.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1784698235264" class="icon" viewBox="0 0 1050 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7017" xmlns:xlink="http://www.w3.org/1999/xlink" width="205.078125" height="200"><path d="M23.760635 1024c-13.130877 0-23.760635-10.629758-23.760635-23.760635 0-12.922451 10.629758-23.552208 23.760635-23.552208h1002.948911c13.130877 0 23.760635 10.629758 23.760635 23.552208 0 13.130877-10.629758 23.760635-23.760635 23.760635H23.760635zM500.849176 23.760635c0-13.130877 10.629758-23.760635 23.552208-23.760635 13.130877 0 23.760635 10.629758 23.760635 23.760635v802.4425c0 12.922451-10.629758 23.552208-23.760635 23.552208-12.922451 0-23.552208-10.629758-23.552208-23.552208V23.760635z" p-id="7018" fill="#ffffff"></path><path d="M93.375127 431.026257c-9.379198-9.170771-9.379198-24.177488-0.208426-33.34826 9.170771-9.379198 24.177488-9.379198 33.556686-0.208426l413.935274 411.851007c9.170771 9.170771 9.170771 24.177488 0 33.556686-9.170771 9.170771-24.177488 9.170771-33.34826 0L93.375127 431.026257z" p-id="7019" fill="#ffffff"></path><path d="M922.287808 397.469571c9.170771-9.170771 24.177488-9.170771 33.34826 0.208426 9.379198 9.170771 9.170771 24.177488 0 33.34826L540.658661 842.877264c-9.379198 9.170771-24.385915 9.170771-33.556687 0-9.170771-9.379198-9.170771-24.385915 0.208427-33.556686l414.977407-411.851007z" p-id="7020" fill="#ffffff"></path></svg>

+ 1 - 0
src/assets/images/ventAI/chatModalBlue/4-6.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1784698289493" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8101" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M959.825022 384.002258V191.939717C959.825022 121.2479 902.517291 63.940169 831.825474 63.940169H191.939717C121.2479 63.940169 63.940169 121.2479 63.940169 191.939717v639.885757C63.940169 902.517291 121.2479 959.825022 191.939717 959.825022h639.885757c70.691817 0 127.999548-57.307731 127.999548-127.999548V384.002258zM146.66502 146.66502a63.737872 63.737872 0 0 1 45.336109-18.784682h639.997742A63.961844 63.961844 0 0 1 895.884854 192.001129V320.062089H127.880338V192.001129A63.737872 63.737872 0 0 1 146.66502 146.66502z m269.1267 461.308451v-223.971213h192.181751v223.971213h-192.181751z m192.181751 63.940169v223.971214h-192.181751v-223.971214h192.181751z m-256.12192-63.940169H127.880338v-223.971213h223.971213v223.971213z m-205.186531 269.235073a63.466939 63.466939 0 0 1-18.784682-45.209673V671.91364h223.971213v223.971214H192.001129a63.625887 63.625887 0 0 1-45.336109-18.67631z m749.219834-45.209673A63.763159 63.763159 0 0 1 831.998871 895.884854H671.91364v-223.971214h223.971214v160.085231z m0-224.0254h-223.971214v-223.971213h223.971214v223.971213z" fill="#ffffff" p-id="8102"></path></svg>

BIN
src/assets/images/ventAI/chatModalBlue/5-1.png


+ 28 - 23
src/design/themify/deepblue.less

@@ -68,33 +68,38 @@ html[data-theme='deepblue'] {
   --img-ai-float: url('/src/assets/images/ventAI/chatModalBlue/4-1.png');
 
   // 聊天弹窗图片
-  --img-chat-header-icon: url('/src/assets/images/ventAI/chatModalBlue/2-5.png');
-  --img-chat-selector-bg: url('/src/assets/images/ventAI/chatModalBlue/2-6.png');
-  --img-chat-upload-bg: url('/src/assets/images/ventAI/chatModalBlue/2-7.png');
-  --img-chat-upload-icon: url('/src/assets/images/ventAI/chatModalBlue/2-10.svg');
-  --img-chat-download-icon: url('/src/assets/images/ventAI/chatModalBlue/2-8.svg');
-  --img-chat-modal-title: url('/src/assets/images/ventAI/chatModalBlue/1-1.png');
-  --img-chat-panel-header: url('/src/assets/images/ventAI/chatModalBlue/3-5.png');
-  --img-chat-close-icon: url('/src/assets/images/ventAI/chatModalBlue/2-11.svg');
-  --img-chat-thinking-bg: url('/src/assets/images/ventAI/chatModalBlue/3-6.png');
-  --img-chat-task-bg: url('/src/assets/images/ventAI/chatModalBlue/2-3.png');
-  --img-chat-options-active-bg: url('/src/assets/images/ventAI/chatModalBlue/1-3.png');
-  --img-chat-options-bg: url('/src/assets/images/ventAI/chatModalBlue/1-4.png');
+  --img-chat-modal-bg: url('/src/assets/images/ventAI/chatModalBlue/1-1.png');
+  --img-chat-close-bg: url('/src/assets/images/ventAI/chatModalBlue/1-2.png');
+  --img-chat-options-icon-border: url('/src/assets/images/ventAI/chatModalBlue/1-3.png');
   --img-chat-task-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/1-5.png');
-  --img-chat-options-search-icon: url('/src/assets/images/ventAI/chatModalBlue/1-10.svg');
-  --img-chat-options-search-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-11.svg');
-  --img-chat-options-history-icon: url('/src/assets/images/ventAI/chatModalBlue/1-12.svg');
-  --img-chat-options-history-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-13.svg');
-  --img-chat-options-add-icon: url('/src/assets/images/ventAI/chatModalBlue/1-14.svg');
-  --img-chat-options-add-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-15.svg');
+  --img-chat-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/1-6.png');
+  --img-chat-options-add-icon: url('/src/assets/images/ventAI/chatModalBlue/1-7.svg');
+  --img-chat-options-search-icon: url('/src/assets/images/ventAI/chatModalBlue/1-8.svg');
+  --img-chat-options-skill-icon: url('/src/assets/images/ventAI/chatModalBlue/1-9.svg');
+  --img-chat-expand-icon: url('/src/assets/images/ventAI/chatModalBlue/1-10.svg');
+  --img-chat-collapse-icon: url('/src/assets/images/ventAI/chatModalBlue/1-11.svg');
+  --img-chat-prev-icon: url('/src/assets/images/ventAI/chatModalBlue/1-14.png');
+  --img-chat-next-icon: url('/src/assets/images/ventAI/chatModalBlue/1-15.png');
+  --img-chat-maximize-icon: url('/src/assets/images/ventAI/chatModalBlue/2-1.svg');
+  --img-chat-minimize-icon: url('/src/assets/images/ventAI/chatModalBlue/2-2.svg');
+  --img-chat-thinking-icon: url('/src/assets/images/ventAI/chatModalBlue/2-3.svg');
   --img-chat-task-add-icon: url('/src/assets/images/ventAI/chatModalBlue/2-4.svg');
+  --img-chat-agent-icon: url('/src/assets/images/ventAI/chatModalBlue/2-4.svg');
+  --img-chat-copy-success-icon: url('/src/assets/images/ventAI/chatModalBlue/2-5.svg');
+  --img-chat-send-icon: url('/src/assets/images/ventAI/chatModalBlue/2-6.svg');
+  --img-chat-close-bg: url('/src/assets/images/ventAI/chatModalBlue/2-7.png');
+  --img-chat-download-icon: url('/src/assets/images/ventAI/chatModalBlue/2-8.png');
   --img-chat-ai-avatar: url('/src/assets/images/ventAI/chatModalBlue/2-9.png');
-  --img-chat-thinking-avatar: url('/src/assets/images/ventAI/chatModalBlue/3-1.png');
-  --img-chat-agent-card-bg: url('/src/assets/images/ventAI/chatModalBlue/3-2.png');
-  --img-chat-agent-card-header: url('/src/assets/images/ventAI/chatModalBlue/3-3.png');
+  --img-chat-upload-icon: url('/src/assets/images/ventAI/chatModalBlue/2-10.svg');
+  --img-chat-close-icon: url('/src/assets/images/ventAI/chatModalBlue/2-11.svg');
+  --img-chat-input-bg: url('/src/assets/images/ventAI/chatModalBlue/2-13.png');
   --img-chat-collapse-bg: url('/src/assets/images/ventAI/chatModalBlue/2-15.png');
   --img-chat-attach-icon: url('/src/assets/images/ventAI/chatModalBlue/3-7.svg');
-  --img-chat-send-icon: url('/src/assets/images/ventAI/chatModalBlue/2-6.png');
   --img-chat-scroll-bottom: url('/src/assets/images/ventAI/chatModalBlue/3-8.png');
-  --img-chat-input-bg: url('/src/assets/images/ventAI/chatModalBlue/2-13.png');
+  --img-chat-arrow-icon: url('/src/assets/images/ventAI/chatModalBlue/4-2.svg');
+  --img-chat-copy-icon: url('/src/assets/images/ventAI/chatModalBlue/4-3.svg');
+  --img-chat-close-icon-btn: url('/src/assets/images/ventAI/chatModalBlue/4-4.svg');
+  --img-chat-download-icon-btn: url('/src/assets/images/ventAI/chatModalBlue/4-5.svg');
+  --img-chat-preview-icon: url('/src/assets/images/ventAI/chatModalBlue/4-6.svg');
+  --img-chat-welcome-img: url('/src/assets/images/ventAI/chatModalBlue/5-1.png');
 }

+ 24 - 20
src/design/themify/default.less

@@ -77,31 +77,35 @@ html {
   // 聊天弹窗图片
   --img-chat-modal-bg: url('/src/assets/images/ventAI/chatModalBlue/1-1.png');
   --img-chat-close-bg: url('/src/assets/images/ventAI/chatModalBlue/1-2.png');
-  --img-chat-options-active-bg: url('/src/assets/images/ventAI/chatModalBlue/1-3.png');
-  --img-chat-options-bg: url('/src/assets/images/ventAI/chatModalBlue/1-4.png');
+  --img-chat-options-icon-border: url('/src/assets/images/ventAI/chatModalBlue/1-3.png');
   --img-chat-task-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/1-5.png');
   --img-chat-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/1-6.png');
-  --img-chat-selector-bg: url('/src/assets/images/ventAI/chatModalBlue/1-7.png');
-  --img-chat-upload-bg: url('/src/assets/images/ventAI/chatModalBlue/2-7.png');
-  --img-chat-upload-icon: url('/src/assets/images/ventAI/chatModalBlue/2-10.svg');
-  --img-chat-download-icon: url('/src/assets/images/ventAI/chatModalBlue/2-8.png');
-  --img-chat-panel-header: url('/src/assets/images/ventAI/chatModalBlue/3-5.png');
-  --img-chat-close-icon: url('/src/assets/images/ventAI/chatModalBlue/2-11.svg');
-  --img-chat-thinking-bg: url('/src/assets/images/ventAI/chatModalBlue/3-6.png');
-  --img-chat-options-search-icon: url('/src/assets/images/ventAI/chatModalBlue/1-10.svg');
-  --img-chat-options-search-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-11.svg');
-  --img-chat-options-history-icon: url('/src/assets/images/ventAI/chatModalBlue/1-12.svg');
-  --img-chat-options-history-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-13.svg');
-  --img-chat-options-add-icon: url('/src/assets/images/ventAI/chatModalBlue/1-14.svg');
-  --img-chat-options-add-active-icon: url('/src/assets/images/ventAI/chatModalBlue/1-15.svg');
+  --img-chat-options-add-icon: url('/src/assets/images/ventAI/chatModalBlue/1-7.svg');
+  --img-chat-options-search-icon: url('/src/assets/images/ventAI/chatModalBlue/1-8.svg');
+  --img-chat-options-skill-icon: url('/src/assets/images/ventAI/chatModalBlue/1-9.svg');
+  --img-chat-expand-icon: url('/src/assets/images/ventAI/chatModalBlue/1-10.svg');
+  --img-chat-collapse-icon: url('/src/assets/images/ventAI/chatModalBlue/1-11.svg');
+  --img-chat-prev-icon: url('/src/assets/images/ventAI/chatModalBlue/1-14.png');
+  --img-chat-next-icon: url('/src/assets/images/ventAI/chatModalBlue/1-15.png');
+  --img-chat-maximize-icon: url('/src/assets/images/ventAI/chatModalBlue/2-1.svg');
+  --img-chat-minimize-icon: url('/src/assets/images/ventAI/chatModalBlue/2-2.svg');
+  --img-chat-thinking-icon: url('/src/assets/images/ventAI/chatModalBlue/2-3.svg');
   --img-chat-task-add-icon: url('/src/assets/images/ventAI/chatModalBlue/2-4.svg');
+  --img-chat-agent-icon: url('/src/assets/images/ventAI/chatModalBlue/2-4.svg');
+  --img-chat-copy-success-icon: url('/src/assets/images/ventAI/chatModalBlue/2-5.svg');
+  --img-chat-send-icon: url('/src/assets/images/ventAI/chatModalBlue/2-6.svg');
+  --img-chat-download-icon: url('/src/assets/images/ventAI/chatModalBlue/2-8.png');
   --img-chat-ai-avatar: url('/src/assets/images/ventAI/chatModalBlue/2-9.png');
-  --img-chat-thinking-avatar: url('/src/assets/images/ventAI/chatModalBlue/3-1.png');
-  --img-chat-agent-card-bg: url('/src/assets/images/ventAI/chatModalBlue/3-2.png');
-  --img-chat-agent-card-header: url('/src/assets/images/ventAI/chatModalBlue/3-3.png');
+  --img-chat-upload-icon: url('/src/assets/images/ventAI/chatModalBlue/2-10.svg');
+  --img-chat-close-icon: url('/src/assets/images/ventAI/chatModalBlue/2-11.svg');
+  --img-chat-input-bg: url('/src/assets/images/ventAI/chatModalBlue/1-7.svg');
   --img-chat-collapse-bg: url('/src/assets/images/ventAI/chatModalBlue/2-15.png');
   --img-chat-attach-icon: url('/src/assets/images/ventAI/chatModalBlue/3-7.svg');
-  --img-chat-send-icon: url('/src/assets/images/ventAI/chatModalBlue/2-6.png');
   --img-chat-scroll-bottom: url('/src/assets/images/ventAI/chatModalBlue/3-8.png');
-  --img-chat-input-bg: url('/src/assets/images/ventAI/chatModalBlue/2-13.png');
+  --img-chat-arrow-icon: url('/src/assets/images/ventAI/chatModalBlue/4-2.svg');
+  --img-chat-copy-icon: url('/src/assets/images/ventAI/chatModalBlue/4-3.svg');
+  --img-chat-close-icon-btn: url('/src/assets/images/ventAI/chatModalBlue/4-4.svg');
+  --img-chat-download-icon-btn: url('/src/assets/images/ventAI/chatModalBlue/4-5.svg');
+  --img-chat-preview-icon: url('/src/assets/images/ventAI/chatModalBlue/4-6.svg');
+  --img-chat-welcome-img: url('/src/assets/images/ventAI/chatModalBlue/5-1.png');
 }

+ 285 - 83
src/views/ventAI/manageAssistent/components/AiAssistantModal.vue

@@ -1,33 +1,51 @@
 <template>
-  <a-modal :visible="props.visible" @cancel="emit('close')" :width="1400" :footer="null" destroyOnClose class="ai-assistant-modal">
+  <a-modal
+    :visible="props.visible"
+    @cancel="emit('close')"
+    :width="isFullscreen ? '100vw' : 1400"
+    :footer="null"
+    destroyOnClose
+    :class="['ai-assistant-modal', { fullscreen: isFullscreen }]"
+  >
     <template #title>
-      <div class="draggable-title" @mousedown="onDragStart">"通安智风"大模型</div>
+      <div :class="['draggable-title', { 'no-drag': isFullscreen }]" @mousedown="onDragStart">"通安智风"大模型</div>
     </template>
+    <!-- 最大化/还原按钮 -->
+    <div class="maximize-btn" @click="toggleFullscreen">
+      <div :class="['maximize-icon', { minimized: isFullscreen }]"></div>
+    </div>
+    <!-- 收起/展开按钮 -->
+    <div class="collapse-btn" @click="togglePanel">
+      <div :class="['collapse-icon', { collapsed: panelCollapsed }]"></div>
+    </div>
     <div class="ai-container">
       <!-- 左侧任务列表 -->
-      <TaskListPanel
-        :taskList="taskList"
-        :currentTaskId="currentTaskId"
-        @switch-task="switchTask"
-        @create-task="createNewTask"
-        @delete-task="handleDeleteTask"
-      />
+      <div :class="['task-panel-wrapper', { collapsed: panelCollapsed }]">
+        <TaskListPanel
+          :taskList="taskList"
+          :currentTaskId="currentTaskId"
+          @switch-task="switchTask"
+          @create-task="createNewTask"
+          @delete-task="handleDeleteTask"
+        />
+      </div>
 
       <!-- 中间聊天区域 -->
       <div class="chat-panel">
         <!-- 顶部任务选择器 -->
         <div class="chat-header">
-          <a-select
-            v-model:value="currentTaskId"
-            style="width: 300px"
-            @change="handleTaskChange"
-            :getContainer="false"
-            popup-class-name="ai-task-select-dropdown"
-          >
-            <a-select-option v-for="task in taskList" :key="task.id" :value="task.id">
-              {{ task.name }}
-            </a-select-option>
-          </a-select>
+          <template v-if="panelCollapsed">
+            <div :class="['nav-btn', { disabled: !canGoPrev }]" @click="goToPrev">
+              <div class="nav-icon prev-icon"></div>
+            </div>
+            <div :class="['nav-btn', { disabled: !canGoNext }]" @click="goToNext">
+              <div class="nav-icon next-icon"></div>
+            </div>
+            <div class="nav-btn" @click="createNewTask">
+              <div class="nav-icon add-icon"></div>
+            </div>
+          </template>
+          <span v-if="currentTask?.sessionId" class="chat-header-title">{{ currentTask.name }}</span>
           <div v-if="currentWordUrl" class="upload-bg" @click="downloadWordReport">
             <div class="download-icon"></div>
           </div>
@@ -92,12 +110,13 @@
       const res = await getHistoryList({});
       const sessions = res?.sessions || res?.data || [];
       if (Array.isArray(sessions)) {
-        const apiTasks: Task[] = sessions.map((item: { session_id: string; title: string }) => ({
+        const apiTasks: Task[] = sessions.map((item: { session_id: string; title: string; updated_at: string }) => ({
           id: item.session_id,
           name: item.title || '未命名会话',
           sessionId: item.session_id,
           messages: [],
           attachedFiles: [],
+          updatedAt: item.updated_at,
         }));
 
         const mergedTasks = apiTasks.map((apiTask) => {
@@ -132,13 +151,49 @@
   const showFileList = ref(false);
   const pendingFile = ref<AttachedFile | null>(null);
 
-  const messages = ref<Message[]>([
-    {
-      type: 'ai',
-      content: '您好!我是通安智风助手,请问有什么可以帮助您的吗?',
-      time: dayjs().format('HH:mm'),
-    },
-  ]);
+  const messages = ref<Message[]>([]);
+
+  const panelCollapsed = ref(false);
+  const togglePanel = () => {
+    panelCollapsed.value = !panelCollapsed.value;
+  };
+
+  const isFullscreen = ref(false);
+  const toggleFullscreen = () => {
+    isFullscreen.value = !isFullscreen.value;
+    nextTick(() => {
+      const wraps = document.querySelectorAll<HTMLElement>('.zxm-modal-wrap, .ant-modal-wrap, [class*="modal-wrap"]');
+      wraps.forEach((wrap) => {
+        if (isFullscreen.value) {
+          wrap.style.position = '';
+          wrap.style.left = '';
+          wrap.style.top = '0';
+          wrap.style.right = '';
+          wrap.style.bottom = '';
+          wrap.style.width = '';
+          wrap.style.height = '';
+          wrap.style.margin = '0';
+          wrap.style.padding = '0';
+          wrap.style.transform = '';
+        } else {
+          wrap.style.position = '';
+          wrap.style.left = '';
+          wrap.style.top = '';
+          wrap.style.right = '';
+          wrap.style.bottom = '';
+          wrap.style.width = '';
+          wrap.style.height = '';
+          wrap.style.margin = '';
+          wrap.style.padding = '';
+          wrap.style.transform = '';
+        }
+      });
+      draggedEl = null;
+      if (!isFullscreen.value) {
+        centerModal();
+      }
+    });
+  };
 
   const inputMessage = ref('');
   const loading = ref(false);
@@ -199,11 +254,7 @@
     messages.value = newTask.messages && newTask.messages.length > 0 ? [...newTask.messages] : getDefaultMessages();
 
     await nextTick();
-    scrollToBottom();
-  };
-
-  const handleTaskChange = (taskId: string) => {
-    switchTask(taskId);
+    chatMessagesRef.value?.forceScrollToBottom();
   };
 
   const createNewTask = () => {
@@ -254,13 +305,7 @@
   };
 
   const getDefaultMessages = (): Message[] => {
-    return [
-      {
-        type: 'ai',
-        content: '您好!我是通安智风助手,请问有什么可以帮助您的吗?',
-        time: dayjs().format('HH:mm'),
-      },
-    ];
+    return [];
   };
 
   const normalizeLineBreaks = (str: string): string => {
@@ -370,11 +415,28 @@
     return currentTask?.attachedFiles || [];
   };
 
+  const currentTask = computed(() => taskList.value.find((t) => t.id === currentTaskId.value));
+
   const currentWordUrl = computed(() => {
-    const currentTask = taskList.value.find((t) => t.id === currentTaskId.value);
-    return currentTask?.wordUrl || '';
+    return currentTask.value?.wordUrl || '';
   });
 
+  const currentTaskIndex = computed(() => taskList.value.findIndex((t) => t.id === currentTaskId.value));
+  const canGoPrev = computed(() => currentTaskIndex.value > 0);
+  const canGoNext = computed(() => currentTaskIndex.value >= 0 && currentTaskIndex.value < taskList.value.length - 1);
+
+  const goToPrev = () => {
+    if (!canGoPrev.value) return;
+    const prevTask = taskList.value[currentTaskIndex.value - 1];
+    if (prevTask) switchTask(prevTask.id);
+  };
+
+  const goToNext = () => {
+    if (!canGoNext.value) return;
+    const nextTask = taskList.value[currentTaskIndex.value + 1];
+    if (nextTask) switchTask(nextTask.id);
+  };
+
   const downloadWordReport = () => {
     const url = currentWordUrl.value;
     if (!url) return;
@@ -473,15 +535,9 @@
     return nameMap[toolName] || nameMap[toolName.toLowerCase()] || '智能分析助手';
   };
 
-  // 每个 agent 只保留最新一条步骤,新数据替换旧数据
+  // 累积所有步骤,保留完整历史
   const upsertStep = (steps: any[], step: any) => {
-    const agentName = step.agent || '系统';
-    const idx = steps.findIndex((s) => (s.agent || '系统') === agentName && s.type !== 'updated_todo_list');
-    if (idx !== -1) {
-      steps.splice(idx, 1, step);
-    } else {
-      steps.push(step);
-    }
+    steps.push(step);
   };
 
   const handleSSEMessage = (data: any, aiMsgIndex: number) => {
@@ -856,7 +912,7 @@
         inputMessage.value = '';
 
         await nextTick(() => {
-          scrollToBottom();
+          chatMessagesRef.value?.forceScrollToBottom();
         });
       }
     }
@@ -894,6 +950,7 @@
   };
 
   const onDragStart = (e: MouseEvent) => {
+    if (isFullscreen.value) return;
     draggedEl = findModalWrap(e.target as HTMLElement) || queryModalWrap();
     if (!draggedEl) return;
 
@@ -955,6 +1012,54 @@
     font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
   }
 
+  .collapse-btn {
+    position: absolute;
+    top: 16px;
+    left: 24px;
+    z-index: 10;
+    width: 32px;
+    height: 32px;
+    background: #1a6696;
+    border-radius: 4px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    transition: background 0.3s;
+
+    &:hover {
+      background: #1f7ab8;
+    }
+
+    .collapse-icon {
+      width: 16px;
+      height: 16px;
+      background-image: var(--img-chat-collapse-icon);
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+
+      &.collapsed {
+        background-image: var(--img-chat-expand-icon);
+      }
+    }
+  }
+
+  .task-panel-wrapper {
+    width: 260px;
+    flex-shrink: 0;
+    overflow: hidden;
+    transition:
+      width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
+      margin 0.35s cubic-bezier(0.4, 0, 0.2, 1),
+      opacity 0.25s ease;
+
+    &.collapsed {
+      width: 0;
+      margin: 0;
+      opacity: 0;
+    }
+  }
+
   .chat-panel {
     flex: 1;
     display: flex;
@@ -972,6 +1077,7 @@
       padding: 12px 20px;
       flex-shrink: 0;
       align-items: center;
+      background: rgba(2, 53, 100, 0.3);
 
       .header-icon {
         width: 35px;
@@ -981,33 +1087,60 @@
         background-size: 100% 100%;
         margin-right: 10px;
       }
-      .zxm-select-selector {
-        height: 40px;
-        background-image: var(--img-chat-selector-bg);
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-        border: none;
-        border-color: unset !important;
-        box-shadow: unset !important;
-        color: #e0e6ed;
-        background-color: unset;
-        border-radius: 0;
-        padding-left: 40px;
-        padding-top: 10px;
-      }
-      .zxm-select-arrow {
+
+      .chat-header-title {
+        font-size: 16px;
         color: #e0e6ed;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        margin-left: 10px;
       }
 
-      .zxm-select-selection-item {
-        color: #e0e6ed;
+      .nav-btn {
+        width: 28px;
+        height: 28px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+        border-radius: 4px;
+        transition: background 0.2s;
+
+        &:hover:not(.disabled) {
+          background: rgba(10, 132, 255, 0.15);
+        }
+
+        &.disabled {
+          opacity: 0.3;
+          cursor: not-allowed;
+        }
+
+        .nav-icon {
+          width: 16px;
+          height: 16px;
+          background-repeat: no-repeat;
+          background-size: 100% 100%;
+        }
+
+        .prev-icon {
+          background-image: var(--img-chat-prev-icon);
+        }
+
+        .next-icon {
+          background-image: var(--img-chat-next-icon);
+        }
+
+        .add-icon {
+          background-image: var(--img-chat-options-add-icon);
+        }
       }
 
       .upload-bg {
         cursor: pointer;
         width: 36px;
         height: 36px;
-        background-image: var(--img-chat-upload-bg);
+        background-image: var(--img-chat-close-bg);
         background-repeat: no-repeat;
         background-size: 100% 100%;
         display: flex;
@@ -1031,8 +1164,9 @@
     height: 100%;
     display: flex;
     flex-direction: column;
-    background: linear-gradient(to bottom, rgba(10, 132, 255, 0.08), rgba(2, 22, 50, 0.95));
-    border: 2px solid rgba(63, 80, 106, 0.5);
+    background-image: var(--img-chat-panel-bg);
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
     border-radius: 4px;
     flex-shrink: 0;
   }
@@ -1044,6 +1178,14 @@
     &:active {
       cursor: grabbing;
     }
+
+    &.no-drag {
+      cursor: default;
+
+      &:active {
+        cursor: default;
+      }
+    }
   }
 </style>
 
@@ -1062,8 +1204,8 @@
       background-image: var(--img-chat-close-bg);
       background-repeat: no-repeat;
       background-size: 100% 100%;
-      top: -6px;
-      right: -6px;
+      top: 0px;
+      right: 0px;
       width: 38px;
       height: 38px;
       .zxm-modal-close-x {
@@ -1077,6 +1219,76 @@
       }
     }
 
+    .maximize-btn {
+      position: absolute;
+      top: 0px;
+      right: 56px;
+      width: 38px;
+      height: 38px;
+      background-image: var(--img-chat-close-bg);
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      z-index: 10;
+
+      .maximize-icon {
+        width: 22px;
+        height: 22px;
+        background-image: var(--img-chat-maximize-icon);
+        background-repeat: no-repeat;
+        background-size: 100% 100%;
+
+        &.minimized {
+          background-image: var(--img-chat-minimize-icon);
+        }
+      }
+    }
+
+    &.fullscreen {
+      top: 0 !important;
+      padding: 0 !important;
+      max-width: 100vw !important;
+      margin: 0 !important;
+
+      .zxm-modal-wrap,
+      .ant-modal-wrap {
+        padding: 0 !important;
+        margin: 0 !important;
+        top: 0 !important;
+      }
+
+      .zxm-modal-content {
+        width: 100vw !important;
+        height: 100vh !important;
+        max-width: 100vw !important;
+        margin: 0;
+        border-radius: 0;
+        overflow: hidden;
+      }
+      .zxm-modal-header {
+        height: 120px;
+      }
+      .no-drag {
+        cursor: default;
+        font-size: 32px !important;
+      }
+      .zxm-modal-title {
+        height: 90px;
+      }
+      .zxm-modal-body {
+        height: calc(100vh - 120px);
+        overflow: hidden;
+        padding: 0 24px 12px;
+      }
+      .ai-container {
+        height: 100%;
+        overflow: hidden;
+      }
+    }
+
     .zxm-modal-header {
       background-color: unset !important;
       background: unset;
@@ -1106,14 +1318,4 @@
       padding: 12px 24px;
     }
   }
-  .ai-task-select-dropdown {
-    background-color: rgba(10, 132, 255, 0.1);
-    .zxm-select-item {
-      color: #e0e6ed;
-    }
-    .zxm-select-item-option-selected {
-      color: #e0e6ed !important;
-      background-color: rgba(10, 132, 255, 0.15) !important;
-    }
-  }
 </style>

+ 4 - 4
src/views/ventAI/manageAssistent/components/chatModal/ChatInputArea.vue

@@ -81,10 +81,10 @@
   .chat-input-area {
     padding: 5px 10px;
     flex-shrink: 0;
-    background-color: rgba(10, 132, 255, 0.05);
-    border: 1px solid rgba(63, 80, 106, 0.5);
+    background-color: #002f4a;
+    border: 1px solid #005482;
     border-radius: 4px;
-    margin: 5px 10px;
+    margin: 10px 16px 16px 16px;
 
     .pending-file-display {
       margin-bottom: 5px;
@@ -170,7 +170,7 @@
     }
     .input-actions {
       display: flex;
-      justify-content: end;
+      justify-content: space-between;
       align-items: center;
       margin-top: 12px;
 

+ 239 - 173
src/views/ventAI/manageAssistent/components/chatModal/ChatMessages.vue

@@ -1,92 +1,100 @@
 <template>
   <div class="chat-messages-container">
     <div class="chat-messages" ref="messagesRef">
-      <div v-for="(message, index) in messages" :key="index" :class="['message-wrapper', message.type]">
+      <!-- 新对话缺省图 -->
+      <div v-if="messages.length === 0" class="welcome-empty">
+        <img :src="getCssUrl('--img-chat-welcome-img')" class="welcome-img" />
+      </div>
+      <div v-for="(message, index) in messages" :key="index" :class="['message-wrapper', message.type]" @mouseleave="copiedMessageIndex = -1">
         <!-- AI消息 -->
         <div v-if="message.type === 'ai'" class="ai-message">
-          <div class="message-agent">
+          <!-- <div class="message-agent">
             <div class="agent-icon"></div>
-          </div>
+          </div> -->
           <div class="message-body">
             <!-- 思考过程折叠卡片 -->
             <div v-if="message.thinkingSteps && message.thinkingSteps.length > 0" class="thinking-card">
-              <div class="thinking-header" @click="toggleThinking(index)">
-                <div class="thinking-header-left">
-                  <div class="thinking-icon"></div>
-                  <span class="thinking-title">思考过程</span>
-                  <span class="thinking-count">{{ getAgentCount(message.thinkingSteps) }} 个子任务</span>
-                  <span v-if="getDurationText(message)" class="thinking-duration">{{ getDurationText(message) }}</span>
-                </div>
-                <div :class="['thinking-arrow', { expanded: expandedThinking[index] }]">
-                  <img :src="arrowIcon" width="12" height="12" />
+              <div class="thinking-duration-bar" @click="toggleThinkingCard(index)">
+                <span v-if="getDurationText(message)" class="thinking-duration">{{ getDurationText(message) }}</span>
+                <div :class="['thinking-arrow', { expanded: !collapsedThinking[index] }]">
+                  <img :src="getCssUrl('--img-chat-arrow-icon')" width="12" height="12" />
                 </div>
               </div>
-              <div v-show="expandedThinking[index]" class="thinking-body">
-                <div v-for="(group, groupIdx) in groupStepsByAgent(message.thinkingSteps)" :key="groupIdx" class="agent-group">
-                  <div class="agent-group-header" @click="toggleAgent(index + '-' + group.agent)">
-                    <div class="agent-group-header-left">
-                      <div class="agent-group-icon"></div>
-                      <span class="agent-group-name">{{ group.agent }}</span>
-                      <span class="agent-group-count">{{ group.steps.length }} 步</span>
-                    </div>
-                    <div :class="['thinking-arrow', { expanded: expandedAgents[index + '-' + group.agent] }]">
-                      <img :src="arrowIcon" width="10" height="10" />
-                    </div>
+              <div v-show="!collapsedThinking[index]">
+                <div class="thinking-header">
+                  <div class="thinking-header-left">
+                    <div class="thinking-icon"></div>
+                    <span class="thinking-title">思考过程 持续了几秒</span>
                   </div>
-                  <div v-show="expandedAgents[index + '-' + group.agent]" class="agent-group-body">
-                    <div v-for="(step, stepIdx) in group.steps" :key="stepIdx" class="thinking-step">
-                      <!-- agent_start -->
-                      <div v-if="step.type === 'agent_start'" class="step-item step-agent-start">
-                        <div class="step-icon agent-icon-start"></div>
-                        <div class="step-content">
-                          <span class="step-desc">{{ step.message }}</span>
-                        </div>
+                </div>
+                <div class="thinking-body">
+                  <div
+                    v-for="(group, groupIdx) in groupStepsByAgent(message.thinkingSteps)"
+                    :key="groupIdx"
+                    :class="['agent-group', { expanded: expandedAgents[index + '-' + group.agent] }]"
+                  >
+                    <div class="agent-group-header" @click="toggleAgent(index + '-' + group.agent)">
+                      <div class="agent-group-header-left">
+                        <div class="agent-group-icon"></div>
+                        <span class="agent-group-name">{{ group.agent }}</span>
                       </div>
-                      <!-- tool_call -->
-                      <div v-else-if="step.type === 'tool_call'" class="step-item step-tool-call">
-                        <div class="step-icon tool-icon"></div>
-                        <div class="step-content">
-                          <span class="step-label">调用工具:</span>
-                          <span class="step-tool-name">{{ step.tool }}</span>
-                          <span v-if="step.message" class="step-desc">{{ step.message }}</span>
-                        </div>
+                      <!-- 最新一条执行结果,内联显示 -->
+                      <span v-if="getLatestStepMessage(group)" class="agent-group-latest">
+                        {{ getLatestStepMessage(group) }}
+                      </span>
+                      <div :class="['thinking-arrow', 'agent-arrow', { expanded: expandedAgents[index + '-' + group.agent] }]">
+                        <img :src="getCssUrl('--img-chat-arrow-icon')" width="10" height="10" />
                       </div>
-                      <!-- executing -->
-                      <div v-else-if="step.type === 'executing'" class="step-item step-executing">
-                        <div class="step-icon executing-icon"></div>
-                        <div class="step-content">
-                          <span class="step-desc">{{ step.message || '正在执行...' }}</span>
-                          <span v-if="step.tool" class="step-tool-name">{{ step.tool }}</span>
+                    </div>
+                    <div v-show="expandedAgents[index + '-' + group.agent]" class="agent-group-body">
+                      <div v-for="(step, stepIdx) in group.steps" :key="stepIdx" class="thinking-step">
+                        <!-- agent_start -->
+                        <div v-if="step.type === 'agent_start'" class="step-item step-agent-start">
+                          <div class="step-content">
+                            <span class="step-desc">{{ step.message }}</span>
+                          </div>
                         </div>
-                      </div>
-                      <!-- updated_todo_list -->
-                      <div v-else-if="step.type === 'updated_todo_list'" class="step-item step-todo">
-                        <div class="step-icon todo-icon"></div>
-                        <div class="step-content">
-                          <div class="todo-list">
-                            <div v-for="(todo, todoIdx) in step.todos" :key="todoIdx" class="todo-item">
-                              <span :class="['todo-status', todo.status]">
-                                {{ todo.status === 'completed' ? '✓' : todo.status === 'in_progress' ? '●' : '○' }}
-                              </span>
-                              <span class="todo-text">{{ todo.content }}</span>
+                        <!-- tool_call -->
+                        <div v-else-if="step.type === 'tool_call'" class="step-item step-tool-call">
+                          <div class="step-content">
+                            <span class="step-label">调用工具:</span>
+                            <span class="step-tool-name">{{ step.tool }}</span>
+                            <span v-if="step.message" class="step-desc">{{ step.message }}</span>
+                          </div>
+                        </div>
+                        <!-- executing -->
+                        <div v-else-if="step.type === 'executing'" class="step-item step-executing">
+                          <div class="step-content">
+                            <span class="step-desc">{{ step.message || '正在执行...' }}</span>
+                            <span v-if="step.tool" class="step-tool-name">{{ step.tool }}</span>
+                          </div>
+                        </div>
+                        <!-- updated_todo_list -->
+                        <div v-else-if="step.type === 'updated_todo_list'" class="step-item step-todo">
+                          <div class="step-content">
+                            <div class="todo-list">
+                              <div v-for="(todo, todoIdx) in step.todos" :key="todoIdx" class="todo-item">
+                                <span :class="['todo-status', todo.status]">
+                                  {{ todo.status === 'completed' ? '✓' : todo.status === 'in_progress' ? '●' : '○' }}
+                                </span>
+                                <span class="todo-text">{{ todo.content }}</span>
+                              </div>
                             </div>
                           </div>
                         </div>
-                      </div>
-                      <!-- tool_result -->
-                      <div v-else-if="step.type === 'tool_result'" class="step-item step-tool-result">
-                        <div class="step-icon result-icon"></div>
-                        <div class="step-content">
-                          <span class="step-label">工具结果:</span>
-                          <span class="step-tool-name">{{ step.tool }}</span>
-                          <span class="step-desc">{{ step.message }}</span>
+                        <!-- tool_result -->
+                        <div v-else-if="step.type === 'tool_result'" class="step-item step-tool-result">
+                          <div class="step-content">
+                            <span class="step-label">工具结果:</span>
+                            <span class="step-tool-name">{{ step.tool }}</span>
+                            <span class="step-desc">{{ step.message }}</span>
+                          </div>
                         </div>
-                      </div>
-                      <!-- agent_done -->
-                      <div v-else-if="step.type === 'agent_done'" class="step-item step-agent-done">
-                        <div class="step-icon done-icon"></div>
-                        <div class="step-content">
-                          <span class="step-desc">{{ step.message }}</span>
+                        <!-- agent_done -->
+                        <div v-else-if="step.type === 'agent_done'" class="step-item step-agent-done">
+                          <div class="step-content">
+                            <span class="step-desc">{{ step.message }}</span>
+                          </div>
                         </div>
                       </div>
                     </div>
@@ -95,7 +103,7 @@
               </div>
             </div>
 
-            <div v-if="message.content" class="message-text" v-html="renderMarkdown(message.content)"></div>
+            <div v-if="message.content" class="message-text" v-html="renderMarkdown(message.content, tableIcons)"></div>
             <div v-if="message.wordDownloadUrl" class="word-download-area">
               <a-button type="link" @click="emit('download-word', message.wordDownloadUrl)"> 下载报告文件 (.docx) </a-button>
             </div>
@@ -107,8 +115,8 @@
           </div>
           <!-- AI消息操作栏 -->
           <div class="message-actions">
-            <div class="action-btn" @click="copyMessageContent(message.content)" title="复制">
-              <img :src="copyIcon" width="14" height="14" />
+            <div class="action-btn" @click="copyMessageContent(message.content, index)" :title="copiedMessageIndex === index ? '复制成功' : '复制'">
+              <img :src="copyIconUrl(index)" width="14" height="14" />
             </div>
             <span v-if="message.createdAt" class="action-time">{{ formatFullTime(message.createdAt) }}</span>
           </div>
@@ -117,7 +125,7 @@
         <!-- 用户消息 -->
         <div v-else class="user-message">
           <div class="message-body">
-            <div class="message-text" v-html="renderMarkdown(message.content)"></div>
+            <div class="message-text" v-html="renderMarkdown(message.content, tableIcons)"></div>
             <div v-if="message.attachedFile" class="attached-file-card" @click="emit('file-preview', message.attachedFile)">
               <div class="file-icon-card"></div>
               <div class="file-info-card">
@@ -128,8 +136,8 @@
           </div>
           <!-- 用户消息操作栏 -->
           <div class="message-actions">
-            <div class="action-btn" @click="copyMessageContent(message.content)" title="复制">
-              <img :src="copyIcon" width="14" height="14" />
+            <div class="action-btn" @click="copyMessageContent(message.content, index)" :title="copiedMessageIndex === index ? '复制成功' : '复制'">
+              <img :src="copyIconUrl(index)" width="14" height="14" />
             </div>
             <span v-if="message.createdAt" class="action-time">{{ formatFullTime(message.createdAt) }}</span>
           </div>
@@ -148,7 +156,7 @@
         <div class="table-preview-header">
           <span class="table-preview-title">表格预览</span>
           <div class="table-preview-close" @click="closePreview">
-            <img :src="closeIcon" width="16" height="16" />
+            <img :src="getCssUrl('--img-chat-close-icon-btn')" width="16" height="16" />
           </div>
         </div>
         <div class="table-preview-body" v-html="previewTableHtml"></div>
@@ -158,13 +166,28 @@
 </template>
 
 <script setup lang="ts">
-  import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
+  import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue';
   import dayjs from 'dayjs';
   import { renderMarkdown, formatFileSize, tableHtmlToMarkdown, tableHtmlToCsv } from './utils';
   import type { Message, AttachedFile, ThinkingStep } from './types';
-  import arrowIcon from '@/assets/images/ventAI/chatModalBlue/4-2.svg';
-  import copyIcon from '@/assets/images/ventAI/chatModalBlue/4-3.svg';
-  import closeIcon from '@/assets/images/ventAI/chatModalBlue/4-4.svg';
+
+  const getCssUrl = (varName: string) => {
+    const val = getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
+    return val.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
+  };
+
+  const tableIcons = {
+    copy: getCssUrl('--img-chat-copy-icon'),
+    download: getCssUrl('--img-chat-download-icon-btn'),
+    preview: getCssUrl('--img-chat-preview-icon'),
+    copySuccess: getCssUrl('--img-chat-copy-success-icon'),
+  };
+
+  const copyIconUrl = computed(() => {
+    const icon = getCssUrl('--img-chat-copy-icon');
+    const successIcon = getCssUrl('--img-chat-copy-success-icon');
+    return (index: number) => (copiedMessageIndex.value === index ? successIcon : icon);
+  });
 
   // 全局计时器 - 每秒刷新一次,用于实时显示思考耗时
   const nowTs = ref(Date.now());
@@ -198,9 +221,10 @@
   }>();
 
   const messagesRef = ref<HTMLElement>();
-  const expandedThinking = reactive<Record<number, boolean>>({});
+  const collapsedThinking = reactive<Record<number, boolean>>({});
   const expandedAgents = reactive<Record<string, boolean>>({});
   const isAtBottom = ref(true);
+  const copiedMessageIndex = ref(-1);
 
   // 表格预览状态
   const previewTableHtml = ref('');
@@ -219,15 +243,36 @@
     switch (action) {
       case 'copy': {
         const markdown = tableHtmlToMarkdown(tableHtml);
-        navigator.clipboard.writeText(markdown).catch(() => {
-          const ta = document.createElement('textarea');
-          ta.value = markdown;
-          ta.style.position = 'fixed';
-          ta.style.opacity = '0';
-          document.body.appendChild(ta);
-          ta.select();
-          document.execCommand('copy');
-          document.body.removeChild(ta);
+        const doCopy = async () => {
+          try {
+            await navigator.clipboard.writeText(markdown);
+          } catch {
+            const ta = document.createElement('textarea');
+            ta.value = markdown;
+            ta.style.position = 'fixed';
+            ta.style.opacity = '0';
+            document.body.appendChild(ta);
+            ta.select();
+            document.execCommand('copy');
+            document.body.removeChild(ta);
+          }
+        };
+        doCopy().then(() => {
+          const btn = target;
+          const img = btn.querySelector('img');
+          const successIcon = btn.dataset.iconSuccess;
+          const originalIcon = btn.dataset.icon;
+          if (img && successIcon) {
+            img.src = successIcon;
+            btn.title = '复制成功';
+            const reset = () => {
+              img.src = originalIcon!;
+              btn.title = '复制Markdown';
+              wrapper.removeEventListener('mouseleave', reset);
+            };
+            const wrapper = btn.closest('.markdown-table-wrapper')!;
+            wrapper.addEventListener('mouseleave', reset);
+          }
         });
         break;
       }
@@ -269,6 +314,14 @@
     }
   };
 
+  const forceScrollToBottom = () => {
+    const el = messagesRef.value;
+    if (el) {
+      el.scrollTop = el.scrollHeight;
+    }
+    isAtBottom.value = true;
+  };
+
   onMounted(() => {
     messagesRef.value?.addEventListener('click', handleTableAction);
     messagesRef.value?.addEventListener('scroll', checkScrollBottom);
@@ -286,14 +339,26 @@
     }
   });
 
-  const toggleThinking = (index: number) => {
-    expandedThinking[index] = !expandedThinking[index];
+  const toggleThinkingCard = (index: number) => {
+    collapsedThinking[index] = !collapsedThinking[index];
   };
 
   const toggleAgent = (key: string) => {
     expandedAgents[key] = !expandedAgents[key];
   };
 
+  const getLatestStepMessage = (group: AgentGroup): string => {
+    if (group.steps.length === 0) return '';
+    const last = group.steps[group.steps.length - 1];
+    if (last.type === 'executing') return last.message || '正在执行...';
+    if (last.type === 'tool_call') return last.message || last.tool || '';
+    if (last.type === 'tool_result') return last.message || '';
+    if (last.type === 'agent_start') return last.message || '';
+    if (last.type === 'agent_done') return last.message || '';
+    if (last.type === 'updated_todo_list') return '任务列表已更新';
+    return '';
+  };
+
   interface AgentGroup {
     agent: string;
     steps: ThinkingStep[];
@@ -324,10 +389,11 @@
     return dayjs(createdAt).format('YYYY-MM-DD HH:mm:ss');
   };
 
-  const copyMessageContent = async (content: string) => {
+  const copyMessageContent = async (content: string, index: number) => {
     if (!content) return;
     try {
       await navigator.clipboard.writeText(content);
+      copiedMessageIndex.value = index;
     } catch {
       const textarea = document.createElement('textarea');
       textarea.value = content;
@@ -337,10 +403,11 @@
       textarea.select();
       document.execCommand('copy');
       document.body.removeChild(textarea);
+      copiedMessageIndex.value = index;
     }
   };
 
-  defineExpose({ messagesRef, isAtBottom });
+  defineExpose({ messagesRef, isAtBottom, forceScrollToBottom });
 </script>
 
 <style scoped lang="less">
@@ -356,9 +423,26 @@
     flex: 1;
     overflow-y: auto;
     padding: 20px;
+    position: relative;
+
+    .welcome-empty {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      .welcome-img {
+        max-width: 300px;
+        max-height: 300px;
+        object-fit: contain;
+      }
+    }
 
     .message-wrapper {
-      margin-bottom: 20px;
+      // margin-bottom: 20px;
 
       .ai-message {
         display: flex;
@@ -385,16 +469,14 @@
           /* 思考过程卡片 */
           .thinking-card {
             margin-bottom: 12px;
-            border: 1px solid rgba(63, 80, 106, 0.4);
-            border-radius: 8px;
-            background: rgba(10, 132, 255, 0.04);
             overflow: hidden;
 
-            .thinking-header {
+            .thinking-duration-bar {
               display: flex;
               align-items: center;
               justify-content: space-between;
-              padding: 10px 14px;
+              padding: 8px 14px;
+              border-bottom: 1px solid rgba(63, 80, 106, 0.3);
               cursor: pointer;
               user-select: none;
               transition: background 0.2s;
@@ -403,6 +485,28 @@
                 background: rgba(10, 132, 255, 0.08);
               }
 
+              .thinking-duration {
+                font-size: 16px;
+                color: #8b949e;
+              }
+
+              .thinking-arrow {
+                color: #8b949e;
+                display: flex;
+                align-items: center;
+                transition: transform 0.2s;
+
+                &.expanded {
+                  transform: rotate(180deg);
+                }
+              }
+            }
+
+            .thinking-header {
+              display: flex;
+              align-items: center;
+              padding: 10px 14px;
+
               .thinking-header-left {
                 display: flex;
                 align-items: center;
@@ -412,17 +516,15 @@
               .thinking-icon {
                 width: 16px;
                 height: 16px;
-                background-image: var(--img-chat-thinking-icon, none);
+                background-image: var(--img-chat-thinking-icon);
                 background-repeat: no-repeat;
                 background-size: 100% 100%;
-                /* fallback: 用一个 brain/lightbulb emoji 风格的 SVG */
-                background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M8 1.5a4.5 4.5 0 0 1 3.5 7.35V11a1 1 0 0 1-1 1H5.5a1 1 0 0 1-1-1v-2.15A4.5 4.5 0 0 1 8 1.5Z' stroke='%230a84ff' stroke-width='1.2'/%3E%3Cpath d='M6 13.5h4M6.5 15h3' stroke='%230a84ff' stroke-width='1.2' stroke-linecap='round'/%3E%3C/svg%3E");
               }
 
               .thinking-title {
                 font-size: 13px;
                 font-weight: 500;
-                color: #0a84ff;
+                color: #8b949e;
               }
 
               .thinking-count {
@@ -432,36 +534,21 @@
                 padding: 1px 6px;
                 border-radius: 10px;
               }
-
-              .thinking-duration {
-                font-size: 12px;
-                color: #8b949e;
-                margin-left: 4px;
-              }
-            }
-
-            .thinking-arrow {
-              color: #8b949e;
-              display: flex;
-              align-items: center;
-              transition: transform 0.2s;
-
-              &.expanded {
-                transform: rotate(180deg);
-              }
             }
 
             .thinking-body {
-              border-top: 1px solid rgba(63, 80, 106, 0.3);
               padding: 8px 14px;
-              max-height: 400px;
-              overflow-y: auto;
 
               .agent-group {
                 margin-bottom: 8px;
-                border: 1px solid rgba(63, 80, 106, 0.25);
+                border: 1px solid transparent;
                 border-radius: 6px;
                 overflow: hidden;
+                transition: border-color 0.2s;
+
+                &.expanded {
+                  border-color: rgba(63, 80, 106, 0.25);
+                }
 
                 &:last-child {
                   margin-bottom: 0;
@@ -474,7 +561,6 @@
                   padding: 8px 12px;
                   cursor: pointer;
                   user-select: none;
-                  background: rgba(10, 132, 255, 0.06);
                   transition: background 0.2s;
 
                   &:hover {
@@ -490,7 +576,7 @@
                   .agent-group-icon {
                     width: 14px;
                     height: 14px;
-                    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none'%3E%3Ccircle cx='7' cy='5' r='2.5' stroke='%230a84ff' stroke-width='1'/%3E%3Cpath d='M2.5 12.5c0-2.49 2.01-4.5 4.5-4.5s4.5 2.01 4.5 4.5' stroke='%230a84ff' stroke-width='1' stroke-linecap='round'/%3E%3C/svg%3E");
+                    background-image: var(--img-chat-agent-icon);
                     background-repeat: no-repeat;
                     background-size: 100% 100%;
                     flex-shrink: 0;
@@ -499,20 +585,37 @@
                   .agent-group-name {
                     font-size: 13px;
                     font-weight: 500;
-                    color: #0a84ff;
+                    color: #fff;
                   }
 
-                  .agent-group-count {
-                    font-size: 11px;
+                  .agent-group-latest {
+                    font-size: 12px;
                     color: #8b949e;
-                    background: rgba(10, 132, 255, 0.08);
-                    padding: 1px 5px;
-                    border-radius: 8px;
+                    margin-left: 8px;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+                    flex: 1;
+                    min-width: 0;
+                  }
+
+                  .agent-arrow {
+                    margin-left: 8px;
+                    flex-shrink: 0;
+                    display: flex;
+                    align-items: center;
+                    transition: transform 0.2s;
+
+                    &.expanded {
+                      transform: rotate(180deg);
+                    }
                   }
                 }
 
                 .agent-group-body {
                   padding: 4px 12px;
+                  max-height: 300px;
+                  overflow-y: auto;
                 }
               }
 
@@ -520,7 +623,6 @@
                 .step-item {
                   display: flex;
                   align-items: flex-start;
-                  gap: 8px;
                   padding: 6px 0;
                   border-bottom: 1px solid rgba(63, 80, 106, 0.15);
 
@@ -528,15 +630,6 @@
                     border-bottom: none;
                   }
 
-                  .step-icon {
-                    width: 18px;
-                    height: 18px;
-                    flex-shrink: 0;
-                    margin-top: 1px;
-                    background-repeat: no-repeat;
-                    background-size: 100% 100%;
-                  }
-
                   .step-content {
                     flex: 1;
                     font-size: 13px;
@@ -567,25 +660,8 @@
                   }
                 }
 
-                /* agent_start */
-                .step-agent-start .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='6' r='3' stroke='%230a84ff' stroke-width='1.2'/%3E%3Cpath d='M3 16c0-3.31 2.69-6 6-6s6 2.69 6 6' stroke='%230a84ff' stroke-width='1.2' stroke-linecap='round'/%3E%3C/svg%3E");
-                }
-
-                /* tool_call */
-                .step-tool-call .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M10.5 2.5l5 5-8 8H2.5v-5.5l8-8Z' stroke='%23d29922' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpath d='M7 7l4 4' stroke='%23d29922' stroke-width='1.2'/%3E%3C/svg%3E");
-                }
-
-                /* executing */
-                .step-executing .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='9' r='7' stroke='%230a84ff' stroke-width='1.2' stroke-dasharray='4 2'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 9 9' to='360 9 9' dur='2s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/svg%3E");
-                }
-
                 /* updated_todo_list */
-                .step-todo .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Crect x='2' y='2' width='14' height='14' rx='2' stroke='%233fb950' stroke-width='1.2'/%3E%3Cpath d='M5 9l3 3 5-6' stroke='%233fb950' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
-
+                .step-todo {
                   .todo-list {
                     .todo-item {
                       display: flex;
@@ -617,16 +693,6 @@
                     }
                   }
                 }
-
-                /* tool_result */
-                .step-tool-result .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='9' r='7' stroke='%233fb950' stroke-width='1.2'/%3E%3Cpath d='M6 9l2 2 4-4' stroke='%233fb950' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
-                }
-
-                /* agent_done */
-                .step-agent-done .step-icon {
-                  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Ccircle cx='9' cy='9' r='7' stroke='%233fb950' stroke-width='1.2'/%3E%3Cpath d='M5.5 9l2.5 2.5 4.5-5' stroke='%233fb950' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
-                }
               }
             }
           }
@@ -919,7 +985,7 @@
       }
 
       .ai-message .message-actions {
-        padding: 4px 0 0 50px;
+        padding: 4px 0 0 10px;
       }
 
       .user-message .message-actions {

+ 2 - 2
src/views/ventAI/manageAssistent/components/chatModal/FilePreviewPanel.vue

@@ -64,7 +64,7 @@
       cursor: pointer;
       width: 36px;
       height: 36px;
-      background-image: var(--img-chat-upload-bg);
+      background-image: var(--img-chat-close-bg);
       background-repeat: no-repeat;
       background-size: 100% 100%;
       display: flex;
@@ -77,7 +77,7 @@
       .btn-close-icon {
         width: 20px;
         height: 20px;
-        background-image: var(--img-chat-close-icon);
+        background-image: var(--img-chat-minimize-icon);
         background-repeat: no-repeat;
         background-size: 100% 100%;
       }

+ 76 - 87
src/views/ventAI/manageAssistent/components/chatModal/TaskListPanel.vue

@@ -1,13 +1,19 @@
 <template>
   <div class="task-list-panel">
+    <!-- 操作区域(顶部) -->
+    <div class="options-area">
+      <div v-for="item in optionItems" :key="item.type" :class="['options-area-item', `options-${item.type}`]" @click="handleOptionClick(item.type)">
+        <div class="options-img">
+          <div class="options-icon"></div>
+        </div>
+        <a-button size="small" type="primary">{{ item.label }}</a-button>
+      </div>
+    </div>
+
     <!-- 搜索模式 -->
     <div v-if="activeOption === 'search'" class="search-header">
       <a-input v-model:value="searchKeyword" placeholder="搜索任务名称..." allow-clear size="small" class="search-input" />
     </div>
-    <!-- 历史记录模式 -->
-    <div v-else class="task-header">
-      <span class="task-title">历史记录</span>
-    </div>
 
     <div class="task-list">
       <div
@@ -17,26 +23,15 @@
         @click="emit('switch-task', task.id)"
       >
         <span class="task-name">{{ task.name }}</span>
-        <div class="task-delete" @click.stop="emit('delete-task', task, index)">
-          <DeleteOutlined />
+        <div class="task-right">
+          <span class="task-time">{{ formatRelativeTime(task.updatedAt) }}</span>
+          <div class="task-delete" @click.stop="emit('delete-task', task, index)">
+            <DeleteOutlined />
+          </div>
         </div>
       </div>
       <div v-if="activeOption === 'search' && searchKeyword && filteredTaskList.length === 0" class="empty-hint"> 未找到匹配的任务 </div>
     </div>
-
-    <div class="options-area">
-      <div
-        v-for="item in optionItems"
-        :key="item.type"
-        :class="['options-area-item', `options-${item.type}`, { active: activeOption === item.type }]"
-        @click="handleOptionClick(item.type)"
-      >
-        <div class="options-img">
-          <div class="options-icon"></div>
-        </div>
-        <a-button size="small" type="primary">{{ item.label }}</a-button>
-      </div>
-    </div>
   </div>
 </template>
 
@@ -56,15 +51,15 @@
     (e: 'delete-task', task: Task, index: number): void;
   }>();
 
-  type OptionType = 'search' | 'history' | 'add';
+  type OptionType = 'add' | 'search' | 'skill';
 
-  const activeOption = ref<OptionType>('history');
+  const activeOption = ref<OptionType>('add');
   const searchKeyword = ref('');
 
   const optionItems = [
-    { type: 'search' as OptionType, label: '内容搜索' },
-    { type: 'history' as OptionType, label: '历史记录' },
-    { type: 'add' as OptionType, label: '新增任务' },
+    { type: 'add' as OptionType, label: '新建任务' },
+    { type: 'search' as OptionType, label: '搜索' },
+    { type: 'skill' as OptionType, label: '技能' },
   ];
 
   const filteredTaskList = computed(() => {
@@ -75,15 +70,24 @@
     return props.taskList.filter((task) => task.name.toLowerCase().includes(keyword));
   });
 
-  const handleAddTask = () => {
-    emit('create-task');
+  const formatRelativeTime = (dateStr?: string) => {
+    if (!dateStr) return '刚刚';
+    const now = Date.now();
+    const time = new Date(dateStr).getTime();
+    const diff = now - time;
+    if (diff < 60 * 1000) return '刚刚';
+    if (diff < 60 * 60 * 1000) return `${Math.floor(diff / (60 * 1000))}分钟前`;
+    if (diff < 24 * 60 * 60 * 1000) return `${Math.floor(diff / (60 * 60 * 1000))}小时前`;
+    return `${Math.floor(diff / (24 * 60 * 60 * 1000))}天前`;
   };
 
   const handleOptionClick = (type: OptionType) => {
-    activeOption.value = type;
     if (type === 'add') {
       emit('create-task');
+    } else if (type === 'skill') {
+      // TODO: 技能点击事件
     } else {
+      activeOption.value = type;
       searchKeyword.value = '';
     }
   };
@@ -92,6 +96,7 @@
 <style scoped lang="less">
   .task-list-panel {
     width: 260px;
+    height: 100%;
     display: flex;
     flex-direction: column;
     background-image: var(--img-chat-task-panel-bg);
@@ -117,31 +122,12 @@
       }
     }
 
-    .task-header {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      padding-bottom: 10px;
-
-      .task-title {
-        font-size: 15px;
-        line-height: 1.4;
-        color: #0a84ff;
-      }
-      .task-add-btn {
-        background-color: #0a84ff;
-
-        &:hover {
-          background-color: #0077e6;
-        }
-      }
-    }
-
     .task-list {
       flex: 1;
       overflow-y: auto;
 
       .task-item {
+        height: 36px;
         display: flex;
         align-items: center;
         gap: 10px;
@@ -157,8 +143,9 @@
         }
 
         &.active {
-          background: rgba(10, 132, 255, 0.1);
-          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+          background: transparent;
+          box-shadow: inset 0 0 8px rgba(10, 132, 255, 0.4);
+          border: 1px solid rgba(10, 132, 255, 0.3);
           color: #e0e6ed;
         }
 
@@ -181,17 +168,23 @@
           flex: 1;
         }
 
+        .task-time {
+          font-size: 12px;
+          color: #8b949e;
+          flex-shrink: 0;
+          white-space: nowrap;
+        }
+
         .task-delete {
           flex-shrink: 0;
           width: 28px;
           height: 28px;
-          display: flex;
+          display: none;
           align-items: center;
           justify-content: center;
           border-radius: 4px;
           color: #8b949e;
           font-size: 14px;
-          visibility: hidden;
           transition: all 0.2s;
 
           &:hover {
@@ -200,8 +193,12 @@
           }
         }
 
+        &:hover .task-time {
+          display: none;
+        }
+
         &:hover .task-delete {
-          visibility: visible;
+          display: flex;
         }
       }
 
@@ -215,73 +212,65 @@
 
     .options-area {
       display: flex;
-      gap: 6px;
-      padding-top: 8px;
-      border-top: 1px solid rgba(63, 80, 106, 0.3);
+      flex-direction: column;
+      gap: 4px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid rgba(63, 80, 106, 0.3);
 
       .options-area-item {
-        flex: 1;
         display: flex;
-        flex-direction: column;
+        flex-direction: row;
         align-items: center;
-        gap: 6px;
+        gap: 10px;
         cursor: pointer;
         border-radius: 6px;
+        padding: 6px 8px;
         transition: all 0.3s;
 
+        &:hover {
+          background: rgba(10, 132, 255, 0.1);
+        }
+
         .options-img {
-          width: 60px;
-          height: 60px;
+          width: 32px;
+          height: 32px;
           display: flex;
           align-items: center;
           justify-content: center;
-          background-image: var(--img-chat-options-bg);
+          flex-shrink: 0;
+          background-image: var(--img-chat-options-icon-border);
           background-repeat: no-repeat;
-          background-size: 45px 45px;
+          background-size: 100% 100%;
           background-position: center;
         }
 
-        &.active .options-img {
-          background-image: var(--img-chat-options-active-bg);
-          background-size: 60px 60px;
-        }
-
         .options-icon {
-          width: 16px;
-          height: 16px;
+          width: 14px;
+          height: 14px;
           background-repeat: no-repeat;
           background-size: 100% 100%;
           background-position: center;
         }
 
-        &.options-search .options-icon {
-          background-image: var(--img-chat-options-search-icon);
-        }
-        &.options-search.active .options-icon {
-          background-image: var(--img-chat-options-search-active-icon);
+        &.options-add .options-icon {
+          background-image: var(--img-chat-options-add-icon);
         }
 
-        &.options-history .options-icon {
-          background-image: var(--img-chat-options-history-icon);
-        }
-        &.options-history.active .options-icon {
-          background-image: var(--img-chat-options-history-active-icon);
+        &.options-search .options-icon {
+          background-image: var(--img-chat-options-search-icon);
         }
 
-        &.options-add .options-icon {
-          background-image: var(--img-chat-options-add-icon);
-        }
-        &.options-add.active .options-icon {
-          background-image: var(--img-chat-options-add-active-icon);
+        &.options-skill .options-icon {
+          background-image: var(--img-chat-options-skill-icon);
         }
 
         .zxm-btn {
           font-size: 14px;
-          padding: 2px 6px;
+          padding: 0;
           height: auto;
           background: transparent !important;
           border: none;
-          color: #0a84ff;
+          color: #e0e6ed;
           box-shadow: none;
         }
       }

+ 0 - 397
src/views/ventAI/manageAssistent/components/chatModal/ThinkingPanel.vue

@@ -1,397 +0,0 @@
-<template>
-  <div class="thinking-panel">
-    <div class="panel-header">
-      <div class="panel-left">
-        <div class="agent-avatar-small"></div>
-        <div class="panel-title-group">
-          <div class="panel-title">{{ currentDisplayAgent?.agentName || '智能分析' }}</div>
-        </div>
-      </div>
-      <div class="close-btn" @click="emit('close')">
-        <div class="btn-close-icon"></div>
-      </div>
-    </div>
-
-    <div class="thinking-section">
-      <div class="section-content thinking-content" ref="thinkingContentRef">
-        <div v-if="!thinkingSections.length" class="empty-thinking">暂无思考过程</div>
-        <div v-for="(section, idx) in thinkingSections" :key="idx" :class="['timeline-item', `timeline-${section.type}`]">
-          <div class="timeline-marker">
-            <div class="timeline-dot"></div>
-            <div v-if="idx < thinkingSections.length - 1" class="timeline-line"></div>
-          </div>
-          <div class="timeline-body">
-            <div class="timeline-header">
-              <span class="timeline-label">{{ section.label }}</span>
-            </div>
-            <div class="timeline-text" v-html="renderMarkdown(section.content)"></div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <div class="agent-horizontal-list" v-if="selectedAgentParentMsg?.agentAnswers?.length">
-      <div
-        v-for="agent in selectedAgentParentMsg!.agentAnswers"
-        :key="agent.id"
-        :class="['agent-chip', { active: currentDisplayAgent?.id === agent.id }]"
-        @click="emit('select-agent', agent)"
-      >
-        <div class="chip-body">
-          <div class="chip-icon"></div>
-          <div class="chip-name">
-            {{ agent.agentName || '智能分析' }}
-          </div>
-        </div>
-        <div class="chip-status">
-          <span v-if="agent.status === 'thinking'">正在连接</span>
-          <span v-else>已完成</span>
-        </div>
-        <div class="chip-border"></div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { ref } from 'vue';
-  import { renderMarkdown } from './utils';
-  import type { AgentAnswer, Message, ThinkingSection } from './types';
-
-  defineProps<{
-    currentDisplayAgent: AgentAnswer | null;
-    selectedAgentParentMsg: Message | null;
-    thinkingSections: ThinkingSection[];
-  }>();
-
-  const emit = defineEmits<{
-    (e: 'select-agent', answer: AgentAnswer): void;
-    (e: 'close'): void;
-  }>();
-
-  const thinkingContentRef = ref<HTMLElement | null>(null);
-
-  defineExpose({ thinkingContentRef });
-</script>
-
-<style scoped lang="less">
-  .thinking-panel {
-    height: 100%;
-    width: 100%;
-    display: flex;
-    flex-direction: column;
-    padding: 12px 16px;
-
-    .panel-header {
-      display: flex;
-      padding: 0;
-      justify-content: space-between;
-      align-items: center;
-      margin-bottom: 6px;
-      flex-shrink: 0;
-
-      .panel-left {
-        display: flex;
-        align-items: center;
-        gap: 12px;
-      }
-
-      .agent-avatar-small {
-        width: 35px;
-        height: 36px;
-        border-radius: 8px;
-        background-image: var(--img-chat-panel-header);
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-        flex-shrink: 0;
-      }
-
-      .panel-title-group {
-        display: flex;
-        flex-direction: column;
-        line-height: 1;
-      }
-
-      .panel-title {
-        font-size: 15px;
-        font-weight: 600;
-        line-height: 1.4;
-        color: #0a84ff;
-      }
-      .close-btn {
-        cursor: pointer;
-        width: 36px;
-        height: 36px;
-        background-image: var(--img-chat-upload-bg);
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        flex-shrink: 0;
-        transition: all 0.3s;
-        margin-bottom: auto;
-
-        .btn-close-icon {
-          width: 20px;
-          height: 20px;
-          background-image: var(--img-chat-close-icon);
-          background-repeat: no-repeat;
-          background-size: 100% 100%;
-        }
-      }
-    }
-
-    .thinking-section {
-      flex: 1;
-      height: 0;
-      display: flex;
-      flex-direction: column;
-      border: 1px solid #0a84ff;
-      border-radius: 4px 4px 0 0;
-
-      .thinking-content {
-        flex: 1;
-        background: rgba(10, 132, 255, 0.05);
-        border: 1px solid rgba(63, 80, 106, 0.5);
-        border-radius: 8px;
-        padding: 20px 16px;
-        overflow-y: auto;
-        font-size: 12px;
-        font-weight: 400;
-        color: #e0e6ed;
-        line-height: 1.6;
-
-        .empty-thinking {
-          color: #8b949e;
-          font-style: italic;
-          text-align: center;
-          padding: 32px 0;
-        }
-
-        .timeline-item {
-          display: flex;
-          gap: 0;
-          position: relative;
-
-          .timeline-marker {
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            width: 28px;
-            flex-shrink: 0;
-            position: relative;
-          }
-
-          .timeline-dot {
-            width: 12px;
-            height: 12px;
-            border-radius: 50%;
-            border: 2px solid #fff;
-            flex-shrink: 0;
-            margin-top: 6px;
-            position: relative;
-            z-index: 1;
-          }
-
-          .timeline-line {
-            flex: 1;
-            width: 0;
-            min-height: 16px;
-            margin: 4px 0;
-            border-left: 2px dashed #8b949e;
-          }
-
-          &.timeline-select {
-            .timeline-dot {
-              background: #0a84ff;
-              box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.15);
-            }
-            .timeline-header {
-              color: #e0e6ed;
-            }
-          }
-          &.timeline-params {
-            display: none;
-            .timeline-dot {
-              background: #faad14;
-              box-shadow: 0 0 0 3px rgba(223, 91, 12, 0.15);
-            }
-            .timeline-header {
-              color: #e0e6ed;
-            }
-          }
-          &.timeline-result {
-            .timeline-dot {
-              background: #52c41a;
-              box-shadow: 0 0 0 3px rgba(46, 125, 50, 0.15);
-            }
-          }
-
-          .timeline-body {
-            flex: 1;
-            min-width: 0;
-            padding-bottom: 16px;
-            padding-left: 12px;
-          }
-
-          .timeline-header {
-            font-size: 13px;
-            font-weight: 500;
-            margin-bottom: 8px;
-            line-height: 1.4;
-          }
-
-          .timeline-text {
-            font-size: 14px;
-            font-weight: 400;
-            color: #e0e6ed;
-            line-height: 1.6;
-
-            :deep(p) {
-              margin: 0 0 6px;
-            }
-            :deep(code) {
-              background: rgba(10, 132, 255, 0.1);
-              padding: 2px 6px;
-              border-radius: 3px;
-              font-family: monospace;
-              font-size: 12px;
-            }
-            :deep(pre) {
-              background: rgba(10, 132, 255, 0.1);
-              padding: 10px;
-              border-radius: 4px;
-              overflow-x: auto;
-              margin: 8px 0;
-            }
-            :deep(pre code) {
-              background: transparent;
-              padding: 0;
-            }
-            :deep(ul),
-            :deep(ol) {
-              padding-left: 20px;
-              margin: 4px 0;
-            }
-            :deep(li) {
-              margin-bottom: 2px;
-            }
-            :deep(h1),
-            :deep(h2),
-            :deep(h3),
-            :deep(h4) {
-              margin: 8px 0 4px;
-              font-weight: 600;
-            }
-            :deep(blockquote) {
-              border-left: 3px solid rgba(63, 80, 106, 0.5);
-              padding-left: 12px;
-              margin: 8px 0;
-              color: #8b949e;
-            }
-            :deep(table) {
-              border-collapse: collapse;
-              width: 100%;
-              margin: 8px 0;
-            }
-            :deep(th),
-            :deep(td) {
-              border: 1px solid rgba(63, 80, 106, 0.5);
-              padding: 6px 10px;
-              text-align: left;
-            }
-            :deep(th) {
-              background: rgba(10, 132, 255, 0.1);
-              font-weight: 600;
-            }
-            :deep(strong) {
-              font-weight: 600;
-            }
-          }
-        }
-      }
-    }
-
-    .agent-horizontal-list {
-      display: flex;
-      gap: 10px;
-      padding: 8px 0;
-      overflow-x: auto;
-      align-items: center;
-      flex-shrink: 0;
-      border-radius: 0 0 4px 4px;
-      border-top: none;
-      background-color: rgba(10, 132, 255, 0.05);
-    }
-
-    .agent-chip {
-      display: flex;
-      align-items: center;
-      gap: 10px;
-      padding: 8px 12px 8px 20px;
-      background: rgba(10, 132, 255, 0.08);
-      border-radius: 10px;
-      border: 1px solid rgba(63, 80, 106, 0.5);
-      min-width: 140px;
-      cursor: pointer;
-      transition: all 0.2s;
-      position: relative;
-
-      .chip-body {
-        display: flex;
-        align-items: start;
-        gap: 8px;
-        flex-direction: column;
-      }
-
-      .chip-border {
-        position: absolute;
-        left: 10px;
-        top: 16px;
-        width: 5px;
-        height: 35px;
-        border: 2px solid #0a84ff;
-        pointer-events: none;
-        border-right: none;
-      }
-      .chip-icon {
-        width: 24px;
-        height: 24px;
-        background-image: var(--img-chat-thinking-bg);
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-      }
-      .chip-name {
-        font-size: 13px;
-        font-weight: 500;
-        line-height: 1.4;
-        color: #e0e6ed;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        width: 100px;
-      }
-
-      .chip-status {
-        font-size: 11px;
-        font-weight: 400;
-        line-height: 1.3;
-        color: #8b949e;
-        position: absolute;
-        top: 10px;
-        right: 10px;
-      }
-
-      &.active {
-        background-color: rgba(10, 132, 255, 0.12);
-        box-shadow: 0 6px 18px rgba(10, 132, 255, 0.06);
-        border-color: #0a84ff;
-
-        .chip-status {
-          color: #0a84ff;
-        }
-      }
-    }
-  }
-</style>

+ 1 - 0
src/views/ventAI/manageAssistent/components/chatModal/types.ts

@@ -53,6 +53,7 @@ export interface Task {
   messages: Message[];
   attachedFiles: AttachedFile[];
   wordUrl?: string;
+  updatedAt?: string;
 }
 
 export type SectionType = 'select' | 'params' | 'result';

+ 7 - 7
src/views/ventAI/manageAssistent/components/chatModal/utils.ts

@@ -1,25 +1,25 @@
 import { marked } from 'marked';
 
-export const renderMarkdown = (text: string): string => {
+export const renderMarkdown = (text: string, icons?: { copy: string; download: string; preview: string; copySuccess: string }): string => {
   if (!text) return '';
   const processed = text.replace(/<br\s*\/?>/gi, '  \n');
   const html = marked.parse(processed) as string;
-  return wrapTables(html);
+  return icons ? wrapTables(html, icons) : html;
 };
 
-const wrapTables = (html: string): string => {
+export const wrapTables = (html: string, icons: { copy: string; download: string; preview: string; copySuccess: string }): string => {
   return html.replace(/<table>([\s\S]*?)<\/table>/g, (match) => {
     const encodedTable = encodeURIComponent(match);
     return `<div class="markdown-table-wrapper">
       <div class="table-actions">
-        <span class="table-action-btn" data-action="copy" data-table="${encodedTable}" title="复制Markdown">
-          <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="4.5" y="4.5" width="7" height="7" rx="1" stroke="currentColor" stroke-width="1.2"/><path d="M9.5 4.5V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v5.5a1 1 0 0 0 1 1h1.5" stroke="currentColor" stroke-width="1.2"/></svg>
+        <span class="table-action-btn" data-action="copy" data-table="${encodedTable}" data-icon="${icons.copy}" data-icon-success="${icons.copySuccess}" title="复制Markdown">
+          <img src="${icons.copy}" width="14" height="14" />
         </span>
         <span class="table-action-btn" data-action="csv" data-table="${encodedTable}" title="下载CSV">
-          <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v7M4 7l3 3 3-3M3 12h8" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          <img src="${icons.download}" width="14" height="14" />
         </span>
         <span class="table-action-btn" data-action="preview" data-table="${encodedTable}" title="预览表格">
-          <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="1" y="1" width="12" height="12" rx="1.5" stroke="currentColor" stroke-width="1.2"/><path d="M1 5h12M1 9h12M5 1v12M9 1v12" stroke="currentColor" stroke-width="1.2"/></svg>
+          <img src="${icons.preview}" width="14" height="14" />
         </span>
       </div>
       ${match}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels