diff --git a/src/hooks/useTalkRecord.ts b/src/hooks/useTalkRecord.ts index 7b36c2b..64ace07 100644 --- a/src/hooks/useTalkRecord.ts +++ b/src/hooks/useTalkRecord.ts @@ -224,91 +224,38 @@ export const useTalkRecord = (uid: number) => { // 如果首尾消息ID存在于服务器数据中,进行详细比较 if (firstServerIdx !== undefined && lastServerIdx !== undefined) { - const criticalFields = ['is_revoke', 'is_read', 'is_mark'] - - // 比较首尾消息的关键字段 + // 根据用户建议,只比较msg_id和is_revoke字段 + // 因为消息ID是唯一的,内容变化主要是由撤回操作引起的 const compareMessage = (localMsg, serverMsg) => { - // 比较基本字段 - for (const field of criticalFields) { - if (localMsg[field] !== serverMsg[field]) { - return false - } - } - - // 特殊处理content字段,它在extra对象中 - const localContent = localMsg.extra?.content - const serverContent = serverMsg.extra?.content - - if (localContent !== serverContent) { - return false - } - - return true + // 消息ID已在外部比较过,这里只需检查is_revoke状态 + return localMsg.is_revoke === serverMsg.is_revoke } const firstMatch = compareMessage(firstLocalMsg, items[firstServerIdx]) const lastMatch = compareMessage(lastLocalMsg, items[lastServerIdx]) - // 如果首尾消息匹配,使用抽样检查中间消息 + // 如果首尾消息匹配,进行全量检查所有消息 if (firstMatch && lastMatch) { - // 智能抽样检查策略 - // 1. 检查首尾消息(已完成) - // 2. 检查中间点消息 - // 3. 检查最近修改的消息(通常是最新的几条) - // 4. 随机抽样检查 - + // 全量检查策略:检查所有消息 + // 由于一次只有30条消息,全量检查不会带来太大的性能负担 let allMatch = true - // 中间点检查 - const midIndex = Math.floor(localMessages.length / 2) - const midMsg = localMessages[midIndex] - const midServerIdx = serverMsgMap.get(midMsg.msg_id) - - if (midServerIdx === undefined || !compareMessage(midMsg, items[midServerIdx])) { - allMatch = false - } - - // 最近消息检查(检查最新的3条消息,通常是最可能被修改的) - if (allMatch && localMessages.length >= 4) { - for (let i = 1; i <= 3; i++) { - const recentMsg = localMessages[localMessages.length - i] - const recentServerIdx = serverMsgMap.get(recentMsg.msg_id) - - if (recentServerIdx === undefined || !compareMessage(recentMsg, items[recentServerIdx])) { - allMatch = false - break - } - } - } - - // 随机抽样检查(如果前面的检查都通过) - if (allMatch && localMessages.length > 10) { - // 随机选择5%的消息或至少2条进行检查 - const sampleSize = Math.max(2, Math.floor(localMessages.length * 0.05)) - const usedIndices = new Set([0, midIndex, localMessages.length - 1]) // 避免重复检查已检查的位置 + // 遍历所有本地消息,与服务器消息进行比较 + for (let i = 0; i < localMessages.length; i++) { + const localMsg = localMessages[i] + const serverIdx = serverMsgMap.get(localMsg.msg_id) - for (let i = 0; i < sampleSize; i++) { - // 生成不重复的随机索引 - let randomIndex - do { - randomIndex = Math.floor(Math.random() * localMessages.length) - } while (usedIndices.has(randomIndex)) - - usedIndices.add(randomIndex) - - const randomMsg = localMessages[randomIndex] - const randomServerIdx = serverMsgMap.get(randomMsg.msg_id) - - if (randomServerIdx === undefined || !compareMessage(randomMsg, items[randomServerIdx])) { - allMatch = false - break - } + // 如果消息ID不存在于服务器数据中,或者消息内容不匹配 + if (serverIdx === undefined || !compareMessage(localMsg, items[serverIdx])) { + allMatch = false + console.log(`消息不匹配,索引: ${i}, 消息ID: ${localMsg.msg_id}`) + break // 一旦发现不匹配,立即退出循环 } } if (allMatch) { const compareEndTime = performance.now() - console.log(`本地数据与服务器数据一致(抽样检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`) + console.log(`本地数据与服务器数据一致(全量检查),无需更新UI,比较耗时: ${(compareEndTime - compareStartTime).toFixed(2)}ms`) return } }