index.tsx 49 KB

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