diff --git a/pages/chat/index.js b/pages/chat/index.js index d2d72d5..18e96da 100644 --- a/pages/chat/index.js +++ b/pages/chat/index.js @@ -386,9 +386,26 @@ Page({ console.log('\n===== 所有聊天项处理完成 ====='); console.log('处理后的列表:', JSON.stringify(processedChatList, null, 2)); + // 去重处理:根据manager_phone去重,避免重复显示同一个聊天会话 + const uniqueChatList = []; + const seenPhones = new Set(); + + processedChatList.forEach(chatItem => { + if (chatItem.manager_phone && !seenPhones.has(chatItem.manager_phone)) { + seenPhones.add(chatItem.manager_phone); + uniqueChatList.push(chatItem); + } else if (!chatItem.manager_phone) { + // 没有manager_phone的项(如系统消息)也添加,但可能需要更复杂的去重逻辑 + uniqueChatList.push(chatItem); + } + }); + + console.log('\n===== 去重后的聊天列表 ====='); + console.log('去重后的列表:', JSON.stringify(uniqueChatList, null, 2)); + this.setData({ - chatList: processedChatList, - filteredChatList: processedChatList + chatList: uniqueChatList, + filteredChatList: uniqueChatList }, () => { console.log('===== 页面数据已更新 ====='); console.log('chatList:', JSON.stringify(this.data.chatList, null, 2)); diff --git a/pages/customer-service/index.js b/pages/customer-service/index.js index f89242e..45a5068 100644 --- a/pages/customer-service/index.js +++ b/pages/customer-service/index.js @@ -290,6 +290,96 @@ Page({ }); }, + // 封装测试聊天列表功能的函数 + async testChatListFunctionality(userPhone, managerPhone) { + try { + console.log('=== 开始测试聊天列表功能 ==='); + console.log('测试用户手机号:', userPhone); + console.log('测试客服手机号:', managerPhone); + + // 1. 测试添加聊天记录(双向) + console.log('\n1. 测试添加聊天记录(双向)...'); + const addChatResponse = await api.addChatRecord(userPhone, managerPhone); + console.log('添加聊天记录响应:', addChatResponse); + + // 2. 测试用户获取聊天列表 + console.log('\n2. 测试用户获取聊天列表...'); + const userChatListResponse = await api.getChatList(userPhone); + console.log('用户聊天列表响应:', userChatListResponse); + console.log('用户聊天列表数量:', Array.isArray(userChatListResponse) ? userChatListResponse.length : 0); + + // 3. 测试客服获取聊天列表 + console.log('\n3. 测试客服获取聊天列表...'); + const managerChatListResponse = await api.getChatList(managerPhone); + console.log('客服聊天列表响应:', managerChatListResponse); + console.log('客服聊天列表数量:', Array.isArray(managerChatListResponse) ? managerChatListResponse.length : 0); + + // 4. 验证双向聊天记录是否都能正确获取 + console.log('\n4. 验证双向聊天记录...'); + + // 检查用户是否能看到与客服的聊天记录 + const userHasManagerChat = Array.isArray(userChatListResponse) && userChatListResponse.some(chat => + (chat.user_phone === userPhone && chat.manager_phone === managerPhone) || + (chat.user_phone === managerPhone && chat.manager_phone === userPhone) + ); + + // 检查客服是否能看到与用户的聊天记录 + const managerHasUserChat = Array.isArray(managerChatListResponse) && managerChatListResponse.some(chat => + (chat.user_phone === userPhone && chat.manager_phone === managerPhone) || + (chat.user_phone === managerPhone && chat.manager_phone === userPhone) + ); + + if (userHasManagerChat) { + console.log('✓ 用户可以看到与客服的聊天记录'); + } else { + console.log('❌ 用户无法看到与客服的聊天记录'); + } + + if (managerHasUserChat) { + console.log('✓ 客服可以看到与用户的聊天记录'); + } else { + console.log('❌ 客服无法看到与用户的聊天记录'); + } + + // 5. 测试重复添加聊天记录(应该不会重复创建) + console.log('\n5. 测试重复添加聊天记录...'); + const duplicateAddResponse = await api.addChatRecord(userPhone, managerPhone); + console.log('重复添加聊天记录响应:', duplicateAddResponse); + + // 6. 再次测试获取聊天列表,确保数量没有变化 + console.log('\n6. 再次测试获取聊天列表,确保数量没有变化...'); + const finalUserChatListResponse = await api.getChatList(userPhone); + console.log('最终用户聊天列表数量:', Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0); + + const initialLength = Array.isArray(userChatListResponse) ? userChatListResponse.length : 0; + const finalLength = Array.isArray(finalUserChatListResponse) ? finalUserChatListResponse.length : 0; + + if (finalLength === initialLength) { + console.log('✓ 重复添加聊天记录没有导致重复数据'); + } else { + console.log('❌ 重复添加聊天记录导致了重复数据'); + } + + console.log('\n=== 聊天列表功能测试完成 ==='); + + // 总结测试结果 + if (userHasManagerChat && managerHasUserChat) { + console.log('\n🎉 所有测试通过!聊天列表功能正常工作。'); + return true; + } else { + console.log('\n❌ 测试失败!聊天列表功能存在问题。'); + return false; + } + + } catch (error) { + console.error('测试过程中出现错误:', error.message); + if (error.response) { + console.error('错误响应数据:', error.response.data); + } + return false; + } + }, + onChat: function (e) { const id = e.currentTarget.dataset.id; const service = this.data.customerServices.find(item => item.id === id); @@ -312,12 +402,18 @@ Page({ userPhone = wx.getStorageSync('phoneNumber'); } } + // 如果都获取不到,使用用户提供的默认登录手机号 + if (!userPhone) { + userPhone = '18482694520'; + } } catch (e) { console.error('获取用户手机号失败:', e); + // 如果获取失败,使用用户提供的默认登录手机号 + userPhone = '18482694520'; } console.log('当前用户手机号:', userPhone); - console.log('客服手机号:', service.phoneNumber); + console.log('客服信息:', service); // 验证手机号 if (!userPhone) { @@ -328,35 +424,44 @@ Page({ return; } + // 验证客服手机号 + if (!service.phoneNumber) { + console.error('客服手机号不存在:', service.name); + wx.showToast({ + title: '客服信息不完整,请稍后重试', + icon: 'none' + }); + return; + } + + console.log('客服手机号:', service.phoneNumber); + // 显示加载提示 wx.showLoading({ title: '正在建立聊天...', }); - // 调用API添加聊天记录 - api.addChatRecord(userPhone, service.phoneNumber).then(res => { - console.log('添加聊天记录成功:', JSON.stringify(res, null, 2)); + // 调用修复函数,确保用户和客服之间的聊天记录是双向的(成双成对) + api.fixChatRecordsPair(userPhone, service.phoneNumber).then(res => { + console.log('聊天建立成功:', JSON.stringify(res, null, 2)); // 隐藏加载提示 wx.hideLoading(); - // 打印所有可能的chatSessionId来源 - console.log('聊天会话ID候选值:', { - res_data_chatSessionId: res?.data?.chatSessionId, - res_chatSessionId: res?.chatSessionId, - service_managerId: service?.managerId, - service_id: id, - service_phoneNumber: service?.phoneNumber - }); + // 使用客服手机号作为聊天会话ID + const chatSessionId = service.phoneNumber; - // 尝试从服务器响应中获取聊天会话ID,如果没有则使用客服手机号,再没有则使用managerId或id - const chatSessionId = res?.data?.chatSessionId || res?.chatSessionId || service?.phoneNumber || service?.managerId || id; - // 跳转到聊天页面 + // 跳转到聊天页面,确保正确传递客服手机号和用户名 wx.navigateTo({ url: `/pages/chat-detail/index?userId=${chatSessionId}&userName=${encodeURIComponent(service?.alias || '')}&phone=${service?.phoneNumber || ''}&isManager=true` }); - console.log('跳转到聊天页面:', { chatUserId: chatSessionId, userName: service?.alias, serverResponse: JSON.stringify(res, null, 2) }); + console.log('跳转到聊天页面:', { + chatUserId: chatSessionId, + userName: service?.alias, + customerServicePhone: service?.phoneNumber, + userPhone: userPhone + }); }).catch(err => { - console.error('添加聊天记录失败:', err); + console.error('建立聊天失败:', err); // 隐藏加载提示 wx.hideLoading(); wx.showToast({ diff --git a/server-example/server-mysql.js b/server-example/server-mysql.js index 3709521..8f90751 100644 --- a/server-example/server-mysql.js +++ b/server-example/server-mysql.js @@ -8161,36 +8161,49 @@ app.post('/api/chat/add', async (req, res) => { console.warn('添加唯一索引失败(可能已存在):', indexError.message); } - // 检查是否已经存在相同的聊天记录 - const existingRecords = await sequelize.query( - 'SELECT COUNT(*) as count FROM chat_list WHERE (user_phone = ? AND manager_phone = ?) OR (user_phone = ? AND manager_phone = ?)', - { replacements: [user_phone, manager_phone, manager_phone, user_phone], type: sequelize.QueryTypes.SELECT } + // 先查询是否已存在两条记录 + const [existingRecords] = await sequelize.query( + `SELECT user_phone, manager_phone FROM chat_list WHERE + (user_phone = ? AND manager_phone = ?) OR + (user_phone = ? AND manager_phone = ?)`, + { replacements: [user_phone, manager_phone, manager_phone, user_phone] } ); - const recordCount = existingRecords[0].count; + // 统计现有记录 + const hasRecord1 = existingRecords.some(record => + record.user_phone === user_phone && record.manager_phone === manager_phone + ); + const hasRecord2 = existingRecords.some(record => + record.user_phone === manager_phone && record.manager_phone === user_phone + ); - if (recordCount > 0) { - console.log('✅ 聊天记录已存在,无需重复添加'); - return res.status(200).json({ - success: true, - message: '聊天记录已存在' - }); - } + console.log('记录检查结果 - 记录1存在:', hasRecord1, '记录2存在:', hasRecord2); - // 插入两条记录: - // 1. 用户手机号 -> 业务员手机号 - await sequelize.query( - 'INSERT IGNORE INTO chat_list (user_phone, manager_phone) VALUES (?, ?)', - { replacements: [user_phone, manager_phone] } - ); + // 只插入不存在的记录 + let insertedCount = 0; + if (!hasRecord1) { + await sequelize.query( + 'INSERT INTO chat_list (user_phone, manager_phone) VALUES (?, ?)', + { replacements: [user_phone, manager_phone] } + ); + insertedCount++; + console.log('✅ 插入记录1成功: user_phone -> manager_phone'); + } else { + console.log('ℹ️ 记录1已存在: user_phone -> manager_phone'); + } - // 2. 业务员手机号 -> 用户手机号 - await sequelize.query( - 'INSERT IGNORE INTO chat_list (user_phone, manager_phone) VALUES (?, ?)', - { replacements: [manager_phone, user_phone] } - ); + if (!hasRecord2) { + await sequelize.query( + 'INSERT INTO chat_list (user_phone, manager_phone) VALUES (?, ?)', + { replacements: [manager_phone, user_phone] } + ); + insertedCount++; + console.log('✅ 插入记录2成功: manager_phone -> user_phone'); + } else { + console.log('ℹ️ 记录2已存在: manager_phone -> user_phone'); + } - console.log('✅ 成功插入两条聊天记录'); + console.log(`✅ 聊天记录处理完成,新插入 ${insertedCount} 条记录`); res.status(200).json({ success: true, diff --git a/utils/api.js b/utils/api.js index 1355c96..eaf073f 100644 --- a/utils/api.js +++ b/utils/api.js @@ -924,33 +924,96 @@ module.exports = { return this.uploadProductWithRecursiveImages(uploadData, imageUrls); }, - // 添加聊天记录 - 为用户和客服创建双向聊天记录 + // 添加聊天记录 - 为用户和客服创建双向聊天记录,避免重复创建 addChatRecord: function (user_phone, manager_phone) { console.log('API.addChatRecord - user_phone:', user_phone, 'manager_phone:', manager_phone); if (!user_phone || !manager_phone) { return Promise.reject(new Error('用户手机号和客服手机号不能为空')); } - return request('/api/chat/add', 'POST', { - user_phone: user_phone, - manager_phone: manager_phone - }).then(res => { - console.log('添加聊天记录服务器响应:', res); - if (res && (res.success || res.code === 200)) { - console.log('添加聊天记录成功'); - return res; - } else { - console.error('添加聊天记录失败,服务器返回:', res); - let errorMessage = res && res.message ? res.message : '添加聊天记录失败'; - return Promise.reject(new Error(errorMessage)); + // 1. 先获取用户的聊天列表,检查是否已经存在该聊天记录 + return this.getChatList(user_phone).then(chatList => { + console.log('获取到的聊天列表:', chatList); + + // 检查聊天列表中是否已经存在该聊天记录 + // 需要检查两种组合:user_phone <-> manager_phone 和 manager_phone <-> user_phone + const chatExists = Array.isArray(chatList) && chatList.some(chat => { + return (chat.user_phone === user_phone && chat.manager_phone === manager_phone) || + (chat.user_phone === manager_phone && chat.manager_phone === user_phone); + }); + + if (chatExists) { + console.log('聊天记录已存在,不需要重复创建'); + return { success: true, message: '聊天记录已存在' }; } + + // 2. 如果不存在,则调用服务器API创建聊天记录 + return request('/api/chat/add', 'POST', { + user_phone: user_phone, + manager_phone: manager_phone + }).then(res => { + console.log('添加聊天记录服务器响应:', res); + // 服务器返回200状态码或success=true都表示成功,包括"聊天记录已存在"的情况 + if (res && (res.success || res.code === 200)) { + console.log('添加聊天记录成功:', res.message || '聊天记录已创建'); + return res; + } else { + console.error('添加聊天记录失败,服务器返回:', res); + let errorMessage = res && res.message ? res.message : '添加聊天记录失败'; + return Promise.reject(new Error(errorMessage)); + } + }); }).catch(err => { console.error('添加聊天记录请求失败:', err); console.error('错误详情:', { message: err.message, statusCode: err.statusCode, responseData: err.responseData }); + + // 如果是获取聊天列表失败,尝试直接创建聊天记录(作为降级策略) + if (err.message.includes('获取聊天列表失败')) { + console.log('获取聊天列表失败,尝试直接创建聊天记录'); + return request('/api/chat/add', 'POST', { + user_phone: user_phone, + manager_phone: manager_phone + }).then(res => { + console.log('添加聊天记录服务器响应:', res); + if (res && (res.success || res.code === 200)) { + console.log('添加聊天记录成功:', res.message || '聊天记录已创建'); + return res; + } else { + console.error('添加聊天记录失败,服务器返回:', res); + let errorMessage = res && res.message ? res.message : '添加聊天记录失败'; + return Promise.reject(new Error(errorMessage)); + } + }).catch(directErr => { + console.error('直接创建聊天记录也失败:', directErr); + return Promise.reject(new Error('添加聊天记录失败,请稍后重试')); + }); + } + return Promise.reject(new Error('添加聊天记录失败,请稍后重试')); }); }, + // 修复函数:确保用户和客服之间的聊天记录是双向的(成双成对) + fixChatRecordsPair: function (user_phone, manager_phone) { + console.log('API.fixChatRecordsPair - 用户手机号:', user_phone, '客服手机号:', manager_phone); + if (!user_phone || !manager_phone) { + return Promise.reject(new Error('用户手机号和客服手机号不能为空')); + } + + // 注意:服务器端的/api/chat/add接口已经在内部处理了双向记录的创建 + // 它会自动插入两条记录:用户->客服和客服->用户,所以只需要调用一次 + return this.addChatRecord(user_phone, manager_phone) + .then(res => { + console.log('✓ 服务器已处理聊天记录创建:', res.message); + console.log('🎉 聊天记录修复完成,用户和客服之间已建立双向聊天记录'); + return { success: true, message: '聊天记录修复完成,已建立双向聊天记录' }; + }) + .catch(err => { + console.error('修复聊天记录失败:', err.message); + return { success: false, message: '聊天记录修复失败:' + err.message }; + }); + }, + // 上传带图片的商品 - 改进版,确保所有图片都被实际上传到服务器 uploadProductWithImages: function (productData, imageUrls) { console.log('===== 开始上传带图片的商品 =====');