Files
a_long/miniprogram/utils/xiaoxilj.js

270 lines
8.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 订单群聊跳转:先确定群 IDIM 连接失败也尽量能进聊天页
*/
import request from './request';
import { persistGroupMeta } from './im-user.js';
import { resolveLocalGroupId } from './group-chat.js';
const app = getApp();
function formatError(err) {
if (!err) return '进入聊天失败';
if (typeof err === 'string') return err;
if (err.message) return err.message;
if (err.content) return String(err.content);
if (err.msg) return String(err.msg);
if (err.code) return `连接失败(${err.code})`;
try {
return JSON.stringify(err);
} catch (e) {
return '进入聊天失败';
}
}
function withTimeout(promise, ms, errMsg) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error(errMsg || '操作超时')), ms);
promise
.then((v) => { clearTimeout(timer); resolve(v); })
.catch((e) => { clearTimeout(timer); reject(e); });
});
}
function getConnectedUserId() {
const fromState = app.globalData?.goEasyConnection?.userId;
const fromIm = wx.goEasy?.im?.userId;
return fromState || fromIm || '';
}
function isImConnected() {
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected';
return status === 'connected' || status === 'reconnected';
}
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,
};
if (!app.globalData.chatEnabled || !wx.goEasy?.im) {
throw new Error('聊天服务未就绪,请稍后重试');
}
if (isImConnected() && getConnectedUserId() === userId) {
return;
}
const connectedId = getConnectedUserId();
if (connectedId && connectedId !== userId && app.disconnectGoEasy) {
await app.disconnectGoEasy();
}
if (!app.connectWithIdentity) {
throw new Error('聊天功能未初始化');
}
await withTimeout(
app.connectWithIdentity(identityType, userId, true),
12000,
'IM连接超时'
);
if (!isImConnected()) {
throw new Error('IM连接失败请检查网络后重试');
}
}
async function prepareGroupChat(identityType, userId, orderId, partnerUid, fadanPingtai, groupName, isCross) {
let chatData = null;
try {
const res = await withTimeout(
request({
url: '/dingdan/ltdhzb',
method: 'POST',
data: {
dingdan_id: orderId,
identityType,
push_order_card: false,
},
}),
12000,
'准备群聊超时'
);
const body = res?.data || {};
if (body.code === 0 && body.data?.groupId) {
chatData = body.data;
} else if (body.msg) {
console.warn('ltdhzb:', body.msg);
}
} catch (e) {
console.warn('ltdhzb 请求失败,尝试本地 groupId', e);
}
if (!chatData?.groupId) {
const myUid = userId.replace(/^(Ds|Sj|Boss)/, '');
let localGroupId = resolveLocalGroupId(
identityType, myUid, partnerUid, fadanPingtai, orderId, isCross
);
if (!localGroupId && orderId) {
localGroupId = `group_${orderId}`;
}
if (!localGroupId) {
throw new Error('无法确定群聊,请确认订单已接单且对方信息完整');
}
chatData = {
groupId: localGroupId,
orderId,
groupName: groupName || '订单群聊',
isCross: isCross || fadanPingtai || 0,
};
try {
await request({
url: '/dingdan/ltdhzb',
method: 'POST',
data: { dingdan_id: orderId, identityType, push_order_card: false },
});
} catch (e) { /* ignore */ }
}
return chatData;
}
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 };
wx.navigateTo({ url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)) });
}
async connectToGroupChat(params) {
const {
identityType, userId, orderId, groupName, groupAvatar, isCross,
partnerUid, fadanPingtai,
} = params;
if (!identityType || !userId || !orderId) {
throw new Error('参数不完整');
}
app.globalData.currentRole = identityType;
wx.setStorageSync('currentRole', identityType);
wx.showLoading({ title: '建立联系中...', mask: true });
try {
const chatData = await prepareGroupChat(
identityType, userId, orderId, partnerUid, fadanPingtai || isCross, groupName, isCross
);
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);
let imReady = false;
try {
await ensureIdentityConnection(identityType, userId);
imReady = true;
try {
await withTimeout(
new Promise((resolve, reject) => {
wx.goEasy.im.subscribeGroup({
groupIds: [realGroupId],
onSuccess: () => resolve(),
onFailed: (error) => reject(error),
});
}),
8000,
'订阅群聊超时'
);
} catch (subErr) {
console.warn('订阅群聊失败,仍尝试进入页面', subErr);
}
} catch (imErr) {
console.warn('IM连接失败仍进入聊天页由页面重连', imErr);
}
const uid = userId.replace(/^(Ds|Sj|Boss)/, '');
const param = {
groupId: realGroupId,
orderId: chatData.orderId || orderId,
groupName: chatData.counterpartName || chatData.groupName || groupName || '订单群聊',
groupAvatar: avatar,
isCross: chatData.isCross != null ? chatData.isCross : (isCross || 0),
currentUserId: userId,
currentUserName: app.globalData.currentUser?.name || `用户${uid}`,
currentUserAvatar: app.globalData.currentUser?.avatar ||
(wx.getStorageSync('touxiang') || (app.globalData.ossImageUrl + app.globalData.morentouxiang)),
orderZhuangtai: chatData.orderZhuangtai,
orderJine: chatData.orderJine,
orderDesc: chatData.orderDesc || '',
imReady,
};
wx.hideLoading();
wx.navigateTo({
url: '/pages/qunliaotian/qunliaotian?data=' + encodeURIComponent(JSON.stringify(param)),
fail: (navErr) => {
wx.showToast({ title: formatError(navErr), icon: 'none', duration: 2500 });
},
});
} catch (err) {
wx.hideLoading();
console.error('跳转群聊失败:', err);
wx.showToast({ title: formatError(err), icon: 'none', duration: 2500 });
throw err;
}
}
}
export default new ConnectionManager();