diff --git a/.env.production b/.env.production index b7f30f3..c3b1489 100644 --- a/.env.production +++ b/.env.production @@ -19,7 +19,7 @@ VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktx VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/' # websocket 地址 -VITE_APP_WS_URL = 'wss://file.ysaix.com:7868' +VITE_APP_WS_URL = 'wss://prev.ysaix.com:7868' # 是否显示开发工具 -VITE_SHOW_DEV_TOOLS = 'true' +VITE_SHOW_DEV_TOOLS = 'false' diff --git a/src/renderer/src/AixPPTist/src/App.vue b/src/renderer/src/AixPPTist/src/App.vue index 7621b9f..c06919f 100644 --- a/src/renderer/src/AixPPTist/src/App.vue +++ b/src/renderer/src/AixPPTist/src/App.vue @@ -28,8 +28,9 @@ import msgUtils from '@/plugins/modal' // 消息工具 import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api import { PPTApi } from './api' import { sessionStore } from '@/utils/store' // electron-store 状态管理 -import './api/watcher' // 监听 - +// import './api/watcher' // 监听 +import watcher from './api/watcher' // 监听 +watcher() // 监听启动 const loading = ref(true) const _isPC = isPC() diff --git a/src/renderer/src/AixPPTist/src/api/classcourse.ts b/src/renderer/src/AixPPTist/src/api/classcourse.ts index e78a19d..f15b0af 100644 --- a/src/renderer/src/AixPPTist/src/api/classcourse.ts +++ b/src/renderer/src/AixPPTist/src/api/classcourse.ts @@ -7,13 +7,19 @@ import { sessionStore } from '@/utils/store' // electron-store 状态管理 import * as useStore from '../store' // pptist-状态管理 import ChatWs from '@/plugins/socket' // 聊天socket import msgUtils from '@/plugins/modal' // 消息工具 +import * as Fullscreen from '../utils/fullscreen' // 全屏 +import useExecPlay from '../views/Screen/hooks/useExecPlay' // 播放控制 +const slidesStore = useStore.useSlidesStore() // 幻灯片-状态管理 const screenStore = useStore.useScreenStore() // 全屏-状态管理 const classcourseStore = useStore.useClasscourseStore() // 课堂信息-状态管理 const classcourse = sessionStore.get('curr.classcourse') // 课堂信息 +const execPlay = useExecPlay() // 播放控制 export class Classcourse { msgObj:ElMessageBox = null // 提示消息对象 + classcourse:any = null // 课堂信息 + id: number|string = null // 课堂id constructor() { this.load() @@ -22,21 +28,36 @@ export class Classcourse { * @description 加载 */ load() { + console.log('classcourse-load', classcourse) // 打开全屏 - screenStore.setScreening(!!classcourse) + const isCourse = !!classcourse + if (isCourse) Fullscreen.enterFullscreen() + screenStore.setScreening(isCourse) // 如果课堂信息有值,则连接socket if (!!classcourse) { // 连接socket if (!ChatWs.ws) ChatWs.init() ChatWs.id = classcourse.timgroupid // 群组id - console.log('ws- ', classcourse) + this.classcourse = classcourse // 课堂信息 + this.id = classcourse.id // 课堂id + // 如果课堂信息有paging,则更新当前页码 + const isPaging = !!classcourse.paging + if (isPaging) slidesStore.updateSlideIndex(classcourse.paging) + // 如果课堂信息有paging,则更新动画播放状态 + const isAnim = !!classcourse.cartoonTimes + if (isAnim) { // 动画播放 + for (let i = 0; i <= classcourse.cartoonTimes; i++) { + execPlay.runAnimation(true) // 异步执行动画 + } + } + // 课堂信息-状态管理 classcourseStore.setClasscourse(classcourse) // 待上课提示 if (!classcourse.status) { this.msgObj = { type: 'success', title: '系统提示', - message: '公屏课堂已准备完毕,请等待老师开启课堂!', + message: '公屏课堂已准备完毕,等待老师开启课堂...', center: true, showClose: false, showCancelButton: false, diff --git a/src/renderer/src/AixPPTist/src/api/index.ts b/src/renderer/src/AixPPTist/src/api/index.ts index 611efb6..ba0130e 100644 --- a/src/renderer/src/AixPPTist/src/api/index.ts +++ b/src/renderer/src/AixPPTist/src/api/index.ts @@ -55,26 +55,28 @@ export class PPTApi { // 变量 static isUpdate = true // 是否更新数据 - // 获取所有幻灯片列表 - static getSlideList(parentid: (Number | String)): Promise { + // 获取所有幻灯片列表 isUpdate为true不更新 + static getSlideList(parentid: (Number | String),isUpdate?:Boolean): Promise { return new Promise(async (resolve, reject) => { const params: object = { parentid, orderByColumn: 'fileidx', isAsc: 'asc', pageSize: 9999 } const res: Result = await API_entpcoursefile.listEntpcoursefileNew(params) - if (res.code === 200) { - const slides = (res.rows || []).map(o => { - if (!!o.datacontent) { - const json = JSON.parse(o.datacontent) - !!json && (json.id = o.id) - return json - } - // 如果没有数据,默认空白页 - return {id: o.id,elements:[],background:{type:"solid",color:"#fff"}} - }) + if (res.code === 200) { + if(!isUpdate){ + const slides = (res.rows || []).map(o => { + if (!!o.datacontent) { + const json = JSON.parse(o.datacontent) + !!json && (json.id = o.id) + return json + } + // 如果没有数据,默认空白页 + return {id: o.id,elements:[],background:{type:"solid",color:"#fff"}} + }) + // slidesStore.updateSlideIndex(0) // 下标0 为第一页 + slidesStore.setSlides(slides) // 写入数据 + } // 活动列表处理 const workList = (res.rows || []).map(o => o.activityContent) - const workItem = [...res.rows] - // slidesStore.updateSlideIndex(0) // 下标0 为第一页 - slidesStore.setSlides(slides) // 写入数据 + const workItem = res.rows ? [...res.rows] : [] // 写入作业列表数据 slidesStore.setWorkList(workList) // 获取所有的pptlist的数据 @@ -111,7 +113,6 @@ export class PPTApi { data.id = rid slidesStore.updateSlide(data) // msgUtils.msgSuccess('新增成功') - PPTApi.getSlideList(resource.id) this.isUpdate = false // 新增后会触发监听,不再更新数据 resolve(true) } else msgUtils.msgError('新增失败');resolve(false) @@ -134,7 +135,9 @@ export class PPTApi { const isAdd = !/^\d+$/.test(currentSlide.id) // 是否新增 if (isAdd) { // 新增的幻灯片(id 为非数字,说明是新增的幻灯片) const bool = await this.addSlide(currentSlide) - bool && this.batchUpdateSlides(newData, true) // 批量更新-排序 + bool && await this.batchUpdateSlides(newData, true) // 批量更新-排序 + const resource = sessionStore.get('curr.resource')||{} + await PPTApi.getSlideList(resource.id) } else { // 防抖-更新 if (!this.isUpdate) return this.isUpdate = true // 下次更新数据 const params = { diff --git a/src/renderer/src/AixPPTist/src/api/types.ts b/src/renderer/src/AixPPTist/src/api/types.ts index 26881e9..e762748 100644 --- a/src/renderer/src/AixPPTist/src/api/types.ts +++ b/src/renderer/src/AixPPTist/src/api/types.ts @@ -106,6 +106,8 @@ export class MsgEnum { MSG_anmationclick : 'anmationclick', /** @desc: 群组创建成功 */ MSG_classcourseopen : 'classcourseopen', + /** @desc: 学生提交作业 */ + MSG_finishHomework : 'finishHomework', /** @desc: 学生的测练结果反馈 */ MSG_classquizfeedback : 'classquizfeedback', /** @desc: 老师端:接收到学生反馈消息-课堂测练中的其他任务 */ @@ -120,6 +122,12 @@ export class MsgEnum { MSG_classWorkOfPresentDataUpdate : 'classWorkOfPresentDataUpdate', /** @desc: 课堂讲授活动,选择不同的内容 */ MSG_classlecturePagesrc : 'classlecturePagesrc', + /** @desc: 课堂作业|活动 */ + MSG_homework : 'HOMEWORK', + /** @desc: 点赞 */ + MSG_dz : 'dz', + /** @desc: 疑惑 */ + MSG_yh : 'yh', // === 新定义-消息头 === /** @desc: 课程创建-待开课 */ MSG_0000: 0x0000, diff --git a/src/renderer/src/AixPPTist/src/api/watcher.ts b/src/renderer/src/AixPPTist/src/api/watcher.ts index ff14229..f555f3d 100644 --- a/src/renderer/src/AixPPTist/src/api/watcher.ts +++ b/src/renderer/src/AixPPTist/src/api/watcher.ts @@ -10,85 +10,111 @@ import { MsgEnum } from './types' // 消息枚举 import ChatWs from '@/plugins/socket' // 聊天socket import Classcourse from './classcourse' // 课程相关 import msgUtils from '@/plugins/modal' // 消息工具 -const slidesStore = store.useSlidesStore() -const classcourseStore = store.useClasscourseStore() // 课堂信息-状态管理 -const resource = sessionStore.get('curr.resource') // apt 资源 -const smarttalk = sessionStore.get('curr.smarttalk') // 备课资源 +import { Homework } from './index' // api-作业相关 +import emitter from '@/utils/mitt' //mitt 事件总线 +import useExecPlay from '../views/Screen/hooks/useExecPlay' // 播放控制 + /** * @description 监听器 */ -// 监听幻灯片内容变化 -watch(() => slidesStore.slides, (newVal, oldVal) => { - PPTApi.updateSlides(newVal, oldVal) // 更新幻灯片内容 -},{ deep: true }) - -// 监听标题变化 -watch(() => slidesStore.title, (newVal, oldVal) => { - if (oldVal == '未命名演示文稿') return // 初始加载,不需要更新数据 - updatePPT({title: newVal}) -}) - -// 消息监听ws -console.log('监听器已开启', ChatWs) -if (ChatWs.ws) { - ChatWs.watch((msg, e) => { - try { - handleMessage(JSON.parse(msg)) - } catch (error) { - console.error('socket 解析异常 ', error, e) - handleMessage(msg) - } +export default () => { + const slidesStore = store.useSlidesStore() + const classcourseStore = store.useClasscourseStore() // 课堂信息-状态管理 + const resource = sessionStore.get('curr.resource') // apt 资源 + const smarttalk = sessionStore.get('curr.smarttalk') // 备课资源 + const execPlay = useExecPlay() // 播放控制 + + // 监听幻灯片内容变化 + watch(() => slidesStore.slides, (newVal, oldVal) => { + PPTApi.updateSlides(newVal, oldVal) // 更新幻灯片内容 + },{ deep: true }) + + // 监听标题变化 + watch(() => slidesStore.title, (newVal, oldVal) => { + if (oldVal == '未命名演示文稿') return // 初始加载,不需要更新数据 + updatePPT({title: newVal}) }) -} - -// 更新ppt内容 -const updatePPT = async (data) => { - if (!resource) return - data.id = resource.id - await PPTApi.updateSlide(data) // 更新ppt内容 - sessionStore.set('curr.resource.title', data.title) - // 更新smarttalk内容 - if (!!smarttalk && !!data.title) { - const {id, fileFlag} = smarttalk - const params = { id, fileShowName: `${data.title}.${fileFlag}` } - await PPTApi.updateSmarttalk(params) // 更新ppt内容 - sessionStore.set('curr.smarttalk.fileShowName', params.fileShowName) + + // 消息监听ws + // console.log('监听器已开启', ChatWs) + if (!!ChatWs.ws) { + ChatWs.watch((data, e) => { + try { + handleMessage(JSON.parse(data)?.msg) + } catch (error) { + console.error('socket 解析异常 ', error, e) + handleMessage(data) + } + }) } -} - -// ws消息处理 -const handleMessage = (msg) => { - if (typeof msg === 'object'){ - const { head, content, ...other } = msg - switch (head) { - case MsgEnum.HEADS.MSG_open: // 开课 - // 课堂信息不一致 - if (Classcourse.id !== content.id) { - msgUtils.alertError('老师开课信息异常,请重新进入公屏!') - .then(() => { // 点击确定按钮,关闭窗口 - window.close() - }) - } else { // 正常更新数据 - classcourseStore.classcourse.status = 'open' - // 更新课堂信息-关闭警告框 - Classcourse?.msgObj?.onVanish() - } - break - case MsgEnum.HEADS.MSG_slideFlapping: // 幻灯片翻页 - const slideIndex = content.current - slidesStore.updateSlideIndex(slideIndex) // 更新幻灯片下标 - break - case MsgEnum.HEADS.MSG_closed: // 下课: - window.close() // 关闭窗口 - break - default: - break + + // 更新ppt内容 + const updatePPT = async (data) => { + if (!resource) return + data.id = resource.id + await PPTApi.updateSlide(data) // 更新ppt内容 + sessionStore.set('curr.resource.title', data.title) + // 更新smarttalk内容 + if (!!smarttalk && !!data.title) { + const {id, fileFlag} = smarttalk + const params = { id, fileShowName: `${data.title}.${fileFlag}` } + await PPTApi.updateSmarttalk(params) // 更新ppt内容 + sessionStore.set('curr.smarttalk.fileShowName', params.fileShowName) } } + + // ws消息处理 + const handleMessage = (msg) => { + console.log('ws消息处理', msg) + if (typeof msg === 'object'){ + const { head, content, ...other } = msg + switch (head) { + case MsgEnum.HEADS.MSG_open: // 开课 + // 课堂信息不一致 + if (Classcourse.id !== content.id) { + msgUtils.alertError('老师开课信息异常,请重新进入公屏!') + .then(() => { // 点击确定按钮,关闭窗口 + close() + }) + } else { // 正常更新数据 + classcourseStore.classcourse.status = 'open' + sessionStore.set('curr.classcourse.status', 'open') + // 更新课堂信息-关闭警告框 + Classcourse?.msgObj?.onVanish() + } + break + case MsgEnum.HEADS.MSG_slideFlapping: // 幻灯片翻页 + const slideIndex = content?.current || 0 + const type = content?.animation + if (type === 'Nextsteps') execPlay.execNext() // 下一步 + else if (type === 'Previoustep') execPlay.execPrev() // 上一步 + else slidesStore.updateSlideIndex(slideIndex) // 更新幻灯片下标 + break + case MsgEnum.HEADS.MSG_homework: // 作业|活动-布置 + if (!content.classWorkId) return + Homework.showHomework(content.classWorkId) + break + case MsgEnum.HEADS.MSG_closed: // 下课: + close() + break + case MsgEnum.HEADS.MSG_dz: // 点赞 + emitter.emit('upvoteTrigger', 1) + break + case MsgEnum.HEADS.MSG_yh: // 疑惑 + emitter.emit('upvoteTrigger', 2) + break + case MsgEnum.HEADS.MSG_0010: // 备用 + break + default: + break + } + } + } + // 关闭窗口 + const close = () => { + ChatWs?.close() // 关闭ws + setTimeout(() => { + window.close() // 关闭窗口 + }, 1000) + } } -// console.log('监听器已开启', Classcourse) -// setTimeout(() => { -// console.log('关闭弹窗') -// // Classcourse.msgObj?.close() -// Classcourse?.msgObj?.onVanish() -// }, 10 * 1000) \ No newline at end of file diff --git a/src/renderer/src/AixPPTist/src/hooks/useScreening.ts b/src/renderer/src/AixPPTist/src/hooks/useScreening.ts index e8cc32a..979b8c4 100644 --- a/src/renderer/src/AixPPTist/src/hooks/useScreening.ts +++ b/src/renderer/src/AixPPTist/src/hooks/useScreening.ts @@ -1,5 +1,6 @@ import { useScreenStore, useSlidesStore, useClasscourseStore } from '../store' import { enterFullscreen, exitFullscreen, isFullscreen } from '../utils/fullscreen' +import ChatWs from '@/plugins/socket' // 聊天socket export default () => { const screenStore = useScreenStore() @@ -23,7 +24,10 @@ export default () => { const classcourse = classcourseStore.classcourse if (!!classcourse) { //DOTO 有课堂,执行退相关操作 console.log('退出放映状态') - window.close() + ChatWs?.close() // 关闭ws + setTimeout(() => { + window.close() // 关闭窗口 + }, 1000) } else screenStore.setScreening(false) if (isFullscreen()) exitFullscreen() } diff --git a/src/renderer/src/AixPPTist/src/store/slides.ts b/src/renderer/src/AixPPTist/src/store/slides.ts index 37ba6b2..c86c7c7 100644 --- a/src/renderer/src/AixPPTist/src/store/slides.ts +++ b/src/renderer/src/AixPPTist/src/store/slides.ts @@ -145,21 +145,16 @@ export const useSlidesStore = defineStore('slides', { setWorkItem(list: Object[]) { this.workItem = list }, - addWorkItem(data: any) { - const id = data?.id - if (!id) return - this.workItem.splice(this.slideIndex + 1, 0, data) - this.slideIndex += 1 - }, addSlide(slide: Slide | Slide[]) { const slides = Array.isArray(slide) ? slide : [slide] for (const slide of slides) { if (slide.sectionTag) delete slide.sectionTag } + // const addIndex = this.slideIndex + 1 this.slides.splice(this.slideIndex, 0, ...slides) + // this.slideIndex = addIndex }, - updateSlide(props: Partial, slideId?: string) { const slideIndex = slideId ? this.slides.findIndex(item => item.id === slideId) : this.slideIndex this.slides[slideIndex] = { ...this.slides[slideIndex], ...props } diff --git a/src/renderer/src/AixPPTist/src/views/Editor/Toolbar/ElementStylePanel/Active/index.vue b/src/renderer/src/AixPPTist/src/views/Editor/Toolbar/ElementStylePanel/Active/index.vue index cddd334..1294986 100644 --- a/src/renderer/src/AixPPTist/src/views/Editor/Toolbar/ElementStylePanel/Active/index.vue +++ b/src/renderer/src/AixPPTist/src/views/Editor/Toolbar/ElementStylePanel/Active/index.vue @@ -168,6 +168,10 @@ const type = ref([ label: '常规作业', value: 'primary' }, + { + label: '框架梳理', + value: 'primary' + } ]) const objItem = ref({}) @@ -302,9 +306,9 @@ const getData = async (data: WorkItem) => { dialogVisible.value = false } const upDateData = async () => { - // await PPTApi.updateSlide(paramData.value) loadingActive.value = true - await updateEntpcoursefileNew(paramData.value) + await PPTApi.updateSlide(paramData.value) + // await updateEntpcoursefileNew(paramData.value) const resource = sessionStore.get('curr.resource') await PPTApi.getSlideList(resource.id) const res = await homeworklist({ ids: paramData.value.activityContent, pageSize: 100 }) diff --git a/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts b/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts index f002995..8ec0233 100644 --- a/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts +++ b/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts @@ -19,10 +19,10 @@ export default () => { // 最小已播放页面索引 const playedSlidesMinIndex = ref(slideIndex.value) - // 执行元素动画 - const runAnimation = () => { + // 执行元素动画 isAsync 为 true 时,异步执行,否则同步执行 + const runAnimation = (isAsync: boolean) => { // 正在执行动画时,禁止其他新的动画开始 - if (inAnimation.value) return + if (inAnimation.value && !isAsync) return const { animations, autoNext } = formatedAnimations.value[animationIndex.value] animationIndex.value += 1 @@ -69,7 +69,7 @@ export default () => { elRef.addEventListener('animationend', handleAnimationEnd, { once: true }) } } - + onMounted(() => { const firstAnimations = formatedAnimations.value[0] if (firstAnimations && firstAnimations.animations.length) { @@ -174,6 +174,7 @@ export default () => { // 鼠标滚动翻页 const mousewheelListener = throttle(function(e: WheelEvent) { + e.preventDefault() // 阻止默认事件 if (e.deltaY < 0) execPrev() else if (e.deltaY > 0) execNext() }, 500, { leading: true, trailing: false }) @@ -182,20 +183,20 @@ export default () => { const touchInfo = ref<{ x: number; y: number; } | null>(null) const touchStartListener = (e: TouchEvent) => { + e.preventDefault() // 阻止默认事件 touchInfo.value = { - x: e.changedTouches[0].pageX, - y: e.changedTouches[0].pageY, + // x: e.changedTouches[0].pageX, + // y: e.changedTouches[0].pageY, + x: e.changedTouches[0].clientX, + y: e.changedTouches[0].clientY, } } const touchEndListener = (e: TouchEvent) => { if (!touchInfo.value) return - - const offsetX = Math.abs(touchInfo.value.x - e.changedTouches[0].pageX) - const offsetY = e.changedTouches[0].pageY - touchInfo.value.y - + const offsetX = Math.abs(touchInfo.value.x - e.changedTouches[0].clientX) + const offsetY = e.changedTouches[0].clientY - touchInfo.value.y if ( Math.abs(offsetY) > offsetX && Math.abs(offsetY) > 50 ) { touchInfo.value = null - if (offsetY > 0) execPrev() else execNext() } @@ -203,6 +204,7 @@ export default () => { // 快捷键翻页 const keydownListener = (e: KeyboardEvent) => { + e.preventDefault() // 阻止默认事件 const key = e.key.toUpperCase() if (key === KEYS.UP || key === KEYS.LEFT || key === KEYS.PAGEUP) execPrev() diff --git a/src/renderer/src/api/file/index.js b/src/renderer/src/api/file/index.js index 25c7e76..dac999b 100644 --- a/src/renderer/src/api/file/index.js +++ b/src/renderer/src/api/file/index.js @@ -71,3 +71,11 @@ export const addFileToKj = (id) => { method: 'get' }) } + +export const getModelInfo = (params) => { + return request({ + url: '/education/llmModel/getModelInfo', + method: 'post', + params + }) +} diff --git a/src/renderer/src/layout/components/Aside.vue b/src/renderer/src/layout/components/Aside.vue index 9182498..ba2186f 100644 --- a/src/renderer/src/layout/components/Aside.vue +++ b/src/renderer/src/layout/components/Aside.vue @@ -5,13 +5,13 @@
    -
  • +
  • 学校认证 {{ userStore.DeptInfo.register.schoolName }} @@ -19,8 +19,8 @@
  • 加入学校
  • 个人中心
  • -
  • 学校管理
  • -
  • 班级中心
  • +
  • 学校管理
  • +
  • 班级中心
  • 退出登录
