xiangpei
2024-07-12 ad6b1e9102d62d175f2496a5f96e1fbe81b53c3d
会议展示学生在线情况
4个文件已修改
165 ■■■■■ 已修改文件
src/api/meet.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/meet/index.vue 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/train/data-list/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/train/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/meet.js
@@ -58,6 +58,7 @@
    data: params
  })
}
// 添加会议表
export const addMeet = (params) => {
  return axios({
@@ -66,3 +67,12 @@
    data: params
  })
}
// 获取会议学生
export const getStudentList = (id, params) => {
  return axios({
    url: "/api/admin/meet/students/" + id,
    method: "GET",
    params: params
  })
}
src/views/meet/index.vue
@@ -1,16 +1,122 @@
<template>
  <div id="meet" ref="meet">
  <div>
    <div style="display: flex; flex-direction: row">
      <div id="meet" ref="meet"/>
      <div style="padding: 5px">
        <el-row :gutter="5">
          <el-col :span="22">
            <el-input placeholder="搜索" size="small" v-model="searchForm.keyword"/>
          </el-col>
          <el-col :span="2">
            <el-button type="primary" size="small" @click="getRoomInfo">搜索</el-button>
          </el-col>
        </el-row>
        <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-row>
        <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>
      </div>
    </div>
  </div>
</template>
<script>
import { getStudentList } from '@/api/meet'
let jitsiApi = null
export default {
  data() {
    return {
      intervalId: null,
      meetId: null,
      roomName: '',
      joinList: [],
      searchForm: {
        keyword: '',
        // 0 未在线、 1 在线
        onlineStatus: 0,
      },
      studentList: [],
      showStudentList: [],
    }
  },
  methods: {
    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.keyword
      }
      getStudentList(this.meetId, params).then(res => {
        this.studentList = res.data.data
        this.showStudentList = this.studentList.filter(student => {
          return student.onlineStatus === 0
        })
      })
    },
    getRoomInfo () {
      jitsiApi.getRoomsInfo().then(rooms => {
        rooms.rooms.forEach(room => {
          // 房间的id是一个子域名,且@符前的会议名称是经过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 () {
    const width = window.innerWidth
    const width = window.innerWidth * 0.7
    const 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 = {
@@ -30,11 +136,23 @@
      },
      toolbarButtons: ['whiteboard']
    }
    jitsiApi = new window.JitsiMeetExternalAPI(domain, options)
    jitsiApi.addListener('readyToClose', () => {
      window.close()
    })
    // 每三秒更学员在线状态
    this.intervalId = setInterval(() => {
      this.getRoomInfo()
    }, 3000)
  },
  beforeDestroy () {
    // 清除定时器,避免内存泄漏
    if (this.intervalId) {
      clearInterval(this.intervalId)
      this.intervalId = null
    }
  }
}
@@ -42,7 +160,21 @@
<style lang="scss" scoped>
#meet {
  width: 100%;
  height: 100%;
}
.online {
  color: #42b983;
}
.outline {
  color: #aa1111;
}
.studentWarp {
  display: flex;
  flex-display: row;
}
.student-row {
  margin-top: 8px;
  padding-left: 3px;
  color: #565b5e;
}
</style>
src/views/train/data-list/index.vue
@@ -26,9 +26,9 @@
                <div class="info-text">{{ item.endTime }}</div>
              </div>
              <div class="button-container">
                <el-button v-if="item.status!==2" @click="start(item)">开始上课</el-button>
                <el-button @click="handleUpdate(item)">编辑</el-button>
                <el-button @click="remove(item)">删除</el-button>
                <el-button v-if="item.status!==2" @click="start(item)" type="primary" size="small">开始上课</el-button>
                <el-button @click="handleUpdate(item)" type="warning" size="small">编辑</el-button>
                <el-button @click="remove(item)" type="danger" size="small">删除</el-button>
              </div>
            </div>
          </el-card>
src/views/train/index.vue
@@ -8,7 +8,7 @@
            <div class="card-wrapper">
              <div class="card-header">
                <div class="header-tab">
                  <el-tabs v-model="activeName" @tab-click="handleClick">
                  <el-tabs v-model="activeName" @tab-click="handleClick" size="small">
                    <el-tab-pane label="全部" name="all"></el-tab-pane>
                    <el-tab-pane label="未开始" name="0"></el-tab-pane>
                    <el-tab-pane label="进行中" name="1"></el-tab-pane>
@@ -16,12 +16,12 @@
                  </el-tabs>
                </div>
                <div class="header-search">
                  <el-input v-model="queryParam.meetName" @input="getList" clearable @clear="getList"
                  <el-input v-model="queryParam.meetName" @input="getList" clearable @clear="getList" size="small"
                            placeholder="请输入课程名称"/>
                  <el-button type="primary" class="ml-4" @click="getList">搜索</el-button>
                  <el-button type="primary" class="ml-4" style="margin-left: 5px" size="small" @click="getList">搜索</el-button>
                </div>
                <div>
                  <el-button type="primary" @click="handleAdd()">添加</el-button>
                  <el-button type="primary" @click="handleAdd()" size="small">添加</el-button>
                </div>
              </div>
@@ -156,6 +156,7 @@
          let routeUrl = this.$router.resolve({
            path: '/meet',
            query: {
              meetId: item.id,
              domain: 'ycl.easyblog.vip:8443/' + item.id,
              roomName: item.meetName,
              userInfoStr: JSON.stringify({