// 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({ /** * 页面的初始数据 */ data: { messages: [], // 初始为空数组,后续通过数据获取和WebSocket更新 activeTab: 'all', webSocketUrl: '' // WebSocket服务器地址 }, // WebSocket消息处理函数 handleWebSocketMessage: function(message) { console.log('聊天列表页面接收到消息:', message); // 判断是否为新消息 - 支持'new_message'类型(服务器实际发送的类型) if (message.type === 'new_message') { const newMessage = message.payload; this.updateMessageList(newMessage); } else if (message.type === 'chat_message') { // 保留原有的'chat_message'类型支持,兼容不同的消息格式 const newMessage = message.data; this.updateMessageList(newMessage); } }, // 更新消息列表 updateMessageList: function(newMessage) { console.log('更新消息列表:', newMessage); const messages = [...this.data.messages]; // 获取当前用户信息 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(); const messageDate = new Date(newMessage.createdAt || newMessage.timestamp || Date.now()); let displayTime = ''; if (messageDate.toDateString() === now.toDateString()) { // 今天的消息只显示时间 displayTime = messageDate.getHours().toString().padStart(2, '0') + ':' + messageDate.getMinutes().toString().padStart(2, '0'); } else if (messageDate.toDateString() === new Date(now.getTime() - 86400000).toDateString()) { // 昨天的消息 displayTime = '昨天'; } else { // 其他日期显示月日 displayTime = (messageDate.getMonth() + 1) + '月' + messageDate.getDate() + '日'; } // 关键修复:确定显示的用户ID // 对于客服端,总是显示用户ID let displayUserId; if (userType === 'manager') { displayUserId = senderId; // 客服端显示发送者(用户)ID } else { // 用户端根据消息方向确定显示ID displayUserId = senderId === currentUserId ? 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: messageContent, time: displayTime, isRead: false, // 确保有会话ID conversationId: conversationId || messages[existingIndex].conversationId }; // 将更新的消息移到列表顶部 const [updatedMessage] = messages.splice(existingIndex, 1); messages.unshift(updatedMessage); } else { // 新会话消息,添加到列表顶部 messages.unshift({ id: uniqueId, name: displayName, avatar: displayName.charAt(0), content: messageContent, time: displayTime, isRead: false, unreadCount: 1, conversationId: conversationId }); } // 使用setData更新视图 this.setData({ messages }); // 触发消息提示振动(可选) wx.vibrateShort(); // 更新TabBar未读消息数(如果需要) this.updateTabBarBadge(); }, // 更新TabBar未读消息提示 - 使用自定义TabBar兼容方式 updateTabBarBadge: function() { console.log('更新TabBar未读提示,当前消息数:', this.data.messages.length); // 检查是否有未读消息 const hasUnread = this.data.messages.some(msg => !msg.isRead); console.log('是否有未读消息:', hasUnread); // 对于自定义TabBar,使用全局状态来管理未读标记 const app = getApp(); if (app && app.globalData) { app.globalData.tabBarBadge = { chat: hasUnread ? ' ' : '' }; console.log('已更新全局TabBar未读标记状态:', hasUnread ? '显示' : '隐藏'); // 尝试通过getTabBar方法通知自定义TabBar更新 try { const tabBar = this.getTabBar(); if (tabBar) { tabBar.setData({ selected: 'buyer', // 假设聊天页是buyer tab badge: hasUnread ? ' ' : '' }); } } catch (e) { console.log('TabBar更新失败,将在下一次页面显示时自动更新'); } } }, // 清理所有未读消息状态 clearAllUnreadStatus: function() { console.log('清理所有未读消息状态'); try { // 1. 更新本地消息列表中的未读状态 const updatedMessages = this.data.messages.map(msg => ({ ...msg, isRead: true })); this.setData({ messages: updatedMessages }); // 2. 对于自定义TabBar,使用全局状态来管理未读标记 const app = getApp(); if (app && app.globalData) { app.globalData.tabBarBadge = { chat: '' }; console.log('已清理全局TabBar未读标记'); // 尝试通过getTabBar方法通知自定义TabBar更新 try { const tabBar = this.getTabBar(); if (tabBar) { tabBar.setData({ selected: 'buyer', // 假设聊天页是buyer tab badge: '' }); } } catch (e) { console.log('TabBar更新失败,将在下一次页面显示时自动更新'); } } // 3. 显示成功提示 wx.showToast({ title: '已清除所有未读提示', icon: 'success', duration: 2000 }); } catch (error) { console.error('清理未读状态失败:', error); wx.showToast({ title: '清理失败', icon: 'none', duration: 2000 }); } }, // 初始化WebSocket连接 initWebSocket: function() { try { const app = getApp(); // 使用正确的WebSocket服务器地址 - 开发环境通常是ws://localhost:3003 // 动态构建WebSocket URL,基于全局配置或环境 let wsProtocol = 'ws://'; let wsHost = app.globalData.webSocketUrl || 'localhost:3003'; let wsUrl; // 如果wsHost已经包含协议,直接使用 if (wsHost.startsWith('ws://') || wsHost.startsWith('wss://')) { wsUrl = wsHost; } else { // 否则添加协议前缀 wsUrl = `${wsProtocol}${wsHost}`; } this.setData({ webSocketUrl: wsUrl }); console.log('WebSocket连接初始化,使用地址:', wsUrl); // 连接WebSocket socketManager.connect(wsUrl); // 添加消息监听 socketManager.on('message', this.handleWebSocketMessage.bind(this)); // 添加状态监听,以便调试 socketManager.on('status', (status) => { console.log('WebSocket状态更新:', status); }); console.log('聊天列表页面WebSocket已初始化'); } catch (error) { console.error('初始化WebSocket失败:', error); wx.showToast({ title: 'WebSocket初始化失败', icon: 'none' }); } }, // 清理WebSocket连接 cleanupWebSocket: function() { socketManager.off('message', this.handleWebSocketMessage); }, // 加载聊天列表数据 - 优化版本 loadChatList: function() { wx.showLoading({ title: '加载中' }); try { // 从服务器获取真实的聊天列表数据 const app = getApp(); const token = app.globalData.token || wx.getStorageSync('token'); // 使用正确的API配置,兼容开发环境 const baseUrl = app.globalData.baseUrl || 'http://localhost:3003'; const currentUserId = app.globalData.userInfo?.userId || wx.getStorageSync('userId') || 'unknown'; console.log('使用API地址:', baseUrl); console.log('当前用户ID:', currentUserId); // 根据用户类型选择正确的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}${apiPath}`, method: 'GET', header: { 'Authorization': token ? `Bearer ${token}` : '', 'content-type': 'application/json' }, success: (res) => { console.log('获取聊天列表成功:', res.data); // 处理不同的API响应格式 let chatData = []; // 更灵活的响应格式处理 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)) { // 如果直接返回数组 chatData = res.data; } else if (res.data) { // 如果返回的是对象但不是标准格式,尝试直接使用 chatData = [res.data]; } // 保存原始数据到日志,便于调试 console.log('处理前的聊天数据:', chatData); if (Array.isArray(chatData) && chatData.length > 0) { // 格式化聊天列表数据 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 || item.timestamp || Date.now()); let displayTime = ''; if (messageDate.toDateString() === now.toDateString()) { // 今天的消息只显示时间 displayTime = messageDate.getHours().toString().padStart(2, '0') + ':' + messageDate.getMinutes().toString().padStart(2, '0'); } else if (messageDate.toDateString() === new Date(now.getTime() - 86400000).toDateString()) { // 昨天的消息 displayTime = '昨天'; } else { // 其他日期显示月日 displayTime = (messageDate.getMonth() + 1) + '月' + messageDate.getDate() + '日'; } // 获取当前用户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 { // 使用conversation_id作为唯一标识,避免重复ID问题 id: item.conversation_id || displayUserId, name: item.userName || item.name || displayName, avatar: item.avatar || (item.userName || displayName).charAt(0) || '用', content: messageContent, time: displayTime, isRead: unreadCount === 0, // 有未读数就是未读状态 unreadCount: unreadCount, // 添加原始数据引用,便于调试 _raw: item, // 保留会话ID用于导航 conversationId: item.conversation_id || item.id }; }); // 去重 - 基于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.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: '获取消息失败,重试中...', icon: 'none', duration: 3000 }); // 尝试使用本地缓存数据 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, 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) { console.error('加载聊天列表异常:', error); wx.hideLoading(); wx.showToast({ title: '加载异常', icon: 'none' }); } }, // 返回上一页 onBack: function() { wx.navigateBack({ delta: 1 }); }, /** * 生命周期函数--监听页面加载 */ 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); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { // 设置导航栏右侧按钮的点击事件 wx.showNavigationBarLoading(); }, // 导航栏左侧按钮点击事件 onNavigationBarButtonTap(e) { if (e.type === 'left') { this.onBack(); } else if (e.type === 'right') { // 处理管理按钮点击 wx.showToast({ title: '管理功能待开发', icon: 'none' }); } }, /** * 生命周期函数--监听页面显示 */ onShow() { 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(); } }, /** * 生命周期函数--监听页面隐藏 */ onHide() { // 页面隐藏时清理WebSocket连接 this.cleanupWebSocket(); }, /** * 生命周期函数--监听页面卸载 */ onUnload() { // 页面卸载时清理WebSocket连接 this.cleanupWebSocket(); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { console.log('下拉刷新触发'); // 重新加载聊天列表数据 this.loadChatList(); // 停止下拉刷新动画 wx.stopPullDownRefresh(); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { // 页面分享配置 return { title: '聊天列表', path: '/pages/chat/index' } }, // 跳转到对话详情页面 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]; // 查找会话时同时考虑id和conversationId const messageIndex = messages.findIndex(item => item.id === userId || item.conversationId === conversationId ); if (messageIndex >= 0) { messages[messageIndex].isRead = true; messages[messageIndex].unreadCount = 0; this.setData({ messages }); // 更新TabBar未读消息数 this.updateTabBarBadge(); // 通知服务器已读状态(使用userId) this.markAsRead(userId); } // 关键修复:在URL中同时传递userId和conversationId,确保正确打开会话 wx.navigateTo({ url: `/pages/chat-detail/index?userId=${userId}&userName=${encodeURIComponent(userName)}${conversationId ? `&conversationId=${conversationId}` : ''}` }); }); }, // 通知服务器消息已读 markAsRead: function(userId) { // 只执行本地标记已读,不再调用服务器API console.log('执行本地标记已读,不再调用服务器API:', userId); // 在本地标记消息已读,确保应用功能正常 this.localMarkAsRead(userId); }, // 本地标记消息已读 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 }); } })