与牧同行-小程序用户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

1366 lines
36 KiB

// 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() {
// 空函数,仅用于阻止事件冒泡
}
});