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/store/slides.ts b/src/renderer/src/AixPPTist/src/store/slides.ts index c86c7c7..d7a3bae 100644 --- a/src/renderer/src/AixPPTist/src/store/slides.ts +++ b/src/renderer/src/AixPPTist/src/store/slides.ts @@ -151,9 +151,9 @@ export const useSlidesStore = defineStore('slides', { 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 + const addIndex = this.slideIndex + 1 + this.slides.splice(addIndex, 0, ...slides) + this.slideIndex = addIndex }, updateSlide(props: Partial, slideId?: string) { const slideIndex = slideId ? this.slides.findIndex(item => item.id === slideId) : this.slideIndex 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 1294986..de3a244 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 @@ -45,9 +45,9 @@ - - -
+ + +
@@ -335,9 +335,10 @@ onMounted(() => { objItem.value = workItem.value[slideIndex.value] getCurrentPPtData() }) -watch(() => [workItem.value.length,slideIndex.value], (newVal,oldVal) => { +watch(() => [workItem.value.length,workItem.value[slideIndex.value]?.id], (newVal,oldVal) => { if(!objectsAreEqual(newVal,oldVal)) - getCurrentPPtData() + if(workItem.value[slideIndex.value]) + getCurrentPPtData() }) // watch(() => workItem.value.length, () => { // getCurrentPPtData() 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/components/template-study/container/keyword-dialog.vue b/src/renderer/src/components/template-study/container/keyword-dialog.vue index 4eb1cd2..bdd6c29 100644 --- a/src/renderer/src/components/template-study/container/keyword-dialog.vue +++ b/src/renderer/src/components/template-study/container/keyword-dialog.vue @@ -40,7 +40,7 @@ const props = defineProps({ type: Number, default: 1 }, - item: { // 子模板 + item: { // 当前操作的模板 type: Object, default: () => { return { ex3: '' } @@ -73,23 +73,25 @@ const loading = ref(false) const saveAdd = async () => { loading.value = true if (props.item.ex3 == '1') { - + let id; // id 为主模板id if (props.item.isAdd) { - try { - // 系统预设模板 copy一份 - const { msg } = await addKeyWords({ name: form.name, id: props.item.id }) - emitter.emit('onGetMain') - ElMessage.success(msg) - mode.value = false - } finally { - loading.value = false - } + id = props.item.id } else{ - onAddChildTemp(props.item.parentId) + // 编辑状态下 item 为子模板 主模板则是item.parentId + id = props.item.parentId } + try { + // 系统预设模板 copy一份 + const { msg } = await addKeyWords({ name: form.name, id }) + emitter.emit('onGetMain') + ElMessage.success(msg) + mode.value = false + } finally { + loading.value = false + } + } else { - if (props.item.isAdd) { onAddChildTemp(props.item.id) } diff --git a/src/renderer/src/components/template-study/container/left.vue b/src/renderer/src/components/template-study/container/left.vue index 02db0d4..d2b9285 100644 --- a/src/renderer/src/components/template-study/container/left.vue +++ b/src/renderer/src/components/template-study/container/left.vue @@ -16,12 +16,12 @@ \ No newline at end of file diff --git a/src/renderer/src/views/teachingDesign/container/left.vue b/src/renderer/src/views/teachingDesign/container/left.vue index ab6f38b..7df70fa 100644 --- a/src/renderer/src/views/teachingDesign/container/left.vue +++ b/src/renderer/src/views/teachingDesign/container/left.vue @@ -2,6 +2,7 @@
教学模式
+
{{ item.name }} @@ -29,27 +30,33 @@ + \ No newline at end of file