diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java index 5aa5857..f62e80f 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java @@ -14,6 +14,7 @@ import com.bx.imcommon.enums.IMTerminalType; import com.bx.imcommon.model.IMGroupMessage; import com.bx.imcommon.model.IMUserInfo; import com.bx.imcommon.util.CommaTextUtils; +import com.bx.imcommon.util.ThreadPoolExecutorFactory; import com.bx.implatform.contant.Constant; import com.bx.implatform.contant.RedisKey; import com.bx.implatform.dto.GroupMessageDTO; @@ -40,19 +41,21 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor -public class GroupMessageServiceImpl extends ServiceImpl implements - GroupMessageService { +public class GroupMessageServiceImpl extends ServiceImpl + implements GroupMessageService { private final GroupService groupService; private final GroupMemberService groupMemberService; private final RedisTemplate redisTemplate; private final IMClient imClient; private final SensitiveFilterUtil sensitiveFilterUtil; + private static final ScheduledThreadPoolExecutor EXECUTOR = ThreadPoolExecutorFactory.getThreadPoolExecutor(); @Override public GroupMessageVO sendMessage(GroupMessageDTO dto) { @@ -67,7 +70,8 @@ public class GroupMessageServiceImpl extends ServiceImpl userIds = groupMemberService.findUserIdsByGroupId(group.getId()); if (dto.getReceipt() && userIds.size() > Constant.MAX_LARGE_GROUP_MEMBER) { // 大群的回执消息过于消耗资源,不允许发送 - throw new GlobalException(String.format("当前群聊大于%s人,不支持发送回执消息", Constant.MAX_LARGE_GROUP_MEMBER)); + throw new GlobalException( + String.format("当前群聊大于%s人,不支持发送回执消息", Constant.MAX_LARGE_GROUP_MEMBER)); } // 不用发给自己 userIds = userIds.stream().filter(id -> !session.getUserId().equals(id)).collect(Collectors.toList()); @@ -78,11 +82,10 @@ public class GroupMessageServiceImpl extends ServiceImpl members = groupMemberService.findByUserId(session.getUserId()); Map groupMemberMap = CollStreamUtil.toIdentityMap(members, GroupMember::getGroupId); Set groupIds = groupMemberMap.keySet(); - if(CollectionUtil.isEmpty(groupIds)){ + if (CollectionUtil.isEmpty(groupIds)) { // 关闭加载中标志 - this.sendLoadingMessage(false); + this.sendLoadingMessage(false, session); return; } - // 开启加载中标志 - this.sendLoadingMessage(true); - // 只能拉取最近3个月的,最多拉取3000条 + + // 只能拉取最近3个月的,移动端只拉最近一个月 int months = session.getTerminal().equals(IMTerminalType.APP.code()) ? 1 : 3; Date minDate = DateUtils.addMonths(new Date(), -months); LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); - wrapper.gt(GroupMessage::getId, minId) - .gt(GroupMessage::getSendTime, minDate) - .in(GroupMessage::getGroupId, groupIds) - .orderByAsc(GroupMessage::getId); + wrapper.gt(GroupMessage::getId, minId).gt(GroupMessage::getSendTime, minDate) + .in(GroupMessage::getGroupId, groupIds).orderByAsc(GroupMessage::getId); List messages = this.list(wrapper); // 通过群聊对消息进行分组 - Map> messageGroupMap = messages.stream().collect(Collectors.groupingBy(GroupMessage::getGroupId)); + Map> messageGroupMap = + messages.stream().collect(Collectors.groupingBy(GroupMessage::getGroupId)); // 退群前的消息 List quitMembers = groupMemberService.findQuitInMonth(session.getUserId()); - for(GroupMember quitMember: quitMembers){ + for (GroupMember quitMember : quitMembers) { wrapper = Wrappers.lambdaQuery(); - wrapper.gt(GroupMessage::getId, minId) - .between(GroupMessage::getSendTime, minDate,quitMember.getQuitTime()) + wrapper.gt(GroupMessage::getId, minId).between(GroupMessage::getSendTime, minDate, quitMember.getQuitTime()) .eq(GroupMessage::getGroupId, quitMember.getGroupId()) - .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()) - .orderByAsc(GroupMessage::getId); + .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()).orderByAsc(GroupMessage::getId); List groupMessages = this.list(wrapper); - messageGroupMap.put(quitMember.getGroupId(),groupMessages); - groupMemberMap.put(quitMember.getGroupId(),quitMember); + messageGroupMap.put(quitMember.getGroupId(), groupMessages); + groupMemberMap.put(quitMember.getGroupId(), quitMember); } - // 推送消息 - AtomicInteger sendCount = new AtomicInteger(); - messageGroupMap.forEach((groupId, groupMessages) -> { - // 填充消息状态 - String key = StrUtil.join(":", RedisKey.IM_GROUP_READED_POSITION, groupId); - Object o = redisTemplate.opsForHash().get(key, session.getUserId().toString()); - long readedMaxId = Objects.isNull(o) ? -1 : Long.parseLong(o.toString()); - Map maxIdMap = null; - for(GroupMessage m:groupMessages){ - // 排除加群之前的消息 - GroupMember member = groupMemberMap.get(m.getGroupId()); - if(DateUtil.compare(member.getCreatedTime(), m.getSendTime()) > 0){ - continue; + EXECUTOR.execute(() -> { + // 开启加载中标志 + this.sendLoadingMessage(true, session); + // 推送消息 + AtomicInteger sendCount = new AtomicInteger(); + messageGroupMap.forEach((groupId, groupMessages) -> { + // 第一次拉取时,一个群最多推送1w条消息,防止前端接收能力溢出导致卡顿 + List sendMessages = groupMessages; + if (minId <= 0 && groupMessages.size() > 10000) { + sendMessages = groupMessages.subList(groupMessages.size() - 10000, groupMessages.size()); } - // 排除不需要接收的消息 - List recvIds = CommaTextUtils.asList(m.getRecvIds()); - if(!recvIds.isEmpty() && !recvIds.contains(session.getUserId().toString())){ - continue; - } - // 组装vo - GroupMessageVO vo = BeanUtils.copyProperties(m, GroupMessageVO.class); - // 被@用户列表 - List atIds = CommaTextUtils.asList(m.getAtUserIds()); - vo.setAtUserIds(atIds.stream().map(Long::parseLong).collect(Collectors.toList())); - // 填充状态 - vo.setStatus(readedMaxId >= m.getId() ? MessageStatus.READED.code() : MessageStatus.UNSEND.code()); - // 针对回执消息填充已读人数 - if(m.getReceipt()){ - if(Objects.isNull(maxIdMap)) { - maxIdMap = redisTemplate.opsForHash().entries(key); + // 填充消息状态 + String key = StrUtil.join(":", RedisKey.IM_GROUP_READED_POSITION, groupId); + Object o = redisTemplate.opsForHash().get(key, session.getUserId().toString()); + long readedMaxId = Objects.isNull(o) ? -1 : Long.parseLong(o.toString()); + Map maxIdMap = null; + for (GroupMessage m : sendMessages) { + // 排除加群之前的消息 + GroupMember member = groupMemberMap.get(m.getGroupId()); + if (DateUtil.compare(member.getCreatedTime(), m.getSendTime()) > 0) { + continue; + } + // 排除不需要接收的消息 + List recvIds = CommaTextUtils.asList(m.getRecvIds()); + if (!recvIds.isEmpty() && !recvIds.contains(session.getUserId().toString())) { + continue; + } + // 组装vo + GroupMessageVO vo = BeanUtils.copyProperties(m, GroupMessageVO.class); + // 被@用户列表 + List atIds = CommaTextUtils.asList(m.getAtUserIds()); + vo.setAtUserIds(atIds.stream().map(Long::parseLong).collect(Collectors.toList())); + // 填充状态 + vo.setStatus(readedMaxId >= m.getId() ? MessageStatus.READED.code() : MessageStatus.UNSEND.code()); + // 针对回执消息填充已读人数 + if (m.getReceipt()) { + if (Objects.isNull(maxIdMap)) { + maxIdMap = redisTemplate.opsForHash().entries(key); + } + int count = getReadedUserIds(maxIdMap, m.getId(), m.getSendId()).size(); + vo.setReadedCount(count); } - int count = getReadedUserIds(maxIdMap, m.getId(),m.getSendId()).size(); - vo.setReadedCount(count); + // 推送 + IMGroupMessage sendMessage = new IMGroupMessage<>(); + sendMessage.setSender(new IMUserInfo(m.getSendId(), IMTerminalType.WEB.code())); + sendMessage.setRecvIds(Arrays.asList(session.getUserId())); + sendMessage.setRecvTerminals(Arrays.asList(session.getTerminal())); + sendMessage.setSendResult(false); + sendMessage.setSendToSelf(false); + sendMessage.setData(vo); + imClient.sendGroupMessage(sendMessage); + sendCount.getAndIncrement(); } - // 推送 - IMGroupMessage sendMessage = new IMGroupMessage<>(); - sendMessage.setSender(new IMUserInfo(m.getSendId(), IMTerminalType.WEB.code())); - sendMessage.setRecvIds(Arrays.asList(session.getUserId())); - sendMessage.setRecvTerminals(Arrays.asList(session.getTerminal())); - sendMessage.setSendResult(false); - sendMessage.setSendToSelf(false); - sendMessage.setData(vo); - imClient.sendGroupMessage(sendMessage); - sendCount.getAndIncrement(); - } + }); + // 关闭加载中标志 + this.sendLoadingMessage(false, session); + log.info("拉取离线群聊消息,用户id:{},数量:{}", session.getUserId(), sendCount.get()); }); - // 关闭加载中标志 - this.sendLoadingMessage(false); - log.info("拉取离线群聊消息,用户id:{},数量:{}",session.getUserId(),sendCount.get()); } @Override @@ -238,10 +245,8 @@ public class GroupMessageServiceImpl extends ServiceImpl wrapper = Wrappers.lambdaQuery(); - wrapper.eq(GroupMessage::getGroupId, groupId) - .orderByDesc(GroupMessage::getId) - .last("limit 1") - .select(GroupMessage::getId); + wrapper.eq(GroupMessage::getGroupId, groupId).orderByDesc(GroupMessage::getId).last("limit 1") + .select(GroupMessage::getId); GroupMessage message = this.getOne(wrapper); if (Objects.isNull(message)) { return; @@ -276,9 +281,10 @@ public class GroupMessageServiceImpl extends ServiceImpl userIds = groupMemberService.findUserIdsByGroupId(groupId); Map maxIdMap = redisTemplate.opsForHash().entries(key); for (GroupMessage receiptMessage : receiptMessages) { - Integer readedCount = getReadedUserIds(maxIdMap, receiptMessage.getId(),receiptMessage.getSendId()).size(); + Integer readedCount = + getReadedUserIds(maxIdMap, receiptMessage.getId(), receiptMessage.getSendId()).size(); // 如果所有人都已读,记录回执消息完成标记 - if(readedCount >= userIds.size() - 1){ + if (readedCount >= userIds.size() - 1) { receiptMessage.setReceiptOk(true); this.updateById(receiptMessage); } @@ -311,12 +317,12 @@ public class GroupMessageServiceImpl extends ServiceImpl maxIdMap = redisTemplate.opsForHash().entries(key); // 返回已读用户的id集合 - return getReadedUserIds(maxIdMap, message.getId(),message.getSendId()); + return getReadedUserIds(maxIdMap, message.getId(), message.getSendId()); } @Override @@ -333,10 +339,11 @@ public class GroupMessageServiceImpl extends ServiceImpl wrapper = new QueryWrapper<>(); wrapper.lambda().eq(GroupMessage::getGroupId, groupId).gt(GroupMessage::getSendTime, member.getCreatedTime()) - .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()).orderByDesc(GroupMessage::getId).last("limit " + stIdx + "," + size); + .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()).orderByDesc(GroupMessage::getId) + .last("limit " + stIdx + "," + size); List messages = this.list(wrapper); List messageInfos = - messages.stream().map(m -> BeanUtils.copyProperties(m, GroupMessageVO.class)).collect(Collectors.toList()); + messages.stream().map(m -> BeanUtils.copyProperties(m, GroupMessageVO.class)).collect(Collectors.toList()); log.info("拉取群聊记录,用户id:{},群聊id:{},数量:{}", userId, groupId, messageInfos.size()); return messageInfos; } @@ -354,8 +361,7 @@ public class GroupMessageServiceImpl extends ServiceImpl wrapper = Wrappers.lambdaQuery(); // 只能拉取最近3个月的消息,移动端只拉取一个月消息 @@ -148,21 +149,25 @@ public class PrivateMessageServiceImpl extends ServiceImpl messages = this.list(wrapper); - // 推送消息 - for (PrivateMessage m : messages) { - PrivateMessageVO vo = BeanUtils.copyProperties(m, PrivateMessageVO.class); - IMPrivateMessage sendMessage = new IMPrivateMessage<>(); - sendMessage.setSender(new IMUserInfo(m.getSendId(), IMTerminalType.WEB.code())); - sendMessage.setRecvId(session.getUserId()); - sendMessage.setRecvTerminals(List.of(session.getTerminal())); - sendMessage.setSendToSelf(false); - sendMessage.setData(vo); - sendMessage.setSendResult(true); - imClient.sendPrivateMessage(sendMessage); - } - // 关闭加载中标志 - this.sendLoadingMessage(false); - log.info("拉取私聊消息,用户id:{},数量:{}", session.getUserId(), messages.size()); + // 异步推送消息 + EXECUTOR.execute(() -> { + // 开启加载中标志 + this.sendLoadingMessage(true, session); + for (PrivateMessage m : messages) { + PrivateMessageVO vo = BeanUtils.copyProperties(m, PrivateMessageVO.class); + IMPrivateMessage sendMessage = new IMPrivateMessage<>(); + sendMessage.setSender(new IMUserInfo(m.getSendId(), IMTerminalType.WEB.code())); + sendMessage.setRecvId(session.getUserId()); + sendMessage.setRecvTerminals(List.of(session.getTerminal())); + sendMessage.setSendToSelf(false); + sendMessage.setData(vo); + sendMessage.setSendResult(true); + imClient.sendPrivateMessage(sendMessage); + } + // 关闭加载中标志 + this.sendLoadingMessage(false, session); + log.info("拉取私聊消息,用户id:{},数量:{}", session.getUserId(), messages.size()); + }); } @Transactional(rollbackFor = Exception.class) @@ -215,8 +220,7 @@ public class PrivateMessageServiceImpl extends ServiceImpl 0 && chat.messages.length > UNI_APP.MAX_MESSAGE_SIZE) { - chat.messages = chat.messages.slice(0, UNI_APP.MAX_MESSAGE_SIZE); - } // 暂存至缓冲区 cacheChats.push(JSON.parse(JSON.stringify(chat))); // 加载期间显示只前15个会话做做样子,一切都为了加快初始化时间 @@ -64,6 +59,7 @@ export default defineStore('chatStore', { lastContent: "", lastSendTime: new Date().getTime(), unreadCount: 0, + hotMinIdx: 0, messages: [], atMe: false, atAll: false, @@ -244,24 +240,28 @@ export default defineStore('chatStore', { deleteMessage(msgInfo, chatInfo) { // 获取对方id或群id let chat = this.findChat(chatInfo); + let isColdMessage = false; for (let idx in chat.messages) { // 已经发送成功的,根据id删除 if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { chat.messages.splice(idx, 1); + isColdMessage = idx < chat.hotMinIdx; break; } // 正在发送中的消息可能没有id,只有临时id if (chat.messages[idx].tmpId && chat.messages[idx].tmpId == msgInfo.tmpId) { chat.messages.splice(idx, 1); + isColdMessage = idx < chat.hotMinIdx; break; } } chat.stored = false; - this.saveToStorage(); + this.saveToStorage(isColdMessage); }, recallMessage(msgInfo, chatInfo) { let chat = this.findChat(chatInfo); if (!chat) return; + let isColdMessage = false; // 要撤回的消息id let id = msgInfo.content; let name = msgInfo.selfSend ? '你' : chat.type == 'PRIVATE' ? '对方' : msgInfo.sendNickName; @@ -279,6 +279,7 @@ export default defineStore('chatStore', { if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED) { chat.unreadCount++; } + isColdMessage = idx < chat.hotMinIdx; } // 被引用的消息也要撤回 if (m.quoteMessage && m.quoteMessage.id == msgInfo.id) { @@ -288,7 +289,7 @@ export default defineStore('chatStore', { } } chat.stored = false; - this.saveToStorage(); + this.saveToStorage(isColdMessage); }, updateChatFromFriend(friend) { let chat = this.findChatByFriend(friend.id) @@ -336,20 +337,31 @@ export default defineStore('chatStore', { } }, refreshChats() { - if (!cacheChats) { - return; - } + if (!cacheChats) return; // 排序 - cacheChats.sort((chat1, chat2) => { - return chat2.lastSendTime - chat1.lastSendTime; - }); + cacheChats.sort((chat1, chat2) => chat2.lastSendTime - chat1.lastSendTime); + // #ifndef APP-PLUS + /** + * 由于h5和小程序的stroge只有5m,大约只能存储2w条消息, + * 所以这里每个会话只保留1000条消息,防止溢出 + */ + cacheChats.forEach(chat =>{ + if(chat.messages.length > 1000){ + let idx = chat.messages.length - 1000; + chat.messages = chat.messages.slice(idx); + } + }) + // #endif + // 记录热数据索引位置 + cacheChats.forEach(chat => chat.hotMinIdx = chat.messages.length); // 将消息一次性装载回来 this.chats = cacheChats; - // 清空缓存,不再使用 + // 清空缓存,不再使用 cacheChats = null; - this.saveToStorage(); + // 消息持久化 + this.saveToStorage(true); }, - saveToStorage(state) { + saveToStorage(withColdMessage) { // 加载中不保存,防止卡顿 if (this.isLoading()) { return; @@ -362,12 +374,27 @@ export default defineStore('chatStore', { this.chats.forEach((chat) => { let chatKey = `${key}-${chat.type}-${chat.targetId}` if (!chat.stored) { + chat.stored = true; if (chat.delete) { uni.removeStorageSync(chatKey); } else { - uni.setStorageSync(chatKey, chat); + // 存储冷数据 + if (withColdMessage) { + let coldChat = Object.assign({}, chat); + coldChat.messages = chat.messages.slice(0, chat.hotMinIdx); + uni.setStorageSync(chatKey, coldChat) + } + // 存储热消息 + let hotKey = chatKey + '-hot'; + if (chat.messages.length > chat.hotMinIdx) { + let hotChat = Object.assign({}, chat); + hotChat.messages = chat.messages.slice(chat.hotMinIdx) + uni.setStorageSync(hotKey, hotChat); + console.log("热数据:",hotChat.messages.length) + } else { + uni.removeStorageSync(hotKey); + } } - chat.stored = true; } if (!chat.delete) { chatKeys.push(chatKey); @@ -391,20 +418,26 @@ export default defineStore('chatStore', { this.loadingPrivateMsg = false; this.loadingGroupMsg = false; }, - loadChat(context) { + loadChat() { 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) { - let time = new Date().getTime(); chatsData.chats = []; chatsData.chatKeys.forEach(key => { - let chat = uni.getStorageSync(key); - if (chat) { - chatsData.chats.push(chat); + let coldChat = uni.getStorageSync(key); + let hotChat = uni.getStorageSync(key + '-hot'); + if (!coldChat && hotChat) { + return; + } + // 冷热消息合并 + let chat = Object.assign({}, coldChat, hotChat); + if (hotChat && coldChat) { + chat.messages = coldChat.messages.concat(hotChat.messages) } + chatsData.chats.push(chat); }) } this.initChats(chatsData); diff --git a/im-web/package.json b/im-web/package.json index 50fcc26..019c50b 100644 --- a/im-web/package.json +++ b/im-web/package.json @@ -19,8 +19,7 @@ "vue": "2.7.16", "vue-axios": "3.5.2", "vue-router": "3.6.5", - "vuex": "3.6.2", - "vuex-persist": "3.1.3" + "pinia": "^2.1.7" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.12", @@ -61,4 +60,4 @@ "last 2 versions", "not dead" ] -} +} \ No newline at end of file diff --git a/im-web/src/components/chat/ChatAtBox.vue b/im-web/src/components/chat/ChatAtBox.vue index 747f0a4..1b55965 100644 --- a/im-web/src/components/chat/ChatAtBox.vue +++ b/im-web/src/components/chat/ChatAtBox.vue @@ -42,7 +42,7 @@ export default { init() { this.$refs.scrollBox.wrap.scrollTop = 0; this.showMembers = []; - let userId = this.$store.state.userStore.userInfo.id; + let userId = this.userStore.userInfo.id; let name = "全体成员"; if (this.ownerId == userId && name.startsWith(this.searchText)) { this.showMembers.push({ @@ -108,7 +108,7 @@ export default { }, computed: { isOwner() { - return this.$store.state.userStore.userInfo.id == this.ownerId; + return this.userStore.userInfo.id == this.ownerId; } }, watch: { diff --git a/im-web/src/components/chat/ChatBox.vue b/im-web/src/components/chat/ChatBox.vue index 55788db..b79d67b 100644 --- a/im-web/src/components/chat/ChatBox.vue +++ b/im-web/src/components/chat/ChatBox.vue @@ -10,16 +10,13 @@
-
    -
  • - - -
  • -
+
+ + +
@@ -140,8 +137,8 @@ export default { }, methods: { moveChatToTop() { - let chatIdx = this.$store.getters.findChatIdx(this.chat); - this.$store.commit("moveTop", chatIdx); + let chatIdx = this.chatStore.findChatIdx(this.chat); + this.chatStore.moveTop(chatIdx); }, closeRefBox() { this.$refs.emoBox.close(); @@ -166,13 +163,13 @@ export default { msgInfo.loadStatus = 'ok'; msgInfo.id = m.id; this.isReceipt = false; - this.$store.commit("insertMessage", [msgInfo, file.chat]); + this.chatStore.insertMessage(msgInfo, file.chat); }) }, onImageFail(e, file) { let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); msgInfo.loadStatus = 'fail'; - this.$store.commit("insertMessage", [msgInfo, file.chat]); + this.chatStore.insertMessage(msgInfo, file.chat); }, onImageBefore(file) { // 被封禁提示 @@ -201,7 +198,7 @@ export default { // 填充对方id this.fillTargetId(msgInfo, this.chat.targetId); // 插入消息 - this.$store.commit("insertMessage", [msgInfo, this.chat]); + this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); // 滚动到底部 @@ -224,13 +221,13 @@ export default { msgInfo.id = m.id; this.isReceipt = false; this.refreshPlaceHolder(); - this.$store.commit("insertMessage", [msgInfo, file.chat]); + this.chatStore.insertMessage(msgInfo, file.chat); }) }, onFileFail(e, file) { let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); msgInfo.loadStatus = 'fail'; - this.$store.commit("insertMessage", [msgInfo, file.chat]); + this.chatStore.insertMessage(msgInfo, file.chat); }, onFileBefore(file) { // 被封禁提示 @@ -259,7 +256,7 @@ export default { // 填充对方id this.fillTargetId(msgInfo, this.chat.targetId); // 插入消息 - this.$store.commit("insertMessage", [msgInfo, this.chat]); + this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); // 滚动到底部 @@ -330,7 +327,7 @@ export default { } // 邀请成员发起通话 let ids = [this.mine.id]; - let maxChannel = this.$store.state.configStore.webrtc.maxChannel; + let maxChannel = this.configStore.webrtc.maxChannel; this.$refs.rtcSel.open(maxChannel, ids, ids, []); }, onInviteOk(members) { @@ -375,9 +372,9 @@ export default { } // 填充对方id this.fillTargetId(msgInfo, this.chat.targetId); - this.sendMessageRequest(msgInfo).then((m) => { + this.sendMessageRequest(msgInfo).then(m => { m.selfSend = true; - this.$store.commit("insertMessage", [m, this.chat]); + this.chatStore.insertMessage(m, this.chat); // 会话置顶 this.moveChatToTop(); // 保持输入框焦点 @@ -462,7 +459,7 @@ export default { this.lockMessage = true; this.sendMessageRequest(msgInfo).then((m) => { m.selfSend = true; - this.$store.commit("insertMessage", [m, this.chat]); + this.chatStore.insertMessage(m, this.chat); // 会话置顶 this.moveChatToTop(); }).finally(() => { @@ -487,7 +484,7 @@ export default { cancelButtonText: '取消', type: 'warning' }).then(() => { - this.$store.commit("deleteMessage", [msgInfo, this.chat]); + this.chatStore.deleteMessage(msgInfo, this.chat); }); }, recallMessage(msgInfo) { @@ -503,7 +500,7 @@ export default { }).then((m) => { this.$message.success("消息已撤回"); m.selfSend = true; - this.$store.commit("recallMessage", [m, this.chat]); + this.chatStore.recallMessage(m, this.chat); }) }); }, @@ -511,7 +508,7 @@ export default { if (this.chat.unreadCount == 0) { return; } - this.$store.commit("resetUnreadCount", this.chat) + this.chatStore.resetUnreadCount(this.chat) if (this.chat.type == "GROUP") { var url = `/message/group/readed?groupId=${this.chat.targetId}` } else { @@ -520,14 +517,14 @@ export default { this.$http({ url: url, method: 'put' - }).then(() => {}) + }).then(() => { }) }, loadReaded(fId) { this.$http({ url: `/message/private/maxReadedId?friendId=${fId}`, method: 'get' }).then((id) => { - this.$store.commit("readedMessage", { + this.chatStore.readedMessage({ friendId: fId, maxId: id }); @@ -539,8 +536,8 @@ export default { method: 'get' }).then((group) => { this.group = group; - this.$store.commit("updateChatFromGroup", group); - this.$store.commit("updateGroup", group); + this.chatStore.updateChatFromGroup(group); + this.groupStore.updateGroup(group); }); this.$http({ @@ -557,10 +554,10 @@ export default { friend.headImage = this.userInfo.headImageThumb; friend.nickName = this.userInfo.nickName; friend.showNickName = friend.remarkNickName ? friend.remarkNickName : friend.nickName; - this.$store.commit("updateChatFromFriend", friend); - this.$store.commit("updateFriend", friend); + this.chatStore.updateChatFromFriend(friend); + this.friendStore.updateFriend(friend); } else { - this.$store.commit("updateChatFromUser", this.userInfo); + this.chatStore.updateChatFromUser(this.userInfo); } }, loadFriend(friendId) { @@ -653,7 +650,7 @@ export default { msgInfo.groupId = this.group.id; msgInfo.content = "本群聊已被管理员封禁,原因:" + this.group.reason } - this.$store.commit("insertMessage", [msgInfo, this.chat]); + this.chatStore.insertMessage(msgInfo, this.chat); }, generateId() { // 生成临时id @@ -662,13 +659,13 @@ export default { }, computed: { mine() { - return this.$store.state.userStore.userInfo; + return this.userStore.userInfo; }, isFriend() { - return this.$store.getters.isFriend(this.userInfo.id); + return this.friendStore.isFriend(this.userInfo.id); }, friend() { - return this.$store.getters.findFriend(this.userInfo.id) + return this.friendStore.findFriend(this.userInfo.id) }, title() { let title = this.chat.showName; @@ -684,6 +681,10 @@ export default { unreadCount() { return this.chat.unreadCount; }, + showMessages() { + console.log("this.chat.messages.slice(this.showMinIdx):",this.chat.messages.slice(this.showMinIdx)) + return this.chat.messages.slice(this.showMinIdx) + }, messageSize() { if (!this.chat || !this.chat.messages) { return 0; @@ -708,7 +709,7 @@ export default { chat: { handler(newChat, oldChat) { if (newChat.targetId > 0 && (!oldChat || newChat.type != oldChat.type || - newChat.targetId != oldChat.targetId)) { + newChat.targetId != oldChat.targetId)) { this.userInfo = {} this.group = {}; this.groupMembers = []; diff --git a/im-web/src/components/chat/ChatGroupReaded.vue b/im-web/src/components/chat/ChatGroupReaded.vue index dfe5dce..c35b96f 100644 --- a/im-web/src/components/chat/ChatGroupReaded.vue +++ b/im-web/src/components/chat/ChatGroupReaded.vue @@ -115,7 +115,7 @@ export default { type: 'GROUP', targetId: this.msgInfo.groupId } - this.$store.commit("updateMessage", [msgInfo, chatInfo]) + this.chatStore.updateMessage(msgInfo, chatInfo) }) } } diff --git a/im-web/src/components/chat/ChatGroupSide.vue b/im-web/src/components/chat/ChatGroupSide.vue index 9024315..5f4dd85 100644 --- a/im-web/src/components/chat/ChatGroupSide.vue +++ b/im-web/src/components/chat/ChatGroupSide.vue @@ -124,7 +124,7 @@ export default { data: vo }).then((group) => { this.editing = !this.editing - this.$store.commit("updateGroup", group); + this.groupStore.updateGroup(group); this.$emit('reload'); this.$message.success("修改成功"); }) @@ -139,8 +139,8 @@ export default { url: `/group/quit/${this.group.id}`, method: 'delete' }).then(() => { - this.$store.commit("removeGroup", this.group.id); - this.$store.commit("removeGroupChat", this.group.id); + this.groupStore.removeGroup(this.group.id); + this.chatStore.removeGroupChat(this.group.id); }); }) }, @@ -156,7 +156,7 @@ export default { }, computed: { mine() { - return this.$store.state.userStore.userInfo; + return this.userStore.userInfo; }, ownerName() { let member = this.groupMembers.find((m) => m.userId == this.group.ownerId); diff --git a/im-web/src/components/chat/ChatHistory.vue b/im-web/src/components/chat/ChatHistory.vue index 8ce1601..76792e4 100644 --- a/im-web/src/components/chat/ChatHistory.vue +++ b/im-web/src/components/chat/ChatHistory.vue @@ -126,7 +126,7 @@ export default { }, computed: { mine() { - return this.$store.state.userStore.userInfo; + return this.userStore.userInfo; }, histroyAction() { return `/message/${this.chat.type.toLowerCase()}/history`; diff --git a/im-web/src/components/chat/ChatMessageItem.vue b/im-web/src/components/chat/ChatMessageItem.vue index 16f1b05..c6d719e 100644 --- a/im-web/src/components/chat/ChatMessageItem.vue +++ b/im-web/src/components/chat/ChatMessageItem.vue @@ -126,7 +126,7 @@ export default { showFullImageBox() { let imageUrl = JSON.parse(this.msgInfo.content).originUrl; if (imageUrl) { - this.$store.commit('showFullImageBox', imageUrl); + this.$eventBus.$emit("openFullImage", imageUrl); } }, onPlayVoice() { diff --git a/im-web/src/components/common/FullImage.vue b/im-web/src/components/common/FullImage.vue index 6c5661e..dcfdb3f 100644 --- a/im-web/src/components/common/FullImage.vue +++ b/im-web/src/components/common/FullImage.vue @@ -1,10 +1,10 @@ @@ -13,20 +13,17 @@ export default { name: "fullImage", data() { return { - fit: 'contain' + show: false, + url: '' } }, methods: { - onClose() { - this.$emit("close"); - } - }, - props: { - visible: { - type: Boolean + open(url) { + this.show = true; + this.url = url; }, - url: { - type: String + close() { + this.show = false; } } } diff --git a/im-web/src/components/common/HeadImage.vue b/im-web/src/components/common/HeadImage.vue index 9a18bd5..ed0008f 100644 --- a/im-web/src/components/common/HeadImage.vue +++ b/im-web/src/components/common/HeadImage.vue @@ -63,8 +63,7 @@ export default { x: e.x + 30, y: e.y } - this.$store.commit("setUserInfoBoxPos", pos); - this.$store.commit("showUserInfoBox", user); + this.$eventBus.$emit("openUserInfo", user, pos); }) } } diff --git a/im-web/src/components/common/UserInfo.vue b/im-web/src/components/common/UserInfo.vue index 3cdd07e..6a33988 100644 --- a/im-web/src/components/common/UserInfo.vue +++ b/im-web/src/components/common/UserInfo.vue @@ -1,5 +1,5 @@