|
@@ -12,23 +12,24 @@
|
|
|
:isSticky="true"
|
|
|
:customStyle="{
|
|
|
//#ifdef APP-PLUS || MP-WEIXIN
|
|
|
- height: `calc(100vh - (44px + ${footerHeight}px + ${proxy.$settingStore.StatusBarHeight}))`,
|
|
|
+ height: `calc(100vh - (44px + ${proxy.$settingStore.StatusBarHeight}))`,
|
|
|
//#endif
|
|
|
//#ifdef H5
|
|
|
- height: `calc(100vh - (44px + ${footerHeight}px))`,
|
|
|
+ height: `calc(100vh - (44px))`,
|
|
|
//#endif
|
|
|
+
|
|
|
+ paddingBottom: `${footerHeight}px`,
|
|
|
}"
|
|
|
+ :scrollTop="scrollTop"
|
|
|
:refresherLoad="false"
|
|
|
:refresherEnabled="false"
|
|
|
- :scrollTop="scrollTop"
|
|
|
- :scrollIntoView="scrollIntoView"
|
|
|
:refresherDefaultStyle="'none'"
|
|
|
:refresherBackground="'#fffff'"
|
|
|
:data-theme="'theme-' + proxy.$settingStore.themeColor.name"
|
|
|
>
|
|
|
<template #default>
|
|
|
<view class="mainArea">
|
|
|
- <view class="center-area">
|
|
|
+ <view ref="centerArea" class="center-area">
|
|
|
<view class="center-area-item">
|
|
|
<viwe class="center-area-item__avatar">
|
|
|
<image src="@/static/images/ai/ai-avatar.png" mode="widthFix"></image>
|
|
@@ -48,7 +49,14 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <viwe v-for="(item, index) in answerList" :key="index" :class="['center-area-item', { roleUser: item.role === 'user' }]" :id="index == answerList.length - 1 ? 'bottomInfo' : ''">
|
|
|
+ <viwe
|
|
|
+ v-for="(item, index) in answerList"
|
|
|
+ :key="index"
|
|
|
+ :class="['center-area-item', { roleUser: item.role === 'user' }]"
|
|
|
+ :style="{
|
|
|
+ paddingBottom: `calc(${answerList.length - 1 == index ? 50 : 0}px)`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
<viwe class="center-area-item__avatar">
|
|
|
<image v-show="item.role === 'assistant'" src="@/static/images/ai/ai-avatar.png" mode="widthFix"></image>
|
|
|
<image v-show="item.role === 'user'" src="@/static/images/ai/ai-question-avatar.png" mode="widthFix"></image>
|
|
@@ -63,6 +71,17 @@
|
|
|
<zero-markdown-view :markdown="item.reasoningContent" themeColor="#05073b"></zero-markdown-view>
|
|
|
</viwe>
|
|
|
|
|
|
+ <view
|
|
|
+ v-if="item.role === 'assistant' && answerList.length - 1 == index && submitLoading"
|
|
|
+ @click="stop()"
|
|
|
+ :style="{
|
|
|
+ float: item.role === 'user' ? 'right' : 'left',
|
|
|
+ margin: item.role === 'user' ? '3px 5px 0 0' : '5px 0 0 5px',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ 停止回答
|
|
|
+ </view>
|
|
|
+
|
|
|
<view
|
|
|
class="iconfont oaIcon-copy center-area-item__center__icon"
|
|
|
@click="copy(item.role === 'user' ? item.content : item.reasoningContent)"
|
|
@@ -144,8 +163,8 @@
|
|
|
/*----------------------------------依赖引入-----------------------------------*/
|
|
|
import config from "@/config";
|
|
|
import { getToken } from "@/utils/auth";
|
|
|
-import { onLoad, onShow, onReady, onHide, onLaunch, onUnload, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
|
|
|
-import { ref, reactive, computed, getCurrentInstance, toRefs, inject, nextTick } from "vue";
|
|
|
+import { onLoad, onShow, onReady, onHide, onLaunch, onResize, onUnload, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
|
|
|
+import { ref, reactive, computed, getCurrentInstance, toRefs, inject, nextTick, watch, watchEffect } from "vue";
|
|
|
/*----------------------------------接口引入-----------------------------------*/
|
|
|
import { aiApi } from "@/api/business/ai.js";
|
|
|
/*----------------------------------组件引入-----------------------------------*/
|
|
@@ -176,7 +195,7 @@ const state = reactive({
|
|
|
sessionId: undefined,
|
|
|
},
|
|
|
footerHeight: 0, //底部区域高度
|
|
|
- scrollIntoView: "", //滚动位置
|
|
|
+ scrollTop: 0, //滚动位置
|
|
|
|
|
|
sheet: {
|
|
|
show: false,
|
|
@@ -198,7 +217,7 @@ const state = reactive({
|
|
|
},
|
|
|
});
|
|
|
|
|
|
-const { buffer, defaultQuestion, submitLoading, answerKeyword, answerList, chatHistory, footerHeight, scrollIntoView, sheet, modal } = toRefs(state);
|
|
|
+const { buffer, defaultQuestion, submitLoading, answerKeyword, answerList, chatHistory, footerHeight, scrollTop, sheet, modal } = toRefs(state);
|
|
|
|
|
|
/** 操作 */
|
|
|
function handle(type) {
|
|
@@ -243,14 +262,11 @@ function getChatList() {
|
|
|
|
|
|
/** 点击历史对话事件 */
|
|
|
function onClickChatItem(item) {
|
|
|
- state.scrollIntoView = "";
|
|
|
state.chatHistory.sessionId = item.sessionId;
|
|
|
state.answerList = item.itemList;
|
|
|
|
|
|
- nextTick(() => {
|
|
|
- state.scrollIntoView = "bottomInfo";
|
|
|
- proxy.$refs["popup"].close();
|
|
|
- });
|
|
|
+ scrollForter(100); //调用滚动到页面底部方法
|
|
|
+ proxy.$refs["popup"].close();
|
|
|
}
|
|
|
|
|
|
/** 长按历史对话事件 */
|
|
@@ -273,6 +289,19 @@ function linechange(event) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/** 滚动到页面底部 */
|
|
|
+function scrollForter(value) {
|
|
|
+ setTimeout(() => {
|
|
|
+ uni
|
|
|
+ .createSelectorQuery()
|
|
|
+ .select(".center-area")
|
|
|
+ .boundingClientRect((res) => {
|
|
|
+ state.scrollTop = res.height;
|
|
|
+ })
|
|
|
+ .exec();
|
|
|
+ }, value);
|
|
|
+}
|
|
|
+
|
|
|
/** 操作菜单回调事件 */
|
|
|
function changeSheet(event) {
|
|
|
if (event.name == "删除") {
|
|
@@ -350,8 +379,6 @@ async function onSubmit(event) {
|
|
|
|
|
|
//数据处理
|
|
|
function processSSEChunk(chunk) {
|
|
|
- state.scrollIntoView = "";
|
|
|
-
|
|
|
try {
|
|
|
const jsonData = JSON.parse(chunk);
|
|
|
|
|
@@ -359,18 +386,25 @@ function processSSEChunk(chunk) {
|
|
|
state.chatHistory.sessionId = jsonData.sessionId;
|
|
|
}
|
|
|
if (jsonData.reasoningContent) {
|
|
|
+ // if (jsonData.reasoningContent.split("```").length % 2) {
|
|
|
+ // let content = jsonData.reasoningContent;
|
|
|
+ // if (content[content.length - 1] != "\n") {
|
|
|
+ // content += "\n";
|
|
|
+ // }
|
|
|
+ // state.answerList[state.answerList.length - 1].reasoningContent += content;
|
|
|
+ // } else {
|
|
|
+ // state.answerList[state.answerList.length - 1].reasoningContent += jsonData.reasoningContent;
|
|
|
+ // }
|
|
|
state.answerList[state.answerList.length - 1].reasoningContent += jsonData.reasoningContent;
|
|
|
} else if (jsonData.content) {
|
|
|
state.answerList[state.answerList.length - 1].content += jsonData.content;
|
|
|
}
|
|
|
+
|
|
|
+ scrollForter(200); //调用滚动到页面底部方法
|
|
|
} catch (error) {
|
|
|
console.log("parsing JSON错误", jsonString, index);
|
|
|
console.log("parsing JSON错误", error);
|
|
|
}
|
|
|
-
|
|
|
- nextTick(() => {
|
|
|
- state.scrollIntoView = "bottomInfo";
|
|
|
- });
|
|
|
}
|
|
|
|
|
|
//开始回答回调事件
|
|
@@ -378,13 +412,11 @@ function openCore() {
|
|
|
console.log("open sse");
|
|
|
|
|
|
state.answerKeyword = undefined;
|
|
|
-
|
|
|
- // 定义一个函数来读取流数据
|
|
|
state.answerList.push({
|
|
|
role: "assistant",
|
|
|
content: "",
|
|
|
reasoningContent: "",
|
|
|
- });
|
|
|
+ }); // 定义一个函数来读取流数据
|
|
|
}
|
|
|
|
|
|
//回答异常回调事件
|
|
@@ -400,6 +432,7 @@ function messageCore(response) {
|
|
|
|
|
|
//回答完毕回调事件
|
|
|
function finishCore() {
|
|
|
+ scrollForter(200); //调用滚动到页面底部方法
|
|
|
console.log("finish sse");
|
|
|
state.submitLoading = false;
|
|
|
}
|
|
@@ -412,6 +445,8 @@ function stop() {
|
|
|
|
|
|
onReady(() => {});
|
|
|
|
|
|
+onResize(() => {});
|
|
|
+
|
|
|
onShow(() => {});
|
|
|
|
|
|
onLoad((options) => {});
|
|
@@ -431,7 +466,7 @@ onUnload(() => {});
|
|
|
&-item {
|
|
|
display: flex;
|
|
|
color: #05073b;
|
|
|
- padding: 15px;
|
|
|
+ padding: 15px 15px 50px 15px;
|
|
|
|
|
|
&__avatar {
|
|
|
width: 26px;
|