|
@@ -9,7 +9,8 @@ import {
|
|
watch,
|
|
watch,
|
|
Transition,
|
|
Transition,
|
|
computed,
|
|
computed,
|
|
- onBeforeUnmount
|
|
|
|
|
|
+ onBeforeUnmount,
|
|
|
|
+ shallowRef
|
|
} from 'vue'
|
|
} from 'vue'
|
|
import iconBack from './image/back.svg'
|
|
import iconBack from './image/back.svg'
|
|
import styles from './index.module.less'
|
|
import styles from './index.module.less'
|
|
@@ -32,6 +33,7 @@ import {
|
|
// iconPen,
|
|
// iconPen,
|
|
iconTouping,
|
|
iconTouping,
|
|
iconCourseType,
|
|
iconCourseType,
|
|
|
|
+ iconSearch,
|
|
iconMenu
|
|
iconMenu
|
|
} from './image/icons.json'
|
|
} from './image/icons.json'
|
|
import Points from './component/points'
|
|
import Points from './component/points'
|
|
@@ -52,6 +54,7 @@ import CoursewareTips from './component/courseware-tips'
|
|
import GlobalTools from '@/components/globalTools'
|
|
import GlobalTools from '@/components/globalTools'
|
|
import CoursewareType from './component/courseware-type'
|
|
import CoursewareType from './component/courseware-type'
|
|
import { useNetwork } from '@vueuse/core'
|
|
import { useNetwork } from '@vueuse/core'
|
|
|
|
+import PointsSearch from './component/points-search'
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'CoursewarePlay',
|
|
name: 'CoursewarePlay',
|
|
@@ -130,7 +133,13 @@ export default defineComponent({
|
|
|
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
const headeRef = ref()
|
|
const headeRef = ref()
|
|
|
|
+ const detailTempSearchList = shallowRef<any[]>()
|
|
|
|
+ const detailList = shallowRef<any[]>()// 搜索来的所有数据
|
|
const data = reactive({
|
|
const data = reactive({
|
|
|
|
+ source: route.query.source as any, // 来源 search 搜索
|
|
|
|
+ searchLoading: false, // 搜索加载状态
|
|
|
|
+ search: route.query.search as any, // 默认的搜索条件 -
|
|
|
|
+ searchTemp: route.query.search as any, // 默认的搜索条件 -
|
|
currentId: route.query.id as any,
|
|
currentId: route.query.id as any,
|
|
detail: null as any,
|
|
detail: null as any,
|
|
knowledgePointList: [] as any,
|
|
knowledgePointList: [] as any,
|
|
@@ -382,17 +391,185 @@ export default defineComponent({
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- const onTitleTip = (type: "phaseGoals" | "checkItem", text: string) => {
|
|
|
|
- handleStop()
|
|
|
|
- popupData.pointOpen = true
|
|
|
|
- popupData.pointContent = text
|
|
|
|
- if(type === "checkItem") {
|
|
|
|
- popupData.pointTitle = '检查事项'
|
|
|
|
- } else if(type === "phaseGoals") {
|
|
|
|
- popupData.pointTitle = '阶段目标'
|
|
|
|
|
|
+ const getSearchItemList = async (knowledgePointList: any[]) => {
|
|
|
|
+ const list: any = [];
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < knowledgePointList.length; i++) {
|
|
|
|
+ const item = knowledgePointList[i];
|
|
|
|
+ if (item.materialList && item.materialList.length > 0) {
|
|
|
|
+ const tempList = await getTempList(item.materialList, item.name);
|
|
|
|
+ list.push(...tempList);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 第二层级
|
|
|
|
+ if (item.children && item.children.length > 0) {
|
|
|
|
+ const childrenList = item.children || [];
|
|
|
|
+ for (let j = 0; j < childrenList.length; j++) {
|
|
|
|
+ const childItem = childrenList[j];
|
|
|
|
+ const tempList = await getTempList(
|
|
|
|
+ childItem.materialList,
|
|
|
|
+ childItem.name
|
|
|
|
+ );
|
|
|
|
+ list.push(...tempList);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ return list
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /** 从搜索页面来的 */
|
|
|
|
+ const getSearchDetail = async (params: { type?: string, id?: any, search?: string }) => {
|
|
|
|
+ try {
|
|
|
|
+ const res = await request.get(
|
|
|
|
+ state.platformApi +
|
|
|
|
+ `/tenantAlbumMusic/getLessonCoursewareCourseList/${params.id || route.query.lessonId}`,
|
|
|
|
+ {
|
|
|
|
+ hideLoading: true,
|
|
|
|
+ params: {
|
|
|
|
+ detailFlag: "1",
|
|
|
|
+ search: params.search
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ const result = res.data || []
|
|
|
|
+ const allList: any[] = []
|
|
|
|
+ for(let i = 0; i < result.length; i++) {
|
|
|
|
+ const itemResult = result[i];
|
|
|
|
+ itemResult.name = itemResult.coursewareDetailName;
|
|
|
|
+ itemResult.id = itemResult.coursewareDetailId;
|
|
|
|
+ itemResult.lessonTargetDesc = itemResult.lessonTargetDesc ? itemResult.lessonTargetDesc.replace(/\n/g, "<br />") : ""
|
|
|
|
+ if (Array.isArray(itemResult?.knowledgePointList)) {
|
|
|
|
+ let index = 0;
|
|
|
|
+ itemResult.children = itemResult.knowledgePointList.map(
|
|
|
|
+ (n: any) => {
|
|
|
|
+ if (Array.isArray(n.materialList)) {
|
|
|
|
+ n.materialList = n.materialList.map((item: any) => {
|
|
|
|
+ index++;
|
|
|
|
+ const materialRefs = item.materialRefs
|
|
|
|
+ ? item.materialRefs
|
|
|
|
+ : [];
|
|
|
|
+ const materialMusicId =
|
|
|
|
+ materialRefs.length > 0
|
|
|
|
+ ? materialRefs[0].resourceIdStr
|
|
|
|
+ : null;
|
|
|
|
+ return {
|
|
|
|
+ ...item,
|
|
|
|
+ materialMusicId,
|
|
|
|
+ content: item.content,
|
|
|
|
+ coursewareDetailId: itemResult.coursewareDetailId,
|
|
|
|
+ knowledgePointId: [itemResult.coursewareDetailId, item.knowledgePointId],
|
|
|
|
+ materialId: item.id,
|
|
|
|
+ id: index + ''
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if (Array.isArray(n.children)) {
|
|
|
|
+ n.children = n.children.map((cn: any) => {
|
|
|
|
+ cn.materialList = cn.materialList.map((item: any) => {
|
|
|
|
+ index++;
|
|
|
|
+ const materialRefs = item.materialRefs
|
|
|
|
+ ? item.materialRefs
|
|
|
|
+ : [];
|
|
|
|
+ const materialMusicId =
|
|
|
|
+ materialRefs.length > 0
|
|
|
|
+ ? materialRefs[0].resourceIdStr
|
|
|
|
+ : null;
|
|
|
|
+ return {
|
|
|
|
+ ...item,
|
|
|
|
+ materialMusicId,
|
|
|
|
+ coursewareDetailId: itemResult.coursewareDetailId,
|
|
|
|
+ content: item.content,
|
|
|
|
+ knowledgePointId: [itemResult.coursewareDetailId, n.id, item.knowledgePointId],
|
|
|
|
+ materialId: item.id,
|
|
|
|
+ id: index + ''
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+ return cn;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ return n;
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ itemResult.knowledgePointList = null // 去掉不要的
|
|
|
|
+ itemResult.list = await getSearchItemList(itemResult.children);
|
|
|
|
+
|
|
|
|
+ allList.push(...itemResult.list)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(params.type === 'pointSearch') {
|
|
|
|
+ detailTempSearchList.value = result
|
|
|
|
+
|
|
|
|
+ // 初始化选中的数据 临时
|
|
|
|
+ popupData.tempTabActive = allList.length > 0 ? allList[0].knowledgePointId : []
|
|
|
|
+ popupData.tempItemActive = "-1"
|
|
|
|
+ data.searchTemp = params.search
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ detailList.value = result
|
|
|
|
+ detailTempSearchList.value = result
|
|
|
|
+
|
|
|
|
+ if(!params.type) {
|
|
|
|
+ let _firstIndex = allList.findIndex(
|
|
|
|
+ (n: any) =>
|
|
|
|
+ n.knowledgePointMaterialRelationId == route.query.kId ||
|
|
|
|
+ n.materialId == route.query.kId
|
|
|
|
+ );
|
|
|
|
+ _firstIndex = _firstIndex > -1 ? _firstIndex : 0;
|
|
|
|
+ const item = allList[_firstIndex];
|
|
|
|
+ // console.log(item, 'item')
|
|
|
|
+ // console.log(_firstIndex, '_firstIndex', route.query.kId, 'route.query.kId', item)
|
|
|
|
+ // 是否自动播放
|
|
|
|
+ if (activeData.isAutoPlay) {
|
|
|
|
+ item.autoPlay = true;
|
|
|
|
+ }
|
|
|
|
+ popupData.activeIndex = _firstIndex;
|
|
|
|
+ popupData.playIndex = _firstIndex;
|
|
|
|
+ popupData.tabName = item.tabName;
|
|
|
|
+ popupData.tabActive = item.knowledgePointId;
|
|
|
|
+ popupData.itemActive = item.id;
|
|
|
|
+ popupData.itemName = item.name;
|
|
|
|
+
|
|
|
|
+ data.detail = detailList.value?.find((child: any) => child.coursewareDetailId === item.coursewareDetailId)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ data.itemList = allList;
|
|
|
|
+ checkedAnimation(popupData.activeIndex);
|
|
|
|
+ postMessage({
|
|
|
|
+ api: 'courseLoading',
|
|
|
|
+ content: {
|
|
|
|
+ show: false,
|
|
|
|
+ type: 'fullscreen'
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (data.disableScreenRecordingFlag === '1') {
|
|
|
|
+ // 检测是否录屏
|
|
|
|
+ handleLimitScreenRecord();
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ data.animationState = 'end';
|
|
|
|
+ }, 500);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ return true
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const onTitleTip = (type: "phaseGoals" | "checkItem", text: string) => {
|
|
|
|
+ handleStop()
|
|
|
|
+ popupData.pointOpen = true
|
|
|
|
+ popupData.pointContent = text
|
|
|
|
+ if(type === "checkItem") {
|
|
|
|
+ popupData.pointTitle = '检查事项'
|
|
|
|
+ } else if(type === "phaseGoals") {
|
|
|
|
+ popupData.pointTitle = '阶段目标'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
// ifram事件处理
|
|
// ifram事件处理
|
|
const iframeHandle = (ev: MessageEvent) => {
|
|
const iframeHandle = (ev: MessageEvent) => {
|
|
@@ -498,11 +675,17 @@ export default defineComponent({
|
|
|
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
await sysParamConfig()
|
|
await sysParamConfig()
|
|
- // 只有老师端才有课程类型
|
|
|
|
- if(baseState.platformType === "TEACHER") {
|
|
|
|
- await getRefLevel()
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if(data.source === 'search') {
|
|
|
|
+ await getSearchDetail({search: data.search})
|
|
|
|
+ } else {
|
|
|
|
+ // 只有老师端才有课程类型
|
|
|
|
+ if(baseState.platformType === "TEACHER") {
|
|
|
|
+ await getRefLevel()
|
|
|
|
+ }
|
|
|
|
+ await getDetail()
|
|
}
|
|
}
|
|
- await getDetail()
|
|
|
|
// getCourseSchedule();
|
|
// getCourseSchedule();
|
|
window.addEventListener('message', iframeHandle)
|
|
window.addEventListener('message', iframeHandle)
|
|
|
|
|
|
@@ -552,6 +735,8 @@ export default defineComponent({
|
|
open: false,
|
|
open: false,
|
|
activeIndex: 0,
|
|
activeIndex: 0,
|
|
playIndex: 0,
|
|
playIndex: 0,
|
|
|
|
+ tempTabActive: '', // 临时选中
|
|
|
|
+ tempItemActive: "", // 临时编号
|
|
tabActive: '',
|
|
tabActive: '',
|
|
tabName: '',
|
|
tabName: '',
|
|
itemActive: '',
|
|
itemActive: '',
|
|
@@ -703,6 +888,10 @@ export default defineComponent({
|
|
const acitveTimer = ref()
|
|
const acitveTimer = ref()
|
|
// 轮播切换
|
|
// 轮播切换
|
|
const handleSwipeChange = async (index: number) => {
|
|
const handleSwipeChange = async (index: number) => {
|
|
|
|
+ if(data.source === 'search') {
|
|
|
|
+ const item = data.itemList[index];
|
|
|
|
+ data.detail = detailList.value?.find((child: any) => child.coursewareDetailId === item.coursewareDetailId)
|
|
|
|
+ }
|
|
// 如果是当前正在播放 或者是视频最后一个
|
|
// 如果是当前正在播放 或者是视频最后一个
|
|
if (popupData.activeIndex == index) return
|
|
if (popupData.activeIndex == index) return
|
|
await handleStop()
|
|
await handleStop()
|
|
@@ -1045,39 +1234,53 @@ export default defineComponent({
|
|
>
|
|
>
|
|
|
|
|
|
<div class={[styles.btnsWrap, styles.prePoint]}>
|
|
<div class={[styles.btnsWrap, styles.prePoint]}>
|
|
- {baseState.platformType === "TEACHER" && <div class={styles.fullBtn} onClick={() => {
|
|
|
|
- handleStop()
|
|
|
|
- popupData.coursewareOpen = true
|
|
|
|
- }}>
|
|
|
|
- <img src={iconCourseType} />
|
|
|
|
- </div>}
|
|
|
|
|
|
+
|
|
|
|
+ {data.source === 'search' ?
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => {
|
|
|
|
+ handleStop()
|
|
|
|
+ detailTempSearchList.value = detailList.value
|
|
|
|
+ popupData.tempItemActive = ""
|
|
|
|
+ popupData.tempTabActive = ""
|
|
|
|
+ data.searchTemp = ""
|
|
|
|
+ // data.searchTemp = JSON.parse(JSON.stringify(data.search))
|
|
|
|
+ popupData.open = true
|
|
|
|
+ }}>
|
|
|
|
+ <img src={iconSearch} />
|
|
|
|
+ </div> : <>
|
|
|
|
+ {baseState.platformType === "TEACHER" && <div class={styles.fullBtn} onClick={() => {
|
|
|
|
+ handleStop()
|
|
|
|
+ popupData.coursewareOpen = true
|
|
|
|
+ }}>
|
|
|
|
+ <img src={iconCourseType} />
|
|
|
|
+ </div>}
|
|
|
|
+
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => {
|
|
|
|
+ handleStop()
|
|
|
|
+ popupData.open = true
|
|
|
|
+ }}>
|
|
|
|
+ <img src={iconMenu} />
|
|
|
|
+ {/* <span>知识点</span> */}
|
|
|
|
+ </div>
|
|
|
|
+ </>}
|
|
|
|
|
|
- <div class={styles.fullBtn} onClick={() => {
|
|
|
|
- handleStop()
|
|
|
|
- popupData.open = true
|
|
|
|
- }}>
|
|
|
|
- <img src={iconMenu} />
|
|
|
|
- {/* <span>知识点</span> */}
|
|
|
|
|
|
+ <div
|
|
|
|
+ class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
|
|
|
|
+ onClick={() => {
|
|
|
|
+ if(popupData.activeIndex != 0) handlePreAndNext('up')
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <img src={iconUp} />
|
|
|
|
+ {/* <span style={{ textAlign: 'center' }}>上一个</span> */}
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class={[styles.fullBtn, !(popupData.activeIndex != data.itemList.length - 1) && styles.disabled]}
|
|
|
|
+ onClick={() => {
|
|
|
|
+ if(popupData.activeIndex != data.itemList.length - 1) handlePreAndNext('down')
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ {/* <span style={{ textAlign: 'center' }}>下一个</span> */}
|
|
|
|
+ <img src={iconDown} />
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <div
|
|
|
|
- class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
|
|
|
|
- onClick={() => {
|
|
|
|
- if(popupData.activeIndex != 0) handlePreAndNext('up')
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <img src={iconUp} />
|
|
|
|
- {/* <span style={{ textAlign: 'center' }}>上一个</span> */}
|
|
|
|
- </div>
|
|
|
|
- <div
|
|
|
|
- class={[styles.fullBtn, !(popupData.activeIndex != data.itemList.length - 1) && styles.disabled]}
|
|
|
|
- onClick={() => {
|
|
|
|
- if(popupData.activeIndex != data.itemList.length - 1) handlePreAndNext('down')
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- {/* <span style={{ textAlign: 'center' }}>下一个</span> */}
|
|
|
|
- <img src={iconDown} />
|
|
|
|
- </div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
)}
|
|
@@ -1165,16 +1368,50 @@ export default defineComponent({
|
|
v-model:show={popupData.open}
|
|
v-model:show={popupData.open}
|
|
onClose={handleClosePopup}
|
|
onClose={handleClosePopup}
|
|
>
|
|
>
|
|
- <Points
|
|
|
|
- data={data.knowledgePointList}
|
|
|
|
- tabActive={popupData.tabActive}
|
|
|
|
- itemActive={popupData.itemActive}
|
|
|
|
- onHandleSelect={(res: any) => {
|
|
|
|
- // onChangeSwiper('change', res.itemActive)
|
|
|
|
- popupData.open = false
|
|
|
|
- toggleMaterial(res.itemActive)
|
|
|
|
- }}
|
|
|
|
- />
|
|
|
|
|
|
+ {data.source === 'search' ?
|
|
|
|
+ <PointsSearch
|
|
|
|
+ data={detailTempSearchList.value}
|
|
|
|
+ search={data.searchTemp || data.search}
|
|
|
|
+ loading={data.searchLoading}
|
|
|
|
+ tabActive={popupData.tempTabActive || popupData.tabActive}
|
|
|
|
+ itemActive={popupData.tempItemActive || popupData.itemActive}
|
|
|
|
+ open={popupData.open}
|
|
|
|
+ onHandleSelect={(res: any) => {
|
|
|
|
+ popupData.open = false;
|
|
|
|
+ if(res.isSearch) {
|
|
|
|
+ detailList.value = detailTempSearchList.value
|
|
|
|
+ const tempList: any[] = []
|
|
|
|
+ detailTempSearchList.value?.forEach((item: any) => {
|
|
|
|
+ if(Array.isArray(item.list)) {
|
|
|
|
+ tempList.push(...item.list)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ data.itemList = tempList || []
|
|
|
|
+ data.search = JSON.parse(JSON.stringify(data.searchTemp))
|
|
|
|
+ }
|
|
|
|
+ toggleMaterial(res.itemActive);
|
|
|
|
+ }}
|
|
|
|
+ onHandleSearch={async (val: any) => {
|
|
|
|
+ data.searchLoading = true
|
|
|
|
+ detailTempSearchList.value = []
|
|
|
|
+ await getSearchDetail({
|
|
|
|
+ type: 'pointSearch',
|
|
|
|
+ search: val.search
|
|
|
|
+ })
|
|
|
|
+ data.searchTemp = val.search;
|
|
|
|
+ data.searchLoading = false
|
|
|
|
+ }} /> :
|
|
|
|
+ <Points
|
|
|
|
+ data={data.knowledgePointList}
|
|
|
|
+ tabActive={popupData.tabActive}
|
|
|
|
+ itemActive={popupData.itemActive}
|
|
|
|
+ onHandleSelect={(res: any) => {
|
|
|
|
+ // onChangeSwiper('change', res.itemActive)
|
|
|
|
+ popupData.open = false
|
|
|
|
+ toggleMaterial(res.itemActive)
|
|
|
|
+ }}
|
|
|
|
+ />}
|
|
|
|
+
|
|
</Popup>
|
|
</Popup>
|
|
|
|
|
|
<Popup
|
|
<Popup
|