wujingjing
2025-01-19 1113ced19c32c1b9b65571c48491d9435dbaf085
src/components/chat/hooks/useScrollLoad.ts
@@ -1,77 +1,23 @@
import moment from 'moment';
import type { Ref, ShallowRef } from 'vue';
import { computed, nextTick, onBeforeUnmount, ref, unref } from 'vue';
import { nextTick, onBeforeUnmount, ref, unref } from 'vue';
import { LOAD_CHAT_LIMIT } from '../constants';
import type { ChatContent, ChatMessage, StepItem } from '../model/types';
import { AnswerType, MultiChatType, RoleEnum, StepEnum } from '../model/types';
import { GetHistoryAnswer, QueryHistoryDetail, getShareChatJsonByPost } from '/@/api/ai/chat';
import router from '/@/router';
import { isSharePage } from '/@/stores/chatRoom';
import type { ChatMessage } from '../model/types';
import { useLoadData } from './useLoadData';
import { QueryHistoryDetail } from '/@/api/ai/chat';
type UseScrollLoadOption = {
   container: ShallowRef<HTMLDivElement>;
   historyGroupId: string | Ref<string>;
   messageList: Ref<ChatMessage[]>;
   parseAnswerContent: (res: any) => ChatContent;
   loadReplyData: (res: any) => Promise<ChatMessage[]>;
};
export const convertProcessItem = (processItem: any) => {
   switch (processItem.mode) {
      case 'begin':
         break;
      case 'end':
         break;
   }
   return {
      status: StepEnum.Success,
      title: processItem.value,
   } as StepItem;
};
export const convertProcessToStep = (process: any[],isHistory = true) => {
   const stepList = (process ?? []).reduce((preVal, curVal) => {
      if (curVal.mode === 'question' ) {
         if(isHistory) return preVal;
         const last = preVal.at(-1);
         if (!last.subStep) {
            last.subStep = [];
         }
         const sub = {
            data: curVal.value,
            type: MultiChatType.Select,
         };
         last.subStep.push(sub);
      } else {
         const cur = convertProcessItem(curVal);
         preVal.push(cur);
      }
      return preVal;
   }, []);
   return stepList;
};
export const formatShowTimeYear = (str: string) => {
   const date = moment(str);
   const now = moment();
   const diffDays = now.diff(date, 'days');
   if (diffDays === 0) {
      return `今天 ${date.format('HH:mm:ss')}`;
   } else if (diffDays === 1) {
      return `昨天 ${date.format('HH:mm:ss')}`;
   } else if (diffDays === 2) {
      return `前天 ${date.format('HH:mm:ss')}`;
   }
   if (date.year() === now.year()) {
      return date.format('MM月DD日 HH:mm:ss');
   } else {
      return date.format('YYYY年MM月DD日 HH:mm:ss');
   }
};
/**
 * 滚动加载数据
 * @returns
 */
export const useScrollLoad = (option: UseScrollLoadOption) => {
   const { container, historyGroupId, messageList, parseAnswerContent } = option;
   const { container, historyGroupId, messageList, loadReplyData } = option;
   const moreIsLoading = ref(false);
   /** @description 下次需要加载的用户结束索引(倒着数) */
@@ -79,86 +25,18 @@
   // 是否没有更多数据了
   let isNoMore = false;
   const getAnswerById = async (historyId: string) => {
      return await GetHistoryAnswer({
         history_id: historyId,
      });
   };
   /**
    * 更新加载索引
    */
   const updateLoadIndex = () => {
      nextUserMsgEndIndex++;
   const updateLoadIndex = (addCount = 1) => {
      nextUserMsgEndIndex += addCount;
   };
   /**
    * 获取用户回复数据,并插入到对话当中去
    */
   const loadReplyData = async (userMsg: any[]) => {
      const userItemIdMap = new Map();
      // 用户消息
      const tmpMessageList: ChatMessage[] = userMsg.map((item) => {
         return {
            historyId: item.history_id,
            role: RoleEnum.user,
            content: {
               type: AnswerType.Text,
               values: item.question,
            },
            isChecked: false,
         } as ChatMessage;
      });
      const resList = await Promise.all(
         (userMsg ?? []).map((item) => {
            userItemIdMap.set(item.history_id, item);
            return getAnswerById(item.history_id);
         })
      );
      let i = 0;
      resList.map((item, index) => {
         const insertIndex = index + 1 + i;
         const currentUserMsg = tmpMessageList[insertIndex - 1];
         currentUserMsg.content.values = item?.answer?.question ?? currentUserMsg.content.values;
         const mapUser = userItemIdMap.get(item.answer?.history_id);
         const answerTime = formatShowTimeYear(mapUser?.create_time);
         tmpMessageList.splice(
            insertIndex,
            0,
            item.answer === null
               ? null
               : {
                     historyId: item.answer?.history_id,
                     role: RoleEnum.assistant,
                     content: parseAnswerContent(item?.answer),
                     state: item.answer_state,
                     createTime: answerTime,
                     isStopMsg: false,
                     stepGroup: (item?.answer?.reports ?? []).map((item) => ({
                        value: convertProcessToStep(item?.exec_process),
                        isShow: false,
                     })),
                     conclusion: item?.answer?.conclusion ?? [],
                     isChecked: false,
                 }
         );
         i++;
      });
      messageList.value.unshift(...tmpMessageList);
   };
   /**
    * 加载滚动范围数据
    */
   const loadRangeData = async (lastEnd = nextUserMsgEndIndex) => {
      const res = await QueryHistoryDetail({
         history_group_id: unref(historyGroupId),
         last_end: lastEnd,
@@ -167,7 +45,8 @@
      const result: ChatMessage[] = res.details ?? [];
      if (result.length) {
         nextUserMsgEndIndex += result.length;
         await loadReplyData(res.details);
         const rangeMsgList = await loadReplyData(res.details);
         messageList.value.unshift(...rangeMsgList);
      } else {
         isNoMore = true;
      }