fix: 修复监控传参

This commit is contained in:
阿梦 2026-05-15 18:27:32 +08:00
parent 49023a433d
commit 30560474da
3 changed files with 102 additions and 24 deletions

View File

@ -1,12 +1,25 @@
import { $XXL } from '@/utils' import { $XXL } from '@/utils'
import { userStore } from '@/stores'
import { useTips } from './useTips' import { useTips } from './useTips'
let monitorSessionId = '' let monitorSessionId = ''
let monitorState: 0 | 1 = 0 let monitorState: 0 | 1 = 0
let closeMonitorTip: (() => void) | null = null let closeMonitorTip: (() => void) | null = null
/** 旧版课堂监控 WS 类型 */
const MONITOR_MSG_TYPE = 'monitorStart' const MONITOR_MSG_TYPE = 'monitorStart'
const MONITOR_STOP_MSG_TYPE = 'monitorStop' const MONITOR_STOP_MSG_TYPE = 'monitorStop'
/** 新版学生投屏 WS 类型 */
const STUDENT_SCREEN_SHARE_START = 'studentScreenShareStart'
const STUDENT_SCREEN_SHARE_STOP = 'studentScreenShareStop'
const MONITOR_WS_TYPES = new Set([
MONITOR_MSG_TYPE,
MONITOR_STOP_MSG_TYPE,
STUDENT_SCREEN_SHARE_START,
STUDENT_SCREEN_SHARE_STOP,
])
const MONITOR_LOG_PREFIX = '[class-monitor]' const MONITOR_LOG_PREFIX = '[class-monitor]'
const monitorLog = (...args: unknown[]) => console.log(MONITOR_LOG_PREFIX, ...args) const monitorLog = (...args: unknown[]) => console.log(MONITOR_LOG_PREFIX, ...args)
@ -20,22 +33,74 @@ const showMonitorTip = (tips: string) => {
}) })
} }
const startStudentShareScreen = () => { const mergeMonitorPayload = (data: anyObj): anyObj => {
monitorLog('call native startStudentShareScreen') const msg = data?.msg && typeof data.msg === 'object' && !Array.isArray(data.msg) ? data.msg : {}
$XXL.startStudentShareScreen() return {
...(data && typeof data === 'object' ? data : {}),
...msg,
}
} }
const stopStudentShareScreen = () => { const getMonitorSessionKey = (msg: anyObj) => {
monitorLog('call native stopStudentShareScreen') const key =
$XXL.stopStudentShareScreen() msg?.sessionId ??
msg?.startedAt ??
msg?.classId ??
msg?.monitorSessionId ??
msg?.classMonitorSessionId
return key !== undefined && key !== null ? String(key).trim() : ''
} }
/** 与老师讲解 WS 等场景兼容:外层 type 可能是 push/classMessage监控类型在 msg.type */ const applyStudentShareStart = (msg: anyObj): boolean => {
const host = msg.ip !== undefined && msg.ip !== null ? String(msg.ip) : ''
const port = Number(msg.port)
if (!host || !Number.isFinite(port)) {
monitorWarn('startStudentShareScreen missing ip/port', msg)
return false
}
const u = userStore().userInfo
const config = {
host,
port,
name: String(u?.name || u?.nickName || ''),
id: String(u?.userId ?? ''),
}
monitorLog('startStudentShareScreen config', config)
$XXL.startStudentShareScreen(config)
return true
}
const startStudentShareScreenLive = (msg: anyObj) => {
const sessionKey = getMonitorSessionKey(msg)
monitorLog('start student screen share', msg)
if (monitorState === 1 && sessionKey && monitorSessionId === sessionKey) {
monitorLog('start ignored, session already running', sessionKey)
return
}
stopClassMonitor()
monitorSessionId = sessionKey
monitorState = 1
showMonitorTip('已进入课堂监控状态')
if (!applyStudentShareStart(msg)) {
monitorState = 0
monitorSessionId = ''
}
}
/** 与老师讲解 WS 等场景兼容:外层 type 可能是 push/classMessage监控类型在 msg.type 或 data.type */
export const resolveMonitorWsType = (data: anyObj): string | undefined => { export const resolveMonitorWsType = (data: anyObj): string | undefined => {
const nested = data?.msg?.type const candidates = [data?.msg?.type, data?.type]
if (nested === MONITOR_STOP_MSG_TYPE || nested === MONITOR_MSG_TYPE) return nested const inner = (data as Record<string, unknown>).data
const top = data?.type if (inner && typeof inner === 'object') {
if (top === MONITOR_STOP_MSG_TYPE || top === MONITOR_MSG_TYPE) return top candidates.push((inner as anyObj).type)
}
for (const t of candidates) {
if (typeof t === 'string' && MONITOR_WS_TYPES.has(t)) return t
}
return undefined return undefined
} }
@ -43,7 +108,7 @@ export const stopClassMonitor = (showTip = false) => {
const isMonitoring = !!monitorSessionId || monitorState === 1 const isMonitoring = !!monitorSessionId || monitorState === 1
monitorLog('stop monitor', { showTip, isMonitoring, monitorSessionId, monitorState }) monitorLog('stop monitor', { showTip, isMonitoring, monitorSessionId, monitorState })
if (monitorState === 1) { if (monitorState === 1) {
stopStudentShareScreen() $XXL.stopStudentShareScreen()
} }
if (showTip && isMonitoring) { if (showTip && isMonitoring) {
showMonitorTip('已结束课堂监控') showMonitorTip('已结束课堂监控')
@ -59,16 +124,19 @@ const startClassMonitor = (msg: anyObj) => {
monitorWarn('start monitor ignored because sessionId is empty') monitorWarn('start monitor ignored because sessionId is empty')
return return
} }
if (monitorState === 1 && monitorSessionId === sessionId) { if (monitorState === 1 && monitorSessionId === String(sessionId)) {
monitorLog('start monitor ignored because session is already running', sessionId) monitorLog('start monitor ignored because session is already running', sessionId)
return return
} }
stopClassMonitor() stopClassMonitor()
monitorSessionId = sessionId monitorSessionId = String(sessionId)
monitorState = 1 monitorState = 1
showMonitorTip('已进入课堂监控状态') showMonitorTip('已进入课堂监控状态')
startStudentShareScreen() if (!applyStudentShareStart(msg)) {
monitorState = 0
monitorSessionId = ''
}
} }
const getMonitorSessionId = (data: anyObj) => { const getMonitorSessionId = (data: anyObj) => {
@ -87,16 +155,22 @@ const getMonitorSessionId = (data: anyObj) => {
export const handleClassMonitorMessage = (data: anyObj) => { export const handleClassMonitorMessage = (data: anyObj) => {
const monitorType = resolveMonitorWsType(data) const monitorType = resolveMonitorWsType(data)
monitorLog('handle monitor ws message', { monitorType, data }) monitorLog('handle monitor ws message', { monitorType, data })
if (monitorType === MONITOR_STOP_MSG_TYPE) { if (!monitorType) return false
const msg = mergeMonitorPayload(data)
if (monitorType === STUDENT_SCREEN_SHARE_STOP || monitorType === MONITOR_STOP_MSG_TYPE) {
stopClassMonitor(true) stopClassMonitor(true)
return true return true
} }
if (monitorType === STUDENT_SCREEN_SHARE_START) {
startStudentShareScreenLive(msg)
return true
}
if (monitorType !== MONITOR_MSG_TYPE) return false if (monitorType !== MONITOR_MSG_TYPE) return false
const msg: anyObj = {
...(data && typeof data === 'object' ? data : {}),
...(data?.msg && typeof data.msg === 'object' && !Array.isArray(data.msg) ? data.msg : {}),
}
const monitoring = msg?.monitoring const monitoring = msg?.monitoring
if (monitoring === true || monitoring === 'true') { if (monitoring === true || monitoring === 'true') {
startClassMonitor(msg) startClassMonitor(msg)
@ -122,9 +196,8 @@ export const syncClassMonitorState = (state: unknown) => {
const sessionId = getMonitorSessionId(stateInfo) const sessionId = getMonitorSessionId(stateInfo)
if (!sessionId) { if (!sessionId) {
monitorWarn('sync monitor state ignored because sessionId is empty', stateInfo) monitorWarn('sync monitor state ignored because sessionId is empty', stateInfo)
if (monitorState !== 1) { if (monitorState !== 1 && applyStudentShareStart(stateInfo)) {
monitorState = 1 monitorState = 1
startStudentShareScreen()
} }
return return
} }

View File

@ -25,6 +25,8 @@ enum SOCKET_MSG_TYPE {
messageReceive = 'messageReceive', messageReceive = 'messageReceive',
monitorStart = 'monitorStart', monitorStart = 'monitorStart',
monitorStop = 'monitorStop', monitorStop = 'monitorStop',
studentScreenShareStart = 'studentScreenShareStart',
studentScreenShareStop = 'studentScreenShareStop',
} }
const inspectorEnd = ref<anyObj>() const inspectorEnd = ref<anyObj>()
@ -152,6 +154,8 @@ export const useSocket = () => {
break break
case SOCKET_MSG_TYPE.monitorStart: case SOCKET_MSG_TYPE.monitorStart:
case SOCKET_MSG_TYPE.monitorStop: case SOCKET_MSG_TYPE.monitorStop:
case SOCKET_MSG_TYPE.studentScreenShareStart:
case SOCKET_MSG_TYPE.studentScreenShareStop:
handleClassMonitorMessage(data) handleClassMonitorMessage(data)
break break
case SOCKET_MSG_TYPE.inspectorStart: case SOCKET_MSG_TYPE.inspectorStart:

View File

@ -109,8 +109,9 @@ export const $XXL = {
packSync('startTeacherShareScreen', JSON.stringify(config)), packSync('startTeacherShareScreen', JSON.stringify(config)),
/** 老师投屏结束 */ /** 老师投屏结束 */
stopTeacherShareScreen: () => packSync('stopTeacherShareScreen'), stopTeacherShareScreen: () => packSync('stopTeacherShareScreen'),
/** 学生课堂监控投屏开始 */ /** 学生课堂监控投屏开始:参数与 `startTeacherShareScreen` 一致 */
startStudentShareScreen: () => packSync('startStudentShareScreen'), startStudentShareScreen: (config: { host: string; port: number; name: string; id: string }) =>
packSync('startStudentShareScreen', JSON.stringify(config)),
/** 学生课堂监控投屏结束 */ /** 学生课堂监控投屏结束 */
stopStudentShareScreen: () => packSync('stopStudentShareScreen'), stopStudentShareScreen: () => packSync('stopStudentShareScreen'),
// openApp: (config: anyObj) => pack('openApp', config), // openApp: (config: anyObj) => pack('openApp', config),