Merge branch 'main' of https://gitlab.lingxixue.com/limeng/lingxixue-web
This commit is contained in:
commit
12c6f0759b
@ -1,7 +1,6 @@
|
||||
import str from '@/utils/str'
|
||||
import { http } from './http'
|
||||
import { get } from './request'
|
||||
import { $XXL } from '@/utils'
|
||||
|
||||
export type Option = {
|
||||
value: any
|
||||
@ -99,6 +98,11 @@ export interface UserData {
|
||||
smartUserIdentifier: string
|
||||
schoolPersonType: number
|
||||
lockFlag: number
|
||||
screenLock?: 0 | 1
|
||||
// 作业模式 0: 未开启 1: 已开启
|
||||
workMode: number
|
||||
// 监控状态 0: 未开启 1: 已开启
|
||||
monitorState: number
|
||||
isTeacher: boolean
|
||||
// 是否为可以接受任务的学员
|
||||
isTaskStudent: boolean
|
||||
@ -206,6 +210,14 @@ const globalApi = {
|
||||
data,
|
||||
}),
|
||||
|
||||
// 上报课堂监控截图
|
||||
reportSnapshot: (data: { sessionId: string; url: string; userId: string }) =>
|
||||
http.request({
|
||||
url: '/school/classMonitor/reportSnapshot',
|
||||
method: 'POST',
|
||||
data,
|
||||
}),
|
||||
|
||||
// 用户视频表-id查询
|
||||
getUserVideoById: (id: any) =>
|
||||
http.request({
|
||||
|
||||
161
src/hooks/useClassMonitor.ts
Normal file
161
src/hooks/useClassMonitor.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import html2canvas from 'html2canvas'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import globalApi from '@/api/global'
|
||||
import { userStore } from '@/stores'
|
||||
import { $XXL, sys_type, sys_type_study_machine } from '@/utils'
|
||||
import sass from '@/utils/sass'
|
||||
import { useTips } from './useTips'
|
||||
|
||||
let monitorTimer: ReturnType<typeof setInterval> | null = null
|
||||
let monitorSessionId = ''
|
||||
let isUploadingMonitorSnapshot = false
|
||||
let monitorState: 0 | 1 = 0
|
||||
|
||||
const MONITOR_SNAPSHOT_INTERVAL = 10000
|
||||
const MONITOR_MSG_TYPE = 'monitorStart'
|
||||
|
||||
const normalizeUploadPath = (res: any) => {
|
||||
return String(
|
||||
res?.data?.filePath || res?.data?.url || res?.filePath || res?.url || res?.data?.path || '',
|
||||
)
|
||||
.replace(/[`]/g, '')
|
||||
.replace(/http:\/\//gi, 'https://')
|
||||
.trim()
|
||||
}
|
||||
|
||||
const uploadNativeScreenshot = async () => {
|
||||
const { token } = storeToRefs(userStore())
|
||||
const { data: filePath } = $XXL.getScreenshot() || {}
|
||||
if (!filePath) return ''
|
||||
|
||||
const res = await $XXL.uploadFile({
|
||||
url: `${import.meta.env.VITE_SERVER_URL}/sysFileInfo/tenUploadAll`,
|
||||
header: {
|
||||
Authorization: token.value,
|
||||
'X-Tenant-Id': sass.platform.tenantId,
|
||||
},
|
||||
filePath,
|
||||
fileKey: 'file',
|
||||
})
|
||||
return normalizeUploadPath(res)
|
||||
}
|
||||
|
||||
const createWebScreenshotFile = async () => {
|
||||
const canvas = await html2canvas(document.body, {
|
||||
useCORS: true,
|
||||
backgroundColor: null,
|
||||
x: window.scrollX,
|
||||
y: window.scrollY,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight,
|
||||
scale: window.devicePixelRatio || 1,
|
||||
})
|
||||
|
||||
return await new Promise<File | null>(resolve => {
|
||||
canvas.toBlob(blob => {
|
||||
if (!blob) return resolve(null)
|
||||
resolve(new File([blob], `monitor-${Date.now()}.png`, { type: 'image/png' }))
|
||||
}, 'image/png')
|
||||
})
|
||||
}
|
||||
|
||||
const uploadWebScreenshot = async () => {
|
||||
const file = await createWebScreenshotFile()
|
||||
if (!file) return ''
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
const { data: res } = await globalApi.uploadFile(formData)
|
||||
return normalizeUploadPath(res)
|
||||
}
|
||||
|
||||
const uploadMonitorScreenshot = async () => {
|
||||
if (sys_type === sys_type_study_machine) {
|
||||
return await uploadNativeScreenshot()
|
||||
}
|
||||
return await uploadWebScreenshot()
|
||||
}
|
||||
|
||||
const reportMonitorSnapshot = async (sessionId: string) => {
|
||||
const { userInfo } = storeToRefs(userStore())
|
||||
if (isUploadingMonitorSnapshot || monitorSessionId !== sessionId) return
|
||||
|
||||
isUploadingMonitorSnapshot = true
|
||||
try {
|
||||
const url = await uploadMonitorScreenshot()
|
||||
if (!url || monitorSessionId !== sessionId) return
|
||||
|
||||
await globalApi.reportSnapshot({
|
||||
sessionId,
|
||||
url,
|
||||
userId: userInfo.value.userId,
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
isUploadingMonitorSnapshot = false
|
||||
}
|
||||
}
|
||||
|
||||
export const stopClassMonitor = (showTip = false) => {
|
||||
const isMonitoring = !!monitorTimer || !!monitorSessionId || monitorState === 1
|
||||
if (monitorTimer) {
|
||||
clearInterval(monitorTimer)
|
||||
monitorTimer = null
|
||||
}
|
||||
if (showTip && isMonitoring) {
|
||||
useTips({
|
||||
tips: '已结束课堂监控',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
monitorSessionId = ''
|
||||
monitorState = 0
|
||||
}
|
||||
|
||||
const startClassMonitor = (msg: anyObj) => {
|
||||
const sessionId = msg?.sessionId
|
||||
if (!sessionId) return
|
||||
if (monitorTimer && monitorSessionId === sessionId) return
|
||||
|
||||
stopClassMonitor()
|
||||
monitorSessionId = sessionId
|
||||
monitorState = 1
|
||||
useTips({
|
||||
tips: '已进入课堂监控状态',
|
||||
showCancel: false,
|
||||
})
|
||||
reportMonitorSnapshot(sessionId)
|
||||
monitorTimer = setInterval(() => reportMonitorSnapshot(sessionId), MONITOR_SNAPSHOT_INTERVAL)
|
||||
}
|
||||
|
||||
export const handleClassMonitorMessage = (data: anyObj) => {
|
||||
const messageType = data?.type || data?.msg?.type
|
||||
if (messageType !== MONITOR_MSG_TYPE) return false
|
||||
|
||||
const msg = data?.msg || data
|
||||
const monitoring = msg?.monitoring
|
||||
if (monitoring === true || monitoring === 'true') {
|
||||
startClassMonitor(msg)
|
||||
return true
|
||||
}
|
||||
if (monitoring === false || monitoring === 'false') {
|
||||
stopClassMonitor(true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const syncClassMonitorState = (state: unknown) => {
|
||||
const nextState = Number(state)
|
||||
if (nextState !== 0 && nextState !== 1) return
|
||||
|
||||
if (nextState === 0) {
|
||||
stopClassMonitor(true)
|
||||
return
|
||||
}
|
||||
|
||||
monitorState = 1
|
||||
}
|
||||
@ -1,10 +1,11 @@
|
||||
import { useWebSocket } from '@vueuse/core'
|
||||
import { userStore, globalStore, urgeStore } from '@/stores'
|
||||
import type { UseWebSocketReturn } from '@vueuse/core'
|
||||
import { getSN, $XXL, sys_type, sys_type_study_machine, isNotStudyMachine } from '@/utils'
|
||||
import { getSN, $XXL, isNotStudyMachine } from '@/utils'
|
||||
import { useLog, LogType, useTips } from '@/hooks'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { handleClassMonitorMessage, stopClassMonitor } from './useClassMonitor'
|
||||
|
||||
let SOCKET: UseWebSocketReturn<any>
|
||||
|
||||
@ -17,6 +18,7 @@ enum SOCKET_MSG_TYPE {
|
||||
inspectorEnd = 'inspectorEnd',
|
||||
systemMessage = 'systemMessage',
|
||||
messageReceive = 'messageReceive',
|
||||
monitorStart = 'monitorStart',
|
||||
}
|
||||
|
||||
const inspectorEnd = ref<anyObj>()
|
||||
@ -30,7 +32,6 @@ export const useSocket = () => {
|
||||
const SN = getSN()
|
||||
|
||||
const init = () => {
|
||||
return
|
||||
if (import.meta.env.MODE === 'test') return
|
||||
if (!token.value) return
|
||||
stop()
|
||||
@ -79,8 +80,28 @@ export const useSocket = () => {
|
||||
// console.log(ws, event);
|
||||
}
|
||||
|
||||
const getLockFlag = (data: anyObj, fallback: 0 | 1): 0 | 1 => {
|
||||
const locked = data.msg?.locked
|
||||
if (locked === true || locked === 'true') return 1
|
||||
if (locked === false || locked === 'false') return 0
|
||||
|
||||
const lockFlag = Number(locked)
|
||||
return lockFlag === 0 || lockFlag === 1 ? lockFlag : fallback
|
||||
}
|
||||
|
||||
const updateLockScreen = (lockFlag: 0 | 1) => {
|
||||
if (isNotStudyMachine) return
|
||||
|
||||
system.value.isLock = lockFlag === 1
|
||||
useLog(LogType.LockScreenTime, {
|
||||
simSerialNumber: SN,
|
||||
lockFlag,
|
||||
})
|
||||
}
|
||||
|
||||
const onMessage = (ws: WebSocket, event: MessageEvent) => {
|
||||
const data = JSON.parse(event.data)
|
||||
const messageType = data.type || data.msg?.type
|
||||
|
||||
// 确认接收
|
||||
sendMsg({
|
||||
@ -89,7 +110,7 @@ export const useSocket = () => {
|
||||
})
|
||||
|
||||
// 全局消息提醒
|
||||
if (data.type === SOCKET_MSG_TYPE.systemMessage) {
|
||||
if (messageType === SOCKET_MSG_TYPE.systemMessage) {
|
||||
useTips({
|
||||
tips: data.msg,
|
||||
showCancel: false,
|
||||
@ -98,29 +119,31 @@ export const useSocket = () => {
|
||||
}
|
||||
|
||||
// if (isWeb) return;
|
||||
switch (data.type) {
|
||||
if (
|
||||
messageType !== SOCKET_MSG_TYPE.lockScreen &&
|
||||
messageType !== SOCKET_MSG_TYPE.unLockScreen &&
|
||||
typeof data.msg?.locked !== 'undefined'
|
||||
) {
|
||||
updateLockScreen(getLockFlag(data, 0))
|
||||
return
|
||||
}
|
||||
|
||||
switch (messageType) {
|
||||
case SOCKET_MSG_TYPE.lockScreen:
|
||||
if (isNotStudyMachine) return
|
||||
// 执行锁屏
|
||||
system.value.isLock = true
|
||||
useLog(LogType.LockScreenTime, {
|
||||
simSerialNumber: SN,
|
||||
lockFlag: 1,
|
||||
})
|
||||
updateLockScreen(getLockFlag(data, 1))
|
||||
break
|
||||
case SOCKET_MSG_TYPE.unLockScreen:
|
||||
if (isNotStudyMachine) return
|
||||
// 执行解锁
|
||||
system.value.isLock = false
|
||||
useLog(LogType.LockScreenTime, {
|
||||
simSerialNumber: SN,
|
||||
lockFlag: 0,
|
||||
})
|
||||
updateLockScreen(getLockFlag(data, 0))
|
||||
break
|
||||
case SOCKET_MSG_TYPE.desktopPreview:
|
||||
if (isNotStudyMachine) return
|
||||
onDesktopPreview()
|
||||
break
|
||||
case SOCKET_MSG_TYPE.monitorStart:
|
||||
handleClassMonitorMessage(data)
|
||||
break
|
||||
case SOCKET_MSG_TYPE.inspectorStart:
|
||||
// 开始督学
|
||||
// console.log('开始督学');
|
||||
@ -197,6 +220,7 @@ export const useSocket = () => {
|
||||
}
|
||||
|
||||
const stop = () => {
|
||||
stopClassMonitor()
|
||||
SOCKET?.close()
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import { ref, shallowRef } from 'vue'
|
||||
import questionExplainApi from '@/api/subject/questionExplain'
|
||||
import { getCache } from '@/utils'
|
||||
import { userStore } from '@/stores'
|
||||
import { handleClassMonitorMessage, stopClassMonitor } from './useClassMonitor'
|
||||
|
||||
// ======================== 常量配置 ========================
|
||||
|
||||
@ -194,6 +195,8 @@ function handleMessage(data: TeacherWsMessage) {
|
||||
// 心跳响应不做业务处理
|
||||
if (data.type === 'pong') return
|
||||
|
||||
handleClassMonitorMessage(data)
|
||||
|
||||
// 调用所有已注册的外部消息回调
|
||||
messageHandlers.forEach(handler => {
|
||||
try {
|
||||
@ -285,6 +288,7 @@ async function init() {
|
||||
function close() {
|
||||
isManualClose = true
|
||||
stopHeartbeat()
|
||||
stopClassMonitor()
|
||||
clearReconnectTimer()
|
||||
stopVisibilityListener()
|
||||
reconnectAttempts = 0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { globalStore, subjectStore } from '@/stores'
|
||||
import { useSocket, useTeacherExplain } from '@/hooks'
|
||||
import { $XXL, isWebEvn } from '@/utils'
|
||||
import { globalStore, subjectStore, userStore } from '@/stores'
|
||||
import { LogType, useLog, useSocket, useTeacherExplain } from '@/hooks'
|
||||
import { $XXL, getSN, isStudyMachine, isWebEvn } from '@/utils'
|
||||
import hud from '@/utils/hud'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
@ -12,8 +12,12 @@ const logo = sass.getLogo()
|
||||
|
||||
const router = useRouter()
|
||||
const { system, init, getDict, initDevTool, destroyDevTool } = globalStore()
|
||||
const { getUserInfo } = userStore()
|
||||
|
||||
const { getSubjectAllList } = subjectStore()
|
||||
const LOCK_HOME_PAGE_REFRESH_INTERVAL = 10_000
|
||||
let lockHomePageTimer: ReturnType<typeof setInterval> | null = null
|
||||
let lockHomePageRefreshing = false
|
||||
|
||||
if (!isWebEvn) {
|
||||
// 注入安卓方法
|
||||
@ -82,6 +86,52 @@ const {
|
||||
} = useTeacherExplain()
|
||||
teacherExplainInit()
|
||||
|
||||
function getLockFlag(data: anyObj, fallback: 0 | 1): 0 | 1 {
|
||||
const locked = data.msg?.locked
|
||||
if (locked === true || locked === 'true') return 1
|
||||
if (locked === false || locked === 'false') return 0
|
||||
|
||||
const lockFlag = Number(locked)
|
||||
return lockFlag === 0 || lockFlag === 1 ? lockFlag : fallback
|
||||
}
|
||||
|
||||
function updateLockScreen(lockFlag: 0 | 1) {
|
||||
if (!isStudyMachine) return
|
||||
|
||||
system.isLock = lockFlag === 1
|
||||
useLog(LogType.LockScreenTime, {
|
||||
simSerialNumber: getSN(),
|
||||
lockFlag,
|
||||
})
|
||||
}
|
||||
|
||||
async function refreshLockHomePage() {
|
||||
if (lockHomePageRefreshing) return
|
||||
|
||||
lockHomePageRefreshing = true
|
||||
try {
|
||||
await getUserInfo()
|
||||
} catch (err) {
|
||||
console.warn('锁屏状态刷新首页信息失败', err)
|
||||
} finally {
|
||||
lockHomePageRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
function startLockHomePageRefresh() {
|
||||
if (lockHomePageTimer) return
|
||||
|
||||
refreshLockHomePage()
|
||||
lockHomePageTimer = setInterval(refreshLockHomePage, LOCK_HOME_PAGE_REFRESH_INTERVAL)
|
||||
}
|
||||
|
||||
function stopLockHomePageRefresh() {
|
||||
if (!lockHomePageTimer) return
|
||||
|
||||
clearInterval(lockHomePageTimer)
|
||||
lockHomePageTimer = null
|
||||
}
|
||||
|
||||
// 重新登录后重连 WebSocket
|
||||
watch(
|
||||
() => router.currentRoute.value.path,
|
||||
@ -92,9 +142,32 @@ watch(
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
() => system.isLock,
|
||||
isLock => {
|
||||
if (isLock) {
|
||||
startLockHomePageRefresh()
|
||||
return
|
||||
}
|
||||
|
||||
stopLockHomePageRefresh()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 监听老师讲解 WebSocket 消息,收到 questionExplainStart 且 explaining 为 true 时跳转讲解页面
|
||||
// 如果当前已在讲解页面则不跳转,由讲解页面内部根据 questionId 切换题目
|
||||
onTeacherMessage(data => {
|
||||
if (data.type === 'lockScreen') {
|
||||
updateLockScreen(getLockFlag(data, 1))
|
||||
return
|
||||
}
|
||||
|
||||
if (data.type === 'unLockScreen') {
|
||||
updateLockScreen(getLockFlag(data, 0))
|
||||
return
|
||||
}
|
||||
|
||||
if (data.type === 'questionExplainStart') {
|
||||
let msg = data.msg
|
||||
if (typeof msg === 'string') {
|
||||
@ -190,6 +263,10 @@ function onLoaded() {
|
||||
onMounted(() => {
|
||||
$XXL.closeLoading()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stopLockHomePageRefresh()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<!-- @click="onPageClick" -->
|
||||
|
||||
@ -3,7 +3,7 @@ import { userStore, globalStore, taskStore, subjectStore } from '@/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import globalApi from '@/api/global'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAudio } from '@/hooks'
|
||||
import { useAudio, XMessage } from '@/hooks'
|
||||
import {
|
||||
getLevelProgress,
|
||||
$XXL,
|
||||
@ -43,6 +43,7 @@ const taskData = taskStore()
|
||||
const { userInfo, workToken } = storeToRefs(userStore())
|
||||
const { getUserInfo, isFirstBind } = userStore()
|
||||
const { system, checkUpdate } = globalStore()
|
||||
const isHomePageLoading = ref(false)
|
||||
|
||||
const navMain = computed(() => {
|
||||
// const { purchasedInspector, nextInspectorCourseDate, conductInspectorPlanId } =
|
||||
@ -238,6 +239,8 @@ function getTaskRedPoint() {
|
||||
const { selectSubject } = subjectStore()
|
||||
const handleNav = debounce(
|
||||
(data: anyObj) => {
|
||||
if (isHomePageLoading.value) return
|
||||
|
||||
if (data.key === 'homeWork' && userInfo.value.isTeacher) {
|
||||
const path = `${import.meta.env.VITE_TEACHER_ADMIN_URL}?token=${workToken.value.replace('Bearer ', '')}`
|
||||
if (isWebEvn) {
|
||||
@ -287,17 +290,36 @@ function handleKnown(data: anyObj) {
|
||||
|
||||
// 个人中心
|
||||
function handleToUserPage() {
|
||||
if (isHomePageLoading.value) return
|
||||
|
||||
router.push({ path: '/system/user' })
|
||||
}
|
||||
|
||||
// 点击个人形象
|
||||
function clickPhoto() {
|
||||
if (isHomePageLoading.value) return
|
||||
|
||||
if (isShufaAccount(userInfo.value.account)) {
|
||||
// 书法小状元的账号
|
||||
router.replace(SHUFA_PATH)
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshHomePage() {
|
||||
isHomePageLoading.value = true
|
||||
try {
|
||||
await getUserInfo()
|
||||
if (Number(userInfo.value.workMode) === 1) {
|
||||
XMessage.info('当前处于作业模式')
|
||||
await router.replace('/system/homeWork')
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} finally {
|
||||
isHomePageLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
let timer: any
|
||||
onMounted(async () => {
|
||||
// 是否首绑
|
||||
@ -316,7 +338,8 @@ onActivated(async () => {
|
||||
getPoint()
|
||||
getTaskRedPoint()
|
||||
|
||||
await getUserInfo()
|
||||
const isWorkMode = await refreshHomePage()
|
||||
if (isWorkMode) return
|
||||
|
||||
// 获取徽章
|
||||
await nextTick()
|
||||
|
||||
@ -190,7 +190,7 @@ const startDoWork = () => {
|
||||
></Empty>
|
||||
</div>
|
||||
<div class="top">
|
||||
<BackBar leftText="作业" />
|
||||
<BackBar leftText="作业" index />
|
||||
<div class="top-history">
|
||||
<!-- <mj-button type="success" tilt @click="to(`/system/homeWork/statistics`)"
|
||||
>统计分析</mj-button
|
||||
|
||||
@ -204,7 +204,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
// 全局的返回函数
|
||||
export function globalBack(home = false) {
|
||||
if (window.history.state?.position === 1 || !window.history.state.back || home) {
|
||||
router.push('/')
|
||||
router.replace('/')
|
||||
} else {
|
||||
const afterRoute = router.currentRoute.value.fullPath
|
||||
router.back()
|
||||
|
||||
@ -6,8 +6,9 @@ import loginApi from '@/api/login'
|
||||
import type { accountLoginType } from '@/api/login'
|
||||
import type { Option, UserData } from '@/api/global'
|
||||
import type { School } from '@/api/studentManage'
|
||||
import { setCache, clearCache, getSN, getManufacturer, isStudyMachine } from '@/utils'
|
||||
import { useSocket } from '@/hooks'
|
||||
import { setCache, clearCache, getSN, getManufacturer, isStudyMachine, isWebEvn } from '@/utils'
|
||||
import { LogType, useLog, useSocket } from '@/hooks'
|
||||
import { syncClassMonitorState } from '@/hooks/useClassMonitor'
|
||||
import { globalStore } from '@/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import obj from '@/utils/obj'
|
||||
@ -84,17 +85,42 @@ export const userStore = defineStore('user', () => {
|
||||
return userInfo.value.schoolClass?.[0]?.classList?.[0]
|
||||
}
|
||||
|
||||
const updateScreenLock = (screenLock?: unknown) => {
|
||||
const lockFlag = Number(screenLock)
|
||||
if (lockFlag !== 0 && lockFlag !== 1) return
|
||||
|
||||
const { system } = storeToRefs(globalStore())
|
||||
const isLock = lockFlag === 1
|
||||
if (!isStudyMachine && isLock) return
|
||||
if (system.value.isLock === isLock) return
|
||||
|
||||
system.value.isLock = isLock
|
||||
if (!isStudyMachine) return
|
||||
|
||||
useLog(LogType.LockScreenTime, {
|
||||
simSerialNumber: getSN(),
|
||||
lockFlag,
|
||||
})
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
const updateUserInfo = async (info: any) => {
|
||||
if (!info) return
|
||||
const hasMonitorState = Object.prototype.hasOwnProperty.call(info, 'monitorState')
|
||||
info = { ...userInfo.value, ...info }
|
||||
|
||||
if (isStudyMachine) {
|
||||
if (typeof info.screenLock !== 'undefined') {
|
||||
updateScreenLock(info.screenLock)
|
||||
} else if (isStudyMachine) {
|
||||
// 锁屏
|
||||
const { system } = storeToRefs(globalStore())
|
||||
system.value.isLock = info.lockFlag === 0
|
||||
}
|
||||
|
||||
if (hasMonitorState) {
|
||||
syncClassMonitorState(info.monitorState)
|
||||
}
|
||||
|
||||
if (typeof info.schoolClass === 'string') {
|
||||
info.schoolClass = JSON.parse(info.schoolClass)
|
||||
if (info.schoolClass?.length) {
|
||||
@ -158,13 +184,25 @@ export const userStore = defineStore('user', () => {
|
||||
setCache('token', `Bearer ${tokenValue}`)
|
||||
}
|
||||
|
||||
const getDeviceSerialNumber = () => {
|
||||
const { system } = globalStore()
|
||||
return system.device.SN || getSN()
|
||||
}
|
||||
|
||||
// 账号登录
|
||||
const accountLogin = async (data: accountLoginType) => {
|
||||
const res = await loginApi.psdLogin({
|
||||
const loginData: accountLoginType = {
|
||||
...data,
|
||||
simSerialNumber: getSN(),
|
||||
model: getManufacturer(),
|
||||
})
|
||||
}
|
||||
|
||||
if (isWebEvn) {
|
||||
delete loginData.simSerialNumber
|
||||
} else {
|
||||
loginData.simSerialNumber = getDeviceSerialNumber()
|
||||
}
|
||||
|
||||
const res = await loginApi.psdLogin(loginData)
|
||||
await loginBefore()
|
||||
setToken(res as any)
|
||||
await loginAfter()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user