123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- import request from '@/helpers/request';
- import { state } from '@/state';
- import {
- Button,
- Cell,
- CellGroup,
- Popup,
- showConfirmDialog,
- showLoadingToast
- } from 'vant';
- import {
- defineComponent,
- onMounted,
- reactive,
- onUnmounted,
- TransitionGroup,
- computed
- } from 'vue';
- import styles from './index.module.less';
- import { useRoute, useRouter } from 'vue-router';
- import {
- listenerMessage,
- postMessage,
- removeListenerMessage
- } from '@/helpers/native-message';
- // import iconLook from './image/look.svg'
- import iconCourse from './image/icon-course.png';
- import iconCachePoint from './image/icon-cache-point.png';
- // import iconCourseLock from './image/icon-course-lock.png';
- // import iconTip from './image/iconTip.png';
- import { browser } from '@/helpers/utils';
- import OEmpty from '@/components/o-empty';
- import { handleCheckVip, gotoMemberCenter, hasVip } from '../hook/useFee';
- import iconList from './image/icon-list.png';
- // import OSticky from '@/components/o-sticky';
- import OHeader from '@/components/o-header';
- import { useEventListener } from '@vant/use';
- import OLoading from '@/components/o-loading';
- import OSticky from '@/components/o-sticky';
- export default defineComponent({
- name: 'courseList',
- setup() {
- const route = useRoute();
- const router = useRouter();
- const browserInfo = browser();
- const data = reactive({
- titleOpacity: 0,
- catchStatus: false,
- catchItem: {} as any,
- loading: true,
- detail: {
- cover: '',
- name: '',
- des: ''
- },
- list: [] as any,
- isDownloading: false // 是否在下载资源
- });
- /** 获取课件详情 */
- const getDetail = async () => {
- const res: any = await request.get(
- `${state.platformApi}/lessonCourseware/getLessonCoursewareDetail/${route.query.id}`
- );
- if (res?.data) {
- data.detail.cover = res.data.coverImg;
- data.detail.name = res.data.name;
- data.detail.des = res.data.lessonTargetDesc;
- }
- };
- const getList = async () => {
- data.loading = true;
- try {
- const res: any = await request.get(
- state.platformApi +
- '/lessonCourseware/getLessonCoursewareCourseList/' +
- route.query.id
- );
- if (Array.isArray(res?.data)) {
- data.list = res.data;
- res.data.forEach((item: any) => {
- const { knowledgePointList, ...res } = item;
- const tempK = knowledgePointList || [];
- tempK.forEach((child: any) => {
- child.materialList = [
- ...(child.materialList || []),
- ...getKnowledgeMaterials(child.children || [])
- ];
- child.children = null;
- });
- });
- // 由于ios没有对应api
- const _list = await checkCoursewareCache(res.data);
- data.list = browserInfo.isApp
- ? res.data.map((item: any) => {
- const _item = _list.find(
- (n: any) =>
- n.lessonCoursewareDetailId == item.lessonCoursewareDetailId
- );
- const n = {
- ...item
- };
- if (_item) {
- n.hasCache = _item.hasCache;
- }
- return n;
- })
- : res.data;
- }
- } catch (error) {
- //
- }
- data.loading = false;
- };
- // 获取子节点数据
- const getKnowledgeMaterials = (list: any = []) => {
- const tempList: any = [];
- list.forEach((item: any) => {
- if (item.materialList && item.materialList.length > 0) {
- tempList.push(...(item.materialList || []));
- }
- if (item.children && item.children.length > 0) {
- tempList.push(...getKnowledgeMaterials(item.children || []));
- }
- });
- return tempList;
- };
- // 去购买
- const onGoVip = () => {
- // window.location.href = location.origin + '/#/member';
- };
- onMounted(() => {
- getDetail();
- getList();
- listenerMessage('downloadCoursewareToCache', getProgress);
- });
- onUnmounted(() => {
- removeListenerMessage('downloadCoursewareToCache', getProgress);
- });
- const handleClick = async (item: any) => {
- if (!item.knowledgePointList) {
- showConfirmDialog({
- message: '该课件暂无知识点'
- });
- return;
- }
- const isVip = handleCheckVip();
- if (!isVip) return;
- if (!item.hasCache) {
- // const hasFree = String(item.accessScope) === '0';
- // if (!hasFree) {
- // 下载中不提示
- if (item.downloadStatus == 1) {
- // 取消下载
- postMessage({ api: 'cancelDownloadCourseware' });
- setTimeout(() => {
- postMessage({ api: 'cancelDownloadCourseware' });
- item.downloadStatus = 0;
- data.isDownloading = false;
- }, 1000);
- showLoadingToast({
- message: '取消中...',
- forbidClick: false,
- loadingType: 'spinner',
- duration: 1000
- });
- return;
- }
- // 重新下载
- if (item.downloadStatus == 3) {
- downCatch(item);
- return;
- }
- data.catchStatus = true;
- data.catchItem = item;
- return;
- }
- gotoPlay(item);
- };
- // 去课件播放
- const gotoPlay = (item: any) => {
- data.catchStatus = false;
- if (browser().isApp) {
- postMessage({
- api: 'openWebView',
- content: {
- url: `${location.origin}${location.pathname}#/coursewarePlay?id=${item.coursewareDetailId}&source=my-course`,
- orientation: 0,
- isHideTitle: true,
- statusBarTextColor: false,
- isOpenLight: true,
- showLoadingAnim: true
- }
- });
- } else {
- router.push({
- path: '/coursewarePlay',
- query: {
- id: item.coursewareDetailId,
- source: 'my-course'
- }
- });
- }
- };
- // 检查数据的缓存状态
- const checkCoursewareCache = (list: []): Promise<any[]> => {
- if (!browser().isApp) {
- return Promise.resolve(list);
- }
- return new Promise(resolve => {
- postMessage(
- {
- api: 'checkCoursewareCache',
- content: {
- data: list
- }
- },
- res => {
- if (res?.content?.data) {
- resolve(res.content.data);
- return;
- }
- return [];
- }
- );
- });
- };
- // 下载缓存
- const downCatch = async (item: any) => {
- if (browserInfo.isApp) {
- data.catchStatus = false;
- data.isDownloading = true;
- const res = await postMessage({
- api: 'downloadCoursewareToCache',
- content: {
- data: item
- }
- });
- return res;
- }
- return true;
- };
- // 下载缓存进度
- const getProgress = (res: any) => {
- // console.log('🚀 ~ res', res)
- if (!data.isDownloading) {
- return;
- }
- if (res?.content?.lessonCoursewareDetailId) {
- const { lessonCoursewareDetailId, downloadStatus, progress } =
- res.content;
- const course = data.list.find(
- (n: any) => n.lessonCoursewareDetailId == lessonCoursewareDetailId
- );
- if (course) {
- course.downloadStatus = downloadStatus;
- course.progress = progress;
- if (downloadStatus == 2) {
- course.hasCache = 1;
- course.progress = 100;
- // 下载完成
- data.isDownloading = false;
- }
- }
- }
- };
- useEventListener('scroll', () => {
- const height =
- window.scrollY ||
- window.pageYOffset ||
- document.documentElement.scrollTop;
- data.titleOpacity = height > 100 ? 1 : height / 100;
- });
- return () => (
- <div class={styles.courseList}>
- <OHeader
- border={false}
- background={`rgba(255,255,255, ${data.titleOpacity})`}
- title="教材详情"
- />
- <div class={styles.periodContent}>
- <div class={styles.cover}>
- <img
- src={data.detail.cover}
- onLoad={(e: Event) => {
- if (e.target) {
- (e.target as any).style.opacity = 1;
- }
- }}
- />
- </div>
- <div>
- <div class={styles.contentTitle}>{data.detail.name}</div>
- <div class={styles.contentLabel}>教学目标:{data.detail.des}</div>
- </div>
- </div>
- <TransitionGroup name="van-fade">
- {!data.loading && (
- <>
- <div key="periodTitle" class={styles.periodTitle}>
- <img class={styles.pIcon} src={iconList} />
- <div class={styles.pTitle}>课程列表</div>
- <div class={styles.pNum}>共{data.list.length}课</div>
- </div>
- <div key="list" class={styles.periodList}>
- <CellGroup inset>
- {data.list.map((item: any) => {
- // const isLock =
- // item.lockFlag ||
- // ((route.query.code == 'select' ||
- // state.platformType == 'STUDENT') &&
- // !item.unlock);
- // const isSelect = route.query.code === 'select';
- return (
- <Cell
- border
- center
- title={item.coursewareDetailName}
- // label={
- // !browserInfo.isStudent
- // ? `已使用${item.useNum || 0}次`
- // : ''
- // }
- onClick={() => handleClick(item)}>
- {{
- icon: () => (
- <div class={styles.periodItem}>
- <div class={styles.periodItemModel}>
- <img src={iconCourse} />
- {item.hasCache ? (
- <img
- class={styles.iconCachePoint}
- src={iconCachePoint}
- />
- ) : (
- ''
- )}
- {item.downloadStatus === 1 && (
- <div class={styles.downloading}>{`${
- item.progress || 0
- }%`}</div>
- )}
- </div>
- </div>
- ),
- value: () => (
- <>
- {item.knowledgePointList ? (
- <>
- {item.hasCache ? (
- <Button
- class={[
- styles.baseBtn,
- styles.look,
- state.platformType === 'STUDENT' &&
- !hasVip()
- ? styles.disabled
- : ''
- ]}>
- 查看
- </Button>
- ) : (
- <Button
- class={[
- styles.baseBtn,
- styles.down,
- state.platformType === 'STUDENT' &&
- !hasVip()
- ? styles.disabled
- : '',
- item.downloadStatus == 1
- ? styles.downing
- : ''
- ]}>
- {item.downloadStatus === 1
- ? `取消下载`
- : '查看'}
- </Button>
- )}
- </>
- ) : (
- ''
- )}
- </>
- )
- }}
- </Cell>
- );
- })}
- </CellGroup>
- </div>
- </>
- )}
- </TransitionGroup>
- {data.loading && <OLoading />}
- {!data.loading && !data.list.length && <OEmpty tips="暂无内容" />}
- {state.platformType === 'STUDENT' && !hasVip() && (
- <OSticky position="bottom">
- <div class={styles.btnGroup}>
- <Button round block type="primary" onClick={gotoMemberCenter}>
- 开通会员即可查看所有课件
- </Button>
- </div>
- </OSticky>
- )}
- <Popup
- v-model:show={data.catchStatus}
- round
- class={styles.courseDialog}>
- <i
- class={styles.iconClose}
- onClick={() => (data.catchStatus = false)}></i>
- <div class={styles.title}>下载提醒</div>
- <div class={styles.content}>
- 您尚未下载课件内容,为了更加流畅的学习体验,推荐您下载后观看课件。
- </div>
- <div class={styles.popupBtnGroup}>
- <Button round onClick={() => gotoPlay(data.catchItem)}>
- 直接观看
- </Button>
- <Button
- round
- type="primary"
- onClick={() => downCatch(data.catchItem)}>
- 下载课件
- </Button>
- </div>
- </Popup>
- </div>
- );
- }
- });
|