index.tsx 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. import { closeToast, Form, Icon, Popup, showDialog, showToast } from 'vant';
  2. import {
  3. defineComponent,
  4. onMounted,
  5. reactive,
  6. nextTick,
  7. onUnmounted,
  8. ref,
  9. watch,
  10. Transition,
  11. computed
  12. } from 'vue';
  13. import iconBack from './image/back.svg';
  14. import styles from './index.module.less';
  15. import 'plyr/dist/plyr.css';
  16. import { useRoute, useRouter } from 'vue-router';
  17. import {
  18. listenerMessage,
  19. postMessage,
  20. promisefiyPostMessage,
  21. removeListenerMessage
  22. } from '@/helpers/native-message';
  23. import MusicScore from './component/musicScore';
  24. import iconMenu from './image/icon-menu.svg';
  25. import iconChange from './image/icon-change.svg';
  26. import iconDian from './image/icon-dian.svg';
  27. import iconPoint from './image/icon-point.svg';
  28. import iconUp from './image/icon-up.svg';
  29. import iconDown from './image/icon-down.svg';
  30. import Points from './component/points';
  31. import { browser, getSecondRPM } from '@/helpers/utils';
  32. import { Vue3Lottie } from 'vue3-lottie';
  33. import playLoadData from './datas/data.json';
  34. import { usePageVisibility } from '@vant/use';
  35. import AudioItem from './component/audio-item';
  36. import {
  37. api_classLessonCoursewareQuery,
  38. api_lessonCoursewareKnowledgeDetailDetail
  39. } from './api';
  40. import {
  41. api_lessonDetailCourseware,
  42. api_classDetailCourseware
  43. } from '../courseware-list/api';
  44. import VideoItem from './component/video-item';
  45. import Chapter from './component/chapter';
  46. import {
  47. api_classLessonCoursewareDetail,
  48. api_lessonCoursewareDetail
  49. } from '../courseware-list/api';
  50. // import detail from '../information/help-center/detail';
  51. import { setLogin, state } from '@/state';
  52. import Theory from './component/theory';
  53. import InstrumentInfo from './component/instrument-info';
  54. // import TempoPractice from '../../views/tempo-practice';
  55. import SelectCoursewarePop from '@/components/select-courseware-pop';
  56. import { debounce } from '../../helpers/utils';
  57. import TempoItem from './component/tempo-item';
  58. import ListenItem from './component/listen-item';
  59. import SelectCoursewareMember from '@/components/select-courseware-member';
  60. import request from '@/helpers/request';
  61. export default defineComponent({
  62. name: 'CoursewarePlay',
  63. setup() {
  64. const pageVisibility = usePageVisibility();
  65. const lastTimeKey = 'lastTime' + (state?.user?.data?.phone ?? '');
  66. const showSelectCourseware = ref(false);
  67. const showMember = ref(false);
  68. const debounceSkip = ref(false);
  69. /** 设置播放容器 16:9 */
  70. const parentContainer = reactive({
  71. width: '100vw'
  72. });
  73. const setContainer = () => {
  74. let min = Math.min(screen.width, screen.height);
  75. let max = Math.max(screen.width, screen.height);
  76. let width = min * (16 / 9);
  77. if (width > max) {
  78. parentContainer.width = '100vw';
  79. return;
  80. } else {
  81. parentContainer.width = width + 'px';
  82. }
  83. };
  84. const handleInit = (type = 0) => {
  85. //设置容器16:9
  86. setContainer();
  87. // 横屏
  88. // postMessage(
  89. // {
  90. // api: 'setRequestedOrientation',
  91. // content: {
  92. // orientation: type
  93. // }
  94. // },
  95. // () => {
  96. // console.log(234);
  97. // }
  98. // );
  99. // 头,包括返回箭头
  100. // postMessage({
  101. // api: 'setTitleBarVisibility',
  102. // content: {
  103. // status: type
  104. // }
  105. // })
  106. // 安卓的状态栏
  107. postMessage({
  108. api: 'setStatusBarVisibility',
  109. content: {
  110. isVisibility: type
  111. }
  112. });
  113. // 进入页面设置常量
  114. postMessage({
  115. api: 'keepScreenLongLight',
  116. content: {
  117. isOpenLight: type ? true : false
  118. }
  119. });
  120. };
  121. handleInit();
  122. onUnmounted(() => {
  123. handleInit(1);
  124. window.removeEventListener('message', iframeHandle);
  125. });
  126. const getCourseDetail = async () => {
  127. try {
  128. if (route.query.tab == 'course') {
  129. const res = await api_classLessonCoursewareDetail({
  130. id: activeData.courseId as any,
  131. subjectId: activeData.subjectId
  132. });
  133. if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
  134. data.courseDetails = res.data.lessonList || [];
  135. // console.log('🚀 ~ data.details course:', data.courseDetails);
  136. }
  137. } else {
  138. const res = await api_lessonCoursewareDetail({
  139. id: route.query.lessonCoursewareId as any,
  140. subjectId: activeData.subjectId
  141. });
  142. if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
  143. data.courseDetails = res.data.lessonList || [];
  144. }
  145. }
  146. // console.log(data.courseDetails, 'data.courseDetails');
  147. } catch {
  148. //
  149. }
  150. };
  151. const route = useRoute();
  152. const headeRef = ref();
  153. const loadingClass = ref(false); // 重新加载课件
  154. const data = reactive({
  155. allList: [] as any, // 所选章节下的所有课件列表
  156. kjId: route.query.id as string, // 所选的课件id
  157. currentCourse: {} as any, // 当前选中的课件
  158. zsdId: '' as string, // 知识点id
  159. knowledgePointList: [] as any, //所选课件,所选知识点下所有的资源列表
  160. courseDetails: [] as any,
  161. itemList: [] as any,
  162. videoRefs: {} as any[],
  163. videoState: 'init' as 'init' | 'play',
  164. videoItemRef: null as any,
  165. animationState: 'start' as 'start' | 'end',
  166. coursewareList: []
  167. });
  168. const activeData = reactive({
  169. isAutoPlay: true, // 是否自动播放
  170. subjectId: route.query.subjectId,
  171. lessonCoursewareId: route.query.lessonCoursewareId,
  172. lessonCoursewareDetailId: route.query.lessonCoursewareDetailId,
  173. coursewareDetailKnowledgeId: route.query.coursewareDetailKnowledgeId,
  174. courseId: route.query.courseId, // 我的课程专用编号
  175. nowTime: 0,
  176. model: true, // 遮罩
  177. isAnimation: true, // 是否动画
  178. videoBtns: true, // 视频
  179. currentTime: 0,
  180. duration: 0,
  181. timer: null as any,
  182. item: null as any
  183. });
  184. // 切换单元临时数据
  185. const temporaryData = reactive({
  186. dyId: '', // 单元id
  187. zjId: '' // 章节id
  188. });
  189. const getDetail = async () => {
  190. data.allList = [];
  191. let courseList: any[] = [];
  192. if (route.query.tab == 'course') {
  193. // const res = await api_classLessonCoursewareQuery({
  194. // coursewareDetailKnowledgeId: activeData.coursewareDetailKnowledgeId,
  195. // subjectId: activeData.subjectId,
  196. // page: 1,
  197. // rows: -1
  198. // });
  199. const res = await api_classDetailCourseware({
  200. lessonCoursewareKnowledgeDetailId:
  201. activeData.coursewareDetailKnowledgeId // 章节id
  202. });
  203. if (res?.code === 200 && Array.isArray(res.data)) {
  204. // const tempRows = res.data.rows || [];
  205. // tempRows.forEach((item: any) => {
  206. // courseList.push({
  207. // content: item.content,
  208. // coverImg: item.coverImg,
  209. // id: item.id,
  210. // materialId: item.materialId,
  211. // name: item.materialName,
  212. // relOrder: 0,
  213. // sourceFrom: item.source,
  214. // type: item.materialType
  215. // });
  216. // });
  217. res.data.forEach((item: any) => {
  218. item.knowledgeList = item.resourceList;
  219. item.resourceList.forEach((n: any) => {
  220. n.materialInfo = n.resourceList;
  221. });
  222. });
  223. data.allList = res.data;
  224. const currentCourse = res.data.find(
  225. (item: any) => item.id === data.kjId
  226. );
  227. data.zsdId = currentCourse?.knowledgeList?.[0].id;
  228. courseList = currentCourse?.knowledgeList?.[0].materialInfo || [];
  229. data.currentCourse = currentCourse || {};
  230. }
  231. } else {
  232. // const res = await api_lessonCoursewareKnowledgeDetailDetail({
  233. // lessonCoursewareKnowledgeDetailId:
  234. // activeData.coursewareDetailKnowledgeId,
  235. // subjectId: activeData.subjectId
  236. // });
  237. const res = await api_lessonDetailCourseware({
  238. lessonCoursewareKnowledgeDetailId:
  239. activeData.coursewareDetailKnowledgeId // 章节id
  240. });
  241. if (res?.code === 200 && Array.isArray(res.data)) {
  242. data.allList = res.data;
  243. const currentCourse = res.data.find(
  244. (item: any) => item.id === data.kjId
  245. );
  246. data.zsdId = currentCourse?.knowledgeList?.[0].id;
  247. courseList = currentCourse?.knowledgeList?.[0].materialInfo || [];
  248. data.currentCourse = currentCourse || {};
  249. // console.log('课件类型', data.allList);
  250. }
  251. }
  252. // 当前的资源id
  253. let resourceId: any = null;
  254. // 课程
  255. if (courseList.length > 0) {
  256. resourceId = courseList[0].id;
  257. data.knowledgePointList = courseList.map((item: any) => {
  258. return {
  259. ...item,
  260. url:
  261. item.type === 'SONG'
  262. ? 'https://oss.dayaedu.com/ktqy/1698420034679a22d3f7a.png'
  263. : item.type === 'PPT'
  264. ? 'https://oss.dayaedu.com/ktqy/12/1701931810284.png'
  265. : item.coverImg
  266. };
  267. });
  268. }
  269. // 当前章节下的所有资源列表
  270. let allResource: any = [];
  271. console.log(data.allList, 'data.allList');
  272. data.allList.forEach((item: any) => {
  273. item.knowledgeList.forEach((material: any) => {
  274. material.materialInfo.forEach((resource: any) => {
  275. resource.zsdId = material.id; // 知识点id
  276. resource.kjId = item.id; // 课件id
  277. resource.bizId =
  278. route.query.tab == 'course'
  279. ? resource.materialId
  280. : resource.bizId;
  281. resource.url =
  282. resource.coverImg ||
  283. (resource.type === 'SONG'
  284. ? 'https://oss.dayaedu.com/ktqy/1698420034679a22d3f7a.png'
  285. : resource.type === 'PPT'
  286. ? 'https://oss.dayaedu.com/ktqy/12/1701931810284.png'
  287. : resource.coverImg);
  288. });
  289. allResource = allResource.concat(material.materialInfo);
  290. });
  291. console.log(allResource, 'allResource');
  292. });
  293. // 当前章节下,所选的课件所有资源列表
  294. let allKjResource: any = [];
  295. data.currentCourse?.knowledgeList?.forEach((material: any) => {
  296. material.materialInfo.forEach((resource: any) => {
  297. resource.zsdId = material.id; // 知识点id
  298. resource.kjId = data.currentCourse.id; // 课件id
  299. resource.bizId =
  300. route.query.tab == 'course' ? resource.materialId : resource.bizId;
  301. resource.url =
  302. resource.coverImg ||
  303. (resource.type === 'SONG'
  304. ? 'https://oss.dayaedu.com/ktqy/1698420034679a22d3f7a.png'
  305. : resource.type === 'PPT'
  306. ? 'https://oss.dayaedu.com/ktqy/12/1701931810284.png'
  307. : resource.coverImg);
  308. });
  309. allKjResource = allKjResource.concat(material.materialInfo);
  310. });
  311. data.itemList = allKjResource.map((m: any, index: number) => {
  312. if (!popupData.itemActive) {
  313. popupData.itemActive = m.id;
  314. popupData.itemName = m.name;
  315. }
  316. return {
  317. ...m,
  318. iframeRef: null,
  319. videoEle: null,
  320. autoPlay: showMember.value
  321. ? false
  322. : data.currentCourse.autoPlay || false, //加载完成是否自动播放
  323. isprepare: false, // 视频是否加载完成
  324. isRender: false // 是否渲染了
  325. };
  326. });
  327. const resourceIndex = data.itemList.findIndex(
  328. (resource: any) => resource.id === resourceId
  329. );
  330. setTimeout(() => {
  331. handleSwipeChange(resourceIndex);
  332. }, 0);
  333. setTimeout(() => {
  334. data.animationState = 'end';
  335. }, 500);
  336. };
  337. // ifram事件处理
  338. const iframeHandle = (ev: MessageEvent) => {
  339. if (ev.data?.api === 'headerTogge') {
  340. activeData.model =
  341. ev.data.show || (ev.data.playState == 'play' ? false : true);
  342. }
  343. if (ev.data?.api === 'api_fingerPreView') {
  344. clearInterval(activeData.timer);
  345. activeData.model = !ev.data.state;
  346. }
  347. if (ev.data?.api === 'clickTempo' || ev.data?.api === 'clickViewFigner') {
  348. setModelOpen();
  349. }
  350. };
  351. onMounted(() => {
  352. // needVipLock
  353. const schoolInfos = state.user.data?.schoolInfos;
  354. const schoolLock =
  355. schoolInfos && schoolInfos.length > 0
  356. ? schoolInfos[0].needVipLock
  357. : true;
  358. if (!state?.user?.data.vipMember && schoolLock) {
  359. showMember.value = true;
  360. } else {
  361. showMember.value = false;
  362. }
  363. postMessage({
  364. api: 'courseLoading',
  365. content: {
  366. show: false,
  367. type: 'fullscreen'
  368. }
  369. });
  370. getDetail();
  371. getCourseDetail();
  372. window.addEventListener('message', iframeHandle);
  373. });
  374. const playRef = ref();
  375. // 返回
  376. const goback = () => {
  377. try {
  378. playRef.value?.handleOut();
  379. } catch (error) {}
  380. postMessage({ api: 'goBack' });
  381. // router.back()
  382. };
  383. const popupData = reactive({
  384. open: false,
  385. activeIndex: 0,
  386. itemActive: '',
  387. itemName: '',
  388. itemPointName: route.query.name as any,
  389. chapterOpen: false
  390. });
  391. // 切换素材
  392. const toggleMaterial = (itemActive: any, zsdId: any, kjId: any) => {
  393. // 如果切换了知识点或者切换了课件,需要加载新的
  394. // if (zsdId !== data.zsdId || kjId !== data.kjId) {
  395. // data.zsdId = zsdId
  396. // data.kjId = kjId
  397. // let target = { materialInfo: [] }
  398. // // 如果是切换了知识点id
  399. // const kjIndex = data.allList.findIndex((item: any) => item.id === kjId)
  400. // target = data.allList[kjIndex].knowledgeList.find((item: any) => item.id === zsdId)
  401. // } else {
  402. // const index = data.itemList.findIndex((n: any) => n.id == itemActive);
  403. // if (index > -1) {
  404. // handleSwipeChange(index);
  405. // }
  406. // }
  407. const index = data.itemList.findIndex((n: any) => n.id == itemActive);
  408. if (index > -1) {
  409. handleSwipeChange(index);
  410. }
  411. };
  412. /** 延迟收起模态框 */
  413. const setModelOpen = () => {
  414. clearTimeout(activeData.timer);
  415. closeToast();
  416. activeData.model = !activeData.model;
  417. activeData.timer = setTimeout(() => {
  418. activeData.model = false;
  419. }, 4000);
  420. };
  421. const setModelOpen1 = () => {
  422. clearTimeout(activeData.timer);
  423. closeToast();
  424. activeData.model = true;
  425. activeData.timer = setTimeout(() => {
  426. activeData.model = false;
  427. }, 4000);
  428. };
  429. // 双击
  430. const handleDbClick = (item: any) => {
  431. if (item && ['VIDEO'].includes(item.type)) {
  432. console.log('双击');
  433. }
  434. };
  435. const effectIndex = ref(3);
  436. const effects = [
  437. {
  438. prev: {
  439. transform: 'translate3d(0, 0, -800px) rotateX(180deg)'
  440. },
  441. next: {
  442. transform: 'translate3d(0, 0, -800px) rotateX(-180deg)'
  443. }
  444. },
  445. {
  446. prev: {
  447. transform: 'translate3d(-100%, 0, -800px)'
  448. },
  449. next: {
  450. transform: 'translate3d(100%, 0, -800px)'
  451. }
  452. },
  453. {
  454. prev: {
  455. transform: 'translate3d(-50%, 0, -800px) rotateY(80deg)'
  456. },
  457. next: {
  458. transform: 'translate3d(50%, 0, -800px) rotateY(-80deg)'
  459. }
  460. },
  461. {
  462. prev: {
  463. transform: 'translate3d(-100%, 0, -800px) rotateY(-120deg)',
  464. opacity: 0
  465. },
  466. next: {
  467. transform: 'translate3d(100%, 0, -800px) rotateY(120deg)',
  468. opacity: 0
  469. }
  470. },
  471. // 风车4
  472. {
  473. prev: {
  474. transform: 'translate3d(-50%, 50%, -800px) rotateZ(-14deg)',
  475. opacity: 0
  476. },
  477. next: {
  478. transform: 'translate3d(50%, 50%, -800px) rotateZ(14deg)',
  479. opacity: 0
  480. }
  481. },
  482. // 翻页5
  483. {
  484. prev: {
  485. transform: 'translateZ(-800px) rotate3d(0, -1, 0, 90deg)',
  486. opacity: 0
  487. },
  488. next: {
  489. transform: 'translateZ(-800px) rotate3d(0, 1, 0, 90deg)',
  490. opacity: 0
  491. },
  492. current: { transitionDelay: '700ms' }
  493. }
  494. ];
  495. const handleStop = () => {
  496. data.videoItemRef?.pause();
  497. };
  498. const acitveTimer = ref();
  499. // 轮播切换
  500. const handleSwipeChange = (index: number) => {
  501. // 如果是当前正在播放 或者是视频最后一个
  502. if (popupData.activeIndex == index) return;
  503. data.animationState = 'start';
  504. data.videoState = 'init';
  505. handleStop();
  506. clearTimeout(acitveTimer.value);
  507. activeData.model = true;
  508. const item = data.itemList[index];
  509. data.kjId = item.kjId;
  510. data.zsdId = item.zsdId;
  511. popupData.activeIndex = index;
  512. popupData.itemActive = item.id;
  513. popupData.itemName = item.name;
  514. if (item.type == 'MUSIC') {
  515. activeData.model = true;
  516. } else if (item.type == 'VIDEO') {
  517. if (item.error) {
  518. data.videoRefs[index]?.onPlay();
  519. }
  520. setTimeout(() => {
  521. data.animationState = 'end';
  522. }, 800);
  523. }
  524. };
  525. // 上一个知识点, 下一个知识点
  526. const handlePreAndNext = async (type: string) => {
  527. // 层级关系:单元〉章节〉知识点〉课件资源
  528. if (type === 'up') {
  529. // 判断上面是否还有章节
  530. if (popupData.activeIndex > 0) {
  531. handleSwipeChange(popupData.activeIndex - 1);
  532. return;
  533. }
  534. // 获取当前是哪个章节
  535. let detailIndex = data.courseDetails.findIndex(
  536. (item: any) => item.id == activeData.lessonCoursewareDetailId
  537. );
  538. const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
  539. let lessonIndex = detailItem.findIndex(
  540. (item: any) => item.id == activeData.coursewareDetailKnowledgeId
  541. );
  542. let lessonStatus = false; // 当前章节上面是否有内容
  543. let lessonCoursewareDetailId = '';
  544. let coursewareDetailKnowledgeId = '';
  545. let coursewareDetailKnowledgeName = '';
  546. let coursewareItem = {} as any;
  547. while (lessonIndex >= 0) {
  548. lessonIndex--;
  549. if (lessonIndex >= 0) {
  550. if (detailItem[lessonIndex].containMaterial) {
  551. lessonStatus = true;
  552. lessonCoursewareDetailId =
  553. detailItem[lessonIndex].lessonCoursewareDetailId;
  554. coursewareDetailKnowledgeId = detailItem[lessonIndex].id;
  555. coursewareDetailKnowledgeName = detailItem[lessonIndex].name;
  556. coursewareItem = detailItem[lessonIndex];
  557. }
  558. }
  559. if (lessonStatus) {
  560. break;
  561. }
  562. }
  563. // 判断当前章节下面课程是否有内容,否则往上一个章节走
  564. if (lessonStatus) {
  565. // loadingClass.value = true;
  566. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  567. // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
  568. // await getDetail();
  569. // popupData.activeIndex = data.itemList.length - 1 || 0;
  570. // popupData.itemActive =
  571. // data.knowledgePointList[data.itemList.length - 1]?.id ||
  572. // data.knowledgePointList[0]?.id;
  573. // popupData.itemPointName = coursewareDetailKnowledgeName;
  574. // popupData.itemName =
  575. // data.knowledgePointList[data.itemList.length - 1]?.name ||
  576. // data.knowledgePointList[0]?.name;
  577. // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
  578. // popupData.chapterOpen = false;
  579. // loadingClass.value = false;
  580. // console.log
  581. temporaryData.zjId = coursewareDetailKnowledgeId;
  582. temporaryData.dyId = lessonCoursewareDetailId;
  583. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  584. checkCourseware({
  585. ...coursewareItem,
  586. itemActive: coursewareDetailKnowledgeId
  587. });
  588. return;
  589. }
  590. let prevLessonStatus = false;
  591. while (detailIndex >= 0) {
  592. detailIndex--;
  593. const tempDetail =
  594. data.courseDetails[detailIndex]?.knowledgeList || [];
  595. let tempLessonLength = tempDetail.length;
  596. while (tempLessonLength > 0) {
  597. if (tempDetail[tempLessonLength - 1].containMaterial) {
  598. prevLessonStatus = true;
  599. lessonCoursewareDetailId =
  600. tempDetail[tempLessonLength - 1].lessonCoursewareDetailId;
  601. coursewareDetailKnowledgeId = tempDetail[tempLessonLength - 1].id;
  602. coursewareDetailKnowledgeName =
  603. tempDetail[tempLessonLength - 1].name;
  604. coursewareItem = tempDetail[tempLessonLength - 1];
  605. }
  606. tempLessonLength--;
  607. if (prevLessonStatus) {
  608. break;
  609. }
  610. }
  611. if (prevLessonStatus) {
  612. break;
  613. }
  614. }
  615. // 判断当前章节下面课程是否有内容,否则往上一个章节走
  616. if (prevLessonStatus) {
  617. // loadingClass.value = true;
  618. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  619. // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
  620. // await getDetail();
  621. // popupData.activeIndex = data.itemList.length - 1 || 0;
  622. // popupData.itemActive =
  623. // data.knowledgePointList[data.itemList.length - 1]?.id ||
  624. // data.knowledgePointList[0]?.id;
  625. // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
  626. // popupData.itemPointName = coursewareDetailKnowledgeName;
  627. // popupData.itemName =
  628. // data.knowledgePointList[data.itemList.length - 1]?.name ||
  629. // data.knowledgePointList[0]?.name;
  630. // popupData.chapterOpen = false;
  631. // loadingClass.value = false;
  632. // console.log('2', coursewareItem, coursewareDetailKnowledgeId);
  633. temporaryData.zjId = coursewareDetailKnowledgeId;
  634. temporaryData.dyId = lessonCoursewareDetailId;
  635. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  636. checkCourseware({
  637. ...coursewareItem,
  638. itemActive: coursewareDetailKnowledgeId
  639. });
  640. return;
  641. }
  642. } else {
  643. if (popupData.activeIndex < data.itemList.length - 1) {
  644. handleSwipeChange(popupData.activeIndex + 1);
  645. return;
  646. }
  647. // 获取当前是哪个单元
  648. let detailIndex = data.courseDetails.findIndex(
  649. (item: any) => item.id == activeData.lessonCoursewareDetailId
  650. );
  651. // 当前章节列表
  652. const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
  653. // 获取当前是哪个章节
  654. let lessonIndex = detailItem.findIndex(
  655. (item: any) => item.id == activeData.coursewareDetailKnowledgeId
  656. );
  657. let lessonStatus = false; // 当前章节下面是否有内容
  658. let lessonCoursewareDetailId = '';
  659. let coursewareDetailKnowledgeId = '';
  660. let coursewareDetailKnowledgeName = '';
  661. let coursewareItem = {} as any;
  662. while (lessonIndex < detailItem.length - 1) {
  663. lessonIndex++;
  664. if (lessonIndex >= 0) {
  665. if (detailItem[lessonIndex].containMaterial) {
  666. lessonStatus = true;
  667. lessonCoursewareDetailId =
  668. detailItem[lessonIndex].lessonCoursewareDetailId;
  669. coursewareDetailKnowledgeId = detailItem[lessonIndex].id;
  670. coursewareDetailKnowledgeName = detailItem[lessonIndex].name;
  671. coursewareItem = detailItem[lessonIndex];
  672. }
  673. }
  674. if (lessonStatus) {
  675. break;
  676. }
  677. }
  678. // 判断当前章节下面课程是否有内容,否则往下一个章节走
  679. if (lessonStatus) {
  680. // loadingClass.value = true;
  681. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  682. // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
  683. // await getDetail();
  684. // popupData.activeIndex = 0;
  685. // popupData.itemActive = data.knowledgePointList[0].id;
  686. // popupData.itemName = data.knowledgePointList[0].name;
  687. // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
  688. // popupData.itemPointName = coursewareDetailKnowledgeName;
  689. // popupData.chapterOpen = false;
  690. // loadingClass.value = false;
  691. temporaryData.zjId = coursewareDetailKnowledgeId;
  692. temporaryData.dyId = lessonCoursewareDetailId;
  693. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  694. // console.log(coursewareItem, 'coursewareItem', temporaryData);
  695. checkCourseware({
  696. ...coursewareItem,
  697. itemActive: coursewareDetailKnowledgeId
  698. });
  699. return;
  700. }
  701. let nextLessonStatus = false;
  702. while (detailIndex <= data.courseDetails.length - 1) {
  703. detailIndex++;
  704. const tempDetail =
  705. data.courseDetails[detailIndex]?.knowledgeList || [];
  706. let tempLessonLength = 0;
  707. while (tempLessonLength <= tempDetail.length - 1) {
  708. if (tempDetail[tempLessonLength].containMaterial) {
  709. nextLessonStatus = true;
  710. lessonCoursewareDetailId =
  711. tempDetail[tempLessonLength].lessonCoursewareDetailId;
  712. coursewareDetailKnowledgeId = tempDetail[tempLessonLength].id;
  713. coursewareDetailKnowledgeName = tempDetail[tempLessonLength].name;
  714. coursewareItem = tempDetail[tempLessonLength];
  715. }
  716. tempLessonLength++;
  717. if (nextLessonStatus) {
  718. break;
  719. }
  720. }
  721. if (nextLessonStatus) {
  722. break;
  723. }
  724. }
  725. // 判断当前章节下面课程是否有内容,否则往下一个单元走
  726. if (nextLessonStatus) {
  727. // loadingClass.value = true;
  728. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  729. // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
  730. // await getDetail();
  731. // popupData.activeIndex = 0;
  732. // popupData.itemActive = data.knowledgePointList[0].id;
  733. // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
  734. // popupData.itemName = data.knowledgePointList[0].name;
  735. // popupData.itemPointName = coursewareDetailKnowledgeName;
  736. // popupData.chapterOpen = false;
  737. // loadingClass.value = false;
  738. temporaryData.zjId = coursewareDetailKnowledgeId;
  739. temporaryData.dyId = lessonCoursewareDetailId;
  740. // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
  741. // console.log(coursewareItem, 'coursewareItem', temporaryData);
  742. checkCourseware({
  743. ...coursewareItem,
  744. itemActive: coursewareDetailKnowledgeId
  745. });
  746. return;
  747. }
  748. }
  749. };
  750. /** 弹窗关闭 */
  751. const handleClosePopup = () => {
  752. // setModelOpen();
  753. };
  754. // popupData.activeIndex == 0 && styles.btnsDisabled
  755. // popupData.activeIndex == data.itemList.length - 1
  756. // 是否允许上一页
  757. const isUpArrow = computed(() => {
  758. /**
  759. * 1,判断当前课程中是否处在第一个资源;
  760. * 2,判断当前课程是否在当前章节的第一个;
  761. * 3,判断当前章节,当前课程上面还没有其它课程,是否有资源;
  762. * 4,判断当前章节上面还没有其它章节;
  763. * 5,判断上面章节里面课程是否有资源;
  764. */
  765. if (popupData.activeIndex > 0) {
  766. return true;
  767. }
  768. // 获取当前是哪个章节
  769. let detailIndex = data.courseDetails.findIndex(
  770. (item: any) => item.id == activeData.lessonCoursewareDetailId
  771. );
  772. const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
  773. let lessonIndex = detailItem.findIndex(
  774. (item: any) => item.id == activeData.coursewareDetailKnowledgeId
  775. );
  776. // 说明已经是第一单元,第一课
  777. if (detailIndex <= 0 && lessonIndex <= 0) {
  778. return false;
  779. }
  780. let lessonStatus = false; // 当前章节上面是否有内容
  781. while (lessonIndex >= 0) {
  782. lessonIndex--;
  783. if (lessonIndex >= 0) {
  784. if (detailItem[lessonIndex].containMaterial) {
  785. lessonStatus = true;
  786. }
  787. }
  788. }
  789. // 判断当前章节下面课程是否有内容,否则往上一个章节走
  790. if (lessonStatus) {
  791. return true;
  792. }
  793. // 已经是第一个章节了
  794. if (detailIndex <= 0) {
  795. return false;
  796. }
  797. let prevLessonStatus = false;
  798. while (detailIndex >= 0) {
  799. detailIndex--;
  800. const tempDetail = data.courseDetails[detailIndex]?.knowledgeList || [];
  801. let tempLessonLength = tempDetail.length;
  802. while (tempLessonLength > 0) {
  803. if (tempDetail[tempLessonLength - 1].containMaterial) {
  804. prevLessonStatus = true;
  805. }
  806. tempLessonLength--;
  807. }
  808. if (prevLessonStatus) {
  809. return true;
  810. }
  811. }
  812. return false;
  813. });
  814. // 是否允许下一页
  815. const isDownArrow = computed(() => {
  816. if (popupData.activeIndex < data.itemList.length - 1) {
  817. return true;
  818. }
  819. // 获取当前是哪个章节
  820. let detailIndex = data.courseDetails.findIndex(
  821. (item: any) => item.id == activeData.lessonCoursewareDetailId
  822. );
  823. const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
  824. let lessonIndex = detailItem.findIndex(
  825. (item: any) => item.id == activeData.coursewareDetailKnowledgeId
  826. );
  827. // 说明已经是最后-单元,最后一课
  828. if (
  829. detailIndex >= data.courseDetails.length - 1 &&
  830. lessonIndex >= detailItem.length - 1
  831. ) {
  832. return false;
  833. }
  834. let lessonStatus = false; // 当前章节下面是否有内容
  835. while (lessonIndex < detailItem.length - 1) {
  836. lessonIndex++;
  837. if (lessonIndex >= 0) {
  838. if (detailItem[lessonIndex].containMaterial) {
  839. lessonStatus = true;
  840. }
  841. }
  842. }
  843. // 判断当前章节下面课程是否有内容,否则往下一个章节走
  844. if (lessonStatus) {
  845. return true;
  846. }
  847. // 已经是最后一个章节了
  848. if (detailIndex >= data.courseDetails.length - 1) {
  849. return false;
  850. }
  851. let nextLessonStatus = false;
  852. while (detailIndex < data.courseDetails.length - 1) {
  853. detailIndex++;
  854. const tempDetail = data.courseDetails[detailIndex]?.knowledgeList || [];
  855. let tempLessonLength = 0;
  856. while (tempLessonLength <= tempDetail.length - 1) {
  857. if (tempDetail[tempLessonLength].containMaterial) {
  858. nextLessonStatus = true;
  859. }
  860. tempLessonLength++;
  861. }
  862. if (nextLessonStatus) {
  863. return true;
  864. }
  865. }
  866. return false;
  867. });
  868. const activeVideoItem = computed(() => {
  869. const item = data.itemList[popupData.activeIndex];
  870. if (item && item.type && item.type.toLocaleUpperCase() === 'VIDEO') {
  871. return item;
  872. }
  873. return {};
  874. });
  875. // 加载新的章节里的课件
  876. const loadNewCourseware = async (item: any) => {
  877. if (item.id === data.kjId) {
  878. showSelectCourseware.value = false;
  879. return;
  880. }
  881. if (debounceSkip.value) return;
  882. debounceSkip.value = true;
  883. data.itemList = [];
  884. loadingClass.value = true;
  885. // activeData.coursewareDetailKnowledgeId = item.coursewareDetailKnowledgeId;
  886. // activeData.lessonCoursewareDetailId = item.lessonCoursewareDetailId;
  887. if (route.query.tab == 'all' || route.query.tab == 'favorite') {
  888. activeData.coursewareDetailKnowledgeId =
  889. item.coursewareDetailKnowledgeId;
  890. activeData.lessonCoursewareDetailId = temporaryData.dyId;
  891. localStorage.setItem(lastTimeKey, item.coursewareDetailKnowledgeId);
  892. } else {
  893. activeData.lessonCoursewareDetailId = temporaryData.dyId;
  894. activeData.coursewareDetailKnowledgeId = temporaryData.zjId;
  895. localStorage.setItem(lastTimeKey, temporaryData.zjId);
  896. }
  897. // console.log(item, 'item', route.query.tab);
  898. // console.log(activeData, temporaryData, 'active');
  899. popupData.chapterOpen = false;
  900. showSelectCourseware.value = false;
  901. data.kjId = item.id;
  902. await getDetail();
  903. popupData.activeIndex = 0;
  904. popupData.itemActive = data.knowledgePointList[0].id;
  905. popupData.itemName = data.knowledgePointList[0].name;
  906. // 匹配到当前的章节名称
  907. const dyItem = data.courseDetails.find(
  908. (unit: any) => unit.id === activeData.lessonCoursewareDetailId
  909. );
  910. const zjItem = dyItem?.knowledgeList?.find(
  911. (chapter: any) => chapter.id === activeData.coursewareDetailKnowledgeId
  912. );
  913. zjItem && (popupData.itemPointName = zjItem.name);
  914. // console.log('章节名称', popupData.itemPointName);
  915. loadingClass.value = false;
  916. debounceSkip.value = false;
  917. };
  918. // 通过章节id,检测此章节有几个课件
  919. const checkCourseware = async (item: any, checkType?: any) => {
  920. // 如果有多个课件,需要选择一个课件进入上课页面
  921. if (item.coursewareNum || checkType) {
  922. try {
  923. if (checkType) {
  924. // @ts-ignore
  925. temporaryData.zjId = activeData.coursewareDetailKnowledgeId;
  926. // @ts-ignore
  927. temporaryData.dyId = activeData.lessonCoursewareDetailId;
  928. }
  929. const res =
  930. route.query.tab == 'all' || route.query.tab == 'favorite'
  931. ? await api_lessonDetailCourseware({
  932. lessonCoursewareKnowledgeDetailId: checkType
  933. ? activeData.coursewareDetailKnowledgeId
  934. : item.itemActive
  935. })
  936. : await api_classDetailCourseware({
  937. lessonCoursewareKnowledgeDetailId: checkType
  938. ? activeData.coursewareDetailKnowledgeId
  939. : item.itemActive
  940. });
  941. if (res?.code == 200 && res.data?.length) {
  942. data.coursewareList = res.data;
  943. // 如果只有一个课件,直接进入该课件
  944. // console.log(res.data, 'data');
  945. if (res.data.length == 1) {
  946. loadNewCourseware({ ...res.data[0] });
  947. } else {
  948. // 如果有多个课件,需要选择一个课件进入上课页面
  949. showSelectCourseware.value = true;
  950. }
  951. }
  952. } catch {
  953. //
  954. }
  955. }
  956. };
  957. watch(
  958. () => pageVisibility.value,
  959. async (val: any) => {
  960. console.log(val, 'pageVisibility.value -----');
  961. if (val === 'visible') {
  962. const userCash = await request.get('/edu-app/user/getUserInfo', {
  963. initRequest: true // 初始化接口
  964. });
  965. setLogin(userCash.data);
  966. console.log(userCash, 'userCash');
  967. const schoolInfos = userCash.data?.schoolInfos;
  968. const schoolLock =
  969. schoolInfos && schoolInfos.length > 0
  970. ? schoolInfos[0].needVipLock
  971. : true;
  972. if (!state?.user?.data.vipMember && schoolLock) {
  973. showMember.value = true;
  974. } else {
  975. showMember.value = false;
  976. }
  977. }
  978. }
  979. );
  980. return () => (
  981. <div id="playContent" class={styles.playContent}>
  982. <div
  983. class={styles.coursewarePlay}
  984. style={{ width: parentContainer.width }}
  985. onClick={() => setModelOpen()}>
  986. {!loadingClass.value && (
  987. <div class={styles.wraps}>
  988. <div
  989. style={
  990. activeVideoItem.value.type &&
  991. data.animationState === 'end' &&
  992. data.videoState === 'play'
  993. ? {
  994. zIndex: 15,
  995. opacity: 1
  996. }
  997. : { opacity: 0, zIndex: -1 }
  998. }
  999. class={styles.itemDiv}>
  1000. <VideoItem
  1001. ref={(el: any) => (data.videoItemRef = el)}
  1002. item={activeVideoItem.value}
  1003. showModel={activeData.model}
  1004. onClose={setModelOpen1}
  1005. onCanplay={() => {
  1006. data.videoState = 'play';
  1007. }}
  1008. onPause={() => {
  1009. clearTimeout(activeData.timer);
  1010. activeData.model = true;
  1011. }}
  1012. onEnded={() => {
  1013. // const _index = popupData.activeIndex + 1
  1014. // if (_index < data.itemList.length) {
  1015. // handleSwipeChange(_index);
  1016. // }
  1017. }}
  1018. />
  1019. </div>
  1020. {data.itemList.map((m: any, mIndex: number) => {
  1021. const isRender =
  1022. m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
  1023. const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
  1024. if (isRender) {
  1025. m.isRender = true;
  1026. }
  1027. return isRender ? (
  1028. <div
  1029. key={'index' + mIndex}
  1030. class={[
  1031. styles.itemDiv,
  1032. popupData.activeIndex === mIndex && styles.itemActive,
  1033. activeData.isAnimation && styles.acitveAnimation,
  1034. Math.abs(popupData.activeIndex - mIndex) < 2
  1035. ? styles.show
  1036. : styles.hide
  1037. ]}
  1038. style={
  1039. mIndex < popupData.activeIndex
  1040. ? effects[effectIndex.value].prev
  1041. : mIndex > popupData.activeIndex
  1042. ? effects[effectIndex.value].next
  1043. : {}
  1044. }
  1045. onClick={(e: Event) => {
  1046. if (Date.now() - activeData.nowTime < 300) {
  1047. handleDbClick(m);
  1048. return;
  1049. }
  1050. activeData.nowTime = Date.now();
  1051. }}>
  1052. {m.type === 'IMG' && <img src={m.content} />}
  1053. {m.type === 'PPT' && (
  1054. <iframe
  1055. src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
  1056. m.content
  1057. )}`}
  1058. width="100%"
  1059. height="100%"
  1060. frameborder="1"></iframe>
  1061. )}
  1062. {m.type === 'VIDEO' && (
  1063. <img
  1064. src={m.coverImg}
  1065. onLoad={() => {
  1066. m.isprepare = true;
  1067. }}
  1068. />
  1069. )}
  1070. {/* {m.type === 'VIDEO' && (
  1071. <VideoItem
  1072. ref={(v: any) => (data.videoRefs[mIndex] = v)}
  1073. item={m}
  1074. show={popupData.activeIndex === mIndex}
  1075. pageVisibility={pageVisibility.value}
  1076. showModel={activeData.model}
  1077. isEmtry={isEmtry}
  1078. onLoadedmetadata={() => {
  1079. m.isprepare = true;
  1080. m.error = false;
  1081. }}
  1082. onEnded={() => {
  1083. const _index = popupData.activeIndex + 1;
  1084. if (_index < data.itemList.length) {
  1085. handleSwipeChange(_index);
  1086. }
  1087. }}
  1088. onReset={() => {
  1089. m.error = false;
  1090. }}
  1091. onError={() => {
  1092. m.isprepare = true;
  1093. m.error = true;
  1094. }}
  1095. />
  1096. )} */}
  1097. {m.type === 'SONG' && (
  1098. <AudioItem
  1099. item={m}
  1100. show={popupData.activeIndex === mIndex}
  1101. pageVisibility={pageVisibility.value}
  1102. showModel={activeData.model}
  1103. isEmtry={isEmtry}
  1104. onEnded={() => {
  1105. const _index = popupData.activeIndex + 1;
  1106. if (_index < data.itemList.length) {
  1107. handleSwipeChange(_index);
  1108. }
  1109. }}
  1110. onClose={() => {
  1111. clearTimeout(activeData.timer);
  1112. activeData.timer = setTimeout(() => {
  1113. activeData.model = false;
  1114. }, 4000);
  1115. }}
  1116. />
  1117. )}
  1118. {m.type === 'MUSIC' && (
  1119. <MusicScore
  1120. pageVisibility={pageVisibility.value}
  1121. show={popupData.activeIndex === mIndex}
  1122. activeModel={activeData.model}
  1123. data-vid={m.id}
  1124. music={m}
  1125. />
  1126. )}
  1127. {m.type === 'VIDEO' && (
  1128. <Transition name="van-fade">
  1129. {/* {!m.isprepare && (
  1130. <div class={styles.loadWrap}>
  1131. <Vue3Lottie
  1132. style={{ width: '100%', height: '100%' }}
  1133. animationData={playLoadData}></Vue3Lottie>
  1134. </div>
  1135. )} */}
  1136. {data.videoState !== 'play' && (
  1137. <div class={styles.loadWrap}>
  1138. <Vue3Lottie
  1139. style={{ width: '100%', height: '100%' }}
  1140. animationData={playLoadData}></Vue3Lottie>
  1141. </div>
  1142. )}
  1143. </Transition>
  1144. )}
  1145. {/* 新增:RHYTHM:节奏练习,THEORY:乐理知识,MUSIC_WIKI:名曲鉴赏 INSTRUMENT:乐器 MUSICIAN:音乐家 资源类型 */}
  1146. {m.type === 'RHYTHM' && (
  1147. <TempoItem
  1148. key={mIndex}
  1149. class={styles.tempoPracticeGroup}
  1150. dataJson={m.dataJson}
  1151. show={popupData.activeIndex === mIndex}
  1152. pageVisibility={pageVisibility.value}
  1153. />
  1154. // <TempoPractice
  1155. // key={mIndex}
  1156. // class={styles.tempoPracticeGroup}
  1157. // dataJson={m?.dataJson ? JSON.parse(m?.dataJson) : {}}
  1158. // modeType={'courseware'}
  1159. // show={popupData.activeIndex === mIndex}
  1160. // />
  1161. )}
  1162. {m.type === 'THEORY' && <Theory id={m.bizId} />}
  1163. {/* {popupData.activeIndex === mIndex && ( */}
  1164. <>
  1165. {m.type === 'MUSIC_WIKI' && (
  1166. <InstrumentInfo
  1167. type={'wiki'}
  1168. id={m.bizId}
  1169. show={popupData.activeIndex === mIndex}
  1170. />
  1171. )}
  1172. {m.type === 'INSTRUMENT' && (
  1173. <InstrumentInfo
  1174. type={'instrument'}
  1175. id={m.bizId}
  1176. show={popupData.activeIndex === mIndex}
  1177. />
  1178. )}
  1179. {m.type === 'MUSICIAN' && (
  1180. <InstrumentInfo
  1181. type={'musician'}
  1182. id={m.bizId}
  1183. show={popupData.activeIndex === mIndex}
  1184. />
  1185. )}
  1186. {m.type === 'LISTEN' && (
  1187. <ListenItem
  1188. pageVisibility={pageVisibility.value}
  1189. show={popupData.activeIndex === mIndex}
  1190. activeModel={activeData.model}
  1191. data-vid={m.id}
  1192. item={m}
  1193. />
  1194. )}
  1195. </>
  1196. {/* )} */}
  1197. </div>
  1198. ) : (
  1199. <div
  1200. key={'index' + mIndex}
  1201. class={[
  1202. styles.itemDiv,
  1203. popupData.activeIndex === mIndex && styles.itemActive,
  1204. activeData.isAnimation && styles.acitveAnimation,
  1205. Math.abs(popupData.activeIndex - mIndex) < 2
  1206. ? styles.show
  1207. : styles.hide
  1208. ]}
  1209. style={
  1210. mIndex < popupData.activeIndex
  1211. ? effects[effectIndex.value].prev
  1212. : mIndex > popupData.activeIndex
  1213. ? effects[effectIndex.value].next
  1214. : {}
  1215. }></div>
  1216. );
  1217. })}
  1218. </div>
  1219. )}
  1220. <Transition name="right">
  1221. {activeData.model && (
  1222. <div
  1223. class={styles.rightFixedBtns}
  1224. onClick={(e: Event) => {
  1225. e.stopPropagation();
  1226. clearTimeout(activeData.timer);
  1227. }}>
  1228. <div
  1229. class={[styles.fullBtn, styles.point]}
  1230. onClick={() => (popupData.chapterOpen = true)}>
  1231. <img src={iconChange} />
  1232. <span>切换</span>
  1233. </div>
  1234. <div
  1235. class={[styles.fullBtn, styles.point]}
  1236. onClick={() => (popupData.open = true)}>
  1237. <img src={iconMenu} />
  1238. <span>课件</span>
  1239. </div>
  1240. <div
  1241. class={[
  1242. styles.fullBtn,
  1243. // popupData.activeIndex == 0 && styles.btnsDisabled
  1244. !isUpArrow.value && styles.btnsDisabled
  1245. ]}
  1246. onClick={() => handlePreAndNext('up')}>
  1247. <img src={iconUp} />
  1248. <span style={{ textAlign: 'center' }}>上一个</span>
  1249. </div>
  1250. <div
  1251. class={[
  1252. styles.fullBtn,
  1253. !isDownArrow.value && styles.btnsDisabled
  1254. ]}
  1255. onClick={() => handlePreAndNext('down')}>
  1256. <span style={{ textAlign: 'center' }}>下一个</span>
  1257. <img src={iconDown} />
  1258. </div>
  1259. </div>
  1260. )}
  1261. </Transition>
  1262. </div>
  1263. <div
  1264. style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
  1265. class={styles.headerContainer}
  1266. ref={headeRef}>
  1267. <div class={styles.backBtn} onClick={() => goback()}>
  1268. <Icon name={iconBack} />
  1269. 返回
  1270. </div>
  1271. <div class={styles.menu}>{popupData.itemName}</div>
  1272. </div>
  1273. {/* 课件列表 */}
  1274. <Popup
  1275. class={styles.popup}
  1276. style={{ background: 'rgba(0,0,0, 0.75)' }}
  1277. overlayClass={styles.overlayClass}
  1278. position="right"
  1279. round
  1280. v-model:show={popupData.open}
  1281. onClose={handleClosePopup}>
  1282. <Points
  1283. allList={data.allList}
  1284. currentCourse={data.currentCourse}
  1285. data={data.knowledgePointList}
  1286. itemActive={popupData.itemActive}
  1287. itemName={popupData.itemPointName}
  1288. kjId={data.kjId}
  1289. zsdId={data.zsdId}
  1290. popShow={popupData.open}
  1291. onHandleSelect={(res: any) => {
  1292. popupData.open = false;
  1293. toggleMaterial(res.itemActive, res.zsdId, res.kjId);
  1294. }}
  1295. onCourseSelect={async () => {
  1296. popupData.open = false;
  1297. checkCourseware({}, 'same');
  1298. }}
  1299. />
  1300. </Popup>
  1301. {/* 知识点列表 */}
  1302. <Popup
  1303. class={styles.popup}
  1304. style={{ background: 'rgba(0,0,0, 0.75)' }}
  1305. overlayClass={styles.overlayClass}
  1306. position="right"
  1307. round
  1308. v-model:show={popupData.chapterOpen}
  1309. onClose={handleClosePopup}>
  1310. <Chapter
  1311. detail={data.courseDetails}
  1312. itemActive={activeData.coursewareDetailKnowledgeId as any}
  1313. active={activeData.lessonCoursewareDetailId as any}
  1314. popShow={popupData.chapterOpen}
  1315. onHandleSelect={async (item: any) => {
  1316. temporaryData.dyId = item.tabActive;
  1317. temporaryData.zjId = item.itemActive;
  1318. popupData.itemPointName = item.itemName;
  1319. checkCourseware(item);
  1320. }}
  1321. />
  1322. </Popup>
  1323. {showSelectCourseware.value && (
  1324. <SelectCoursewarePop
  1325. list={data.coursewareList}
  1326. kjId={data.kjId}
  1327. onClose={() => {
  1328. showSelectCourseware.value = false;
  1329. }}
  1330. onSelect={item => loadNewCourseware(item)}></SelectCoursewarePop>
  1331. )}
  1332. {showMember.value && (
  1333. <SelectCoursewareMember
  1334. onClose={() => {
  1335. showSelectCourseware.value = false;
  1336. }}></SelectCoursewareMember>
  1337. )}
  1338. </div>
  1339. );
  1340. }
  1341. });