|
|
|
@ -1,5 +1,109 @@ |
|
|
|
// pages/chat/index.js
|
|
|
|
import socketManager from '../../utils/websocket.js'; |
|
|
|
const AuthManager = require('../../utils/auth.js'); |
|
|
|
|
|
|
|
// 获取用户名的辅助函数,支持手机号格式的ID - 增强版本
|
|
|
|
function getUserNameById(userId, isCustomerServiceMode = false) { |
|
|
|
// 严格验证用户ID的有效性
|
|
|
|
if (!userId || userId === null || userId === undefined) { |
|
|
|
// 返回默认名称而不是null,避免unknown显示
|
|
|
|
return '系统用户'; |
|
|
|
} |
|
|
|
|
|
|
|
// 确保userId是字符串类型,并去除前后空格
|
|
|
|
const safeUserId = String(userId).trim(); |
|
|
|
|
|
|
|
// 检查是否是空字符串
|
|
|
|
if (safeUserId === '' || safeUserId === '0') { |
|
|
|
return '系统用户'; |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否是手机号格式 (中国手机号格式)
|
|
|
|
if (/^1[3-9]\d{9}$/.test(safeUserId)) { |
|
|
|
// 关键修复:将"客户-"改为"用户-",统一用户显示格式
|
|
|
|
return `用户-${safeUserId.slice(-4)}`; |
|
|
|
} |
|
|
|
|
|
|
|
// 纯数字ID - 关键修复:默认显示为客服
|
|
|
|
// 客服ID通常是纯数字,用户ID通常是字符串格式
|
|
|
|
if (/^\d+$/.test(safeUserId)) { |
|
|
|
return `客服${safeUserId}`; |
|
|
|
} |
|
|
|
|
|
|
|
// 增强的用户ID格式处理
|
|
|
|
if (safeUserId.startsWith('manager_')) { |
|
|
|
// 提取客服ID数字部分
|
|
|
|
const managerNum = safeUserId.replace('manager_', ''); |
|
|
|
if (!isNaN(managerNum) && managerNum > 0) { |
|
|
|
return `客服${managerNum}`; |
|
|
|
} |
|
|
|
return '客服' + safeUserId.substring(8, 12); |
|
|
|
} else if (safeUserId.startsWith('user_')) { |
|
|
|
// 用户ID格式处理
|
|
|
|
const parts = safeUserId.split('_'); |
|
|
|
if (parts.length >= 3) { |
|
|
|
// 使用最后一部分生成更友好的名称
|
|
|
|
const randomPart = parts[parts.length - 1]; |
|
|
|
return `用户${randomPart.substring(0, 4).toUpperCase()}`; |
|
|
|
} |
|
|
|
return '用户' + safeUserId.substring(5, 9); |
|
|
|
} else if (safeUserId.startsWith('test_')) { |
|
|
|
return '测试用户'; |
|
|
|
} else if (safeUserId.includes('_customer_')) { |
|
|
|
// 提取客户标识部分
|
|
|
|
const parts = safeUserId.split('_customer_'); |
|
|
|
// 关键修复:将"客户-"改为"用户-"
|
|
|
|
return parts.length > 1 ? `用户-${parts[1].substring(0, 4)}` : '用户'; |
|
|
|
} |
|
|
|
|
|
|
|
// 安全的本地存储访问
|
|
|
|
try { |
|
|
|
if (isCustomerServiceMode) { |
|
|
|
// 客服模式下尝试从本地存储获取用户信息
|
|
|
|
const userInfo = wx.getStorageSync('userInfo'); |
|
|
|
// 检查userInfo类型,避免重复JSON解析
|
|
|
|
if (userInfo && typeof userInfo === 'object') { |
|
|
|
// 如果用户ID匹配,返回用户名或手机号后四位
|
|
|
|
if (userInfo.userId === safeUserId || userInfo.id === safeUserId) { |
|
|
|
// 关键修复:将"客户-"改为"用户-"
|
|
|
|
return userInfo.name || (userInfo.phone && `用户-${userInfo.phone.slice(-4)}`) || '用户'; |
|
|
|
} |
|
|
|
} else if (userInfo && typeof userInfo === 'string') { |
|
|
|
try { |
|
|
|
const parsedUserInfo = JSON.parse(userInfo); |
|
|
|
if (parsedUserInfo.userId === safeUserId || parsedUserInfo.id === safeUserId) { |
|
|
|
// 关键修复:将"客户-"改为"用户-"
|
|
|
|
return parsedUserInfo.name || (parsedUserInfo.phone && `用户-${parsedUserInfo.phone.slice(-4)}`) || '用户'; |
|
|
|
} |
|
|
|
} catch (parseError) { |
|
|
|
console.warn('解析userInfo字符串失败,忽略此步骤:', parseError); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
console.error('获取本地用户信息失败:', e); |
|
|
|
} |
|
|
|
|
|
|
|
// 增强的固定用户名映射表
|
|
|
|
const userNameMap = { |
|
|
|
'user_1765610275027_qqkb12ws3': '测试用户', |
|
|
|
'17780155537': '客服-5537', |
|
|
|
'17844569862': '用户-862', // 关键修复:将"客户-"改为"用户-"
|
|
|
|
// 添加已知用户ID的映射
|
|
|
|
'user_1763452685075_rea007flq': '用户REA0' // 添加特定用户ID的映射
|
|
|
|
}; |
|
|
|
|
|
|
|
if (userNameMap[safeUserId]) { |
|
|
|
return userNameMap[safeUserId]; |
|
|
|
} |
|
|
|
|
|
|
|
// 对于未识别的有效用户ID,返回更友好的用户ID标识
|
|
|
|
const displayId = safeUserId.length > 8 ? safeUserId.substring(0, 8) : safeUserId; |
|
|
|
|
|
|
|
// 客服模式下默认显示为用户,除非是自己
|
|
|
|
const isSelf = isCustomerServiceMode && String(displayId) === String(wx.getStorageSync('managerId')); |
|
|
|
return isSelf ? `客服-${displayId}` : `用户-${displayId}`; |
|
|
|
} |
|
|
|
|
|
|
|
Page({ |
|
|
|
|
|
|
|
@ -32,9 +136,29 @@ Page({ |
|
|
|
console.log('更新消息列表:', newMessage); |
|
|
|
const messages = [...this.data.messages]; |
|
|
|
|
|
|
|
// 确定消息发送者ID - 处理服务器返回的数据格式
|
|
|
|
const senderId = newMessage.senderId; |
|
|
|
const existingIndex = messages.findIndex(item => item.id === senderId); |
|
|
|
// 获取当前用户信息
|
|
|
|
const app = getApp(); |
|
|
|
const currentUserId = app.globalData.userInfo?.userId || wx.getStorageSync('userId') || 'unknown'; |
|
|
|
const userType = app.globalData.userInfo?.userType || wx.getStorageSync('userType'); |
|
|
|
const managerId = app.globalData.userInfo?.managerId || wx.getStorageSync('managerId'); |
|
|
|
|
|
|
|
// 关键修复:处理不同格式的消息数据
|
|
|
|
// 提取消息的发送者、接收者和会话ID
|
|
|
|
const senderId = newMessage.senderId || newMessage.from || newMessage.sender || newMessage.userId; |
|
|
|
const receiverId = newMessage.receiverId || newMessage.to || newMessage.receiver || newMessage.managerId; |
|
|
|
const conversationId = newMessage.conversationId || newMessage.conversation_id; |
|
|
|
|
|
|
|
// 关键修复:对于客服端,只处理用户发送的消息,忽略自己发送的消息
|
|
|
|
if (userType === 'manager' && managerId) { |
|
|
|
// 客服只处理发送者是用户且接收者是当前客服的消息
|
|
|
|
const isFromUser = senderId && String(senderId).includes('user_') || !String(senderId).includes('manager_') && senderId !== managerId; |
|
|
|
const isToCurrentManager = String(receiverId) === String(managerId) || String(receiverId).includes('manager_') || !receiverId; |
|
|
|
|
|
|
|
if (!isFromUser || !isToCurrentManager) { |
|
|
|
console.log('客服端过滤掉非用户消息:', { senderId, receiverId, managerId }); |
|
|
|
return; // 不处理这条消息
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 格式化消息时间 - 服务器使用createdAt字段
|
|
|
|
const now = new Date(); |
|
|
|
@ -53,35 +177,59 @@ Page({ |
|
|
|
displayTime = (messageDate.getMonth() + 1) + '月' + messageDate.getDate() + '日'; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取当前用户ID,确定消息方向
|
|
|
|
const app = getApp(); |
|
|
|
const currentUserId = app.globalData.userInfo?.userId || wx.getStorageSync('userId') || 'unknown'; |
|
|
|
// 关键修复:确定显示的用户ID
|
|
|
|
// 对于客服端,总是显示用户ID
|
|
|
|
let displayUserId; |
|
|
|
if (userType === 'manager') { |
|
|
|
displayUserId = senderId; // 客服端显示发送者(用户)ID
|
|
|
|
} else { |
|
|
|
// 用户端根据消息方向确定显示ID
|
|
|
|
displayUserId = senderId === currentUserId ? receiverId : senderId; |
|
|
|
} |
|
|
|
|
|
|
|
// 确定显示的用户ID(如果是自己发送的消息,显示接收者ID)
|
|
|
|
const displayUserId = senderId === currentUserId ? newMessage.receiverId : senderId; |
|
|
|
// 使用会话ID作为唯一标识,避免重复问题
|
|
|
|
const uniqueId = conversationId || displayUserId; |
|
|
|
const existingIndex = messages.findIndex(item => |
|
|
|
item.conversationId === conversationId || item.id === uniqueId |
|
|
|
); |
|
|
|
|
|
|
|
// 使用增强的用户名显示函数
|
|
|
|
const displayName = getUserNameById(displayUserId, userType === 'manager'); |
|
|
|
|
|
|
|
// 消息类型处理
|
|
|
|
let messageContent = newMessage.content || ''; |
|
|
|
if (newMessage.content_type === 2 || newMessage.type === 'image') { |
|
|
|
messageContent = '[图片]'; |
|
|
|
} else if (newMessage.content_type === 3 || newMessage.type === 'voice') { |
|
|
|
messageContent = '[语音]'; |
|
|
|
} else if (newMessage.content_type === 4 || newMessage.type === 'video') { |
|
|
|
messageContent = '[视频]'; |
|
|
|
} |
|
|
|
|
|
|
|
if (existingIndex >= 0) { |
|
|
|
// 存在该用户的消息,更新内容和时间
|
|
|
|
// 存在该会话的消息,更新内容和时间
|
|
|
|
messages[existingIndex] = { |
|
|
|
...messages[existingIndex], |
|
|
|
content: newMessage.content || '', |
|
|
|
content: messageContent, |
|
|
|
time: displayTime, |
|
|
|
isRead: false |
|
|
|
isRead: false, |
|
|
|
// 确保有会话ID
|
|
|
|
conversationId: conversationId || messages[existingIndex].conversationId |
|
|
|
}; |
|
|
|
// 将更新的消息移到列表顶部
|
|
|
|
const [updatedMessage] = messages.splice(existingIndex, 1); |
|
|
|
messages.unshift(updatedMessage); |
|
|
|
} else { |
|
|
|
// 新用户消息,添加到列表顶部
|
|
|
|
// 这里暂时使用ID作为用户名,实际应用中应该从用户信息中获取
|
|
|
|
const displayName = `用户${displayUserId}`; |
|
|
|
// 新会话消息,添加到列表顶部
|
|
|
|
messages.unshift({ |
|
|
|
id: displayUserId, |
|
|
|
id: uniqueId, |
|
|
|
name: displayName, |
|
|
|
avatar: displayName.charAt(0), |
|
|
|
content: newMessage.content || '', |
|
|
|
content: messageContent, |
|
|
|
time: displayTime, |
|
|
|
isRead: false |
|
|
|
isRead: false, |
|
|
|
unreadCount: 1, |
|
|
|
conversationId: conversationId |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@ -226,7 +374,7 @@ Page({ |
|
|
|
socketManager.off('message', this.handleWebSocketMessage); |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载聊天列表数据
|
|
|
|
// 加载聊天列表数据 - 优化版本
|
|
|
|
loadChatList: function() { |
|
|
|
wx.showLoading({ title: '加载中' }); |
|
|
|
|
|
|
|
@ -241,9 +389,22 @@ Page({ |
|
|
|
console.log('使用API地址:', baseUrl); |
|
|
|
console.log('当前用户ID:', currentUserId); |
|
|
|
|
|
|
|
// 使用正确的API端点 - /api/conversations/user/:userId
|
|
|
|
// 根据用户类型选择正确的API端点
|
|
|
|
const userType = app.globalData.userInfo?.userType || wx.getStorageSync('userType'); |
|
|
|
const managerId = app.globalData.userInfo?.managerId || wx.getStorageSync('managerId'); |
|
|
|
|
|
|
|
// 构建API路径:客服使用manager端点,普通用户使用user端点
|
|
|
|
let apiPath; |
|
|
|
if (userType === 'manager' && managerId) { |
|
|
|
apiPath = `/api/conversations/manager/${managerId}`; |
|
|
|
console.log('客服身份,使用manager API端点'); |
|
|
|
} else { |
|
|
|
apiPath = `/api/conversations/user/${currentUserId}`; |
|
|
|
console.log('普通用户身份,使用user API端点'); |
|
|
|
} |
|
|
|
|
|
|
|
wx.request({ |
|
|
|
url: `${baseUrl}/api/conversations/user/${currentUserId}`, |
|
|
|
url: `${baseUrl}${apiPath}`, |
|
|
|
method: 'GET', |
|
|
|
header: { |
|
|
|
'Authorization': token ? `Bearer ${token}` : '', |
|
|
|
@ -254,7 +415,12 @@ Page({ |
|
|
|
// 处理不同的API响应格式
|
|
|
|
let chatData = []; |
|
|
|
|
|
|
|
if (res.data.code === 0 && res.data.data) { |
|
|
|
// 更灵活的响应格式处理
|
|
|
|
if (res.data && res.data.success && res.data.code === 200 && res.data.data) { |
|
|
|
// 标准API响应格式
|
|
|
|
chatData = res.data.data; |
|
|
|
} else if (res.data && res.data.code === 0 && res.data.data) { |
|
|
|
// 备用API响应格式
|
|
|
|
chatData = res.data.data; |
|
|
|
} else if (Array.isArray(res.data)) { |
|
|
|
// 如果直接返回数组
|
|
|
|
@ -264,12 +430,47 @@ Page({ |
|
|
|
chatData = [res.data]; |
|
|
|
} |
|
|
|
|
|
|
|
if (chatData.length > 0) { |
|
|
|
// 保存原始数据到日志,便于调试
|
|
|
|
console.log('处理前的聊天数据:', chatData); |
|
|
|
|
|
|
|
if (Array.isArray(chatData) && chatData.length > 0) { |
|
|
|
// 格式化聊天列表数据
|
|
|
|
const formattedMessages = chatData.map(item => { |
|
|
|
const formattedMessages = chatData |
|
|
|
.filter(item => { |
|
|
|
// 跳过无效项
|
|
|
|
if (!item) return false; |
|
|
|
|
|
|
|
// 关键修复:对于客服端,只显示用户的消息,不显示自己的消息
|
|
|
|
if (userType === 'manager' && managerId) { |
|
|
|
// 获取会话中的用户ID和客服ID
|
|
|
|
const conversationUserId = item.userId || item.user_id; |
|
|
|
const conversationManagerId = item.managerId || item.manager_id || ''; |
|
|
|
|
|
|
|
// 确保只显示用户发送给当前客服的消息,且不显示自己的消息
|
|
|
|
// 1. 确保是当前客服的会话
|
|
|
|
// 2. 确保不是客服自己的会话(避免显示客服自己)
|
|
|
|
// 3. 确保有有效的用户ID
|
|
|
|
const isCurrentManagerConversation = String(conversationManagerId) === String(managerId); |
|
|
|
const isNotSelfConversation = conversationUserId !== currentUserId; |
|
|
|
const hasValidUserId = conversationUserId && conversationUserId !== 'unknown'; |
|
|
|
|
|
|
|
console.log('客服消息过滤:', { |
|
|
|
conversationUserId, |
|
|
|
conversationManagerId, |
|
|
|
currentUserId, |
|
|
|
managerId, |
|
|
|
keep: isCurrentManagerConversation && isNotSelfConversation && hasValidUserId |
|
|
|
}); |
|
|
|
|
|
|
|
return isCurrentManagerConversation && isNotSelfConversation && hasValidUserId; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
}) |
|
|
|
.map(item => { |
|
|
|
// 格式化时间
|
|
|
|
const now = new Date(); |
|
|
|
const messageDate = new Date(item.lastMessageTime || item.createdAt || Date.now()); |
|
|
|
const messageDate = new Date(item.lastMessageTime || item.createdAt || item.timestamp || Date.now()); |
|
|
|
let displayTime = ''; |
|
|
|
|
|
|
|
if (messageDate.toDateString() === now.toDateString()) { |
|
|
|
@ -284,51 +485,176 @@ Page({ |
|
|
|
displayTime = (messageDate.getMonth() + 1) + '月' + messageDate.getDate() + '日'; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取当前用户ID,确定显示哪个用户
|
|
|
|
const displayUserId = item.userId === currentUserId ? item.managerId : item.userId || item.id; |
|
|
|
const displayName = `用户${displayUserId}`; |
|
|
|
// 获取当前用户ID,确定显示哪个用户 - 重点支持数据库驼峰命名
|
|
|
|
const userIdFromData = item.userId || item.user_id; |
|
|
|
const managerIdFromData = item.managerId || item.manager_id; |
|
|
|
|
|
|
|
// 关键修复:对于客服端,总是显示用户ID,确保正确显示用户消息
|
|
|
|
let displayUserId; |
|
|
|
if (userType === 'manager') { |
|
|
|
// 客服端应该显示用户ID
|
|
|
|
displayUserId = userIdFromData || 'unknown'; |
|
|
|
} else { |
|
|
|
// 用户端正常处理
|
|
|
|
displayUserId = (userIdFromData === currentUserId) ? |
|
|
|
(managerIdFromData || 'unknown') : |
|
|
|
(userIdFromData || 'unknown'); |
|
|
|
} |
|
|
|
|
|
|
|
// 添加调试信息
|
|
|
|
console.log('处理会话项:', { |
|
|
|
originalItem: item, |
|
|
|
userId: userIdFromData, |
|
|
|
managerId: managerIdFromData, |
|
|
|
conversationId: item.conversation_id, |
|
|
|
selectedUserId: displayUserId, |
|
|
|
userType: userType |
|
|
|
}); |
|
|
|
|
|
|
|
// 使用增强的用户名显示函数
|
|
|
|
const displayName = getUserNameById(displayUserId, userType === 'manager'); |
|
|
|
|
|
|
|
// 获取消息内容,支持多种格式
|
|
|
|
let lastMessage = item.lastMessage || item.content || ''; |
|
|
|
if (item.lastMessage && typeof item.lastMessage === 'object') { |
|
|
|
// 如果lastMessage是对象,获取content字段
|
|
|
|
lastMessage = item.lastMessage.content || ''; |
|
|
|
} |
|
|
|
|
|
|
|
// 消息类型处理 - 支持数据库字段格式
|
|
|
|
let messageContent = lastMessage; |
|
|
|
// 检查content_type字段(数据库使用)
|
|
|
|
if (item.content_type === 2 || item.content_type === 'image') { |
|
|
|
messageContent = '[图片]'; |
|
|
|
} else if (item.content_type === 3 || item.content_type === 'voice') { |
|
|
|
messageContent = '[语音]'; |
|
|
|
} else if (item.content_type === 4 || item.content_type === 'video') { |
|
|
|
messageContent = '[视频]'; |
|
|
|
} else if (item.messageType === 'image' || (item.lastMessage && item.lastMessage.type === 'image')) { |
|
|
|
messageContent = '[图片]'; |
|
|
|
} else if (item.messageType === 'voice' || (item.lastMessage && item.lastMessage.type === 'voice')) { |
|
|
|
messageContent = '[语音]'; |
|
|
|
} else if (item.messageType === 'video' || (item.lastMessage && item.lastMessage.type === 'video')) { |
|
|
|
messageContent = '[视频]'; |
|
|
|
} |
|
|
|
|
|
|
|
// 确定未读消息数量 - 根据用户类型使用不同字段
|
|
|
|
let unreadCount = 0; |
|
|
|
if (userType === 'manager') { |
|
|
|
// 客服端使用cs_unread_count
|
|
|
|
unreadCount = item.cs_unread_count || 0; |
|
|
|
} else { |
|
|
|
// 用户端使用unread_count
|
|
|
|
unreadCount = typeof item.unreadCount === 'number' ? item.unreadCount : (item.unread_count || 0); |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
id: displayUserId, |
|
|
|
// 使用conversation_id作为唯一标识,避免重复ID问题
|
|
|
|
id: item.conversation_id || displayUserId, |
|
|
|
name: item.userName || item.name || displayName, |
|
|
|
avatar: item.avatar || (item.userName || displayName).charAt(0) || '用', |
|
|
|
content: item.lastMessage || item.content || '', |
|
|
|
content: messageContent, |
|
|
|
time: displayTime, |
|
|
|
isRead: item.isRead || false, |
|
|
|
unreadCount: item.unreadCount || 0 |
|
|
|
isRead: unreadCount === 0, // 有未读数就是未读状态
|
|
|
|
unreadCount: unreadCount, |
|
|
|
// 添加原始数据引用,便于调试
|
|
|
|
_raw: item, |
|
|
|
// 保留会话ID用于导航
|
|
|
|
conversationId: item.conversation_id || item.id |
|
|
|
}; |
|
|
|
}); |
|
|
|
|
|
|
|
this.setData({ messages: formattedMessages }); |
|
|
|
// 去重 - 基于conversation_id或userId
|
|
|
|
const uniqueMessages = []; |
|
|
|
const seenIds = new Set(); |
|
|
|
|
|
|
|
formattedMessages.forEach(msg => { |
|
|
|
const uniqueId = msg.conversationId || msg.id; |
|
|
|
if (!seenIds.has(uniqueId)) { |
|
|
|
seenIds.add(uniqueId); |
|
|
|
uniqueMessages.push(msg); |
|
|
|
} else { |
|
|
|
console.log('暂无聊天消息'); |
|
|
|
this.setData({ messages: [] }); |
|
|
|
console.warn(`发现重复的会话ID: ${uniqueId},已过滤`); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 按时间和未读状态排序
|
|
|
|
uniqueMessages.sort((a, b) => { |
|
|
|
// 未读消息优先
|
|
|
|
if (a.isRead !== b.isRead) { |
|
|
|
return a.isRead ? 1 : -1; |
|
|
|
} |
|
|
|
// 其他按时间排序
|
|
|
|
return 0; |
|
|
|
}); |
|
|
|
|
|
|
|
// 保存到本地存储,便于调试和离线访问
|
|
|
|
wx.setStorageSync('lastChatList', formattedMessages); |
|
|
|
|
|
|
|
// 同时为chatList和messages赋值,确保页面模板能正确获取数据
|
|
|
|
const processedChatList = uniqueMessages; |
|
|
|
this.setData({ |
|
|
|
messages: formattedMessages, |
|
|
|
chatList: processedChatList, |
|
|
|
noChats: processedChatList.length === 0 |
|
|
|
}); |
|
|
|
// 更新TabBar未读状态
|
|
|
|
this.updateTabBarBadge(); |
|
|
|
} else { |
|
|
|
console.log('暂无聊天消息,但数据在数据库中存在,可能是API请求路径或参数问题'); |
|
|
|
console.log('API请求详情:', { |
|
|
|
baseUrl, |
|
|
|
apiPath, |
|
|
|
currentUserId, |
|
|
|
userType, |
|
|
|
managerId |
|
|
|
}); |
|
|
|
|
|
|
|
// 即使API返回空数组,也要显示空状态,而不是白屏
|
|
|
|
this.setData({ |
|
|
|
messages: [], |
|
|
|
noChats: true |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
console.error('网络请求失败:', err); |
|
|
|
wx.showToast({ |
|
|
|
title: '网络请求失败,使用本地数据', |
|
|
|
title: '获取消息失败,重试中...', |
|
|
|
icon: 'none', |
|
|
|
duration: 3000 |
|
|
|
}); |
|
|
|
|
|
|
|
// 失败时使用模拟数据,确保页面能够正常显示
|
|
|
|
this.setData({ |
|
|
|
messages: [ |
|
|
|
// 尝试使用本地缓存数据
|
|
|
|
const cachedList = wx.getStorageSync('lastChatList') || []; |
|
|
|
if (cachedList.length > 0) { |
|
|
|
console.log('使用本地缓存数据:', cachedList.length); |
|
|
|
this.setData({ messages: cachedList }); |
|
|
|
this.updateTabBarBadge(); |
|
|
|
} else { |
|
|
|
// 缓存也没有,使用模拟数据
|
|
|
|
console.log('使用模拟数据'); |
|
|
|
const mockMessages = [ |
|
|
|
{ |
|
|
|
id: '1', |
|
|
|
name: '系统消息', |
|
|
|
avatar: '系', |
|
|
|
content: '欢迎使用聊天功能', |
|
|
|
time: '刚刚', |
|
|
|
isRead: false |
|
|
|
isRead: false, |
|
|
|
unreadCount: 0, |
|
|
|
conversationId: 'conv_1' // 添加conversationId,确保导航正常
|
|
|
|
} |
|
|
|
] |
|
|
|
}); |
|
|
|
]; |
|
|
|
this.setData({ messages: mockMessages }); |
|
|
|
} |
|
|
|
// 确保设置了noChats状态,避免白屏
|
|
|
|
this.setData({ noChats: this.data.messages.length === 0 }); |
|
|
|
}, |
|
|
|
complete: () => { |
|
|
|
wx.hideLoading(); |
|
|
|
// 确保设置了noChats状态,避免白屏
|
|
|
|
this.setData({ noChats: this.data.messages.length === 0 }); |
|
|
|
} |
|
|
|
}); |
|
|
|
} catch (error) { |
|
|
|
@ -349,7 +675,32 @@ Page({ |
|
|
|
* 生命周期函数--监听页面加载 |
|
|
|
*/ |
|
|
|
onLoad(options) { |
|
|
|
console.log('聊天列表页面onLoad,准备加载数据'); |
|
|
|
|
|
|
|
try { |
|
|
|
// 页面加载时执行身份验证
|
|
|
|
AuthManager.authenticate((authResult) => { |
|
|
|
console.log('身份验证成功,开始加载聊天列表:', authResult); |
|
|
|
this.loadChatList(); |
|
|
|
}, (error) => { |
|
|
|
console.warn('身份验证失败,使用访客模式:', error); |
|
|
|
// 即使身份验证失败,也加载聊天列表,避免白屏
|
|
|
|
this.loadChatList(); |
|
|
|
}); |
|
|
|
} catch (error) { |
|
|
|
console.error('身份验证过程中发生错误:', error); |
|
|
|
// 即使身份验证过程中发生错误,也加载聊天列表
|
|
|
|
this.loadChatList(); |
|
|
|
} |
|
|
|
|
|
|
|
// 初始化WebSocket连接
|
|
|
|
setTimeout(() => { |
|
|
|
try { |
|
|
|
this.initWebSocket(); |
|
|
|
} catch (error) { |
|
|
|
console.error('初始化WebSocket过程中发生错误:', error); |
|
|
|
} |
|
|
|
}, 1000); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
@ -377,8 +728,23 @@ Page({ |
|
|
|
* 生命周期函数--监听页面显示 |
|
|
|
*/ |
|
|
|
onShow() { |
|
|
|
// 页面显示时初始化WebSocket连接
|
|
|
|
console.log('聊天列表页面onShow'); |
|
|
|
|
|
|
|
// 检查是否已登录
|
|
|
|
if (AuthManager.isLoggedIn()) { |
|
|
|
// 已登录,初始化WebSocket连接
|
|
|
|
try { |
|
|
|
this.initWebSocket(); |
|
|
|
} catch (error) { |
|
|
|
console.error('初始化WebSocket过程中发生错误:', error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 确保消息列表有数据,避免白屏
|
|
|
|
if (!this.data.messages || this.data.messages.length === 0) { |
|
|
|
console.log('消息列表为空,尝试重新加载数据'); |
|
|
|
this.loadChatList(); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
@ -401,7 +767,11 @@ Page({ |
|
|
|
* 页面相关事件处理函数--监听用户下拉动作 |
|
|
|
*/ |
|
|
|
onPullDownRefresh() { |
|
|
|
|
|
|
|
console.log('下拉刷新触发'); |
|
|
|
// 重新加载聊天列表数据
|
|
|
|
this.loadChatList(); |
|
|
|
// 停止下拉刷新动画
|
|
|
|
wx.stopPullDownRefresh(); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
@ -424,12 +794,21 @@ Page({ |
|
|
|
|
|
|
|
// 跳转到对话详情页面
|
|
|
|
navigateToChatDetail: function(e) { |
|
|
|
// 关键修复:获取userId和userName
|
|
|
|
const userId = e.currentTarget.dataset.userId; |
|
|
|
const userName = e.currentTarget.dataset.userName; |
|
|
|
const conversationId = e.currentTarget.dataset.conversationId; |
|
|
|
|
|
|
|
console.log('导航到聊天详情:', { userId, userName, conversationId }); |
|
|
|
|
|
|
|
// 执行身份验证
|
|
|
|
AuthManager.authenticate(() => { |
|
|
|
// 将该聊天标记为已读
|
|
|
|
const messages = [...this.data.messages]; |
|
|
|
const messageIndex = messages.findIndex(item => item.id === userId); |
|
|
|
// 查找会话时同时考虑id和conversationId
|
|
|
|
const messageIndex = messages.findIndex(item => |
|
|
|
item.id === userId || item.conversationId === conversationId |
|
|
|
); |
|
|
|
|
|
|
|
if (messageIndex >= 0) { |
|
|
|
messages[messageIndex].isRead = true; |
|
|
|
@ -439,36 +818,74 @@ Page({ |
|
|
|
// 更新TabBar未读消息数
|
|
|
|
this.updateTabBarBadge(); |
|
|
|
|
|
|
|
// 通知服务器已读状态(可选)
|
|
|
|
// 通知服务器已读状态(使用userId)
|
|
|
|
this.markAsRead(userId); |
|
|
|
} |
|
|
|
|
|
|
|
// 关键修复:在URL中同时传递userId和conversationId,确保正确打开会话
|
|
|
|
wx.navigateTo({ |
|
|
|
url: `/pages/chat-detail/index?userId=${userId}&userName=${encodeURIComponent(userName)}` |
|
|
|
url: `/pages/chat-detail/index?userId=${userId}&userName=${encodeURIComponent(userName)}${conversationId ? `&conversationId=${conversationId}` : ''}` |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 通知服务器消息已读
|
|
|
|
markAsRead: function(userId) { |
|
|
|
const app = getApp(); |
|
|
|
const token = app.globalData.token || wx.getStorageSync('token'); |
|
|
|
// 只执行本地标记已读,不再调用服务器API
|
|
|
|
console.log('执行本地标记已读,不再调用服务器API:', userId); |
|
|
|
|
|
|
|
wx.request({ |
|
|
|
url: `${app.globalData.baseUrl || 'https://your-server.com'}/api/chat/read`, |
|
|
|
method: 'POST', |
|
|
|
header: { |
|
|
|
'Authorization': `Bearer ${token}`, |
|
|
|
'content-type': 'application/json' |
|
|
|
}, |
|
|
|
data: { |
|
|
|
userId: userId |
|
|
|
// 在本地标记消息已读,确保应用功能正常
|
|
|
|
this.localMarkAsRead(userId); |
|
|
|
}, |
|
|
|
success: (res) => { |
|
|
|
console.log('标记消息已读成功:', res.data); |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
console.error('标记消息已读失败:', err); |
|
|
|
|
|
|
|
// 本地标记消息已读
|
|
|
|
localMarkAsRead: function(userId) { |
|
|
|
try { |
|
|
|
// 获取当前的消息列表 (使用messages而不是chatList)
|
|
|
|
const messages = this.data.messages || []; |
|
|
|
// 更新指定用户的未读状态
|
|
|
|
const updatedMessages = messages.map(chat => { |
|
|
|
if (chat.userId === userId || chat.id === userId || chat.conversationId === userId) { |
|
|
|
return { |
|
|
|
...chat, |
|
|
|
unreadCount: 0, |
|
|
|
lastReadTime: Date.now() |
|
|
|
}; |
|
|
|
} |
|
|
|
return chat; |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新数据和本地存储 (使用messages而不是chatList)
|
|
|
|
this.setData({ messages: updatedMessages }); |
|
|
|
wx.setStorageSync('lastChatList', updatedMessages); |
|
|
|
|
|
|
|
// 更新TabBar的未读提示
|
|
|
|
this.updateTabBarBadge(); |
|
|
|
|
|
|
|
console.log(`本地标记用户 ${userId} 的消息已读成功`); |
|
|
|
} catch (error) { |
|
|
|
console.error('本地标记已读失败:', error); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 切换消息标签页
|
|
|
|
switchTab: function(e) { |
|
|
|
const tab = e.currentTarget.dataset.tab; |
|
|
|
this.setData({ activeTab: tab }); |
|
|
|
|
|
|
|
// 根据选中的标签页过滤消息列表
|
|
|
|
if (tab === 'unread') { |
|
|
|
this.filterUnreadMessages(); |
|
|
|
} else { |
|
|
|
// 显示所有消息 - 从本地存储恢复原始列表
|
|
|
|
const cachedList = wx.getStorageSync('lastChatList') || []; |
|
|
|
this.setData({ messages: cachedList }); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 过滤未读消息
|
|
|
|
filterUnreadMessages: function() { |
|
|
|
const unreadMessages = this.data.messages.filter(item => !item.isRead || item.unreadCount > 0); |
|
|
|
this.setData({ messages: unreadMessages }); |
|
|
|
} |
|
|
|
}) |