ppt上课

This commit is contained in:
zdg 2024-12-10 10:08:53 +08:00
parent 97962d591f
commit 38c041465e
10 changed files with 84 additions and 28 deletions

View File

@ -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'

View File

@ -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()

View File

@ -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)
}
// 打开全屏

View File

@ -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<Boolean> {
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<Boolean> {
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

View File

@ -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, // 开课时间
}

View File

@ -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
@ -37,3 +51,19 @@ const updatePPT = async (data) => {
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
}
}
}

View File

@ -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', {

View File

@ -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()

View File

@ -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,

View File

@ -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`