Ver código fonte

直播间消息的展示及中控台设置用户自见等功能存在bug无法正常使用

yys 5 dias atrás
pai
commit
139d38d7a5
2 arquivos alterados com 113 adições e 48 exclusões
  1. 9 7
      src/store/index.js
  2. 104 41
      src/views/live/liveConsole/LiveConsole.vue

+ 9 - 7
src/store/index.js

@@ -36,24 +36,26 @@ const store = new Vuex.Store({
   actions: {
     // 修改 action 以正确传递参数
     initLiveWs({ commit, state }, { liveWsUrl, liveId, userId }) {
+      const normalizedLiveId = String(liveId);
       // 如果已经存在对应 liveId 的连接,先关闭它
-      if (state.liveWs[liveId]) {
-        state.liveWs[liveId].close();
+      if (state.liveWs[normalizedLiveId]) {
+        state.liveWs[normalizedLiveId].close();
       }
 
       // 创建新的 WebSocket 连接
-      const ws = new LiveWS(liveWsUrl, liveId, userId);
+      const ws = new LiveWS(liveWsUrl, normalizedLiveId, userId);
 
       // 提交到 mutation
-      commit('setLiveWs', { ws, liveId });
+      commit('setLiveWs', { ws, liveId: normalizedLiveId });
 
       return ws;
     },
     // 添加关闭特定 WebSocket 连接的 action
     closeLiveWs({ commit, state }, liveId) {
-      if (state.liveWs[liveId]) {
-        state.liveWs[liveId].close();
-        commit('removeLiveWs', liveId);
+      const normalizedLiveId = String(liveId);
+      if (state.liveWs[normalizedLiveId]) {
+        state.liveWs[normalizedLiveId].close();
+        commit('removeLiveWs', normalizedLiveId);
       }
     }
   }

+ 104 - 41
src/views/live/liveConsole/LiveConsole.vue

@@ -230,8 +230,8 @@
         </div>
         <div class="message-container" @click="handleMessageBoxClick">
           <el-scrollbar class="msg-scroll" ref="manageRightRef">
-            <div v-for="m in msgList" :key="m.msgId" class="msg-item">
-              <div v-if="m.userId === userId && m.msgId == null" class="msg-row msg-row--self">
+            <div v-for="(m, index) in msgList" :key="getMsgKey(m, index)" class="msg-item">
+              <div v-if="isSelfMessage(m)" class="msg-row msg-row--self">
                 <div class="msg-content msg-content--self">
                   <div class="msg-nickname">{{ m.nickName }}</div>
                   <div class="msg-bubble msg-bubble--self">{{ m.msg }}</div>
@@ -246,7 +246,7 @@
                   <div class="msg-actions">
                     <a class="action-link" @click.stop="changeUserState(m)">{{ m.msgStatus === 1 ? '解禁' : '禁言' }}</a>
                     <a class="action-link" @click.stop="blockUser(m)">拉黑</a>
-                    <a class="action-link" @click.stop="singleVisible(m)">{{ m.singleVisible === 1 ? '解除用户自见' : '用户自见' }}</a>
+                    <a class="action-link" @click.stop="singleVisible(m)">{{ isSingleVisible(m) ? '解除用户自见' : '用户自见' }}</a>
                     <a class="action-link" @click.stop="deleteMsg(m)">删除</a>
                   </div>
                 </div>
@@ -475,6 +475,7 @@ export default {
         pageSize: 30,
         liveId: null
       },
+      chatScrollTop: 0,
       opsTabActive: 'marketing',
       marketingCategory: 'goods',
       marketingCategories: [
@@ -695,11 +696,27 @@ export default {
     },
     ensureSocket() {
       if (!this.socket) {
-        this.$message.error('请从直播间开启 WebSocket 连接');
+        this.$message.error('WebSocket 连接,请稍后重试');
         return false;
       }
       return true;
     },
+    isSameUser(id1, id2) {
+      if (id1 == null || id2 == null) return false;
+      return String(id1) === String(id2);
+    },
+    isSelfMessage(m) {
+      return this.isSameUser(m.userId, this.userId);
+    },
+    isSingleVisible(m) {
+      return Number(m.singleVisible) === 1;
+    },
+    getMsgKey(m, index) {
+      if (m.msgId != null && m.msgId !== '') {
+        return m.msgId;
+      }
+      return `msg-${index}-${m.userId || 'unknown'}`;
+    },
     handleGoodsShelf(row, status) {
       handleShelfOrUn({ goodsIds: [row.goodsId], status, liveId: this.liveId }).then(res => {
         if (res.code === 200) {
@@ -931,18 +948,22 @@ export default {
       this.loadMsgList();
     },
     singleVisible(m){
-      // 过滤当前所有消息 找到userId的相同的消息 更改他们的自可见状态
-      m.singleVisible= m.singleVisible === 1 ? 0 : 1
-      this.msgList.forEach(m1 => {m1.singleVisible = m1.userId === m.userId ? m.singleVisible : !m.singleVisible})
-      // 消息自可见
-      let msg = {
+      const newStatus = this.isSingleVisible(m) ? 0 : 1;
+      m.singleVisible = newStatus;
+      this.msgList.forEach(m1 => {
+        if (this.isSameUser(m1.userId, m.userId)) {
+          m1.singleVisible = newStatus;
+        }
+      });
+      if (!this.ensureSocket()) return;
+      const msg = {
         liveId: this.liveId,
         userId: m.userId,
         userType: 0,
         cmd: 'singleVisible',
-        status:m.singleVisible
-      }
-      this.socket.send(JSON.stringify(msg))
+        status: newStatus
+      };
+      this.socket.send(JSON.stringify(msg));
     },
     deleteMsg(m){
       // 1. 弹出确认对话框
@@ -961,9 +982,10 @@ export default {
             let msg = {
               liveId: this.liveId,
               userId: m.userId,
-              msg: m.msgId, // 关键:将消息ID发送给后台
+              msg: m.msgId,
               cmd: 'deleteMsg',
             };
+            if (!this.ensureSocket()) return;
             this.socket.send(JSON.stringify(msg));
             // 可以在这里给用户一个删除成功的提示
             this.$message({
@@ -980,16 +1002,19 @@ export default {
         });
       });
     },
-    globalVisibleChange( val){
-      // 消息自可见
-      let msg = {
+    globalVisibleChange(){
+      if (!this.ensureSocket()) {
+        this.globalVisible = !this.globalVisible;
+        return;
+      }
+      const msg = {
         liveId: this.liveId,
         userId: '9999',
         userType: 0,
         cmd: 'globalVisible',
-        status:this.globalVisible ? 1 :0
-      }
-      this.socket.send(JSON.stringify(msg))
+        status: this.globalVisible ? 1 : 0
+      };
+      this.socket.send(JSON.stringify(msg));
     },
     showCartChange(val) {
       const status = val ? 1 : 0
@@ -997,16 +1022,6 @@ export default {
         if (res.code !== 200) {
           this.$message.error(res.msg || '更新购物车显示状态失败')
           this.showCart = !val
-          return
-        }
-        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
-          this.socket.send(JSON.stringify({
-            liveId: this.liveId,
-            userId: '9999',
-            userType: 0,
-            cmd: 'showCart',
-            status
-          }))
         }
       }).catch(() => {
         this.showCart = !val
@@ -1065,10 +1080,10 @@ export default {
       this.watermarkIndex += 1
     },
     sendMessage() {
-      // 发送前简单校验
       if (this.newMsg.trim() === '') {
         return;
       }
+      if (!this.ensureSocket()) return;
 
       let msg = {
         msg: this.newMsg,
@@ -1085,18 +1100,20 @@ export default {
       this.newMsg = '';
     },
     handleWsMessage(event) {
-      let { code, data } = JSON.parse(event.data)
-      if (code === 200) {
+      try {
+        let { code, data } = JSON.parse(event.data)
+        if (code === 200) {
         let { cmd } = data
         if (cmd === 'sendMsg') {
           let message = JSON.parse(data.data)
 
-          let user = this.alDisplayList.find(u => u.userId === message.userId)
+          let user = this.alDisplayList.find(u => this.isSameUser(u.userId, message.userId))
           if (user) {
             message.msgStatus = user.msgStatus
           } else {
             message.msgStatus = 0
           }
+          message.singleVisible = message.singleVisible == null ? 0 : Number(message.singleVisible)
           delete message.params
           if(this.msgList.length > 50){
             this.msgList.shift()
@@ -1161,7 +1178,28 @@ export default {
 
         } else if (cmd === 'live_end') {
 
+        } else if (cmd === 'deleteMsg') {
+          const msgId = data.msg || data.msgId;
+          if (msgId != null) {
+            const index = this.msgList.findIndex(item => String(item.msgId) === String(msgId));
+            if (index !== -1) {
+              this.msgList.splice(index, 1);
+            }
+          }
+        } else if (cmd === 'singleVisible') {
+          const targetUserId = data.userId;
+          const status = Number(data.status) === 1 ? 1 : 0;
+          this.msgList.forEach(m1 => {
+            if (this.isSameUser(m1.userId, targetUserId)) {
+              m1.singleVisible = status;
+            }
+          });
+        } else if (cmd === 'globalVisible') {
+          this.globalVisible = Number(data.status) === 1 || data.status === true;
         }
+        }
+      } catch (e) {
+        console.error('WebSocket message parse error:', e);
       }
     },
     getLive(){
@@ -1200,7 +1238,7 @@ export default {
             }
           }
           this.$nextTick(() => {
-            this.globalVisible = res.data.globalVisible
+            this.globalVisible = res.data.globalVisible === 1 || res.data.globalVisible === true
             this.showCart = res.data.showCart == null || res.data.showCart === 1
             if (this.$refs.livePlayer) {
               this.$refs.livePlayer.initPlayer()
@@ -1215,13 +1253,27 @@ export default {
       })
     },
     connectWebSocket() {
+      const liveId = this.liveId;
       this.$store.dispatch('initLiveWs', {
         liveWsUrl: this.liveWsUrl,
-        liveId: this.liveId,
+        liveId,
         userId: this.userId
-      })
-      this.socket = this.$store.state.liveWs[this.liveId]
-      this.socket.onmessage = (event) => this.handleWsMessage(event)
+      });
+      this.socket = this.$store.state.liveWs[liveId];
+      if (!this.socket) {
+        this.$message.error('WebSocket 初始化失败');
+        return;
+      }
+      this.socket.onmessage = (event) => this.handleWsMessage(event);
+      const nativeWs = this.socket.ws;
+      if (nativeWs) {
+        nativeWs.addEventListener('open', () => {
+          console.log('[LiveConsole] WebSocket connected');
+        }, { once: true });
+        nativeWs.addEventListener('error', () => {
+          this.$message.error('WebSocket 连接失败,请确认 fs-live-app(7114) 已启动');
+        }, { once: true });
+      }
     },
     changeUserState(u) {
       const displayList = this[`${this.currentTab}DisplayList`];
@@ -1550,12 +1602,13 @@ export default {
           let totalPage = (total % this.msgParams.pageSize == 0) ? Math.floor(total / this.msgParams.pageSize) : Math.floor(total / this.msgParams.pageSize + 1);
           rows.forEach(row => {
             if (!this.msgList.some(m => m.msgId === row.msgId)) {
-              let user = this.alDisplayList.find(u => u.userId === row.userId)
+              let user = this.alDisplayList.find(u => this.isSameUser(u.userId, row.userId))
               if (user) {
                 row.msgStatus = user.msgStatus
               } else {
                 row.msgStatus = 0
               }
+              row.singleVisible = row.singleVisible == null ? 0 : Number(row.singleVisible)
               this.msgList.push(row)
             }
           })
@@ -1563,7 +1616,7 @@ export default {
           this.msgList.reverse()
           // 同步更新消息列表中相同用户的状态
           this.alDisplayList.forEach(u => {
-            this.msgList.filter(m => m.userId === u.userId).forEach(m => m.msgStatus = u.msgStatus)
+            this.msgList.filter(m => this.isSameUser(m.userId, u.userId)).forEach(m => m.msgStatus = u.msgStatus)
           })
           // 所有消息加载完成后,根据自动滚动状态决定是否滚动
           this.$nextTick(() => {
@@ -2159,16 +2212,26 @@ export default {
   flex: 1;
   min-height: 0;
   padding: 8px 16px 0;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
 }
 
 .msg-scroll {
-  height: 100%;
+  flex: 1;
+  min-height: 0;
+  height: auto;
 }
 
 .msg-scroll ::v-deep .el-scrollbar {
   height: 100%;
 }
 
+.msg-scroll ::v-deep .el-scrollbar__wrap {
+  height: 100% !important;
+  max-height: 100%;
+}
+
 .msg-item + .msg-item {
   margin-top: 8px;
 }