wujingjing
2025-04-07 07f5e49d4031f74c296fe01bb79e913c864979e5
src/components/chat/Chat.vue
@@ -48,7 +48,6 @@
<script setup lang="ts">
import type { CancelTokenSource } from 'axios';
import axios from 'axios';
import { orderBy } from 'lodash-es';
import moment from 'moment';
import { computed, nextTick, onActivated, onMounted, ref } from 'vue';
import { loadAmisSource } from '../amis/load';
@@ -60,7 +59,7 @@
import CustomDrawer from '/@/components/drawer/CustomDrawer.vue';
import { Logger } from '/@/model/logger/Logger';
import { triggerRef } from 'vue';
import { ElLoadingService, ElMessage } from 'element-plus';
import {  ElMessage } from 'element-plus';
import ChatContainer from './components/ChatContainer.vue';
import ShareLinkDlg from './components/shareLink/index.vue';
import router from '/@/router';
@@ -76,16 +75,28 @@
} from '/@/stores/chatRoom';
import emitter from '/@/utils/mitt';
import { useCompRef } from '/@/utils/types';
import { toMyFixed } from '/@/utils/util';
import { toFormData, toMyFixed } from '/@/utils/util';
import { useLoadData } from './hooks/useLoadData';
import { useSyncMsg } from './hooks/useSyncMsg';
import { getCurrentPosition } from '/@/utils/brower';
import { deepClone } from '/@/utils/other';
import { ParentRegister } from '/@/stores/global';
const containerRef = useCompRef(ChatContainer);
const chatListDom = computed(() => containerRef.value?.chatListDom);
const scrollToBottom = () => {
   containerRef.value?.scrollToBottom();
};
const { loadReplyData, parseContent, parseExtraContent, convertProcessItem, convertProcessToStep, formatShowTimeYear, getStepGroupList } = useLoadData();
const {
   loadReplyData,
   parseContent,
   parseExtraContent,
   convertProcessItem,
   convertProcessToStep,
   convertAttach,
   formatShowTimeYear,
   getStepGroupList,
} = useLoadData();
const voicePageIsShow = ref(false);
let isTalking = ref(false);
const chatWidth = computed(() => containerRef.value?.chatWidth);
@@ -115,6 +126,8 @@
   });
};
const enableCallback = ref(false);
let streamOutputIsStart = false;
let position: Position = null;
const questionAi = async (text) => {
@@ -133,7 +146,15 @@
      raw_mode: roomConfig.value?.[currentRouteId]?.isAnswerByLLM ?? false,
      ...judgeParams,
   } as any;
   const tableList = attachList.value.filter((item) => item.type === 'table').map((item) => item.model);
   if (tableList?.length > 0) {
      params.tables = JSON.stringify(tableList);
   }
   const metricList = attachList.value.filter((item) => item.type === 'metric').map((item) => item.model);
   if (metricList?.length > 0) {
      params.metrics = JSON.stringify(metricList);
   }
   // if (!position) {
   //    const loadingInstance = ElLoadingService({
   //       text: '获取位置中...',
@@ -158,7 +179,12 @@
      params.sample_id = currentSampleId;
      currentSampleId = '';
   }
   const formDataParams = toFormData(params);
   const fileList = attachList.value.filter((item) => item.type === 'file').map((item) => item.model);
   for (const item of fileList) {
      formDataParams.append('files', item.file);
   }
   // clearAttach();
   let lastTimestamp = new Date().getTime();
   questionRes = {};
   let lastIsResult = false;
@@ -178,7 +204,7 @@
         return isEmpty;
      };
      questionStreamByPost(
         params,
         formDataParams,
         (chunkRes) => {
            Logger.info('chunk response:\n\n' + JSON.stringify(chunkRes));
            if (chunkRes.mode === 'result') {
@@ -207,6 +233,26 @@
               triggerRefresh();
               return;
               // chunkRes.value = '准备数据分析';
            }
            if (chunkRes.mode === 'main_frame') {
               const jsonObj = JSON.parse(chunkRes.value);
               if (!enableCallback.value) {
                  return;
               }
               ParentRegister.notify?.({
                  type: 'main_frame',
                  value: jsonObj,
               });
               return;
            }
            if (chunkRes.mode === 'create_work_order') {
               const lastMsg = computedMessageList.value.at(-1);
               lastMsg.modeContent = chunkRes;
               triggerRefresh();
               return;
            }
            if (chunkRes.mode === 'summary') {
@@ -258,10 +304,12 @@
            if (chunkRes.mode === 'conclusion') {
               const lastReport = computedMessageList.value.at(-1)?.content?.values?.at(-1);
               if (lastReport) {
                  lastReport.conclusion = chunkRes.value;
                  chunkRes.value = '分析结束';
               }
               chunkRes.value = '分析结束';
            }
            const getLastGroup = () => {
               const lastGroup = computedMessageList.value.at(-1).stepGroup[0];
@@ -323,7 +371,7 @@
               const ms = toMyFixed(currentTimeStamp - lastTimestamp, 2) + ' ms';
               stepList.at(-1).ms = ms;
            }
            }
            if (!streamOutputIsStart) {
               lastTimestamp = currentTimeStamp;
@@ -333,7 +381,9 @@
               stepList.push(stepItem);
            } else {
               const lastItem = stepList.at(-1);
               lastItem.title += chunkRes.value ?? '';
               if (lastItem) {
                  lastItem.title += chunkRes.value ?? '';
               }
            }
            if (chunkRes.mode === 'begin_stream') {
@@ -368,12 +418,14 @@
   const content = parseContent(questionRes, true);
   return content;
};
const clearMessageContent = () =>
   (messageContent.value = {
const playBarRef = useCompRef(PlayBar);
const attachList = computed(() => playBarRef.value?.attachList ?? []);
const clearMessageContent = () => {
   messageContent.value = {
      type: AnswerType.Text,
      values: '',
   });
   };
};
let currentSampleId = '';
@@ -383,7 +435,7 @@
   lastAxiosSource?.cancel();
   isTalking.value = false;
   chatListLoading.value = false;
   streamOutputIsStart = false;
   computedMessageList.value.at(-1).isStopMsg = true;
};
@@ -400,7 +452,7 @@
const addChatItem = (content: ChatContent) => {
   isTalking.value = true;
   const userItem: ChatMessage = { role: RoleEnum.user, content, isChecked: false } as any;
   const userItem: ChatMessage = { role: RoleEnum.user, content, isChecked: false, attachList: deepClone(attachList.value) } as any;
   const assistantItem: ChatMessage = {
      role: RoleEnum.assistant,
      content: {
@@ -413,6 +465,7 @@
            isShow: true,
         },
      ],
      isStopMsg: false,
      isChecked: false,
   } as any;
@@ -422,6 +475,13 @@
   messageList.value.push(assistantItem);
   scrollToBottom();
   return [userItem, assistantItem];
};
/**
 * 清除附件
 */
const clearAttach = () => {
   playBarRef.value?.clearAttach();
};
const sendChatMessage = async (content: ChatContent = messageContent.value) => {
@@ -526,6 +586,7 @@
         type: AnswerType.Text,
         values: msgValue.question,
      },
      attachList: convertAttach(msgValue),
      isChecked: false,
   };
@@ -583,7 +644,6 @@
   messageContent.value.values = content;
};
//#endregion
const playBarRef = useCompRef(PlayBar);
//用户问题设置为常用语
const setCommonPhraseClick = (item) => {
   playBarRef.value.addPhrase(item);