// import http from '../../../utils/api' Page({ data: { // 专家信息 expertInfo: { id: 0, name: '', title: '', expertise: '', avatar: '/images/avatars/expert1.png', online: false, phone: '' }, // 用户信息 userInfo: { id: 0, name: '用户', avatar: '/images/avatars/user.png' }, // 消息列表 messageList: [], scrollTop: 0, scrollAnimate: false, // 输入相关 inputValue: '', inputFocus: false, inputMode: 'keyboard', inputPlaceholder: '请输入消息...', // 多媒体 showMediaSheet: false, // 录音相关 isRecording: false, isCanceling: false, recordingTime: 0, recordingTip: '松开 发送', voiceTip: '按住 说话', recordingTimer: null, recordManager: null, // 页面状态 showDateDivider: true, todayDate: '', loading: false, loadingMore: false, // 滚动相关 isScrolling: false, lastScrollTop: 0, // 录音相关 recordStartY: 0, // 当前专家ID currentExpertId: 0, // 分页相关 page: 1, pageSize: 20, hasMore: true, // 时间显示间隔(分钟) - 微信默认为5分钟 timeInterval: 5, // 用于存储最后一条显示时间的消息的时间戳 lastShowTimeStamp: 0 }, onLoad: function(options) { console.log('页面加载,参数:', options); // 初始化录音管理器 this.initRecordManager(); // 获取今天日期 this.setTodayDate(); // 加载用户信息 this.loadUserInfo(); // 加载专家信息 if (options.expertId) { this.setData({ currentExpertId: options.expertId }); this.loadExpertInfo(options.expertId); } else { // 如果没有传expertId,使用默认值 this.setData({ currentExpertId: 1, expertInfo: { id: 1, name: '张明专家', title: '资深畜牧兽医', expertise: '牛羊疾病防治', avatar: '/images/avatars/expert1.png', online: true, phone: '13800138000' } }, () => { // 加载聊天记录 this.loadChatHistory(); }); } // 设置键盘监听 wx.onKeyboardHeightChange(this.onKeyboardHeightChange.bind(this)); }, onUnload: function() { console.log('页面卸载'); // 清理定时器 if (this.data.recordingTimer) { clearInterval(this.data.recordingTimer); } // 移除监听器 wx.offKeyboardHeightChange(); }, onShow: function() { console.log('页面显示'); }, onReady: function() { console.log('页面初次渲染完成'); }, // 初始化录音管理器 initRecordManager: function() { this.recordManager = wx.getRecorderManager(); this.recordManager.onStart(() => { console.log('录音开始'); this.setData({ isRecording: true, recordingTime: 0, recordingTip: '松开 发送' }); // 开始计时 const timer = setInterval(() => { const time = this.data.recordingTime + 1; this.setData({ recordingTime: time }); }, 1000); this.setData({ recordingTimer: timer }); }); this.recordManager.onStop((res) => { console.log('录音停止', res); if (this.data.recordingTimer) { clearInterval(this.data.recordingTimer); } const { tempFilePath, duration } = res; if (tempFilePath && !this.data.isCanceling) { this.sendAudioMessage(tempFilePath, Math.floor(duration / 1000)); } this.setData({ isRecording: false, isCanceling: false, recordingTime: 0 }); }); this.recordManager.onError((err) => { console.error('录音失败:', err); wx.showToast({ title: '录音失败', icon: 'none' }); this.setData({ isRecording: false, isCanceling: false }); }); }, // 设置今天日期 setTodayDate: function() { const now = new Date(); const month = now.getMonth() + 1; const date = now.getDate(); const week = ['日', '一', '二', '三', '四', '五', '六'][now.getDay()]; this.setData({ todayDate: `${month}月${date}日 星期${week}` }); }, // 加载用户信息 loadUserInfo: function() { try { // 从本地存储获取用户信息,如果没有则使用默认值 const userInfo = wx.getStorageSync('userInfo'); if (userInfo) { this.setData({ userInfo }); } else { // 默认用户信息 const defaultUserInfo = { id: 1001, name: '养殖户', avatar: '/images/avatars/user.png' }; this.setData({ userInfo: defaultUserInfo }); wx.setStorageSync('userInfo', defaultUserInfo); } } catch (e) { console.error('加载用户信息失败:', e); // 使用默认用户信息 this.setData({ userInfo: { id: 1001, name: '养殖户', avatar: '/images/avatars/user.png' } }); } }, // 加载专家信息 - 使用您的接口调用方式 loadExpertInfo: function(expertId) { console.log('加载专家信息:', expertId); wx.showLoading({ title: '加载中...' }); // 使用您的接口调用方式 // http.getExpertInfo({ // data: { expertId: expertId }, // success: (res) => { // console.log('专家信息:', res); // if (res.code === 0) { // this.setData({ // expertInfo: res.data, // loading: false // }); // // 加载聊天记录 // this.loadChatHistory(); // } else { // // 如果接口返回失败,使用默认数据 // this.loadDefaultExpertInfo(expertId); // } // wx.hideLoading(); // }, // fail: (err) => { // console.error('加载专家信息失败:', err); // wx.hideLoading(); // wx.showToast({ // title: '加载失败', // icon: 'none' // }); // // 如果接口调用失败,使用默认数据 // this.loadDefaultExpertInfo(expertId); // } // }); // 模拟数据 setTimeout(() => { const experts = [ { id: 1, name: '张明专家', title: '资深畜牧兽医', expertise: '牛羊疾病防治', avatar: '/images/avatars/expert1.png', online: true, phone: '13800138000' }, { id: 2, name: '李华专家', title: '高级畜牧师', expertise: '饲料营养', avatar: '/images/avatars/expert2.png', online: false, phone: '13800138001' }, { id: 3, name: '王强专家', title: '兽医专家', expertise: '疾病防治', avatar: '/images/avatars/expert3.png', online: true, phone: '13800138002' } ]; const expertInfo = experts.find(e => e.id == expertId) || experts[0]; this.setData({ expertInfo, loading: false }); wx.hideLoading(); // 加载聊天记录 this.loadChatHistory(); }, 500); }, // 加载默认专家信息(当接口失败时使用) loadDefaultExpertInfo: function(expertId) { const experts = [ { id: 1, name: '张明专家', title: '资深畜牧兽医', expertise: '牛羊疾病防治', avatar: '/images/avatars/expert1.png', online: true, phone: '13800138000' }, { id: 2, name: '李华专家', title: '高级畜牧师', expertise: '饲料营养', avatar: '/images/avatars/expert2.png', online: false, phone: '13800138001' }, { id: 3, name: '王强专家', title: '兽医专家', expertise: '疾病防治', avatar: '/images/avatars/expert3.png', online: true, phone: '13800138002' } ]; const expertInfo = experts.find(e => e.id == expertId) || experts[0]; this.setData({ expertInfo, loading: false }); // 加载聊天记录 this.loadChatHistory(); }, // 加载聊天记录 - 使用您的接口调用方式 loadChatHistory: function() { const { currentExpertId, userInfo, page, pageSize } = this.data; this.setData({ loading: true }); console.log('加载聊天记录:', { expertId: currentExpertId, userId: userInfo.id, page: page, pageSize: pageSize }); // 使用您的接口调用方式 // http.getChatHistory({ // data: { // expertId: currentExpertId, // userId: userInfo.id, // page: page, // pageSize: pageSize // }, // success: (res) => { // console.log('聊天记录:', res); // if (res.code === 0) { // const messages = res.data.list || []; // if (messages.length > 0) { // // 处理消息时间显示 - 使用完全修复的时间处理逻辑 // const processedMessages = this.processMessageTimes(messages); // // 调试:查看处理后的消息 // console.log('处理后的消息数据:', processedMessages.map(msg => ({ // id: msg.id, // showTime: msg.showTime, // time: this.formatTime(msg.timestamp), // timestamp: msg.timestamp // }))); // this.setData({ // messageList: processedMessages, // loading: false, // hasMore: messages.length >= pageSize // }, () => { // // 滚动到底部 // this.scrollToBottom(true); // }); // } else { // // 如果没有历史记录,添加一条欢迎消息 // this.addWelcomeMessage(); // } // } else { // // 如果接口返回失败,使用测试数据 // this.loadMockChatHistory(); // } // }, // fail: (err) => { // console.error('加载聊天记录失败:', err); // this.setData({ loading: false }); // // 如果接口调用失败,使用测试数据 // this.loadMockChatHistory(); // } // }); // 模拟数据 - 修复时间戳问题 setTimeout(() => { const now = Date.now(); let mockMessages = []; if (page === 1) { // 第一页数据 - 测试不同时间间隔的消息 mockMessages = [ { id: 'msg-1', sender: 'expert', type: 'text', content: '您好,我是张明专家,有什么可以帮您?', timestamp: now - 10 * 60 * 1000, // 10分钟前 - 应该显示时间 status: 'success' }, { id: 'msg-2', sender: 'user', type: 'text', content: '您好,我养的牛最近食欲不振,请问是什么原因?', timestamp: now - 9 * 60 * 1000, // 9分钟前 - 不显示时间(与上条间隔1分钟) status: 'success' }, { id: 'msg-3', sender: 'expert', type: 'text', content: '可能是饲料问题或环境变化引起的,请描述一下具体情况。', timestamp: now - 7 * 60 * 1000, // 7分钟前 - 显示时间(与上条间隔2分钟,但与第一条间隔3分钟) status: 'success' }, { id: 'msg-4', sender: 'user', type: 'text', content: '具体症状是拉稀,体温偏高,精神状态不好。', timestamp: now - 2 * 60 * 1000, // 2分钟前 - 显示时间(与上条间隔5分钟) status: 'success' }, { id: 'msg-5', sender: 'expert', type: 'text', content: '明白了,建议您调整饲料配方,添加一些益生菌。', timestamp: now - 1 * 60 * 1000, // 1分钟前 - 不显示时间(与上条间隔1分钟) status: 'success' } ]; } else { // 更多数据 mockMessages = [ { id: 'msg-6', sender: 'user', type: 'text', content: '之前喂的是玉米秸秆,需要换饲料吗?', timestamp: now - 30 * 60 * 1000, // 30分钟前 status: 'success' }, { id: 'msg-7', sender: 'expert', type: 'text', content: '可以尝试添加一些豆粕和麦麸,改善营养结构。', timestamp: now - 25 * 60 * 1000, // 25分钟前 status: 'success' } ]; } if (mockMessages.length > 0) { // 处理消息时间显示 - 使用完全修复的时间处理逻辑 const processedMessages = this.processMessageTimes(mockMessages); // 调试:查看处理后的消息 console.log('处理后的消息数据:', processedMessages.map(msg => ({ id: msg.id, showTime: msg.showTime, time: this.formatTime(msg.timestamp), timestamp: msg.timestamp, sender: msg.sender }))); let newMessageList = []; if (page === 1) { newMessageList = processedMessages; } else { newMessageList = [...processedMessages, ...this.data.messageList]; } this.setData({ messageList: newMessageList, loading: false, loadingMore: false, hasMore: mockMessages.length >= pageSize }, () => { if (page === 1) { // 滚动到底部 this.scrollToBottom(true); } }); } else { // 如果没有历史记录,添加一条欢迎消息 this.addWelcomeMessage(); } }, 800); }, // 加载模拟聊天记录(当接口失败时使用) loadMockChatHistory: function() { const now = Date.now(); // 测试数据 - 确保有时间戳 const mockMessages = [ { id: 'msg-1', sender: 'expert', type: 'text', content: '您好,我是张明专家,有什么可以帮您?', timestamp: now - 10 * 60 * 1000, // 10分钟前 status: 'success' }, { id: 'msg-2', sender: 'user', type: 'text', content: '您好,我养的牛最近食欲不振,请问是什么原因?', timestamp: now - 8 * 60 * 1000, // 8分钟前 status: 'success' }, { id: 'msg-3', sender: 'expert', type: 'text', content: '可能是饲料问题或环境变化引起的,请描述一下具体情况。', timestamp: now - 6 * 60 * 1000, // 6分钟前 status: 'success' }, { id: 'msg-4', sender: 'user', type: 'text', content: '具体症状是...', timestamp: now - 4 * 60 * 1000, // 4分钟前 status: 'success' }, { id: 'msg-5', sender: 'expert', type: 'text', content: '明白了,建议您调整饲料配方。', timestamp: now - 2 * 60 * 1000, // 2分钟前 status: 'success' } ]; // 处理消息时间显示 const processedMessages = this.processMessageTimes(mockMessages); this.setData({ messageList: processedMessages, loading: false, hasMore: false }, () => { // 滚动到底部 this.scrollToBottom(true); }); }, // 添加欢迎消息 addWelcomeMessage: function() { const welcomeMessage = { id: 'welcome-' + Date.now(), sender: 'expert', type: 'text', content: `您好,我是${this.data.expertInfo.name},有什么可以帮您?`, timestamp: Date.now(), status: 'success' }; const processedMessage = this.processSingleMessageTime(welcomeMessage, []); this.setData({ messageList: [processedMessage], loading: false }, () => { // 滚动到底部 this.scrollToBottom(true); }); }, // 完全修复:处理消息时间显示逻辑(类似微信) processMessageTimes: function(messages) { if (!messages || messages.length === 0) return []; // 按时间排序(从早到晚) const sortedMessages = [...messages].sort((a, b) => a.timestamp - b.timestamp); const processedMessages = []; let lastShowTime = null; // 最后一条显示时间消息的时间戳 for (let i = 0; i < sortedMessages.length; i++) { const msg = { ...sortedMessages[i] }; // 确保时间戳是有效数字 if (!msg.timestamp || isNaN(msg.timestamp) || msg.timestamp <= 0) { msg.timestamp = Date.now() - (sortedMessages.length - i) * 60000; } // 第一条消息始终显示时间 if (i === 0) { msg.showTime = true; lastShowTime = msg.timestamp; } else { // 计算与最后一条显示时间的消息的时间差(分钟) const timeDiffMinutes = (msg.timestamp - lastShowTime) / (1000 * 60); // 超过5分钟显示时间 if (timeDiffMinutes >= this.data.timeInterval) { msg.showTime = true; lastShowTime = msg.timestamp; } else { msg.showTime = false; } } processedMessages.push(msg); } // 存储最后一条显示时间的消息的时间戳 if (lastShowTime) { this.setData({ lastShowTimeStamp: lastShowTime }); } return processedMessages; }, // 处理单条消息的时间显示(添加新消息时调用) processSingleMessageTime: function(message, messageList) { const msg = { ...message }; // 确保时间戳是有效数字 if (!msg.timestamp || isNaN(msg.timestamp) || msg.timestamp <= 0) { msg.timestamp = Date.now(); } if (messageList.length === 0) { // 第一条消息 msg.showTime = true; this.setData({ lastShowTimeStamp: msg.timestamp }); return msg; } // 获取最后一条显示时间的消息 const lastShowTime = this.data.lastShowTimeStamp; // 计算时间差(分钟) const timeDiffMinutes = (msg.timestamp - lastShowTime) / (1000 * 60); // 超过5分钟显示时间 if (timeDiffMinutes >= this.data.timeInterval) { msg.showTime = true; this.setData({ lastShowTimeStamp: msg.timestamp }); } else { msg.showTime = false; } return msg; }, // 返回上一页 goBack: function() { wx.navigateBack(); }, // 打电话 makePhoneCall: function() { const phone = this.data.expertInfo.phone; if (!phone) { wx.showToast({ title: '暂无联系电话', icon: 'none' }); return; } wx.makePhoneCall({ phoneNumber: phone, success: () => { console.log('拨打电话成功'); }, fail: (err) => { console.error('拨打电话失败:', err); wx.showToast({ title: '拨打失败', icon: 'none' }); } }); }, // 输入处理 onInput: function(e) { this.setData({ inputValue: e.detail.value }); }, // 输入框获得焦点 onInputFocus: function() { this.setData({ inputFocus: true }); }, // 输入框失去焦点 onInputBlur: function() { this.setData({ inputFocus: false }); }, // 清除输入 clearInput: function() { this.setData({ inputValue: '', inputFocus: true }); }, // 发送文本消息 - 使用您的接口调用方式 sendTextMessage: function() { const content = this.data.inputValue.trim(); if (!content) return; console.log('发送文本消息:', content); const newMessage = { id: 'msg-' + Date.now(), sender: 'user', type: 'text', content: content, timestamp: Date.now(), status: 'sending' }; // 处理时间显示并添加到消息列表 this.addMessageToList(newMessage); // 清空输入框 this.setData({ inputValue: '', inputFocus: false }); // 使用您的接口调用方式发送消息 // http.sendTextMessage({ // data: { // expertId: this.data.currentExpertId, // userId: this.data.userInfo.id, // content: content, // timestamp: Date.now() // }, // success: (res) => { // console.log('发送消息成功:', res); // if (res.code === 0) { // // 更新消息状态 // this.updateMessageStatus(newMessage.id, 'success'); // // 模拟专家回复 // setTimeout(() => { // this.receiveExpertReply(); // }, 1000 + Math.random() * 1000); // } else { // // 发送失败 // this.updateMessageStatus(newMessage.id, 'error'); // wx.showToast({ // title: '发送失败', // icon: 'none' // }); // } // }, // fail: (err) => { // console.error('发送消息失败:', err); // this.updateMessageStatus(newMessage.id, 'error'); // wx.showToast({ // title: '发送失败', // icon: 'none' // }); // } // }); // 模拟发送成功 setTimeout(() => { this.updateMessageStatus(newMessage.id, 'success'); // 模拟专家回复 setTimeout(() => { this.receiveExpertReply(); }, 1000 + Math.random() * 1000); }, 500); }, // 添加消息到列表 addMessageToList: function(message) { const { messageList } = this.data; // 处理消息时间显示 const processedMessage = this.processSingleMessageTime(message, messageList); // 添加到列表 messageList.push(processedMessage); this.setData({ messageList }, () => { // 消息添加后滚动到底部 this.scrollToBottom(); }); }, // 更新消息状态 updateMessageStatus: function(messageId, status) { const { messageList } = this.data; const index = messageList.findIndex(msg => msg.id === messageId); if (index !== -1) { messageList[index].status = status; this.setData({ messageList }); } }, // 接收专家回复 - 使用您的接口调用方式 receiveExpertReply: function() { // 这里可以使用WebSocket或轮询获取新消息 // 模拟专家回复 const replies = [ '收到您的消息,让我分析一下您说的情况。', '建议您提供更多细节,比如发病时间、具体症状等。', '根据描述,可能是饲料问题引起的,建议调整饲料配方。', '可以考虑添加一些维生素补充剂,改善食欲问题。', '最好能提供照片,这样我可以更准确地判断情况。' ]; const randomReply = replies[Math.floor(Math.random() * replies.length)]; const newMessage = { id: 'exp-' + Date.now(), sender: 'expert', type: 'text', content: randomReply, timestamp: Date.now(), status: 'success' }; this.addMessageToList(newMessage); }, // 切换输入模式(语音/键盘) switchInputMode: function() { const currentMode = this.data.inputMode; const newMode = currentMode === 'keyboard' ? 'voice' : 'keyboard'; console.log('切换输入模式:', currentMode, '->', newMode); this.setData({ inputMode: newMode, showMediaSheet: false }); if (newMode === 'keyboard') { // 切换到键盘模式 setTimeout(() => { this.setData({ inputFocus: true, inputPlaceholder: '请输入消息...' }); }, 100); } else { // 切换到语音模式 this.setData({ inputFocus: false, inputPlaceholder: '按住说话' }); } }, // 滚动事件处理 onScroll: function(e) { const scrollTop = e.detail.scrollTop; this.setData({ lastScrollTop: scrollTop, isScrolling: true }); // 延迟重置滚动状态 clearTimeout(this.scrollTimer); this.scrollTimer = setTimeout(() => { this.setData({ isScrolling: false }); }, 200); // 检查是否需要加载更多 if (scrollTop <= 100 && !this.data.loadingMore && this.data.hasMore && this.data.page > 1) { this.loadMoreMessages(); } }, // 加载更多消息 loadMoreMessages: function() { if (this.data.loadingMore || !this.data.hasMore) return; this.setData({ loadingMore: true }); // 加载更多聊天记录 setTimeout(() => { this.setData({ page: this.data.page + 1 }, () => { this.loadChatHistory(); }); }, 500); }, // 滚动到底部 scrollToBottom: function(animate = true) { if (this.data.isScrolling) return; this.setData({ scrollAnimate: animate }, () => { // 设置一个足够大的值确保滚动到底部 setTimeout(() => { this.setData({ scrollTop: 999999 }); }, 100); }); }, // 显示多媒体选择面板 showMediaActionSheet: function() { this.setData({ showMediaSheet: true, inputFocus: false }); }, // 隐藏多媒体选择面板 hideMediaActionSheet: function() { this.setData({ showMediaSheet: false }); }, // 键盘高度变化 onKeyboardHeightChange: function(res) { console.log('键盘高度变化:', res.height); if (res.height > 0) { // 键盘弹出时隐藏多媒体面板 this.setData({ showMediaSheet: false }); // 键盘弹出后滚动到底部 setTimeout(() => { this.scrollToBottom(); }, 300); } }, // 选择图片 chooseImage: function() { this.hideMediaActionSheet(); wx.chooseImage({ count: 9, sizeType: ['compressed'], sourceType: ['album'], success: (res) => { console.log('选择图片成功:', res.tempFilePaths); this.uploadImages(res.tempFilePaths); }, fail: (err) => { console.error('选择图片失败:', err); wx.showToast({ title: '选择图片失败', icon: 'none' }); } }); }, // 选择视频 chooseVideo: function() { this.hideMediaActionSheet(); wx.chooseVideo({ sourceType: ['album'], compressed: true, maxDuration: 60, success: (res) => { console.log('选择视频成功:', res); this.uploadVideo(res.tempFilePath, res.thumbTempFilePath); }, fail: (err) => { console.error('选择视频失败:', err); wx.showToast({ title: '选择视频失败', icon: 'none' }); } }); }, // 选择文件 chooseFile: function() { this.hideMediaActionSheet(); wx.chooseMessageFile({ count: 1, type: 'all', success: (res) => { console.log('选择文件成功:', res); const file = res.tempFiles[0]; this.uploadFile(file.path, file.name, file.size); }, fail: (err) => { console.error('选择文件失败:', err); wx.showToast({ title: '选择文件失败', icon: 'none' }); } }); }, // 上传图片 uploadImages: function(tempFilePaths) { tempFilePaths.forEach((tempFilePath, index) => { const fileName = `image_${Date.now()}_${index}.jpg`; this.uploadFile(tempFilePath, fileName, 0, 'image'); }); }, // 上传视频 uploadVideo: function(tempFilePath, thumbPath) { const fileName = `video_${Date.now()}.mp4`; this.uploadFile(tempFilePath, fileName, 0, 'video', thumbPath); }, // 通用文件上传 uploadFile: function(tempFilePath, fileName, fileSize = 0, type = 'file', thumbPath = '') { console.log('开始上传文件:', { fileName, type, fileSize }); // 获取文件扩展名 const extension = fileName.split('.').pop().toLowerCase(); // 创建消息 const messageId = 'file-' + Date.now(); const message = { id: messageId, sender: 'user', type: type, content: tempFilePath, thumb: thumbPath, fileName: fileName, fileSize: fileSize, extension: extension, timestamp: Date.now(), status: 'uploading', progress: 0 }; this.addMessageToList(message); // 模拟上传过程 this.simulateUpload(messageId, type); }, // 模拟上传过程 simulateUpload: function(messageId, type) { let progress = 0; const uploadInterval = setInterval(() => { progress += Math.random() * 20 + 10; if (progress >= 100) { progress = 100; clearInterval(uploadInterval); setTimeout(() => { this.updateMessageStatus(messageId, 'success'); // 清除进度信息 const { messageList } = this.data; const index = messageList.findIndex(msg => msg.id === messageId); if (index !== -1) { delete messageList[index].progress; this.setData({ messageList }); // 模拟专家回复 if (type === 'image' || type === 'video') { setTimeout(() => { this.receiveMediaReply(type); }, 800); } } }, 200); } // 更新进度 const { messageList } = this.data; const index = messageList.findIndex(msg => msg.id === messageId); if (index !== -1) { messageList[index].progress = Math.min(progress, 100); this.setData({ messageList }); } }, 100); }, // 接收媒体回复 receiveMediaReply: function(type) { const imageReplies = [ '照片收到了,牛的状况看起来确实不太理想。', '从照片看,饲养环境需要改善一下。', '图片清晰,我可以更准确地判断问题了。' ]; const videoReplies = [ '视频看到了,动物的精神状态需要关注。', '从视频可以观察到更多细节,这很有帮助。', '视频内容很有价值,让我了解了具体情况。' ]; const replies = type === 'image' ? imageReplies : videoReplies; const randomReply = replies[Math.floor(Math.random() * replies.length)]; const newMessage = { id: 'exp-media-' + Date.now(), sender: 'expert', type: 'text', content: randomReply, timestamp: Date.now(), status: 'success' }; this.addMessageToList(newMessage); }, // 开始语音录制 startVoiceRecord: function(e) { if (e && e.touches && e.touches[0]) { this.setData({ recordStartY: e.touches[0].clientY }); } this.recordManager.start({ duration: 60000, sampleRate: 44100, numberOfChannels: 1, encodeBitRate: 192000, format: 'aac' }); }, // 语音录制触摸移动 onVoiceTouchMove: function(e) { if (!this.data.isRecording) return; if (e.touches && e.touches[0]) { const currentY = e.touches[0].clientY; const startY = this.data.recordStartY; const deltaY = startY - currentY; const isCanceling = deltaY > 50; if (isCanceling !== this.data.isCanceling) { this.setData({ isCanceling: isCanceling, recordingTip: isCanceling ? '松开取消' : '松开 发送', voiceTip: isCanceling ? '松开取消' : '按住 说话' }); } } }, // 结束语音录制 endVoiceRecord: function() { if (this.data.isRecording) { this.recordManager.stop(); } }, // 取消语音录制 cancelVoiceRecord: function() { if (this.data.isRecording) { this.setData({ isCanceling: true }); this.recordManager.stop(); } }, // 发送语音消息 sendAudioMessage: function(tempFilePath, duration) { console.log('发送语音消息:', { duration }); const message = { id: 'audio-' + Date.now(), sender: 'user', type: 'audio', content: tempFilePath, duration: duration, timestamp: Date.now(), status: 'sending' }; this.addMessageToList(message); // 模拟发送成功 setTimeout(() => { this.updateMessageStatus(message.id, 'success'); // 模拟专家回复 setTimeout(() => { const reply = { id: 'exp-audio-' + Date.now(), sender: 'expert', type: 'text', content: '语音收到了,我会仔细听取分析。', timestamp: Date.now(), status: 'success' }; this.addMessageToList(reply); }, 1500); }, 800); }, // 预览图片 previewImage: function(e) { const url = e.currentTarget.dataset.url; wx.previewImage({ current: url, urls: [url], fail: (err) => { console.error('预览图片失败:', err); wx.showToast({ title: '预览失败', icon: 'none' }); } }); }, // 下载文件 downloadFile: function(e) { const url = e.currentTarget.dataset.url; wx.showLoading({ title: '下载中...' }); wx.downloadFile({ url: url, success: (res) => { wx.hideLoading(); wx.showToast({ title: '下载成功', icon: 'success' }); // 保存到相册(如果是图片) if (url.match(/\.(jpg|jpeg|png|gif)$/i)) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { wx.showToast({ title: '已保存到相册', icon: 'success' }); }, fail: (err) => { console.error('保存到相册失败:', err); } }); } }, fail: (err) => { wx.hideLoading(); console.error('下载失败:', err); wx.showToast({ title: '下载失败', icon: 'none' }); } }); }, // 修复:时间格式化函数 - 确保正确显示 formatTime: function(timestamp) { // 调试日志 console.log('formatTime 接收到的timestamp:', timestamp, '类型:', typeof timestamp); if (!timestamp || timestamp <= 0) { console.warn('无效的时间戳:', timestamp); return '未知时间'; } const timeNum = Number(timestamp); if (isNaN(timeNum)) { console.warn('时间戳不是有效数字:', timestamp); return '未知时间'; } const date = new Date(timeNum); if (isNaN(date.getTime())) { console.warn('无法创建有效日期对象:', timeNum); return '未知时间'; } // 只显示小时和分钟 const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const result = `${hours}:${minutes}`; console.log('formatTime 结果:', result); return result; }, // 格式化文件大小 formatFileSize: function(bytes) { if (bytes === 0 || !bytes) return '未知大小'; const units = ['B', 'KB', 'MB', 'GB']; let size = bytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return size.toFixed(1) + units[unitIndex]; }, // 阻止事件冒泡 stopPropagation: function() { // 空函数,仅用于阻止事件冒泡 } });