瀏覽代碼

Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base

lxh 3 周之前
父節點
當前提交
25658dff25

+ 3 - 0
src/assets/icons/add-plane.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.978" height="15.978" viewBox="0 0 15.978 15.978">
+  <path id="路径_57020" data-name="路径 57020" d="M70.415,62.7A7.989,7.989,0,1,0,78.4,70.685,7.989,7.989,0,0,0,70.415,62.7Zm4.788,8.9H71.3V75.5H69.48V71.594H65.575V69.776H69.48V65.871H71.3v3.905H75.2Z" transform="translate(-62.426 -62.696)" fill="#fff"/>
+</svg>

+ 3 - 0
src/assets/icons/add.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.979" height="15.978" viewBox="0 0 15.979 15.978">
+  <path id="添加对话" d="M70.415,62.7A7.989,7.989,0,1,0,78.4,70.685,7.989,7.989,0,0,0,70.415,62.7Zm4.788,8.9H71.3V75.5H69.48V71.594H65.575V69.776H69.48V65.871H71.3v3.905H75.2Z" transform="translate(-62.426 -62.696)" fill="#2cb6ff"/>
+</svg>

+ 7 - 0
src/assets/icons/expand.svg

@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16.761" height="16.761" viewBox="0 0 16.761 16.761">
+  <g id="展开" transform="translate(0 16.761) rotate(-90)">
+    <path id="路径_57023" data-name="路径 57023" d="M2.514,15.084a.838.838,0,0,1-.839-.838V2.514a.839.839,0,0,1,.839-.838H14.246a.839.839,0,0,1,.839.838V14.247a.838.838,0,0,1-.839.838H2.514ZM0,14.247a2.514,2.514,0,0,0,2.514,2.514H14.246a2.514,2.514,0,0,0,2.514-2.514V2.514A2.514,2.514,0,0,0,14.246,0H2.514A2.514,2.514,0,0,0,0,2.514V14.247Z" transform="translate(0 0)" fill="#fff"/>
+    <path id="路径_57024" data-name="路径 57024" d="M0,.839a.838.838,0,0,0,.838.838H15.923a.838.838,0,1,0,0-1.676H.838A.838.838,0,0,0,0,.839ZM6.111,5.274a.838.838,0,0,1,1.186,0L8.38,6.357,9.463,5.274a.838.838,0,1,1,1.186,1.186L8.972,8.135a.838.838,0,0,1-1.185,0L6.111,6.459a.838.838,0,0,1,0-1.186Z" transform="translate(0 4.19)" fill="#fff"/>
+    <path id="路径_57025" data-name="路径 57025" d="M.838,6.7a.838.838,0,0,0,.838-.838V.838A.838.838,0,0,0,0,.838V5.866A.838.838,0,0,0,.838,6.7Zm15.085,0a.838.838,0,0,0,.838-.838V.838a.838.838,0,0,0-1.675,0V5.866A.838.838,0,0,0,15.923,6.7Z" transform="translate(0 1.677)" fill="#fff"/>
+  </g>
+</svg>

+ 7 - 0
src/assets/icons/fold.svg

@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16.761" height="16.761" viewBox="0 0 16.761 16.761">
+  <g id="收起" transform="translate(-85.351 102.11) rotate(-90)">
+    <path id="路径_57023" data-name="路径 57023" d="M87.864,87.027a.838.838,0,0,0-.839.838V99.6a.839.839,0,0,0,.839.838H99.6a.839.839,0,0,0,.839-.838V87.865a.838.838,0,0,0-.839-.838H87.864Zm-2.514.838a2.514,2.514,0,0,1,2.514-2.514H99.6a2.514,2.514,0,0,1,2.514,2.514V99.6a2.514,2.514,0,0,1-2.514,2.514H87.864A2.514,2.514,0,0,1,85.35,99.6V87.865Z" transform="translate(0 0)" fill="#fff"/>
+    <path id="路径_57024" data-name="路径 57024" d="M85.35,306.244a.838.838,0,0,1,.838-.838h15.084a.838.838,0,0,1,0,1.676H86.188a.838.838,0,0,1-.838-.839Zm6.111-4.435a.838.838,0,0,0,1.186,0l1.083-1.083,1.083,1.083A.838.838,0,1,0,96,300.623l-1.676-1.675a.838.838,0,0,0-1.185,0l-1.676,1.675a.838.838,0,0,0,0,1.186Z" transform="translate(0 -209.162)" fill="#fff"/>
+    <path id="路径_57025" data-name="路径 57025" d="M86.188,512a.838.838,0,0,1,.838.838v5.028a.838.838,0,0,1-1.675,0v-5.028A.838.838,0,0,1,86.188,512Zm15.084,0a.838.838,0,0,1,.838.838v5.028a.838.838,0,0,1-1.675,0v-5.028A.838.838,0,0,1,101.273,512Z" transform="translate(0 -418.27)" fill="#fff"/>
+  </g>
+</svg>

