From 8e867f310b54fe94fe8914608ede9a06836937c3 Mon Sep 17 00:00:00 2001
From: 龚焕茏 <2842157468@qq.com>
Date: 星期一, 12 八月 2024 16:52:39 +0800
Subject: [PATCH] feat:自带命令全体静音、关闭摄像头

---
 src/views/meet/index.vue |  183 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 151 insertions(+), 32 deletions(-)

diff --git a/src/views/meet/index.vue b/src/views/meet/index.vue
index a4c38cb..8b86a28 100644
--- a/src/views/meet/index.vue
+++ b/src/views/meet/index.vue
@@ -1,13 +1,15 @@
 <template>
   <div>
-    <div style="display: flex; flex-direction: row; position: relative">
-      <div id="meet" ref="meet"/>
-      <div style="padding-top: 5px; padding-left: 5px; position: absolute;right: 15px">
-        <el-button type="success" size="small" @click="hiddenStudent" >{{getShowText()}}</el-button>
+    <div style="display: flex; flex-direction: row;">
+      <div id="meet" ref="meet" style="flex-grow: 1;">
+      </div>
+      <div style="padding-top: 5px; padding-left: 5px;right: 15px">
+        <el-button type="success" size="small" @click="hiddenStudent">{{ getShowText() }}</el-button>
         <el-row v-show="showStudent">
           <el-row :gutter="5">
             <el-col :span="12">
-              <el-input placeholder="鎼滅储瀛﹀憳" size="small" clearable @input="getStudentList" @clear="getStudentList" v-model="searchForm.keyword"/>
+              <el-input placeholder="鎼滅储瀛﹀憳" size="small" clearable @input="getStudentList" @clear="getStudentList"
+                v-model="searchForm.keyword" />
             </el-col>
             <el-col :span="2">
               <el-button type="primary" size="small" @click="getStudentList">鎼滅储</el-button>
@@ -17,18 +19,30 @@
             <el-tab-pane label="鍦ㄧ嚎瀛﹀憳" name="1"></el-tab-pane>
             <el-tab-pane label="绂荤嚎瀛﹀憳" name="0"></el-tab-pane>
           </el-tabs>
-          <el-row :gutter="20" v-for="student in showStudentList" :key="student.id" class="student-row">
-            <el-col :span="18">
-              <div>
-                {{student.realName}}
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div :class="{online: student.onlineStatus === 1, outline: student.onlineStatus === 0}">
-                {{getStatus(student.onlineStatus)}}
-              </div>
-            </el-col>
-          </el-row>
+          <el-table :data="showStudentList" style="width: 100%">
+            <el-table-column prop="realName" label="瀛﹀憳濮撳悕"></el-table-column>
+            <el-table-column prop="id" label="鎿嶄綔" width="80px;">
+              <template slot-scope="scope">
+                <el-dropdown trigger="click" @command="handleCommand">
+                  <i class="el-icon-more-outline" id="more"></i>
+                  <el-dropdown-menu slot="dropdown">
+                    <el-dropdown-item :command="{ command: 'openCamera', id: scope.row.id }">鎵撳紑/鍏抽棴鎽勫儚澶�</el-dropdown-item>
+                    <el-dropdown-item :command="{ command: 'mute', id: scope.row.id }">闈欓煶/鍙栨秷闈欓煶</el-dropdown-item>
+                    <el-dropdown-item :command="{ command: 'kickOut', id: scope.row.id }">韪㈠嚭</el-dropdown-item>
+                  </el-dropdown-menu>
+                </el-dropdown>
+              </template>
+            </el-table-column>
+            <el-table-column prop="onlineStatus" label="鐘舵��" width="80px;">
+              <template slot-scope="scope">
+                <div :class="{ online: scope.row.onlineStatus === 1, outline: scope.row.onlineStatus === 0 }">
+                  {{ getStatus(scope.row.onlineStatus) }}
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-button class="link-left" type="primary" size="small" @click="muteEveryone">鍏ㄤ綋闈欓煶</el-button>
+          <el-button class="link-left" type="primary" size="small" @click="videoEveryone">鍏ㄤ綋鍏抽棴鎽勫儚澶�</el-button>
         </el-row>
       </div>
     </div>
@@ -37,10 +51,10 @@
 
 <script>
 import { getStudentList } from '@/api/meet'
