feat: homepage里面新增直播判断

This commit is contained in:
阿梦 2026-05-15 14:38:42 +08:00
parent efe57930aa
commit 9655f4742a
3 changed files with 88 additions and 19 deletions

View File

@ -104,6 +104,13 @@ export interface UserData {
workMode: number
// 监控状态 0: 未开启 1: 已开启
monitorState: number
/** 老师投屏状态getHomePage 返回) */
screenShareState?: {
classId: string
ip: string | null
port: number | null
sharing: boolean
}
isTeacher: boolean
// 是否为可以接受任务的学员
isTaskStudent: boolean

View File

@ -140,6 +140,77 @@ function startTeacherScreenSharePolling(classId: string) {
}, TEACHER_SCREEN_SHARE_STATE_POLL_INTERVAL)
}
function resolveTeacherScreenSharePollClassId(msg: Record<string, unknown>): string {
if (msg.classId !== undefined && msg.classId !== null && String(msg.classId).trim() !== '') {
return String(msg.classId)
}
if (classInfo.value?.classId !== undefined && classInfo.value?.classId !== null) {
return String(classInfo.value.classId)
}
const userClassId = userStore().userInfo?.classId
if (userClassId !== undefined && userClassId !== null && String(userClassId).trim() !== '') {
return String(userClassId)
}
return ''
}
/** 启动老师投屏直播(原生 + 状态轮询) */
function applyTeacherScreenShareStart(msg: Record<string, unknown>): boolean {
const host = msg.ip !== undefined && msg.ip !== null ? String(msg.ip) : ''
const port = Number(msg.port)
if (!host || !Number.isFinite(port)) return false
const u = userStore().userInfo
$XXL.startTeacherShareScreen({
host,
port,
name: String(u?.name || u?.nickName || ''),
id: String(u?.userId ?? ''),
})
const pollClassId = resolveTeacherScreenSharePollClassId(msg)
if (pollClassId) startTeacherScreenSharePolling(pollClassId)
return true
}
function stopTeacherScreenShareLive() {
stopTeacherScreenSharePolling()
$XXL.stopTeacherShareScreen()
}
/**
* getHomePage screenShareState
* sharing true
*/
export const syncTeacherScreenShareState = async (state: unknown) => {
const stateInfo = state && typeof state === 'object' ? (state as Record<string, unknown>) : {}
const screenShare = stateInfo.screenShareState
if (!screenShare || typeof screenShare !== 'object') return
const share = screenShare as Record<string, unknown>
if (share.sharing !== true) {
stopTeacherScreenShareLive()
return
}
let msg = { ...share }
const host = msg.ip !== undefined && msg.ip !== null ? String(msg.ip) : ''
const port = Number(msg.port)
if (!host || !Number.isFinite(port)) {
const classId = resolveTeacherScreenSharePollClassId(msg)
if (!classId) return
try {
const res = await teacherScreenShareApi.state(classId)
if (!res?.sharing) return
msg = { ...msg, ip: res.ip, port: res.port, classId: res.classId ?? classId }
} catch (err) {
console.warn('[TeacherExplain] 首页投屏状态补全失败:', err)
return
}
}
applyTeacherScreenShareStart(msg)
}
/** 老师投屏开始/结束:调原生桥接 */
function handleTeacherScreenShareMessage(data: TeacherWsMessage) {
const root = resolveTeacherScreenSharePayload(data)
@ -148,29 +219,12 @@ function handleTeacherScreenShareMessage(data: TeacherWsMessage) {
if (root.type === 'teacherScreenShareStart') {
const msg = parseMsgObject(root.msg)
if (!msg) return
const host = msg.ip !== undefined && msg.ip !== null ? String(msg.ip) : ''
const port = Number(msg.port)
if (!host || !Number.isFinite(port)) return
const u = userStore().userInfo
$XXL.startTeacherShareScreen({
host,
port,
name: String(u?.name || u?.nickName || ''),
id: String(u?.userId ?? ''),
})
const pollClassId =
msg.classId !== undefined && msg.classId !== null && String(msg.classId).trim() !== ''
? String(msg.classId)
: classInfo.value?.classId !== undefined && classInfo.value?.classId !== null
? String(classInfo.value.classId)
: ''
if (pollClassId) startTeacherScreenSharePolling(pollClassId)
applyTeacherScreenShareStart(msg)
return
}
if (root.type === 'teacherScreenShareStop') {
stopTeacherScreenSharePolling()
$XXL.stopTeacherShareScreen()
stopTeacherScreenShareLive()
}
}

View File

@ -9,6 +9,7 @@ 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 { syncTeacherScreenShareState } from '@/hooks/useTeacherExplain'
import { globalStore } from '@/stores'
import { storeToRefs } from 'pinia'
import obj from '@/utils/obj'
@ -107,6 +108,7 @@ export const userStore = defineStore('user', () => {
const updateUserInfo = async (info: any) => {
if (!info) return
const hasMonitorState = Object.prototype.hasOwnProperty.call(info, 'monitorState')
const hasScreenShareState = Object.prototype.hasOwnProperty.call(info, 'screenShareState')
info = { ...userInfo.value, ...info }
if (typeof info.screenLock !== 'undefined') {
@ -121,6 +123,12 @@ export const userStore = defineStore('user', () => {
syncClassMonitorState(info)
}
if (hasScreenShareState) {
syncTeacherScreenShareState(info).catch(err => {
console.warn('[User] 同步投屏状态失败:', err)
})
}
if (typeof info.schoolClass === 'string') {
info.schoolClass = JSON.parse(info.schoolClass)
if (info.schoolClass?.length) {