+ 3 - 0
src/assets/icons/history-chat.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="13.03" height="13" viewBox="0 0 13.03 13">
+  <path id="历史对话" d="M115.055,185.072a5.7,5.7,0,0,0-.13,1.042,4.532,4.532,0,0,0,4.56,4.56,3.935,3.935,0,0,0,1.954-.456v2.476a1.752,1.752,0,0,1-1.759,1.759H117.01l-.977,1.173a.557.557,0,0,1-.847.065.064.064,0,0,1-.065-.065l-.977-1.173h-2.671a1.752,1.752,0,0,1-1.759-1.759v-5.863a1.752,1.752,0,0,1,1.759-1.759Zm4.43,4.3a3.257,3.257,0,1,1,3.257-3.257A3.226,3.226,0,0,1,119.485,189.372Zm.391-3.648v-1.368a.4.4,0,1,0-.782,0v1.694a.239.239,0,0,0,.065.2.358.358,0,0,0,.326.2h1.173a.4.4,0,1,0,0-.782h-.782Z" transform="translate(-109.713 -182.857)" fill="#fff"/>
+</svg>

+ 3 - 0
src/assets/icons/send-file.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="13.584" height="12.224" viewBox="0 0 13.584 12.224">
+  <path id="附件" d="M12.935,62.838a3.275,3.275,0,0,1,.746,1.123,3.459,3.459,0,0,1,0,2.553,3.275,3.275,0,0,1-.746,1.123l-5.343,5.3a4.185,4.185,0,0,1-1.235.837,4.419,4.419,0,0,1-1.549.391,4.361,4.361,0,0,1-1.667-.223,3.986,3.986,0,0,1-1.576-1A3.971,3.971,0,0,1,.574,71.4a4.246,4.246,0,0,1-.223-1.653A4.461,4.461,0,0,1,.734,68.2a4.1,4.1,0,0,1,.83-1.228l4.743-4.7a.364.364,0,0,1,.37-.063.791.791,0,0,1,.37.188.945.945,0,0,1,.181.37.354.354,0,0,1-.056.37L2.443,67.818a3.351,3.351,0,0,0-.628.879,2.842,2.842,0,0,0-.293,1.074A2.806,2.806,0,0,0,1.69,70.93a3.084,3.084,0,0,0,.753,1.13,2.8,2.8,0,0,0,1.081.691,3.06,3.06,0,0,0,1.179.167,3.371,3.371,0,0,0,1.116-.258,2.805,2.805,0,0,0,.907-.6l5.329-5.287a2.335,2.335,0,0,0,.537-.781,2.064,2.064,0,0,0,.153-.8,1.842,1.842,0,0,0-.188-.774,2.551,2.551,0,0,0-.5-.7,1.756,1.756,0,0,0-1.346-.551,2.326,2.326,0,0,0-1.5.788L4.4,68.739a.961.961,0,0,0-.314.712.893.893,0,0,0,.258.642.8.8,0,0,0,.7.251,1.105,1.105,0,0,0,.649-.307L10.061,65.7a.364.364,0,0,1,.37-.063.791.791,0,0,1,.37.188.841.841,0,0,1,.2.37.354.354,0,0,1-.056.37L6.559,70.9a3.158,3.158,0,0,1-.963.7,1.957,1.957,0,0,1-.865.174,1.7,1.7,0,0,1-.753-.216,3.181,3.181,0,0,1-.642-.474,2.235,2.235,0,0,1-.426-.572,1.854,1.854,0,0,1-.216-.767,2.167,2.167,0,0,1,.146-.893,2.674,2.674,0,0,1,.677-.963q.251-.251.446-.46.167-.181.314-.321l.16-.153,3.892-3.878a4.011,4.011,0,0,1,1.1-.788,3.272,3.272,0,0,1,1.207-.328,2.981,2.981,0,0,1,1.207.167A2.924,2.924,0,0,1,12.935,62.838Z" transform="translate(-0.341 -61.952)" fill="#fff"/>
+</svg>

