|
|
|
@ -30,43 +30,68 @@ export default defineStore('chatStore', { |
|
|
|
this.groupMsgMaxId = chatsData.groupMsgMaxId || 0; |
|
|
|
}, |
|
|
|
|
|
|
|
mergeOldCustomerToNew(oldKfId, newKfId) { |
|
|
|
const oldChat = this.findChatByFriend(oldKfId); |
|
|
|
const newChat = this.findChatByFriend(newKfId); |
|
|
|
if (!oldChat || !newChat) { |
|
|
|
console.warn('合并失败:旧/新会话不存在', oldKfId, newKfId); |
|
|
|
return; |
|
|
|
// 未知客服触发:全量合并所有旧客服到新客服
|
|
|
|
forceMergeAllOldCustomerToNew(newKfId) { |
|
|
|
const userStore = useUserStore(); |
|
|
|
const uid = userStore.userInfo.id; |
|
|
|
const prefix = `chats-app-${uid}-PRIVATE-`; |
|
|
|
const rootKey = `chats-app-${uid}`; |
|
|
|
|
|
|
|
const allKeys = uni.getStorageInfoSync().keys; |
|
|
|
const oldKeys = allKeys.filter(k => |
|
|
|
k.startsWith(prefix) && |
|
|
|
!k.endsWith('-hot') && |
|
|
|
!k.includes(`-${newKfId}`) |
|
|
|
); |
|
|
|
|
|
|
|
if (oldKeys.length === 0) return; |
|
|
|
|
|
|
|
let newChat = this.findChatByFriend(newKfId); |
|
|
|
if (!newChat) { |
|
|
|
newChat = { |
|
|
|
targetId: newKfId, |
|
|
|
type: "PRIVATE", |
|
|
|
messages: [], |
|
|
|
unreadCount: 0, |
|
|
|
lastContent: "", |
|
|
|
lastSendTime: 0, |
|
|
|
hotMinIdx: 0, |
|
|
|
readedMessageIdx: 0, |
|
|
|
atMe: false, |
|
|
|
atAll: false, |
|
|
|
stored: false |
|
|
|
}; |
|
|
|
this.chats.unshift(newChat); |
|
|
|
} |
|
|
|
|
|
|
|
newChat.messages = [...oldChat.messages, ...newChat.messages]; |
|
|
|
// 读取每一个旧客服 【冷+热完整消息】
|
|
|
|
let allOldMessages = []; |
|
|
|
oldKeys.forEach(oldKey => { |
|
|
|
const oldCold = uni.getStorageSync(oldKey); |
|
|
|
const oldHot = uni.getStorageSync(oldKey + "-hot"); |
|
|
|
// 旧客服完整消息:冷历史 + 热新消息
|
|
|
|
const oldFullMsg = [...(oldCold?.messages || []), ...(oldHot?.messages || [])]; |
|
|
|
allOldMessages = [...oldFullMsg, ...allOldMessages]; |
|
|
|
|
|
|
|
newChat.unreadCount += oldChat.unreadCount; |
|
|
|
newChat.lastContent = oldChat.lastContent || newChat.lastContent; |
|
|
|
newChat.lastSendTime = Math.max(oldChat.lastSendTime || 0, newChat.lastSendTime || 0); |
|
|
|
newChat.atMe = newChat.atMe || oldChat.atMe; |
|
|
|
newChat.atAll = newChat.atAll || oldChat.atAll; |
|
|
|
// 合并完成后才删除旧缓存,绝不提前删!
|
|
|
|
uni.removeStorageSync(oldKey); |
|
|
|
uni.removeStorageSync(oldKey + "-hot"); |
|
|
|
}); |
|
|
|
|
|
|
|
const keepHot = 300; |
|
|
|
const totalMsg = newChat.messages.length; |
|
|
|
newChat.hotMinIdx = totalMsg <= keepHot ? 0 : Math.max(0, totalMsg - keepHot); |
|
|
|
newChat.readedMessageIdx = Math.min(oldChat.readedMessageIdx || 0, newChat.readedMessageIdx || 0); |
|
|
|
newChat.messages = [...allOldMessages, ...newChat.messages]; |
|
|
|
|
|
|
|
this.clearCustomerCache(oldKfId); |
|
|
|
this.removePrivateChat(oldKfId); |
|
|
|
// 根缓存只保留最新客服
|
|
|
|
const root = uni.getStorageSync(rootKey); |
|
|
|
if (root) { |
|
|
|
root.chatKeys = [`${prefix}${newKfId}`]; |
|
|
|
uni.setStorageSync(rootKey, root); |
|
|
|
} |
|
|
|
|
|
|
|
newChat.stored = false; |
|
|
|
// 按照原生冷热规则拆分保存
|
|
|
|
this.saveToStorage(true); |
|
|
|
console.log('【合并完成】旧客服消息全部转入新客服', newChat.messages.length); |
|
|
|
}, |
|
|
|
|
|
|
|
clearCustomerCache(userId) { |
|
|
|
const userStore = useUserStore(); |
|
|
|
const currentUserId = userStore.userInfo.id; |
|
|
|
const key = `chats-app-${currentUserId}-PRIVATE-${userId}`; |
|
|
|
|
|
|
|
uni.removeStorageSync(key); |
|
|
|
uni.removeStorageSync(key + '-hot'); |
|
|
|
}, |
|
|
|
openChat(chatInfo) { |
|
|
|
let chats = this.curChats; |
|
|
|
let chat = null; |
|
|
|
@ -117,7 +142,6 @@ export default defineStore('chatStore', { |
|
|
|
this.saveToStorage(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
readedMessage(pos) { |
|
|
|
let chat = this.findChatByFriend(pos.friendId); |
|
|
|
@ -384,10 +408,9 @@ export default defineStore('chatStore', { |
|
|
|
} |
|
|
|
this.fliterMessage(chats, 3000, 500); |
|
|
|
chats.forEach(chat => { |
|
|
|
if (!chat.hotMinIdx || chat.hotMinIdx != chat.messages.length) { |
|
|
|
chat.hotMinIdx = chat.messages.length; |
|
|
|
// 原生规则:所有消息默认都放入热缓存,hotMinIdx归0
|
|
|
|
chat.hotMinIdx = 0; |
|
|
|
chat.stored = false; |
|
|
|
} |
|
|
|
}); |
|
|
|
this.chats = chats; |
|
|
|
cacheChats = null; |
|
|
|
@ -417,29 +440,40 @@ export default defineStore('chatStore', { |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
|
|
|
|
saveToStorage(withColdMessage) { |
|
|
|
if (this.loading) { |
|
|
|
return; |
|
|
|
} |
|
|
|
const userStore = useUserStore(); |
|
|
|
let userId = userStore.userInfo.id; |
|
|
|
let key = "chats-app-" + userId; |
|
|
|
let rootKey = "chats-app-" + userId; |
|
|
|
let chatKeys = []; |
|
|
|
const keepHotCount = 300; // 原生热缓存保留条数
|
|
|
|
|
|
|
|
this.chats.forEach((chat) => { |
|
|
|
let chatKey = `${key}-${chat.type}-${chat.targetId}` |
|
|
|
let chatKey = `${rootKey}-${chat.type}-${chat.targetId}` |
|
|
|
if (!chat.stored) { |
|
|
|
if (chat.delete) { |
|
|
|
uni.removeStorageSync(chatKey); |
|
|
|
uni.removeStorageSync(chatKey + '-hot'); |
|
|
|
} else { |
|
|
|
// 原生标准切割:hotMinIdx = 总消息长度 - 最新300条
|
|
|
|
const totalMsgLen = chat.messages.length; |
|
|
|
chat.hotMinIdx = Math.max(0, totalMsgLen - keepHotCount); |
|
|
|
// cold:前面所有久远历史消息
|
|
|
|
const coldMsg = chat.messages.slice(0, chat.hotMinIdx); |
|
|
|
// hot:后面最新的300条消息(所有新发消息全在这里!)
|
|
|
|
const hotMsg = chat.messages.slice(chat.hotMinIdx); |
|
|
|
|
|
|
|
// 写入冷缓存
|
|
|
|
if (withColdMessage) { |
|
|
|
let coldChat = Object.assign({}, chat); |
|
|
|
coldChat.messages = chat.messages.slice(0, chat.hotMinIdx); |
|
|
|
uni.setStorageSync(chatKey, coldChat) |
|
|
|
let coldChat = { ...chat, messages: coldMsg }; |
|
|
|
uni.setStorageSync(chatKey, coldChat); |
|
|
|
} |
|
|
|
let hotKey = chatKey + '-hot'; |
|
|
|
let hotChat = Object.assign({}, chat); |
|
|
|
hotChat.messages = chat.messages.slice(chat.hotMinIdx) |
|
|
|
uni.setStorageSync(hotKey, hotChat); |
|
|
|
// 写入热缓存(新发消息100%保存)
|
|
|
|
let hotChat = { ...chat, messages: hotMsg }; |
|
|
|
uni.setStorageSync(chatKey + '-hot', hotChat); |
|
|
|
} |
|
|
|
chat.stored = true; |
|
|
|
} |
|
|
|
@ -447,14 +481,17 @@ export default defineStore('chatStore', { |
|
|
|
chatKeys.push(chatKey); |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
// 更新根会话列表
|
|
|
|
let chatsData = { |
|
|
|
privateMsgMaxId: this.privateMsgMaxId, |
|
|
|
groupMsgMaxId: this.groupMsgMaxId, |
|
|
|
chatKeys: chatKeys |
|
|
|
} |
|
|
|
uni.setStorageSync(key, chatsData) |
|
|
|
uni.setStorageSync(rootKey, chatsData) |
|
|
|
this.chats = this.chats.filter(chat => !chat.delete) |
|
|
|
}, |
|
|
|
|
|
|
|
clear(state) { |
|
|
|
cacheChats = []; |
|
|
|
this.chats = []; |
|
|
|
@ -467,34 +504,59 @@ export default defineStore('chatStore', { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
let userStore = useUserStore(); |
|
|
|
let userId = userStore.userInfo.id; |
|
|
|
let chatsData = uni.getStorageSync("chats-app-" + userId) |
|
|
|
if (chatsData) { |
|
|
|
if (chatsData.chatKeys) { |
|
|
|
chatsData.chats = []; |
|
|
|
chatsData.chatKeys.forEach(key => { |
|
|
|
let coldChat = uni.getStorageSync(key); |
|
|
|
let hotChat = uni.getStorageSync(key + '-hot'); |
|
|
|
if (!coldChat && !hotChat) { |
|
|
|
return; |
|
|
|
const rootCacheKey = `chats-app-${userId}`; |
|
|
|
let chatsData = uni.getStorageSync(rootCacheKey); |
|
|
|
|
|
|
|
// 安全处理:没有数据直接返回
|
|
|
|
if (!chatsData) { |
|
|
|
chatsData = { |
|
|
|
privateMsgMaxId: 0, |
|
|
|
groupMsgMaxId: 0, |
|
|
|
chatKeys: [] |
|
|
|
}; |
|
|
|
} |
|
|
|
hotChat && hotChat.messages.forEach(msg => { |
|
|
|
if (msg.status == MESSAGE_STATUS.SENDING) { |
|
|
|
msg.status = MESSAGE_STATUS.FAILED |
|
|
|
|
|
|
|
// 安全处理:chatKeys 必须是数组
|
|
|
|
if (!chatsData.chatKeys || !Array.isArray(chatsData.chatKeys)) { |
|
|
|
chatsData.chatKeys = []; |
|
|
|
} |
|
|
|
}) |
|
|
|
let chat = Object.assign({}, coldChat, hotChat); |
|
|
|
if (hotChat && coldChat) { |
|
|
|
chat.messages = coldChat.messages.concat(hotChat.messages) |
|
|
|
|
|
|
|
uni.removeStorageSync("currentActiveCustomerId"); |
|
|
|
|
|
|
|
let finalChats = []; |
|
|
|
chatsData.chatKeys.forEach(key => { |
|
|
|
try { |
|
|
|
const coldChat = uni.getStorageSync(key) || {}; |
|
|
|
const hotChat = uni.getStorageSync(key + "-hot") || {}; |
|
|
|
|
|
|
|
// 修复发送中状态
|
|
|
|
if (hotChat.messages && Array.isArray(hotChat.messages)) { |
|
|
|
hotChat.messages.forEach(msg => { |
|
|
|
if (msg.status === MESSAGE_STATUS.SENDING) { |
|
|
|
msg.status = MESSAGE_STATUS.FAILED; |
|
|
|
} |
|
|
|
chat.readedMessageIdx = chat.readedMessageIdx || 0; |
|
|
|
chatsData.chats.push(chat); |
|
|
|
}) |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 消息合并(绝对安全)
|
|
|
|
const coldMsg = Array.isArray(coldChat.messages) ? coldChat.messages : []; |
|
|
|
const hotMsg = Array.isArray(hotChat.messages) ? hotChat.messages : []; |
|
|
|
const fullMsg = [...coldMsg, ...hotMsg]; |
|
|
|
|
|
|
|
let chat = { ...coldChat, ...hotChat }; |
|
|
|
chat.messages = fullMsg; |
|
|
|
chat.hotMinIdx = coldMsg.length; |
|
|
|
chat.readedMessageIdx = chat.readedMessageIdx || 0; |
|
|
|
|
|
|
|
finalChats.push(chat); |
|
|
|
} catch (e) {} |
|
|
|
}); |
|
|
|
|
|
|
|
chatsData.chats = finalChats; |
|
|
|
this.initChats(chatsData); |
|
|
|
} |
|
|
|
resolve() |
|
|
|
}) |
|
|
|
} |
|
|
|
resolve(); |
|
|
|
}); |
|
|
|
}, |
|
|
|
}, |
|
|
|
getters: { |
|
|
|
curChats: (state) => { |
|
|
|
@ -558,4 +620,4 @@ export default defineStore('chatStore', { |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}) |