|
@@ -21,6 +21,7 @@ import {
|
|
|
} from '@/helpers/native-message';
|
|
|
import MusicScore from './component/musicScore';
|
|
|
import iconMenu from './image/icon-menu.svg';
|
|
|
+import iconChange from './image/icon-change.svg';
|
|
|
import iconDian from './image/icon-dian.svg';
|
|
|
import iconPoint from './image/icon-point.svg';
|
|
|
import iconUp from './image/icon-up.svg';
|
|
@@ -36,6 +37,8 @@ import {
|
|
|
api_lessonCoursewareKnowledgeDetailDetail
|
|
|
} from './api';
|
|
|
import VideoItem from './component/video-item';
|
|
|
+import Chapter from './component/chapter';
|
|
|
+import { api_lessonCoursewareDetail } from '../courseware-list/api';
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: 'CoursewarePlay',
|
|
@@ -100,15 +103,33 @@ export default defineComponent({
|
|
|
window.removeEventListener('message', iframeHandle);
|
|
|
});
|
|
|
|
|
|
+ const getCourseDetail = async () => {
|
|
|
+ try {
|
|
|
+ const res = await api_lessonCoursewareDetail(
|
|
|
+ route.query.lessonCoursewareId as any
|
|
|
+ );
|
|
|
+ if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
|
|
|
+ data.courseDetails = res.data.lessonList || [];
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
const route = useRoute();
|
|
|
const headeRef = ref();
|
|
|
+ const loadingClass = ref(false); // 重新加载课件
|
|
|
const data = reactive({
|
|
|
knowledgePointList: [] as any,
|
|
|
+ courseDetails: [] as any,
|
|
|
itemList: [] as any,
|
|
|
videoRefs: {} as any[]
|
|
|
});
|
|
|
const activeData = reactive({
|
|
|
isAutoPlay: true, // 是否自动播放
|
|
|
+ lessonCoursewareId: route.query.lessonCoursewareId,
|
|
|
+ lessonCoursewareDetailId: route.query.lessonCoursewareDetailId,
|
|
|
+ coursewareDetailKnowledgeId: route.query.id,
|
|
|
nowTime: 0,
|
|
|
model: true, // 遮罩
|
|
|
isAnimation: true, // 是否动画
|
|
@@ -122,7 +143,7 @@ export default defineComponent({
|
|
|
let courseList: any[] = [];
|
|
|
if (route.query.tab == 'course') {
|
|
|
const res = await api_classLessonCoursewareQuery({
|
|
|
- coursewareDetailKnowledgeId: route.query.id,
|
|
|
+ coursewareDetailKnowledgeId: activeData.coursewareDetailKnowledgeId,
|
|
|
page: 1,
|
|
|
rows: -1
|
|
|
});
|
|
@@ -143,7 +164,8 @@ export default defineComponent({
|
|
|
}
|
|
|
} else {
|
|
|
const res = await api_lessonCoursewareKnowledgeDetailDetail({
|
|
|
- lessonCoursewareKnowledgeDetailId: route.query.id
|
|
|
+ lessonCoursewareKnowledgeDetailId:
|
|
|
+ activeData.coursewareDetailKnowledgeId
|
|
|
});
|
|
|
if (res?.code === 200 && Array.isArray(res.data)) {
|
|
|
courseList = res.data || [];
|
|
@@ -184,9 +206,9 @@ export default defineComponent({
|
|
|
activeData.model =
|
|
|
ev.data.show || (ev.data.playState == 'play' ? false : true);
|
|
|
}
|
|
|
- if (ev.data?.api === 'api_fingerPreView'){
|
|
|
- clearInterval(activeData.timer)
|
|
|
- activeData.model = !ev.data.state
|
|
|
+ if (ev.data?.api === 'api_fingerPreView') {
|
|
|
+ clearInterval(activeData.timer);
|
|
|
+ activeData.model = !ev.data.state;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -199,6 +221,7 @@ export default defineComponent({
|
|
|
}
|
|
|
});
|
|
|
getDetail();
|
|
|
+ getCourseDetail();
|
|
|
window.addEventListener('message', iframeHandle);
|
|
|
});
|
|
|
|
|
@@ -214,9 +237,11 @@ export default defineComponent({
|
|
|
|
|
|
const popupData = reactive({
|
|
|
open: false,
|
|
|
+
|
|
|
activeIndex: 0,
|
|
|
itemActive: '',
|
|
|
- itemName: ''
|
|
|
+ itemName: '',
|
|
|
+ chapterOpen: false
|
|
|
});
|
|
|
|
|
|
// 切换素材
|
|
@@ -337,176 +362,185 @@ export default defineComponent({
|
|
|
};
|
|
|
return () => (
|
|
|
<div id="playContent" class={styles.playContent}>
|
|
|
- <div>
|
|
|
- <div
|
|
|
- class={styles.coursewarePlay}
|
|
|
- style={{ width: parentContainer.width }}
|
|
|
- onClick={() => setModelOpen()}>
|
|
|
- <div class={styles.wraps}>
|
|
|
- {data.itemList.map((m: any, mIndex: number) => {
|
|
|
- const isRender =
|
|
|
- m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
|
|
|
- const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
|
|
|
- if (isRender) {
|
|
|
- m.isRender = true;
|
|
|
- }
|
|
|
- return isRender ? (
|
|
|
+ {!loadingClass.value && (
|
|
|
+ <div>
|
|
|
+ <div
|
|
|
+ class={styles.coursewarePlay}
|
|
|
+ style={{ width: parentContainer.width }}
|
|
|
+ onClick={() => setModelOpen()}>
|
|
|
+ <div class={styles.wraps}>
|
|
|
+ {data.itemList.map((m: any, mIndex: number) => {
|
|
|
+ const isRender =
|
|
|
+ m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
|
|
|
+ const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
|
|
|
+ if (isRender) {
|
|
|
+ m.isRender = true;
|
|
|
+ }
|
|
|
+ return isRender ? (
|
|
|
+ <div
|
|
|
+ key={'index' + mIndex}
|
|
|
+ class={[
|
|
|
+ styles.itemDiv,
|
|
|
+ popupData.activeIndex === mIndex && styles.itemActive,
|
|
|
+ activeData.isAnimation && styles.acitveAnimation,
|
|
|
+ Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
+ ? styles.show
|
|
|
+ : styles.hide
|
|
|
+ ]}
|
|
|
+ style={
|
|
|
+ mIndex < popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].prev
|
|
|
+ : mIndex > popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].next
|
|
|
+ : {}
|
|
|
+ }
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ if (Date.now() - activeData.nowTime < 300) {
|
|
|
+ handleDbClick(m);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ activeData.nowTime = Date.now();
|
|
|
+ }}>
|
|
|
+ {m.type === 'IMG' && <img src={m.content} />}
|
|
|
+ {m.type === 'VIDEO' && (
|
|
|
+ <VideoItem
|
|
|
+ ref={(v: any) => (data.videoRefs[mIndex] = v)}
|
|
|
+ item={m}
|
|
|
+ show={popupData.activeIndex === mIndex}
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
+ showModel={activeData.model}
|
|
|
+ isEmtry={isEmtry}
|
|
|
+ onLoadedmetadata={() => {
|
|
|
+ m.isprepare = true;
|
|
|
+ m.error = false;
|
|
|
+ }}
|
|
|
+ onEnded={() => {
|
|
|
+ const _index = popupData.activeIndex + 1;
|
|
|
+ if (_index < data.itemList.length) {
|
|
|
+ handleSwipeChange(_index);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ onReset={() => {
|
|
|
+ m.error = false;
|
|
|
+ }}
|
|
|
+ onError={() => {
|
|
|
+ m.isprepare = true;
|
|
|
+ m.error = true;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {m.type === 'SONG' && (
|
|
|
+ <AudioItem
|
|
|
+ item={m}
|
|
|
+ show={popupData.activeIndex === mIndex}
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
+ showModel={activeData.model}
|
|
|
+ isEmtry={isEmtry}
|
|
|
+ onEnded={() => {
|
|
|
+ const _index = popupData.activeIndex + 1;
|
|
|
+ if (_index < data.itemList.length) {
|
|
|
+ handleSwipeChange(_index);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ onClose={() => {
|
|
|
+ clearTimeout(activeData.timer);
|
|
|
+ activeData.timer = setTimeout(() => {
|
|
|
+ activeData.model = false;
|
|
|
+ }, 4000);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {m.type === 'MUSIC' && (
|
|
|
+ <MusicScore
|
|
|
+ pageVisibility={pageVisibility.value}
|
|
|
+ show={popupData.activeIndex === mIndex}
|
|
|
+ activeModel={activeData.model}
|
|
|
+ data-vid={m.id}
|
|
|
+ music={m}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+
|
|
|
+ {m.type === 'VIDEO' && (
|
|
|
+ <Transition name="van-fade">
|
|
|
+ {!m.isprepare && (
|
|
|
+ <div class={styles.loadWrap}>
|
|
|
+ <Vue3Lottie
|
|
|
+ style={{ width: '100%', height: '100%' }}
|
|
|
+ animationData={playLoadData}></Vue3Lottie>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div
|
|
|
+ key={'index' + mIndex}
|
|
|
+ class={[
|
|
|
+ styles.itemDiv,
|
|
|
+ popupData.activeIndex === mIndex && styles.itemActive,
|
|
|
+ activeData.isAnimation && styles.acitveAnimation,
|
|
|
+ Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
+ ? styles.show
|
|
|
+ : styles.hide
|
|
|
+ ]}
|
|
|
+ style={
|
|
|
+ mIndex < popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].prev
|
|
|
+ : mIndex > popupData.activeIndex
|
|
|
+ ? effects[effectIndex.value].next
|
|
|
+ : {}
|
|
|
+ }></div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ <Transition name="right">
|
|
|
+ {activeData.model && (
|
|
|
<div
|
|
|
- key={'index' + mIndex}
|
|
|
- class={[
|
|
|
- styles.itemDiv,
|
|
|
- popupData.activeIndex === mIndex && styles.itemActive,
|
|
|
- activeData.isAnimation && styles.acitveAnimation,
|
|
|
- Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
- ? styles.show
|
|
|
- : styles.hide
|
|
|
- ]}
|
|
|
- style={
|
|
|
- mIndex < popupData.activeIndex
|
|
|
- ? effects[effectIndex.value].prev
|
|
|
- : mIndex > popupData.activeIndex
|
|
|
- ? effects[effectIndex.value].next
|
|
|
- : {}
|
|
|
- }
|
|
|
+ class={styles.rightFixedBtns}
|
|
|
onClick={(e: Event) => {
|
|
|
- if (Date.now() - activeData.nowTime < 300) {
|
|
|
- handleDbClick(m);
|
|
|
- return;
|
|
|
- }
|
|
|
- activeData.nowTime = Date.now();
|
|
|
+ e.stopPropagation();
|
|
|
+ clearTimeout(activeData.timer);
|
|
|
}}>
|
|
|
- {m.type === 'IMG' && <img src={m.content} />}
|
|
|
- {m.type === 'VIDEO' && (
|
|
|
- <VideoItem
|
|
|
- ref={(v: any) => (data.videoRefs[mIndex] = v)}
|
|
|
- item={m}
|
|
|
- show={popupData.activeIndex === mIndex}
|
|
|
- pageVisibility={pageVisibility.value}
|
|
|
- showModel={activeData.model}
|
|
|
- isEmtry={isEmtry}
|
|
|
- onLoadedmetadata={() => {
|
|
|
- m.isprepare = true;
|
|
|
- m.error = false;
|
|
|
- }}
|
|
|
- onEnded={() => {
|
|
|
- const _index = popupData.activeIndex + 1;
|
|
|
- if (_index < data.itemList.length) {
|
|
|
- handleSwipeChange(_index);
|
|
|
- }
|
|
|
- }}
|
|
|
- onReset={() => {
|
|
|
- m.error = false;
|
|
|
- }}
|
|
|
- onError={() => {
|
|
|
- m.isprepare = true;
|
|
|
- m.error = true;
|
|
|
- }}
|
|
|
- />
|
|
|
- )}
|
|
|
- {m.type === 'SONG' && (
|
|
|
- <AudioItem
|
|
|
- item={m}
|
|
|
- show={popupData.activeIndex === mIndex}
|
|
|
- pageVisibility={pageVisibility.value}
|
|
|
- showModel={activeData.model}
|
|
|
- isEmtry={isEmtry}
|
|
|
- onEnded={() => {
|
|
|
- const _index = popupData.activeIndex + 1;
|
|
|
- if (_index < data.itemList.length) {
|
|
|
- handleSwipeChange(_index);
|
|
|
- }
|
|
|
- }}
|
|
|
- onClose={() => {
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- activeData.timer = setTimeout(() => {
|
|
|
- activeData.model = false;
|
|
|
- }, 4000);
|
|
|
- }}
|
|
|
- />
|
|
|
- )}
|
|
|
- {m.type === 'MUSIC' && (
|
|
|
- <MusicScore
|
|
|
- pageVisibility={pageVisibility.value}
|
|
|
- show={popupData.activeIndex === mIndex}
|
|
|
- activeModel={activeData.model}
|
|
|
- data-vid={m.id}
|
|
|
- music={m}
|
|
|
- />
|
|
|
- )}
|
|
|
+ <div
|
|
|
+ class={[styles.fullBtn, styles.point]}
|
|
|
+ onClick={() => (popupData.chapterOpen = true)}>
|
|
|
+ <img src={iconChange} />
|
|
|
+ <span>切换</span>
|
|
|
+ </div>
|
|
|
|
|
|
- {m.type === 'VIDEO' && (
|
|
|
- <Transition name="van-fade">
|
|
|
- {!m.isprepare && (
|
|
|
- <div class={styles.loadWrap}>
|
|
|
- <Vue3Lottie
|
|
|
- style={{ width: '100%', height: '100%' }}
|
|
|
- animationData={playLoadData}></Vue3Lottie>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </Transition>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <div
|
|
|
- key={'index' + mIndex}
|
|
|
- class={[
|
|
|
- styles.itemDiv,
|
|
|
- popupData.activeIndex === mIndex && styles.itemActive,
|
|
|
- activeData.isAnimation && styles.acitveAnimation,
|
|
|
- Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
- ? styles.show
|
|
|
- : styles.hide
|
|
|
- ]}
|
|
|
- style={
|
|
|
- mIndex < popupData.activeIndex
|
|
|
- ? effects[effectIndex.value].prev
|
|
|
- : mIndex > popupData.activeIndex
|
|
|
- ? effects[effectIndex.value].next
|
|
|
- : {}
|
|
|
- }></div>
|
|
|
- );
|
|
|
- })}
|
|
|
- </div>
|
|
|
- <Transition name="right">
|
|
|
- {activeData.model && (
|
|
|
- <div
|
|
|
- class={styles.rightFixedBtns}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation();
|
|
|
- clearTimeout(activeData.timer);
|
|
|
- }}>
|
|
|
- <div
|
|
|
- class={[styles.fullBtn, styles.point]}
|
|
|
- onClick={() => (popupData.open = true)}>
|
|
|
- <img src={iconMenu} />
|
|
|
- <span>课件</span>
|
|
|
- </div>
|
|
|
+ <div
|
|
|
+ class={[styles.fullBtn, styles.point]}
|
|
|
+ onClick={() => (popupData.open = true)}>
|
|
|
+ <img src={iconMenu} />
|
|
|
+ <span>课件</span>
|
|
|
+ </div>
|
|
|
|
|
|
- <div
|
|
|
- class={[
|
|
|
- styles.fullBtn,
|
|
|
- popupData.activeIndex == 0 && styles.btnsDisabled
|
|
|
- ]}
|
|
|
- onClick={() => handlePreAndNext('up')}>
|
|
|
- <img src={iconUp} />
|
|
|
- <span style={{ textAlign: 'center' }}>上一个</span>
|
|
|
- </div>
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.fullBtn,
|
|
|
+ popupData.activeIndex == 0 && styles.btnsDisabled
|
|
|
+ ]}
|
|
|
+ onClick={() => handlePreAndNext('up')}>
|
|
|
+ <img src={iconUp} />
|
|
|
+ <span style={{ textAlign: 'center' }}>上一个</span>
|
|
|
+ </div>
|
|
|
|
|
|
- <div
|
|
|
- class={[
|
|
|
- styles.fullBtn,
|
|
|
- popupData.activeIndex == data.itemList.length - 1 &&
|
|
|
- styles.btnsDisabled
|
|
|
- ]}
|
|
|
- onClick={() => handlePreAndNext('down')}>
|
|
|
- <span style={{ textAlign: 'center' }}>下一个</span>
|
|
|
- <img src={iconDown} />
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.fullBtn,
|
|
|
+ popupData.activeIndex == data.itemList.length - 1 &&
|
|
|
+ styles.btnsDisabled
|
|
|
+ ]}
|
|
|
+ onClick={() => handlePreAndNext('down')}>
|
|
|
+ <span style={{ textAlign: 'center' }}>下一个</span>
|
|
|
+ <img src={iconDown} />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </Transition>
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ )}
|
|
|
|
|
|
<div
|
|
|
style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
|
|
@@ -519,6 +553,7 @@ export default defineComponent({
|
|
|
<div class={styles.menu}>{popupData.itemName}</div>
|
|
|
</div>
|
|
|
|
|
|
+ {/* 课件列表 */}
|
|
|
<Popup
|
|
|
class={styles.popup}
|
|
|
style={{ background: 'rgba(0,0,0, 0.75)' }}
|
|
@@ -536,6 +571,34 @@ export default defineComponent({
|
|
|
}}
|
|
|
/>
|
|
|
</Popup>
|
|
|
+
|
|
|
+ {/* 知识点列表 */}
|
|
|
+ <Popup
|
|
|
+ class={styles.popup}
|
|
|
+ style={{ background: 'rgba(0,0,0, 0.75)' }}
|
|
|
+ overlayClass={styles.overlayClass}
|
|
|
+ position="right"
|
|
|
+ round
|
|
|
+ v-model:show={popupData.chapterOpen}
|
|
|
+ onClose={handleClosePopup}>
|
|
|
+ <Chapter
|
|
|
+ detail={data.courseDetails}
|
|
|
+ itemActive={activeData.coursewareDetailKnowledgeId as any}
|
|
|
+ active={activeData.lessonCoursewareDetailId as any}
|
|
|
+ onHandleSelect={async (item: any) => {
|
|
|
+ console.log(item, 'item');
|
|
|
+ loadingClass.value = true;
|
|
|
+ activeData.coursewareDetailKnowledgeId = item.itemActive;
|
|
|
+ activeData.lessonCoursewareDetailId = item.tabActive;
|
|
|
+ await getDetail();
|
|
|
+ popupData.activeIndex = 0;
|
|
|
+ popupData.itemActive = item.itemActive;
|
|
|
+ popupData.itemName = item.itemName;
|
|
|
+ popupData.chapterOpen = false;
|
|
|
+ loadingClass.value = false;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Popup>
|
|
|
</div>
|
|
|
);
|
|
|
}
|