只用表情 XML 里的 md5 + len/totallen 作为发送参数。

不再用图片文件大小、文件名等回退逻辑去“猜参数”。
发送接口不再“先返回发送中”,而是直接调用 SendEmoji 并等待结果:
成功才返回 表情发送成功
失败直接返回具体错误(不会再假成功)
This commit is contained in:
liuwei
2026-04-15 11:36:22 +08:00
parent d0fa823557
commit ee5c1ebadc
4 changed files with 55 additions and 30 deletions
@@ -1221,6 +1221,11 @@
},
getChatMediaUrl(url) {
if (!url) return '';
if (url.trim().startsWith('<')) {
const parsed = this.extractXmlMediaUrl(url);
if (!parsed) return '';
return `/api/messages/media_proxy?url=${encodeURIComponent(parsed)}`;
}
if (url.startsWith('blob:') || url.startsWith('data:') || url.startsWith('/static/') || url.startsWith('http://') || url.startsWith('https://')) {
return url;
}
@@ -1232,6 +1237,23 @@
}
return `/api/messages/media_proxy?url=${encodeURIComponent(url)}`;
},
extractXmlMediaUrl(xmlText) {
if (!xmlText) return '';
const patterns = [
/cdnurl\s*=\s*["']([^"']+)["']/i,
/encrypturl\s*=\s*["']([^"']+)["']/i,
/externurl\s*=\s*["']([^"']+)["']/i,
/cdnmidimgurl\s*=\s*["']([^"']+)["']/i,
/cdnthumburl\s*=\s*["']([^"']+)["']/i
];
for (const pattern of patterns) {
const match = pattern.exec(xmlText);
if (match && match[1]) {
return match[1].replace(/&amp;/g, '&').trim();
}
}
return '';
},
createLocalChatMessage(payload = {}) {
return {
messageId: `local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,