|
@@ -6,7 +6,8 @@ import {
|
|
|
ref,
|
|
|
Transition,
|
|
|
computed,
|
|
|
- nextTick
|
|
|
+ nextTick,
|
|
|
+ watch
|
|
|
} from 'vue';
|
|
|
import styles from './index.module.less';
|
|
|
import 'plyr/dist/plyr.css';
|
|
@@ -73,6 +74,20 @@ import iconUp from './new-image/icon-up.png';
|
|
|
import iconWhite from './new-image/icon-white.png';
|
|
|
import iconWork from './new-image/icon-work.png';
|
|
|
|
|
|
+import rightIconEnd from './image/right_icon1.png';
|
|
|
+import rightIconArrange from './image/right_icon2.png';
|
|
|
+import rightIconPostil from './image/right_icon3.png';
|
|
|
+import rightIconWhiteboard from './image/right_icon4.png';
|
|
|
+import rightIconMetronome from './image/right_icon5.png';
|
|
|
+import rightIconTuner from './image/right_icon6.png';
|
|
|
+import rightIconTimer from './image/right_icon7.png';
|
|
|
+import rightIconPackUp from './image/right_icon8.png';
|
|
|
+import bottomIconSwitch from './image/bottom_icon1.png';
|
|
|
+import bottomIconResource from './image/bottom_icon2.png';
|
|
|
+import bottomIconPre from './image/bottom_icon3.png';
|
|
|
+import bottomIconNext from './image/bottom_icon4.png';
|
|
|
+import rightHideIcon from './image/right_hide_icon.png';
|
|
|
+
|
|
|
export type ToolType = 'init' | 'pen' | 'whiteboard';
|
|
|
export type ToolItem = {
|
|
|
type: ToolType;
|
|
@@ -186,6 +201,10 @@ export default defineComponent({
|
|
|
timer: null as any,
|
|
|
item: null as any
|
|
|
});
|
|
|
+
|
|
|
+ // 键盘事件监听状态
|
|
|
+ const listenerKeyUpState = ref(false);
|
|
|
+
|
|
|
const getDetail = async () => {
|
|
|
try {
|
|
|
const res = await queryCourseware({
|
|
@@ -279,7 +298,6 @@ export default defineComponent({
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
|
- // debugger
|
|
|
// initMoveable();
|
|
|
const query = route.query;
|
|
|
console.log(query, props.preStudentNum, '学生人数');
|
|
@@ -291,10 +309,12 @@ export default defineComponent({
|
|
|
data.classGroupId = props.classGroupId || query.classGroupId;
|
|
|
data.classId = props.classId || query.classId;
|
|
|
data.preStudentNum = props.preStudentNum || query.preStudentNum;
|
|
|
-
|
|
|
window.addEventListener('message', iframeHandle);
|
|
|
getDetail();
|
|
|
getLessonCoursewareDetail();
|
|
|
+ if (data.type === 'preview') {
|
|
|
+ rightList.splice(1,1)
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
const onFullScreen = () => {
|
|
@@ -824,8 +844,6 @@ export default defineComponent({
|
|
|
setModelOpen();
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
- // 监听页面键盘事件 - 上下切换
|
|
|
document.body.addEventListener('keyup', (e: KeyboardEvent) => {
|
|
|
// console.log(e, 'e');
|
|
|
if (e.code === 'ArrowLeft') {
|
|
@@ -839,6 +857,39 @@ export default defineComponent({
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ const toggleListenerKeyUp = (type: string) => {
|
|
|
+ if (type === 'remove') {
|
|
|
+ document.body.removeEventListener('keyup', () => {
|
|
|
+ listenerKeyUpState.value = false
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ // 监听页面键盘事件 - 上下切换
|
|
|
+ document.body.addEventListener('keyup', (e: KeyboardEvent) => {
|
|
|
+ // console.log(e, 'e');
|
|
|
+ if (e.code === 'ArrowLeft') {
|
|
|
+ // if (popupData.activeIndex === 0) return;
|
|
|
+ setModalOpen();
|
|
|
+ handlePreAndNext('up');
|
|
|
+ } else if (e.code === 'ArrowRight') {
|
|
|
+ // if (popupData.activeIndex === data.itemList.length - 1) return;
|
|
|
+ setModalOpen();
|
|
|
+ handlePreAndNext('down');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ listenerKeyUpState.value = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听切换到ppt课件时,手动移除键盘监听器
|
|
|
+ // watch(() => popupData.activeIndex, () => {
|
|
|
+ // const activeItem = data.itemList[popupData.activeIndex];
|
|
|
+ // if (activeItem?.type === 'PPT') {
|
|
|
+ // toggleListenerKeyUp('remove')
|
|
|
+ // } else {
|
|
|
+ // !listenerKeyUpState.value && toggleListenerKeyUp('add')
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
const setModalOpen = (status = true) => {
|
|
|
clearTimeout(activeData.timer);
|
|
|
activeData.model = status;
|
|
@@ -1053,6 +1104,161 @@ export default defineComponent({
|
|
|
}
|
|
|
return {}
|
|
|
})
|
|
|
+
|
|
|
+ // 右侧菜单栏
|
|
|
+ const rightList = reactive([
|
|
|
+ {
|
|
|
+ name: '结束课程',
|
|
|
+ name2: '结束预览',
|
|
|
+ icon: rightIconEnd,
|
|
|
+ id: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '布置作业',
|
|
|
+ icon: rightIconArrange,
|
|
|
+ id: 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '批注',
|
|
|
+ icon: rightIconPostil,
|
|
|
+ id: 3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '白板',
|
|
|
+ icon: rightIconWhiteboard,
|
|
|
+ id: 4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '节拍器',
|
|
|
+ icon: rightIconMetronome,
|
|
|
+ id: 5,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '调音器',
|
|
|
+ icon: rightIconTuner,
|
|
|
+ id: 6,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '计时器',
|
|
|
+ icon: rightIconTimer,
|
|
|
+ id: 7,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '收起',
|
|
|
+ icon: rightIconPackUp,
|
|
|
+ id: 8,
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 底部菜单栏
|
|
|
+ const bottomList = reactive([
|
|
|
+ {
|
|
|
+ name: '切换章节',
|
|
|
+ icon: bottomIconSwitch,
|
|
|
+ id: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '资源列表',
|
|
|
+ icon: bottomIconResource,
|
|
|
+ id: 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '上一张',
|
|
|
+ icon: bottomIconPre,
|
|
|
+ id: 3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '下一张',
|
|
|
+ icon: bottomIconNext,
|
|
|
+ id: 4,
|
|
|
+ }
|
|
|
+ ]);
|
|
|
+ const rightColumnShow = ref(true);
|
|
|
+
|
|
|
+
|
|
|
+ // 右边栏操作
|
|
|
+ const operateRightBtn = async (id: number) => {
|
|
|
+ switch (id) {
|
|
|
+ case 1:
|
|
|
+ if (data.type === 'preview') {
|
|
|
+ handleStop();
|
|
|
+ data.removeVisiable = true;
|
|
|
+ data.removeTitle = '结束预览';
|
|
|
+ data.removeContent = '请确认是否结束预览?';
|
|
|
+ } else {
|
|
|
+ data.removeVisiable = true;
|
|
|
+ data.removeTitle = '结束课程';
|
|
|
+ data.removeContent = '请确认是否结束课程?';
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ // 学生人数必须大于0,才可以布置作业
|
|
|
+ if (data.preStudentNum <= 0) return;
|
|
|
+ const res = await lessonPreTrainingPage({
|
|
|
+ coursewareKnowledgeDetailId: data.detailId,
|
|
|
+ subjectId: data.subjectId,
|
|
|
+ page: 1,
|
|
|
+ rows: 99
|
|
|
+ });
|
|
|
+ if (res.data.rows && res.data.rows.length) {
|
|
|
+ data.modalAttendMessage =
|
|
|
+ '本节课已设置课后作业,是否布置?';
|
|
|
+ }
|
|
|
+ data.modelAttendStatus = true;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ openStudyTool({
|
|
|
+ type: 'pen',
|
|
|
+ icon: iconNote,
|
|
|
+ name: '批注'
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ openStudyTool({
|
|
|
+ type: 'whiteboard',
|
|
|
+ icon: iconWhite,
|
|
|
+ name: '白板'
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ startShowModal('beatIcon')
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ startShowModal('toneIcon')
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ startShowModal('setTimeIcon')
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ rightColumnShow.value = false
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 底部悬浮按钮操作
|
|
|
+ const operateBottomBtn = (id: number) => {
|
|
|
+ switch (id) {
|
|
|
+ case 1:
|
|
|
+ popupData.chapterOpen = true
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ popupData.open = true
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ if (!isUpArrow.value) return;
|
|
|
+ handlePreAndNext('up');
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ if (!isDownArrow.value) return;
|
|
|
+ handlePreAndNext('down');
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return () => (
|
|
|
<div id="playContent" class={[styles.playContent, 'wrap']}>
|
|
|
<div
|
|
@@ -1225,10 +1431,11 @@ export default defineComponent({
|
|
|
}}
|
|
|
/>
|
|
|
)
|
|
|
- : m.type === 'PPT' ? <div class={styles.iframePpt}>
|
|
|
- <div class={styles.pptBox}></div>
|
|
|
- <iframe src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(m.content)}`} width='100%' height='100%' frameborder='1'></iframe>
|
|
|
- </div>
|
|
|
+ // : m.type === 'PPT' ? <div class={styles.iframePpt}>
|
|
|
+ // <div class={styles.pptBox}></div>
|
|
|
+ // <iframe src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(m.content)}`} width='100%' height='100%' frameborder='1'></iframe>
|
|
|
+ // </div>
|
|
|
+ : m.type === 'PPT' ? <iframe src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(m.content)}`} width='100%' height='100%' frameborder='1'></iframe>
|
|
|
: (
|
|
|
<MusicScore
|
|
|
activeModel={activeData.model}
|
|
@@ -1251,14 +1458,14 @@ export default defineComponent({
|
|
|
</div>
|
|
|
|
|
|
{/* 头部样式 */}
|
|
|
- <div
|
|
|
+ {/* <div
|
|
|
style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
|
|
|
class={styles.headerContainer}>
|
|
|
<div class={styles.menu}>{activeName.value}</div>
|
|
|
- </div>
|
|
|
+ </div> */}
|
|
|
{/* 布置作业按钮 */}
|
|
|
|
|
|
- <div
|
|
|
+ {/* <div
|
|
|
onClick={(e: any) => {
|
|
|
e.stopPropagation();
|
|
|
if (activeData.timer){
|
|
@@ -1392,6 +1599,41 @@ export default defineComponent({
|
|
|
<p>下一个</p>
|
|
|
</div>
|
|
|
</NSpace>
|
|
|
+ </div> */}
|
|
|
+
|
|
|
+ {/* 右边操作栏 */}
|
|
|
+ <div class={[styles.rightColumn, !rightColumnShow.value ? styles.rightColumnHide : '']}>
|
|
|
+ {rightList.map((item: any, index: number) => (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.rightItem,
|
|
|
+ (item.id === 2 && data.preStudentNum <= 0) ? styles.itemDisabled : ''
|
|
|
+ ]}
|
|
|
+ onClick={() => operateRightBtn(item.id)}>
|
|
|
+ <img src={item.icon} />
|
|
|
+ <div class={styles.rightTips}>{index === 0 && data.type === 'preview' ? item.name2 : item.name}</div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ {
|
|
|
+ !rightColumnShow.value && <img
|
|
|
+ class={[styles.rightHideIcon, !rightColumnShow.value ? styles.rightIconShow : '']}
|
|
|
+ src={rightHideIcon}
|
|
|
+ onClick={() => rightColumnShow.value = true } />
|
|
|
+ }
|
|
|
+ {/* 右下角悬浮按钮 */}
|
|
|
+ <div class={styles.bottomColumn}>
|
|
|
+ {bottomList.map((item: any, index: number) => (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.bottomItem,
|
|
|
+ ((item.id === 3 && !isUpArrow.value) || (item.id === 4 && !isDownArrow.value)) ? styles.itemDisabled : ''
|
|
|
+ ]}
|
|
|
+ onClick={() => operateBottomBtn(item.id)}>
|
|
|
+ <img src={item.icon} />
|
|
|
+ <div class={styles.bottomTips}>{item.name}</div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
</div>
|
|
|
|
|
|
{/* 显示列表 */}
|