Browse Source

[Feat 0000]智能问答功能开发

bobo04052021@163.com 1 hour ago
parent
commit
51288047e9
1 changed files with 338 additions and 177 deletions
  1. 338 177
      src/components/AIChat/MiniChat.vue

+ 338 - 177
src/components/AIChat/MiniChat.vue

@@ -8,6 +8,23 @@
   <div v-if="isShowChatBroad" class="mini-chat">
     <!-- 左侧折叠区域 -->
     <div class="left-side" :class="{ collapsed: isFold }" id="leftSide">
+      <div
+        class="addBtn"
+        :style="{
+          backgroundImage: `url(${isFold ? '/src/assets/images/vent/home/add.svg' : ''})`,
+          backgroundColor: isFold ? '' : '#2cb6ff',
+          width: isFold ? '20px' : 'auto',
+        }"
+        @click="addNew"
+      >
+        <span
+          class="btn-text-bg"
+          :style="{
+            backgroundImage: `url(${!isFold ? '/src/assets/images/vent/home/addB.svg' : ''})`,
+          }"
+        ></span>
+        <span v-if="!isFold" class="btn-text">添加新对话</span>
+      </div>
       <div
         v-if="isFold"
         class="historyBtn"
@@ -81,23 +98,35 @@
             </div>
           </template>
           <template v-else>
-            <SvgIcon size="80" class="ml-2px mr-2px" name="ai-logo" />
+            <SvgIcon size="40" class="answerIcon" name="ai-logo" />
             <div class="message-wrapper ai-message-wrapper">
               <div class="answer-message">
-                <div v-if="message.contentR1" class="color-gray font-size-12px" v-html="message.contentR1"> </div>
-                <div v-else v-html="message.content"> </div>
+                <div v-if="message.contentR1" class="thinking-section">
+                  <div class="thinking-header" @click="isShow(message)">
+                    <span class="thinking-title"
+                      >思考过程:<RightOutlined v-if="!message.isShowThink" /> <DownOutlined v-if="message.isShowThink"
+                    /></span>
+                  </div>
+                  <div v-show="message.isShowThink" class="color-gray font-size-12px" v-html="formatMessage(message.contentR1)"></div>
+                </div>
+                <div v-if="message.content" v-html="formatMessage(message.content)"> </div>
               </div>
-              <CopyOutlined class="copy-icon" @click="copyToClipboard(message.contentR1 || message.content)" title="复制消息" />
+              <CopyOutlined class="copy-icon" @click="copyToClipboard(message.content)" title="复制消息" />
             </div>
           </template>
         </div>
+        <!-- 建议信息 -->
+        <div v-for="(item, index) in suggestList" :key="index" class="suggestion-item" @click="handleSuggestClick(item)">
+          <span class="suggestion-text">{{ item }}</span>
+          <a-icon type="right" class="suggestion-arrow" />
+        </div>
       </div>
       <!-- 底部输入区 -->
       <div class="input-area">
-        <a-input v-model:value="inputText" placeholder="请输入你的问题" @keyup.enter="handleSend(inputText)" class="ant-input" />
+        <a-textarea v-model:value="inputText" placeholder="请输入你的问题" @keyup.enter="handleSend(inputText)" class="ant-input" auto-size />
         <div class="ctrl-btn">
           <div class="input-controls">
-            <button class="control-btn">深度学习</button>
+            <button class="control-btn" :class="{ active: isThinking }" @click="toggleThinking">深度学习</button>
             <button class="control-btn" @click="stopReq()">停止响应</button>
           </div>
           <div class="action-bar">
@@ -117,15 +146,16 @@
         </div>
         <!-- 右侧文件上传区 -->
         <div v-if="open" class="file-upload">
-          <!-- 输入框区域,包含确认按钮 -->
-          <div class="input-container">
-            <a-input v-model:value="filePath" placeholder="输入文件连接" class="file-input" @pressEnter="handlePathConfirm" />
-            <button class="confirm-btn" @click="handlePathConfirm">确认</button>
-          </div>
           <!-- 上传按钮 -->
-          <!-- <a-upload> <button class="upload-btn" @click="customUpload">从本地上传</button></a-upload> -->
-          <a-upload class="custom-upload" name="file" :multiple="false">
-            <a-button class="upload-btn" @click="customUpload">
+          <a-upload
+            class="custom-upload"
+            name="file"
+            :multiple="false"
+            :before-upload="handleBeforeUpload"
+            :file-list="fileList"
+            :remove="handleRemove"
+          >
+            <a-button class="upload-btn">
               <UploadOutlined></UploadOutlined>
               从本地上传
             </a-button>