+ 3 - 0
src/assets/icons/send-image.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="13.584" height="13.584" viewBox="0 0 13.584 13.584">
+  <path id="图片" d="M104.731,108.591l-2.122-2.652a.97.97,0,0,0-1.363-.152,1.029,1.029,0,0,0-.152.152l-3.123,3.9h11.643L107.478,107a.971.971,0,0,0-1.358-.195,1,1,0,0,0-.195.195ZM97.97,98.2h11.643a.97.97,0,0,1,.97.97v11.643a.97.97,0,0,1-.97.97H97.97a.97.97,0,0,1-.97-.97V99.17A.971.971,0,0,1,97.97,98.2Zm8.732,5.822a1.941,1.941,0,1,0-1.941-1.941A1.941,1.941,0,0,0,106.7,104.022Z" transform="translate(-97 -98.2)" fill="#fff"/>
+</svg>

+ 3 - 0
src/assets/icons/send.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16.945" height="14.121" viewBox="0 0 16.945 14.121">
+  <path id="发送" d="M80.493,139.058l-15.47,5.969c-.872.336-.85.825.044,1.091l3.738,1.109,1.52,4.522a.648.648,0,0,0,1.163.276l1.961-1.942,3.87,2.836a.682.682,0,0,0,1.156-.437L81.3,139.757C81.435,139.147,81.074,138.834,80.493,139.058Zm-2.354,2.877-6.6,5.879a.844.844,0,0,0-.243.47l-.291,2.739c-.033.308-.139.32-.237.025L69.493,147.2a.368.368,0,0,1,.152-.415l8.368-5.019C78.547,141.446,78.6,141.522,78.139,141.935Z" transform="translate(-64.383 -138.985)" fill="#fff"/>
+</svg>

+ 6 - 0
src/assets/icons/zoom-in.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.172" height="15.221" viewBox="0 0 15.172 15.221">
+  <g id="组_15439" data-name="组 15439" transform="translate(-1.63)">
+    <path id="路径_57050" data-name="路径 57050" d="M7.409,0A5.78,5.78,0,1,1,1.63,5.78,5.78,5.78,0,0,1,7.409,0Zm0,1.75a4.03,4.03,0,1,0,4.03,4.03,4.03,4.03,0,0,0-4.03-4.03Zm4,9.088c-.138.1-.171.134-.066.27.812,1.062,1.689,2.19,2.5,3.249,1.7,2.228,4.318-.357,2.11-2.085-1.049-.821-2.167-1.712-3.219-2.536-.135-.106-.169-.074-.271.063a4.781,4.781,0,0,1-1.051,1.038Z" transform="translate(0)" fill="#fff"/>
+    <path id="路径_57051" data-name="路径 57051" d="M195.675,194.975h5.514a.147.147,0,0,1,.146.146v1.272a.147.147,0,0,1-.146.146h-5.514a.147.147,0,0,1-.146-.146v-1.272a.147.147,0,0,1,.146-.146Z" transform="translate(-190.991 -189.961)" fill="#fff"/>
+  </g>
+</svg>

