From d0d825e09ffdb95e9c4edcc44eeff08c4b2a9c23 Mon Sep 17 00:00:00 2001 From: luohairen <3399054449@qq.com> Date: 星期四, 07 十一月 2024 15:53:22 +0800 Subject: [PATCH] 完成教师端,考试列表展示 --- src/views/meet/index.vue | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 324 insertions(+), 15 deletions(-) diff --git a/src/views/meet/index.vue b/src/views/meet/index.vue index 8b6e996..6fef657 100644 --- a/src/views/meet/index.vue +++ b/src/views/meet/index.vue @@ -1,24 +1,333 @@ <template> - <body><div id="meet" /></body> + <div> + <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-col> + <el-col :span="2"> + <el-button type="primary" size="small" @click="getStudentList">鎼滅储</el-button> + </el-col> + </el-row> + <el-tabs v-model="searchForm.onlineStatus" @tab-click="handleTabChange" style="margin-left: 3px"> + <el-tab-pane label="鍦ㄧ嚎瀛﹀憳" name="1"></el-tab-pane> + <el-tab-pane label="绂荤嚎瀛﹀憳" name="0"></el-tab-pane> + </el-tabs> + <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> + </div> </template> -<script src='https://ycl.easyblog.vip:8443/external_api.js'></script> <script> -let api -const initIframeAPI = () => { - const domain = 'ycl.easyblog.vip:8443' - const options = { - roomName: 'test', - width: 700, - height: 700, - parentNode: document.querySelector('#meet') +import { getStudentList } from '@/api/meet' +import Cookies from 'js-cookie' + +export default { + data () { + return { + ws: null, + jitsiApi: null, + width: 0, + height: 0, + showStudent: true, + intervalId: null, + meetId: null, + roomName: '', + joinList: [], + searchForm: { + keyword: '', + // 0 鏈湪绾裤�� 1 鍦ㄧ嚎 + onlineStatus: 0 + }, + studentList: [], + showStudentList: [] + } + }, + beforeDestroy () { + if (this.ws) { + this.ws.close() + } + }, + methods: { + muteEveryone () { + this.jitsiApi.executeCommand('muteEveryone', 'audio') + const h = this.$createElement; + + this.$notify({ + title: '鎻愮ず', + message: h('i', { style: 'color: teal'}, '宸插叏浣撶闊�') + }); + }, + videoEveryone () { + this.jitsiApi.executeCommand('muteEveryone', 'video') + const h = this.$createElement; + + this.$notify({ + title: '鎻愮ず', + message: h('i', { style: 'color: teal'}, '宸插叧闂叏浣撹棰�') + }); + }, + handleCommand (command) { + this.sendMessage(JSON.stringify(command)) + }, + initWebSocket () { + this.ws = new WebSocket('wss://www.kgmeet.com:18080/websocket/' + JSON.parse(Cookies.get('adminUserInfo')).id) + 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) { + this.jitsiApi.resizeLargeVideo(width, height) + }, + getShowText () { + if (this.showStudent) { + return '闅愯棌' + } else { + return '鏄剧ず' + } + }, + getStatus (status) { + if (status === 1) { + return '鍦ㄧ嚎' + } else if (status === 0) { + return '绂荤嚎' + } + }, + handleTabChange (tab) { + let status = parseInt(tab.name) + this.showStudentList = this.studentList.filter(student => { + return student.onlineStatus === status + }) + }, + getStudentList () { + let params = { + keyword: this.searchForm.keyword + } + getStudentList(this.meetId, params).then(res => { + this.studentList = res.data.data + this.showStudentList = this.studentList.filter(student => { + return student.onlineStatus === this.searchForm.onlineStatus + }) + }) + }, + getRoomInfo () { + this.jitsiApi.getRoomsInfo().then(rooms => { + rooms.rooms.forEach(room => { + // 鎴块棿鐨刬d鏄竴涓瓙鍩熷悕锛屼笖@绗﹀墠鐨勪細璁悕绉版槸缁忚繃URL缂栫爜鐨� + let encodedPart = room.id.split('@')[0] + let decodedPart = decodeURIComponent(encodedPart) + if (this.roomName === decodedPart) { + room.participants.forEach(user => { + // 浣跨敤'_'浣滀负鍒嗛殧绗﹀垎鍓插瓧绗︿覆锛岃幏鍙栧埌userId + const parts = user.displayName.split('_') + let userId = null + if (parts.length > 1) { + userId = parseInt(parts[1]) + // 璁剧疆瀛﹀憳鐘舵�佷负鍦ㄧ嚎 + this.studentList.forEach(student => { + console.log(student.id === userId) + if (student.id === userId) { + student.onlineStatus = 1 + } + }) + } + }) + } + }) + this.showStudentList = this.studentList.filter(student => { + return student.onlineStatus === parseInt(this.searchForm.onlineStatus) + }) + }) + } + }, + mounted () { + this.height = window.innerHeight + this.meetId = this.$route.query.meetId + this.getStudentList() + const domain = this.$route.query.domain + const roomName = this.$route.query.roomName + this.roomName = roomName + const userInfoStr = this.$route.query.userInfoStr + const userInfo = userInfoStr ? JSON.parse(userInfoStr) : null + const options = { + roomName: roomName, + height: this.height, + parentNode: this.$refs.meet, + lang: 'zh_CN', + userInfo: userInfo, + configOverwrite: { + prejoinConfig: { + enabled: false + }, + // 绂佺敤閭�璇� + disableInviteFunctions: true, + // 绂佺敤閭 + gravatar: { + disabled: true + }, + // 绂佺敤鏀瑰悕 + readOnlyName: true, + // 鑷畾涔夋寜閽� + toolbarButtons: [ + // 鎽勫儚澶� + 'camera', + // 鑱婂ぉ + 'chat', + // 鍏变韩 + 'desktop', + 'download', + 'fullscreen', + 'hangup', + // 'help', + 'highlight', + // 'invite', + 'linktosalesforce', + 'livestreaming', + 'microphone', + 'noisesuppression', + 'recording', + 'select-background', + 'settings', + 'shareaudio', + 'sharedvideo', + 'shortcuts', + 'stats', + 'tileview', + 'toggle-camera', + 'whiteboard', + + // 'closedcaptions', + // 'embedmeeting', + // 'etherpad', + // 'feedback', + // 'filmstrip', + 'participants-pane', + // 'profile', + 'raisehand', + // 'security', + 'videoquality', + ], + whiteboard: { + enabled: true + } + } + } + + this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options) + + this.jitsiApi.addListener('readyToClose', () => { + window.close() + }) + // 鍒濆鍖� + this.initWebSocket() + // 姣忎笁绉掓洿瀛﹀憳鍦ㄧ嚎鐘舵�� + this.intervalId = setInterval(() => { + this.getRoomInfo() + // 鍙戦�佸績璺虫暟鎹� + this.ws.send('ping') + }, 2500) + + }, + beforeDestroy () { + // 娓呴櫎瀹氭椂鍣紝閬垮厤鍐呭瓨娉勬紡 + if (this.intervalId) { + clearInterval(this.intervalId) + this.intervalId = null + } } - api = new JitsiMeetExternalAPI(domain, options) } -window.onload = () => { - initIframeAPI() -} </script> -<style lang="scss" scoped></style> +<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; + color: #565b5e; +} +</style> -- Gitblit v1.8.0