修复聊天头像与列表:配对群元数据、排序与连接稳定(miniprogram目录)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-23 23:21:20 +08:00
parent 1ea106f101
commit 033359f6f4
9 changed files with 2342 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
/**
* 连接管理模块 - 订单群聊跳转(后端准备群 + 稳定连接)
*/
import request from './request';
import { persistGroupMeta } from './im-user.js';
const app = getApp();
function waitForConnection(expectedUserId, timeout = 15000) {
return new Promise((resolve, reject) => {
const status = wx.goEasy?.getConnectionStatus?.();
const currentUserId = wx.goEasy?.im?.userId;
if ((status === 'connected' || status === 'reconnected') && currentUserId === expectedUserId) {
resolve();
return;
}
const timer = setTimeout(() => {
app.off('connectionChanged', handler);
reject(new Error('连接超时'));
}, timeout);
const handler = (event) => {
if (event.status === 'connected') {
const uid = event.userId || wx.goEasy?.im?.userId;
if (uid === expectedUserId) {
clearTimeout(timer);
app.off('connectionChanged', handler);
resolve();
}
} else if (event.status === 'disconnected' && event.manual) {
clearTimeout(timer);
app.off('connectionChanged', handler);
reject(new Error('连接已断开'));
}
};
app.on('connectionChanged', handler);
});
}
async function ensureIdentityConnection(identityType, userId) {
app.globalData.currentRole = identityType;
wx.setStorageSync('currentRole', identityType);
const uid = userId.replace(/^(Ds|Sj|Boss|Gs|Zz|Kh)/, '');
const avatar = wx.getStorageSync('touxiang') ||
(app.globalData.ossImageUrl + app.globalData.morentouxiang);
app.globalData.currentUser = {
id: userId,
name: app.globalData.currentUser?.name || `用户${uid}`,
avatar: avatar,
};
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected';
const currentUserId = wx.goEasy?.im?.userId;
if ((status === 'connected' || status === 'reconnected') && currentUserId === userId) {
return;
}
if (currentUserId && currentUserId !== userId && app.disconnectGoEasy) {
await app.disconnectGoEasy();
}
const waitPromise = waitForConnection(userId);
const connectPromise = app.connectWithIdentity(identityType, userId, true);
await waitPromise;
await connectPromise;
}
class ConnectionManager {
async connectAndChat(params) {
const { identityType, userId, targetUser } = params;
if (!identityType || !userId || !targetUser || !targetUser.id) {
throw new Error('参数不完整');
}
await ensureIdentityConnection(identityType, userId);
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 });
}
async connectToGroupChat(params) {
const { identityType, userId, orderId, groupName, groupAvatar, isCross } = params;
if (!identityType || !userId || !orderId) {
throw new Error('参数不完整identityType, userId, orderId 必填');
}
wx.showLoading({ title: '建立联系中...', mask: true });
try {
await ensureIdentityConnection(identityType, userId);
const res = await request({
url: '/dingdan/ltdhzb',
method: 'POST',
data: {
dingdan_id: orderId,
identityType,
push_order_card: true,
},
});
const body = res?.data || {};
if (body.code !== 0 || !body.data || !body.data.groupId) {
throw new Error(body.msg || '准备群聊失败');
}
const chatData = body.data;
const realGroupId = chatData.groupId;
let avatar = chatData.counterpartAvatar || chatData.groupAvatar || groupAvatar || '';
if (avatar && !avatar.startsWith('http')) {
avatar = app.globalData.ossImageUrl + avatar.replace(/^\//, '');
}
if (!app.globalData.groupInfoMap) app.globalData.groupInfoMap = {};
const meta = {
name: chatData.counterpartName || chatData.groupName || groupName,
avatar,
orderId: chatData.orderId || orderId,
orderDesc: chatData.orderDesc || '',
orderZhuangtai: chatData.orderZhuangtai,
dashouGoEasyId: chatData.dashouGoEasyId,
partnerGoEasyId: chatData.partnerGoEasyId,
dashouYonghuid: chatData.dashouYonghuid,
partnerYonghuid: chatData.partnerYonghuid,
dashouName: chatData.dashouName,
partnerName: chatData.partnerName,
dashouAvatar: chatData.dashouAvatar,
partnerAvatar: chatData.partnerAvatar,
counterpartId: chatData.counterpartId,
counterpartYonghuid: chatData.counterpartYonghuid,
};
app.globalData.groupInfoMap[realGroupId] = meta;
persistGroupMeta(app, realGroupId, meta);
await new Promise((resolve, reject) => {
wx.goEasy.im.subscribeGroup({
groupIds: [realGroupId],
onSuccess: () => resolve(),
onFailed: (error) => reject(error),
});
});
const param = {
groupId: realGroupId,
orderId: chatData.orderId || orderId,
groupName: chatData.counterpartName || chatData.groupName || groupName || '订单群聊',
groupAvatar: avatar,
isCross: chatData.isCross != null ? chatData.isCross : (isCross || 0),
};
wx.hideLoading();
wx.navigateTo({
url: '/pages/qunliaotian/qunliaotian?data=' + encodeURIComponent(JSON.stringify(param)),
});
} catch (err) {
wx.hideLoading();
console.error('跳转群聊失败:', err);
wx.showToast({ title: err.message || '进入聊天失败', icon: 'none' });
throw err;
}
}
}
export default new ConnectionManager();