|
|
import http from '../../../utils/api'
Page({ data: { // 当前时间
currentTime: '', // 聊天消息
messages: [], // 输入框相关
inputValue: '', autoFocus: false, inputHeight: 60, isKeyboardShow: false, // 滚动控制
scrollIntoView: 'welcome-message', scrollAnimation: true, isUserScrolling: false, // 用户是否正在手动滚动
scrollTimer: null, // 滚动定时器
lastMessageCount: 0, // 上次消息数量
// 症状选择
quickSymptoms: [], wzsearch: {}, selectedSymptoms: [], showSymptomSelector: false, // 状态控制
isAIThinking: false, isLoading: false, loadingText: '', showMoreMenu: false },
onLoad() { this.initData(); this.getInquiry(); // 监听键盘高度变化
wx.onKeyboardHeightChange(this.onKeyboardHeightChange.bind(this)); },
onUnload() { // 页面卸载时移除监听
wx.offKeyboardHeightChange(this.onKeyboardHeightChange); // 清除定时器
if (this.data.scrollTimer) { clearTimeout(this.data.scrollTimer); } },
// 监听滚动事件
onScroll(e) { // 检测用户是否在手动滚动
const scrollTop = e.detail.scrollTop; // 获取滚动容器和底部元素的位置
const query = wx.createSelectorQuery(); query.select('#scrollBottom').boundingClientRect(); query.select('#chatScroll').boundingClientRect(); query.exec((res) => { if (res[0] && res[1]) { const bottomPosition = res[0].top - res[1].top + res[1].height; // 如果滚动位置不在底部(偏差超过50px),认为是用户手动滚动
if (Math.abs(scrollTop - bottomPosition) > 100) { if (!this.data.isUserScrolling) { this.setData({ isUserScrolling: true }); } // 清除之前的定时器
if (this.data.scrollTimer) { clearTimeout(this.data.scrollTimer); } // 5秒后重置用户滚动状态
const timer = setTimeout(() => { this.setData({ isUserScrolling: false }); // 重置后检查是否需要滚动到底部
this.checkAndScrollToBottom(); }, 5000); this.setData({ scrollTimer: timer }); } } }); },
// 滚动到底部事件
onScrollToLower() { // 用户滚动到底部时,重置滚动状态
this.setData({ isUserScrolling: false }); },
// 键盘高度变化监听
onKeyboardHeightChange(res) { if (res.height > 0) { // 键盘弹起
this.setData({ isKeyboardShow: true }); // 强制滚动到底部
this.scrollToBottom(true); } else { // 键盘收起
this.setData({ isKeyboardShow: false }); } },
// 检查并滚动到底部
checkAndScrollToBottom() { // 如果用户没有手动滚动,则滚动到底部
if (!this.data.isUserScrolling) { this.scrollToBottom(true); } },
// AI问诊快捷字列表
getInquiry() { http.inquiry({ data: {}, success: res => { console.log('快捷症状列表', res); this.setData({ quickSymptoms: res.rows }); } }); },
onShow() { this.updateCurrentTime(); // 延迟设置焦点,避免影响滚动
setTimeout(() => { this.setData({ autoFocus: true }); }, 300); },
// 初始化数据
initData() { // 设置当前时间
this.updateCurrentTime();
// 定时更新当前时间
setInterval(() => { this.updateCurrentTime(); }, 60000); // 初始化消息数量
this.setData({ lastMessageCount: this.data.messages.length }); },
// 更新当前时间
updateCurrentTime() { const now = new Date(); const timeString = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; this.setData({ currentTime: timeString }); },
// 滚动到底部
scrollToBottom(force = false) { // 如果用户正在手动滚动且不是强制滚动,则不滚动
if (this.data.isUserScrolling && !force) { console.log('用户正在手动滚动,跳过自动滚动'); return; }
// 获取最新消息的ID
let targetId = 'scrollBottom'; // 优先滚动到最新的消息
if (this.data.messages.length > 0) { targetId = `msg-${this.data.messages.length - 1}`; } else { targetId = 'welcome-message'; }
console.log('滚动到:', targetId);
// 先重置scrollIntoView,确保能触发滚动
this.setData({ scrollIntoView: '', scrollAnimation: true }, () => { // 延迟一下再设置滚动目标,确保视图更新
setTimeout(() => { this.setData({ scrollIntoView: targetId, scrollAnimation: true }); }, 50); }); // 多重保障滚动
setTimeout(() => { if (!this.data.isUserScrolling || force) { this.setData({ scrollIntoView: targetId }); } }, 150); setTimeout(() => { if (!this.data.isUserScrolling || force) { this.setData({ scrollIntoView: targetId }); } }, 300); },
// 输入框行数变化
onInputLineChange(e) { // 输入框高度变化时,确保滚动到底部
if (this.data.isKeyboardShow) { this.scrollToBottom(); } },
// 输入框聚焦
onInputFocus(e) { this.setData({ autoFocus: true, isKeyboardShow: true }); // 延迟滚动到底部,等待键盘完全弹起
setTimeout(() => { this.scrollToBottom(true); }, 300); },
// 输入框失焦
onInputBlur(e) { this.setData({ autoFocus: false, isKeyboardShow: false }); },
// 输入框变化
onInput(e) { this.setData({ inputValue: e.detail.value }); },
// 发送消息
sendMessage() { const message = this.data.inputValue.trim(); if (!message) return;
// 添加用户消息
const userMessage = { id: Date.now(), type: 'user', content: message, time: this.getCurrentTime() };
// 更新消息列表
const newMessages = [...this.data.messages, userMessage]; this.setData({ inputValue: '', autoFocus: true, inputHeight: 60, messages: newMessages, isUserScrolling: false, // 发送消息时重置用户滚动状态
lastMessageCount: newMessages.length });
// 立即滚动到底部
this.scrollToBottom(true);
// 显示AI思考状态
this.setData({ isAIThinking: true });
// 滚动到底部(显示思考状态后)
setTimeout(() => { this.scrollToBottom(true); }, 100);
// 模拟AI思考时间
setTimeout(() => { this.generateAIResponse(message); }, 1500 + Math.random() * 1000); },
// 获取当前时间
getCurrentTime() { const now = new Date(); return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; },
// 生成AI响应
generateAIResponse(userMessage) { console.log('发送消息:', userMessage); http.search({ data: { keyword: userMessage }, success: res => { console.log('AI响应:', res); let aiMessage; if (res.rows && res.rows.length > 0) { const wzsearch = res.rows[0]; aiMessage = { id: Date.now() + 1, type: 'assistant', content: '根据您的描述,' + (wzsearch.title || '已收到您的症状描述'), diagnosis: wzsearch, time: this.getCurrentTime() }; } else { aiMessage = { id: Date.now() + 1, type: 'assistant', content: '已收到您的症状描述', diagnosis: { possibleDiseases: '暂无匹配诊断', severityLevel: '未知', suggestions: '建议您提供更详细的症状描述,或直接咨询专业兽医' }, time: this.getCurrentTime() }; } // 添加AI消息
const newMessages = [...this.data.messages, aiMessage]; this.setData({ messages: newMessages, isAIThinking: false, isUserScrolling: false, // 收到新消息时强制重置用户滚动状态
lastMessageCount: newMessages.length }, () => { // 消息添加后立即滚动到底部
console.log('AI消息已添加,滚动到底部'); this.scrollToBottom(true); // 多重保险滚动
setTimeout(() => { this.scrollToBottom(true); }, 100); setTimeout(() => { this.scrollToBottom(true); }, 300); setTimeout(() => { this.scrollToBottom(true); }, 500); }); }, fail: err => { console.error('API请求失败:', err); const aiMessage = { id: Date.now() + 1, type: 'assistant', content: '已收到您的症状描述', diagnosis: { possibleDiseases: '网络请求失败', severityLevel: '未知', suggestions: '请检查网络连接后重试,或直接联系兽医' }, time: this.getCurrentTime() }; const newMessages = [...this.data.messages, aiMessage]; this.setData({ messages: newMessages, isAIThinking: false, isUserScrolling: false, lastMessageCount: newMessages.length }, () => { this.scrollToBottom(true); }); }, complete: () => { if (this.data.isAIThinking) { this.setData({ isAIThinking: false }); } } }); },
// 选择快捷症状
selectQuickSymptom(e) { const symptom = e.currentTarget.dataset.symptom.keywords; this.setData({ inputValue: symptom }); this.sendMessage(); },
// 返回
goBack() { wx.navigateBack(); },
// 显示更多菜单
showMoreMenu() { this.setData({ showMoreMenu: true }); },
// 关闭更多菜单
closeMoreMenu() { this.setData({ showMoreMenu: false }); },
// 阻止事件冒泡
stopPropagation() {},
// 清空记录
clearHistory() { wx.showModal({ title: '提示', content: '确定要清空所有聊天记录吗?', success: (res) => { if (res.confirm) { this.setData({ messages: [], selectedSymptoms: [], isUserScrolling: false, lastMessageCount: 0 }, () => { // 清空后滚动到欢迎消息
this.setData({ scrollIntoView: 'welcome-message' }); }); this.closeMoreMenu(); } } }); },
// 导出记录
exportChat() { wx.showToast({ title: '记录已保存到本地', icon: 'success' }); this.closeMoreMenu(); },
// 联系兽医
contactDoctor() { wx.showModal({ title: '联系兽医', content: '确定要拨打兽医热线吗?', success: (res) => { if (res.confirm) { wx.makePhoneCall({ phoneNumber: '400-123-4567' }); } } }); this.closeMoreMenu(); },
// 显示使用说明
showInstructions() { wx.showModal({ title: '使用说明', content: '1. 描述您或牲畜的症状\n2. AI助手会分析并提供建议\n3. 可使用快捷症状选择\n4. 诊断结果仅供参考,请及时咨询专业兽医', showCancel: false }); this.closeMoreMenu(); }});
|