feat: 首页新增监控判断

This commit is contained in:
阿梦 2026-05-15 18:50:05 +08:00
parent 30560474da
commit 3c70e1d05b
4 changed files with 97 additions and 1 deletions

View File

@ -111,6 +111,14 @@ export interface UserData {
port: number | null
sharing: boolean
}
/** 学生课堂监控投屏状态getHomePage 返回) */
studentScreenShareState?: {
classId: string
ip: string | null
port: number | null
sharing: boolean
startedAt?: number
}
isTeacher: boolean
// 是否为可以接受任务的学员
isTaskStudent: boolean

View 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

View File

@ -1,3 +1,4 @@
import studentScreenShareApi from '@/api/subject/studentScreenShare'
import { $XXL } from '@/utils'
import { userStore } from '@/stores'
import { useTips } from './useTips'
@ -183,6 +184,63 @@ export const handleClassMonitorMessage = (data: anyObj) => {
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) => {
const stateInfo = state && typeof state === 'object' ? (state as anyObj) : {}
const nextState = Number(stateInfo.monitorState ?? state)

View File

@ -8,7 +8,7 @@ import type { Option, UserData } from '@/api/global'
import type { School } from '@/api/studentManage'
import { setCache, clearCache, getSN, getManufacturer, isStudyMachine, isWebEvn } from '@/utils'
import { LogType, useLog, useSocket } from '@/hooks'
import { syncClassMonitorState } from '@/hooks/useClassMonitor'
import { syncClassMonitorState, syncStudentScreenShareState } from '@/hooks/useClassMonitor'
import { syncTeacherScreenShareState } from '@/hooks/useTeacherExplain'
import { globalStore } from '@/stores'
import { storeToRefs } from 'pinia'
@ -108,6 +108,10 @@ export const userStore = defineStore('user', () => {
const updateUserInfo = async (info: any) => {
if (!info) return
const hasMonitorState = Object.prototype.hasOwnProperty.call(info, 'monitorState')
const hasStudentScreenShareState = Object.prototype.hasOwnProperty.call(
info,
'studentScreenShareState',
)
const hasScreenShareState = Object.prototype.hasOwnProperty.call(info, 'screenShareState')
info = { ...userInfo.value, ...info }
@ -123,6 +127,12 @@ export const userStore = defineStore('user', () => {
syncClassMonitorState(info)
}
if (hasStudentScreenShareState) {
syncStudentScreenShareState(info).catch(err => {
console.warn('[User] 同步学生监控投屏状态失败:', err)
})
}
if (hasScreenShareState) {
syncTeacherScreenShareState(info).catch(err => {
console.warn('[User] 同步投屏状态失败:', err)