/** * 连接管理模块 - xiaoxilj.js (根治发送失败:跳转前确保群组已订阅) * 从详情页跳转订单群聊时,提前订阅群组,避免发送消息时订阅未完成而失败 */ const app = getApp(); function waitForConnection(expectedUserId, timeout = 10000) { return new Promise((resolve, reject) => { const timer = setTimeout(() => { app.off('connectionChanged', handler); reject(new Error('连接超时')); }, timeout); const handler = (event) => { if (event.status === 'connected') { if (event.userId === expectedUserId) { clearTimeout(timer); app.off('connectionChanged', handler); resolve(); } else { console.error(`连接身份不匹配: 期望 ${expectedUserId}, 实际 ${event.userId}`); wx.removeStorageSync('savedGoEasyConnection'); wx.removeStorageSync('goEasyUserId'); wx.removeStorageSync('currentGoEasyIdentity'); if (app.clearSavedConnection) app.clearSavedConnection(); clearTimeout(timer); app.off('connectionChanged', handler); reject(new Error(`连接身份不匹配: 期望 ${expectedUserId}, 实际 ${event.userId}`)); } } else if (event.status === 'disconnected' && !event.manual) { wx.removeStorageSync('savedGoEasyConnection'); wx.removeStorageSync('goEasyUserId'); wx.removeStorageSync('currentGoEasyIdentity'); if (app.clearSavedConnection) app.clearSavedConnection(); clearTimeout(timer); app.off('connectionChanged', handler); reject(new Error('连接失败')); } }; app.on('connectionChanged', handler); }); } class ConnectionManager { // 原有的私聊方法保持不变 async connectAndChat(params) { const { identityType, userId, targetUser } = params; if (!identityType || !userId || !targetUser || !targetUser.id) { throw new Error('参数不完整'); } if (identityType === 'dashou' && !userId.startsWith('Ds')) { throw new Error(`打手身份的用户ID必须以Ds开头,实际为 ${userId}`); } if (identityType === 'shangjia' && !userId.startsWith('Sj')) { throw new Error(`商家身份的用户ID必须以Sj开头,实际为 ${userId}`); } if (identityType === 'boss' && !userId.startsWith('Boss')) { throw new Error(`老板身份的用户ID必须以Boss开头,实际为 ${userId}`); } wx.removeStorageSync('savedGoEasyConnection'); wx.removeStorageSync('goEasyUserId'); wx.removeStorageSync('currentGoEasyIdentity'); if (app.clearSavedConnection) app.clearSavedConnection(); if (wx.goEasy && wx.goEasy.getConnectionStatus() === 'connected') { wx.goEasy.disconnect(); } const waitPromise = waitForConnection(userId); app.connectWithIdentity(identityType, userId, false); try { await waitPromise; const currentUser = { id: userId, name: app.globalData.currentUser?.name || '用户', avatar: app.globalData.currentUser?.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang) }; const to = { id: targetUser.id, name: targetUser.name || '用户', avatar: targetUser.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang) }; const param = { to, currentUser }; const path = '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)); wx.navigateTo({ url: path }); } catch (err) { console.error('连接失败:', err); wx.showToast({ title: err.message || '连接失败', icon: 'none' }); throw err; } } async connectToGroupChat(params) { const { identityType, userId, orderId, groupName, groupAvatar, isCross } = params; if (!identityType || !userId || !orderId) { throw new Error('参数不完整:identityType, userId, orderId 必填'); } // 校验 userId 前缀 if (identityType === 'dashou' && !userId.startsWith('Ds')) { throw new Error(`打手身份的用户ID必须以Ds开头,实际为 ${userId}`); } if (identityType === 'shangjia' && !userId.startsWith('Sj')) { throw new Error(`商家身份的用户ID必须以Sj开头,实际为 ${userId}`); } if (identityType === 'boss' && !userId.startsWith('Boss')) { throw new Error(`老板身份的用户ID必须以Boss开头,实际为 ${userId}`); } // 1. 同步全局角色,确保群聊页初始化正确 app.globalData.currentRole = identityType; wx.setStorageSync('currentRole', identityType); const uid = userId.replace(/^(Ds|Sj|Boss|Gs|Zz)/, ''); const avatar = wx.getStorageSync('touxiang') || (app.globalData.ossImageUrl + app.globalData.morentouxiang); app.globalData.currentUser = { id: userId, name: app.globalData.currentUser?.name || `用户${uid}`, avatar: avatar }; // 2. 确保 GoEasy 已使用目标身份连接 let needConnect = false; if (!wx.goEasy || !wx.goEasy.getConnectionStatus || wx.goEasy.getConnectionStatus() !== 'connected') { needConnect = true; } else { const currentUserId = wx.goEasy.im?.userId; if (currentUserId !== userId) { needConnect = true; } } if (needConnect) { wx.removeStorageSync('savedGoEasyConnection'); wx.removeStorageSync('goEasyUserId'); if (app.clearSavedConnection) app.clearSavedConnection(); if (wx.goEasy && wx.goEasy.getConnectionStatus() === 'connected') { wx.goEasy.disconnect(); } const waitPromise = waitForConnection(userId); app.connectWithIdentity(identityType, userId, false); try { await waitPromise; } catch (err) { wx.showToast({ title: '连接失败', icon: 'none' }); throw err; } } // 3. 从会话列表查找真实群组ID let realGroupId = null; try { const result = await new Promise((resolve, reject) => { wx.goEasy.im.latestConversations({ onSuccess: (res) => { const conversations = res.content?.conversations || []; const found = conversations.find(c => c.type === 'group' && c.data && c.data.orderId === orderId); resolve(found ? found.groupId : null); }, onFailed: reject }); }); realGroupId = result; } catch (err) { console.error('获取会话列表失败:', err); wx.showToast({ title: '获取群聊信息失败', icon: 'none' }); throw err; } if (!realGroupId) { wx.showToast({ title: '暂未创建群聊', icon: 'none' }); return; } // 4. 🔥 关键:主动订阅群组并等待成功,确保发送消息时订阅已完成 try { await new Promise((resolve, reject) => { wx.goEasy.im.subscribeGroup({ groupIds: [realGroupId], onSuccess: () => { resolve(); }, onFailed: (error) => { console.error('订阅群组失败:', error); reject(error); } }); }); } catch (err) { wx.showToast({ title: '订阅群组失败', icon: 'none' }); throw err; } // 5. 跳转群聊页(参数与消息列表完全一致) const param = { groupId: realGroupId, orderId: orderId, groupName: groupName || '订单群聊', groupAvatar: groupAvatar || '', isCross: isCross || 0 }; const path = '/pages/qunliaotian/qunliaotian?data=' + encodeURIComponent(JSON.stringify(param)); wx.navigateTo({ url: path }); } } export default new ConnectionManager();