123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- import {
- PropType,
- defineComponent,
- nextTick,
- onMounted,
- reactive,
- watch,
- ref
- } from 'vue';
- import styles from './index.module.less';
- import icon_back from '../../image/icon_back.svg';
- import icon_play from '../../image/icon_class.png';
- import pre from '../../image/pre.png';
- import { useRouter } from 'vue-router';
- import { listenerMessage, postMessage } from '@/helpers/native-message';
- import { showToast } from 'vant';
- import queryString from 'query-string';
- import CoursewareDetail from '@/custom-plugins/guide-page/courseware-detail';
- import { usePageVisibility } from '@vant/use';
- import { state } from '@/state';
- import TheNoticeBar from '@/components/the-noticeBar';
- import {
- api_lessonDetailCourseware,
- api_classDetailCourseware
- } from '../../api';
- import SelectCoursewarePop from '@/components/select-courseware-pop';
- export default defineComponent({
- name: 'the-book',
- props: {
- bookData: {
- type: Object as PropType<any>,
- default: () => ({})
- },
- tab: {
- type: String,
- default: ''
- },
- show: {
- type: Boolean,
- default: false
- },
- rect: {
- type: Object as PropType<DOMRect>,
- default: () => ({})
- },
- subjectId: {
- type: [String, Number],
- default: ''
- }
- },
- emits: ['close'],
- setup(props, { emit }) {
- const router = useRouter();
- console.log(state.user.data.phone);
- const lastTimeKey = 'lastTime' + (state?.user?.data?.phone ?? '');
- const debounceSkip = ref(false);
- const data = reactive({
- show: false,
- width: 0,
- height: 0,
- transform: '',
- list: [] as any[][],
- lastTime: localStorage.getItem(lastTimeKey),
- isClick: false,
- coursewareList: [] as any
- });
- const showSelectCourseware = ref(false);
- const showGuide = ref(false);
- const isend = ref(false);
- const step = ref(0);
- const CoursewareDetailRef = ref();
- const handleCreate = (key: string, url: string) => {
- return new Promise((resolve, reject) => {
- const _s = document.head.querySelector(`script[data-key="${key}"]`);
- if (!_s) {
- const s = document.createElement('script');
- s.setAttribute('data-key', key);
- s.src = url;
- s.onload = async () => {
- console.log(key + ' 加载完成');
- resolve(1);
- };
- document.head.appendChild(s);
- }
- });
- };
- const init = async () => {
- // await handleCreate('jquery', '/book/jquery.min.1.7.js');
- // await handleCreate('turn', '/book/turn.js');
- console.log('初始化完成');
- };
- const isFirest = ref(true);
- let book: any = null;
- let timer: any = null;
- const handleBook = () => {
- book = (window as any).$('#flipbook');
- const height = document.body.clientHeight * 0.8;
- data.height = height;
- data.width = height * (210 / 297) * 2;
- book.turn({
- autoCenter: true,
- duration: 1000,
- disabled: true,
- acceleration: true, // 是否启动硬件加速 如果为触摸设备必须为true
- // pages: 11, // 页码总数
- elevation: 50, // 转换期间页面的高度
- width: data.width, // 宽度 单位 px
- height: data.height, // 高度 单位 px
- gradients: true // 是否显示翻页阴影效果
- // display: 'single', //设置单页还是双页
- });
- book.bind('start', (event: Event, pageObject: any, corner: any) => {
- // console.log(event, 'last', pageObject.next)
- // if (isFirest.value) {
- // console.log('第一次进来禁用', pageObject)
- // isFirest.value = false
- // book.turn('disabled', true);
- // }
- if (corner == 'tl' || corner == 'tr') {
- event.preventDefault();
- }
- if (data.isClick) {
- nextTick(() => {
- data.isClick = false;
- if (corner == 'tl' || corner == 'tr') {
- event.preventDefault();
- } else {
- book.turn('page', pageObject.next);
- }
- });
- }
- });
- book.bind('turned', (event: Event, page: any, corner: any) => {
- // setTimeout(() => {
- // }, 1000);
- // console.log(page - 1, 'page')
- // const index = (page - 1)
- // console.log(data.list[index * step.value], data.list)
- nextTick(() => {
- showGuide.value = true;
- });
- // if (page + 1 === book.turn('pages')) {
- // // noanimateClose()
- // handleClose()
- // // nextTick(() => {
- // // });
- // }
- });
- book.bind('turning', (event: Event, page: any, corner: any) => {
- // console.log(page, 'page', book.turn('pages'))
- if (page === book.turn('pages')) {
- handleClose(false);
- // handleClose()
- // nextTick(() => {
- // });
- }
- if (page === 1) {
- handleClose(false);
- }
- return;
- });
- // book.bind('turned', (e: any, page: any) => {
- };
- const getRect = () => {
- const bookWrap = document.querySelector(
- '.bookWrap'
- ) as unknown as HTMLElement;
- if (bookWrap) {
- const rect = bookWrap.getBoundingClientRect();
- const xScale = props.rect.width / (rect.width / 2);
- const yScale = props.rect.height / rect.height;
- const left =
- (((rect.width / 2) * (xScale - 1)) / 2 +
- props.rect.x -
- rect.x -
- rect.width / 4) /
- xScale;
- const top =
- ((rect.height * (yScale - 1)) / 2 + props.rect.y - rect.y) / yScale;
- const transform = `scale3d(${xScale}, ${yScale}, 1) translate(${left}px, ${top}px)`;
- bookWrap.style.transform = data.transform = transform;
- bookWrap.style.transition = 'transform 0s';
- nextTick(() => {
- requestAnimationFrame(() => {
- requestAnimationFrame(() => {
- bookWrap.style.transition = 'transform 1s';
- bookWrap.style.transform = '';
- data.show = true;
- timer = setTimeout(() => {
- book.turn('page', 2);
- }, 500);
- });
- });
- });
- }
- };
- const handleClose = (gotoOne = true) => {
- showGuide.value = false;
- // book.turn('disabled', false);
- if (isend.value) {
- return;
- }
- isend.value = true;
- clearTimeout(timer);
- const bookWrap = document.querySelector(
- '.bookWrap'
- ) as unknown as HTMLElement;
- if (gotoOne) {
- book.turn('page', 1);
- }
- if (bookWrap) {
- bookWrap.style.transform = data.transform;
- }
- emit('close');
- setTimeout(() => {
- bookWrap.style.transition = '';
- bookWrap.style.transform = '';
- data.show = false;
- data.list = [];
- isend.value = false;
- }, 1000);
- };
- onMounted(async () => {
- await init();
- listenerMessage('webViewOnResume', () => {
- data.lastTime = localStorage.getItem(lastTimeKey);
- });
- });
- const getList = () => {
- if (!props.bookData?.lessonList) return;
- step.value = Math.floor((document.body.clientHeight * 0.8 - 40) / 50);
- const list = [];
- let listItem = [] as any[];
- for (let i = 0; i < props.bookData.lessonList.length; i++) {
- const item = props.bookData.lessonList[i];
- if (listItem.length >= step.value) {
- list.push([...listItem]);
- listItem = [{ name: item.name }];
- } else {
- listItem.push({ name: item.name });
- }
- for (let j = 0; j < item.knowledgeList.length; j++) {
- if (listItem.length >= step.value) {
- list.push([...listItem]);
- listItem = [item.knowledgeList[j]];
- } else {
- listItem.push(item.knowledgeList[j]);
- }
- }
- }
- if (listItem.length) {
- list.push(listItem);
- }
- data.list = list;
- // console.log('🚀 ~ data.list:', data.list.length);
- // console.log(book.turn.pages, 'book.turn.pages')
- // console.log(book.turn('pages'), 'pages')
- };
- watch(
- () => props.show,
- () => {
- if (props.show) {
- getList();
- nextTick(() => {
- handleBook();
- requestAnimationFrame(() => {
- getRect();
- });
- });
- }
- }
- );
- // 检测有几个课件
- const checkCourseware = async (item: any) => {
- if (item.id) {
- if (!item.containMaterial) {
- showToast('暂无资源');
- return;
- }
- if (item.coursewareNum) {
- try {
- const res =
- props.tab == 'all'
- ? await api_lessonDetailCourseware({
- lessonCoursewareKnowledgeDetailId: item.id
- })
- : await api_classDetailCourseware({
- lessonCoursewareKnowledgeDetailId: item.id
- });
- if (res?.code == 200 && res.data?.length) {
- // console.log(res.data)
- res.data.forEach((n: any) => {
- n.coursewareDetailKnowledgeId =
- n.coursewareDetailKnowledgeId || item.id;
- n.lessonCoursewareId = item.lessonCoursewareId;
- n.lessonCoursewareDetailId = item.lessonCoursewareDetailId;
- n.zjName = item.name; // 章节name
- });
- data.coursewareList = res.data;
- // 如果只有一个课件,直接进入该课件
- if (res.data.length == 1) {
- handleOpenPlay(res.data[0]);
- } else {
- // 如果有多个课件,需要选择一个课件进入上课页面
- showSelectCourseware.value = true;
- }
- }
- } catch {
- //
- }
- }
- }
- };
- const handleOpenPlay = async (item: any) => {
- if (item.id) {
- if( debounceSkip.value ) return;
- debounceSkip.value = true;
- localStorage.setItem(lastTimeKey, item.id);
- const query = queryString.stringify({
- id: item.id, // 课件id
- lessonCoursewareId: item.lessonCoursewareId,
- courseId: props.bookData.id,
- lessonCoursewareDetailId: item.lessonCoursewareDetailId,
- name: item.zjName,
- subjectId: props.subjectId,
- tab: props.tab, // 当前切换的是哪个类型
- coursewareDetailKnowledgeId: item.coursewareDetailKnowledgeId // 章节id
- });
- const url =
- location.origin + location.pathname + '#/courseware-play?' + query;
- console.log('🚀 ~ url:', url);
- debounceSkip.value = false;
- postMessage({
- api: 'openWebView',
- content: {
- url,
- orientation: 0,
- isHideTitle: false,
- c_orientation: 0 // 0 横屏 1 竖屏
- }
- });
- router.push({
- path: '/courseware-play',
- query: {
- id: item.id,
- subjectId: props.subjectId,
- lessonCoursewareId: item.lessonCoursewareId,
- courseId: props.bookData.id,
- lessonCoursewareDetailId: item.lessonCoursewareDetailId,
- name: item.zjName,
- tab: props.tab,
- coursewareDetailKnowledgeId: item.coursewareDetailKnowledgeId
- }
- });
- }
- };
- const isStartAnimate = (item: any) => {
- // console.log(item) item.name.length > 9 ? true :
- return false;
- };
- const changeShowGuide = (flag: boolean) => {
- showGuide.value = flag;
- if (flag) {
- console.log('changeShowGuide禁用');
- // book.turn('disabled', true);
- } else {
- console.log('changeShowGuide取消禁用');
- // book.turn('disabled', false);
- }
- };
- return () => (
- <div
- class={[styles.book, data.show ? '' : styles.bookHide]}
- onClick={() => handleClose()}
- onTouchmove={() => {
- console.log('sdfds');
- data.isClick = true;
- }}>
- <div class={styles.back}>
- <img src={icon_back} />
- </div>
- <div
- class="bookWrap"
- style={{ width: data.width + 'px' }}
- onClick={(e: Event) => {
- e.stopPropagation();
- }}>
- {!!data.list.length && (
- <div id="flipbook" class={[data.show && 'animated']}>
- <div class="page">
- <img
- style="width: 100%; height: 100%; object-fit: cover;"
- src={props.bookData.coverImg}
- />
- </div>
- {data.list.map((list: any) => {
- return (
- <div class="page">
- <div class={styles.wrap}>
- <div class={styles.wrapItem}>
- {list.map((item: any, index: number) => {
- return (
- <>
- <div
- class={[styles.item, item.id && styles.des]}
- onTouchstart={(e: TouchEvent) => {
- e.stopPropagation();
- }}
- onClick={(e: Event) => {
- e.stopPropagation();
- checkCourseware(item);
- }}
- onTouchend={(e: TouchEvent) => {
- console.log(e);
- }}>
- {item.id ? (
- <img
- id={index == 1 ? 'coursewareDetail-0' : ''}
- class={styles.icon}
- src={icon_play}
- />
- ) : null}
- <div
- class={styles.name}
- style={{ lineHeight: '20Px' }}>
- {data.lastTime === item.id && (
- <img
- src={pre}
- alt=""
- class={styles.preIcon}
- />
- )}
- <div class={styles.nameText}>
- {' '}
- {item.name}
- </div>
- {/* <TheNoticeBar text={item.name} isAnimation={isStartAnimate(item)}></TheNoticeBar> */}
- </div>
- </div>
- </>
- );
- })}
- </div>
- </div>
- </div>
- );
- })}
- {data.list.length % 2 === 1 && (
- <div class="page" style={{ pointerEvents: 'none' }}>
- <div class={styles.wrap}>
- <div class={styles.wrapItem}></div>
- </div>
- </div>
- )}
- <div class="page">
- <img
- style="width: 100%; height: 100%; object-fit: cover;"
- src={props.bookData.coverImg}
- />
- {/* <div class={styles.wrap}>
- <div
- class={styles.wrapItem}
- style={{ backgroundColor: '#fff' }}></div>
- </div> */}
- </div>
- </div>
- )}
- </div>
- {/* {showGuide.value ? <CoursewareDetail onChangeShowGuide={changeShowGuide} ref={CoursewareDetailRef}></CoursewareDetail> : null} */}
- {showSelectCourseware.value && (
- <SelectCoursewarePop
- list={data.coursewareList}
- onClose={() => {
- showSelectCourseware.value = false;
- }}
- onSelect={item => handleOpenPlay(item)}></SelectCoursewarePop>
- )}
- </div>
- );
- }
- });
|