Browse Source

修复聊天切换联系人发送消息问题,统一时间显示格式

pull/1/head
徐飞洋 3 months ago
parent
commit
6c7b081c70
  1. 289
      pages/chat-detail/index.js
  2. 4
      pages/chat-detail/index.wxml
  3. 2
      pages/chat-detail/index.wxss
  4. 172
      pages/chat/index.js
  5. 38
      utils/api.js

289
pages/chat-detail/index.js

@ -8,13 +8,15 @@ Page({
inputValue: '',
loading: false,
chatTitle: '聊天对象',
managerPhone: null
managerPhone: null,
timer: null
},
onLoad: function (options) {
if (options.id) {
this.setData({
chatId: options.id
chatId: options.id,
managerPhone: options.id // 直接将chatId作为managerPhone使用,因为聊天列表页传递的是manager_phone
});
// 如果有传递name参数,直接使用该名称作为聊天标题
@ -23,60 +25,30 @@ Page({
chatTitle: decodeURIComponent(options.name)
});
} else {
// 否则从API获取聊天标题
// 如果没有传递name参数,加载聊天标题
this.loadChatTitle();
}
}
this.loadMessages();
},
// 加载聊天标题
loadChatTitle: function () {
// 从本地存储获取聊天列表
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;
}
}
}
// 设置定时器,每5秒查询一次数据库同步内容
this.startTimer();
},
// 如果还没有获取到,尝试从直接存储获取
if (!userPhone) {
if (wx.getStorageSync('phoneNumber')) {
userPhone = wx.getStorageSync('phoneNumber');
} else if (wx.getStorageSync('phone')) {
userPhone = wx.getStorageSync('phone');
}
// 页面显示时重新启动定时器
onShow: function () {
if (!this.data.timer) {
this.startTimer();
}
},
if (userPhone) {
// 获取聊天列表
API.getChatList(userPhone).then(chatList => {
if (Array.isArray(chatList)) {
// 找到当前聊天项
const currentChat = chatList.find(item => item.id === this.data.chatId);
if (currentChat && currentChat.manager_phone) {
this.setData({ managerPhone: currentChat.manager_phone });
// 加载聊天标题
loadChatTitle: function () {
// 直接使用已有的managerPhone获取业务员信息
const managerPhone = this.data.managerPhone;
if (managerPhone) {
// 获取业务员信息
API.getSalesPersonnelInfo(currentChat.manager_phone).then(personnelInfo => {
API.getSalesPersonnelInfo(managerPhone).then(personnelInfo => {
if (personnelInfo && personnelInfo.alias) {
this.setData({ chatTitle: personnelInfo.alias });
}
@ -84,11 +56,6 @@ Page({
console.error('获取业务员信息失败:', error);
});
}
}
}).catch(error => {
console.error('获取聊天列表失败:', error);
});
}
},
onBack: function () {
@ -126,6 +93,7 @@ Page({
},
loadMessages: function () {
return new Promise((resolve, reject) => {
this.setData({ loading: true });
// 获取当前用户的手机号
@ -179,7 +147,9 @@ Page({
content: message.content,
sender: sender,
time: time,
originalTime: message.created_at
originalTime: message.created_at,
sender_phone: message.sender_phone,
receiver_phone: message.receiver_phone
};
});
@ -190,14 +160,23 @@ Page({
this.setData({
messages: processedMessages,
loading: false
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({
@ -207,6 +186,8 @@ Page({
title: '加载聊天记录失败',
icon: 'none'
});
reject(error);
});
});
},
@ -314,30 +295,208 @@ Page({
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: Date.now(),
id: tempId,
content: content,
sender: 'me',
time: '刚刚'
};
// 先在本地显示消息
this.setData({
messages: [...this.data.messages, newMessage],
inputValue: ''
inputValue: '',
scrollToView: 'latest-message'
});
// 模拟对方回复
setTimeout(() => {
const reply = {
id: Date.now() + 1,
content: '这是一条自动回复',
sender: 'other',
time: '刚刚'
// 调用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({
messages: [...this.data.messages, reply]
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
});
}, 1000);
}
},
});

4
pages/chat-detail/index.wxml

@ -11,7 +11,7 @@
</view>
</view>
<scroll-view class="chat-content" scroll-y bindscrolltolower="loadMoreMessages">
<scroll-view class="chat-content" scroll-y bindscrolltolower="loadMoreMessages" scroll-into-view="{{scrollToView}}" scroll-with-animation="true">
<view class="chat-messages">
<block wx:if="{{loading && messages.length === 0}}">
<view class="loading">加载中...</view>
@ -21,7 +21,7 @@
</block>
<block wx:else>
<!-- 动态渲染聊天消息 -->
<view wx:for="{{messages}}" wx:key="id" class="message-item {{item.sender}}">
<view wx:for="{{messages}}" wx:key="id" class="message-item {{item.sender}}" id="{{index === messages.length - 1 ? 'latest-message' : 'message-' + item.id}}">
<!-- 对方消息 -->
<view wx:if="{{item.sender === 'other'}}" class="avatar">
<image src="https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0" mode="aspectFill"></image>

2
pages/chat-detail/index.wxss

@ -41,7 +41,7 @@
.chat-content {
flex: 1;
padding: 20rpx;
padding: 20rpx 20rpx 120rpx 20rpx; /* 增加底部padding,避免被输入框遮挡 */
overflow-y: auto;
}

172
pages/chat/index.js

@ -5,18 +5,83 @@ Page({
data: {
chatList: [],
searchKeyword: '',
filteredChatList: []
filteredChatList: [],
timer: null,
debugCount: 0, // 调试信息输出计数器
loginToastShown: false // 登录提示是否已显示
},
onLoad: function (options) {
this.loadChatList();
},
loadChatList: function () {
// 显示加载提示
wx.showLoading({
title: '加载中...',
// 检查用户是否已登录(与loadChatList中的手机号检查逻辑保持一致)
isUserLoggedIn: function () {
const users = wx.getStorageSync('users') || {};
const userId = wx.getStorageSync('userId');
let userPhone = null;
// 与loadChatList中的手机号检查逻辑完全一致
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) {
userPhone = wx.getStorageSync('phoneNumber') || wx.getStorageSync('phone');
}
if (!userPhone) {
const loginInfo = wx.getStorageSync('loginInfo');
if (loginInfo) {
if (loginInfo.phoneNumber) {
userPhone = loginInfo.phoneNumber;
} else if (loginInfo.phone) {
userPhone = loginInfo.phone;
}
}
}
// 只有获取到手机号才视为已登录
return !!userPhone;
},
onShow: function () {
// 只有已登录用户才启动定时器
if (!this.data.timer && this.isUserLoggedIn()) {
this.startTimer();
}
},
startTimer: function () {
// 设置5秒刷新定时器
this.setData({
timer: setInterval(() => {
this.loadChatList();
}, 5000)
});
},
loadChatList: function () {
// 增加调试信息计数器
const newDebugCount = this.data.debugCount + 1;
this.setData({ debugCount: newDebugCount });
// 获取用户手机号 - 增强版,增加更多获取途径和调试信息
const users = wx.getStorageSync('users') || {};
@ -24,12 +89,13 @@ Page({
let userPhone = null;
// 添加调试信息,显示当前存储的用户信息
console.log('调试信息 - 登录用户:', {
console.log('调试信息 - 登录用户 (第' + newDebugCount + '次):', {
userId: userId,
users: users,
userInfo: wx.getStorageSync('userInfo'),
phoneNumber: wx.getStorageSync('phoneNumber'),
phone: wx.getStorageSync('phone')
phone: wx.getStorageSync('phone'),
debugCount: newDebugCount
});
// 尝试从users中获取手机号(支持不同的键名)
@ -85,10 +151,35 @@ Page({
// 如果没有手机号,显示错误提示
if (!userPhone) {
wx.hideLoading();
// 登录提示只显示一次
if (!this.data.loginToastShown) {
wx.showToast({
title: '请先登录并绑定手机号',
icon: 'none'
});
this.setData({ loginToastShown: true });
}
// 调试信息输出3次后返回首页并关闭定时器
if (newDebugCount >= 3) {
console.log('调试信息已输出3次,准备返回首页并关闭定时器');
// 关闭定时器
if (this.data.timer) {
clearInterval(this.data.timer);
this.setData({ timer: null });
}
// 返回首页
wx.navigateBack({
delta: 1,
success: function() {
console.log('已成功返回首页');
}
});
}
return;
}
@ -119,9 +210,22 @@ Page({
}
// 确保消息内容存在
chatItem.content = chatItem.content || '暂无消息内容';
// 确保时间存在
chatItem.time = chatItem.time || '刚刚';
if (!chatItem.content) {
// 如果没有消息内容,尝试获取该聊天会话的最新消息
try {
const messages = await API.getChatMessages(chatItem.manager_phone, userPhone, { limit: 1 });
if (messages.length > 0) {
chatItem.content = messages[0].content || '暂无消息内容';
} else {
chatItem.content = '暂无消息内容';
}
} catch (error) {
console.error('获取聊天消息失败:', error);
chatItem.content = '暂无消息内容';
}
}
// 格式化时间
chatItem.time = this.formatDateTime(chatItem.time || null);
// 确保unread字段存在
chatItem.unread = chatItem.unread || false;
@ -214,5 +318,53 @@ Page({
onPullDownRefresh: function () {
this.loadChatList();
wx.stopPullDownRefresh();
},
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
});
}
},
// 格式化时间显示
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}`;
}
}
});

38
utils/api.js

@ -3588,6 +3588,44 @@ module.exports = {
});
},
// 发送聊天消息
sendMessage: function (senderPhone, receiverPhone, content) {
return new Promise((resolve, reject) => {
console.log('API.sendMessage - senderPhone:', senderPhone, 'receiverPhone:', receiverPhone, 'content:', content);
// 验证必要参数
if (!senderPhone || !receiverPhone || !content) {
const error = new Error('发送者电话、接收者电话和消息内容不能为空');
console.error('API.sendMessage - 错误:', error);
reject(error);
return;
}
const requestData = {
sender_phone: senderPhone,
receiver_phone: receiverPhone,
content: content
};
console.log('API.sendMessage - 请求数据:', requestData);
request('/api/chat/send', 'POST', requestData).then(res => {
console.log('API.sendMessage - 响应数据:', res);
// 处理不同格式的响应
if (res && (res.success || res.code === 200)) {
resolve(res);
} else {
const errorMessage = res && res.message ? res.message : '发送消息失败';
reject(new Error(errorMessage));
}
}).catch(error => {
console.error('API.sendMessage - 请求失败:', error);
reject(error);
});
});
},
// 获取聊天列表数据
getChatList: function (userPhone) {
console.log('API.getChatList - userPhone:', userPhone);

Loading…
Cancel
Save