From 38c041465e44a0dfe4de14e648ffc834bfe645d4 Mon Sep 17 00:00:00 2001 From: zdg Date: Tue, 10 Dec 2024 10:08:53 +0800 Subject: [PATCH 1/2] =?UTF-8?q?ppt=E4=B8=8A=E8=AF=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +-- src/renderer/src/AixPPTist/src/App.vue | 2 +- .../src/AixPPTist/src/api/classcourse.ts | 12 ++++---- src/renderer/src/AixPPTist/src/api/index.ts | 21 ++++++++++++- src/renderer/src/AixPPTist/src/api/types.ts | 1 + src/renderer/src/AixPPTist/src/api/watcher.ts | 30 +++++++++++++++++++ .../src/AixPPTist/src/store/classcourse.ts | 2 +- src/renderer/src/plugins/socket/index.js | 25 +++++++++------- src/renderer/src/views/model/index.vue | 4 +-- .../views/prepare/container/class-start.vue | 11 +++---- 10 files changed, 84 insertions(+), 28 deletions(-) diff --git a/.env.development b/.env.development index b3a7114..422cd04 100644 --- a/.env.development +++ b/.env.development @@ -17,8 +17,8 @@ VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktx VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/' # websocket 地址 -# VITE_APP_WS_URL = 'wss://file.ysaix.com:7868' -VITE_APP_WS_URL = 'ws://192.168.2.16:7865' +VITE_APP_WS_URL = 'wss://file.ysaix.com:7868' +# VITE_APP_WS_URL = 'ws://192.168.2.16:7865' # 是否显示开发工具 VITE_SHOW_DEV_TOOLS = 'true' diff --git a/src/renderer/src/AixPPTist/src/App.vue b/src/renderer/src/AixPPTist/src/App.vue index 77b800d..f90545d 100644 --- a/src/renderer/src/AixPPTist/src/App.vue +++ b/src/renderer/src/AixPPTist/src/App.vue @@ -27,8 +27,8 @@ 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/classcourse' // 课程相关 +import './api/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 ca162e1..efa8df9 100644 --- a/src/renderer/src/AixPPTist/src/api/classcourse.ts +++ b/src/renderer/src/AixPPTist/src/api/classcourse.ts @@ -2,20 +2,20 @@ * @author zdg * @description 上课相关内容 */ -import type { Classcourse } from './types' +// import type { Classcourse } from './types' import { sessionStore } from '@/utils/store' // electron-store 状态管理 import * as useStore from '../store' // pptist-状态管理 -import { ChatWs } from '@/plugins/socket' // 聊天socket +import ChatWs from '@/plugins/socket' // 聊天socket const screenStore = useStore.useScreenStore() // 全屏-状态管理 const classcourseStore = useStore.useClasscourseStore() // 课堂信息-状态管理 -const classcourse: Classcourse = sessionStore.get('curr.classcourse') // 课堂信息 +const classcourse = sessionStore.get('curr.classcourse') // 课堂信息 // 如果课堂信息有值,则连接socket if (!!classcourse) { // 连接socket - const ws = new ChatWs() - console.log('ws- ',ws) - // ChatWs.connect(classcourse.id) + if (!ChatWs.ws) ChatWs.init() + ChatWs.id = classcourse.timgroupid // 群组id + console.log('ws- ',ws, classcourse) classcourseStore.setClasscourse(classcourse) } // 打开全屏 diff --git a/src/renderer/src/AixPPTist/src/api/index.ts b/src/renderer/src/AixPPTist/src/api/index.ts index b0c8239..57bc29e 100644 --- a/src/renderer/src/AixPPTist/src/api/index.ts +++ b/src/renderer/src/AixPPTist/src/api/index.ts @@ -3,7 +3,7 @@ * @author zdg * @date 2024-11-26 */ -import { toRaw } from 'vue' +import { toRaw, nextTick } from 'vue' import type { Result } from './types' // 接口类型 import msgUtils from '@/plugins/modal' // 消息工具 import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api @@ -12,6 +12,8 @@ import * as useStore from '../store' // pptist-状态管理 import { sessionStore } from '@/utils/store' // electron-store 状态管理 import useUserStore from '@/store/modules/user' // 外部-用户信息 +import { toPng, toJpeg } from 'html-to-image' // 引入html-to-image库 + const slidesStore = useStore.useSlidesStore() const userStore = useUserStore() @@ -142,6 +144,8 @@ export class PPTApi { // 更新幻灯片 static updateSlide(data: object): Promise { return new Promise(async (resolve, reject) => { + const thumUrl = await this.getSlideThumUrl() + data.base64Code = thumUrl // 更新缩略图 const res: Result = await API_entpcoursefile.updateEntpcoursefileNew(data) if (res.code === 200) { resolve(true) @@ -184,6 +188,21 @@ export class PPTApi { else msgUtils.msgError(res.msg || '更新失败');return false }) } + // thumbnail-slide thumbnail + static getSlideThumUrl(): Promise { + return nextTick().then(async() => { + const slideIndex = slidesStore.slideIndex + const elements = document.querySelectorAll('.thumbnail-slide') + if (elements.length && slideIndex >= 0) { + const element = elements[slideIndex] + return await toPng(element) + } + return null + }) + // return API_smarttalk.updateThumbnail().then(res => { + // if (res.code === 200) return true + // else msgUtils.msgError(res.msg || '更新失败');return false + } } export default PPTApi \ No newline at end of file diff --git a/src/renderer/src/AixPPTist/src/api/types.ts b/src/renderer/src/AixPPTist/src/api/types.ts index 8d4f81c..1f2de61 100644 --- a/src/renderer/src/AixPPTist/src/api/types.ts +++ b/src/renderer/src/AixPPTist/src/api/types.ts @@ -19,6 +19,7 @@ export interface Classcourse { entpcoursefileid?: number|string, // 课程文件id classid?: number|string, // 班级id entpcourseid?: number|string, // 章节中间表id + timgroupid?: number|string, // ws 群组id plandate?: string, // 计划时间 opendate?: string, // 开课时间 } \ No newline at end of file diff --git a/src/renderer/src/AixPPTist/src/api/watcher.ts b/src/renderer/src/AixPPTist/src/api/watcher.ts index f1f21ba..f515b8e 100644 --- a/src/renderer/src/AixPPTist/src/api/watcher.ts +++ b/src/renderer/src/AixPPTist/src/api/watcher.ts @@ -6,6 +6,7 @@ import { watch } from 'vue' import { PPTApi } from './index' import * as store from '../store' import { sessionStore } from '@/utils/store' // electron-store 状态管理 +import ChatWs from '@/plugins/socket' // 聊天socket const slidesStore = store.useSlidesStore() const resource = sessionStore.get('curr.resource') // apt 资源 const smarttalk = sessionStore.get('curr.smarttalk') // 备课资源 @@ -24,6 +25,19 @@ watch(() => slidesStore.title, (newVal, oldVal) => { updatePPT({title: newVal}) }) +// 消息监听ws +if (ChatWs.ws) { + ChatWs.watch((msg, e) => { + try { + handleMessage(JSON.parse(msg)) + } catch (error) { + console.error('socket 解析异常 ', error, e) + handleMessage(msg) + } + }) +} + +// 更新ppt内容 const updatePPT = async (data) => { if (!resource) return data.id = resource.id @@ -36,4 +50,20 @@ const updatePPT = async (data) => { await PPTApi.updateSmarttalk(params) // 更新ppt内容 sessionStore.set('curr.smarttalk.fileShowName', params.fileShowName) } +} + +// ws消息处理 +const handleMessage = (msg) => { + if (typeof msg === 'object'){ + const { head, content, ...other } = msg + console.log('ws-msg', head, content, other) + switch (head) { + case 'chat': + break + case 'update': + break + default: + break + } + } } \ No newline at end of file diff --git a/src/renderer/src/AixPPTist/src/store/classcourse.ts b/src/renderer/src/AixPPTist/src/store/classcourse.ts index 7abd3fe..bd77fbd 100644 --- a/src/renderer/src/AixPPTist/src/store/classcourse.ts +++ b/src/renderer/src/AixPPTist/src/store/classcourse.ts @@ -2,7 +2,7 @@ import { defineStore } from 'pinia' import type { Classcourse } from '../api/types' export interface ClasscourseState { - classcourse: Classcourse + classcourse: Classcourse | any, // 课堂信息 } export const useClasscourseStore = defineStore('classcourse', { diff --git a/src/renderer/src/plugins/socket/index.js b/src/renderer/src/plugins/socket/index.js index 968ac53..3edd643 100644 --- a/src/renderer/src/plugins/socket/index.js +++ b/src/renderer/src/plugins/socket/index.js @@ -8,6 +8,7 @@ import useUserStore from '@/store/modules/user' // 用户信息 export class ChatWs { instance = null; // 实例 id = null; // 群聊id || 单聊id-用户id(userId) + url = null; // ws地址 closed = false; // 关闭状态 onmessage = null; // 自定义处理 errCount = 5; // 重连次数 (ms) 暂时不使用 @@ -19,12 +20,16 @@ export class ChatWs { beat: 'heart_beat', // 心跳 } static base = 'wss://file.ysaix.com:7868' - constructor() { + + // 构造函数 是否自动连接 + constructor(bool = true) { if (!ChatWs.instance) { - const userStore = useUserStore() // 用户信息 - const wsBase = import.meta.env.VITE_APP_WS_URL; // ws地址 - const url = `${wsBase||ChatWs.base}/ws/websocket/${userStore.id}`; - this.init(url); + if (bool) { // 是否自动连接 + const userStore = useUserStore() // 用户信息 + const wsBase = import.meta.env.VITE_APP_WS_URL; // ws地址 + this.url = `${wsBase||ChatWs.base}/ws/websocket/${userStore.id}`; + // this.init(url); + } ChatWs.instance = this; } return ChatWs.instance; @@ -32,7 +37,7 @@ export class ChatWs { // 初始化 init(url) { - this.url = url; + !!url && (this.url = url); this.ws = null; const _this = this this.heartCheck = { @@ -78,10 +83,9 @@ export class ChatWs { // 拿到任何消息都说明当前连接是正常的 const isBeat = e.data == 'pong' isBeat && self.heartCheck.reset().start(); - const exts = ['sessionId', 'pong'] // 不处理的消息头 const isEmpty = !e.data - const isExts = exts.some(item => e.data.includes(item)) - if (isEmpty && isExts) return; + const isExts = e.data.includes('sessionId') || e.data == ('pong') + if (isEmpty || isExts) return; // 自定义处理 self.onmessage && self.onmessage(e.data, e); }; @@ -137,7 +141,7 @@ export class ChatWs { * @param {*} id 群聊id || 单聊id-用户id(userId) */ getMsgObj(msg, chatType = 'group', id) { - if (typeof msg === "object") msg = JSON.stringify(msg) + // if (typeof msg === "object") msg = JSON.stringify(msg) const res = {msg, chatType} // if (!id) throw new Error(`${type=='group'?'群ID':'用户ID'} is not null`) if (chatType == 'group') res.groupId = id || this.id || '' @@ -160,5 +164,6 @@ export class ChatWs { } // 连接socket export const connect = () => new ChatWs() +export const getInstance = () => new ChatWs(false) // 默认实例 export default new ChatWs() \ No newline at end of file diff --git a/src/renderer/src/views/model/index.vue b/src/renderer/src/views/model/index.vue index 3fe9bbc..b290275 100644 --- a/src/renderer/src/views/model/index.vue +++ b/src/renderer/src/views/model/index.vue @@ -199,8 +199,8 @@ const HTTP_SERVER_API = (type, params = {}) => { case 'addSmarttalk': { // 获取课程 const def = { fileId: '', // 文件id - Entpcoursefile 对应id - fileFlag: 'aptist', - fileShowName: courseObj.coursetitle + '.aptist', + fileFlag: 'aippt', + fileShowName: courseObj.coursetitle + '.aippt', textbookId: courseObj.textbookId, levelFirstId: courseObj.levelFirstId, levelSecondId: courseObj.levelSecondId, diff --git a/src/renderer/src/views/prepare/container/class-start.vue b/src/renderer/src/views/prepare/container/class-start.vue index 77eb615..08b3b7f 100644 --- a/src/renderer/src/views/prepare/container/class-start.vue +++ b/src/renderer/src/views/prepare/container/class-start.vue @@ -267,10 +267,10 @@ const createClasscourse = async () => { setTimeout(() => { msgEl.close() msgEl = ElMessage.warning({message:'正在打开公屏,请稍后...',duration: 0}) - setTimeout(() => { + setTimeout(async() => { msgEl.close() - const classcourse = {...params, id: teacherForm.form.classcourseid} - openPublicScreen(classcourse) + const res = await Http_Classcourse.getClasscourse(teacherForm.form.classcourseid) + openPublicScreen(res.data) }, 2000); }, 1000); } @@ -303,9 +303,10 @@ const classTeachingStart = async () => { // 新版-pptList 打开公屏 if (myClassActive.value.filetype == 'aptist') { const msgEl = ElMessage.warning({message:'正在打开公屏,请稍后...',duration: 0}) - setTimeout(() => { + setTimeout(async () => { msgEl.close() - openPublicScreen({id}) + const res = await Http_Classcourse.getClasscourse(teacherForm.form.classcourseid) + openPublicScreen(res.data) }, 2000); }else { const url = `/teaching/classteaching?classcourseid=${id}&actor=classTeachingOnPublicScreen` -- 2.44.0.windows.1 From 9e5609fbdd118708d169969417c815790b12c39b Mon Sep 17 00:00:00 2001 From: zdg Date: Wed, 11 Dec 2024 09:44:52 +0800 Subject: [PATCH 2/2] =?UTF-8?q?ppt=E4=B8=8A=E8=AF=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/AixPPTist/src/App.vue | 1 - .../src/AixPPTist/src/api/classcourse.ts | 48 ++++-- src/renderer/src/AixPPTist/src/api/types.ts | 142 +++++++++++++++++- src/renderer/src/AixPPTist/src/api/watcher.ts | 35 ++++- src/renderer/src/plugins/imChat/msgEnum.js | 4 + src/renderer/src/plugins/modal.js | 37 ++--- src/renderer/src/plugins/socket/index.js | 10 +- .../src/views/classManage/reserv-item-apt.vue | 40 +++-- .../views/prepare/container/class-start.vue | 53 ++++--- src/renderer/src/views/prepare/index.vue | 34 ++++- 10 files changed, 330 insertions(+), 74 deletions(-) diff --git a/src/renderer/src/AixPPTist/src/App.vue b/src/renderer/src/AixPPTist/src/App.vue index f90545d..7cb504f 100644 --- a/src/renderer/src/AixPPTist/src/App.vue +++ b/src/renderer/src/AixPPTist/src/App.vue @@ -27,7 +27,6 @@ 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/classcourse' // 课程相关 import './api/watcher' // 监听 const loading = ref(true) diff --git a/src/renderer/src/AixPPTist/src/api/classcourse.ts b/src/renderer/src/AixPPTist/src/api/classcourse.ts index efa8df9..e78a19d 100644 --- a/src/renderer/src/AixPPTist/src/api/classcourse.ts +++ b/src/renderer/src/AixPPTist/src/api/classcourse.ts @@ -6,17 +6,47 @@ import { sessionStore } from '@/utils/store' // electron-store 状态管理 import * as useStore from '../store' // pptist-状态管理 import ChatWs from '@/plugins/socket' // 聊天socket +import msgUtils from '@/plugins/modal' // 消息工具 + const screenStore = useStore.useScreenStore() // 全屏-状态管理 const classcourseStore = useStore.useClasscourseStore() // 课堂信息-状态管理 const classcourse = sessionStore.get('curr.classcourse') // 课堂信息 -// 如果课堂信息有值,则连接socket -if (!!classcourse) { - // 连接socket - if (!ChatWs.ws) ChatWs.init() - ChatWs.id = classcourse.timgroupid // 群组id - console.log('ws- ',ws, classcourse) - classcourseStore.setClasscourse(classcourse) +export class Classcourse { + msgObj:ElMessageBox = null // 提示消息对象 + + constructor() { + this.load() + } + /** + * @description 加载 + */ + load() { + // 打开全屏 + screenStore.setScreening(!!classcourse) + // 如果课堂信息有值,则连接socket + if (!!classcourse) { + // 连接socket + if (!ChatWs.ws) ChatWs.init() + ChatWs.id = classcourse.timgroupid // 群组id + console.log('ws- ', classcourse) + classcourseStore.setClasscourse(classcourse) + // 待上课提示 + if (!classcourse.status) { + this.msgObj = { + type: 'success', + title: '系统提示', + message: '公屏课堂已准备完毕,请等待老师开启课堂!', + center: true, + showClose: false, + showCancelButton: false, + showConfirmButton: false, + beforeClose: () => {} + } + msgUtils.ElMessageBox(this.msgObj) + } + } + } } -// 打开全屏 -screenStore.setScreening(!!classcourse) \ No newline at end of file + +export default new Classcourse() \ No newline at end of file diff --git a/src/renderer/src/AixPPTist/src/api/types.ts b/src/renderer/src/AixPPTist/src/api/types.ts index 1f2de61..26881e9 100644 --- a/src/renderer/src/AixPPTist/src/api/types.ts +++ b/src/renderer/src/AixPPTist/src/api/types.ts @@ -22,4 +22,144 @@ export interface Classcourse { timgroupid?: number|string, // ws 群组id plandate?: string, // 计划时间 opendate?: string, // 开课时间 -} \ No newline at end of file +} + +/** + * @description 消息枚举 + * @author zdg + * @date 2021-07-05 14:07:01 + */ + +export class MsgEnum { + /** + * @description: 消息类型 + * + * | 名称 | 含义 | 值(enum) | + * | ---- | ---- | ---- | + * | SYSTEM | 系统消息 | system | + * | TEACHER | 老师消息 | teacher | + * | STUDENT | 学生消息 | student | + * | NOTICE | 通知消息 | notice | + */ + static TYPES = { + /** @desc: 系统消息 */ + SYSTEM: 'system', + /** @desc: 老师消息 */ + TEACHER: 'teacher', + /** @desc: 学生消息 */ + STUDENT: 'student', + /** @desc: 通知消息 */ + NOTICE: 'notice' + } + /** + * @description: 消息头-类型 + * + * | 名称 | 含义 | 值(enum) | + * | ---- | ---- | ---- | + * | --- | 以下为旧定义-消息头 | --- | + * | MSG_closed | 结束课程(下课) | closed | + * | MSG_onlineStatus | 在线状态 | onlineStatus | + * | MSG_pushQuizOfClassWorkdata2Public | 老师端:把选中的学生习题作业,推到大屏 | pushQuizOfClassWorkdata2Public | + * | MSG_pushClassWorkdata2Public | 老师端:把选中的学生作业,推到大屏 | pushClassWorkdata2Public | + * | MSG_shareStudentPresentdata2All | 把某个学生的展示成果数据推给全班所有学生 | shareStudentPresentdata2All | + * | MSG_pushStudentPresentdata2Public | 老师端:课堂展示活动,把选中的学生展示数据,推到大屏 | pushStudentPresentdata2Public | + * | MSG_pushClassWorkPresentList2Public | 老师端:课堂展示活动,任务列表,推到大屏 | pushClassWorkPresentList2Public | + * | MSG_activePageType | 课标研读-分页切换 | activePageType | + * | MSG_slideFlapping | 幻灯片-切换 | slideFlapping | + * | MSG_anmationclick | 幻灯片-动画切换 | anmationclick | + * | MSG_classcourseopen | 群组创建成功 | classcourseopen | + * | MSG_classquizfeedback | 学生的测练结果反馈 | classquizfeedback | + * | MSG_classtaskfeedback | 老师端:接收到学生反馈消息-课堂测练中的其他任务 | classtaskfeedback | + * | MSG_studentfeedback | 老师端:学生反馈的消息,具体要看其中的feedbackkey,类别较繁杂 | studentfeedback | + * | MSG_studentfeedbackcancel | 老师端:学生反馈的消息取消,如取消学会了,取消困惑 | studentfeedbackcancel | + * | MSG_classshowdata | 学生提交的课堂展示数据-要在老师端显示,再由老师选择推送到公屏上 | classshowdata | + * | MSG_classWorkOfPresentDataUpdate | 学生在公屏上展示并完善后,保存后,老师端要更新 | classWorkOfPresentDataUpdate | + * | MSG_classlecturePagesrc | 课堂讲授活动,选择不同的内容 | classlecturePagesrc | + * | --- | 以下为新定义-消息头 | --- | + * | MSG_0001 | 点赞 | 0x0001 | + * | MSG_0002 | xx | 0x0002 | + * | MSG_0003 | xx | 0x0003 | + */ + static HEADS = { + // === 旧定义-消息头(兼容以前) === + /** @desc: 开课 */ + MSG_open : 'open', + /** @desc: 结束课程(下课) */ + MSG_closed : 'closed', + /** @desc: 在线状态 */ + MSG_onlineStatus : 'onlineStatus', + /** @desc: 老师端:把选中的学生习题作业,推到大屏 */ + MSG_pushQuizOfClassWorkdata2Public : 'pushQuizOfClassWorkdata2Public', + /** @desc: 老师端:把选中的学生作业,推到大屏 */ + MSG_pushClassWorkdata2Public : 'pushClassWorkdata2Public', + /** @desc: 把某个学生的展示成果数据推给全班所有学生 */ + MSG_shareStudentPresentdata2All : 'shareStudentPresentdata2All', + /** @desc: 老师端:课堂展示活动,把选中的学生展示数据,推到大屏 */ + MSG_pushStudentPresentdata2Public : 'pushStudentPresentdata2Public', + /** @desc: 老师端:课堂展示活动,任务列表,推到大屏 */ + MSG_pushClassWorkPresentList2Public : 'pushClassWorkPresentList2Public', + /** @desc: 课标研读-分页切换 */ + MSG_activePageType : 'activePageType', + /** @desc: 幻灯片-切换 */ + MSG_slideFlapping : 'slideFlapping', + /** @desc: 幻灯片-动画切换 */ + MSG_anmationclick : 'anmationclick', + /** @desc: 群组创建成功 */ + MSG_classcourseopen : 'classcourseopen', + /** @desc: 学生的测练结果反馈 */ + MSG_classquizfeedback : 'classquizfeedback', + /** @desc: 老师端:接收到学生反馈消息-课堂测练中的其他任务 */ + MSG_classtaskfeedback : 'classtaskfeedback', + /** @desc: 老师端:学生反馈的消息,具体要看其中的feedbackkey,类别较繁杂 */ + MSG_studentfeedback : 'studentfeedback', + /** @desc: 老师端:学生反馈的消息取消,如取消学会了,取消困惑 */ + MSG_studentfeedbackcancel : 'studentfeedbackcancel', + /** @desc: 学生提交的课堂展示数据-要在老师端显示,再由老师选择推送到公屏上 */ + MSG_classshowdata : 'classshowdata', + /** @desc: 学生在公屏上展示并完善后,保存后,老师端要更新 */ + MSG_classWorkOfPresentDataUpdate : 'classWorkOfPresentDataUpdate', + /** @desc: 课堂讲授活动,选择不同的内容 */ + MSG_classlecturePagesrc : 'classlecturePagesrc', + // === 新定义-消息头 === + /** @desc: 课程创建-待开课 */ + MSG_0000: 0x0000, + /** @desc: 点赞 */ + MSG_0001: 0x0001, + /** @desc: 疑惑 */ + MSG_0002: 0x0002, + MSG_0003: 0x0003, + MSG_0004: 0x0004, + MSG_0005: 0x0005, + MSG_0006: 0x0006, + MSG_0007: 0x0007, + MSG_0008: 0x0008, + MSG_0009: 0x0009, + MSG_0010: 0x000a, + MSG_0011: 0x000b, + MSG_0012: 0x000c, + MSG_0013: 0x000d, + MSG_0014: 0x000e, + MSG_0015: 0x000f, + /** @desc: 作业推送 */ + MSG_0016: 0x0010, + MSG_0017: 0x0011, + MSG_0018: 0x0012, + MSG_0019: 0x0013, + MSG_0020: 0x0014, + MSG_0021: 0x0015, + MSG_0022: 0x0016, + MSG_0023: 0x0017, + MSG_0024: 0x0018, + MSG_0025: 0x0019, + MSG_0026: 0x001a, + MSG_0027: 0x001b, + MSG_0028: 0x001c, + MSG_0029: 0x001d, + MSG_0030: 0x001e, + MSG_0031: 0x001f, + MSG_0032: 0x0020, + MSG_0033: 0x0021, + MSG_0034: 0x0022, + MSG_0035: 0x0023, + } +} diff --git a/src/renderer/src/AixPPTist/src/api/watcher.ts b/src/renderer/src/AixPPTist/src/api/watcher.ts index f515b8e..ff14229 100644 --- a/src/renderer/src/AixPPTist/src/api/watcher.ts +++ b/src/renderer/src/AixPPTist/src/api/watcher.ts @@ -6,14 +6,17 @@ import { watch } from 'vue' import { PPTApi } from './index' import * as store from '../store' import { sessionStore } from '@/utils/store' // electron-store 状态管理 +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') // 备课资源 /** * @description 监听器 */ - // 监听幻灯片内容变化 watch(() => slidesStore.slides, (newVal, oldVal) => { PPTApi.updateSlides(newVal, oldVal) // 更新幻灯片内容 @@ -26,6 +29,7 @@ watch(() => slidesStore.title, (newVal, oldVal) => { }) // 消息监听ws +console.log('监听器已开启', ChatWs) if (ChatWs.ws) { ChatWs.watch((msg, e) => { try { @@ -56,14 +60,35 @@ const updatePPT = async (data) => { const handleMessage = (msg) => { if (typeof msg === 'object'){ const { head, content, ...other } = msg - console.log('ws-msg', head, content, other) switch (head) { - case 'chat': + 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 'update': + case MsgEnum.HEADS.MSG_slideFlapping: // 幻灯片翻页 + const slideIndex = content.current + slidesStore.updateSlideIndex(slideIndex) // 更新幻灯片下标 + break + case MsgEnum.HEADS.MSG_closed: // 下课: + window.close() // 关闭窗口 break default: break } } -} \ No newline at end of file +} +// 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/plugins/imChat/msgEnum.js b/src/renderer/src/plugins/imChat/msgEnum.js index da8e486..d685406 100644 --- a/src/renderer/src/plugins/imChat/msgEnum.js +++ b/src/renderer/src/plugins/imChat/msgEnum.js @@ -56,6 +56,8 @@ export class MsgEnum { */ static HEADS = { // === 旧定义-消息头(兼容以前) === + /** @desc: 开课 */ + MSG_open : 'open', /** @desc: 结束课程(下课) */ MSG_closed : 'closed', /** @desc: 在线状态 */ @@ -93,6 +95,8 @@ export class MsgEnum { /** @desc: 课堂讲授活动,选择不同的内容 */ MSG_classlecturePagesrc : 'classlecturePagesrc', // === 新定义-消息头 === + /** @desc: 课程创建-待开课 */ + MSG_0000: 0x0000, /** @desc: 点赞 */ MSG_0001: 0x0001, /** @desc: 疑惑 */ diff --git a/src/renderer/src/plugins/modal.js b/src/renderer/src/plugins/modal.js index b59e14d..679b446 100644 --- a/src/renderer/src/plugins/modal.js +++ b/src/renderer/src/plugins/modal.js @@ -5,51 +5,51 @@ let loadingInstance; export default { // 消息提示 msg(content) { - ElMessage.info(content) + return ElMessage.info(content) }, // 错误消息 msgError(content) { - ElMessage.error(content) + return ElMessage.error(content) }, // 成功消息 msgSuccess(content) { - ElMessage.success(content) + return ElMessage.success(content) }, // 警告消息 msgWarning(content) { - ElMessage.warning(content) + return ElMessage.warning(content) }, // 弹出提示 - alert(content) { - ElMessageBox.alert(content, "系统提示") + alert(content, option = {}) { + return ElMessageBox.alert(content, "系统提示", option) }, // 错误提示 - alertError(content) { - ElMessageBox.alert(content, "系统提示", { type: 'error' }) + alertError(content, option = {}) { + return ElMessageBox.alert(content, "系统提示", { type: 'error', ...option }) }, // 成功提示 - alertSuccess(content) { - ElMessageBox.alert(content, "系统提示", { type: 'success' }) + alertSuccess(content, option = {}) { + return ElMessageBox.alert(content, "系统提示", { type: 'success', ...option }) }, // 警告提示 - alertWarning(content) { - ElMessageBox.alert(content, "系统提示", { type: 'warning' }) + alertWarning(content, option = {}) { + return ElMessageBox.alert(content, "系统提示", { type: 'warning', ...option }) }, // 通知提示 notify(content) { - ElNotification.info(content) + return ElNotification.info(content) }, // 错误通知 notifyError(content) { - ElNotification.error(content); + return ElNotification.error(content); }, // 成功通知 notifySuccess(content) { - ElNotification.success(content) + return ElNotification.success(content) }, // 警告通知 notifyWarning(content) { - ElNotification.warning(content) + return ElNotification.warning(content) }, // 确认窗体 confirm(content) { @@ -78,5 +78,8 @@ export default { // 关闭遮罩层 closeLoading() { loadingInstance.close(); - } + }, + // messageBox: opt => ElMessageBox(opt), + // 其他实例放出去,方便调用 + ElMessage, ElMessageBox, ElNotification, ElLoading } diff --git a/src/renderer/src/plugins/socket/index.js b/src/renderer/src/plugins/socket/index.js index 3edd643..e5d3289 100644 --- a/src/renderer/src/plugins/socket/index.js +++ b/src/renderer/src/plugins/socket/index.js @@ -41,7 +41,7 @@ export class ChatWs { this.ws = null; const _this = this this.heartCheck = { - timeout: 1000 * 10, // 60s + timeout: 1000 * 60, // 60s timeoutObj: null, serverTimeoutObj: null, reset() { @@ -122,12 +122,12 @@ export class ChatWs { this.ws.send(msg) } // 发送消息-带消息头(key) - sendMsg(head, content, option = {}) { - if (!head) throw new Error("head is not null") - if (!content) throw new Error("content is not null") + sendMsg(head, content, option = {}, ...arg) { + if (!head && head!==0) throw new Error("head is not null") + if (!content && content!==0) throw new Error("content is not null") let msg = { head, content, ...option } // 发送消息 - this.send(this.getMsgObj(msg)) + this.send(this.getMsgObj(msg, ...arg)) } // 发送心跳 sendMsgBeat() { diff --git a/src/renderer/src/views/classManage/reserv-item-apt.vue b/src/renderer/src/views/classManage/reserv-item-apt.vue index 59c1137..55a2a51 100644 --- a/src/renderer/src/views/classManage/reserv-item-apt.vue +++ b/src/renderer/src/views/classManage/reserv-item-apt.vue @@ -7,15 +7,20 @@ {{item.caption}}
- 已结束 - 上课中 - 继续上课 - - 下课{{ loading?'中...':'' }} + 待开课 + 已结束 + 上课中 + +
@@ -25,10 +30,12 @@