+ 6 - 0
src/assets/icons/zoom-out.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="15.172" height="15.221" viewBox="0 0 15.172 15.221">
+  <g id="组_15438" data-name="组 15438" transform="translate(-1.63)">
+    <path id="路径_57050" data-name="路径 57050" d="M7.409,0A5.78,5.78,0,1,1,1.63,5.78,5.78,5.78,0,0,1,7.409,0Zm0,1.75a4.03,4.03,0,1,0,4.03,4.03,4.03,4.03,0,0,0-4.03-4.03Zm4,9.088c-.138.1-.171.134-.066.27.812,1.062,1.689,2.19,2.5,3.249,1.7,2.228,4.318-.357,2.11-2.085-1.049-.821-2.167-1.712-3.219-2.536-.135-.106-.169-.074-.271.063a4.781,4.781,0,0,1-1.051,1.038Z" transform="translate(0)" fill="#fff"/>
+    <path id="路径_57051" data-name="路径 57051" d="M195.675,194.975h1.9a.073.073,0,0,0,.073-.073V193a.147.147,0,0,1,.146-.146h1.272a.147.147,0,0,1,.146.146v1.9a.073.073,0,0,0,.073.073h1.9a.147.147,0,0,1,.146.146v1.272a.147.147,0,0,1-.146.146h-1.9a.073.073,0,0,0-.073.073v1.9a.147.147,0,0,1-.146.146H197.8a.147.147,0,0,1-.146-.146v-1.9a.073.073,0,0,0-.073-.073h-1.9a.147.147,0,0,1-.146-.146v-1.272a.147.147,0,0,1,.146-.146Z" transform="translate(-190.991 -189.961)" fill="#fff"/>
+  </g>
+</svg>

+ 160 - 30
src/views/vent/home/configurable/components/preset/AIChat.vue → src/components/AIChat/index.vue

@@ -34,17 +34,35 @@
           }"
         ></span>
         <span v-if="!isFold" class="btn-text">历史对话</span>
-        <a-list style="width: 110px" :split="false" :data-source="historySessions" class="custom-list">
+        <a-list style="width: 110px" :split="false" :data-source="historySessions" :scroll="200" class="custom-list">
           <template #renderItem="{ item }">
             <a-list-item
               :style="{
-                padding: '5px 0 0 10px',
+                padding: '8px 10px 0 8px',
                 color: '#5e7081',
-                fontSize: '12px',
+                fontSize: '10px',
+                position: 'relative', // 新增定位
               }"
               @click="sessionsHistory(item.id)"
             >
-              {{ item.title ? item.title : '新会话' }}
+              <!-- 新增flex布局容器 -->
+              <div style="display: flex; justify-content: space-between; width: 100%">
+                <div v-if="editingId !== item.id" class="text-container">
+                  <span class="edit-text">{{ item.title || '新会话' }}</span>
+                  <edit-outlined class="edit-icon" @click="startEditing(item)" />
+                </div>
+
+                <!-- 输入框 -->
+                <a-input
+                  size="small"
+                  v-else
+                  v-model:value="editText"
+                  v-focus
+                  @blur="handleSave(item)"
+                  @keyup.enter="handleSave(item)"
+                  class="edit-input"
+                />
+              </div>
             </a-list-item>
           </template>
         </a-list>
@@ -74,7 +92,6 @@
               </div>
             </div>
           </div>
-          <!-- </div> -->
         </div>
         <!-- 文本输入区域 -->
         <div v-if="spinning" class="thinking-area">
@@ -103,6 +120,7 @@
 <script lang="ts" setup>
   import { ref, onMounted, unref, nextTick, computed } from 'vue';
   import { useUserStore } from '/@/store/modules/user';
+  import { EditOutlined } from '@ant-design/icons-vue';
   // 响应式变量声明
   const dialogVisible = ref(false);
   const isFold = ref(true); // 是否折叠
@@ -114,6 +132,12 @@
   const hasCreated = ref(false); // 标志位,防止重复调用create接口
   const hasAdd = ref(false); // 标志位,防止重复调用create接口
   const userStore = useUserStore(); //获取用户信息
