From 114a30acb8d566e37b917a5f0cbf1060714f1645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=85=E9=A5=BC?= <2815246336@qq.com> Date: Thu, 14 Aug 2025 11:42:34 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=AE=8C=E6=88=90ai=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/aiChat/ai_index.js | 4 +- config.js | 2 +- pages.json | 11 +- pages/aiChat/ai_index.vue | 114 ++++-- pages/aiChat/simple_chat.vue | 758 +++++++++++++++++++++++++++++++++++ pages/index/index.vue | 5 +- static/scss/ai_index.css | 29 +- 7 files changed, 881 insertions(+), 42 deletions(-) create mode 100644 pages/aiChat/simple_chat.vue diff --git a/api/aiChat/ai_index.js b/api/aiChat/ai_index.js index 0391abe..5d4cc22 100644 --- a/api/aiChat/ai_index.js +++ b/api/aiChat/ai_index.js @@ -15,9 +15,9 @@ export const getHistory = ({ limit }; - // 如果有beforeId参数,添加到请求中 + // 如果有beforeId参数,添加到请求中(后端参数名为firstId) if (beforeId) { - params.beforeId = beforeId; + params.firstId = beforeId; } return request({ diff --git a/config.js b/config.js index f4eeb69..40debdd 100644 --- a/config.js +++ b/config.js @@ -28,7 +28,7 @@ module.exports = { /** * 开启cas */ - casEnable: true, + casEnable: false, /** * 单点登录url diff --git a/pages.json b/pages.json index 21f623a..110c103 100644 --- a/pages.json +++ b/pages.json @@ -1159,7 +1159,16 @@ { "path": "pages/aiChat/ai_index", "style": { - "navigationBarTitleText": "AI辅导员" + "navigationBarTitleText": "智水AI辅导员" + } + }, + { + "path": "pages/aiChat/simple_chat", + "style": { + "navigationBarTitleText": "智水AI助手", + "enablePullDownRefresh": false, + "navigationBarBackgroundColor": "#1890FF", + "navigationBarTextStyle": "white" } } ], diff --git a/pages/aiChat/ai_index.vue b/pages/aiChat/ai_index.vue index b269dc1..434d09c 100644 --- a/pages/aiChat/ai_index.vue +++ b/pages/aiChat/ai_index.vue @@ -1,20 +1,18 @@ @@ -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); }); }, diff --git a/pages/aiChat/simple_chat.vue b/pages/aiChat/simple_chat.vue new file mode 100644 index 0000000..0b7b73a --- /dev/null +++ b/pages/aiChat/simple_chat.vue @@ -0,0 +1,758 @@ + + + + + \ No newline at end of file diff --git a/pages/index/index.vue b/pages/index/index.vue index de6f82d..58daa2a 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -33,7 +33,6 @@ - @@ -288,10 +287,10 @@ getImgUrl(name) { return require('../../static/images/workbench/' + name + '.png'); }, - + //跳转到AI toAI() { uni.navigateTo({ - url: '/pages/aiChat/ai_index' + url: '/pages/aiChat/simple_chat' }); }, diff --git a/static/scss/ai_index.css b/static/scss/ai_index.css index ef69e80..5efb1b9 100644 --- a/static/scss/ai_index.css +++ b/static/scss/ai_index.css @@ -65,12 +65,13 @@ /* ============= 消息列表(可滚动区域) ============= */ .message-list { flex: 1; + height: calc(100vh - 120px); + /* 设置固定高度,为输入框和导航栏预留空间 */ padding: 16px 0 calc(env(safe-area-inset-bottom) + 80px) 0; /* 增加底部内边距 */ background-color: #f5f5f5; box-sizing: border-box; - overflow-y: auto; - /* 确保内容超出时可滚动 */ + /* 移除overflow-y: auto,因为scroll-view自己处理滚动 */ -webkit-overflow-scrolling: touch; /* 增加iOS设备上的滚动流畅度 */ } @@ -199,6 +200,30 @@ /* 增加图标之间的间距 */ } +.send-button { + height: 36px; + padding: 0 16px; + background-color: #4f46e5; + color: #fff; + border: none; + border-radius: 18px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + margin: 0 8px; + transition: background-color 0.2s; + min-width: 60px; +} + +.send-button:hover { + background-color: #337ecc; +} + +.send-button:active { + background-color: #2b6cb0; + transform: scale(0.98); +} + .toggle-button { margin-top: 10px; color: blue;