|
@@ -0,0 +1,284 @@
|
|
|
+import { NButton } from 'naive-ui';
|
|
|
+import {
|
|
|
+ defineComponent,
|
|
|
+ nextTick,
|
|
|
+ onMounted,
|
|
|
+ onUnmounted,
|
|
|
+ reactive,
|
|
|
+ ref,
|
|
|
+ watch
|
|
|
+} from 'vue';
|
|
|
+import styles from './index.module.less';
|
|
|
+import { getImage } from './images';
|
|
|
+import { eventGlobal, px2vw, px2vwH } from '@/utils/index';
|
|
|
+import { getGuidance, setGuidance } from './api';
|
|
|
+export default defineComponent({
|
|
|
+ name: 'lessons-guide',
|
|
|
+ emits: ['close'],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const data = reactive({
|
|
|
+ box: {
|
|
|
+ height: '0px'
|
|
|
+ } as any,
|
|
|
+ show: false,
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ width: px2vw(840),
|
|
|
+ height: px2vw(295)
|
|
|
+ */
|
|
|
+ steps: [
|
|
|
+ {
|
|
|
+ ele: '',
|
|
|
+ img: getImage('lessons2.png'),
|
|
|
+ imgStyle: {
|
|
|
+ left: px2vw(-647),
|
|
|
+ width: px2vw(647),
|
|
|
+ height: px2vw(223)
|
|
|
+ },
|
|
|
+ btnsStyle: {
|
|
|
+ bottom: '30px',
|
|
|
+ left: px2vw(-488)
|
|
|
+ },
|
|
|
+
|
|
|
+ eleRectPadding: {
|
|
|
+ left: 7,
|
|
|
+ top: 7,
|
|
|
+ width: 14,
|
|
|
+ height: 14
|
|
|
+ },
|
|
|
+ type: 'left'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ ele: '',
|
|
|
+ img: getImage('lessons3.png'),
|
|
|
+ imgStyle: {
|
|
|
+ top: px2vw(-4),
|
|
|
+ left: px2vw(-471),
|
|
|
+ width: px2vw(471),
|
|
|
+ height: px2vw(223)
|
|
|
+ },
|
|
|
+ btnsStyle: {
|
|
|
+ bottom: px2vw(20),
|
|
|
+ left: px2vw(-310)
|
|
|
+ },
|
|
|
+
|
|
|
+ eleRectPadding: {
|
|
|
+ left: 7,
|
|
|
+ top: 7,
|
|
|
+ width: 14,
|
|
|
+ height: 14
|
|
|
+ },
|
|
|
+ type: 'left'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ step: 0
|
|
|
+ });
|
|
|
+ const tipShow = ref(false);
|
|
|
+ const guideInfo = ref({} as any);
|
|
|
+ const getAllGuidance = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getGuidance({ guideTag: 'teacher-guideInfo' });
|
|
|
+ if (res.data) {
|
|
|
+ guideInfo.value = JSON.parse(res.data?.guideValue) || null;
|
|
|
+ } else {
|
|
|
+ guideInfo.value = {};
|
|
|
+ }
|
|
|
+ if (guideInfo.value && guideInfo.value.lessonsGuideIn) {
|
|
|
+ tipShow.value = false;
|
|
|
+ } else {
|
|
|
+ tipShow.value = true;
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ // const guideInfo = localStorage.getItem('teacher-guideInfo');
|
|
|
+ };
|
|
|
+
|
|
|
+ getAllGuidance();
|
|
|
+ // const guideInfo = localStorage.getItem('teacher-guideInfo');
|
|
|
+ // if (guideInfo && JSON.parse(guideInfo).lessonsGuideIn) {
|
|
|
+ // tipShow.value = false;
|
|
|
+ // } else {
|
|
|
+ // tipShow.value = true;
|
|
|
+ // }
|
|
|
+ const getStepELe = () => {
|
|
|
+ const ele: HTMLElement = document.getElementById(
|
|
|
+ `lessonsIn-${data.step}`
|
|
|
+ )!;
|
|
|
+ if (ele) {
|
|
|
+ const eleRect = ele.getBoundingClientRect();
|
|
|
+
|
|
|
+ const left = data.steps[data.step].eleRectPadding?.left || 0;
|
|
|
+ const top = data.steps[data.step].eleRectPadding?.top || 0;
|
|
|
+ const width = data.steps[data.step].eleRectPadding?.width || 0;
|
|
|
+ const height = data.steps[data.step].eleRectPadding?.height || 0;
|
|
|
+ data.box = {
|
|
|
+ left: eleRect.x - left + 'px',
|
|
|
+ top: eleRect.y - top + 'px',
|
|
|
+ width: eleRect.width + width + 'px',
|
|
|
+ height: eleRect.height + height + 'px'
|
|
|
+ };
|
|
|
+ // console.log(`coai-${data.step}`, data.box);
|
|
|
+ } else {
|
|
|
+ handleNext();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const onResetGuide = async (name: string) => {
|
|
|
+ try {
|
|
|
+ if (name !== 'prepare-lessons') return;
|
|
|
+ if (!guideInfo.value) {
|
|
|
+ guideInfo.value = { lessonsGuideIn: false };
|
|
|
+ } else {
|
|
|
+ guideInfo.value.lessonsGuideIn = false;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ await setGuidance({
|
|
|
+ guideTag: 'teacher-guideInfo',
|
|
|
+ guideValue: JSON.stringify(guideInfo.value)
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ data.step = 0;
|
|
|
+ getStepELe();
|
|
|
+ tipShow.value = true;
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ };
|
|
|
+ onMounted(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ getStepELe();
|
|
|
+ }, 500);
|
|
|
+ window.addEventListener('resize', resetSize);
|
|
|
+ eventGlobal.on('teacher-guideInfo', (name: string) => onResetGuide(name));
|
|
|
+ });
|
|
|
+ const resetSize = () => {
|
|
|
+ getStepELe();
|
|
|
+ };
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', resetSize);
|
|
|
+ eventGlobal.off('teacher-guideInfo', onResetGuide);
|
|
|
+ });
|
|
|
+
|
|
|
+ const handleNext = () => {
|
|
|
+ if (data.step >= 4) {
|
|
|
+ endGuide();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ data.step = data.step + 1;
|
|
|
+ getStepELe();
|
|
|
+ };
|
|
|
+
|
|
|
+ const endGuide = async () => {
|
|
|
+ // let guideInfo =
|
|
|
+ // JSON.parse(localStorage.getItem('teacher-guideInfo')|| '{}') || null;
|
|
|
+ if (!guideInfo.value) {
|
|
|
+ guideInfo.value = { lessonsGuideIn: true };
|
|
|
+ } else {
|
|
|
+ guideInfo.value.lessonsGuideIn = true;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const res = await setGuidance({
|
|
|
+ guideTag: 'teacher-guideInfo',
|
|
|
+ guideValue: JSON.stringify(guideInfo.value)
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ // localStorage.setItem('teacher-guideInfo', JSON.stringify(guideInfo));
|
|
|
+ tipShow.value = false;
|
|
|
+ // localStorage.setItem('endC')
|
|
|
+ };
|
|
|
+ return () => (
|
|
|
+ <>
|
|
|
+ {tipShow.value ? (
|
|
|
+ <div
|
|
|
+ v-model:show={tipShow.value}
|
|
|
+ class={['n-modal-mask', 'n-modal-mask-guide']}>
|
|
|
+ <div class={styles.content} onClick={() => handleNext()}>
|
|
|
+ <div
|
|
|
+ class={styles.backBtn}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ endGuide();
|
|
|
+ }}>
|
|
|
+ 跳过
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={styles.box}
|
|
|
+ style={{ ...data.box }}
|
|
|
+ id={`modeType-${data.step}`}>
|
|
|
+ {data.steps.map((item: any, index) => (
|
|
|
+ <div
|
|
|
+ onClick={(e: Event) => e.stopPropagation()}
|
|
|
+ class={styles.item}
|
|
|
+ style={
|
|
|
+ item.type == 'bottom'
|
|
|
+ ? {
|
|
|
+ display: index === data.step ? '' : 'none',
|
|
|
+ left: `${item.eleRect?.left}px`,
|
|
|
+ top: `-${item.imgStyle?.height}`
|
|
|
+ }
|
|
|
+ : item.type == 'left'
|
|
|
+ ? {
|
|
|
+ display: index === data.step ? '' : 'none',
|
|
|
+
|
|
|
+ top: `${
|
|
|
+ parseFloat(data.box?.height) / 2 -
|
|
|
+ (parseFloat(item.imgStyle?.height) * 1920) /
|
|
|
+ 100 /
|
|
|
+ 2 -
|
|
|
+ 14
|
|
|
+ }px`
|
|
|
+ }
|
|
|
+ : {
|
|
|
+ display: index === data.step ? '' : 'none',
|
|
|
+ left: `${item.eleRect?.left}px`,
|
|
|
+ top: `${data.box?.height}`
|
|
|
+ }
|
|
|
+ }>
|
|
|
+ <img
|
|
|
+ class={styles.img}
|
|
|
+ style={item.imgStyle}
|
|
|
+ src={item.img}
|
|
|
+ />
|
|
|
+ {/* <img
|
|
|
+ class={styles.iconHead}
|
|
|
+ style={item.handStyle}
|
|
|
+ src={getImage('indexDot.png')}
|
|
|
+ /> */}
|
|
|
+ <div class={styles.btns} style={item.btnsStyle}>
|
|
|
+ {data.step + 1 == data.steps.length ? (
|
|
|
+ <>
|
|
|
+ <div
|
|
|
+ class={[styles.endBtn]}
|
|
|
+ onClick={() => endGuide()}>
|
|
|
+ 完成
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={styles.nextBtn}
|
|
|
+ onClick={() => {
|
|
|
+ data.step = 0;
|
|
|
+ getStepELe();
|
|
|
+ }}>
|
|
|
+ 再看一遍
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <div class={styles.btn} onClick={() => handleNext()}>
|
|
|
+ 下一步 ({data.step + 1}/{data.steps.length})
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|