+  const editingId = ref<number | null>(null);
+  const editText = ref('');
+  interface ListItem {
+    id: number;
+    title?: string;
+  }
   let userId = unref(userStore.getUserInfo).id;
   // const userId = ref(0);
   type MessageItem = {
@@ -126,6 +150,15 @@
   const sortedMessages = computed(() => {
     return messageList.value.sort((a, b) => a.timestamp - b.timestamp);
   });
+  const vFocus = {
+    mounted: (el: HTMLElement) => el.querySelector('input')?.focus(),
+  };
+  const scrollToBottom = () => {
+    const dialogArea = document.querySelector('.dialog-area');
+    if (dialogArea) {
+      dialogArea.scrollTop = dialogArea.scrollHeight;
+    }
+  };
 
   const openMenu = () => {
     dialogVisible.value = !dialogVisible.value;
@@ -157,15 +190,44 @@
     session_id.value = data.id;
     messageList.value = [];
   }
+  //编辑标题
+  const startEditing = (item: ListItem) => {
+    editingId.value = item.id;
+    editText.value = item.title || '';
+  };
+
+  // 保存修改
+  const handleSave = async (item: ListItem) => {
+    const params = {
+      chat_session_id: item.id,
+      new_title: editText.value,
+    };
+    try {
+      let response = await fetch('http://182.92.126.35:6005/sessions/change_title', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify(params),
+      });
+      if (!response.ok) {
+        throw new Error('Network response was not ok');
+      }
+      item.title = editText.value;
+    } catch (error) {
+      console.error('保存失败:', error);
+    }
+    editingId.value = null;
+  };
   //获取消息列表
   async function handleSend() {
     if (session_id.value === '') {
       await addNew();
       createSessionTitle({ session_id: session_id.value, title: inputText.value });
-      sendMessage();
+      sendMessage1();
     } else {
       createSessionTitle({ session_id: session_id.value, title: inputText.value });
-      sendMessage();
+      sendMessage1();
     }
   }
   //发送消息
@@ -221,54 +283,97 @@
     }
   }
   //发送消息  流式响应
