From 6c7b081c704a3a99ac373b04b35a0bbf86e43804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=A3=9E=E6=B4=8B?= <15778543+xufeiyang6017@user.noreply.gitee.com> Date: Sat, 20 Dec 2025 10:31:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E8=81=94=E7=B3=BB=E4=BA=BA=E5=8F=91=E9=80=81=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E9=97=AE=E9=A2=98=EF=BC=8C=E7=BB=9F=E4=B8=80=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=98=BE=E7=A4=BA=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/chat-detail/index.js | 435 ++++++++++++++++++++++++----------- pages/chat-detail/index.wxml | 4 +- pages/chat-detail/index.wxss | 2 +- pages/chat/index.js | 180 +++++++++++++-- utils/api.js | 38 +++ 5 files changed, 504 insertions(+), 155 deletions(-) diff --git a/pages/chat-detail/index.js b/pages/chat-detail/index.js index a660bc5..0d598dd 100644 --- a/pages/chat-detail/index.js +++ b/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,70 +25,35 @@ Page({ chatTitle: decodeURIComponent(options.name) }); } else { - // 否则从API获取聊天标题 + // 如果没有传递name参数,加载聊天标题 this.loadChatTitle(); } } this.loadMessages(); + + // 设置定时器,每5秒查询一次数据库同步内容 + this.startTimer(); }, - // 加载聊天标题 - 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; - } - } - } - - // 如果还没有获取到,尝试从直接存储获取 - 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 }); - // 获取业务员信息 - API.getSalesPersonnelInfo(currentChat.manager_phone).then(personnelInfo => { - if (personnelInfo && personnelInfo.alias) { - this.setData({ chatTitle: personnelInfo.alias }); - } - }).catch(error => { - console.error('获取业务员信息失败:', error); - }); - } + // 加载聊天标题 + 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); + console.error('获取业务员信息失败:', error); }); } }, @@ -126,6 +93,108 @@ Page({ }, loadMessages: function () { + 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'); + } + } + + // 使用新添加的API获取聊天记录 + API.getChatMessages(this.data.chatId, 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 }); // 获取当前用户的手机号 @@ -163,9 +232,12 @@ Page({ } } - // 使用新添加的API获取聊天记录 - API.getChatMessages(this.data.chatId, userPhone).then(res => { - if (Array.isArray(res)) { + // 获取最早的消息时间,用于分页加载 + const earliestTime = this.data.messages.length > 0 ? this.data.messages[0].originalTime : null; + + // 使用API获取更多聊天记录(带分页参数) + API.getChatMessages(this.data.chatId, userPhone, { before: earliestTime }).then(res => { + if (Array.isArray(res) && res.length > 0) { // 处理每条消息,确定发送者和格式化时间 const processedMessages = res.map(message => { // 判断消息是发送还是接收 @@ -189,32 +261,39 @@ Page({ }); this.setData({ - messages: processedMessages, + messages: [...processedMessages, ...this.data.messages], loading: false }); } else { this.setData({ - messages: [], loading: false }); + wx.showToast({ + title: '没有更多消息了', + icon: 'none' + }); } }).catch(error => { - console.error('加载聊天记录失败:', error); + console.error('加载更多聊天记录失败:', error); this.setData({ loading: false }); wx.showToast({ - title: '加载聊天记录失败', + title: '加载更多消息失败', icon: 'none' }); }); }, - loadMoreMessages: function () { - // 加载更多历史消息 - if (this.data.loading) return; - - this.setData({ loading: true }); + 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') || {}; @@ -251,93 +330,173 @@ Page({ } } - // 获取最早的消息时间,用于分页加载 - const earliestTime = this.data.messages.length > 0 ? this.data.messages[0].originalTime : null; + // 获取客服手机号 + let managerPhone = this.data.managerPhone; - // 使用API获取更多聊天记录(带分页参数) - API.getChatMessages(this.data.chatId, 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 - }); + 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: '没有更多消息了', + 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 - }); + return; + } + + // 正常发送消息 + this.sendMessageAfterGetManagerPhone(userPhone, managerPhone, content); }, - - sendMessage: function () { - const content = this.data.inputValue.trim(); - if (!content) return; + + // 当获取到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({ + timer: timer + }); + }, + + // 页面隐藏时清除定时器 + onHide: function () { + if (this.data.timer) { + clearInterval(this.data.timer); this.setData({ - messages: [...this.data.messages, reply] + timer: null }); - }, 1000); - } + } + }, + + // 页面卸载时清除定时器 + onUnload: function () { + if (this.data.timer) { + clearInterval(this.data.timer); + this.setData({ + timer: null + }); + } + }, }); \ No newline at end of file diff --git a/pages/chat-detail/index.wxml b/pages/chat-detail/index.wxml index 5d49a3a..a552785 100644 --- a/pages/chat-detail/index.wxml +++ b/pages/chat-detail/index.wxml @@ -11,7 +11,7 @@ - + 加载中... @@ -21,7 +21,7 @@ - + diff --git a/pages/chat-detail/index.wxss b/pages/chat-detail/index.wxss index 49ca016..c82494c 100644 --- a/pages/chat-detail/index.wxss +++ b/pages/chat-detail/index.wxss @@ -41,7 +41,7 @@ .chat-content { flex: 1; - padding: 20rpx; + padding: 20rpx 20rpx 120rpx 20rpx; /* 增加底部padding,避免被输入框遮挡 */ overflow-y: auto; } diff --git a/pages/chat/index.js b/pages/chat/index.js index c4be354..0f39ac8 100644 --- a/pages/chat/index.js +++ b/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(); - wx.showToast({ - title: '请先登录并绑定手机号', - icon: 'none' - }); + + // 登录提示只显示一次 + 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}`; + } } }); \ No newline at end of file diff --git a/utils/api.js b/utils/api.js index bd9c4d9..331da39 100644 --- a/utils/api.js +++ b/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);