zdg_dev #108
|
@ -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'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
// 打开全屏
|
||||
|
|
|
@ -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
|
|
@ -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, // 开课时间
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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', {
|
||||
|
|
|
@ -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()
|
|
@ -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,
|
||||
|
|
|
@ -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`
|
||||
|
|
Loading…
Reference in New Issue