diff --git a/docs/HTTP-API.md b/docs/HTTP-API.md index c11c66a..180fa26 100644 --- a/docs/HTTP-API.md +++ b/docs/HTTP-API.md @@ -165,7 +165,7 @@ curl "http://127.0.0.1:5031/api/v1/messages?talker=xxx@chatroom&media=1&image=1& 单条消息字段: - `localId` -- `serverId` +- `serverId`(原始 64 位 ID 字符串,避免 JS number 精度丢失) - `localType` - `createTime` - `isSend` @@ -194,7 +194,7 @@ curl "http://127.0.0.1:5031/api/v1/messages?talker=xxx@chatroom&media=1&image=1& "messages": [ { "localId": 123, - "serverId": "456", + "serverId": "6116895530414915131", "localType": 1, "createTime": 1738713600, "isSend": 0, diff --git a/electron/services/chatService.ts b/electron/services/chatService.ts index 047a42e..104bf89 100644 --- a/electron/services/chatService.ts +++ b/electron/services/chatService.ts @@ -4609,6 +4609,7 @@ class ChatService { const createTime = this.getRowTimestampSeconds(row, ['create_time', 'createTime', 'msg_time', 'msgTime', 'time'], 0) const sortSeq = this.getRowInt(row, ['sort_seq'], createTime > 0 ? createTime * 1000 : 0) const localId = this.getRowInt(row, ['local_id'], 0) + const serverIdRaw = this.normalizeUnsignedIntegerToken(row.server_id) const serverId = this.getRowInt(row, ['server_id'], 0) const content = this.decodeMessageContent(row.message_content, row.compress_content) @@ -4635,6 +4636,7 @@ class ChatService { }), localId, serverId, + serverIdRaw, localType, createTime, sortSeq, diff --git a/electron/services/httpService.ts b/electron/services/httpService.ts index a2b5c72..1e9b014 100644 --- a/electron/services/httpService.ts +++ b/electron/services/httpService.ts @@ -1545,7 +1545,7 @@ class HttpService { talker, String(msg.localId), msg.createTime || undefined, - msg.serverId || undefined + this.getMessageServerId(msg) || undefined ) if (result.success && result.data) { const fileName = `voice_${msg.localId}.wav` @@ -1599,9 +1599,11 @@ class HttpService { } private toApiMessage(msg: Message, media?: ApiExportedMedia): Record { + const serverId = this.getMessageServerId(msg) + return { localId: msg.localId, - serverId: msg.serverId, + serverId: serverId || '0', localType: msg.localType, createTime: msg.createTime, sortSeq: msg.sortSeq, @@ -1617,6 +1619,27 @@ class HttpService { } } + private getMessageServerId(msg: Message): string { + const raw = this.normalizeUnsignedIntToken(msg.serverIdRaw) + if (raw && raw !== '0') return raw + + const fallback = this.normalizeUnsignedIntToken(msg.serverId) + return fallback && fallback !== '0' ? fallback : '' + } + + private normalizeUnsignedIntToken(value: unknown): string { + if (value === null || value === undefined) return '' + const text = String(value).trim() + if (!text) return '' + if (/^\d+$/.test(text)) { + return text.replace(/^0+(?=\d)/, '') + } + + const numeric = Number(value) + if (!Number.isFinite(numeric) || numeric <= 0) return '' + return String(Math.floor(numeric)) + } + /** * 解析时间参数 * 支持 YYYYMMDD 格式,返回秒级时间戳 @@ -1881,7 +1904,7 @@ class HttpService { timestamp: msg.createTime, type: this.mapMessageType(msg.localType, msg), content: this.getMessageContent(msg), - platformMessageId: msg.serverId ? String(msg.serverId) : undefined, + platformMessageId: this.getMessageServerId(msg) || undefined, mediaPath: mediaMap.get(msg.localId) ? `http://${this.host}:${this.port}/api/v1/media/${mediaMap.get(msg.localId)!.relativePath}` : undefined } })