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.
527 lines
16 KiB
527 lines
16 KiB
// pages/chat-detail/index.js
|
|
const API = require('../../utils/api.js');
|
|
|
|
Page({
|
|
data: {
|
|
chatId: null,
|
|
messages: [],
|
|
inputValue: '',
|
|
loading: false,
|
|
chatTitle: '聊天对象',
|
|
managerPhone: null,
|
|
timer: null,
|
|
lastLoadTime: 0 // 用于节流的时间戳
|
|
},
|
|
|
|
onLoad: function (options) {
|
|
// 支持两种参数传递方式:
|
|
// 1. 从聊天列表页传递的 id 参数
|
|
// 2. 从客服列表页传递的 userId、userName、phone 参数
|
|
let chatId = options.id || options.userId;
|
|
let managerPhone = options.phone;
|
|
|
|
if (chatId) {
|
|
this.setData({
|
|
chatId: chatId,
|
|
managerPhone: managerPhone || options.id // 如果没有直接传递phone,则使用chatId作为fallback
|
|
});
|
|
|
|
// 如果有传递name或userName参数,使用该名称作为聊天标题
|
|
let chatTitle = options.name || options.userName;
|
|
if (chatTitle) {
|
|
this.setData({
|
|
chatTitle: decodeURIComponent(chatTitle)
|
|
});
|
|
} else {
|
|
// 如果没有传递名称参数,加载聊天标题
|
|
this.loadChatTitle();
|
|
}
|
|
}
|
|
this.loadMessages();
|
|
|
|
// 设置定时器,每5秒查询一次数据库同步内容
|
|
this.startTimer();
|
|
},
|
|
|
|
// 页面显示时重新启动定时器
|
|
onShow: function () {
|
|
if (!this.data.timer) {
|
|
this.startTimer();
|
|
}
|
|
},
|
|
|
|
// 加载聊天标题
|
|
loadChatTitle: function () {
|
|
// 直接使用已有的managerPhone获取业务员信息
|
|
const managerPhone = this.data.managerPhone;
|
|
if (managerPhone) {
|
|
// 获取业务员信息
|
|
API.getSalesPersonnelInfo(managerPhone).then(personnelInfo => {
|
|
if (personnelInfo && personnelInfo.alias) {
|
|
this.setData({ chatTitle: personnelInfo.alias });
|
|
}
|
|
}).catch(error => {
|
|
console.error('获取业务员信息失败:', error);
|
|
});
|
|
}
|
|
},
|
|
|
|
onBack: function () {
|
|
wx.navigateBack();
|
|
},
|
|
|
|
// 格式化时间显示
|
|
formatDateTime: function (dateString) {
|
|
if (!dateString) return '刚刚';
|
|
|
|
const now = new Date();
|
|
const msgDate = new Date(dateString);
|
|
const diffMs = now - msgDate;
|
|
const diffMins = Math.floor(diffMs / 60000);
|
|
const diffHours = Math.floor(diffMs / 3600000);
|
|
const diffDays = Math.floor(diffMs / 86400000);
|
|
|
|
if (diffMins < 1) {
|
|
return '刚刚';
|
|
} else if (diffMins < 60) {
|
|
return `${diffMins}分钟前`;
|
|
} else if (diffHours < 24) {
|
|
return `${diffHours}小时前`;
|
|
} else if (diffDays < 7) {
|
|
return `${diffDays}天前`;
|
|
} else {
|
|
// 超过一周显示具体日期
|
|
const year = msgDate.getFullYear();
|
|
const month = (msgDate.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = msgDate.getDate().toString().padStart(2, '0');
|
|
const hours = msgDate.getHours().toString().padStart(2, '0');
|
|
const minutes = msgDate.getMinutes().toString().padStart(2, '0');
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
}
|
|
},
|
|
|
|
loadMessages: function () {
|
|
// 节流逻辑:避免短时间内多次调用
|
|
const currentTime = Date.now();
|
|
if (currentTime - this.data.lastLoadTime < 2000) { // 2秒内不重复调用
|
|
console.log('API调用节流中,距离上次调用仅' + (currentTime - this.data.lastLoadTime) + 'ms');
|
|
return Promise.resolve();
|
|
}
|
|
|
|
// 更新上次加载时间
|
|
this.setData({
|
|
lastLoadTime: currentTime
|
|
});
|
|
|
|
return new Promise((resolve, reject) => {
|
|
this.setData({ loading: true });
|
|
|
|
// 获取当前用户的手机号
|
|
const users = wx.getStorageSync('users') || {};
|
|
const userId = wx.getStorageSync('userId');
|
|
let userPhone = null;
|
|
|
|
// 尝试从users中获取手机号
|
|
if (userId && users[userId]) {
|
|
if (users[userId].phoneNumber) {
|
|
userPhone = users[userId].phoneNumber;
|
|
} else if (users[userId].phone) {
|
|
userPhone = users[userId].phone;
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从全局用户信息获取
|
|
if (!userPhone) {
|
|
const userInfo = wx.getStorageSync('userInfo');
|
|
if (userInfo) {
|
|
if (userInfo.phoneNumber) {
|
|
userPhone = userInfo.phoneNumber;
|
|
} else if (userInfo.phone) {
|
|
userPhone = userInfo.phone;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从直接存储获取
|
|
if (!userPhone) {
|
|
if (wx.getStorageSync('phoneNumber')) {
|
|
userPhone = wx.getStorageSync('phoneNumber');
|
|
} else if (wx.getStorageSync('phone')) {
|
|
userPhone = wx.getStorageSync('phone');
|
|
}
|
|
}
|
|
|
|
// 重要修复:当有managerPhone时,应该使用managerPhone作为chatId传递给服务器
|
|
// 因为服务器端查询需要的是手机号,而不是客服人员的ID
|
|
const chatIdForApi = this.data.managerPhone || this.data.chatId;
|
|
|
|
// 使用新添加的API获取聊天记录
|
|
API.getChatMessages(chatIdForApi, userPhone).then(res => {
|
|
if (Array.isArray(res)) {
|
|
// 处理每条消息,确定发送者和格式化时间
|
|
const processedMessages = res.map(message => {
|
|
// 判断消息是发送还是接收
|
|
const sender = (message.sender_phone === userPhone) ? 'me' : 'other';
|
|
|
|
// 格式化时间
|
|
const time = this.formatDateTime(message.created_at);
|
|
|
|
return {
|
|
id: message.id,
|
|
content: message.content,
|
|
sender: sender,
|
|
time: time,
|
|
originalTime: message.created_at,
|
|
sender_phone: message.sender_phone,
|
|
receiver_phone: message.receiver_phone
|
|
};
|
|
});
|
|
|
|
// 按时间顺序排序(升序)
|
|
processedMessages.sort((a, b) => {
|
|
return new Date(a.originalTime) - new Date(b.originalTime);
|
|
});
|
|
|
|
this.setData({
|
|
messages: processedMessages,
|
|
loading: false,
|
|
scrollToView: processedMessages.length > 0 ? 'latest-message' : ''
|
|
});
|
|
|
|
// 如果managerPhone尚未设置,尝试从聊天记录中获取
|
|
if (!this.data.managerPhone && processedMessages.length > 0) {
|
|
const firstMessage = processedMessages[0];
|
|
const managerPhone = (firstMessage.sender_phone === userPhone) ? firstMessage.receiver_phone : firstMessage.sender_phone;
|
|
this.setData({ managerPhone: managerPhone });
|
|
}
|
|
} else {
|
|
this.setData({
|
|
messages: [],
|
|
loading: false
|
|
});
|
|
}
|
|
resolve();
|
|
}).catch(error => {
|
|
console.error('加载聊天记录失败:', error);
|
|
this.setData({
|
|
loading: false
|
|
});
|
|
wx.showToast({
|
|
title: '加载聊天记录失败',
|
|
icon: 'none'
|
|
});
|
|
reject(error);
|
|
});
|
|
});
|
|
},
|
|
|
|
loadMoreMessages: function () {
|
|
// 加载更多历史消息
|
|
if (this.data.loading) return;
|
|
|
|
this.setData({ loading: true });
|
|
|
|
// 获取当前用户的手机号
|
|
const users = wx.getStorageSync('users') || {};
|
|
const userId = wx.getStorageSync('userId');
|
|
let userPhone = null;
|
|
|
|
// 尝试从users中获取手机号
|
|
if (userId && users[userId]) {
|
|
if (users[userId].phoneNumber) {
|
|
userPhone = users[userId].phoneNumber;
|
|
} else if (users[userId].phone) {
|
|
userPhone = users[userId].phone;
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从全局用户信息获取
|
|
if (!userPhone) {
|
|
const userInfo = wx.getStorageSync('userInfo');
|
|
if (userInfo) {
|
|
if (userInfo.phoneNumber) {
|
|
userPhone = userInfo.phoneNumber;
|
|
} else if (userInfo.phone) {
|
|
userPhone = userInfo.phone;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从直接存储获取
|
|
if (!userPhone) {
|
|
if (wx.getStorageSync('phoneNumber')) {
|
|
userPhone = wx.getStorageSync('phoneNumber');
|
|
} else if (wx.getStorageSync('phone')) {
|
|
userPhone = wx.getStorageSync('phone');
|
|
}
|
|
}
|
|
|
|
// 获取最早的消息时间,用于分页加载
|
|
const earliestTime = this.data.messages.length > 0 ? this.data.messages[0].originalTime : null;
|
|
|
|
// 使用API获取更多聊天记录(带分页参数)
|
|
const chatIdForApi = this.data.managerPhone || this.data.chatId;
|
|
API.getChatMessages(chatIdForApi, userPhone, { before: earliestTime }).then(res => {
|
|
if (Array.isArray(res) && res.length > 0) {
|
|
// 处理每条消息,确定发送者和格式化时间
|
|
const processedMessages = res.map(message => {
|
|
// 判断消息是发送还是接收
|
|
const sender = (message.sender_phone === userPhone) ? 'me' : 'other';
|
|
|
|
// 格式化时间
|
|
const time = this.formatDateTime(message.created_at);
|
|
|
|
return {
|
|
id: message.id,
|
|
content: message.content,
|
|
sender: sender,
|
|
time: time,
|
|
originalTime: message.created_at
|
|
};
|
|
});
|
|
|
|
// 按时间顺序排序(升序)
|
|
processedMessages.sort((a, b) => {
|
|
return new Date(a.originalTime) - new Date(b.originalTime);
|
|
});
|
|
|
|
this.setData({
|
|
messages: [...processedMessages, ...this.data.messages],
|
|
loading: false
|
|
});
|
|
} else {
|
|
this.setData({
|
|
loading: false
|
|
});
|
|
wx.showToast({
|
|
title: '没有更多消息了',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
}).catch(error => {
|
|
console.error('加载更多聊天记录失败:', error);
|
|
this.setData({
|
|
loading: false
|
|
});
|
|
wx.showToast({
|
|
title: '加载更多消息失败',
|
|
icon: 'none'
|
|
});
|
|
});
|
|
},
|
|
|
|
onInputChange: function (e) {
|
|
this.setData({
|
|
inputValue: e.detail.value
|
|
});
|
|
},
|
|
|
|
sendMessage: function () {
|
|
const content = this.data.inputValue.trim();
|
|
if (!content) return;
|
|
|
|
// 获取当前用户的手机号
|
|
const users = wx.getStorageSync('users') || {};
|
|
const userId = wx.getStorageSync('userId');
|
|
let userPhone = null;
|
|
|
|
// 尝试从users中获取手机号
|
|
if (userId && users[userId]) {
|
|
if (users[userId].phoneNumber) {
|
|
userPhone = users[userId].phoneNumber;
|
|
} else if (users[userId].phone) {
|
|
userPhone = users[userId].phone;
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从全局用户信息获取
|
|
if (!userPhone) {
|
|
const userInfo = wx.getStorageSync('userInfo');
|
|
if (userInfo) {
|
|
if (userInfo.phoneNumber) {
|
|
userPhone = userInfo.phoneNumber;
|
|
} else if (userInfo.phone) {
|
|
userPhone = userInfo.phone;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果还没有获取到,尝试从直接存储获取
|
|
if (!userPhone) {
|
|
if (wx.getStorageSync('phoneNumber')) {
|
|
userPhone = wx.getStorageSync('phoneNumber');
|
|
} else if (wx.getStorageSync('phone')) {
|
|
userPhone = wx.getStorageSync('phone');
|
|
}
|
|
}
|
|
|
|
// 获取客服手机号
|
|
let managerPhone = this.data.managerPhone;
|
|
|
|
if (!userPhone) {
|
|
wx.showToast({
|
|
title: '获取用户手机号失败,请重新登录',
|
|
icon: 'none'
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 如果managerPhone尚未设置,尝试从聊天记录中获取
|
|
if (!managerPhone && this.data.messages && this.data.messages.length > 0) {
|
|
// 从第一条消息中提取与当前用户不同的手机号作为managerPhone
|
|
const firstMessage = this.data.messages[0];
|
|
if (firstMessage && firstMessage.sender_phone) {
|
|
managerPhone = (firstMessage.sender_phone === userPhone) ? firstMessage.receiver_phone : firstMessage.sender_phone;
|
|
this.setData({ managerPhone: managerPhone });
|
|
}
|
|
}
|
|
|
|
// 如果managerPhone仍然不存在,尝试直接从API获取
|
|
if (!managerPhone) {
|
|
// 显示加载提示
|
|
wx.showLoading({
|
|
title: '获取客服信息中...',
|
|
});
|
|
|
|
// 先尝试从聊天列表获取
|
|
API.getChatList(userPhone).then(chatList => {
|
|
if (Array.isArray(chatList)) {
|
|
// 找到当前聊天项
|
|
const currentChat = chatList.find(item => item.id === this.data.chatId);
|
|
if (currentChat && currentChat.manager_phone) {
|
|
managerPhone = currentChat.manager_phone;
|
|
this.setData({ managerPhone: managerPhone });
|
|
|
|
// 获取到managerPhone后立即发送消息
|
|
this.sendMessageAfterGetManagerPhone(userPhone, managerPhone, content);
|
|
} else {
|
|
// 如果聊天列表中没有找到,尝试直接从聊天记录获取
|
|
this.loadMessages().then(() => {
|
|
if (this.data.messages.length > 0) {
|
|
const firstMessage = this.data.messages[0];
|
|
managerPhone = (firstMessage.sender_phone === userPhone) ? firstMessage.receiver_phone : firstMessage.sender_phone;
|
|
this.setData({ managerPhone: managerPhone });
|
|
this.sendMessageAfterGetManagerPhone(userPhone, managerPhone, content);
|
|
} else {
|
|
wx.hideLoading();
|
|
wx.showToast({
|
|
title: '获取客服信息失败,请稍候重试',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
}).catch(() => {
|
|
wx.hideLoading();
|
|
wx.showToast({
|
|
title: '获取客服信息失败,请稍候重试',
|
|
icon: 'none'
|
|
});
|
|
});
|
|
}
|
|
} else {
|
|
wx.hideLoading();
|
|
wx.showToast({
|
|
title: '获取客服信息失败,请稍候重试',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
}).catch(() => {
|
|
wx.hideLoading();
|
|
wx.showToast({
|
|
title: '获取客服信息失败,请稍候重试',
|
|
icon: 'none'
|
|
});
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 正常发送消息
|
|
this.sendMessageAfterGetManagerPhone(userPhone, managerPhone, content);
|
|
},
|
|
|
|
// 当获取到managerPhone后发送消息
|
|
sendMessageAfterGetManagerPhone: function (userPhone, managerPhone, content) {
|
|
// 隐藏加载提示
|
|
wx.hideLoading();
|
|
|
|
// 创建临时消息
|
|
const tempId = Date.now();
|
|
const newMessage = {
|
|
id: tempId,
|
|
content: content,
|
|
sender: 'me',
|
|
time: '刚刚'
|
|
};
|
|
|
|
// 先在本地显示消息
|
|
this.setData({
|
|
messages: [...this.data.messages, newMessage],
|
|
inputValue: '',
|
|
scrollToView: 'latest-message'
|
|
});
|
|
|
|
// 调用API发送消息到数据库
|
|
API.sendMessage(userPhone, managerPhone, content).then(res => {
|
|
console.log('消息发送成功:', res);
|
|
// 如果需要,可以更新消息的id为服务器返回的id
|
|
if (res && res.data && res.data.id) {
|
|
const updatedMessages = this.data.messages.map(msg => {
|
|
if (msg.id === tempId) {
|
|
return {
|
|
...msg,
|
|
id: res.data.id
|
|
};
|
|
}
|
|
return msg;
|
|
});
|
|
this.setData({
|
|
messages: updatedMessages
|
|
});
|
|
}
|
|
}).catch(error => {
|
|
console.error('消息发送失败:', error);
|
|
wx.showToast({
|
|
title: '消息发送失败,请稍后重试',
|
|
icon: 'none'
|
|
});
|
|
});
|
|
|
|
// 移除模拟对方回复的代码,改为定时器同步数据库内容
|
|
},
|
|
|
|
// 启动定时器
|
|
startTimer: function () {
|
|
// 清除之前的定时器(如果有)
|
|
if (this.data.timer) {
|
|
clearInterval(this.data.timer);
|
|
}
|
|
|
|
// 设置新的定时器,每5秒调用一次loadMessages方法
|
|
const timer = setInterval(() => {
|
|
this.loadMessages();
|
|
}, 5000);
|
|
|
|
this.setData({
|
|
timer: timer
|
|
});
|
|
},
|
|
|
|
// 页面隐藏时清除定时器
|
|
onHide: function () {
|
|
if (this.data.timer) {
|
|
clearInterval(this.data.timer);
|
|
this.setData({
|
|
timer: null
|
|
});
|
|
}
|
|
},
|
|
|
|
// 页面卸载时清除定时器
|
|
onUnload: function () {
|
|
if (this.data.timer) {
|
|
clearInterval(this.data.timer);
|
|
this.setData({
|
|
timer: null
|
|
});
|
|
}
|
|
},
|
|
});
|