diff --git a/im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java b/im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java index 61abfa3..75abfa8 100644 --- a/im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java +++ b/im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java @@ -50,5 +50,11 @@ public class GroupVO { @Schema(description = "是否已退出") private Boolean quit; + @Schema(description = "账号是否被封禁") + private Boolean isBanned; + + @Schema(description = "被封禁原因") + private String reason; + } diff --git a/im-platform/src/main/java/com/bx/implatform/vo/UserVO.java b/im-platform/src/main/java/com/bx/implatform/vo/UserVO.java index f54b17d..64ccae5 100644 --- a/im-platform/src/main/java/com/bx/implatform/vo/UserVO.java +++ b/im-platform/src/main/java/com/bx/implatform/vo/UserVO.java @@ -43,4 +43,9 @@ public class UserVO { @Schema(description = "是否在线") private Boolean online; + @Schema(description = "账号是否被封禁") + private Boolean isBanned; + + @Schema(description = "被封禁原因") + private String reason; } diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue index 9b290f3..0f62016 100644 --- a/im-uniapp/App.vue +++ b/im-uniapp/App.vue @@ -9,6 +9,7 @@ import UNI_APP from '@/.env.js' export default { data() { return { + isInit: false, // 是否已经初始化 isExit: false, // 是否已退出 audioTip: null, reconnecting: false // 正在重连标志 @@ -21,6 +22,7 @@ export default { this.loadStore().then(() => { // 初始化websocket this.initWebSocket(); + this.isInit = true; }).catch((e) => { console.log(e); this.exit(); @@ -169,7 +171,7 @@ export default { // 打开会话 this.chatStore.openChat(chatInfo); // 插入消息 - this.chatStore.insertMessage(msg); + this.chatStore.insertMessage(msg, chatInfo); // 播放提示音 this.playAudioTip(); @@ -192,6 +194,10 @@ export default { } // 消息回执处理 if (msg.type == enums.MESSAGE_TYPE.RECEIPT) { + let chatInfo = { + type: 'GROUP', + targetId: msg.groupId + } // 更新消息已读人数 let msgInfo = { id: msg.id, @@ -199,7 +205,7 @@ export default { readedCount: msg.readedCount, receiptOk: msg.receiptOk }; - this.chatStore.updateMessage(msgInfo) + this.chatStore.updateMessage(msgInfo,chatInfo) return; } // 标记这条消息是不是自己发的 @@ -259,7 +265,7 @@ export default { // 打开会话 this.chatStore.openChat(chatInfo); // 插入消息 - this.chatStore.insertMessage(msg); + this.chatStore.insertMessage(msg, chatInfo); // 播放提示音 this.playAudioTip(); }, @@ -374,6 +380,12 @@ export default { // 登录状态校验 let loginInfo = uni.getStorageSync("loginInfo") this.refreshToken(loginInfo).then(() => { + // #ifdef H5 + // 跳转到聊天页 + uni.switchTab({ + url: "/pages/chat/chat" + }) + // #endif // 初始化 this.init(); this.closeSplashscreen(0); diff --git a/im-uniapp/common/recorder-app.js b/im-uniapp/common/recorder-app.js index 0c8ff83..f114bbb 100644 --- a/im-uniapp/common/recorder-app.js +++ b/im-uniapp/common/recorder-app.js @@ -3,6 +3,9 @@ import UNI_APP from '@/.env.js'; const rc = uni.getRecorderManager(); // 录音开始时间 let startTime = null; +let checkIsEnable = ()=>{ + return true; +} let start = () => { return new Promise((resolve, reject) => { @@ -20,10 +23,6 @@ let start = () => { }) } -let pause = () => { - rc.stop(); -} - let close = () => { rc.stop(); } @@ -61,6 +60,7 @@ let upload = () => { } export { + checkIsEnable, start, close, upload diff --git a/im-uniapp/common/recorder-h5.js b/im-uniapp/common/recorder-h5.js index 1425dd3..ddb4112 100644 --- a/im-uniapp/common/recorder-h5.js +++ b/im-uniapp/common/recorder-h5.js @@ -4,26 +4,39 @@ let rc = null; let duration = 0; let chunks = []; let stream = null; +let startTime = null; +let checkIsEnable = () => { + if (origin.indexOf('https') === -1 && origin.indexOf('localhost') === -1 && + origin.indexOf('127.0.0.1') === -1) { + uni.showToast({ + title: '请在https环境中使用录音功能', + icon: 'error' + }) + return false; + } + if (!navigator.mediaDevices || !window.MediaRecorder) { + uni.showToast({ + title: '当前浏览器不支持录音', + icon: 'error' + }) + return false; + } + return true; +} + let start = () => { return navigator.mediaDevices.getUserMedia({ audio: true }).then(audioStream => { - const startTime = new Date().getTime(); + console.log("start record") + startTime = new Date().getTime(); chunks = []; stream = audioStream; rc = new MediaRecorder(stream) - rc.ondataavailable = (e) => { - console.log("ondataavailable") - chunks.push(e.data) - } - rc.onstop = () => { - duration = (new Date().getTime() - startTime) / 1000; - console.log("时长:", duration) - } rc.start() }) - } let close = () => { + console.log("stream:", stream) stream.getTracks().forEach((track) => { track.stop() }) @@ -33,11 +46,23 @@ let close = () => { let upload = () => { return new Promise((resolve, reject) => { - setTimeout(() => { + rc.ondataavailable = (e) => { + console.log("ondataavailable:",e.data) + console.log("size:",e.data.size) + console.log("type:",e.data.type) + chunks.push(e.data) + } + rc.onstop = () => { + if(!chunks[0].size){ + chunks = []; + return; + } + duration = (new Date().getTime() - startTime) / 1000; + console.log("时长:", duration) + console.log("上传,chunks:", chunks.length) const newbolb = new Blob(chunks, { 'type': 'audio/mpeg' }); const name = new Date().getDate() + '.mp3'; const file = new File([newbolb], name) - console.log("upload") uni.uploadFile({ url: UNI_APP.BASE_URL + '/file/upload', header: { @@ -62,11 +87,12 @@ let upload = () => { reject(e); } }) - }, 100) + } }) } export { + checkIsEnable, start, close, upload diff --git a/im-uniapp/components/chat-group-readed/chat-group-readed.vue b/im-uniapp/components/chat-group-readed/chat-group-readed.vue index c47a309..4ae285e 100644 --- a/im-uniapp/components/chat-group-readed/chat-group-readed.vue +++ b/im-uniapp/components/chat-group-readed/chat-group-readed.vue @@ -79,12 +79,18 @@ export default { }) this.items[0] = `已读(${this.readedMembers.length})`; this.items[1] = `未读(${this.unreadMembers.length})`; - // 更新已读人数 - this.chatStore.updateMessage({ + + let chatInfo = { + type: 'GROUP', + targetId: this.msgInfo.groupId + } + let msgInfo = { id: this.msgInfo.id, groupId: this.msgInfo.groupId, readedCount: this.readedMembers.length - }) + } + // 更新已读人数 + this.chatStore.updateMessage(msgInfo, chatInfo) }) }, onClickItem(e) { diff --git a/im-uniapp/components/chat-item/chat-item.vue b/im-uniapp/components/chat-item/chat-item.vue index ed985f6..288adef 100644 --- a/im-uniapp/components/chat-item/chat-item.vue +++ b/im-uniapp/components/chat-item/chat-item.vue @@ -42,8 +42,15 @@ export default { } }, methods: { - showChatBox() { + // 初始化期间进入会话会导致消息不刷新 + if(!getApp().$vm.isInit || this.chatStore.isLoading()){ + uni.showToast({ + title: "正在初始化页面,请稍后...", + icon: 'none' + }) + return; + } uni.navigateTo({ url: "/pages/chat/chat-box?chatIdx=" + this.index }) @@ -155,7 +162,8 @@ export default { font-size: $im-font-size-smaller; color: $im-text-color-lighter; padding-top: 8rpx; - + align-items: center; + .chat-at-text { color: $im-color-danger; } @@ -170,10 +178,6 @@ export default { overflow: hidden; text-overflow: ellipsis; - img { - width: 40rpx !important; - height: 40rpx !important; - } } } 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 71ab643..1b4a3dc 100644 --- a/im-uniapp/components/chat-message-item/chat-message-item.vue +++ b/im-uniapp/components/chat-message-item/chat-message-item.vue @@ -17,7 +17,7 @@ - + @@ -65,12 +65,12 @@ - 已读 - 未读 - + {{ msgInfo.readedCount }}人已读 @@ -125,14 +125,16 @@ export default { this.innerAudioContext = uni.createInnerAudioContext(); let url = JSON.parse(this.msgInfo.content).url; this.innerAudioContext.src = url; - console.log(url); this.innerAudioContext.onEnded((e) => { console.log('停止') this.audioPlayState = "STOP" + this.emit(); }) this.innerAudioContext.onError((e) => { + this.audioPlayState = "STOP" console.log("播放音频出错"); console.log(e) + this.emit(); }); } if (this.audioPlayState == 'STOP') { @@ -145,6 +147,7 @@ export default { this.innerAudioContext.play(); this.audioPlayState = "PLAYING" } + this.emit(); }, onSelectMenu(item) { this.$emit(item.key.toLowerCase(), this.msgInfo); @@ -158,6 +161,16 @@ export default { }, onShowReadedBox() { this.$refs.chatGroupReaded.open(); + }, + emit(){ + this.$emit("audioStateChange",this.audioPlayState,this.msgInfo); + }, + stopPlayAudio(){ + if (this.innerAudioContext) { + this.innerAudioContext.stop(); + this.innerAudioContext = null; + this.audioPlayState = "STOP" + } } }, computed: { @@ -262,6 +275,7 @@ export default { .chat-msg-bottom { display: inline-block; padding-right: 80rpx; + margin-top: 5rpx; .chat-msg-text { position: relative; @@ -289,7 +303,6 @@ export default { border-color: $im-bg transparent transparent; overflow: hidden; border-width: 18rpx; - //box-shadow: $im-box-shadow-dark; } } diff --git a/im-uniapp/components/chat-record/chat-record.vue b/im-uniapp/components/chat-record/chat-record.vue index bde3454..cb390d8 100644 --- a/im-uniapp/components/chat-record/chat-record.vue +++ b/im-uniapp/components/chat-record/chat-record.vue @@ -50,12 +50,14 @@ export default { /* 用户第一次使用语音会唤醒录音权限请求,此时会导致@touchend失效, 一直处于录音状态,这里允许用户再次点击发送语音并结束录音 */ if (this.recording) { - this.onEndRecord(); return; } console.log("开始录音") this.moveToCancel = false; this.initRecordBar(); + if(!this.$rc.checkIsEnable()){ + return; + } this.$rc.start().then(() => { this.recording = true; console.log("开始录音成功") @@ -70,9 +72,12 @@ export default { }); }, onEndRecord() { + if(!this.recording){ + return; + } this.recording = false; // 停止计时 - this.StopTimer(); + this.stopTimer(); // 停止录音 this.$rc.close(); // 触屏位置是否移动到了取消区域 @@ -80,8 +85,8 @@ export default { console.log("录音取消") return; } - // 小于1秒不发送 - if (this.druation == 0) { + // 大于1秒才发送 + if (this.druation <= 1) { uni.showToast({ title: "说话时间太短", icon: 'none' @@ -95,13 +100,11 @@ export default { title: e, icon: 'none' }) - }).finally(() => { - this.$rc.close(); }) }, startTimer() { this.druation = 0; - this.StopTimer(); + this.stopTimer(); this.rcTimer = setInterval(() => { this.druation++; // 大于60s,直接结束 @@ -110,7 +113,7 @@ export default { } }, 1000) }, - StopTimer() { + stopTimer() { this.rcTimer && clearInterval(this.rcTimer); this.rcTimer = null; }, @@ -134,6 +137,10 @@ export default { } return `录音时长:${this.druation}s`; } + }, + unmounted() { + this.stopTimer(); + this.recording = false; } } diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue index e425e81..d9d9878 100644 --- a/im-uniapp/pages/chat/chat-box.vue +++ b/im-uniapp/pages/chat/chat-box.vue @@ -6,10 +6,11 @@ - @@ -19,7 +20,7 @@ - + @@ -31,24 +32,26 @@ + :read-only="isReadOnly" @focus="onEditorFocus" @blur="onEditorBlur" @ready="onEditorReady" @input="onTextInput"> - - + + + + + 文件 + @@ -63,15 +66,6 @@ 拍摄 - - - - - - 文件 - - 语音消息 @@ -131,8 +125,10 @@ export default { scrollMsgIdx: 0, // 滚动条定位为到哪条消息 chatTabBox: 'none', showRecord: false, - keyboardHeight: 300, chatMainHeight: 0, // 聊天窗口高度 + keyboardHeight: 290, // 键盘高度 + windowHeight: 1000, // 窗口高度 + initHeight: 1000, // h5初始高度 atUserIds: [], needScrollToBottom: false, // 需要滚动到底部 showMinIdx: 0, // 下标小于showMinIdx的消息不显示,否则可能很卡 @@ -142,7 +138,8 @@ export default { editorCtx: null, // 编辑器上下文 isEmpty: true, // 编辑器是否为空 isFocus: false, // 编辑器是否焦点 - isReadOnly: false // 编辑器是否只读 + isReadOnly: false, // 编辑器是否只读 + playingAudio: null // 当前正在播放的录音消息 } }, methods: { @@ -155,6 +152,11 @@ export default { this.switchChatTabBox('none'); }, onSendRecord(data) { + // 检查是否被封禁 + if (this.isBanned) { + this.showBannedTip(); + return; + } let msgInfo = { content: JSON.stringify(data), type: this.$enums.MESSAGE_TYPE.AUDIO, @@ -164,7 +166,7 @@ export default { this.fillTargetId(msgInfo, this.chat.targetId); this.sendMessageRequest(msgInfo).then((m) => { m.selfSend = true; - this.chatStore.insertMessage(m); + this.chatStore.insertMessage(m, this.chat); // 会话置顶 this.moveChatToTop(); // 滚动到底部 @@ -260,6 +262,15 @@ export default { sendTextMessage() { this.editorCtx.getContents({ success: (e) => { + // 清空编辑框数据 + this.editorCtx.clear(); + this.atUserIds = []; + this.isReceipt = false; + // 检查是否被封禁 + if (this.isBanned) { + this.showBannedTip(); + return; + } let sendText = this.isReceipt ? "【回执消息】" : ""; e.delta.ops.forEach((op) => { if (op.insert.image) { @@ -294,13 +305,10 @@ export default { }).finally(() => { // 滚动到底部 this.scrollToBottom(); - // 清空编辑框数据 - this.atUserIds = []; - this.isReceipt = false; - this.editorCtx.clear(); }); } }) + }, createAtText() { let atText = ""; @@ -343,7 +351,6 @@ export default { this.$nextTick(() => { this.scrollMsgIdx = idx; }); - }, onShowEmoChatTab() { this.showRecord = false; @@ -379,6 +386,11 @@ export default { }) }, onUploadImageBefore(file) { + // 检查是否被封禁 + if (this.isBanned) { + this.showBannedTip(); + return; + } let data = { originUrl: file.path, thumbUrl: file.path @@ -399,7 +411,7 @@ export default { // 填充对方id this.fillTargetId(msgInfo, this.chat.targetId); // 插入消息 - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); // 借助file对象保存 @@ -416,15 +428,20 @@ export default { msgInfo.loadStatus = 'ok'; msgInfo.id = m.id; this.isReceipt = false; - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); }) }, onUploadImageFail(file, err) { let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); msgInfo.loadStatus = 'fail'; - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); }, onUploadFileBefore(file) { + // 检查是否被封禁 + if (this.isBanned) { + this.showBannedTip(); + return; + } let data = { name: file.name, size: file.size, @@ -445,7 +462,7 @@ export default { // 填充对方id this.fillTargetId(msgInfo, this.chat.targetId); // 插入消息 - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); // 借助file对象保存 @@ -467,13 +484,13 @@ export default { msgInfo.loadStatus = 'ok'; msgInfo.id = m.id; this.isReceipt = false; - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); }) }, onUploadFileFail(file, res) { let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); msgInfo.loadStatus = 'fail'; - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); }, onDeleteMessage(msgInfo) { uni.showModal({ @@ -481,7 +498,7 @@ export default { content: '确认删除消息?', success: (res) => { if (!res.cancel) { - this.chatStore.deleteMessage(msgInfo); + this.chatStore.deleteMessage(msgInfo, this.chat); uni.showToast({ title: "删除成功", icon: "none" @@ -505,7 +522,7 @@ export default { msgInfo.type = this.$enums.MESSAGE_TYPE.RECALL; msgInfo.content = '你撤回了一条消息'; msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL; - this.chatStore.insertMessage(msgInfo); + this.chatStore.insertMessage(msgInfo, this.chat); }) } } @@ -515,7 +532,7 @@ export default { uni.setClipboardData({ data: msgInfo.content, success: () => { - uni.showToast({ title: '已复制', icon: 'none' }); + uni.showToast({ title: '复制成功' }); }, fail: () => { uni.showToast({ title: '复制失败', icon: 'none' }); @@ -552,7 +569,7 @@ export default { // 防止滚动条定格在顶部,不能一直往上滚 this.scrollToMsgIdx(this.showMinIdx); // #endif - // 多展示0条信息 + // 多展示20条信息 this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0; }, onShowMore() { @@ -584,6 +601,15 @@ export default { onEditorBlur(e) { this.isFocus = false; }, + onAudioStateChange(state, msgInfo) { + const playingAudio = this.$refs['message' + msgInfo.id][0] + if (state == 'PLAYING' && playingAudio != this.playingAudio) { + // 停止之前的录音 + this.playingAudio && this.playingAudio.stopPlayAudio(); + // 记录当前正在播放的消息 + this.playingAudio = playingAudio; + } + }, loadReaded(fid) { this.$http({ url: `/message/private/maxReadedId?friendId=${fid}`, @@ -642,7 +668,7 @@ export default { }) }, rpxTopx(rpx) { - // px转换成rpx + // rpx转换成px let info = uni.getSystemInfoSync() let px = info.windowWidth * rpx / 750; return Math.floor(rpx); @@ -673,53 +699,122 @@ export default { }) } }, - listenKeyBoard() { - // #ifdef H5 - // 由于H5无法触发TextArea的@keyboardheightchange事件,所以通过 - // 监听屏幕高度变化来实现键盘监听 - let initHeight = window.innerHeight; - window.addEventListener('resize', () => { - let keyboardHeight = initHeight - window.innerHeight; - this.isShowKeyBoard = keyboardHeight > 0; - if (this.isShowKeyBoard) { - this.keyboardHeight = keyboardHeight; + reCalChatMainHeight() { + setTimeout(() => { + let h = this.windowHeight; + // 减去标题栏高度 + h -= 50; + // 减去键盘高度 + if (this.isShowKeyBoard || this.chatTabBox != 'none') { + console.log("减去键盘高度:", this.keyboardHeight) + h -= this.keyboardHeight; + this.scrollToBottom(); } - this.reCalChatMainHeight(); - }); + // #ifndef H5 + // h5需要减去状态栏高度 + h -= uni.getSystemInfoSync().statusBarHeight; + // #endif + this.chatMainHeight = h; + console.log("窗口高度:", this.chatMainHeight) + if (this.isShowKeyBoard || this.chatTabBox != 'none') { + this.scrollToBottom(); + } + // ios浏览器键盘把页面顶起后,页面长度不会变化,这里把页面拉到顶部适配一下 + // #ifdef H5 + if (uni.getSystemInfoSync().platform == 'ios') { + // 不同手机需要的延时时间不一致,采用分段延时的方式处理 + const delays = [50, 100, 500]; + delays.forEach((delay) => { + setTimeout(() => { + uni.pageScrollTo({ + scrollTop: 0, + duration: 10 + }); + }, delay); + }) + } + // #endif + }, 30) + }, + listenKeyBoard() { + // #ifdef H5 + const userAgent = navigator.userAgent; + const regex = /(macintosh|windows)/i; + if (regex.test(userAgent)) { + // 电脑端不需要弹出键盘 + console.log("userAgent:", userAgent) + return; + } + if (uni.getSystemInfoSync().platform == 'ios') { + // ios h5实现键盘监听 + window.addEventListener('focusin', this.focusInListener); + window.addEventListener('focusout', this.focusOutListener); + } else { + // 安卓h5实现键盘监听 + let initHeight = window.innerHeight; + window.addEventListener('resize', this.resizeListener); + } // #endif // #ifndef H5 - uni.onKeyboardHeightChange((res) => { - this.isShowKeyBoard = res.height > 0; - if (this.isShowKeyBoard) { - this.keyboardHeight = res.height; // 获取并保存键盘高度 - } - this.reCalChatMainHeight(); - }); + // app实现键盘监听 + uni.onKeyboardHeightChange(this.keyBoardListener); // #endif }, - reCalChatMainHeight() { - const sysInfo = uni.getSystemInfoSync(); - let h = sysInfo.windowHeight; - // 减去标题栏高度 - h -= 50; + unListenKeyboard() { // #ifdef H5 - // h5的sysInfo.windowHeight默认就已经减去键盘高度了 - if (this.chatTabBox != 'none') { - h -= this.keyboardHeight; - } + // 安卓h5实现键盘监听 + window.removeEventListener('resize', this.resizeListener); + window.removeEventListener('focusin', this.focusInListener); + window.removeEventListener('focusout', this.focusOutListener); // #endif // #ifndef H5 - // 减去状态栏高度 - h -= sysInfo.statusBarHeight; - if (this.isShowKeyBoard || this.chatTabBox != 'none') { - h -= this.keyboardHeight; - } + uni.offKeyboardHeightChange(this.keyBoardListener); // #endif - console.log("h:", h) - this.chatMainHeight = h; + }, + keyBoardListener(res) { + this.isShowKeyBoard = res.height > 0; + if (this.isShowKeyBoard) { + this.keyboardHeight = res.height; // 获取并保存键盘高度 + } + this.reCalChatMainHeight(); + }, + resizeListener() { + console.log("resize") + let keyboardHeight = this.initHeight - window.innerHeight; + this.isShowKeyBoard = keyboardHeight > 150; + if (this.isShowKeyBoard) { + this.keyboardHeight = keyboardHeight; + } + this.reCalChatMainHeight(); + }, + focusInListener() { + console.log("focusInListener") + this.isShowKeyBoard = true; + this.reCalChatMainHeight(); + }, + focusOutListener() { + console.log("focusOutListener") + this.isShowKeyBoard = false; + this.reCalChatMainHeight(); + }, + showBannedTip() { + let msgInfo = { + tmpId: this.generateId(), + sendId: this.mine.id, + sendTime: new Date().getTime(), + type: this.$enums.MESSAGE_TYPE.TIP_TEXT + } + if (this.chat.type == "PRIVATE") { + msgInfo.recvId = this.mine.id + msgInfo.content = "该用户已被管理员封禁,原因:" + this.friend.reason + } else { + msgInfo.groupId = this.group.id; + msgInfo.content = "本群聊已被管理员封禁,原因:" + this.group.reason + } + this.chatStore.insertMessage(msgInfo, this.chat); }, generateId() { - // 生成临时id + // 生成临时id return String(new Date().getTime()) + String(Math.floor(Math.random() * 1000)); } }, @@ -753,6 +848,10 @@ export default { } return this.chat.unreadCount; }, + isBanned() { + return (this.chat.type == "PRIVATE" && this.friend.isBanned) || + (this.chat.type == "GROUP" && this.group.isBanned) + }, atUserItems() { let atUsers = []; this.atUserIds.forEach((id) => { @@ -815,7 +914,20 @@ export default { // 监听键盘高度 this.listenKeyBoard(); // 计算聊天窗口高度 - this.$nextTick(()=>this.reCalChatMainHeight()) + this.$nextTick(() => { + this.windowHeight = uni.getSystemInfoSync().windowHeight; + this.reCalChatMainHeight() + // 兼容ios h5:禁止页面滚动 + // #ifdef H5 + this.initHeight = window.innerHeight; + document.body.addEventListener('touchmove', function(e) { + e.preventDefault(); + }, { passive: false }); + // #endif + }); + }, + onUnload() { + this.unListenKeyboard(); }, onShow() { if (this.needScrollToBottom) { @@ -827,14 +939,12 @@ export default { } - + \ No newline at end of file diff --git a/im-web/src/components/chat/ChatInput.vue b/im-web/src/components/chat/ChatInput.vue index 2a032d1..a5a9ee5 100644 --- a/im-web/src/components/chat/ChatInput.vue +++ b/im-web/src/components/chat/ChatInput.vue @@ -443,7 +443,7 @@ export default { if (node.dataset.id) { tempText += node.innerHTML; atUserIds.push(node.dataset.id) - } else { + } else if(node.outerHtml) { tempText += node.outerHtml; } } diff --git a/im-web/src/store/chatStore.js b/im-web/src/store/chatStore.js index ea1759e..aa1db6d 100644 --- a/im-web/src/store/chatStore.js +++ b/im-web/src/store/chatStore.js @@ -137,8 +137,8 @@ export default { this.commit("saveToStorage"); } }, - insertMessage(state, msgInfo) { - let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'; + insertMessage(state, [msgInfo, chatInfo]) { + let type = chatInfo.type; // 记录消息的最大id if (msgInfo.id && type == "PRIVATE" && msgInfo.id > state.privateMsgMaxId) { state.privateMsgMaxId = msgInfo.id; @@ -147,7 +147,7 @@ export default { state.groupMsgMaxId = msgInfo.id; } // 如果是已存在消息,则覆盖旧的消息数据 - let chat = this.getters.findChat(msgInfo); + let chat = this.getters.findChat(chatInfo); let message = this.getters.findMessage(chat, msgInfo); if (message) { Object.assign(message, msgInfo); @@ -178,7 +178,8 @@ export default { chat.lastSendTime = msgInfo.sendTime; chat.sendNickName = msgInfo.sendNickName; // 未读加1 - if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED && msgInfo.type != MESSAGE_TYPE.TIP_TEXT) { + if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED && + msgInfo.type != MESSAGE_TYPE.TIP_TEXT) { chat.unreadCount++; } // 是否有人@我 @@ -216,9 +217,9 @@ export default { chat.stored = false; this.commit("saveToStorage"); }, - updateMessage(state, msgInfo) { + updateMessage(state, [msgInfo, chatInfo]) { // 获取对方id或群id - let chat = this.getters.findChat(msgInfo); + let chat = this.getters.findChat(chatInfo); let message = this.getters.findMessage(chat, msgInfo); if (message) { // 属性拷贝 @@ -227,8 +228,8 @@ export default { this.commit("saveToStorage"); } }, - deleteMessage(state, msgInfo) { - let chat = this.getters.findChat(msgInfo); + deleteMessage(state, [msgInfo, chatInfo]) { + let chat = this.getters.findChat(chatInfo); for (let idx in chat.messages) { // 已经发送成功的,根据id删除 if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { @@ -289,7 +290,7 @@ export default { }); // 将消息一次性装载回来 state.chats = cacheChats; - // 清空缓存,不再使用 + // 清空缓存 cacheChats = null; this.commit("saveToStorage"); }, @@ -384,20 +385,10 @@ export default { } } }, - findChat: (state, getters) => (msgInfo) => { + findChat: (state, getters) => (chat) => { let chats = getters.findChats(); - // 获取对方id或群id - let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'; - let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId; - let chat = null; - for (let idx in chats) { - if (chats[idx].type == type && - chats[idx].targetId === targetId) { - chat = chats[idx]; - break; - } - } - return chat; + let idx = getters.findChatIdx(chat); + return chats[idx]; }, findChatByFriend: (state, getters) => (fid) => { let chats = getters.findChats(); diff --git a/im-web/src/view/Home.vue b/im-web/src/view/Home.vue index a31e2fa..676783d 100644 --- a/im-web/src/view/Home.vue +++ b/im-web/src/view/Home.vue @@ -201,7 +201,7 @@ export default { // 打开会话 this.$store.commit("openChat", chatInfo); // 插入消息 - this.$store.commit("insertMessage", msg); + this.$store.commit("insertMessage", [msg, chatInfo]); // 播放提示音 if (!msg.selfSend && this.$msgType.isNormal(msg.type) && msg.status != this.$enums.MESSAGE_STATUS.READED) { @@ -251,7 +251,6 @@ export default { }) }, insertGroupMessage(group, msg) { - let chatInfo = { type: 'GROUP', targetId: group.id, @@ -261,7 +260,7 @@ export default { // 打开会话 this.$store.commit("openChat", chatInfo); // 插入消息 - this.$store.commit("insertMessage", msg); + this.$store.commit("insertMessage", [msg, chatInfo]); // 播放提示音 if (!msg.selfSend && msg.type <= this.$enums.MESSAGE_TYPE.VIDEO && msg.status != this.$enums.MESSAGE_STATUS.READED) {