wujingjing
2024-11-04 437142bb6cb308f38feddb467a9f13e444698c96
src/components/chat/Chat.vue
@@ -23,6 +23,20 @@
                  />
                  <div class="flex-auto flex" :class="{ 'justify-end': item.role === RoleEnum.user }">
                     <div class="inline-flex flex-col" :class="{ 'w-full': item.role === RoleEnum.assistant }">
                        <div class="w-full" v-if="isTalking && index === computedMessageList.length - 1">
                           <div class="text-sm rounded-[6px] p-4 leading-relaxed bg-white" v-if="item.role === RoleEnum.assistant">
                              <!-- 过程输出 -->
                              <el-steps direction="vertical" :active="activeStep">
                                 <!-- <el-step title="process" status="process" />
                                       <el-step title="success" status="success" />
                                       <el-step title="wait" status="wait" />
                                       <el-step title="finish" status="finish" />
                                       <el-steps title="error" status="error" /> -->
                                 <el-step v-for="item in stepList" :title="item.title" :status="stepEnumMap[item.status]" />
                              </el-steps>
                           </div>
                        </div>
                        <div class="w-full" v-if="item.content?.values">
                           <div
                              class="text-sm rounded-[6px] p-4 leading-relaxed"
@@ -123,8 +137,6 @@
                              </div>
                           </div>
                        </div>
                        <Loding v-if="isTalking && index === computedMessageList.length - 1" class="w-fit" :process="process" />
                     </div>
                  </div>
               </div>
@@ -151,6 +163,8 @@
               :isHome="false"
               v-model="messageContent.values"
               @sendClick="sendClick"
               @showUpChatClick="showUpChatClick"
               @showDownChatClick="showDownChatClick"
               :style="{ width: chatWidth }"
            ></PlayBar>
         </div>
@@ -173,7 +187,7 @@
import { useScrollToBottom } from './hooks/useScrollToBottom';
import type { ChatContent } from './model/types';
import { AnswerState, AnswerType, RoleEnum, answerTypeMapCom, roleImageMap, type ChatMessage } from './model/types';
import { QuestionAi, extCallQuery } from '/@/api/ai/chat';
import { QuestionAi, extCallQuery, questionStreamByPost } from '/@/api/ai/chat';
import PlayBar from '/@/components/chat/components/playBar/PlayBar.vue';
import CustomDrawer from '/@/components/drawer/CustomDrawer.vue';
import router from '/@/router';
@@ -264,12 +278,38 @@
   return content;
};
const { clearQueryProcess, process, processId, queryProcess } = useQueryProcess();
//#region ====================== 步骤 step ======================
const enum StepEnum {
   Loading,
   Success,
   Error,
}
const stepEnumMap = {
   [StepEnum.Loading]: 'process',
   [StepEnum.Success]: 'success',
   [StepEnum.Error]: 'error',
};
type StepItem = {
   title: string;
   status: StepEnum;
};
const activeStep = ref(-1);
const stepList = ref<StepItem[]>([]);
const resetStep = () => {
   activeStep.value = -1;
   stepList.value = [];
};
//#endregion
const DEFAULT_SECTION_A_ID = 'knowledge_base';
let questionRes = null;
let finalCalcSectionAId = null;
const questionAi = async (text) => {
   processId.value = uuidv4();
   // processId.value = uuidv4();
   let judgeParams = null;
   if (!preQuestion.value) {
      // const aiContent = computedMessageList.value.filter((item) => item.role === RoleEnum.assistant);
@@ -300,7 +340,7 @@
   finalCalcSectionAId = currentSectionAId;
   const params = {
      process_id: processId.value,
      // process_id: processId.value,
      question: text,
      // FIXME: 暂时这样
      // section_a_id: currentSectionAId,
@@ -321,10 +361,31 @@
   // if (currentLLMId) {
   //    params.llm_id = currentLLMId;
   // }
   clearQueryProcess();
   queryProcess();
   const res = await QuestionAi(params).finally(() => {
      clearQueryProcess();
   // clearQueryProcess();
   // queryProcess();
   resetStep();
   let res = null;
   await questionStreamByPost(params, (chunkRes) => {
      if (chunkRes.mode === 'result') {
         res = chunkRes.value;
      } else {
         switch (chunkRes.mode) {
            case 'begin':
               break;
            case 'end':
               break;
         }
         stepList.value.push({
            title: chunkRes.value,
            status: StepEnum.Success,
         });
         scrollToBottom();
         // process.value = chunkRes.value;
      }
   }).finally(() => {
      resetStep();
   });
   questionRes = res;
   const content = parseContent(res);
@@ -468,7 +529,32 @@
   );
};
//#endregion
//#region ====================== 光标输入上下箭头显示历史消息 ======================
const currentIndex = ref(null);
const history_data = computed(() => {
   return computedMessageList.value.filter((item) => item.role === RoleEnum.user);
});
//显示上一条消息
const showUpChatClick = () => {
   if (computedMessageList.value.length === 0) return;
   if (currentIndex.value === null) {
      currentIndex.value = history_data.value.length - 1;
   } else {
      currentIndex.value = (currentIndex.value + history_data.value.length - 1) % history_data.value.length;
   }
   messageContent.value.values = history_data.value[currentIndex.value].content.values;
};
//显示下一条消息
const showDownChatClick = () => {
   if (computedMessageList.value.length === 0) return;
   if (currentIndex.value === null) {
      currentIndex.value = 0;
   } else {
      currentIndex.value = (currentIndex.value + 1) % history_data.value.length;
   }
   messageContent.value.values = history_data.value[currentIndex.value].content.values;
};
//#endregion
const {
   copyClick,
   likeClick,
@@ -515,4 +601,29 @@
      }
   }
}
.el-step.is-horizontal.stepActive {
   .el-step__head.is-finish {
      .el-step__line {
         // 当前步骤数横线样式设置
         .el-step__line-inner {
            width: 50% !important;
            border-width: 1px !important;
         }
      }
      // 当前步骤数圆圈样式设置
      .el-step__icon.is-text {
         //    background: #409eff;
         color: #fff;
      }
   }
}
:deep(.el-step__icon-inner) {
   font-size: 16px !important;
}
:deep(.el-step__description) {
   height: 20px;
}
</style>