|
@@ -23,7 +23,7 @@ import qs from 'query-string'
|
|
|
import MusicScore from './component/musicScore'
|
|
|
// import iconDian from './image/icon-dian.svg'
|
|
|
// import iconPoint from './image/icon-point.svg'
|
|
|
-import { iconUp, iconDown, iconPen, iconTouping, iconMenu, iconCourseType } from './image/icons.json'
|
|
|
+import { iconUp, iconDown, iconPen, iconTouping, iconMenu, iconCourseType, iconSearch } from './image/icons.json'
|
|
|
import Points from './component/points'
|
|
|
import { browser } from '@/helpers/utils'
|
|
|
import { Vue3Lottie } from 'vue3-lottie'
|
|
@@ -42,6 +42,7 @@ import CoursewareType from './component/courseware-type'
|
|
|
import CoursewareTips from './component/courseware-tips'
|
|
|
import GlobalTools from '@/components/globalTools'
|
|
|
import { isPlay, penShow, toolOpen, whitePenShow } from '@/components/globalTools/globalTools'
|
|
|
+import PointsSearch from './component/points-search'
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: 'CoursewarePlay',
|
|
@@ -118,7 +119,13 @@ export default defineComponent({
|
|
|
const route = useRoute()
|
|
|
const headeRef = ref()
|
|
|
const isCurrentCoursewareMenu = shallowRef(true) // 是否为当前选的课程类型
|
|
|
+ const detailTempSearchList = shallowRef<any[]>()
|
|
|
+ const detailList = shallowRef<any[]>()// 搜索来的所有数据
|
|
|
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,
|
|
|
detail: null as any,
|
|
|
knowledgePointList: [] as any,
|
|
@@ -352,6 +359,184 @@ export default defineComponent({
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ 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.post(
|
|
|
+ state.platformApi +
|
|
|
+ `/courseSchedule/myCoursewareDetail/${params.id || route.query.lessonId}`,
|
|
|
+ {
|
|
|
+ hideLoading: true,
|
|
|
+ data: {
|
|
|
+ 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.courseScheduleId;
|
|
|
+ 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;
|
|
|
+ const useStatus = materialRefs.length > 0
|
|
|
+ ? materialRefs[0]?.extend?.useStatus : null
|
|
|
+ const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ isLock,
|
|
|
+ materialMusicId,
|
|
|
+ content: item.content,
|
|
|
+ coursewareDetailId: itemResult.courseScheduleId,
|
|
|
+ knowledgePointId: [itemResult.courseScheduleId, item.knowledgePointId],
|
|
|
+ materialId: item.id,
|
|
|
+ id: (i * 1000 + '') + 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;
|
|
|
+ const useStatus = materialRefs.length > 0
|
|
|
+ ? materialRefs[0]?.extend?.useStatus : null
|
|
|
+ const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ isLock,
|
|
|
+ materialMusicId,
|
|
|
+ coursewareDetailId: itemResult.courseScheduleId,
|
|
|
+ content: item.content,
|
|
|
+ knowledgePointId: [itemResult.courseScheduleId, n.id, item.knowledgePointId],
|
|
|
+ materialId: item.id,
|
|
|
+ id: (i * 1000 + '') + 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
|
|
@@ -488,11 +673,15 @@ export default defineComponent({
|
|
|
if (state.platformType === 'STUDENT') {
|
|
|
await getLookVideoData()
|
|
|
}
|
|
|
- // 只有老师有 课程类型 切换
|
|
|
- if(state.platformType === "TEACHER") {
|
|
|
- await getRefLevel()
|
|
|
+ if(data.source === 'search') {
|
|
|
+ await getSearchDetail({search: data.search})
|
|
|
+ } else {
|
|
|
+ // 只有老师有 课程类型 切换
|
|
|
+ if(state.platformType === "TEACHER") {
|
|
|
+ await getRefLevel()
|
|
|
+ }
|
|
|
+ await getDetail()
|
|
|
}
|
|
|
- await getDetail()
|
|
|
const hasFree = String(data.detail?.accessScope) === '0'
|
|
|
if (!hasFree) {
|
|
|
const hasVip = handleCheckVip()
|
|
@@ -557,6 +746,8 @@ export default defineComponent({
|
|
|
open: false,
|
|
|
activeIndex: 0,
|
|
|
playIndex: 0,
|
|
|
+ tempTabActive: '', // 临时选中
|
|
|
+ tempItemActive: "", // 临时编号
|
|
|
tabActive: '',
|
|
|
tabName: '',
|
|
|
itemActive: '',
|
|
@@ -712,6 +903,17 @@ export default defineComponent({
|
|
|
const acitveTimer = ref()
|
|
|
// 轮播切换
|
|
|
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)
|
|
|
+ popupData.tabActive = item.knowledgePointId;
|
|
|
+ popupData.itemActive = item.id;
|
|
|
+ popupData.itemName = item.name;
|
|
|
+ popupData.tabName = item.tabName;
|
|
|
+ if (item.typeCode == 'SONG') {
|
|
|
+ activeData.model = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
// 如果是当前正在播放 或者是视频最后一个
|
|
|
if (popupData.activeIndex == index) return
|
|
|
await handleStop()
|
|
@@ -1201,20 +1403,34 @@ export default defineComponent({
|
|
|
{activeData.model && (
|
|
|
<div class={styles.leftFixedBtns} onClick={(e: Event) => e.stopPropagation()}>
|
|
|
<div class={[styles.btnsWrap, styles.prePoint]}>
|
|
|
- {state.platformType === 'TEACHER' && <div class={styles.fullBtn} onClick={() => {
|
|
|
- popupData.coursewareOpen = true
|
|
|
- handleStop()
|
|
|
- }}>
|
|
|
- <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> : <>
|
|
|
+ {state.platformType === 'TEACHER' && <div class={styles.fullBtn} onClick={() => {
|
|
|
+ popupData.coursewareOpen = true
|
|
|
+ handleStop()
|
|
|
+ }}>
|
|
|
+ <img src={iconCourseType} />
|
|
|
+ </div>}
|
|
|
+
|
|
|
+ <div class={styles.fullBtn} onClick={() => {
|
|
|
+ popupData.open = true
|
|
|
+ handleStop()
|
|
|
+ }}>
|
|
|
+ <img src={iconMenu} />
|
|
|
+ {/* <span>知识点</span> */}
|
|
|
+ </div>
|
|
|
+ </>}
|
|
|
|
|
|
- <div class={styles.fullBtn} onClick={() => {
|
|
|
- popupData.open = true
|
|
|
- handleStop()
|
|
|
- }}>
|
|
|
- <img src={iconMenu} />
|
|
|
- {/* <span>知识点</span> */}
|
|
|
- </div>
|
|
|
<div
|
|
|
class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
|
|
|
onClick={() => {
|
|
@@ -1330,16 +1546,50 @@ export default defineComponent({
|
|
|
v-model:show={popupData.open}
|
|
|
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 = data.searchTemp ? 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
|