-
 export default {
-  data () {
+  data() {
     return {
+      ws: null,
       jitsiApi: null,
       width: 0,
       height: 0,
@@ -58,34 +72,80 @@
       showStudentList: []
     }
   },
+  beforeDestroy() {
+    if (this.ws) {
+      this.ws.close();
+    }
+  },
   methods: {
-    hiddenStudent () {
+    muteEveryone() {
+      this.jitsiApi.executeCommand('muteEveryone', 'audio');
+    },
+    videoEveryone() {
+      this.jitsiApi.executeCommand('muteEveryone', 'video');
+    },
+    handleCommand(command) {
+      this.sendMessage(JSON.stringify(command))
+    },
+    initWebSocket() {
+      this.ws = new WebSocket('ws://127.0.0.1:8000/websocket/' + 1);
+      let ws = this.ws;
+      ws.onopen = () => {
+        console.log('WebSocket 杩炴帴鎴愬姛');
+        // 鍙戦�佸績璺虫暟鎹�
+        ws.send('ping');
+      };
+      ws.onmessage = (event) => {
+        console.log('鏀跺埌鏈嶅姟鍣ㄦ秷鎭�:', event.data);
+        // 澶勭悊鏈嶅姟鍣ㄥ彂鏉ョ殑娑堟伅
+      };
+      ws.onerror = (error) => {
+        console.error('WebSocket 杩炴帴鍑洪敊:', error);
+      };
+      ws.onclose = () => {
+        console.log('WebSocket 杩炴帴宸插叧闂�');
+        // 鍙互鍦ㄨ繖閲屽皾璇曢噸鏂拌繛鎺�
+      };
+
+      // 缁勪欢閿�姣佹椂鏂紑 WebSocket 杩炴帴
+      this.$once('hook:beforeDestroy', () => {
+        ws.close();
+      });
+    },
+    sendMessage(message) {
+      if (this.ws.readyState === WebSocket.OPEN) {
+        this.ws.send(message);
+      } else {
+        console.error('WebSocket 杩炴帴鏈墦寮�');
+      }
+    },
+    hiddenStudent() {
       this.showStudent = !this.showStudent
     },
-    changeJitsiWindowSize (width, height) {
+    changeJitsiWindowSize(width, height) {
       this.jitsiApi.resizeLargeVideo(width, height)
     },
-    getShowText () {
+    getShowText() {
       if (this.showStudent) {
         return '闅愯棌'
       } else {
         return '鏄剧ず'
       }
     },
-    getStatus (status) {
+    getStatus(status) {
       if (status === 1) {
         return '鍦ㄧ嚎'
       } else if (status === 0) {
         return '绂荤嚎'
       }
     },
-    handleTabChange (tab) {
+    handleTabChange(tab) {
       let status = parseInt(tab.name)
       this.showStudentList = this.studentList.filter(student => {
         return student.onlineStatus === status
       })
     },
-    getStudentList () {
+    getStudentList() {
       let params = {
         keyword: this.searchForm.keyword
       }
@@ -96,7 +156,7 @@
         })
       })
     },
-    getRoomInfo () {
+    getRoomInfo() {
       this.jitsiApi.getRoomsInfo().then(rooms => {
         rooms.rooms.forEach(room => {
           // 鎴块棿鐨刬d鏄竴涓瓙鍩熷悕锛屼笖@绗﹀墠鐨勪細璁悕绉版槸缁忚繃URL缂栫爜鐨�
@@ -126,8 +186,7 @@
       })
     }
   },
-  mounted () {
-    this.width = window.innerWidth * 0.8
+  mounted() {
     this.height = window.innerHeight
     this.meetId = this.$route.query.meetId
     this.getStudentList()
@@ -138,7 +197,6 @@
     const userInfo = userInfoStr ? JSON.parse(userInfoStr) : null
     const options = {
       roomName: roomName,
-      width: this.width,
       height: this.height,
       parentNode: this.$refs.meet,
       lang: 'zh_CN',
@@ -147,11 +205,57 @@
         prejoinConfig: {
           enabled: false
         },
+        // 绂佺敤閭�璇�
+        disableInviteFunctions: true,
+        // 绂佺敤閭
+        gravatar: {
+          disabled: true
+        },
+        // 绂佺敤鏀瑰悕
+        readOnlyName: true,
+        // 鑷畾涔夋寜閽�
+        toolbarButtons: [
+          // 鎽勫儚澶�
+          'camera',
+          // 鑱婂ぉ
+          'chat',
+          // 'closedcaptions',
+          // 鍏变韩
+          'desktop',
+          'download',
+          // 'embedmeeting',
+          // 'etherpad',
+          // 'feedback',
+          // 'filmstrip',
+          'fullscreen',
+          'hangup',
+          // 'help',
+          'highlight',
+          // 'invite',
+          'linktosalesforce',
+          'livestreaming',
+          'microphone',
+          'noisesuppression',
+          // 'participants-pane',
+          // 'profile',
+          // 'raisehand',
+          'recording',
+          // 'security',
+          'select-background',
+          'settings',
+          'shareaudio',
+          'sharedvideo',
+          'shortcuts',
+          'stats',
+          'tileview',
+          'toggle-camera',
+          // 'videoquality',
+          'whiteboard'
+        ],
         whiteboard: {
           enabled: true
         }
-      },
-      toolbarButtons: ['whiteboard']
+      }
     }
 
     this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options)
@@ -163,8 +267,11 @@
     this.intervalId = setInterval(() => {
       this.getRoomInfo()
     }, 2500)
+
+    // 鍒濆鍖�
+    this.initWebSocket();
   },
-  beforeDestroy () {
+  beforeDestroy() {
     // 娓呴櫎瀹氭椂鍣紝閬垮厤鍐呭瓨娉勬紡
     if (this.intervalId) {
       clearInterval(this.intervalId)
@@ -176,19 +283,31 @@
 </script>
 
 <style lang="scss" scoped>
+/deep/ thead {
+  display: none;
+}
+
+#more:hover {
+  cursor: pointer;
+}
+
 #meet {
   height: 100%;
 }
+
 .online {
   color: #42b983;
 }
+
 .outline {
   color: #aa1111;
 }
+
 .studentWarp {
   display: flex;
   flex-direction: row;
 }
+
 .student-row {
   margin-top: 8px;
   padding-left: 3px;

--
Gitblit v1.8.0