From 7f5c4fd704d4fc7e9eca679bb527822e8b374fc7 Mon Sep 17 00:00:00 2001 From: zouyanyan <254651820@qq.com> Date: Mon, 8 Jun 2026 14:34:57 +0800 Subject: [PATCH] upbug --- components/chat/submit.vue | 14 +- manifest.json | 4 +- pages/chat/chat.vue | 433 +++++++++++++++--------- pages/chat/groupchat.vue | 335 +++++++++++------- pages/index/index.vue | 7 + pages/message/group.vue | 675 ++++++++++++++++++++++--------------- pages/user/user.vue | 5 - static/icon/voice.png | Bin 1717 -> 1733 bytes static/icon/voice0.png | Bin 0 -> 1717 bytes 9 files changed, 911 insertions(+), 562 deletions(-) create mode 100644 static/icon/voice0.png diff --git a/components/chat/submit.vue b/components/chat/submit.vue index b39b386..5905484 100644 --- a/components/chat/submit.vue +++ b/components/chat/submit.vue @@ -152,7 +152,7 @@ // }, 0) // } - if (this.msg.length > 1) { + if (this.msg.length > 0) { // 0为表情和文字 this.send(this.msg, 'txt'); this.ifmore=true; @@ -161,7 +161,7 @@ }, inputs(e) { var chatm = e.detail.value; - if (chatm.length > 1) { + if (chatm.length > 0) { this.ifmore=false; } else{ @@ -431,12 +431,12 @@ display: flex; align-items: flex-end; box-sizing: border-box; - padding: 14rpx 20rpx; + padding: 14rpx; image { - width: 56rpx; - height: 56rpx; - margin: 0 10rpx; + width: 60rpx; + height: 60rpx; + margin: 0 8rpx; flex: auto; } .btnt { @@ -464,7 +464,7 @@ .record { line-height: 44rpx; text-align: center; - font-size: 20rpx; + font-size: 24rpx; color: rgba(39, 40, 50, 0.6); } } diff --git a/manifest.json b/manifest.json index b40d8d2..c1782a1 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "name" : "瑜伽汇", "appid" : "__UNI__B6E0086", "description" : "瑜伽汇", - "versionName" : "1.0.12", - "versionCode" : 1012, + "versionName" : "1.0.16", + "versionCode" : 1016, "transformPx" : false, "app-plus" : { "flexible" : true, diff --git a/pages/chat/chat.vue b/pages/chat/chat.vue index ddc3615..fd9de54 100644 --- a/pages/chat/chat.vue +++ b/pages/chat/chat.vue @@ -90,18 +90,26 @@ {{item.fromname}} + 已读 + 未读 {{item.content}} + 已读 + 未读 + 已读 + 未读 + 已读 + 未读 {{item.time}}″ @@ -112,6 +120,8 @@ + 已读 + 未读 订单咨询 @@ -276,15 +286,13 @@ this.sendinfo=null; this.$forceUpdate(); } - - // 先获取聊天记录缓存 - this.getchatstore(); } }, onShow() { + // 先获取聊天记录缓存 + this.getchatstore(); // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { - console.log("onShow") this.screendo(this.unshiftmsg.length - 1); }, 100); @@ -292,26 +300,24 @@ if(this.heartbeatInterval){ clearInterval(this.heartbeatInterval); // 停止心跳包发送 } - // socket接收实时消息 - this.socketinit(); }, onBackPress(options) { if (options.from === 'backbutton') { // 来自顶部菜单的返回按钮 // 在这里处理你的逻辑 console.log('返回按钮被点击'); - this.closeWebSocket(); - uni.onSocketClose(function (res) { - console.log('WebSocket 已关闭!'); - }); + // this.closeWebSocket(); + // uni.onSocketClose(function (res) { + // console.log('WebSocket 已关闭!'); + // }); return false; } }, beforeDestroy() { console.log('界面关闭socket,beforeDestroy'); // 在组件销毁前,确保关闭 WebSocket 连接 - this.closeWebSocket(); - clearInterval(this.heartbeatInterval); // 停止心跳包发送 + // this.closeWebSocket(); + // clearInterval(this.heartbeatInterval); // 停止心跳包发送 }, methods: { gotoDetail(item){ @@ -385,11 +391,12 @@ }, // 获取聊天记录 getchatstore(){ + console.log("getchatstore"); var that=this; try{ + this.unshiftmsg=[]; // 先获取会话缓存 - var data= myCache(this.info.chatId)?myCache(this.info.chatId):[]; - console.log("data",data) + var data= myCache(this.info.chatId)?myCache(this.info.chatId):[]; data.forEach((cell,i)=>{ cell["ifaudio"]=false; //时间间隔处理 @@ -409,8 +416,7 @@ cell.content=decodeURIComponent(cell.content); } this.unshiftmsg.push(cell); - }); - + }); if(this.unshiftmsg.length<=0) { if(this.info.from=="yh"){ @@ -452,31 +458,42 @@ } ]; this.$forceUpdate(); - } - - // 如果是第一次接收消息没有缓存,且有minId则拉取离线消息 - if(this.info.minId){ - this.readUp(1); - } + } } else{ // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { that.screendo(that.unshiftmsg.length-1); }, 100); - // 已经有缓存,则拉取离线消息 - this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; - this.$forceUpdate(); - // 请求服务器加载加载拉取离线聊天记录 - if(this.info.minId&&this.info.minId>0){ - this.readUp(1); - } } - } catch(err){ console.log(err); } + + // socket接收实时消息 + this.socketinit(); + + }, + // 是否是列表中已经存在了minId + ifpull(){ + var ret=true; + this.unshiftmsg.forEach((cell)=>{ + if(cell.id&&this.info.minId&&parseInt(cell.id)>=parseInt(this.info.minId)){ + ret=false; + } + }); + return ret; + }, + // 消息是否存在列表中 + ifadd(id){ + var ret=true; + this.unshiftmsg.forEach((cell)=>{ + if(cell.id==id){ + ret=false; + } + }); + return ret; }, // 定时心跳包 startHeartbeat() { @@ -497,54 +514,59 @@ // ws接收消息 socketinit(){ var that = this; - if (!this.isConnected) { - this.socketTask=uni.connectSocket({ - url: "wss://www.sanduolantoyoga.com/yoga-imserver/", - header: { - // 'content-type': 'application/json', - Authorization: uni.getStorageSync("token"), - }, - success: (res) => { - console.log(res, 'socket连接成功success'); - }, - fail: (res) => { - console.log(res, 'socket连接失败') + this.socketTask=uni.connectSocket({ + url: "wss://www.sanduolantoyoga.com/yoga-imserver/", + header: { + // 'content-type': 'application/json', + Authorization: uni.getStorageSync("token"), + }, + success: (res) => { + console.log(res, 'socket连接成功success'); + // 获取当前聊天中的minId 拉取离线信息 + that.getReadedId(); + }, + fail: (res) => { + console.log(res, 'socket连接失败') + }, + complete: (res) => { + console.log(res,'socket连接成功complete'); + } + }); + uni.onSocketOpen(res => { + console.log('WebSocket连接已打开!'); + that.isConnected = true; + + // 发送登录心跳包 + uni.sendSocketMessage({ + data: JSON.stringify({ + "cmd": 0,//心跳 + "data": { + "accessToken":uni.getStorageSync("token"), + }, + }), // 发送心跳包数据 // 发送的消息内容 + success(re) { + console.log(re); + console.log('消息发送成功!') }, - complete: (res) => { - console.log(res,'socket连接成功complete'); + fail(err) { + console.log(err); + console.log('消息发送失败!') } }); - uni.onSocketOpen(res => { - console.log('WebSocket连接已打开!'); - that.isConnected = true; - // 发送登录心跳包 - uni.sendSocketMessage({ - data: JSON.stringify({ - "cmd": 0,//心跳 - "data": { - "accessToken":uni.getStorageSync("token"), - }, - }), // 发送心跳包数据 // 发送的消息内容 - success(re) { - console.log(re); - console.log('消息发送成功!') - }, - fail(err) { - console.log(err); - console.log('消息发送失败!') - } - }); - // 发送心跳包 - this.startHeartbeat(); - }); - uni.onSocketMessage(res => { - console.log('收到WebSocket服务器消息:'); - if(res.data){ - let data=JSON.parse(res.data); - console.log(data); - if(data.data){ - data=data.data; - if(data){ + + // 发送心跳包 + this.startHeartbeat(); + + }); + uni.onSocketMessage(res => { + console.log('收到WebSocket服务器消息:'); + if(res.data){ + let data=JSON.parse(res.data); + console.log(data); + if(data.data){ + data=data.data; + if(data){ + if(this.ifadd(data.id)){ // 是发送者发送来的消息 if(data.recvId&&data.recvId.toString()==that.userid.toString()&&data.sendId.toString()==this.info.friendId.toString()){ // 加入聊天记录 @@ -596,19 +618,24 @@ } } } + // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + if(data.type==12){ + // 已读操作 + this.updateRead(data); + } } } - }); - uni.onSocketClose(res => { - console.log('WebSocket连接已关闭!'); - that.isConnected = false; - clearInterval(that.heartbeatInterval); // 停止心跳包发送 - }); - uni.onSocketError(err => { - console.error('WebSocket连接打开失败,请检查:', err); - clearInterval(that.heartbeatInterval); // 停止心跳包发送 - }); - } + } + }); + uni.onSocketClose(res => { + console.log('WebSocket连接已关闭!'); + that.isConnected = false; + clearInterval(that.heartbeatInterval); // 停止心跳包发送 + }); + uni.onSocketError(err => { + console.error('WebSocket连接打开失败,请检查:', err); + clearInterval(that.heartbeatInterval); // 停止心跳包发送 + }); }, // 关闭WebSocket连接 closeWebSocket() { @@ -621,14 +648,37 @@ async setMsglist(data){ data.send=data.type==6?await this.getProduct(data.content):(data.type==5?await this.getOrder(data.content):null); data.type=data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))), - console.log("setMsglist",data) + // console.log("setMsglist",data) this.unshiftmsg.push(data); this.$forceUpdate(); setTimeout(() => { this.screendo(this.unshiftmsg.length-1); }, 100); // 缓存聊天 - myCache(this.info.chatId,this.unshiftmsg); + myCache(this.info.chatId,this.unshiftmsg); + // 保存最大拉取Id + this.savaMaxId({id:this.info.chatId,minId:this.info.minId}); + }, + savaMaxId(info){ + // 保存最大拉取Id + var data= myCache("privateMsgMaxId")?myCache("privateMsgMaxId"):[]; + console.log("data",data) + var ifhas=0; + data.forEach((cell,i)=>{ + if(cell.id==info.id){ + ifhas=1; + data[i].minId==info.minId; + } + }); + if(ifhas){ + // 如果存在信息修改 + myCache("privateMsgMaxId",data); + } + else{ + // 如果不存在信息添加 + data.push(info); + myCache("privateMsgMaxId",data); + } }, async getProduct(id){ console.log("getProduct",id) @@ -679,89 +729,97 @@ async readed() { const {data: res} = await uni.$http.put('/api/message/private/readed?friendId='+this.info.friendId); }, - // 已读推送 - async readUp(ii) { - const {data: res} = await uni.$http.put('/api/message/private/readed?friendId='+this.info.friendId); - this.getList(ii); + // 获取当前聊天中最大minId + async getReadedId() { + const {data: res} = await uni.$http.get('/api/message/private/maxReadedId',{friendId:this.info.friendId}); + if(res.data){ + this.info.minId=res.data; + this.$forceUpdate(); + // 保存最大拉取Id + this.savaMaxId({id:this.info.chatId,minId:this.info.minId}); + this.getList(); + } }, - // 加载对话 - async getList(ii) { - var that=this; - const {data: res} = await uni.$http.get('/api/message/private/pullOfflineMessage',{minId: this.info.minId}); - this.triggered = false; - if(res.data&&res.data.length>0){ - const gotonum=res.data.length; - var type=0; - res.data.forEach((cell,i)=>{ - type=cell.type; - cell["ifaudio"]=false; - //时间间隔处理 - if (i < this.unshiftmsg.length - 1) { - //这里表示头部时间还是显示一下 - let t = dateTime.spaceTime(this.oldTime, cell.fromtime); - if (t) { - this.oldTime = t; + // 拉取离线消息 + async getList() { + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + // if(this.ifpull()){ + var that=this; + const {data: res} = await uni.$http.get('/api/message/private/pullOfflineMessage',{minId: this.info.minId}); + this.triggered = false; + if(res.data&&res.data.length>0){ + var type=0; + res.data.forEach((cell,i)=>{ + type=cell.type; + cell["ifaudio"]=false; + //时间间隔处理 + if (i < this.unshiftmsg.length - 1) { + //这里表示头部时间还是显示一下 + let t = dateTime.spaceTime(this.oldTime, cell.fromtime); + if (t) { + this.oldTime = t; + } + cell.fromtime = t; } - cell.fromtime = t; - } - // 获取图片,为下面的预览做准备 - if (cell.type == 1) { - this.imgMsg.unshift(cell.content) - } - else if(cell.type==0){ - cell.content=decodeURIComponent(cell.content); - } - // // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" - let mdata = { - "fromname": this.userName, - "fromuser": this.userid, - "headimg": cell.headImage?cell.headImage:'/static/image/kfr.png', - "toname": this.info.chatName, // 接收人 - "touser": this.info.friendId, // 接收人姓名 - "content": cell.content, - "time": cell.type==3?5:0, - "ifaudio":cell.type==3? true:false, - "fromtime": cell.sendTime, - "type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))), - "id": cell.id, - "recvId": cell.recvId, - "sendId": cell.sendId, - }; - this.unshiftmsg.unshift(mdata); - }); - if(ii==2){ - // 跳转到加载数据的第一条 与前面的:id进行对照 - setTimeout(() => { - that.screendo(gotonum -1); - }, 100); - } - else{ + // 获取图片,为下面的预览做准备 + if (cell.type == 1) { + this.imgMsg.unshift(cell.content) + } + else if(cell.type==0){ + cell.content=decodeURIComponent(cell.content); + } + // // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" + let mdata = { + "fromname": this.userName, + "fromuser": this.userid, + "headimg": cell.headImage?cell.headImage:'/static/image/kfr.png', + "toname": this.info.chatName, // 接收人 + "touser": this.info.friendId, // 接收人姓名 + "content": cell.content, + "time": cell.type==3?5:0, + "ifaudio":cell.type==3? true:false, + "fromtime": cell.sendTime, + "type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))), + "id": cell.id, + "recvId": cell.recvId, + "sendId": cell.sendId, + }; + this.unshiftmsg.unshift(mdata); + }); + // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { that.screendo(that.unshiftmsg.length-1); }, 100); + + // 缓存聊天 + myCache(this.info.chatId,this.unshiftmsg); + this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; + // 保存最大拉取Id + // this.savaMaxId({id:this.info.chatId,minId:this.info.minId}); + this.$forceUpdate(); + + // 离线加载后更新聊天列表记录 + var chatlastinfo={ + id: this.info.chatId, + content:this.unshiftmsg[this.unshiftmsg.length-1].content, + type: type, + minId: this.unshiftmsg[this.unshiftmsg.length-1].id, + datetime: this.unshiftmsg[this.unshiftmsg.length-1].sendTime, + name: this.info.chatName, + userid: this.userid, + fromuser: this.info.friendId, + img: this.info.chatAvatar, + sort:"privatechat" + }; + this.updateChatList(chatlastinfo); + + // 已读操作 + this.readed(); + } - // 缓存聊天 - myCache(this.info.chatId,this.unshiftmsg); - this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; - this.$forceUpdate(); - - // 离线加载后更新聊天列表记录 - var chatlastinfo={ - id: this.info.chatId, - content:this.unshiftmsg[this.unshiftmsg.length-1].content, - type: type, - minId: this.unshiftmsg[this.unshiftmsg.length-1].id, - datetime: this.unshiftmsg[this.unshiftmsg.length-1].sendTime, - name: this.info.chatName, - userid: this.userid, - fromuser: this.info.friendId, - img: this.info.chatAvatar, - sort:"privatechat" - }; - this.updateChatList(chatlastinfo); - - } + // } + }, screendo(scrindex){ this.scrollToView = ''; @@ -785,7 +843,7 @@ // 自定义下拉刷新被触发 onRefresh(event){ // 加载聊天记录 - this.readUp(2); + this.getList(); }, // 自定义下拉刷新被复位 onRestore() { @@ -1103,6 +1161,10 @@ this.$forceUpdate(); // 缓存聊天 myCache(this.info.chatId,this.unshiftmsg); + this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; + this.$forceUpdate(); + // 保存最大拉取Id + // this.savaMaxId({id:this.info.chatId,minId:this.info.minId}); // 更新聊天列表记录 var chatlastinfo={ id:this.info.chatId, @@ -1162,6 +1224,19 @@ myCache("chatlist-"+this.userid,chatlist); } }, + // 更新是否已读 + updateRead(item){ + console.log("updateRead") + this.unshiftmsg.forEach((cell,index)=>{ + // console.log(cell,item.recvId) + if(cell.fromuser==item.recvId){ + this.unshiftmsg[index].ifread=true; + this.$forceUpdate(); + } + }); + // 缓存聊天 + myCache(this.info.chatId,this.unshiftmsg); + }, //输入框高度 heights(e) { this.inputh = e; @@ -1246,19 +1321,23 @@ } .message { flex: none; - max-width: 480rpx; + max-width: 540rpx; + display: flex; + flex-direction: row; } .messagevideo { - max-width: 480rpx; + max-width: 540rpx; height: 300rpx; + display: flex; + flex-direction: row; } .msg-text { font-size: 32rpx; color: rgba(39, 40, 50, 1); line-height: 44rpx; padding: 18rpx 24rpx; + word-break: break-all; } - .msg-img { max-width: 400rpx; border-radius: 20rpx; @@ -1337,6 +1416,7 @@ margin-left: 16rpx; background-color: #fff; border-radius: 0rpx 20rpx 20rpx 20rpx; + word-break: break-all; } .ms-img { @@ -1497,6 +1577,22 @@ .msg-right { flex-direction: row-reverse; + .read{ + font-size: 24rpx; + color: #888; + margin-right: 10rpx; + display: flex; + justify-content: flex-end; + align-items: flex-end; + } + .noread{ + font-size: 24rpx; + color: #00a89b; + margin-right: 10rpx; + display: flex; + justify-content: flex-end; + align-items: flex-end; + } .feed-imgy{ display: flex; flex-direction: column; @@ -1523,6 +1619,7 @@ font-size: 32rpx; color: #FFFFFF; line-height: 48rpx; + word-break: break-all; border-radius: 20rpx 0rpx 20rpx 20rpx; } diff --git a/pages/chat/groupchat.vue b/pages/chat/groupchat.vue index 53aeb45..d1f6572 100644 --- a/pages/chat/groupchat.vue +++ b/pages/chat/groupchat.vue @@ -90,19 +90,29 @@ {{item.fromname}} + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 {{item.content}} + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 {{item.time}}″ @@ -112,6 +122,8 @@ + 已读 + {{item.readedCount?(2-item.readedCount):2}}未读 订单咨询 @@ -349,15 +361,15 @@ this.sendinfo=null; this.$forceUpdate(); } - - // 先获取聊天记录缓存 - this.getchatstore(); - - // 获取客服 和 教练 头像和名称 - this.getrwinfo(); } }, onShow() { + // 先获取聊天记录缓存 + this.getchatstore(); + + // 获取客服 和 教练 头像和名称 + this.getrwinfo(); + // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { console.log("onShow") @@ -368,18 +380,16 @@ if(this.heartbeatInterval){ clearInterval(this.heartbeatInterval); // 停止心跳包发送 } - // socket接收实时消息 - this.socketinit(); }, onBackPress(options) { if (options.from === 'backbutton') { // 来自顶部菜单的返回按钮 // 在这里处理你的逻辑 console.log('返回按钮被点击'); - this.closeWebSocket(); - uni.onSocketClose(function (res) { - console.log('WebSocket 已关闭!'); - }); + // this.closeWebSocket(); + // uni.onSocketClose(function (res) { + // console.log('WebSocket 已关闭!'); + // }); return false; } }, @@ -393,8 +403,8 @@ beforeDestroy() { console.log('界面关闭socket,beforeDestroy'); // 在组件销毁前,确保关闭 WebSocket 连接 - this.closeWebSocket(); - clearInterval(this.heartbeatInterval); // 停止心跳包发送 + // this.closeWebSocket(); + // clearInterval(this.heartbeatInterval); // 停止心跳包发送 }, methods: { // 获取客服和教练信息 @@ -499,9 +509,9 @@ getchatstore(){ var that=this; try{ + this.unshiftmsg=[]; // 先获取会话缓存 var data= myCache(this.info.chatId)?myCache(this.info.chatId):[]; - console.log("data",data) data.forEach((cell,i)=>{ cell["ifaudio"]=false; //时间间隔处理 @@ -565,30 +575,39 @@ ]; this.$forceUpdate(); } - - // 如果是第一次接收消息没有缓存,且有minId则拉取离线消息 - if(this.info.minId){ - this.readUp(1); - } } else{ // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { that.screendo(that.unshiftmsg.length-1); }, 100); - // 已经有缓存,则拉取离线消息 - this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; - this.$forceUpdate(); - // 请求服务器加载加载拉取离线聊天记录 - if(this.info.minId&&this.info.minId>0){ - this.readUp(1); - } } - } catch(err){ console.log(err); } + + // socket接收实时消息 + this.socketinit(); + }, + // 是否是列表中已经存在了minId + ifpull(){ + var ret=true; + this.unshiftmsg.forEach((cell)=>{ + if(cell.id&&this.info.minId&&parseInt(cell.id)>=parseInt(this.info.minId)){ + ret=false; + } + }); + return ret; + }, + ifadd(id){ + var ret=true; + this.unshiftmsg.forEach((cell)=>{ + if(cell.id==id){ + ret=false; + } + }); + return ret; }, // 定时心跳包 startHeartbeat() { @@ -626,6 +645,8 @@ }, success: (res) => { console.log(res, 'socket连接成功success'); + // 获取当前聊天中的minId 拉取离线信息 + that.getReadedId(); }, fail: (res) => { console.log(res, 'socket连接失败') @@ -666,18 +687,29 @@ // 群聊 if(data.data){ data=data.data; + // 是此群聊发送来的消息 if(data.groupId==this.info.groupId){ - // 加入聊天记录 - // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" - if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ - this.getMsgSender(data) + if(this.ifadd(data.id)){ + // 加入聊天记录 + // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" + if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ + this.getMsgSender(data); + // 已读操作 + this.readed(); + } + else{ + // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + } } - else{ - // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + if(data.type==12){ + // 已读操作 + this.updateRead(data); } } } + } } }); @@ -742,6 +774,8 @@ // 缓存聊天 myCache(this.info.chatId,this.unshiftmsg); + // 保存最大拉取Id + this.savaMaxId({id:this.info.chatId,minId:data.id}); // 接收到socket后更新聊天列表记录 var chatlastinfo={ @@ -764,6 +798,27 @@ // 已读操作 this.readed(); }, + savaMaxId(info){ + // 保存最大拉取Id + var data= myCache("groupMsgMaxId")?myCache("groupMsgMaxId"):[]; + console.log("data",data) + var ifhas=0; + data.forEach((cell,i)=>{ + if(cell.id==info.id){ + ifhas=1; + data[i].minId==info.minId; + } + }); + if(ifhas){ + // 如果存在信息修改 + myCache("groupMsgMaxId",data); + } + else{ + // 如果不存在信息添加 + data.push(info); + myCache("groupMsgMaxId",data); + } + }, async getProduct(id){ console.log("getProduct",id) var rets=null; @@ -812,93 +867,102 @@ async readed() { const {data: res} = await uni.$http.put('/api/message/group/readed?groupId='+this.info.groupId); }, - // 已读推送 - async readUp(ii) { - const {data: res} = await uni.$http.put('/api/message/group/readed?groupId='+this.info.groupId); - this.getList(ii); + // 获取当前聊天中最大minId + async getReadedId() { + const {data: res} = await uni.$http.get('/api/message/group/maxReadedId',{groupId:this.info.groupId}); + if(res.data){ + this.info.minId=res.data; + this.$forceUpdate(); + this.getList(); + } }, // 加载对话 - async getList(ii) { - var that=this; - const {data: res} = await uni.$http.get('/api/message/group/pullOfflineMessage',{minId: this.info.minId}); - this.triggered = false; - if(res.data&&res.data.length>0){ - const gotonum=res.data.length; - var type=0; - res.data.forEach((cell,i)=>{ - type=cell.type; - cell["ifaudio"]=false; - //时间间隔处理 - if (i < this.unshiftmsg.length - 1) { - //这里表示头部时间还是显示一下 - let t = dateTime.spaceTime(this.oldTime, cell.fromtime); - if (t) { - this.oldTime = t; + async getList() { + // if(this.ifpull()){ + var that=this; + const {data: res} = await uni.$http.get('/api/message/group/pullOfflineMessage',{minId: this.info.minId}); + this.triggered = false; + if(res.data&&res.data.length>0){ + const gotonum=res.data.length; + var type=0; + res.data.forEach((cell,i)=>{ + if(this.ifadd(cell.id)){ + type=cell.type; + cell["ifaudio"]=false; + //时间间隔处理 + if (i < this.unshiftmsg.length - 1) { + //这里表示头部时间还是显示一下 + let t = dateTime.spaceTime(this.oldTime, cell.fromtime); + if (t) { + this.oldTime = t; + } + cell.fromtime = t; + } + // 获取图片,为下面的预览做准备 + if (cell.type == 1) { + this.imgMsg.unshift(cell.content) + } + else if(cell.type==0){ + cell.content=decodeURIComponent(cell.content); + } + // // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" + let mdata = { + "fromname": this.userName, + "fromuser": this.userid, + "headimg": cell.headImage?cell.headImage:'/static/image/kfr.png', + "toname": cell.sendNickName, // 接收人 + "touser": cell.sendId, // 接收人姓名 + "content": cell.content, + "readedCount": cell.readedCount, + "time": cell.type==3?5:0, + "ifaudio":cell.type==3? true:false, + "fromtime": cell.sendTime, + "type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))), + "id": cell.id, + "sendId": cell.sendId, + "atUserIds": data.atUserIds, + }; + this.unshiftmsg.unshift(mdata); } - cell.fromtime = t; - } - // 获取图片,为下面的预览做准备 - if (cell.type == 1) { - this.imgMsg.unshift(cell.content) - } - else if(cell.type==0){ - cell.content=decodeURIComponent(cell.content); - } - // // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" - let mdata = { - "fromname": this.userName, - "fromuser": this.userid, - "headimg": cell.headImage?cell.headImage:'/static/image/kfr.png', - "toname": cell.sendNickName, // 接收人 - "touser": cell.sendId, // 接收人姓名 - "content": cell.content, - "readedCount": cell.readedCount, - "time": cell.type==3?5:0, - "ifaudio":cell.type==3? true:false, - "fromtime": cell.sendTime, - "type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))), - "id": cell.id, - "sendId": cell.sendId, - "atUserIds": data.atUserIds, - }; - this.unshiftmsg.unshift(mdata); - }); - if(ii==2){ - // 跳转到加载数据的第一条 与前面的:id进行对照 - setTimeout(() => { - that.screendo(gotonum -1); - }, 100); - } - else{ + }); + // // 跳转到加载数据的第一条 与前面的:id进行对照 + // setTimeout(() => { + // that.screendo(gotonum -1); + // }, 100); // 跳转到最后一条数据 与前面的:id进行对照 setTimeout(() => { that.screendo(that.unshiftmsg.length-1); }, 100); + // 缓存聊天 + myCache(this.info.chatId,this.unshiftmsg); + this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; + this.$forceUpdate(); + // 保存最大拉取Id + this.savaMaxId({id:this.info.chatId,minId:this.info.minId}); + + // 离线加载后更新聊天列表记录 + var chatlastinfo={ + id: this.info.chatId, + groupId:this.info.groupId, + content:this.unshiftmsg[this.unshiftmsg.length-1].content, + type: type, + minId: this.unshiftmsg[this.unshiftmsg.length-1].id, + datetime: this.unshiftmsg[this.unshiftmsg.length-1].sendTime, + name: this.info.chatName, + userid: this.userid, + friendId: this.info.friendId, // 客服userid + teacherId: this.info.teacherId? this.info.teacherId:this.info.instructor, // 教练userid + fromuser: this.unshiftmsg[this.unshiftmsg.length-1].touser, + img: this.unshiftmsg[this.unshiftmsg.length-1].headimg, + sort:"groupchat" + }; + this.updateChatList(chatlastinfo); + + // 已读操作 + this.readed(); } - // 缓存聊天 - myCache(this.info.chatId,this.unshiftmsg); - this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id; - this.$forceUpdate(); - - // 离线加载后更新聊天列表记录 - var chatlastinfo={ - id: this.info.chatId, - groupId:this.info.groupId, - content:this.unshiftmsg[this.unshiftmsg.length-1].content, - type: type, - minId: this.unshiftmsg[this.unshiftmsg.length-1].id, - datetime: this.unshiftmsg[this.unshiftmsg.length-1].sendTime, - name: this.info.chatName, - userid: this.userid, - friendId: this.info.friendId, // 客服userid - teacherId: this.info.teacherId? this.info.teacherId:this.info.instructor, // 教练userid - fromuser: this.unshiftmsg[this.unshiftmsg.length-1].touser, - img: this.unshiftmsg[this.unshiftmsg.length-1].headimg, - sort:"groupchat" - }; - this.updateChatList(chatlastinfo); - - } + // } + }, screendo(scrindex){ this.scrollToView = ''; @@ -922,7 +986,7 @@ // 自定义下拉刷新被触发 onRefresh(event){ // 加载聊天记录 - this.readUp(2); + this.getList(); }, // 自定义下拉刷新被复位 onRestore() { @@ -1240,6 +1304,9 @@ this.$forceUpdate(); // 缓存聊天 myCache(this.info.chatId,this.unshiftmsg); + // 保存最大拉取Id + this.savaMaxId({id:this.info.chatId,minId:rrdata.id}); + // 更新聊天列表记录 var chatlastinfo={ id:this.info.chatId, @@ -1302,6 +1369,21 @@ myCache("chatlist-"+this.userid,chatlist); } }, + // 更新是否已读 + updateRead(item){ + console.log(this.info) + this.unshiftmsg.forEach((cell,index)=>{ + if(cell.id==item.id){ + this.unshiftmsg[index].readedCount=item.readedCount; + if(item.readedCount>=2){ + this.unshiftmsg[index].ifread=true; + } + this.$forceUpdate(); + } + }); + // 缓存聊天 + myCache(this.info.chatId,this.unshiftmsg); + }, //输入框高度 heights(e) { this.inputh = e; @@ -1386,11 +1468,15 @@ } .message { flex: none; - max-width: 480rpx; + max-width: 540rpx; + display: flex; + flex-direction: row; } .messagevideo { - max-width: 480rpx; + max-width: 540rpx; height: 300rpx; + display: flex; + flex-direction: row; } .msg-text { font-size: 32rpx; @@ -1637,6 +1723,23 @@ .msg-right { flex-direction: row-reverse; + .read{ + font-size: 24rpx; + color: #888; + margin-right: 10rpx; + display: flex; + justify-content: flex-end; + align-items: flex-end; + } + .noread{ + font-size: 24rpx; + color: #00a89b; + margin-right: 10rpx; + display: flex; + justify-content: flex-end; + align-items: flex-end; + } + .feed-imgy{ display: flex; flex-direction: column; diff --git a/pages/index/index.vue b/pages/index/index.vue index eabbe16..8e50656 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -781,6 +781,13 @@ .thname{ font-size: 30rpx; color:#000; + display: -webkit-box; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + /* 假设你的行高是20px,并且你想要两行显示 */ + line-height: 40rpx; /* 每行的行高 */ + max-height: 80rpx; } .thtext{ margin-top: 10rpx; diff --git a/pages/message/group.vue b/pages/message/group.vue index cdb5141..cf20d90 100644 --- a/pages/message/group.vue +++ b/pages/message/group.vue @@ -12,27 +12,28 @@ 暂无消息~ - - - - + + + + + + + + {{info.name}} + {{ changeTime(info.datetime)}} - - - {{info.name}} - {{ changeTime(info.datetime)}} + + + {{ info.type==0?info.content:(info.type==1?"图片":(info.type==2?"文件":(info.type==3?"语音":(info.type==4?"视频": + (info.type==5?"订单咨询":(info.type==6?"商品咨询":info.content))))))}} - - - {{ info.type==0?info.content:(info.type==1?"图片":(info.type==2?"文件":(info.type==3?"语音":(info.type==4?"视频": - (info.type==5?"订单咨询":(info.type==6?"商品咨询":info.content))))))}} - - - {{ info.sl}} - + + {{ info.sl}} - + + @@ -71,7 +72,7 @@ backgroundColor: '#ed2a28' } } - ], //u-swipe-action样式 + ], // u-swipe-action样式 imgurl:uni.$http.baseUrl, grouplist:[], socketTask: null, @@ -82,8 +83,6 @@ } }, onLoad(options) { - // socket接收信息初始化 - // this.socketinit(); }, onShow(){ this.openId = myCache('openId'); @@ -110,18 +109,18 @@ // 来自顶部菜单的返回按钮 // 在这里处理你的逻辑 console.log('返回按钮被点击'); - this.closeWebSocket(); - uni.onSocketClose(function (res) { - console.log('WebSocket 已关闭!'); - }); + // this.closeWebSocket(); + // uni.onSocketClose(function (res) { + // console.log('WebSocket 已关闭!'); + // }); return false; } }, beforeDestroy() { console.log('界面关闭socket,beforeDestroy'); // 在组件销毁前,确保关闭 WebSocket 连接 - this.closeWebSocket(); - clearInterval(this.heartbeatInterval); // 停止心跳包发送 + // this.closeWebSocket(); + // clearInterval(this.heartbeatInterval); // 停止心跳包发送 }, beforeRouteLeave(to, from, next) { console.log('界面关闭socket,beforeRouteLeave'); @@ -130,22 +129,7 @@ methods: { handleLongPress(info,index) { console.log(index); - this.$refs.swipeRef[index].open() - // var that=this; - // uni.showModal({ - // title: '提示', - // content: "确定要删除此聊天记录吗?", - // cancelText: '取消', - // confirmText: '确定', - // success: ress => { - // if (ress.confirm) { - // // myCache(info.id,""); - // // that.grouplist.splice(index, 1); - // // that.$forceUpdate(); - // // myCache("chatlist-"+this.userid,that.grouplist); - // } - // } - // }); + this.$refs.swipeRef[index].open(); }, // 删除 actionClick(info,index) { @@ -158,6 +142,7 @@ confirmText: '确定', success: ress => { if (ress.confirm) { + that.$refs.swipeRef[index].close(); myCache(info.id,""); that.grouplist.splice(index, 1); that.$forceUpdate(); @@ -185,182 +170,222 @@ // ws接收消息 socketinit(){ var that = this; - // if (!that.isConnected) { - - that.socketTask=uni.connectSocket({ - url: "wss://www.sanduolantoyoga.com/yoga-imserver/", - header: { - // 'content-type': 'application/json', - Authorization: uni.getStorageSync("token"), - }, - success: (res) => { - console.log(res, 'socket连接成功success'); - }, - fail: (res) => { - console.log(res, 'socket连接失败') + that.socketTask=uni.connectSocket({ + url: "wss://www.sanduolantoyoga.com/yoga-imserver/", + header: { + // 'content-type': 'application/json', + Authorization: uni.getStorageSync("token"), + }, + success: (res) => { + console.log(res, 'socket连接成功success'); + }, + fail: (res) => { + console.log(res, 'socket连接失败') + }, + complete: (res) => { + console.log(res,'socket连接成功complete'); + } + }); + + uni.onSocketOpen(resopen => { + console.log('WebSocket连接已打开!'); + that.isConnected = true; + that.$forceUpdate(); + uni.sendSocketMessage({ + data: JSON.stringify({ + "cmd": 0,//心跳 + "data": { + "accessToken":uni.getStorageSync("token"), + }, + }), // 发送心跳包数据 // 发送的消息内容 + success(re) { + console.log(re); + console.log('消息发送成功!') }, - complete: (res) => { - console.log(res,'socket连接成功complete'); + fail(err) { + console.log(err); + console.log('消息发送失败!') } }); - uni.onSocketOpen(resopen => { - console.log('WebSocket连接已打开!'); - that.isConnected = true; - that.$forceUpdate() - uni.sendSocketMessage({ - data: JSON.stringify({ - "cmd": 0,//心跳 - "data": { - "accessToken":uni.getStorageSync("token"), - }, - }), // 发送心跳包数据 // 发送的消息内容 - success(re) { - console.log(re); - console.log('消息发送成功!') - }, - fail(err) { - console.log(err); - console.log('消息发送失败!') + // 定时发送心跳包 + this.startHeartbeat(); + + // 拉取离线消息 + this.grouplist.forEach((cell,i)=>{ + if(cell.minId){ + // 通过某个会话中已读消息的最大id 获取离线消息 + this.pullMessage(i,cell); + } + }); + + // 已经删除的有最大id的继续拉取是否有消息 + var data= myCache("privateMsgMaxId")?myCache("privateMsgMaxId"):[{id:0,minId:0}]; + data.forEach((cell)=>{ + console.log("privateMsgMaxId") + var ifcz=false; + this.grouplist.forEach((item)=>{ + if(cell.id==item.id){ + // 已经存在列表了,不用拉取离线信息 + ifcz=true; } }); - - // 发送心跳包 - this.startHeartbeat(); + if(!ifcz){ + // 拉取离线信息 + this.getList(cell); + } }); - uni.onSocketMessage(res => { - console.log('收到WebSocket服务器消息:'); - if(res.data){ - var rs=JSON.parse(res.data); - console.log(rs); - if(rs.cmd==3){ - // 私聊 - if(rs.data){ - var data=rs.data; - if(data.recvId&&(data.recvId).toString()==(that.userid).toString()){ - // 是这个用户的接收的私聊信息 - // 加入聊天记录 - // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" - if(data.type==0){ - data.content=decodeURIComponent(data.content); - } - if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ - var ifexist=0,idx=null; - that.grouplist.forEach((cell,index)=>{ - if(cell.fromuser==data.sendId&&cell.userid==data.recvId&&cell.sort=="privatechat"){ - ifexist=1; - idx=index; - that.grouplist[index].sl=(that.grouplist[index].sl?that.grouplist[index].sl+1:1); - that.grouplist[index].content=data.content; - that.grouplist[index].datetime=data.sendTime; - that.grouplist[index].type=data.type; - that.$forceUpdate(); - } - }); - - if(ifexist==0){ - // 未保存缓存 - // 接收到socket后更新聊天列表记录 - var chatlastinfo={ - id: "privatechat-" + data.recvId +"-" + data.sendId, - content: data.content, - minId: data.id, - sl:1, - datetime: data.sendTime, - type: data.type, - name: "", - userid: data.recvId, - fromuser: data.sendId, - img: "", - sort:"privatechat" - }; - that.updateChatList(chatlastinfo,ifexist); - } - else{ - that.updateChatList(that.grouplist[idx],ifexist); + var data= myCache("groupMsgMaxId")?myCache("groupMsgMaxId"):[{id:0,minId:0}]; + data.forEach((cell)=>{ + var ifcz=false; + this.grouplist.forEach((item)=>{ + if(cell.id==item.id){ + // 已经存在列表了,不用拉取离线信息 + ifcz=true; + } + }); + if(!ifcz){ + // 拉取离线信息 + this.getGroupList(cell); + } + }); + + }); + + uni.onSocketMessage(res => { + console.log('收到WebSocket服务器消息:'); + if(res.data){ + var rs=JSON.parse(res.data); + console.log(rs); + if(rs.cmd==3){ + // 私聊 + if(rs.data){ + var data=rs.data; + if(data.recvId&&(data.recvId).toString()==(that.userid).toString()){ + // 是这个用户的接收的私聊信息 + // 加入聊天记录 + // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" + if(data.type==0){ + data.content=decodeURIComponent(data.content); + } + if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ + var ifexist=0,chatinfo=null; + that.grouplist.forEach((cell,index)=>{ + if(cell.fromuser==data.sendId&&cell.userid==data.recvId&&cell.sort=="privatechat"){ + ifexist=1; + that.grouplist[index].sl=(that.grouplist[index].sl?that.grouplist[index].sl+1:1); + that.grouplist[index].content=data.content; + that.grouplist[index].datetime=data.sendTime; + that.grouplist[index].type=data.type; + that.$forceUpdate(); + chatinfo= JSON.parse(JSON.stringify(that.grouplist[index])) ; + console.log(chatinfo) } + }); + if(ifexist==0){ + // 未保存缓存 + // 接收到socket后更新聊天列表记录 + var chatlastinfo={ + id: "privatechat-" + data.recvId +"-" + data.sendId, + content: data.content, + minId: data.id, + sl:1, + datetime: data.sendTime, + type: data.type, + name: "", + userid: data.recvId, + fromuser: data.sendId, + img: "", + sort:"privatechat" + }; + that.updateChatList(chatlastinfo); } else{ - // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + that.updateChatList(chatinfo); } } + else{ + // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + + } } } - else if(rs.cmd==4){ - // 群聊 - if(rs.data){ - var data=rs.data; - if(data.atUserIds&&data.atUserIds.includes(that.userid)){ - // 是这个用户的接收的群聊信息 - // 加入聊天记录 - // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" - if(data.type==0){ - data.content=decodeURIComponent(data.content); - } - if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ - var ifexist=0,idx=null; - that.grouplist.forEach((cell,index)=>{ - if(cell.groupId==data.groupId&&cell.sort=="groupchat"){ - ifexist=1; - idx=index; - that.grouplist[index].sl=(that.grouplist[index].sl?that.grouplist[index].sl+1:1); - that.grouplist[index].content=data.content; - that.grouplist[index].datetime=data.sendTime; - that.grouplist[index].fromuser=data.sendId; - that.grouplist[index].type=data.type; - that.$forceUpdate(); - } - }); - - if(ifexist==0){ - // 未保存缓存 - // 接收到socket后更新聊天列表记录 - var chatlastinfo={ - id: "groupchat-" + data.groupId, - groupId:data.groupId, - content: data.content, - minId: data.id, - sl:1, - datetime: data.sendTime, - type: data.type, - name: "", - userid: this.userid, - fromuser: data.sendId, - img: "", - sendId: data.sendId, - sendNickName: data.sendNickName, - sort:"groupchat" - }; - that.getGroupInfo(chatlastinfo,ifexist); - } - else{ - that.getGroupInfo(that.grouplist[idx],ifexist); + } + else if(rs.cmd==4){ + // 群聊 + if(rs.data){ + var data=rs.data; + if(data.atUserIds&&data.atUserIds.includes(that.userid)){ + // 是这个用户的接收的群聊信息 + // 加入聊天记录 + // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记" + if(data.type==0){ + data.content=decodeURIComponent(data.content); + } + if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){ + var ifexist=0,idx=null; + that.grouplist.forEach((cell,index)=>{ + if(cell.groupId==data.groupId&&cell.sort=="groupchat"){ + ifexist=1; + idx=index; + that.grouplist[index].sl=(that.grouplist[index].sl?that.grouplist[index].sl+1:1); + that.grouplist[index].content=data.content; + that.grouplist[index].datetime=data.sendTime; + that.grouplist[index].fromuser=data.sendId; + that.grouplist[index].type=data.type; + that.$forceUpdate(); } + }); + + if(ifexist==0){ + // 未保存缓存 + // 接收到socket后更新聊天列表记录 + var chatlastinfo={ + id: "groupchat-" + data.groupId, + groupId:data.groupId, + content: data.content, + minId: data.id, + sl:1, + datetime: data.sendTime, + type: data.type, + name: "", + userid: this.userid, + fromuser: data.sendId, + img: "", + sendId: data.sendId, + sendNickName: data.sendNickName, + sort:"groupchat" + }; + that.getGroupInfo(chatlastinfo); } else{ - // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + that.getGroupInfo(that.grouplist[idx]); } } + else{ + // 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记" + + } } } } - }); - - uni.onSocketClose(res => { - console.log('WebSocket连接已关闭!',res); - that.isConnected = false; - that.$forceUpdate(); - clearInterval(that.heartbeatInterval); // 停止心跳包发送 - }); - - uni.onSocketError(err => { - console.error('WebSocket连接打开失败,请检查:', err); - that.isConnected = false; - that.$forceUpdate(); - clearInterval(that.heartbeatInterval); // 停止心跳包发送 - }); - // } + } + }); + + uni.onSocketClose(res => { + console.log('WebSocket连接已关闭!',res); + that.isConnected = false; + that.$forceUpdate(); + clearInterval(that.heartbeatInterval); // 停止心跳包发送 + }); + + uni.onSocketError(err => { + console.error('WebSocket连接打开失败,请检查:', err); + that.isConnected = false; + that.$forceUpdate(); + clearInterval(that.heartbeatInterval); // 停止心跳包发送 + }); }, // 关闭WebSocket连接 closeWebSocket() { @@ -368,6 +393,16 @@ this.isConnected = false; this.$forceUpdate() }, + // 消息是否存在列表中 + ifadd(id){ + var ret=0; + this.grouplist.forEach((cell,ii)=>{ + if(cell.id==id){ + ret=ii+1; + } + }); + return ret; + }, gotoContacts(){ uni.navigateTo({ url: `/pages/message/contact` @@ -440,21 +475,10 @@ // 获取群聊列表 async getgroupsmembers(){ // 获取聊天群列表 - this.grouplist=[]; - var chatlist=myCache("chatlist-"+this.userid)?myCache("chatlist-"+this.userid):[]; - chatlist.forEach(cell=>{ - if(cell.userid==this.userid){ - this.grouplist.push(cell); - } - }); - this.grouplist.forEach((cell,i)=>{ - if(cell.minId){ - // 通过某个会话中已读消息的最大id 获取离线消息 - this.readUp(i,cell); - } - }); + this.grouplist=myCache("chatlist-"+this.userid)?myCache("chatlist-"+this.userid):[]; this.loadStatus="nomore"; this.$forceUpdate(); + // 按照时间排序 var that=this; setTimeout(() => { that.reorder(); @@ -469,68 +493,148 @@ this.grouplist.sort((a, b) => b.datetime - a.datetime); this.$forceUpdate(); }, - // 已读推送 - async readUp(i,item) { + // 拉取离线信息 + async pullMessage(i,item) { if(item.sort=="groupchat"){ - const {data: res} = await uni.$http.put('/api/message/group/readed?groupId='+item.groupId); this.getgroupsnums(i,item); } else{ - const {data: res} = await uni.$http.put('/api/message/private/readed?friendId='+item.fromuser); this.getgroupsnums(i,item); } }, + // 拉取离线消息 + async getGroupList(item) { + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + var that=this; + const {data: res} = await uni.$http.get('/api/message/group/pullOfflineMessage',{minId: item.minId}); + if(res.data&&res.data.length>0){ + res.data.forEach((cell,index)=>{ + // 获取消息后对消息进行缓存处理 + var chatlastinfo={ + id: "groupchat-" + cell.groupId, + groupId:cell.groupId, + content: cell.content, + minId: cell.id, + sl: index+1, + datetime: cell.sendTime, + type: cell.type, + name: "", + userid: this.userid, + fromuser: cell.sendId, + img: "", + sendId: cell.sendId, + sendNickName: cell.sendNickName, + sort:"groupchat" + }; + this.getGroupInfo(chatlastinfo,index); + }); + } + }, + // 拉取离线消息 + async getList(item) { + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + var that=this; + const {data: res} = await uni.$http.get('/api/message/private/pullOfflineMessage',{minId: item.minId}); + if(res.data&&res.data.length>0){ + res.data.forEach((cell,index)=>{ + // 获取消息后对消息进行缓存处理 + var chatlastinfo={ + id: "privatechat-" + cell.recvId +"-" + cell.sendId, + content: cell.content, + minId: cell.id, + sl:index+1, + datetime: cell.sendTime, + type: cell.type, + name: "", + userid: cell.recvId, + fromuser: cell.sendId, + img: "", + sort:"privatechat" + }; + this.updateChatList(chatlastinfo,index); + }); + } + }, + ifprivateMsgMaxId(item){ + var ret=true; + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + var data= myCache("privateMsgMaxId")?myCache("privateMsgMaxId"):[]; + data.forEach((cell)=>{ + if(cell.id==item.id&&parseInt(item.minId)>=parseInt(cell.minId)){ + ret=false; + } + }); + return ret; + }, + ifgroupMsgMaxId(item){ + console.log("ifgroupMsgMaxId") + var ret=true; + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + var data= myCache("groupMsgMaxId")?myCache("groupMsgMaxId"):[]; + data.forEach((cell)=>{ + if(cell.id==item.id&&parseInt(item.minId)>=parseInt(cell.minId)){ + ret=false; + } + }); + return ret; + }, // 获取群聊中离线信息 async getgroupsnums(i,item){ if(item.sort=="groupchat"){ - // 群聊 - const {data: res} = await uni.$http.get("/api/message/group/pullOfflineMessage",{minId:item.minId}); - if(res.data&&res.data.length>0){ - // 获取消息后对消息进行缓存处理 - var data=res.data; - // 获取离线消息数量返回 - this.grouplist[i]["sl"]=res.data.length; - var last=res.data[res.data.length-1]; - if(last.type==0){ - last.content=decodeURIComponent(last.content); - } - if(last.type==0||last.type==1||last.type==2||last.type==3||last.type==4||data.type==5||data.type==6){ - this.grouplist[i].content=last.content; - this.grouplist[i].type=last.type; - this.grouplist[i].datetime=last.datetime; - this.$forceUpdate(); - // 重新排序 - this.reorder(); - myCache("chatlist-"+this.userid,this.grouplist); + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + // if(this.ifgroupMsgMaxId(item)){ + // 群聊 + const {data: res} = await uni.$http.get("/api/message/group/pullOfflineMessage",{minId:item.minId}); + if(res.data&&res.data.length>0){ + // 获取消息后对消息进行缓存处理 + var data=res.data; + // 获取离线消息数量返回 + this.grouplist[i]["sl"]=res.data.length; + var last=res.data[res.data.length-1]; + if(last.type==0){ + last.content=decodeURIComponent(last.content); + } + if(last.type==0||last.type==1||last.type==2||last.type==3||last.type==4||data.type==5||data.type==6){ + this.grouplist[i].content=last.content; + this.grouplist[i].type=last.type; + this.grouplist[i].datetime=last.datetime; + this.$forceUpdate(); + // 重新排序 + this.reorder(); + myCache("chatlist-"+this.userid,this.grouplist); + } } - } + // } } else{ - // 私聊 - const {data: res} = await uni.$http.get("/api/message/private/pullOfflineMessage",{minId:item.minId}); - if(res.data&&res.data.length>0){ - // 获取消息后对消息进行缓存处理 - var data=res.data; - // 获取离线消息数量返回 - this.grouplist[i]["sl"]=res.data.length; - var last=res.data[res.data.length-1]; - if(last.type==0){ - last.content=decodeURIComponent(last.content); - } - if(last.type==0||last.type==1||last.type==2||last.type==3||last.type==4||data.type==5||data.type==6){ - this.grouplist[i].content=last.content; - this.grouplist[i].type=last.type; - this.grouplist[i].datetime=last.datetime; - this.$forceUpdate(); - // 重新排序 - this.reorder(); - myCache("chatlist-"+this.userid,this.grouplist); + // 判断当前 minId 是不是列表中已经存在了,是不再拉取,不是继续拉取 + // if(this.ifprivateMsgMaxId(item)){ + // 私聊 + const {data: res} = await uni.$http.get("/api/message/private/pullOfflineMessage",{minId:item.minId}); + if(res.data&&res.data.length>0){ + // 获取消息后对消息进行缓存处理 + var data=res.data; + // 获取离线消息数量返回 + this.grouplist[i]["sl"]=res.data.length; + var last=res.data[res.data.length-1]; + if(last.type==0){ + last.content=decodeURIComponent(last.content); + } + if(last.type==0||last.type==1||last.type==2||last.type==3||last.type==4||data.type==5||data.type==6){ + this.grouplist[i].content=last.content; + this.grouplist[i].type=last.type; + this.grouplist[i].datetime=last.datetime; + this.$forceUpdate(); + // 重新排序 + this.reorder(); + myCache("chatlist-"+this.userid,this.grouplist); + } } - } + // } } }, // 获取群信息 - async getGroupInfo(info,ifexist) { + async getGroupInfo(info) { const {data: res} = await uni.$http.get('/api/group/find/'+info.groupId); if(res.data){ var data = res.data; @@ -545,26 +649,34 @@ info.instructor=data.instructor; info.productId=data.productId; info.productName=data.productName; - this.updateChatGroupList(info,ifexist); + this.updateChatGroupList(info); } }, - async updateChatGroupList(info,ifexist){ + async updateChatGroupList(info){ var name=info.name,img=info.img||require("@/static/image/girl.png"); const {data: res} = await uni.$http.get("/api/friend/find/"+info.sendId); if(res.data){ var data=res.data; name=data.nickName?data.nickName:"匿名"; img=data.headImage?data.headImage:require("@/static/image/girl.png"); - if(ifexist==0){ + var idx=this.ifadd(info.id); + if(!idx){ this.grouplist.push(info); this.$forceUpdate(); } + else{ + this.grouplist[idx-1].content=info.content; + this.grouplist[idx-1].datetime=info.datetime; + this.grouplist[idx-1].fromuser=info.fromuser; + this.grouplist[idx-1].type=info.type; + this.$forceUpdate(); + } // 重新排序 保存缓存 this.reorder(); myCache("chatlist-"+this.userid,this.grouplist); // 聊天框消息缓存 var msgchat=myCache(info.id); - if(ifexist==0||!msgchat){ + if(!msgchat){ // 第一条聊天记录保存缓存 let firstmsg = [{ "fromname": name, // 发送人 @@ -610,15 +722,23 @@ else{ name="匿名"; img="../../static/image/girl.png"; - if(ifexist==0){ + var idx=this.ifadd(info.id); + if(!idx){ this.grouplist.push(info); this.$forceUpdate(); } + else{ + this.grouplist[idx-1].content=info.content; + this.grouplist[idx-1].datetime=info.datetime; + this.grouplist[idx-1].fromuser=info.fromuser; + this.grouplist[idx-1].type=info.type; + this.$forceUpdate(); + } // 重新排序 this.reorder(); myCache("chatlist-"+this.userid,this.grouplist); var msgchat=myCache(info.id); - if(ifexist==0||!msgchat){ + if(!msgchat){ // 第一条聊天记录保存缓存 let firstmsg = [{ "fromname": name, // 发送人 @@ -661,22 +781,31 @@ } } }, - async updateChatList(info,ifexist){ + async updateChatList(info){ const {data: res} = await uni.$http.get("/api/friend/find/"+info.fromuser); if(res.data){ var data=res.data; info.name=data.nickName?data.nickName:"匿名"; info.img=data.headImage?data.headImage:require("@/static/image/girl.png"); - if(ifexist==0){ + var idx=this.ifadd(info.id); + if(!idx){ this.grouplist.push(info); this.$forceUpdate(); } + else{ + // this.grouplist[idx-1].sl=(this.grouplist[idx-1].sl?this.grouplist[idx-1].sl+1:1); + this.grouplist[idx-1].content=info.content; + this.grouplist[idx-1].datetime=info.datetime; + this.grouplist[idx-1].fromuser=info.fromuser; + this.grouplist[idx-1].type=info.type; + this.$forceUpdate(); + } // 重新排序 保存缓存 this.reorder(); myCache("chatlist-"+this.userid,this.grouplist); // 聊天框消息缓存 var msgchat=myCache(info.id); - if(ifexist==0||!msgchat){ + if(!msgchat){ // 第一条聊天记录保存缓存 let firstmsg = [{ "fromname": info.name, // 发送人 @@ -723,15 +852,26 @@ else{ info.name="匿名"; info.img="../../static/image/girl.png"; - if(ifexist==0){ + var idx=this.ifadd(info.id); + if(!idx){ this.grouplist.push(info); this.$forceUpdate(); } + else{ + // this.grouplist[idx-1].sl=(this.grouplist[idx-1].sl?this.grouplist[idx-1].sl+1:1); + this.grouplist[idx-1].content=info.content; + this.grouplist[idx-1].datetime=info.datetime; + this.grouplist[idx-1].fromuser=info.fromuser; + this.grouplist[idx-1].type=info.type; + this.$forceUpdate(); + } // 重新排序 this.reorder(); myCache("chatlist-"+this.userid,this.grouplist); + var msgchat=myCache(info.id); - if(ifexist==0||!msgchat){ + console.log(info.id,msgchat); + if(!msgchat){ // 第一条聊天记录保存缓存 let firstmsg = [{ "fromname": info.name, // 发送人 @@ -880,6 +1020,7 @@ background: #fff; margin: 0; width: 100%; + min-width: 600rpx; .lcon{ border-bottom: 1rpx solid #eee; padding-top: 20rpx; @@ -939,6 +1080,12 @@ font-family: PingFang SC, PingFang SC; font-weight: 400; color: #595959; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + /* 假设你的行高是20px,并且你想要两行显示 */ + line-height: 40rpx; /* 每行的行高 */ + max-height: 40rpx; } .lnum{ background-color: #de0000; diff --git a/pages/user/user.vue b/pages/user/user.vue index 0f531b9..f6fda12 100644 --- a/pages/user/user.vue +++ b/pages/user/user.vue @@ -360,11 +360,6 @@ uni.stopPullDownRefresh() },500); }, - // onTabItemTap(){ - // console.log('界面关闭socket,onTabItemTap'); - // // 在组件销毁前,确保关闭 WebSocket 连接 - // uni.closeSocket(); - // }, methods: { ifview(value){ // 描述:角色ID;顾问:103 ;教练:104 ;店长:105 ;普通用户:107; diff --git a/static/icon/voice.png b/static/icon/voice.png index b703979978bc0da4e5af80a02d5db16b2938c56a..b865874f0bf97851669744b89f5fe024918640f4 100644 GIT binary patch delta 1704 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 LNkvXXu0mjfbbTLS literal 0 HcmV?d00001