-  async function sendMessage1() {
-    spinning.value = true;
-    // 添加用户消息
+  const sendMessage1 = async () => {
+    spinning.value = true; // 开始加载
     messageList.value.push({
       id: `user_${Date.now()}`,
       type: 'user',
       content: inputText.value,
       timestamp: Date.now(),
     });
+
+    // 构造请求参数
     const params = {
-      chat_session_id: session_id.value,
+      chat_session_id: session_id.value, // 替换为实际的会话 ID
       prompt: inputText.value,
       ref_file_ids: [],
       thinking_enabled: false,
     };
     inputText.value = ''; // 清空输入框
-    //将用户输入的内容发送到后端
     try {
-      // 将用户输入的内容发送到后端;
-      let response = await fetch('http://182.92.126.35:6005/chat_stream', {
+      // 发送 POST 请求
+      const response = await fetch('http://182.92.126.35:6005/chat_stream', {
         method: 'POST',
         headers: {
-          'Content-Type': 'text/event-stream; charset=utf-8',
+          'Content-Type': 'application/json',
         },
         body: JSON.stringify(params),
       });
 
+      // 检查响应是否成功
       if (!response.ok) {
         throw new Error('Network response was not ok');
       }
-      const data = await response.json();
-      const assistantReply = data.reply.content; // 获取助手回复
-      systemMessage.value = assistantReply;
-      // 添加系统回答
+
+      // 获取可读流
+      const reader = response.body.getReader();
+
+      // 创建一条新的消息对象
+      const newMessage = {
+        id: `response_${Date.now()}`,
+        type: 'response', // 消息类型
+        content: '',
+        timestamp: Date.now(), // 时间戳用来排序
+      };
+
+      // 将新消息添加到消息列表
+      messageList.value.push(newMessage);
+
+      // 读取流式数据
+      while (true) {
+        const { done, value } = await reader.read();
+        if (done) {
+          console.log('Stream complete');
+          break;
+        }
+
+        // 将流数据转换为字符串
+        const chunk = new TextDecoder().decode(value);
+        console.log('Received chunk:', chunk);
+        const jsonRegex = /{.*?}/g;
+        const matches = chunk.match(jsonRegex);
+        if (matches) {
+          matches.forEach((match) => {
+            try {
+              const data = JSON.parse(match);
+              if (data.type === 'text') {
+                // 找到当前消息对象并更新 content
+                const targetMessage = messageList.value.find((msg) => msg.id === newMessage.id);
+                if (targetMessage) {
+                  targetMessage.content += data.content; // 追加内容
+                  scrollToBottom();
+                }
+              }
+            } catch (error) {
+              console.error('Failed to parse JSON:', error);
+            }
+          });
+        }
+      }
+    } catch (error) {
+      // 请求失败时设置系统消息
+      systemMessage.value = '服务器异常';
       messageList.value.push({
         id: `system_${Date.now()}`,
         type: 'system',
         content: systemMessage.value,
         timestamp: Date.now(),
       });
-    } catch (error) {
-      // 请求失败时设置系统消息为"服务器异常"
-      systemMessage.value = '服务器异常';
       console.error('请求失败:', error);
     } finally {
-      spinning.value = false; // 无论请求成功与否,都停止加载指示器
+      spinning.value = false; // 停止加载
     }
-  }
+  };
   //创建标题
   async function createSessionTitle({ session_id, title }) {
     const params = {
@@ -286,11 +391,15 @@
   }
   //获取会话历史
   async function sessionsHistoryList() {
-    let response = await fetch(`http://182.92.126.35:6005/sessions/?user_id=${userId}`, {
-      method: 'get',
+    const params = {
+      user_id: userId,
+    };
+    let response = await fetch(`http://182.92.126.35:6005/sessions`, {
+      method: 'post',
       headers: {
         'Content-Type': 'application/json',
       },
+      body: JSON.stringify(params),
     });
     const data = await response.json();
     historySessions.value = data.chat_sessions;
@@ -383,9 +492,6 @@
       border-radius: 4px;
     }
   }
-  ::v-deep .zxm-list-item {
-    white-space: normal; /* 禁止文本换行 */
-  }
   ::v-deep .zxm-list-items {
     color: #1890ff;
   }
@@ -393,6 +499,30 @@
     text-decoration: underline;
     color: #1890ff !important;
   }
+  .text-container {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    overflow: hidden;
+  }
+
+  .text-ellipsis {
+    flex: 1;
+  }
+  .edit-text {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    min-width: 0;
+  }
+  .edit-icon {
+    flex-shrink: 0;
+    cursor: pointer;
+    margin-left: auto;
+  }
+  .edit-input {
+    font-size: 10px;
+  }
   .trigger-button {
     position: fixed;
     bottom: 10px;
@@ -600,7 +730,7 @@
   }
   .loading-wrapper,
   .content-wrapper {
-    min-height: 40px; /* 避免高度塌陷 */
+    min-height: 40px;
   }
   .message-item.user {
     margin-bottom: 50px;

+ 73 - 33
src/layouts/default/sider/bottomSider2.vue

@@ -107,14 +107,18 @@
               <textarea v-model="inputText" placeholder="请输入你的问题"> </textarea>
               <!-- 底部操作栏 -->
               <div class="action-bar">
-                <!-- 文件上传按钮 -->
-                <label class="upload-btn">
-                  <div class="send-file" />
-                  <span class="divider"> | </span>
-                  <div class="send-img" />
-                </label>
-                <!-- 发送按钮 -->
-                <div class="send-btn" @click="handleSend"></div>
+                <!-- 左侧深度思考按钮 -->
+                <div class="think-btn" :class="{ active: isThinking }" @click="toggleThinking"> <span>深度思考</span> </div>
+
+                <!-- 右侧操作按钮 -->
+                <div class="right-actions">
+                  <label class="upload-btn">
+                    <div class="send-file"></div>
+                    <span class="divider"> | </span>
+                    <div class="send-img"></div>
+                    <div class="send-btn" @click="handleSend"></div>
+                  </label>
+                </div>
               </div>
             </div>
           </div>
@@ -141,6 +145,7 @@ const hasAdd = ref(false); // 标志位,防止重复调用create接口
 const userStore = useUserStore(); //获取用户信息
 const editingId = ref<number | null>(null);
 const editText = ref('');
+const isThinking = ref(false);
 interface ListItem {
   id: number;
   title?: string;
@@ -180,6 +185,10 @@ const fold = () => {
     sessionsHistoryList();
   }
 };
+//启用深度思考
+const toggleThinking = () => {
+  isThinking.value = !isThinking.value;
+};
 //创建新对话
 async function addNew() {
   hasAdd.value = !hasAdd.value;
@@ -304,7 +313,7 @@ const sendMessage1 = async () => {
     chat_session_id: session_id.value, // 替换为实际的会话 ID
     prompt: inputText.value,
     ref_file_ids: [],
-    thinking_enabled: false,
+    thinking_enabled: isThinking.value,
   };
   inputText.value = ''; // 清空输入框
   try {
@@ -325,12 +334,12 @@ const sendMessage1 = async () => {
     // 获取可读流
     const reader = response.body.getReader();
 
-    // 创建一条新的消息对象
+    // 创建消息对象
     const newMessage = {
-      id: `response_${Date.now()}`,
-      type: 'response', // 消息类型
-      content: '',
-      timestamp: Date.now(), // 时间戳用来排序
+      id: `msg_${Date.now()}`,
+      type: 'response', // 初始类型为 response
+      content: '', // 初始内容为空
+      timestamp: Date.now(),
     };
 
     // 将新消息添加到消息列表
@@ -347,13 +356,16 @@ const sendMessage1 = async () => {
       // 将流数据转换为字符串
       const chunk = new TextDecoder().decode(value);
       console.log('Received chunk:', chunk);
+
+      // 使用正则表达式匹配完整的 JSON 对象
       const jsonRegex = /{.*?}/g;
       const matches = chunk.match(jsonRegex);
+
       if (matches) {
         matches.forEach((match) => {
           try {
             const data = JSON.parse(match);
-            if (data.type === 'text') {
+            if (data.type === 'text' || data.type === 'thinking') {
               // 找到当前消息对象并更新 content
               const targetMessage = messageList.value.find((msg) => msg.id === newMessage.id);
               if (targetMessage) {
@@ -369,14 +381,16 @@ const sendMessage1 = async () => {
     }
   } catch (error) {
     // 请求失败时设置系统消息
-    systemMessage.value = '服务器异常';
-    messageList.value.push({
-      id: `system_${Date.now()}`,
-      type: 'system',
-      content: systemMessage.value,
-      timestamp: Date.now(),
-    });
-    console.error('请求失败:', error);
+    if (!response || !response.ok) {
+      systemMessage.value = '服务器异常';
+      messageList.value.push({
+        id: `system_${Date.now()}`,
+        type: 'system',
+        content: systemMessage.value,
+        timestamp: Date.now(),
+      });
+      console.error('请求失败:', error);
+    }
   } finally {
     spinning.value = false; // 停止加载
   }
@@ -700,7 +714,6 @@ onMounted(() => {
   padding: 10px;
   margin: 10px;
   border-radius: 5px;
-  color: #fff;
   background: #0c2842;
 }
 
@@ -720,14 +733,11 @@ onMounted(() => {
   background-image: url('/@/assets/images/vent/home/answerIcon.svg');
   background-size: 100% 100%;
 }
-.answer-message {
-  float: left;
-  width: 100%;
-  padding: 10px;
-  margin: 10px;
-  border-radius: 5px;
+.think-area {
+  color: #7979799f;
+}
+.answer-area {
   color: #fff;
-  background: #0c2842;
 }
 .dialog-area {
   flex: 1; /* 占据剩余空间 */
@@ -762,12 +772,42 @@ textarea {
 
 .action-bar {
   display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 8px 16px;
+}
+
+.think-btn {
+  border: 1px solid #ccc;
+  width: 120px;
+  height: 20px;
+  line-height: 20px;
+  text-align: center;
+  border-radius: 50px;
+  cursor: pointer;
+  background: white;
+  transition: background 0.3s;
+}
+
+.think-btn.active {
+  background: #1890ff;
+  color: white;
+  border-color: #1890ff;
+}
+.right-actions {
+  display: flex;
   align-items: center;
-  gap: 12px;
+  gap: 8px;
 }
 
 .upload-btn {
   display: flex;
+  align-items: center;
+  gap: 8px;
+}
+.upload-btn {
+  float: right;
+  display: flex;
   cursor: pointer;
   padding: 6px 12px;
 }
@@ -797,7 +837,7 @@ textarea {
 .send-btn {
   width: 20px;
   height: 20px;
-  margin-left: auto;
+  margin-left: 10px;
   margin-right: 10px;
   background-color: #1074c1;
   background-image: url('/@/assets/images/vent/home/send.svg');

+ 1 - 1
src/views/vent/home/configurable/components/content.vue

@@ -116,7 +116,7 @@
   import BlastDelta from '../../../monitorManager/deviceMonitor/components/device/modal/blastDelta.vue';
   import QHCurve from './preset/QHCurve.vue';
   import MeasureDetail from './preset/MeasureDetail.vue';
-  import AIChat from './preset/AIChat.vue';
+  import AIChat from '/@/components/AIChat/index.vue';
   import DeviceAlarm from './preset/DeviceAlarm.vue';
   // import FIreWarn from './preset/FIreWarn.vue';
   // import FIreControl from './preset/FIreControl.vue';