@@ -59,6 +59,7 @@ import { ElMessageBox, ElMessage } from 'element-plus' import useUserStore from '@/store/modules/user' import { sessionStore } from '@/utils/store' import pkc from "../../../../../package.json" +import defaultUserImg from '@/assets/images/img-avatar.png' const { ipcRenderer } = window.electron || {} diff --git a/src/renderer/src/plugins/imChat/msgEnum.js b/src/renderer/src/plugins/imChat/msgEnum.js index d5c72a3..803aea9 100644 --- a/src/renderer/src/plugins/imChat/msgEnum.js +++ b/src/renderer/src/plugins/imChat/msgEnum.js @@ -80,10 +80,10 @@ export class MsgEnum { MSG_anmationclick : 'anmationclick', /** @desc: 群组创建成功 */ MSG_classcourseopen : 'classcourseopen', - /** @desc: 学生的测练结果反馈 */ - MSG_classquizfeedback : 'classquizfeedback', /** @desc: 学生提交作业 */ MSG_finishHomework : 'finishHomework', + /** @desc: 学生的测练结果反馈 */ + MSG_classquizfeedback : 'classquizfeedback', /** @desc: 老师端:接收到学生反馈消息-课堂测练中的其他任务 */ MSG_classtaskfeedback : 'classtaskfeedback', /** @desc: 老师端:学生反馈的消息,具体要看其中的feedbackkey,类别较繁杂 */ @@ -96,6 +96,12 @@ export class MsgEnum { MSG_classWorkOfPresentDataUpdate : 'classWorkOfPresentDataUpdate', /** @desc: 课堂讲授活动,选择不同的内容 */ MSG_classlecturePagesrc : 'classlecturePagesrc', + /** @desc: 课堂作业|活动 */ + MSG_homework : 'HOMEWORK', + /** @desc: 点赞 */ + MSG_dz : 'dz', + /** @desc: 疑惑 */ + MSG_yh : 'yh', // === 新定义-消息头 === /** @desc: 课程创建-待开课 */ MSG_0000: 0x0000, @@ -140,4 +146,4 @@ export class MsgEnum { } } -export { MsgEnum as default } \ No newline at end of file +export default MsgEnum; \ No newline at end of file diff --git a/src/renderer/src/plugins/socket/index.js b/src/renderer/src/plugins/socket/index.js index e5d3289..5e9870f 100644 --- a/src/renderer/src/plugins/socket/index.js +++ b/src/renderer/src/plugins/socket/index.js @@ -28,6 +28,7 @@ export class ChatWs { const userStore = useUserStore() // 用户信息 const wsBase = import.meta.env.VITE_APP_WS_URL; // ws地址 this.url = `${wsBase||ChatWs.base}/ws/websocket/${userStore.id}`; + this.closed = false; // 关闭状态 防止重连失败 // this.init(url); } ChatWs.instance = this; @@ -38,6 +39,7 @@ export class ChatWs { // 初始化 init(url) { !!url && (this.url = url); + this.closed = false; // 关闭状态 防止重连失败 this.ws = null; const _this = this this.heartCheck = { @@ -64,43 +66,46 @@ export class ChatWs { }, this.timeout); }, }; - this.reconnect(); + return this.reconnect(); } // 重连 reconnect() { - const self = this; - if (!!this.ws) { // 关闭之前的链接 - this.ws.close() - this.ws = null - } - this.ws = new WebSocket(this.url); - this.ws.onopen = function () { - console.log("websocket-连接成功") - self.heartCheck.reset().start(); - }; - this.ws.onmessage = function (e) { - // console.log("websocket-收到消息", e) - // 拿到任何消息都说明当前连接是正常的 - const isBeat = e.data == 'pong' - isBeat && self.heartCheck.reset().start(); - const isEmpty = !e.data - const isExts = e.data.includes('sessionId') || e.data == ('pong') - if (isEmpty || isExts) return; - // 自定义处理 - self.onmessage && self.onmessage(e.data, e); - }; - this.ws.onerror = function (e) { - console.log("websocket-连接异常", e) - self.connectSocket() // 重连 - }; - this.ws.onclose = function (e) { - console.log("websocket-连接断开", e) - self.connectSocket() // 重连 - }; + return new Promise((resolve, reject) => { + const self = this; + if (!!this.ws) { // 关闭之前的链接 + this.ws.close() + this.ws = null + } + this.ws = new WebSocket(this.url); + this.ws.onopen = function () { + console.log("websocket-连接成功") + self.heartCheck.reset().start(); + resolve() + }; + this.ws.onmessage = function (e) { + // console.log("websocket-收到消息", e) + // 拿到任何消息都说明当前连接是正常的 + const isBeat = e.data == 'pong' + isBeat && self.heartCheck.reset().start(); + const isEmpty = !e.data + const isExts = e.data.includes('sessionId') || e.data == ('pong') + if (isEmpty || isExts) return; + // 自定义处理 + self.onmessage && self.onmessage(e.data, e); + }; + this.ws.onerror = function (e) { + console.log("websocket-连接异常", e) + self.connectSocket() // 重连 + }; + this.ws.onclose = function (e) { + console.log("websocket-连接断开", e) + self.connectSocket() // 重连 + }; + }) } connectSocket() { this.heartCheck.reset() // 重置心跳 - if (self.closed) return; // 关闭状态不重连 + if (this.closed) return this.ws = null; // 关闭状态不重连 // if(self.errCount <= 0) return; // 超过重连次数 // self.errCount--; // 重连次数减1 if (this.errTime) { @@ -157,6 +162,16 @@ export class ChatWs { this.closed = true; this.ws.close(); } + // 下课 + closedCourse(id) { + return new Promise((resolve, reject) => { + this.sendMsg('closed', '下课', null, 'group', id) + resolve() + // setTimeout(() => { + // this.close() // 关闭链接 + // }, 1000); + }) + } // 延时 ms 毫秒 sleep(ms){ return new Promise(resolve => setTimeout(resolve, ms)) diff --git a/src/renderer/src/views/classManage/reserv-item-apt.vue b/src/renderer/src/views/classManage/reserv-item-apt.vue index 55a2a51..67fb1ec 100644 --- a/src/renderer/src/views/classManage/reserv-item-apt.vue +++ b/src/renderer/src/views/classManage/reserv-item-apt.vue @@ -15,8 +15,7 @@