feat: 消息问答的调整
This commit is contained in:
@@ -15,11 +15,10 @@
|
||||
<view class="area-msg-list-content" v-for="item in chatMsgList" :key="item.msgId" :id="item.msgId">
|
||||
<template v-if="item.msgType === MessageRole.AI">
|
||||
<ChatCardAI class="flex flex-justify-start" :key="`ai-${item.msgId}-${item.msg ? item.msg.length : 0}`"
|
||||
:text="item.finish && item.componentName ? '' : item.msg || ''" :isLoading="item.isLoading">
|
||||
<template #content v-if="item.toolCall || item.componentName">
|
||||
<AnswerComponent v-if="
|
||||
item.componentName === CompName.longTextCard
|
||||
" :text="item.msg" :title="item.title" />
|
||||
:text="item.componentName && item.componentName === CompName.longTextCard ? '' : item.msg || ''" :isLoading="item.isLoading">
|
||||
<template #content v-if="item.toolCall || item.componentName && item.componentName === CompName.longTextCard">
|
||||
<AnswerComponent v-if=" item.componentName === CompName.longTextCard
|
||||
" :text="(item.componentMsg || item.msg)" :title="item.title" :finish="item.finish" />
|
||||
<QuickBookingComponent v-if="
|
||||
item.toolCall && item.toolCall.componentName === CompName.quickBookingCard
|
||||
" />
|
||||
@@ -545,11 +544,29 @@ const handleWebSocketMessage = (data) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 防护:确保 aiMsgIndex 有效
|
||||
if (aiMsgIndex < 0 || aiMsgIndex >= chatMsgList.value.length) {
|
||||
console.error('无效的 aiMsgIndex:', aiMsgIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// replyMessageId
|
||||
if(data.replyMessageId) {
|
||||
chatMsgList.value[aiMsgIndex].replyMessageId = data.replyMessageId;
|
||||
}
|
||||
|
||||
// 如果服务端在分片中就带来了 componentName,提前记录并将已缓存的 msg 转移到 componentMsg
|
||||
const aiItem = chatMsgList.value[aiMsgIndex];
|
||||
if (data.componentName) {
|
||||
aiItem.componentName = data.componentName;
|
||||
if (data.componentName === CompName.longTextCard) {
|
||||
if (aiItem.msg && aiItem.msg.length > 0) {
|
||||
aiItem.componentMsg = (aiItem.componentMsg || "") + aiItem.msg;
|
||||
aiItem.msg = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保消息内容是字符串类型
|
||||
if (data.content && typeof data.content !== "string") {
|
||||
try {
|
||||
@@ -561,13 +578,24 @@ const handleWebSocketMessage = (data) => {
|
||||
|
||||
// 直接拼接内容到对应 AI 消息
|
||||
if (data.content) {
|
||||
if (chatMsgList.value[aiMsgIndex].isLoading) {
|
||||
// 首次收到内容:替换“加载中”文案并取消 loading 状态(恢复原始渲染逻辑)
|
||||
chatMsgList.value[aiMsgIndex].msg = data.content;
|
||||
chatMsgList.value[aiMsgIndex].isLoading = false;
|
||||
// 如果该条消息属于 longTextCard,使用 componentMsg 存储内容并保持 ChatCardAI 的 text 为空
|
||||
const isLongText = aiItem.componentName === CompName.longTextCard || data.componentName === CompName.longTextCard;
|
||||
if (isLongText) {
|
||||
if (aiItem.isLoading) {
|
||||
aiItem.componentMsg = (aiItem.componentMsg || "") + data.content;
|
||||
aiItem.isLoading = false;
|
||||
} else {
|
||||
aiItem.componentMsg = (aiItem.componentMsg || "") + data.content;
|
||||
}
|
||||
} else {
|
||||
// 后续流式内容追加
|
||||
chatMsgList.value[aiMsgIndex].msg += data.content;
|
||||
if (aiItem.isLoading) {
|
||||
// 首次收到内容:替换“加载中”文案并取消 loading 状态(恢复原始渲染逻辑)
|
||||
aiItem.msg = data.content;
|
||||
aiItem.isLoading = false;
|
||||
} else {
|
||||
// 后续流式内容追加
|
||||
aiItem.msg += data.content;
|
||||
}
|
||||
}
|
||||
nextTick(() => scrollToBottom());
|
||||
}
|
||||
|
||||
@@ -2,20 +2,25 @@
|
||||
<view class="w-full bg-white border-box border-ff overflow-hidden rounded-20 flex flex-col">
|
||||
<!-- 占位撑开 -->
|
||||
<view class="w-vw"></view>
|
||||
<view class="flex flex-col p-16 border-box">
|
||||
<view class="flex flex-row flex-items-start flex-justify-start">
|
||||
<view class="flex flex-col p-16 border-box border-left-4">
|
||||
<view v-if="title" class="flex flex-row flex-items-start flex-justify-start mb-8">
|
||||
<uni-icons class="icon-active" type="fire-filled" size="18" color="opacity" />
|
||||
<text class="font-size-16 font-500 text-color-900 ml-6">游玩划重点</text>
|
||||
<text class="font-size-16 font-500 text-color-900 ml-6"> {{ title }}</text>
|
||||
</view>
|
||||
<!-- 文字内容,最多显示3行 -->
|
||||
<view class="answer-content font-size-12 font-color-600 mt-8">
|
||||
<view class="answer-content font-size-12 font-color-600">
|
||||
<ChatMarkdown :key="textKey" :text="processedText" />
|
||||
</view>
|
||||
<!-- 超过3行时显示...提示 -->
|
||||
<view class="flex flex-row flex-items-center mt-8" v-if="isOverflow" @click="lookDetailAction">
|
||||
<view v-if="!finish" class="flex flex-row flex-items-center mt-8">
|
||||
<text class="font-size-12 font-400 font-color-600">正在生成</text>
|
||||
<DotLoading />
|
||||
</view>
|
||||
<view v-if="isOverflow && finish" class="flex flex-row flex-items-center mt-8" @click="lookDetailAction">
|
||||
<text class="font-size-12 font-400 theme-color-500 mr-4">查看详情</text>
|
||||
<uni-icons class="icon-active" type="right" size="14" color="opacity"></uni-icons>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -25,6 +30,7 @@
|
||||
import { defineProps, computed, ref, watch } from "vue";
|
||||
|
||||
import ChatMarkdown from "../../chat/ChatMarkdown/index.vue";
|
||||
import DotLoading from "../../loading/DotLoading.vue";
|
||||
|
||||
const isOverflow = ref(false)
|
||||
|
||||
@@ -37,7 +43,11 @@ const props = defineProps({
|
||||
text: {
|
||||
type: String,
|
||||
default: "",
|
||||
}
|
||||
},
|
||||
finish: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
// 用于强制重新渲染的key
|
||||
@@ -102,5 +112,9 @@ const lookDetailAction = () => {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 16px;
|
||||
max-height: 80px;
|
||||
}
|
||||
.border-left-4 {
|
||||
border-left: 4px solid $theme-color-500;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="bg-F5F7FA flex flex-col h-screen overflow-hidden">
|
||||
<TopNavBar title="详情" backgroundColor="transparent" />
|
||||
<TopNavBar :title="title" backgroundColor="transparent" />
|
||||
<view class="flex-full overflow-hidden scroll-y p-12 border-box">
|
||||
<ChatMarkdown :text="answerText" />
|
||||
</view>
|
||||
@@ -20,9 +20,13 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const answerText = ref(props.answerText || "");
|
||||
const title = ref("");
|
||||
|
||||
onLoad(({ message = "" }) => {
|
||||
answerText.value = decodeURIComponent(message);
|
||||
if (answerText.value.length > 6) {
|
||||
title.value = answerText.value.substring(0, 6) + "...";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user