优化聊天:配对群组、稳定连接、消息列表与订单详情跳转

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-06-23 22:48:42 +08:00
parent 5e90f7c87c
commit 1ea106f101
8 changed files with 365 additions and 365 deletions

112
utils/group-chat.js Normal file
View File

@@ -0,0 +1,112 @@
/**
* 打手-商家/老板配对群group_Ds{打手}_Sj{商家} 或 group_Ds{打手}_Boss{老板}
*/
export const ORDER_CARD_PREFIX = '[ORDER_CARD]';
const ZHUANGTAI_MAP = {
1: '已下单', 2: '进行中', 3: '已完成', 4: '退款中',
5: '已退款', 6: '退款失败', 7: '指定中', 8: '结算中',
};
export function isPairGroupId(groupId) {
return /^group_Ds\w+_(Sj|Boss)\w+$/.test(groupId || '');
}
export function parsePairGroupId(groupId) {
if (!groupId) return null;
let m = /^group_Ds(\w+)_Sj(\w+)$/.exec(groupId);
if (m) return { dashouId: `Ds${m[1]}`, partnerId: `Sj${m[2]}`, partnerRole: 'shangjia' };
m = /^group_Ds(\w+)_Boss(\w+)$/.exec(groupId);
if (m) return { dashouId: `Ds${m[1]}`, partnerId: `Boss${m[2]}`, partnerRole: 'boss' };
return null;
}
export function getCounterpartGoEasyId(groupId, myGoEasyId) {
const parsed = parsePairGroupId(groupId);
if (!parsed || !myGoEasyId) return null;
if (myGoEasyId === parsed.dashouId) return parsed.partnerId;
if (myGoEasyId === parsed.partnerId) return parsed.dashouId;
return null;
}
export function parseOrderCardText(text) {
if (!text || !text.startsWith(ORDER_CARD_PREFIX)) return null;
try {
const data = JSON.parse(text.slice(ORDER_CARD_PREFIX.length));
return {
orderId: data.dingdan_id,
jieshao: data.jieshao || '',
jine: data.jine || '',
beizhu: data.beizhu || '',
zhuangtai: data.zhuangtai,
nicheng: data.nicheng || '',
create_time: data.create_time || '',
};
} catch (e) {
return null;
}
}
export function normalizeGroupMessage(msg) {
if (!msg) return msg;
if (msg.type === 'text' && msg.payload && msg.payload.text) {
const card = parseOrderCardText(msg.payload.text);
if (card) {
msg.type = 'order';
msg.payload = card;
}
}
return msg;
}
export function formatLastMessagePreview(msg) {
if (!msg) return '';
if (msg.type === 'text' && msg.payload && msg.payload.text) {
const card = parseOrderCardText(msg.payload.text);
if (card) return `[订单] ${card.jieshao || card.orderId}`;
return msg.payload.text;
}
if (msg.type === 'order' && msg.payload) {
return `[订单] ${msg.payload.jieshao || msg.payload.orderId || ''}`;
}
if (msg.type === 'image') return '[图片]';
return '[消息]';
}
export function enrichGroupConversation(item, myGoEasyId, defaultAvatar, ossBase) {
if (!item || item.type !== 'group') return item;
if (!item.data) item.data = {};
const counterpartId = getCounterpartGoEasyId(item.groupId, myGoEasyId);
if (counterpartId) {
item.data.counterpartId = counterpartId;
if (!item.data.name || item.data.name === item.groupId) {
item.data.name = `用户${counterpartId.replace(/^(Ds|Sj|Boss)/, '').slice(-6)}`;
}
}
if (item.lastMessage && item.lastMessage.senderId && item.lastMessage.senderId !== myGoEasyId) {
const sd = item.lastMessage.senderData || {};
if (sd.avatar) item.data.avatar = sd.avatar;
if (sd.name) item.data.name = sd.name;
}
let avatar = item.data.avatar || '';
if (avatar && !avatar.startsWith('http')) {
avatar = (ossBase || '') + avatar.replace(/^\//, '');
}
item.data.avatar = avatar || defaultAvatar;
if (item.data.orderZhuangtai != null) {
item.data.orderZhuangtaiText = ZHUANGTAI_MAP[item.data.orderZhuangtai] || '';
}
item.displayLastMsg = formatLastMessagePreview(item.lastMessage);
return item;
}
export function isOrderGroupConversation(c) {
if (!c || c.type !== 'group') return false;
if (c.data && c.data.orderId) return true;
return isPairGroupId(c.groupId) || /^group_\w+$/.test(c.groupId || '');
}