@@ -142,7 +172,7 @@ import { SvgIcon } from '../Icon';
 import { Space, Button, Modal, Input, message } from 'ant-design-vue';
 // import AIChat from './index.vue';
 import { useUserStore } from '/@/store/modules/user';
-import { EditOutlined, DeleteOutlined, UploadOutlined, CopyOutlined } from '@ant-design/icons-vue';
+import { EditOutlined, DeleteOutlined, UploadOutlined, CopyOutlined, RightOutlined, DownOutlined } from '@ant-design/icons-vue';
 import { createVNode } from 'vue';
 const TextArea = Input.TextArea; // 直接导入TextArea组件使用时打包报错
 const inputText = ref(''); // 输入框内容
@@ -152,7 +182,11 @@ const editingId = ref<number | null>(null);
 const editText = ref('');
 const currentSessionID = ref('');
 const taskID = ref('');
+const messageID = ref('');
 const open = ref<boolean>(false);
+const isThinking = ref(false); //深度思考是否开启
+const Thinking = ref(false);
+const APIKEY = ref('Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd');
 interface ListItem {
   id: number;
   name?: string;
@@ -164,6 +198,7 @@ interface Message {
   /** 深度思考时的文本 */
   contentR1: string;
   timestamp: number; // 排序依据
+  isShowThink: boolean; //深度思考展示
 }
 // 定义消息历史数组类型
 const messageHistory = ref<Message[]>([]);
@@ -172,89 +207,29 @@ const userid = useUserStore().getUserInfo.id as string;
 const filePath = ref(''); // 绑定输入框值
 const showConfirmBtn = ref(false); // 控制确认按钮显示状态
 const fileList = ref([]);
+const suggestList = ref([]); //建议列表
+//启用深度思考
+const toggleThinking = () => {
+  isThinking.value = !isThinking.value;
+  if (isThinking.value) {
+    APIKEY.value = 'Bearer app-kprgsFKtySM4Wjxs0ZGzaNFN';
+  } else {
+    APIKEY.value = 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd';
+  }
+};
+// 折叠思考过程
+const isShow = (message) => {
+  message.isShowThink = !message.isShowThink;
+};
+// 点击建议项时的处理函数
+const handleSuggestClick = (text) => {
+  // 将选中的建议填充到文本框
+  inputText.value = text;
+};
 function showAIChat() {
   isShowChatBroad.value = !isShowChatBroad.value;
 }
-//获取消息列表
-// async function handleSend(data) {
-//   messageHistory.value.push({
-//     id: `user_${Date.now()}`,
-//     type: 'user',
-//     content: data,
-//     contentR1: '',
-//     timestamp: Date.now(),
-//   });
-//   // 发送 POST 请求
-//   fetch('http://39.97.59.228:8000/v1/chat-messages', {
-//     method: 'POST',
-//     headers: {
-//       'Content-Type': 'application/json',
-//       Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
-//     },
-//     body: JSON.stringify({
-//       conversation_id: currentSessionID.value,
-//       query: data,
-//       response_mode: 'streaming',
-//       user: userid,
-//       inputs: {},
-//     }),
-//   }).then((response) => {
-//     const decoder = new TextDecoder('utf-8');
-//     let buffer = [];
-//     // 获取可读流
-//     const reader = response.body.getReader();
-//     const newMessage = {
-//       id: `response_${Date.now()}`,
-//       type: 'response' as any,
-//       content: '',
-//       contentR1: '',
-//       timestamp: Date.now(),
-//     };
-//     messageHistory.value.push(newMessage);
-//     // 读取数据
-//     function read() {
-//       return reader.read().then(({ done, value }) => {
-//         if (done) {
-//           return buffer;
-//         }
-//         // 解码数据块
-//         const chunk = decoder.decode(value, { stream: false });
-//         // 处理每段数据
-//         const processedData = processStreamChunk(chunk);
-//         buffer = buffer.concat(processedData);
-//         // 继续读取
-//         return read();
-//       });
-//     }
-//     // 开始读取
-//     return read();
-//     function processStreamChunk(chunk) {
-//       try {
-//         // 移除 "data: " 前缀
-//         const jsonStr = chunk.replace('data: ', '');
-//         const data = JSON.parse(jsonStr);
-//         const targetMessage = messageHistory.value.find((msg) => msg.id === newMessage.id);
-//         if (!targetMessage) return;
-//         // 根据事件类型分发处理
-//         switch (data.event) {
-//           case 'message':
-//             if (!taskID.value && !currentSessionID.value) {
-//               taskID.value = data.task_id;
-//               currentSessionID.value = data.conversation_id;
-//             }
-//             targetMessage.content += data.answer; // 追加内容
-//             break;
-//         }
-//         return data;
-//       } catch (error) {
-//         // 请求失败时设置系统消息
-//         return null;
-//       }
-//     }
-//   });
-//   inputText.value = '';
-// }
-// 复制消息
+//复制消息
 function copyToClipboard(text) {
   if (!text || text.trim() === '') {
     message.warn('没有可复制的内容');
@@ -285,24 +260,37 @@ function copyToClipboard(text) {
     document.body.removeChild(textarea);
   }
 }
+//获取消息列表
 async function handleSend(data) {
   inputText.value = '';
-  messageHistory.value.push({
-    id: `user_${Date.now()}`,
-    type: 'user',
-    content: data,
-    contentR1: '',
-    timestamp: Date.now(),
-  });
+  if (isThinking) {
+    messageHistory.value.push({
+      id: `user_${Date.now()}`,
+      type: 'user',
+      content: data,
+      contentR1: '',
+      timestamp: Date.now(),
+      isShowThink: true,
+    });
+  } else {
+    messageHistory.value.push({
+      id: `user_${Date.now()}`,
+      type: 'user',
+      content: data,
+      contentR1: '',
+      timestamp: Date.now(),
+      isShowThink: false,
+    });
+  }
   try {
     const response = await fetch('http://39.97.59.228:8000/v1/chat-messages', {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        Authorization: APIKEY.value,
       },
       body: JSON.stringify({
-        conversation_id: currentSessionID.value,
+        conversation_id: currentSessionID.value ? currentSessionID.value : '',
         query: data,
         response_mode: 'streaming',
         user: userid,
@@ -317,14 +305,31 @@ async function handleSend(data) {
     const decoder = new TextDecoder('utf-8');
     const reader = response.body.getReader();
     let textBuffer = ''; // 使用字符串缓冲区来累积数据
-    const newMessage = {
-      id: `response_${Date.now()}`,
-      type: 'response',
-      content: '',
-      contentR1: '',
-      timestamp: Date.now(),
-    };
-    messageHistory.value.push(newMessage);
+    // 在组件中定义
+    const currentProcessingMessage = ref(null);
+    if (isThinking) {
+      const newMessage = {
+        id: `response_${Date.now()}`,
+        type: 'response',
+        content: '',
+        contentR1: '',
+        timestamp: Date.now(),
+        isShowThink: true,
+      };
+      messageHistory.value.push(newMessage);
+      currentProcessingMessage.value = newMessage; // 保存引用
+    } else {
+      const newMessage = {
+        id: `response_${Date.now()}`,
+        type: 'response',
+        content: '',
+        contentR1: '',
+        timestamp: Date.now(),
+        isShowThink: false,
+      };
+      messageHistory.value.push(newMessage);
+      currentProcessingMessage.value = newMessage; // 保存引用
+    }
     while (true) {
       const { done, value } = await reader.read();
       if (done) {
@@ -353,13 +358,53 @@ async function handleSend(data) {
           switch (data.event) {
             case 'message':
               if (data.answer) {
-                const targetMessage = messageHistory.value.find((msg) => msg.id === newMessage.id);
-                if (targetMessage) {
-                  targetMessage.content += data.answer;
+                const targetMessage = messageHistory.value.find((msg) => msg.id === currentProcessingMessage.value.id);
+
+                if (!targetMessage) break;
+                let currentChunk = data.answer;
+
+                // 检查是否包含起始标签
+                const startIndex = currentChunk.indexOf('<think>');
+                if (startIndex !== -1) {
+                  // 找到起始标签:将标签前的内容作为正文
+                  if (startIndex > 0) {
+                    targetMessage.content += currentChunk.substring(0, startIndex);
+                  }
+                  // 进入思考模式,将标签后的内容追加到contentR1
+                  Thinking.value = true;
+                  const remainingContent = currentChunk.substring(startIndex + '<think>'.length);
+                  if (remainingContent) {
+                    targetMessage.contentR1 += remainingContent;
+                  }
+                } else if (Thinking.value) {
+                  // 结束标签
+                  const endIndex = currentChunk.indexOf('</think>');
+                  if (endIndex !== -1) {
+                    // 找到结束标签标签前的内容追加到contentR1
+                    if (endIndex > 0) {
+                      targetMessage.contentR1 += currentChunk.substring(0, endIndex);
+                    }
+                    //将标签后的内容作为正文
+                    const remainingContent = currentChunk.substring(endIndex + '</think>'.length);
+                    if (remainingContent) {
+                      targetMessage.content += remainingContent;
+                    }
+                    targetMessage.content += currentChunk;
+                    Thinking.value = false;
+                    targetMessage.isShowThink = false;
+                  } else {
+                    // 没有结束标签,继续追加到contentR1
+                    targetMessage.contentR1 += currentChunk;
+                  }
+                } else {
+                  targetMessage.content += currentChunk;
                 }
               }
               if (data.task_id && !taskID.value) taskID.value = data.task_id;
               if (data.conversation_id && !currentSessionID.value) currentSessionID.value = data.conversation_id;
+              if (data.message_id && !messageID.value) {
+                messageID.value = data.message_id;
+              }
               break;
           }
         } catch (error) {
@@ -367,6 +412,7 @@ async function handleSend(data) {
         }
       }
     }
+    getNextSuggest();
   } catch (error) {
     console.error('Error in handleSend:', error);
     // 在 UI 上显示错误信息
@@ -376,41 +422,57 @@ async function handleSend(data) {
       content: '请求错误',
       contentR1: '',
       timestamp: Date.now(),
+      isShowThink: false,
     });
   }
 }
+//创建新对话
+async function addNew() {
+  messageHistory.value = [];
+  currentSessionID.value = '';
+  taskID.value = '';
+  messageID.value = '';
+}
 // 上传文件
 const showModal = () => {
   open.value = !open.value;
 };
-async function customUpload(data) {
+// 上传文件
+const handleBeforeUpload = async (file) => {
   const formData = new FormData();
-  if (!data) {
-    return message.warn('请选择文件');
-  }
-  // 添加文件参数
-  formData.append('file', data.file);
-  // 添加用户标识参数
+  formData.append('file', file);
   formData.append('user', userid);
+
   try {
-    let response = await fetch(`http://39.97.59.228:8000/v1/files/upload`, {
+    const response = await fetch(`http://39.97.59.228:8000/v1/files/upload`, {
       method: 'POST',
       headers: {
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        Authorization: APIKEY.value,
       },
       body: formData,
     });
-    // if (response) {
-    //   message.success('上传成功');
-    // }
-    console.log(response, '123');
-    if (!response) {
-      throw new Error('Network response was not ok');
+
+    const result = await response.json();
+    if (response.ok) {
+      message.success('上传成功');
+      const linkText = `[${result.name}](${result.source_url})`;
+      inputText.value += `\n${linkText}`;
+    } else {
+      message.error(`上传失败: ${result.message || '网络错误'}`);
     }
   } catch (error) {
     console.error('保存失败:', error);
+    message.error('上传失败,请重试');
   }
-}
+  return false;
+};
+
+const handleRemove = (file) => {
+  const index = fileList.value.findIndex((item) => item.uid === file.uid);
+  if (index !== -1) {
+    fileList.value.splice(index, 1);
+  }
+};
 //停止响应
 async function stopReq() {
   try {
@@ -418,7 +480,7 @@ async function stopReq() {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        Authorization: APIKEY.value,
       },
       body: JSON.stringify({
         user: userid,
@@ -433,13 +495,12 @@ async function stopReq() {
 }
 //获取具体会话记录
 async function sessionsHistory(id: string) {
-  console.log(id, '123');
   try {
     let response = await fetch(`http://39.97.59.228:8000/v1/messages?conversation_id=${id}&user=${userid}`, {
       method: 'GET',
       headers: {
         'Content-Type': 'application/json',
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        Authorization: APIKEY.value,
       },
     });
     const data = await response.json();
@@ -447,19 +508,45 @@ async function sessionsHistory(id: string) {
     if (data.data.length > 0) {
       messageHistory.value = [];
       data.data.forEach((item: any) => {
+        currentSessionID.value = item.conversation_id;
         messageHistory.value.push({
           id: `user_${Date.now()}`,
           type: 'user',
           content: item.query,
           contentR1: '',
           timestamp: Date.now(),
+          isShowThink: false,
         });
+        const answer = item.answer;
+        // 查找<think>
+        const startIndex = answer.indexOf('<think>');
+        const endIndex = answer.indexOf('</think>');
+        let content = '';
+        let contentR1 = '';
+        // 根据标签判断
+        if (startIndex !== -1 && endIndex !== -1) {
+          content = answer.substring(0, startIndex) + answer.substring(endIndex + '</think>'.length);
+          contentR1 = answer.substring(startIndex + '<think>'.length, endIndex);
+        } else if (startIndex !== -1) {
+          // 只有起始标签
+          content = answer.substring(0, startIndex);
+          contentR1 = answer.substring(startIndex + '<think>'.length);
+        } else if (endIndex !== -1) {
+          // 只有结束标签
+          content = answer.substring(endIndex + '</think>'.length);
+          contentR1 = answer.substring(0, endIndex);
+        } else {
+          // 没有标签
+          content = answer;
+        }
+        // 添加到消息历史
         messageHistory.value.push({
           id: `system_${Date.now()}`,
           type: 'system',
-          content: item.answer,
-          contentR1: '',
+          content: content.trim(),
+          contentR1: contentR1.trim(),
           timestamp: Date.now(),
+          isShowThink: contentR1.length > 0, // 如果有思考内容则显示
         });
       });
     }
@@ -471,37 +558,32 @@ async function sessionsHistory(id: string) {
   }
   editingId.value = null;
 }
-//编辑标题
-const startEditing = (item: ListItem) => {
-  editingId.value = item.id;
-  editText.value = item.name || '';
-};
-// 输入框确认按钮点击事件
-async function handlePathConfirm() {
-  const formData = new FormData();
-  // 添加文件参数
-  formData.append('file', filePath.value);
-  // 添加用户标识参数
-  formData.append('user', userid);
+//获取下一轮建议问题列表
+//停止响应
+async function getNextSuggest() {
+  console.log(messageID.value, '123');
   try {
-    let response = await fetch(`http://39.97.59.228:8000/v1/files/upload`, {
-      method: 'POST',
+    let response = await fetch(`http://39.97.59.228:8000/v1/messages/${messageID.value}/suggested?user=${userid}`, {
+      method: 'GET',
       headers: {
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        'Content-Type': 'application/json',
+        Authorization: APIKEY.value,
       },
-      body: formData,
     });
-    if (!response.ok) {
+    const data = await response.json();
+    suggestList.value = data.data;
+    if (!response) {
       throw new Error('Network response was not ok');
     }
   } catch (error) {
     console.error('保存失败:', error);
   }
-  console.log('确认的文件路径:', filePath.value);
-  // 这里可以添加路径验证、保存等逻辑
-  filePath.value = ''; // 可选:确认后清空输入框
-  showConfirmBtn.value = false;
 }
+//编辑标题
+const startEditing = (item: ListItem) => {
+  editingId.value = item.id;
+  editText.value = item.name || '';
+};
 // 保存修改
 const handleSave = async (item: ListItem) => {
   try {
@@ -509,7 +591,7 @@ const handleSave = async (item: ListItem) => {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
-        Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+        Authorization: APIKEY.value,
       },
       body: JSON.stringify({
         name: editText.value,
@@ -539,7 +621,7 @@ const startDelete = async (item: ListItem) => {
           method: 'DELETE',
           headers: {
             'Content-Type': 'application/json',
-            Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+            Authorization: APIKEY.value,
           },
           body: JSON.stringify({
             user: userid,
@@ -571,14 +653,33 @@ async function getHistoryList() {
     method: 'get',
     headers: {
       'Content-Type': 'application/json',
-      Authorization: 'Bearer app-tSFRUnv0Qkbtik1dwtlhnpkd',
+      Authorization: APIKEY.value,
     },
   });
   const data = await response.json();
   sessionHistory.value = data.data;
-  console.log(sessionHistory.value, '123');
+  data.data.forEach((item) => {
+    currentSessionID.value = item.conversation_id;
+  });
 }
-
+//格式化消息
+const formatMessage = (text) => {
+  if (!text) return '';
+  let formatted = text
+    // 处理换行
+    .replace(/\n\n/g, '<br>')
+    .replace(/\n###/g, '<br> ')
+    .replace(/###/g, '')
+    .replace(/---/g, '')
+    .replace(/^- /gm, '<br> - ')
+    // 处理粗体
+    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
+    // 处理斜体
+    .replace(/\*(.*?)\*/g, '<em>$1</em>')
+    // 处理行内代码
+    .replace(/`([^`]+)`/g, '<code>$1</code>');
+  return formatted;
+};
 // 初始化按钮定位
 onMounted(() => {
   getHistoryList();
@@ -594,15 +695,15 @@ onMounted(() => {
 }
 .mini-chat {
   display: flex;
-  width: 500px;
-  height: 400px;
+  width: 550px;
+  height: 85%;
   border-radius: 4px;
   position: fixed;
-  top: 60px;
+  top: 70px;
   right: 20px;
   background-color: rgb(255, 255, 255);
   background: url('../../assets/images/warn-dialog-bg.png') no-repeat center;
-  background-size: 100% 100%;
+  background-size: 103% 130%;
   z-index: 9999999;
   color: #fff;
 }
@@ -617,8 +718,21 @@ onMounted(() => {
   width: 40px; /* 折叠时宽度 */
 }
 
+.addBtn {
+  height: 30px;
+  position: absolute;
+  background-size: 100% 100%;
+  background-position: center;
+  padding: 2px;
+  right: 10px;
+  bottom: 40px;
+  left: 10px;
+  align-items: center;
+  border-radius: 3px;
+  cursor: pointer;
+}
 .custom-list {
-  height: 325px;
+  height: 680px;
   overflow-y: auto;
 }
 .text-container {
@@ -682,7 +796,7 @@ onMounted(() => {
   color: #fff;
   white-space: nowrap;
   margin-left: 30px;
-  line-height: 35px;
+  line-height: 29px;
 }
 .historyBtn {
   width: 20px;
@@ -726,7 +840,7 @@ onMounted(() => {
   flex: 1; /* 占据剩余空间 */
   display: flex;
   flex-direction: column;
-
+  width: calc(100% - 134px) !important;
   .dialog-area {
     flex: 1; /* 占据剩余空间 */
     gap: 10px; /* 消息块间隔统一控制 */
@@ -740,7 +854,12 @@ onMounted(() => {
       padding: 10px;
       border-radius: 5px;
       background: #0c2842;
-      max-width: 80%;
+      max-width: 300px;
+      white-space: pre-wrap;
+      word-wrap: break-word;
+      overflow-wrap: break-word;
+      overflow: auto;
+      line-height: 1.5;
     }
     .answer-message {
       padding: 10px;
@@ -793,9 +912,9 @@ onMounted(() => {
   }
 
   .ant-input {
-    background-color: rgba(255, 255, 255, 0) !important;
     border: none;
-    outline: none;
+    background-color: rgba(255, 255, 255, 0) !important;
+    color: #fff;
   }
   .ant-input:focus {
     border: none; /* 聚焦时无边框 */
@@ -828,12 +947,12 @@ onMounted(() => {
     font-size: 10px;
     margin-right: 10px;
     cursor: pointer;
-    transition: all 0.2s;
+    transition: background-color 0.2s ease; /* 平滑过渡效果 */
   }
-
-  .control-btn:hover {
-    background-color: #043256;
-    color: #e2e8f0;
+  /* 激活状态样式(点击后) */
+  .control-btn.active {
+    background-color: #2cb6ff; /* 蓝色背景(Ant Design 主色) */
+    color: white; /* 白色文字 */
   }
   .control-btn1 {
     height: 20px;
@@ -932,6 +1051,48 @@ onMounted(() => {
   .custom-upload .ant-upload-select:hover .ant-btn {
     border-color: #1f84bd !important;
   }
+  .message-wrapper.ai-message-wrapper {
+    display: flex;
+    align-items: flex-start;
+  }
+  .answerIcon {
+    flex: 0 0 45px;
+  }
+
+  .suggestion-item {
+    height: 30px;
+    margin-left: 45px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 10px 16px;
+    border: 1px solid #1890ff;
+    color: white;
+    border-radius: 4px;
+    cursor: pointer;
+    width: 33%;
+    font-size: 12px;
+  }
+  .thinking-section {
+    border-left: 3px solid #e5e7eb;
+    padding-left: 12px;
+    margin-bottom: 16px;
+  }
+
+  .thinking-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 8px 0;
+    cursor: pointer;
+    user-select: none;
+  }
+
+  .thinking-title {
+    font-size: 14px;
+    font-weight: 500;
+    color: #6b7280;
+  }
 }
 </style>
 <style scoped>