diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/ImAgentServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/ImAgentServiceImpl.java index 8be900e..27004e5 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/ImAgentServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/ImAgentServiceImpl.java @@ -53,7 +53,6 @@ public class ImAgentServiceImpl extends ServiceImpl impl // if(user == null || ObjectUtil.isEmpty(user)){ // return false; // } - String token = user.getUniqueToken(); if(token == null || ObjectUtil.isEmpty(token)){ return false; @@ -68,4 +67,4 @@ public class ImAgentServiceImpl extends ServiceImpl impl return isFileOpen == 1; } -} +} \ No newline at end of file diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue index 2a6c47a..6e524f6 100644 --- a/im-uniapp/App.vue +++ b/im-uniapp/App.vue @@ -42,7 +42,6 @@ export default { this.configStore.setAppInit(true); } }); - // console.log(cmd, msgInfo); wsApi.onMessage((cmd, msgInfo) => { console.log(cmd, msgInfo); if (cmd == 2) { diff --git a/im-uniapp/components/chat-message-item/chat-message-item.vue b/im-uniapp/components/chat-message-item/chat-message-item.vue index dc9a03b..079ca9f 100644 --- a/im-uniapp/components/chat-message-item/chat-message-item.vue +++ b/im-uniapp/components/chat-message-item/chat-message-item.vue @@ -66,8 +66,7 @@ - + {{ $t('chat.read') }} diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue index 9d780ad..15c82be 100644 --- a/im-uniapp/pages/chat/chat-box.vue +++ b/im-uniapp/pages/chat/chat-box.vue @@ -663,10 +663,27 @@ export default { this.$set(targetChat.messages, msgIndex, failedMessage); this.$forceUpdate(); - uni.showToast({ - title: this.$t('chat.sendFailed'), - icon: "none", - }); + uni.showToast({ + title: "客服已更换,刷新中...", + icon: "none", + duration: 1500 + }); + + setTimeout(() => { + // #ifdef H5 + window.location.reload(); + // #endif + + // #ifdef APP-PLUS + plus.runtime.restart(); + // #endif + + // #ifdef MP-WEIXIN + uni.reLaunch({ + url: '/pages/chat/chat-box?chatIdx=0' + }); + // #endif + }, 800); }); } } diff --git a/im-web/src/components/account/AccountSwitchMenu.vue b/im-web/src/components/account/AccountSwitchMenu.vue index ece44a2..a025e09 100644 --- a/im-web/src/components/account/AccountSwitchMenu.vue +++ b/im-web/src/components/account/AccountSwitchMenu.vue @@ -31,7 +31,7 @@
可切换账号 - +
- Read - Unread + + 已读 + 未读
diff --git a/im-web/src/store/chatStore.js b/im-web/src/store/chatStore.js index 91d0c75..bb719ae 100644 --- a/im-web/src/store/chatStore.js +++ b/im-web/src/store/chatStore.js @@ -34,6 +34,41 @@ export default defineStore('chatStore', { } }, actions: { + cleanOfflineChats() { + const friendStore = useFriendStore(); + const onlineFriendIds = friendStore.onlineFriendIds || []; + // 获取当前会话列表 + let chats = this.findChats(); + let removedCount = 0; + + // 从后往前遍历,避免删除时索引错乱 + for (let idx = chats.length - 1; idx >= 0; idx--) { + const chat = chats[idx]; + + // 只处理私聊会话 + if (chat.type === 'PRIVATE') { + const isOnline = onlineFriendIds.includes(chat.targetId); + + + if (!isOnline) { + // 标记为删除 + chat.delete = true; + chat.stored = false; + removedCount++; + } + } + } + + // 清理已删除的会话 + this.chats = this.chats.filter(chat => !chat.delete); + + // 保存到存储 + this.saveToStorage(true); + + console.log(`清理完成: 删除了 ${removedCount} 个离线会话,剩余 ${this.chats.length} 个会话`); + + return removedCount; + }, initChats(chatsData) { this.chats = []; this.privateMsgMaxId = chatsData.privateMsgMaxId || 0; diff --git a/im-web/src/store/friendStore.js b/im-web/src/store/friendStore.js index 46d29fe..6989675 100644 --- a/im-web/src/store/friendStore.js +++ b/im-web/src/store/friendStore.js @@ -50,19 +50,27 @@ export default defineStore('friendStore', { refreshOnlineStatus() { let userIds = this.friends.filter((f) => !f.deleted).map((f) => f.id); if (userIds.length == 0) { - return; + // 清除定时器 + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.refreshOnlineStatus(); + }, 30000); + return Promise.resolve(); // 返回 resolved Promise } - http({ + + // 返回 Promise,确保可以等待 + return http({ url: '/user/terminal/online?userIds=' + userIds.join(','), method: 'GET' }).then((onlineTerminals) => { this.setOnlineStatus(onlineTerminals); - }) - // 30s后重新拉取 - clearTimeout(this.timer); - this.timer = setTimeout(() => { - this.refreshOnlineStatus(); - }, 30000) + }).finally(() => { + // 30s后重新拉取 + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.refreshOnlineStatus(); + }, 30000); + }); }, setDnd(id, isDnd) { let friend = this.findFriend(id); @@ -80,20 +88,41 @@ export default defineStore('friendStore', { method: 'GET' }).then(async (friends) => { this.setFriends(friends); - this.refreshOnlineStatus(); + // 等待在线状态刷新完成 + await this.refreshOnlineStatus(); resolve(); }).catch(e => { reject(e); }) }); - } + }, }, getters: { + // 原有的 getters isFriend: (state) => (userId) => { return state.friends.filter((f) => !f.deleted).some((f) => f.id == userId); }, findFriend: (state) => (userId) => { return state.friends.find((f) => f.id == userId); + }, + + // 获取在线好友列表 + onlineFriends: (state) => { + return state.friends.filter(f => !f.deleted && f.online); + }, + + // 获取在线好友ID列表 + onlineFriendIds: (state) => { + return state.friends + .filter(f => !f.deleted && f.online) + .map(f => f.id); + }, + + // 获取离线好友ID列表 + offlineFriendIds: (state) => { + return state.friends + .filter(f => !f.deleted && !f.online) + .map(f => f.id); } } }); \ No newline at end of file diff --git a/im-web/src/view/Home.vue b/im-web/src/view/Home.vue index 651ad50..cf14feb 100644 --- a/im-web/src/view/Home.vue +++ b/im-web/src/view/Home.vue @@ -506,7 +506,11 @@ export default { }, onSwtichFullScreen() { - this.configStore.setFullScreen(!this.configStore.fullScreen); + // this.configStore.setFullScreen(!this.configStore.fullScreen); + const newState = !this.configStore.fullScreen; + this.configStore.setFullScreen(newState); + // 保存到本地存储 + localStorage.setItem('im_full_screen', newState); }, onExit() { @@ -583,6 +587,8 @@ export default { } }, mounted() { + const savedFullScreen = localStorage.getItem('im_full_screen') === 'true'; + this.configStore.setFullScreen(savedFullScreen); this.init(); }, unmounted() { diff --git a/im-web/src/view/Login.vue b/im-web/src/view/Login.vue index 47c1b31..0803d09 100644 --- a/im-web/src/view/Login.vue +++ b/im-web/src/view/Login.vue @@ -38,6 +38,9 @@