1.完成ai聊天页面新
This commit is contained in:
@@ -1,20 +1,18 @@
|
||||
<template>
|
||||
<view class="chat-container">
|
||||
<!-- 状态栏占位 -->
|
||||
<view class="status-bar-placeholder"></view>
|
||||
|
||||
<!-- 自定义导航栏 -->
|
||||
<!-- <view class="status-bar-placeholder"></view>
|
||||
|
||||
<view class="custom-nav-bar">
|
||||
<!-- 左侧:历史记录图标(触发抽屉) -->
|
||||
<view class="nav-left" @click="toggleHistoryDrawer">
|
||||
<image src="/static/history.svg" mode="aspectFit" class="nav-icon"></image>
|
||||
</view>
|
||||
<!-- 中间标题 -->
|
||||
<view class="nav-title">智水AI辅导员</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 消息列表 -->
|
||||
<scroll-view scroll-y class="message-list" :scroll-top="scrollTop" scroll-with-animation enable-passive="true"
|
||||
<scroll-view scroll-y class="message-list" :scroll-top="scrollTop" scroll-with-animation="true"
|
||||
show-scrollbar="false" enhanced="true" bounces="true"
|
||||
@scroll="onScroll" @scrolltoupper="loadMoreHistory" upper-threshold="50">
|
||||
<!-- 加载提示 -->
|
||||
<view v-if="isLoadingHistory" class="loading-history">
|
||||
@@ -86,17 +84,17 @@
|
||||
<!-- 消息输入框 -->
|
||||
<input v-model="inputMessage" placeholder="输入消息..." @confirm="sendMessage" confirm-type="send" />
|
||||
<!-- 添加图片按钮 -->
|
||||
<img src="/static/add.svg" class="add-icon" @click="selectImage" />
|
||||
<!-- <img src="/static/add.svg" class="add-icon" @click="selectImage" /> -->
|
||||
<!-- 发送消息按钮 -->
|
||||
<img src="/static/send.svg" class="send-icon" @click="sendMessage" />
|
||||
<button class="send-button" @click="sendMessage">发送</button>
|
||||
</view>
|
||||
|
||||
<!-- 悬浮按钮:固定在右下角 -->
|
||||
<view class="ai-hover" @click="goHome">
|
||||
<!-- <view class="ai-hover" @click="goHome">
|
||||
<view class="ai-hover-content">
|
||||
<text class="ai-hover-text">AI</text>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -174,7 +172,7 @@
|
||||
|
||||
// 第二次尝试(处理iOS等需要额外触发的设备)
|
||||
setTimeout(() => {
|
||||
this.forceScrollToBottom(30); // 使用稍小的偏移量
|
||||
this.forceScrollToBottom(); // 确保滚动到底部
|
||||
|
||||
// 第三次确保(针对动态内容加载的情况)
|
||||
if (attempt < 2) {
|
||||
@@ -210,6 +208,19 @@
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面显示时触发
|
||||
*/
|
||||
onShow() {
|
||||
// 页面显示时确保滚动到底部
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
console.log('onShow: 尝试滚动到底部');
|
||||
this.forceScrollToBottom();
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
|
||||
/* ---------- 方法 ---------- */
|
||||
methods: {
|
||||
/**
|
||||
@@ -223,28 +234,53 @@
|
||||
|
||||
/**
|
||||
* 强制滚动到底部
|
||||
* @param {number} offset - 额外的偏移量,默认为50
|
||||
* @param {number} offset - 额外的偏移量,默认为0
|
||||
*/
|
||||
forceScrollToBottom(offset = 50) {
|
||||
forceScrollToBottom(offset = 0) {
|
||||
console.log('forceScrollToBottom: 开始执行滚动');
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.message-list').boundingClientRect(rect => {
|
||||
if (rect) {
|
||||
const targetScrollTop = rect.scrollHeight - rect.height - offset;
|
||||
this.scrollTop = targetScrollTop;
|
||||
|
||||
// 双重确保滚动生效
|
||||
setTimeout(() => {
|
||||
this.scrollTop = targetScrollTop + 1;
|
||||
query.select('.message-list').scrollOffset(res => {
|
||||
if (res) {
|
||||
console.log('forceScrollToBottom: 获取到scrollOffset', res);
|
||||
console.log('forceScrollToBottom: 当前scrollTop', this.scrollTop);
|
||||
|
||||
// 使用scrollHeight,如果没有则使用一个大值
|
||||
const scrollHeight = res.scrollHeight || 99999;
|
||||
const targetScrollTop = scrollHeight + 1000;
|
||||
|
||||
// 先重置scrollTop,然后设置到底部
|
||||
this.scrollTop = 0;
|
||||
this.$nextTick(() => {
|
||||
this.scrollTop = targetScrollTop;
|
||||
console.log('forceScrollToBottom: 设置scrollTop为', targetScrollTop);
|
||||
|
||||
// 延迟再次确保滚动到底部
|
||||
setTimeout(() => {
|
||||
this.scrollTop = targetScrollTop;
|
||||
}, 50);
|
||||
}, 100);
|
||||
const finalScrollTop = (res.scrollHeight || 99999) + 1000;
|
||||
this.scrollTop = finalScrollTop;
|
||||
console.log('forceScrollToBottom: 延迟设置scrollTop完成', finalScrollTop);
|
||||
}, 100);
|
||||
});
|
||||
} else {
|
||||
console.log('forceScrollToBottom: 未获取到scrollOffset');
|
||||
// 直接使用备用方案
|
||||
this.scrollTop = 0;
|
||||
this.$nextTick(() => {
|
||||
this.scrollTop = 99999;
|
||||
console.log('forceScrollToBottom: 使用备用方案1');
|
||||
});
|
||||
}
|
||||
}).exec();
|
||||
} catch (error) {
|
||||
console.error('滚动到底部失败:', error);
|
||||
// 备用方案:直接设置一个很大的值
|
||||
this.scrollTop = 0;
|
||||
this.$nextTick(() => {
|
||||
this.scrollTop = 99999;
|
||||
console.log('forceScrollToBottom: 使用备用方案2');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -620,6 +656,9 @@
|
||||
});
|
||||
this.inputMessage = '';
|
||||
this.saveMessagesToLocal(); // 保存用户消息
|
||||
|
||||
// 立即滚动到底部显示用户消息
|
||||
this.forceScrollToBottom();
|
||||
|
||||
// 添加AI消息占位
|
||||
const aiIdx = this.messages.push({
|
||||
@@ -703,7 +742,7 @@
|
||||
}
|
||||
|
||||
// 最终完成后再次确保滚动到底部
|
||||
this.forceScrollToTop();
|
||||
this.forceScrollToBottom();
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('JSON解析失败:', line, e);
|
||||
@@ -741,13 +780,22 @@
|
||||
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.message-list').boundingClientRect(rect => {
|
||||
if (rect) {
|
||||
// 确保滚动到最底部
|
||||
this.scrollTop = rect.scrollHeight;
|
||||
}
|
||||
}).exec();
|
||||
try {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.message-list').scrollOffset(res => {
|
||||
if (res && res.scrollHeight) {
|
||||
// 使用大值确保滚动到最底部
|
||||
this.scrollTop = res.scrollHeight + 1000;
|
||||
} else {
|
||||
// 备用方案
|
||||
this.scrollTop = 99999;
|
||||
}
|
||||
}).exec();
|
||||
} catch (error) {
|
||||
console.error('滚动失败:', error);
|
||||
// 备用方案
|
||||
this.scrollTop = 99999;
|
||||
}
|
||||
}, isStreaming ? 50 : 100);
|
||||
});
|
||||
},
|
||||
|
Reference in New Issue
Block a user