From 124f894f4e08fd63eae8c7a85babbc19f2cc1829 Mon Sep 17 00:00:00 2001
From: 潘志宝 <979469083@qq.com>
Date: 星期五, 13 六月 2025 09:39:36 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 src/views/ai/dashboard/components/conversation/CommonConversation.vue |  130 +++++++++++++++++++++++++++----------------
 1 files changed, 82 insertions(+), 48 deletions(-)

diff --git a/src/views/ai/dashboard/components/conversation/CommonConversation.vue b/src/views/ai/dashboard/components/conversation/CommonConversation.vue
index 2de4e77..04137e7 100644
--- a/src/views/ai/dashboard/components/conversation/CommonConversation.vue
+++ b/src/views/ai/dashboard/components/conversation/CommonConversation.vue
@@ -18,6 +18,9 @@
       ref="sidebarRef">
       <ConversationList
         :active-id="activeConversationId"
+        :quick-access="quickAccessFlag"
+        :model-name="modelName"
+        :default-message="defaultMessage"
         ref="conversationListRef"
         @on-conversation-create="handleConversationCreateSuccess"
         @on-conversation-click="handleConversationClick"
@@ -55,9 +58,8 @@
           <!-- 情况一:消息加载中 -->
           <MessageLoading v-if="activeMessageListLoading" />
           <!-- 情况二:无聊天对话时 -->
-          <MessageNewConversation
+          <MessageListEmpty
             v-if="!activeConversation"
-            @on-new-conversation="handleConversationCreate"
           />
           <!-- 情况三:消息列表为空 -->
           <MessageListEmpty
@@ -89,7 +91,7 @@
               @input="handlePromptInput"
               @compositionstart="onCompositionstart"
               @compositionend="onCompositionend"
-              placeholder="问我任何问题...(Shift+Enter 换行,按下 Enter 发送)"
+              placeholder="请问我问题...(Shift+Enter 换行,按下 Enter 发送)"
             ></textarea>
             <div class="prompt-btns">
               <div class="content">
@@ -141,13 +143,21 @@
 import MessageList from '../message/MessageList.vue'
 import MessageListEmpty from '../message/MessageListEmpty.vue'
 import MessageLoading from '../message/MessageLoading.vue'
-import MessageNewConversation from '../message/MessageNewConversation.vue'
 import { onClickOutside } from '@vueuse/core'
 import * as authUtil from "@/utils/auth";
 import {refreshToken} from "@/api/login";
+import {formatToDateTime} from "@/utils/dateUtil";
+import {ElLoading} from "element-plus";
 
 /** AI 聊天对话 列表 */
 defineOptions({ name: 'NormalConversation' })
+
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => null
+  }
+})
 
 const route = useRoute() // 路由
 const message = useMessage() // 消息弹窗
@@ -175,8 +185,12 @@
   isCollapsed.value = !isCollapsed.value
 }
 
+const modelName = ref<string>('common') // 对话搜索
+
 // 聊天对话
 const conversationListRef = ref()
+const quickAccessFlag = ref(false)
+const defaultMessage = ref<ChatMessageVO>()
 const activeConversationId = ref<number | null>(null) // 选中的对话编号
 const activeConversation = ref<ChatConversationVO | null>(null) // 选中的 Conversation
 const conversationInProgress = ref(false) // 对话是否正在进行中。目前只有【发送】消息时,会更新为 true,避免切换对话、删除对话等操作
@@ -199,7 +213,6 @@
 // 接收 Stream 消息
 const receiveMessageFullText = ref('')
 const receiveMessageDisplayedText = ref('')
-
 
 // =========== 【聊天对话】相关 ===========
 
@@ -298,7 +311,6 @@
     activeMessageList.value = await ChatMessageApi.getChatMessageListByConversationId(
       activeConversationId.value
     )
-
     // 滚动到最下面
     await nextTick()
     await scrollToBottom()
@@ -335,19 +347,37 @@
   return []
 })
 
