Zory 12 часов назад
Родитель
Сommit
80c2ce9347
2 измененных файлов с 58 добавлено и 16 удалено
  1. 1 1
      src/components/imFloat/im.vue
  2. 57 15
      src/components/imFloat/imFloat.vue

+ 1 - 1
src/components/imFloat/im.vue

@@ -459,7 +459,7 @@ export default {
          * @param data 
          */
         async sendAddress(data){
-            var orderData = {"img":data.img,"name":"补充收货地址","order":data.out_order_no,"status":0};
+            var orderData = {"img":data.img,"name":"完善会员资料","order":data.out_order_no,"status":0};
             var resp = await this.sendMessageApi("address",orderData);
             if (!resp) {
                 return ;

+ 57 - 15
src/components/imFloat/imFloat.vue

@@ -17,7 +17,7 @@
                     <div class="drawer-detail-header-body">
                         <div class="drawer-detail-header-left">在线客服</div>
                         <div class="drawer-detail-header-left">
-                            <el-button type="default" icon="el-icon-close" @click="hideWindow">隐藏窗口</el-button>
+                            <el-button type="default" icon="el-icon-close" round @click="hideWindow"></el-button>
                         </div>
                     </div>
                 </div>
@@ -33,9 +33,12 @@
                             <el-main class="nopadding">
                                 <div class="chat-contact">
                                     <div :class="checkChat==index?'contact-item active':'contact-item'" v-for="(item,index) in chatContact" :key="index" @click="checkChatItem(index)">
-                                            <div class="img"><el-image :src="item.user.avatar" fit="contain" style="width: 40px; height: 40px"></el-image></div>
+                                            <div class="img">
+                                                <el-image :src="item.user.avatar" fit="contain" style="width: 40px; height: 40px"></el-image>
+                                                <span class="last-num" v-if="item.last.num > 0">{{item.last.num}}</span>
+                                            </div>
                                             <div class="kefu-store">
-                                            <div class="name">{{item.user.nickname}} <span v-if="item.last.num > 0">{{item.last.num}}</span></div>
+                                            <div class="name">{{item.user.nickname}}</div>
                                             <div class="desc" v-if="item.last.type=='text'">{{item.last.content}}</div>
                                             <div class="desc" v-if="item.last.type=='order'">[订单消息]</div>
                                             <div class="desc" v-if="item.last.type=='image'">[图片消息]</div>
@@ -44,7 +47,7 @@
                                             <div class="desc" v-if="item.last.type=='address'">[收集地址]</div>
                                         </div>
                                         <div class="time">
-                                            {{item.last_time}}
+                                            {{item.last.create_at}}
                                         </div>
                                     </div>
                                 </div>
@@ -726,6 +729,7 @@ export default {
             user_channel.on('message', function (data) {
                 _this.playAudio()
                 _this.unreadCount ++;
+                _this.sortItemData(data.item)
                 if (_this.chatItem && _this.chatItem.openid == data.openid) { // 当前窗口实时推送
                     _this.formatMsg(data);
                 }
@@ -735,14 +739,47 @@ export default {
                     var item = msgData[i];
                     if (item && item.openid == data.openid) {
                         item.last.type = data.type;
-                        item.last.num ++;
                         item.last.content = data.content;
                         item.last.create_at = data.create_at
                         item.last.last_at = data.last_at
+                        // item.last.num ++;
                     }
                 }
             })
         },
+        truncateByBytes(str, maxBytes) {
+            let count = 0;
+            let result = '';
+            for (const char of str) {
+                // 中文、全角符号算 2 字节,其他算 1 字节
+                const byteLen = char.match(/[^\x00-\xff]/) ? 2 : 1;
+                if (count + byteLen > maxBytes) break;
+                result += char;
+                count += byteLen;
+            }
+            return result + (count < str.length ? '...' : '');
+        },
+        sortItemData(data){
+            const existIdx = this.chatContact.findIndex(item => item.id === data.id);
+            if (existIdx !== -1) { // 若已存在,按更新处理
+                this.handleNewMessage(data);
+                return;
+            }
+            // 新增数据到最顶部
+            this.chatContact.unshift(data);
+        },
+        handleNewMessage(updateData) {
+            const idx = this.chatContact.findIndex(item => item.id === updateData.id);
+            this.chatContact.splice(idx, 1, updateData);
+            this.sortSessions();
+        },
+        sortSessions() {
+            this.chatContact.sort((a, b) => {
+                const timeA = a.last_at && a.last_at !== '-' ? new Date(a.last_at).getTime() : 0;
+                const timeB = b.last_at && b.last_at !== '-' ? new Date(b.last_at).getTime() : 0;
+                return timeB - timeA;
+            });
+        },
         sortBooks() {
             this.chatContact.sort((a, b) => b.last_at - a.last_at)
         },
@@ -815,18 +852,19 @@ export default {
         // 切换聊天窗口
         async toggleChat() {
             this.visible = !this.visible
-            this.loadMsg = true;
-            this.chatContact = [];
             if (this.visible) {
                 // 打开窗口时清除未读角标
                 this.unreadCount = 0
             }
-            var resp = await this.$API.chat.list.get({page:this.page,pageSize:this.size})
-            this.loadMsg = false;
-            if (resp.code == 0) {
-              return this.$message.error(resp.msg)
+            if (this.chatContact.length == 0) {
+                this.loadMsg = true;
+                var resp = await this.$API.chat.list.get({page:this.page,pageSize:this.size})
+                this.loadMsg = false;
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg)
+                }
+                this.chatContact = this.chatContact.concat(resp.data.rows)
             }
-            this.chatContact = this.chatContact.concat(resp.data.rows)
             // this.chatItem = this.chatContact[0]
             // this.userId = this.chatItem.openid;
             // this.getMsgData();
@@ -931,7 +969,7 @@ export default {
             var resp = await this.$API.chat.send.post({type:type,content: content,groupId: this.chatItem.poi_id,openid:this.chatItem.openid})
             if (resp.code == 0) return false;
             this.chatContact[this.checkChat].last.type = type;
-            this.chatContact[this.checkChat].last.content = content;
+            this.chatContact[this.checkChat].last.content = (type=='text'?this.truncateByBytes(content,18):content);
             this.chatContact[this.checkChat].last.create_at = resp.data.time;
             return true;
         },
@@ -961,7 +999,7 @@ export default {
 .aside-tabs{display: flex;height: 65px;align-items: center;gap: 10px;border-bottom: 1px solid var(--el-border-color-light);padding: 13px 15px;}
 .aside-tabs .aside-tab-items{font-size: 14px;cursor: pointer;padding: 0 20px;}
 .aside-tabs .aside-tab-items.active{color: var(--el-color-primary);}
-.quick-search{display: flex;align-items: center;justify-content: space-between;}
+.quick-search{display: flex;align-items: center;justify-content: space-between;gap: 10px;}
 .quick-search .search-input{flex: 1;display: flex;align-items: center;gap: 5px;}
 .quick-search .search-btn-txt{font-size: 14px;color: #409eff;cursor: pointer;}
 .quick-table .quick-table-body{margin: 10px 0;}
@@ -991,9 +1029,13 @@ export default {
 .hideStr{overflow: hidden;width: 80%;}
 .contact-item{display: flex;align-items: center;background-color: #fff;padding: 10px;border-bottom: 1px solid #f8f8f8;cursor: pointer;}
 .contact-item.active{background-color: #f8f8f8;}
+.contact-item .img{position: relative;border: 1px solid #f8f8f8;border-radius: 5px;display: flex;align-items: center;justify-content: center;}
+.contact-item span.last-num{background-color: #f00;color: #fff;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;border-radius: 20px;font-size: 12px;margin-left: 10px;position: absolute;right: 0;top: 0;}
+
 .contact-item .kefu-store{margin-left: 10px;}
 .contact-item .kefu-store .name{font-size: 14px;color: #333;display: flex;align-items: center;}
-.contact-item .kefu-store .name span{background-color: #f00;color: #fff;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;border-radius: 20px;font-size: 12px;margin-left: 10px;}
+
+
 .contact-item .kefu-store .desc{font-size: 12px;color: #666;margin-top: 5px;}
 .contact-item .time{margin-left: auto;margin-right: 0;font-size: 12px;color: #666;}
 .send-btn-group{margin-top: 10px;display: flex;align-items: center;justify-content: space-between;}