From 9ad959dfb73e656de7afd12e585cb8b7043b55f0 Mon Sep 17 00:00:00 2001 From: zdg Date: Mon, 16 Dec 2024 10:15:08 +0800 Subject: [PATCH] =?UTF-8?q?ppt=E4=B8=8A=E8=AF=BE=20=E6=8B=96=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8E=92=E5=BA=8F=20=E5=8A=A8=E7=94=BB?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron.vite.config.mjs | 1 + src/renderer/src/AixPPTist/src/App.vue | 2 +- .../src/AixPPTist/src/api/classcourse.ts | 4 +- src/renderer/src/AixPPTist/src/api/index.ts | 38 ++++++++++++++----- src/renderer/src/AixPPTist/src/api/watcher.ts | 4 +- .../AixPPTist/src/views/Screen/BaseView.vue | 32 +++++++++++++++- .../src/views/Screen/hooks/useExecPlay.ts | 21 +++++----- .../src/views/classTask/teachClassTask.vue | 4 +- 8 files changed, 80 insertions(+), 26 deletions(-) diff --git a/electron.vite.config.mjs b/electron.vite.config.mjs index 962bf8f..fb25549 100644 --- a/electron.vite.config.mjs +++ b/electron.vite.config.mjs @@ -33,6 +33,7 @@ export default defineConfig({ proxy: { '/dev-api': { target: 'http://27.128.240.72:7865', + // target: 'https://prev.ysaix.com:7868/prod-api/', // target: 'http://36.134.181.164:7863', // target: 'http://192.168.0.102:7865', changeOrigin: true, diff --git a/src/renderer/src/AixPPTist/src/App.vue b/src/renderer/src/AixPPTist/src/App.vue index c06919f..7fe9cd8 100644 --- a/src/renderer/src/AixPPTist/src/App.vue +++ b/src/renderer/src/AixPPTist/src/App.vue @@ -28,8 +28,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 watcher from './api/watcher' // 监听 +import emitter from '@/utils/mitt' //mitt 事件总线 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 f15b0af..e513f3c 100644 --- a/src/renderer/src/AixPPTist/src/api/classcourse.ts +++ b/src/renderer/src/AixPPTist/src/api/classcourse.ts @@ -7,7 +7,6 @@ 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() // 幻灯片-状态管理 @@ -31,10 +30,9 @@ export class Classcourse { console.log('classcourse-load', classcourse) // 打开全屏 const isCourse = !!classcourse - if (isCourse) Fullscreen.enterFullscreen() screenStore.setScreening(isCourse) // 如果课堂信息有值,则连接socket - if (!!classcourse) { + if (isCourse) { // 连接socket if (!ChatWs.ws) ChatWs.init() ChatWs.id = classcourse.timgroupid // 群组id diff --git a/src/renderer/src/AixPPTist/src/api/index.ts b/src/renderer/src/AixPPTist/src/api/index.ts index ba0130e..6d4126a 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,7 +12,8 @@ import * as useStore from '../store' // pptist-状态管理 import { sessionStore } from '@/utils/store' // electron-store 状态管理 import useUserStore from '@/store/modules/user' // 外部-用户信息 import * as Api_server from '@/api/apiService' // 相关api -import * as commUtils from '@/utils/comm.js' +import * as commUtils from '@/utils/comm.js' // 工具 +import { toPng, toJpeg } from 'html-to-image' // 引入html-to-image库 const slidesStore = useStore.useSlidesStore() const userStore = useUserStore() @@ -133,6 +134,9 @@ export class PPTApi { const currentSlide = toRaw(slidesStore.currentSlide) const isAdd = !/^\d+$/.test(currentSlide.id) // 是否新增 + const currInd = toRaw(slidesStore.slideIndex) // 当前页索引-new + const oldInd = oldData.findIndex(o => o.id == currentSlide.id) // 当前页索引-old + const isBatch = oldVal && oldVal.length && currInd != oldInd // 是否批量更新-排序 if (isAdd) { // 新增的幻灯片(id 为非数字,说明是新增的幻灯片) const bool = await this.addSlide(currentSlide) bool && await this.batchUpdateSlides(newData, true) // 批量更新-排序 @@ -140,16 +144,22 @@ export class PPTApi { await PPTApi.getSlideList(resource.id) } else { // 防抖-更新 if (!this.isUpdate) return this.isUpdate = true // 下次更新数据 - const params = { - id: currentSlide.id, - datacontent: JSON.stringify(currentSlide), + if (isBatch) { // 批量更新-排序 + this.batchUpdateSlides(newData, true) + } else { // 更新当前页幻灯片 + const params = { + id: currentSlide.id, + datacontent: JSON.stringify(currentSlide), + } + Utils.mxThrottle(() => {this.updateSlide(params)}, 200, 2) } - Utils.mxThrottle(() => {this.updateSlide(params)}, 200, 2) } } // 更新幻灯片 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) @@ -192,7 +202,18 @@ 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 + }) + } // 图片|音频|视频 转换为在线地址 static toRousrceUrl =async (o:any) => { const formData = new FormData() @@ -203,8 +224,7 @@ export class PPTApi { url &&(o.src = url) return url } - -} + } } export class Homework{ diff --git a/src/renderer/src/AixPPTist/src/api/watcher.ts b/src/renderer/src/AixPPTist/src/api/watcher.ts index f555f3d..8189fb5 100644 --- a/src/renderer/src/AixPPTist/src/api/watcher.ts +++ b/src/renderer/src/AixPPTist/src/api/watcher.ts @@ -86,8 +86,8 @@ export default () => { 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() // 上一步 + if (type === 'Nextsteps') emitter.emit('useExecPlay', 'execNext') // 下一步 + else if (type === 'Previoustep') emitter.emit('useExecPlay', 'turnPrevSlide') // 上一步清空-动画 else slidesStore.updateSlideIndex(slideIndex) // 更新幻灯片下标 break case MsgEnum.HEADS.MSG_homework: // 作业|活动-布置 diff --git a/src/renderer/src/AixPPTist/src/views/Screen/BaseView.vue b/src/renderer/src/AixPPTist/src/views/Screen/BaseView.vue index d4cd388..ae2add1 100644 --- a/src/renderer/src/AixPPTist/src/views/Screen/BaseView.vue +++ b/src/renderer/src/AixPPTist/src/views/Screen/BaseView.vue @@ -100,7 +100,6 @@ const { execNext, animationIndex, } = useExecPlay() - const { slideWidth, slideHeight } = useSlideSize() const { exitScreening } = useScreening() const { fullscreenState, manualExitFullscreen } = useFullscreen() @@ -197,6 +196,37 @@ const contextmenus = (): ContextmenuItem[] => { emitter.on('upvoteTrigger', (type) => { upvoteRef.value?.trigger(type) }); +// zdg: 使用方法才生效 +const execPlay = { + autoPlayTimer, + autoPlay, + closeAutoPlay, + autoPlayInterval, + setAutoPlayInterval, + loopPlay, + setLoopPlay, + mousewheelListener, + touchStartListener, + touchEndListener, + turnPrevSlide, + turnNextSlide, + turnSlideToIndex, + turnSlideToId, + execPrev, + execNext, + animationIndex, +} +emitter.on('useExecPlay', (data: string|any) => { + if (!data) throw new Error('参数错误') + if (typeof data === 'string') { // 字符串 + if (execPlay[data]) execPlay[data]() + else throw new Error('方法不存在') + } else { // 对象 + const { method, ...params } = data || {} + if (execPlay[method]) execPlay[method](...params) + else throw new Error('方法不存在') + } +}) 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 8ec0233..4b0016c 100644 --- a/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts +++ b/src/renderer/src/AixPPTist/src/views/Screen/hooks/useExecPlay.ts @@ -174,9 +174,8 @@ export default () => { // 鼠标滚动翻页 const mousewheelListener = throttle(function(e: WheelEvent) { - e.preventDefault() // 阻止默认事件 - if (e.deltaY < 0) execPrev() - else if (e.deltaY > 0) execNext() + if (e.deltaY < 0) turning(e, 'prev') + else if (e.deltaY > 0) turning(e, 'next') }, 500, { leading: true, trailing: false }) // 触摸屏上下滑动翻页 @@ -197,24 +196,28 @@ export default () => { 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() + if (offsetY > 0) turning(e, 'prev') + else turning(e, 'next') } } - + // 向上翻页/向下翻页 + const turning = (e, type) => { + e.preventDefault() // 阻止默认事件 + if (type === 'prev') execPrev() + else if (type === 'next') execNext() + } // 快捷键翻页 const keydownListener = (e: KeyboardEvent) => { - e.preventDefault() // 阻止默认事件 const key = e.key.toUpperCase() - if (key === KEYS.UP || key === KEYS.LEFT || key === KEYS.PAGEUP) execPrev() + if (key === KEYS.UP || key === KEYS.LEFT || key === KEYS.PAGEUP) turning(e, 'prev') else if ( key === KEYS.DOWN || key === KEYS.RIGHT || key === KEYS.SPACE || key === KEYS.ENTER || key === KEYS.PAGEDOWN - ) execNext() + ) turning(e, 'next') } onMounted(() => document.addEventListener('keydown', keydownListener)) diff --git a/src/renderer/src/views/classTask/teachClassTask.vue b/src/renderer/src/views/classTask/teachClassTask.vue index 8d0db52..3db91ae 100644 --- a/src/renderer/src/views/classTask/teachClassTask.vue +++ b/src/renderer/src/views/classTask/teachClassTask.vue @@ -4,7 +4,7 @@
{{ classWorkAnalysis.title }}完成情况 - {{ + {{ classWorkAnalysis.worktype }}
@@ -726,6 +726,7 @@ const msgHandle = (msg) => { openDialog(data, false); break case MsgEnum.HEADS.MSG_slideFlapping: // 切换页面 + console.log('切换页面-关闭窗口') window.close() // 关闭窗口 break // case 'TIMAddRecvNewMsgCallback': // 收到新消息 data=[] @@ -765,6 +766,7 @@ onMounted(() => { // im监听消息 if (ChatWs.ws) { + console.log('socket监听消息') ChatWs.watch((msg, e) => { try { msgHandle(JSON.parse(msg))