-//处理调度推理结论
-const dealResult = (conversations: any) => {
-  const regex = /<think>(\n*)([\s\S]*?)(\n*)<\/think>(\n*)([\s\S]*)/;
-  conversations.forEach((conversation) => {
-    if(conversation.content.includes('<\/think>')) {
-      conversation.thinkingFlag = false
-    } else {
-      conversation.thinkingFlag = true
-    }
-    const match = conversation.content.match(regex);
-    if(match) {
-      conversation.thinking = match[2];
-      conversation.conclusion = match[5]
+// //处理调度推理结论(deepSeek)
+// const dealResult = (conversations: any) => {
+//   const regex = /<think>(\n*)([\s\S]*?)(\n*)<\/think>(\n*)([\s\S]*)/;
+//   conversations.forEach((conversation) => {
+//     if(conversation.content.includes('<\/think>')) {
+//       conversation.thinkingFlag = false
+//     } else {
+//       conversation.thinkingFlag = true
+//     }
+//     const match = conversation.content.match(regex);
+//     if(match) {
+//       conversation.thinking = match[2];
+//       conversation.conclusion = match[5]
+//     }
+//   })
+// }
+
+//处理调度推理结论(微调大模型)
+const dealResult = (messages: any) => {
+  messages.forEach((message) => {
+    if(message.type === 'assistant') {
+      const spliceText = message.content.includes("总结:") ? "总结:" : "结论:";
+      // 创建同时捕获前后内容的正则表达式
+      const regex = new RegExp(`^([\\s\\S]*?)${spliceText}([\\s\\S]*)$`);
+      const match = message.content.match(regex);
+      if(match) {
+        message.thinking = match[1];
+        message.conclusion = match[2]
+      } else {
+        message.thinking = message.content
+      }
     }
   })
 }
@@ -455,19 +485,20 @@
     message.error('发送失败,原因:内容为空!')
     return
   }
+  // 发送请求时如果accessToken过期,无法中断请求,暂时增加请求前刷新token
+  authUtil.setToken(await refreshToken())
   if (activeConversationId.value == null) {
-    message.error('还没创建对话,不能发送!')
-    return
+    await conversationListRef.value.createConversation(props.data?formatToDateTime(new Date(props.data.createTime)):null)
   }
   // 清空输入框
   prompt.value = ''
-  // 发送请求时如果accessToken过期,无法中断请求,暂时增加请求前刷新token
-  authUtil.setToken(await refreshToken())
-  // 执行发送
-  await doSendMessageStream({
-    conversationId: activeConversationId.value,
-    content: content
-  } as ChatMessageVO)
+  setTimeout(() => {
+    // 执行发送
+    doSendMessageStream({
+      conversationId: activeConversationId.value,
+      content: content
+    } as ChatMessageVO)
+  }, 400)
 }
 
 /** 真正执行【发送】消息操作 */
@@ -478,7 +509,6 @@
   conversationInProgress.value = true
   // 设置为空
   receiveMessageFullText.value = ''
-
   try {
     // 1.1 先添加两个假数据,等 stream 返回再替换
     activeMessageList.value.push({
@@ -499,8 +529,7 @@
     await nextTick()
     await scrollToBottom() // 底部
     // 1.3 开始滚动
-    textRoll()
-
+    await textRoll()
     // 2. 发送 event stream
     let isFirstChunk = true // 是否是第一个 chunk 消息段
     await ChatMessageApi.sendChatMessageStream(
@@ -542,7 +571,9 @@
         stopStream()
       }
     )
-  } catch {}
+  } catch {
+    console.log('sendStream Exception')
+  }
 }
 
 /** 停止 stream 流式调用 */
@@ -632,16 +663,19 @@
 
 /** 初始化 **/
 onMounted(async () => {
-  // 如果有 conversationId 参数,则默认选中
-  if (route.query.conversationId) {
-    const id = route.query.conversationId as unknown as number
-    activeConversationId.value = id
-    await getConversation(id)
+  defaultMessage.value = props.data
+  if(defaultMessage.value) {
+    prompt.value = defaultMessage.value.content
+    quickAccessFlag.value = true
+  } else {
+    // 获取列表数据
+    activeMessageListLoading.value = true
+    await getMessageList()
   }
+})
 
-  // 获取列表数据
-  activeMessageListLoading.value = true
-  await getMessageList()
+onUnmounted(() => {
+  stopStream()
 })
 </script>
 
@@ -655,7 +689,7 @@
 
 .sidebar-toggle {
   position: absolute;
-  left: 300px;  // 初始展开位置
+  left: 320px;  // 初始展开位置
   top: 40%;
   z-index: 1000;
   width: 20px;
@@ -682,12 +716,12 @@
   left: 0;
   top: 0;
   bottom: 0;
-  width: 300px;
+  width: 320px;
   background: rgba(13,28,58,0.9);
   box-shadow: 2px 0 8px rgba(0,0,0,0.1);
   transition: transform 0.3s ease, opacity 0.2s ease;
   z-index: 999;
-  overflow: hidden;
+  overflow-x: hidden;
 
   &.collapsed {
     transform: translateX(-100%);
@@ -699,7 +733,7 @@
 // 头部
 .detail-container {
   width: 100%;
-  height: 885px;
+  height: 910px;
   margin-left: 5px;
   background-color: rgba(0, 0, 0, 0); /* 透明背景 */
   transition: margin 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -796,7 +830,7 @@
 .footer-container {
   display: flex;
   flex-direction: column;
-  height: 114px;
+  height: 205px;
   margin-left: 10px;
   padding: 0;
 
@@ -831,7 +865,7 @@
       flex-direction: column;
       padding: 9px 10px;
       width: 876px;
-      height: 114px;
+      height: 205px;
       background: rgba(115,196,255,0.05);
       border-radius: 4px 4px 4px 4px;
       border: 1px solid #73C4FF;
@@ -842,8 +876,8 @@
     }
 
     .prompt-input {
-      width: 876px;
-      height: 113.55px;
+      width: 860px;
+      height: 203px;
       font-weight: 400;
       font-size: 14px;
       background-color: rgba(219,238,255,0);

--
Gitblit v1.9.3