diff --git a/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java b/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java index b7e7e94..9a0f959 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java @@ -37,7 +37,7 @@ public class GroupMessageController { @GetMapping("/loadMessage") - @ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条") + @ApiOperation(value = "拉取消息(已废弃)", notes = "拉取消息,一次最多拉取100条") public Result> loadMessage(@RequestParam Long minId) { return ResultUtils.success(groupMessageService.loadMessage(minId)); } diff --git a/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java b/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java index 8c30239..758c86f 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java @@ -38,7 +38,7 @@ public class PrivateMessageController { @GetMapping("/loadMessage") - @ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条") + @ApiOperation(value = "拉取消息(已废弃)", notes = "拉取消息,一次最多拉取100条") public Result> loadMessage(@RequestParam Long minId) { return ResultUtils.success(privateMessageService.loadMessage(minId)); } diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java index 0d9c2e3..45f2126 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java @@ -237,8 +237,7 @@ public class PrivateMessageServiceImpl extends ServiceImpl sendMessage = new IMPrivateMessage<>(); sendMessage.setData(msgInfo); sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal())); - sendMessage.setRecvId(session.getUserId()); - sendMessage.setSendToSelf(false); + sendMessage.setSendToSelf(true); sendMessage.setSendResult(false); imClient.sendPrivateMessage(sendMessage); // 推送回执消息给对方,更新已读状态 diff --git a/im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java b/im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java index 78158c2..bad68c1 100644 --- a/im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java +++ b/im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java @@ -79,11 +79,10 @@ public final class SensitiveFilterUtil { */ @PostConstruct public void init() { - try ( - // 类加载器 - InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt"); - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - ) { + try { + // 类加载器 + InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt"); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String keyword; while ((keyword = reader.readLine()) != null) { // 添加到前缀树 diff --git a/im-ui/src/store/chatStore.js b/im-ui/src/store/chatStore.js index 90e62e6..9a240be 100644 --- a/im-ui/src/store/chatStore.js +++ b/im-ui/src/store/chatStore.js @@ -186,12 +186,7 @@ export default { } } } - if(insertPos == chat.messages.length){ - // 这种赋值效率最高 - chat.messages[insertPos]= msgInfo; - }else{ - chat.messages.splice(insertPos, 0, msgInfo); - } + chat.messages.splice(insertPos, 0, msgInfo); this.commit("saveToStorage"); }, updateMessage(state, msgInfo) { diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue index 5a3a7fe..06e58a0 100644 --- a/im-uniapp/App.vue +++ b/im-uniapp/App.vue @@ -63,12 +63,14 @@ }) }, pullPrivateOfflineMessage(minId) { + store.commit("loadingPrivateMsg",true) http({ url: "/message/private/pullOfflineMessage?minId=" + minId, method: 'get' }); }, pullGroupOfflineMessage(minId) { + store.commit("loadingGroupMsg",true) http({ url: "/message/group/pullOfflineMessage?minId=" + minId, method: 'get' @@ -195,7 +197,7 @@ }, loadFriendInfo(id) { return new Promise((resolve, reject) => { - let friend = store.state.friendStore.friends.find((f) => f.id == id); + let friend = store.getters.findFriend(id); if (friend) { resolve(friend); } else { diff --git a/im-uniapp/components/chat-item/chat-item.vue b/im-uniapp/components/chat-item/chat-item.vue index 8b8e2f5..aade43c 100644 --- a/im-uniapp/components/chat-item/chat-item.vue +++ b/im-uniapp/components/chat-item/chat-item.vue @@ -1,5 +1,5 @@ @@ -30,12 +32,12 @@ chatIdx: -1, items: [{ key: 'DELETE', - name: '删除', + name: '删除该聊天', icon: 'trash' }, { key: 'TOP', - name: '置顶', + name: '置顶该聊天', icon: 'arrow-up' } ] @@ -57,6 +59,7 @@ this.menu.show = false; }, onShowMenu(e, chatIdx) { + this.menu.chatIdx = chatIdx; uni.getSystemInfo({ success: (res) => { let touches = e.touches[0]; @@ -81,6 +84,10 @@ } }) }, + onCloseMenu() { + this.menu.chatIdx = -1; + this.menu.show = false; + }, removeChat(chatIdx) { this.$store.commit("removeChat", chatIdx); }, @@ -103,13 +110,30 @@ } }, computed: { + chatsPos() { + // 计算会话的顺序 + let chatsPos = []; + let chats = this.chatStore.chats; + chats.forEach((chat, idx) => { + chatsPos.push({ + idx: idx, + sendTime: chat.lastSendTime + }) + }) + chatsPos.sort((chatPos1, chatPos2) => { + return chatPos2.sendTime - chatPos1.sendTime; + }); + return chatsPos; + }, chatStore() { return this.$store.state.chatStore; }, unreadCount() { let count = 0; this.chatStore.chats.forEach(chat => { - count += chat.unreadCount; + if (!chat.delete) { + count += chat.unreadCount; + } }) return count; }, @@ -147,10 +171,16 @@ .chat-loading { display: block; + width: 100%; height: 100rpx; background: white; position: relative; color: blue; + + .loading-box { + position: relative; + + } } .scroll-bar { diff --git a/im-uniapp/pages/common/user-info.vue b/im-uniapp/pages/common/user-info.vue index ee71979..2dbeea8 100644 --- a/im-uniapp/pages/common/user-info.vue +++ b/im-uniapp/pages/common/user-info.vue @@ -55,8 +55,9 @@ headImage: this.userInfo.headImage, }; this.$store.commit("openChat", chat); + let chatIdx = this.$store.getters.findChatIdx(chat); uni.navigateTo({ - url:"/pages/chat/chat-box?chatIdx=0" + url:"/pages/chat/chat-box?chatIdx=" + chatIdx }) }, onAddFriend() { @@ -130,7 +131,7 @@ }, computed: { isFriend() { - return this.friendInfo != undefined; + return this.friendInfo&&!this.friendInfo.delete; }, friendInfo(){ let friends = this.$store.state.friendStore.friends; diff --git a/im-uniapp/pages/friend/friend-add.vue b/im-uniapp/pages/friend/friend-add.vue index 88c99e5..296c0a9 100644 --- a/im-uniapp/pages/friend/friend-add.vue +++ b/im-uniapp/pages/friend/friend-add.vue @@ -70,7 +70,7 @@ isFriend(userId) { let friends = this.$store.state.friendStore.friends; let friend = friends.find((f) => f.id == userId); - return friend != undefined; + return friend&&!friend.delete; } } } diff --git a/im-uniapp/pages/friend/friend-search.vue b/im-uniapp/pages/friend/friend-search.vue index 20aa91a..9e55379 100644 --- a/im-uniapp/pages/friend/friend-search.vue +++ b/im-uniapp/pages/friend/friend-search.vue @@ -5,8 +5,9 @@ - - + + diff --git a/im-uniapp/pages/friend/friend.vue b/im-uniapp/pages/friend/friend.vue index 6c0bcb1..f1a167e 100644 --- a/im-uniapp/pages/friend/friend.vue +++ b/im-uniapp/pages/friend/friend.vue @@ -8,13 +8,18 @@ - + 温馨提示:您现在还没有任何好友,快点击右上方'+'按钮添加好友吧~ - - + + + + + + + @@ -40,8 +45,12 @@ url: "/pages/friend/friend-add" }) } + }, + computed:{ + friends(){ + return this.$store.state.friendStore.friends; + } } - } diff --git a/im-uniapp/pages/group/group-info.vue b/im-uniapp/pages/group/group-info.vue index c91b160..60cff9b 100644 --- a/im-uniapp/pages/group/group-info.vue +++ b/im-uniapp/pages/group/group-info.vue @@ -86,8 +86,9 @@ headImage: this.group.headImage, }; this.$store.commit("openChat", chat); + let chatIdx = this.$store.getters.findChatIdx(chat); uni.navigateTo({ - url: "/pages/chat/chat-box?chatIdx=0" + url: "/pages/chat/chat-box?chatIdx=" + chatIdx }) }, onQuitGroup() { diff --git a/im-uniapp/pages/group/group-invite.vue b/im-uniapp/pages/group/group-invite.vue index 93596d8..f1a6980 100644 --- a/im-uniapp/pages/group/group-invite.vue +++ b/im-uniapp/pages/group/group-invite.vue @@ -84,6 +84,9 @@ this.friendItems = []; let friends = this.$store.state.friendStore.friends; friends.forEach((f => { + if(f.delete){ + return + } let item = { id: f.id, headImage: f.headImage, diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js index e14dae6..b1cdfc9 100644 --- a/im-uniapp/store/chatStore.js +++ b/im-uniapp/store/chatStore.js @@ -3,14 +3,20 @@ import { MESSAGE_STATUS } from '@/common/enums.js'; import userStore from './userStore'; +/* + uniapp性能优化: + 1.由于uniapp渲染消息性能非常拉胯,所以先把离线消息存储到cacheChats,等 + 待所有离线消息拉取完成后,再统一进行渲染 + 2.在vuex中对数组进行unshift,splice特别卡,所以删除会话、会话置顶、删 + 除消息等操作进行优化,不通过unshift,splice实现,改造方案如下: + 删除会话: 通过delete标志判断是否删除 + 删除消息:通过delete标志判断是否删除 + 会话置顶:通过lastSendTime排序确定会话顺序 +*/ -/* uniapp渲染消息性能非常拉胯,所以这里先把离线消息存储到cacheChats, - 等待所有离线消息拉取完成后,再统一进行渲染 */ let cacheChats = []; - export default { state: { - activeIndex: -1, chats: [], privateMsgMaxId: 0, groupMsgMaxId: 0, @@ -20,14 +26,19 @@ export default { mutations: { initChats(state, chatsData) { - // 暂存至缓冲区 - cacheChats = JSON.parse(JSON.stringify(chatsData.chats)) - // 只取前10条数据做做样子,一切都为了加快初始化时间 - let size = Math.min(chatsData.chats.length,10); - for (let i = 0; i < size; i++) { - let chat = chatsData.chats[i]; - chat.messages = []; - state.chats[i] = chat; + cacheChats = []; + for (let chat of chatsData.chats) { + // 已删除的会话直接丢弃 + if (chat.delete) { + continue; + } + // 暂存至缓冲区 + cacheChats.push(JSON.parse(JSON.stringify(chat))); + // 加载期间显示只前15个会话做做样子,一切都为了加快初始化时间 + if (state.chats.length < 15) { + chat.messages = []; + state.chats.push(chat); + } } state.privateMsgMaxId = chatsData.privateMsgMaxId || 0; state.groupMsgMaxId = chatsData.groupMsgMaxId || 0; @@ -48,6 +59,7 @@ export default { if (chats[idx].type == chatInfo.type && chats[idx].targetId === chatInfo.targetId) { chat = chats[idx]; + chat.delete = false; // 放置头部 this.commit("moveTop", idx) break; @@ -65,15 +77,15 @@ export default { unreadCount: 0, messages: [], atMe: false, - atAll: false + atAll: false, + delete: false }; - chats.unshift(chat); + chats.push(chat); + this.commit("moveTop", chats.length - 1) } - this.commit("saveToStorage"); }, activeChat(state, idx) { let chats = this.getters.findChats(); - state.activeIndex = idx; if (idx >= 0) { chats[idx].unreadCount = 0; } @@ -109,7 +121,7 @@ export default { }, removeChat(state, idx) { let chats = this.getters.findChats(); - chats.splice(idx, 1); + chats[idx].delete = true; this.commit("saveToStorage"); }, removePrivateChat(state, userId) { @@ -122,17 +134,11 @@ export default { } }, moveTop(state, idx) { - // 加载中不移动,防止卡顿 - if (this.getters.isLoading()) { - return; - } let chats = this.getters.findChats(); - if (idx > 0) { - let chat = chats[idx]; - chats.splice(idx, 1); - chats.unshift(chat); - this.commit("saveToStorage"); - } + let chat = chats[idx]; + // 最新的时间会显示在顶部 + chat.lastSendTime = new Date().getTime(); + this.commit("saveToStorage"); }, insertMessage(state, msgInfo) { // 获取对方id或群id @@ -233,13 +239,13 @@ export default { for (let idx in chat.messages) { // 已经发送成功的,根据id删除 if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { - chat.messages.splice(idx, 1); + chat.messages[idx].delete = true; break; } // 正在发送中的消息可能没有id,根据发送时间删除 if (msgInfo.selfSend && chat.messages[idx].selfSend && chat.messages[idx].sendTime == msgInfo.sendTime) { - chat.messages.splice(idx, 1); + chat.messages[idx].delete = true; break; } } @@ -271,24 +277,23 @@ export default { }, loadingPrivateMsg(state, loadding) { state.loadingPrivateMsg = loadding; - if (!state.loadingPrivateMsg && !state.loadingGroupMsg) { + if (!this.getters.isLoading()) { this.commit("refreshChats") } }, loadingGroupMsg(state, loadding) { state.loadingGroupMsg = loadding; - if (!state.loadingPrivateMsg && !state.loadingGroupMsg) { + if (!this.getters.isLoading()) { this.commit("refreshChats") } }, refreshChats(state) { - // 排序 cacheChats.sort((chat1, chat2) => { return chat2.lastSendTime - chat1.lastSendTime; }); - // 将消息一次性装载回来,只显示前30个会话,多了卡的不行 - state.chats = JSON.parse(JSON.stringify(cacheChats.slice(0,30))) + // 将消息一次性装载回来 + state.chats = cacheChats; this.commit("saveToStorage"); }, saveToStorage(state) { @@ -305,12 +310,12 @@ export default { } uni.setStorage({ key: key, - data: chatsData + data: chatsData , }) }, clear(state) { + cacheChats = []; state.chats = []; - state.activeIndex = -1; state.privateMsgMaxId = 0; state.groupMsgMaxId = 0; state.loadingPrivateMsg = false; diff --git a/im-uniapp/store/friendStore.js b/im-uniapp/store/friendStore.js index b13c08d..cc827d5 100644 --- a/im-uniapp/store/friendStore.js +++ b/im-uniapp/store/friendStore.js @@ -13,7 +13,7 @@ export default { }, updateFriend(state, friend) { state.friends.forEach((f, index) => { - if (f.id == friend.id) { + if (!f.delete && f.id == friend.id) { // 拷贝属性 let online = state.friends[index].online; Object.assign(state.friends[index], friend); @@ -22,40 +22,24 @@ export default { }) }, removeFriend(state, id) { - state.friends.forEach((f, idx) => { - if (f.id == id) { - state.friends.splice(idx, 1) - } - }); + let friend = this.getters.findFriend(id); + if(friend){ + friend.delete = true; + } }, addFriend(state, friend) { - state.friends.push(friend); + let f = this.getters.findFriend(friend.id); + if(f){ + Object.assign(f, friend); + f.delete = false; + }else{ + state.friends.push(friend); + } }, - - setOnlineStatus(state, onlineTerminals) { + setOnlineStatus(state, onlineUsers) { state.friends.forEach((f) => { - let userTerminal = onlineTerminals.find((o) => f.id == o.userId); - if (userTerminal) { - f.online = true; - f.onlineTerminals = userTerminal.terminals; - f.onlineWeb = userTerminal.terminals.indexOf(TERMINAL_TYPE.WEB) >= 0 - f.onlineApp = userTerminal.terminals.indexOf(TERMINAL_TYPE.APP) >= 0 - } else { - f.online = false; - f.onlineTerminals = []; - f.onlineWeb = false; - f.onlineApp = false; - } - }); - - state.friends.sort((f1, f2) => { - if (f1.online && !f2.online) { - return -1; - } - if (f2.online && !f1.online) { - return 1; - } - return 0; + let onlineUser = onlineUsers.find((o) => f.id == o.userId); + f.online = !!onlineUser }); }, refreshOnlineStatus(state) { @@ -67,8 +51,8 @@ export default { http({ url: '/user/terminal/online?userIds=' + userIds.join(','), method: 'GET' - }).then((onlineTerminals) => { - this.commit("setOnlineStatus", onlineTerminals); + }).then((onlineUsers) => { + this.commit("setOnlineStatus", onlineUsers); }) } // 30s后重新拉取 @@ -98,5 +82,10 @@ export default { }) }); } + }, + getters:{ + findFriend: (state) => (id) => { + return state.friends.find((f)=>f.id==id); + } } } \ No newline at end of file