index.tsx 49 KB

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