feat: 首页新增监控判断
This commit is contained in:
parent
30560474da
commit
3c70e1d05b
@ -111,6 +111,14 @@ export interface UserData {
|
|||||||
port: number | null
|
port: number | null
|
||||||
sharing: boolean
|
sharing: boolean
|
||||||
}
|
}
|
||||||
|
/** 学生课堂监控投屏状态(getHomePage 返回) */
|
||||||
|
studentScreenShareState?: {
|
||||||
|
classId: string
|
||||||
|
ip: string | null
|
||||||
|
port: number | null
|
||||||
|
sharing: boolean
|
||||||
|
startedAt?: number
|
||||||
|
}
|
||||||
isTeacher: boolean
|
isTeacher: boolean
|
||||||
// 是否为可以接受任务的学员
|
// 是否为可以接受任务的学员
|
||||||
isTaskStudent: boolean
|
isTaskStudent: boolean
|
||||||
|
|||||||
20
src/api/subject/studentScreenShare.ts
Normal file
20
src/api/subject/studentScreenShare.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { get } from '../request'
|
||||||
|
|
||||||
|
export type StudentScreenShareState = {
|
||||||
|
classId: number
|
||||||
|
ip: string
|
||||||
|
lastHeartbeatAt: number
|
||||||
|
port: number
|
||||||
|
sharing: boolean
|
||||||
|
startedAt: number
|
||||||
|
ttlSeconds: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const studentScreenShareApi = {
|
||||||
|
/** 查询当前班级学生监控投屏状态 */
|
||||||
|
state: async (classId: string) => {
|
||||||
|
return await get<StudentScreenShareState>('/school/studentScreenShare/state', { classId })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default studentScreenShareApi
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import studentScreenShareApi from '@/api/subject/studentScreenShare'
|
||||||
import { $XXL } from '@/utils'
|
import { $XXL } from '@/utils'
|
||||||
import { userStore } from '@/stores'
|
import { userStore } from '@/stores'
|
||||||
import { useTips } from './useTips'
|
import { useTips } from './useTips'
|
||||||
@ -183,6 +184,63 @@ export const handleClassMonitorMessage = (data: anyObj) => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resolveStudentScreenShareClassId = (msg: Record<string, unknown>): string => {
|
||||||
|
if (msg.classId !== undefined && msg.classId !== null && String(msg.classId).trim() !== '') {
|
||||||
|
return String(msg.classId)
|
||||||
|
}
|
||||||
|
const userClassId = userStore().userInfo?.classId
|
||||||
|
if (userClassId !== undefined && userClassId !== null && String(userClassId).trim() !== '') {
|
||||||
|
return String(userClassId)
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步 getHomePage 返回的 studentScreenShareState
|
||||||
|
* sharing 为 true 时开启学生监控投屏,否则停止
|
||||||
|
*/
|
||||||
|
export const syncStudentScreenShareState = async (state: unknown) => {
|
||||||
|
const stateInfo = state && typeof state === 'object' ? (state as Record<string, unknown>) : {}
|
||||||
|
const screenShare = stateInfo.studentScreenShareState
|
||||||
|
if (!screenShare || typeof screenShare !== 'object') return
|
||||||
|
|
||||||
|
const share = screenShare as Record<string, unknown>
|
||||||
|
if (share.sharing !== true) {
|
||||||
|
stopClassMonitor(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg: anyObj = { ...share }
|
||||||
|
const host = msg.ip !== undefined && msg.ip !== null ? String(msg.ip) : ''
|
||||||
|
const port = Number(msg.port)
|
||||||
|
if (!host || !Number.isFinite(port)) {
|
||||||
|
const classId = resolveStudentScreenShareClassId(msg)
|
||||||
|
if (!classId) return
|
||||||
|
try {
|
||||||
|
const res = await studentScreenShareApi.state(classId)
|
||||||
|
if (!res?.sharing) return
|
||||||
|
msg = { ...msg, ip: res.ip, port: res.port, classId: res.classId ?? classId }
|
||||||
|
} catch (err) {
|
||||||
|
monitorWarn('首页学生监控状态补全失败:', err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionKey = getMonitorSessionKey(msg)
|
||||||
|
if (monitorState === 1 && sessionKey && monitorSessionId === sessionKey) {
|
||||||
|
applyStudentShareStart(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stopClassMonitor()
|
||||||
|
monitorSessionId = sessionKey
|
||||||
|
monitorState = 1
|
||||||
|
if (!applyStudentShareStart(msg)) {
|
||||||
|
monitorState = 0
|
||||||
|
monitorSessionId = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const syncClassMonitorState = (state: unknown) => {
|
export const syncClassMonitorState = (state: unknown) => {
|
||||||
const stateInfo = state && typeof state === 'object' ? (state as anyObj) : {}
|
const stateInfo = state && typeof state === 'object' ? (state as anyObj) : {}
|
||||||
const nextState = Number(stateInfo.monitorState ?? state)
|
const nextState = Number(stateInfo.monitorState ?? state)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import type { Option, UserData } from '@/api/global'
|
|||||||
import type { School } from '@/api/studentManage'
|
import type { School } from '@/api/studentManage'
|
||||||
import { setCache, clearCache, getSN, getManufacturer, isStudyMachine, isWebEvn } from '@/utils'
|
import { setCache, clearCache, getSN, getManufacturer, isStudyMachine, isWebEvn } from '@/utils'
|
||||||
import { LogType, useLog, useSocket } from '@/hooks'
|
import { LogType, useLog, useSocket } from '@/hooks'
|
||||||
import { syncClassMonitorState } from '@/hooks/useClassMonitor'
|
import { syncClassMonitorState, syncStudentScreenShareState } from '@/hooks/useClassMonitor'
|
||||||
import { syncTeacherScreenShareState } from '@/hooks/useTeacherExplain'
|
import { syncTeacherScreenShareState } from '@/hooks/useTeacherExplain'
|
||||||
import { globalStore } from '@/stores'
|
import { globalStore } from '@/stores'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
@ -108,6 +108,10 @@ export const userStore = defineStore('user', () => {
|
|||||||
const updateUserInfo = async (info: any) => {
|
const updateUserInfo = async (info: any) => {
|
||||||
if (!info) return
|
if (!info) return
|
||||||
const hasMonitorState = Object.prototype.hasOwnProperty.call(info, 'monitorState')
|
const hasMonitorState = Object.prototype.hasOwnProperty.call(info, 'monitorState')
|
||||||
|
const hasStudentScreenShareState = Object.prototype.hasOwnProperty.call(
|
||||||
|
info,
|
||||||
|
'studentScreenShareState',
|
||||||
|
)
|
||||||
const hasScreenShareState = Object.prototype.hasOwnProperty.call(info, 'screenShareState')
|
const hasScreenShareState = Object.prototype.hasOwnProperty.call(info, 'screenShareState')
|
||||||
info = { ...userInfo.value, ...info }
|
info = { ...userInfo.value, ...info }
|
||||||
|
|
||||||
@ -123,6 +127,12 @@ export const userStore = defineStore('user', () => {
|
|||||||
syncClassMonitorState(info)
|
syncClassMonitorState(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasStudentScreenShareState) {
|
||||||
|
syncStudentScreenShareState(info).catch(err => {
|
||||||
|
console.warn('[User] 同步学生监控投屏状态失败:', err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (hasScreenShareState) {
|
if (hasScreenShareState) {
|
||||||
syncTeacherScreenShareState(info).catch(err => {
|
syncTeacherScreenShareState(info).catch(err => {
|
||||||
console.warn('[User] 同步投屏状态失败:', err)
|
console.warn('[User] 同步投屏状态失败:', err)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user