Quellcode durchsuchen

引导页完成

1
mo vor 2 Jahren
Ursprung
Commit
d3c1abf310
35 geänderte Dateien mit 1196 neuen und 23 gelöschten Zeilen
  1. 12 5
      src/page-instrument/component/mode-type-mode/index.module.less
  2. 48 9
      src/page-instrument/component/mode-type-mode/index.tsx
  3. BIN
      src/page-instrument/custom-plugins/guide-page/images/aiTeacher1.png
  4. BIN
      src/page-instrument/custom-plugins/guide-page/images/aiTeacher2.png
  5. BIN
      src/page-instrument/custom-plugins/guide-page/images/aiTeacher3.png
  6. BIN
      src/page-instrument/custom-plugins/guide-page/images/aiTeacher4.png
  7. BIN
      src/page-instrument/custom-plugins/guide-page/images/endBtn.png
  8. 9 0
      src/page-instrument/custom-plugins/guide-page/images/index.ts
  9. BIN
      src/page-instrument/custom-plugins/guide-page/images/indexDot.png
  10. BIN
      src/page-instrument/custom-plugins/guide-page/images/nextBtn.png
  11. BIN
      src/page-instrument/custom-plugins/guide-page/images/numbrBtn.png
  12. BIN
      src/page-instrument/custom-plugins/guide-page/images/studentB1.png
  13. BIN
      src/page-instrument/custom-plugins/guide-page/images/studentB2.png
  14. BIN
      src/page-instrument/custom-plugins/guide-page/images/studentB3.png
  15. BIN
      src/page-instrument/custom-plugins/guide-page/images/studentBtn.png
  16. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT1.png
  17. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT2.png
  18. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT3.png
  19. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT4.png
  20. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT5.png
  21. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT6.png
  22. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT7.png
  23. BIN
      src/page-instrument/custom-plugins/guide-page/images/studnetT8.png
  24. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop1.png
  25. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop2.png
  26. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop3.png
  27. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop4.png
  28. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop5.png
  29. BIN
      src/page-instrument/custom-plugins/guide-page/images/teacherTop6.png
  30. 194 0
      src/page-instrument/custom-plugins/guide-page/index.module.less
  31. 181 0
      src/page-instrument/custom-plugins/guide-page/student-bottom.tsx
  32. 276 0
      src/page-instrument/custom-plugins/guide-page/student-top.tsx
  33. 197 0
      src/page-instrument/custom-plugins/guide-page/teacher-bootom.tsx
  34. 239 0
      src/page-instrument/custom-plugins/guide-page/teacher-top.tsx
  35. 40 9
      src/page-instrument/header-top/index.tsx

+ 12 - 5
src/page-instrument/component/mode-type-mode/index.module.less

@@ -11,12 +11,19 @@
   background: linear-gradient(to top, rgba(255,255,255,1), rgba(255,255,255, .7));
   padding: 0 40px;
   transition: all .3s ease-in-out;
-  img{
-    display: block;
-    width: 24%;
-    max-width: 220Px;
-    cursor: pointer;
+  .infoWrap{
+    display: flex;
+    flex-direction: row;
+    justify-content: space-around;
+    width: 14.31rem;
+    img{
+      display: block;
+      width: 24%;
+      max-width: 220Px;
+      cursor: pointer;
+    }
   }
+
 }
 .hidden{
   opacity: 0;

+ 48 - 9
src/page-instrument/component/mode-type-mode/index.tsx

@@ -1,17 +1,56 @@
-import { defineComponent, onMounted } from "vue";
+import { defineComponent, onMounted, ref, watch } from "vue";
 import styles from "./index.module.less";
 import icons from './icon/index.json'
 import { headTopData } from "../../header-top";
-
+import state, {
+	IPlatform,
+} from "/src/state";
+import TeacherBootom from '../../custom-plugins/guide-page/teacher-bootom'
+import StudentBottom from "../../custom-plugins/guide-page/student-bottom";
 export default defineComponent({
 	name: "modelWraper",
+
 	setup() {
-		return () => (
-			<div class={[styles.wrap, headTopData.modeType === 'init' ? '' : styles.hidden ]}>
-				<img onClick={() => headTopData.handleChangeModeType("practise")} src={icons.icon_1} />
-				<img onClick={() => headTopData.handleChangeModeType("follow")} src={icons.icon_2} />
-				<img onClick={() => headTopData.handleChangeModeType("evaluating")} src={icons.icon_3} />
-			</div>
-		);
+		const showPC = ref(false)
+		const showStudent = ref(false)
+		onMounted(() => {
+			// 加载后 判断 端口号 加载对应的引导
+			if (state.platform === IPlatform.PC) {
+				// PC
+				setTimeout(() => {
+					showPC.value = true
+				}, 1000)
+
+			} else {
+				// 学生端
+				setTimeout(() => {
+					showStudent.value = true
+				}, 1000)
+			}
+			console.log('加载完成', state.platform)
+		})
+		watch(() => headTopData.modeType, (val) => {
+			console.log(val)
+		})
+		return () => (<>
+			{
+				state.platform === IPlatform.PC ? <div class={[styles.wrap, headTopData.modeType === 'init' ? '' : styles.hidden]}>
+					<div class={[styles.infoWrap, headTopData.modeType === 'init' ? '' : styles.hidden]} id='aiTeacher-0'>
+						<img id='aiTeacher-1' onClick={() => headTopData.handleChangeModeType("practise")} src={icons.icon_1} />
+						<img id='aiTeacher-2' onClick={() => headTopData.handleChangeModeType("follow")} src={icons.icon_2} />
+						<img id='aiTeacher-3' onClick={() => headTopData.handleChangeModeType("evaluating")} src={icons.icon_3} />
+					</div>
+					{showPC.value ? <TeacherBootom></TeacherBootom> : null}
+				</div> : <div class={[styles.wrap, headTopData.modeType === 'init' ? '' : styles.hidden]}>
+					<div class={[styles.infoWrap, headTopData.modeType === 'init' ? '' : styles.hidden]} >
+						<img id='studentB-0' onClick={() => headTopData.handleChangeModeType("practise")} src={icons.icon_1} />
+						<img id='studentB-1' onClick={() => headTopData.handleChangeModeType("follow")} src={icons.icon_2} />
+						<img id='studentB-2' onClick={() => headTopData.handleChangeModeType("evaluating")} src={icons.icon_3} />
+					</div>
+					{showStudent.value ? <StudentBottom></StudentBottom> : null}
+				</div>
+			}
+
+		</>);
 	},
 });

BIN
src/page-instrument/custom-plugins/guide-page/images/aiTeacher1.png


BIN
src/page-instrument/custom-plugins/guide-page/images/aiTeacher2.png


BIN
src/page-instrument/custom-plugins/guide-page/images/aiTeacher3.png


BIN
src/page-instrument/custom-plugins/guide-page/images/aiTeacher4.png


BIN
src/page-instrument/custom-plugins/guide-page/images/endBtn.png


+ 9 - 0
src/page-instrument/custom-plugins/guide-page/images/index.ts

@@ -0,0 +1,9 @@
+const modules = import.meta.glob('../images/**', {
+  import: 'default',
+  eager: true
+});
+export const getImage = (name: string): string => {
+  // console.log("🚀 ~ modules", modules[`./${name}`])
+  const src: any = modules[`./${name}`] || '';
+  return src;
+};

BIN
src/page-instrument/custom-plugins/guide-page/images/indexDot.png


BIN
src/page-instrument/custom-plugins/guide-page/images/nextBtn.png


BIN
src/page-instrument/custom-plugins/guide-page/images/numbrBtn.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studentB1.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studentB2.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studentB3.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studentBtn.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT1.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT2.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT3.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT4.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT5.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT6.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT7.png


BIN
src/page-instrument/custom-plugins/guide-page/images/studnetT8.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop1.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop2.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop3.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop4.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop5.png


BIN
src/page-instrument/custom-plugins/guide-page/images/teacherTop6.png


+ 194 - 0
src/page-instrument/custom-plugins/guide-page/index.module.less

@@ -0,0 +1,194 @@
+.guidePopup {
+    z-index: 5000 !important;
+    top: 0;
+    right: 0;
+    left: 0;
+    bottom: 0;
+    transform: none;
+    width: 100vw;
+    height: 100vh;
+    max-width: 100vw;
+    margin: 0;
+    overflow: hidden;
+  }
+  
+  .tipsContainer {
+    position: relative;
+    width: 100vw;
+    height: 100vh;
+    overflow: hidden;
+  }
+  
+  .backBtn {
+    position: absolute;
+    left: 47px;
+    top: 21px;
+    font-size: 14px;
+    line-height: 24px;
+    padding: 0 14px;
+    border-radius: 17px;
+    border: 1px solid #ffffff;
+    color: #fff;
+    text-align: center;
+    z-index: 1;
+  
+    &:active {
+      opacity: 0.8;
+    }
+  }
+  .backBtn.right {
+    width: 60px;
+    line-height: 24px;
+    padding: 0 14px;
+    right: 14px;
+    top: 21px;
+    left: auto;
+  }
+  
+  .content {
+    position: relative;
+    width: 100%;
+    height: 100%;
+  }
+  
+  .box {
+    position: fixed;
+    box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 0px 5000px;
+    transition: all 0.25s;
+    transform: scale(1.2);
+    border-radius: 8px;
+  }
+  
+  .item {
+    position: absolute;
+    // width: 200px;
+    z-index: 2000;
+  
+    .img {
+      position: relative;
+      width: 100%;
+
+    }
+  
+    .iconHead {
+      position: absolute;
+      left: 45px;
+      width: 18px;
+      height: 52px;
+  
+      &.head2 {
+        left: 0.2rem;
+        top: 0.9rem;
+      }
+    }
+  
+    .btns {
+      position: absolute;
+      display: flex;
+    //   width: 100%;
+    //   padding: 0 12px;
+  
+      .btn {
+        width: 73px;
+        height: 23px;
+        line-height: 13px;
+        font-size: 9px;
+        padding: 0;
+      }
+      .endBtn {
+        margin-left: 5px;
+      }
+    }
+    .studentbtn {
+      background: url('./images/studentBtn.png');
+      width:89px;
+      height: 28px;
+      background-size: 89px 28px;
+      line-height: 28px;
+      font-size: 9px;
+      padding: 0;
+      text-align:center;
+      color:#fff;
+    }
+    .teacherBtn {
+        background: url('./images/numbrBtn.png');
+        background-size: 72px 25px;
+        width: 72px;
+        height: 25px;
+        line-height: 25px;
+        font-size: 9px;
+        padding: 0;
+        cursor: pointer;
+        text-align: center;
+        color: #fff;
+        border:none;
+        &:hover {
+          opacity: .8;
+        }
+      }
+    }
+    .endBtn {
+        width: 60px;
+        height: 25px;
+        background: url('./images/endBtn.png');
+        background-size: 60px 25px;
+        line-height: 25px;
+        font-size: 9px;
+        padding: 0;
+        cursor: pointer;
+        text-align: center;
+        color: #fff;
+        margin-right: 20px;
+        &:hover {
+          opacity: .8;
+        }
+      }
+      .nextBtn {
+        width: 60px;
+        height: 25px;
+        background: url('./images/nextBtn.png') no-repeat;
+        background-size: 60px 25px;
+        line-height: 25px;
+        font-size: 9px;
+        padding: 0;
+        cursor: pointer;
+        text-align: center;
+        color: #fff;
+  
+        &:hover {
+          opacity: .8;
+        }
+      }
+      .studentNext {
+        width: 60px;
+        height: 25px;
+        background: url('./images/studentBtn.png') no-repeat;
+        background-size: 60px 25px;
+        line-height: 25px;
+        font-size: 9px;
+        padding: 0;
+        margin-right:20px;
+        cursor: pointer;
+        text-align: center;
+        color: #fff;
+  
+        &:hover {
+          opacity: .8;
+        }
+      }
+  
+  
+  @keyframes myscale {
+    0% {
+      transform: scale(0.9);
+    }
+  
+    50% {
+      transform: scale(1);
+    }
+  
+    100% {
+      transform: scale(0.9);
+    }
+  }
+  

+ 181 - 0
src/page-instrument/custom-plugins/guide-page/student-bottom.tsx

@@ -0,0 +1,181 @@
+import { Button, Popup } from "vant";
+import { } from "vant";
+import { defineComponent, nextTick, onMounted, reactive, ref, watch } from "vue";
+import styles from "./index.module.less";
+import { getImage } from "./images";
+
+export default defineComponent({
+  name: "studentB-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("studentB1.png"),
+          handStyle: {
+            top: "-1.41rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-5.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+            left:'1.2rem'
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'3.2rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studentB2.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.15rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-5.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'1.3rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studentB3.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'2.8rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-4.5rem",
+            width:'6.48rem',
+            height:'3.01rem',
+            left:'-2.9rem'
+
+          },
+          btnsStyle: {
+            top: "-1.1rem",
+            left:'-1.8rem',
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).studentB){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`studentB${data.step}`)
+      const ele: HTMLElement = document.getElementById(`studentB-${data.step}`)!;
+      if (ele) {
+        const eleRect = ele.getBoundingClientRect();
+        data.box = {
+          left: eleRect.x + "px",
+          top: eleRect.y + "px",
+          width: eleRect.width + "px",
+          height: eleRect.height + "px",
+        };
+      }
+    };
+    onMounted(() => {
+      getStepELe();
+    });
+
+
+    const handleNext = () => {
+      if (data.step >= 2) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}') || null
+      if(!guideInfo){
+        guideInfo = {studentB:true}
+      }else{
+        guideInfo.studentB = true
+      }
+      localStorage.setItem('guideInfo',JSON.stringify(guideInfo))
+      tipShow.value = false
+    //  localStorage.setItem('endC')
+    }
+    return () => (
+      <Popup teleport="body" overlay={false} closeOnClickOverlay={false} class={["popup-custom", styles.guidePopup]} v-model:show={tipShow.value}>
+      <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={{
+                display: index === data.step ? "" : "none",
+                left: `${item.eleRect?.left}px`,
+                top: `${item.eleRect?.top}px`,
+              }}
+            >
+              <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.studentNext]}  onClick={() =>endGuide()}>
+              完成
+            </div>
+            <div
+              class={[styles.nextBtn]}
+              style={{ "border-color": "#fff" }}
+          
+              onClick={() => {
+                data.step = 0;
+                getStepELe();
+              }}
+            >
+              再看一遍
+            </div>
+        
+          </>
+        ) : (
+          <Button class={styles.studentNext} round type="primary" onClick={() => handleNext()}>
+
+            下一步 ({data.step + 1}/{data.steps.length})
+          </Button>
+        )}
+                
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 276 - 0
src/page-instrument/custom-plugins/guide-page/student-top.tsx

@@ -0,0 +1,276 @@
+import { Button, Popup } from "vant";
+import { } from "vant";
+import { defineComponent, nextTick, onMounted, reactive, ref, watch } from "vue";
+import styles from "./index.module.less";
+import { getImage } from "./images";
+
+export default defineComponent({
+  name: "studnetT-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("studnetT1.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem'
+          },
+          imgStyle: {
+            top: "1.52rem",
+            width:'5.64rem',
+            height:'2.77rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "4.6rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studnetT2.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem',
+  
+          },
+          imgStyle: {
+            top: "1.52rem",
+            width:'5.64rem',
+            height:'2.77rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "4.6rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studnetT3.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem',
+          },
+          imgStyle: {
+            top: "1.8rem",
+            width:'5.46rem',
+            height:'2.30rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "4.6rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studnetT4.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem',
+          },
+          imgStyle: {
+            top: "1.8rem",
+            width:'5.46rem',
+            height:'2.30rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "4.6rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studnetT5.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem',
+     
+          },
+          imgStyle: {
+            top: "1.8rem",
+            width:'4.46rem',
+            height:'2.6rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "4.6rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("studnetT6.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'0.3rem',
+         
+          },
+          imgStyle: {
+            top: "1.62rem",
+            width:'5.46rem',
+            height:'2.30rem',
+            left:'-3.2rem'
+          },
+          btnsStyle: {
+            top: "4.3rem",
+            left:'-1.8rem'
+          },
+        },
+        {
+            ele: "",
+            eleRect: {} as DOMRect,
+            img: getImage("studnetT7.png"),
+            handStyle: {
+                top: "1.3rem",
+                left:'0.3rem',
+            },
+            imgStyle: {
+              top: "1.62rem",
+              width:'5.46rem',
+              height:'2.3rem',
+              left:'-5.5rem'
+            },
+            btnsStyle: {
+              top: "4.4rem",
+              left:'-2.7rem'
+            },
+          },      {
+            ele: "",
+            eleRect: {} as DOMRect,
+            img: getImage("studnetT8.png"),
+            handStyle: {
+              top: "-1.4rem",
+              left:'0.4',
+              transform: 'rotate(180deg)'
+            },
+            imgStyle: {
+              top: "-3.8rem",
+              width:'5.46rem',
+              height:'2.28rem',
+              left:'-5rem'
+            },
+            btnsStyle: {
+              top: "-1.2rem",
+              left:'-4.3rem'
+            },
+          },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).studnetT){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`studnetT${data.step}`)
+      const ele: HTMLElement = document.getElementById(`studnetT-${data.step}`)!;
+      if (ele) {
+        if (ele.style.display === 'none'){
+					handleNext()
+					return
+				}
+        const eleRect = ele.getBoundingClientRect();
+        data.box = {
+          left: eleRect.x + "px",
+          top: eleRect.y + "px",
+          width: eleRect.width + "px",
+          height: eleRect.height + "px",
+        };
+      }
+    };
+    onMounted(() => {
+      getStepELe();
+    });
+
+
+    const handleNext = () => {
+      if (data.step >= 7) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+    
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}') || null
+      if(!guideInfo){
+        guideInfo = {studnetT:true}
+      }else{
+        guideInfo.studnetT = true
+      }
+      localStorage.setItem('guideInfo',JSON.stringify(guideInfo))
+      tipShow.value = false
+    //  localStorage.setItem('endC')
+    }
+    return () => (
+      <Popup teleport="body" overlay={false} closeOnClickOverlay={false} class={["popup-custom", styles.guidePopup]} v-model:show={tipShow.value}>
+      <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={{
+                display: index === data.step ? "" : "none",
+                left: `${item.eleRect?.left}px`,
+                top: `${item.eleRect?.top}px`,
+              }}
+            >
+              <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.studentNext]}  onClick={() =>endGuide()}>
+                      完成
+                    </div>
+                    <div
+                      class={[styles.nextBtn]}
+                      style={{ "border-color": "#fff" }}
+                  
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </div>
+                
+                  </>
+                ) : (
+                  <Button class={styles.studentNext} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 197 - 0
src/page-instrument/custom-plugins/guide-page/teacher-bootom.tsx

@@ -0,0 +1,197 @@
+import { Button, Popup } from "vant";
+import { } from "vant";
+import { defineComponent, nextTick, onMounted, reactive, ref, watch } from "vue";
+import styles from "./index.module.less";
+import { getImage } from "./images";
+
+export default defineComponent({
+  name: "aiTeacher-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("aiTeacher1.png"),
+          handStyle: {
+            top: "0.91rem",
+          },
+          imgStyle: {
+            top: "-3.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+            left:'4.67rem'
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'6rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("aiTeacher2.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.15rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-3.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'1.3rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("aiTeacher3.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.17rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-3.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'1.3rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("aiTeacher4.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-3.01rem",
+            width:'6.48rem',
+            height:'3.01rem',
+
+          },
+          btnsStyle: {
+            top: "-1.61rem",
+            left:'0.8rem',
+            "justify-content": "center",
+            padding: 0,
+          },
+        },
+      ],
+      step: 0,
+    });
+    
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).teacherBottom){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`aiTeacher${data.step}`)
+      const ele: HTMLElement = document.getElementById(`aiTeacher-${data.step}`)!;
+      if (ele) {
+        const eleRect = ele.getBoundingClientRect();
+        data.box = {
+          left: eleRect.x + "px",
+          top: eleRect.y + "px",
+          width: eleRect.width + "px",
+          height: eleRect.height + "px",
+        };
+      }
+    };
+    onMounted(() => {
+      getStepELe();
+    });
+    const handleNext = () => {
+      if (data.step >= 3) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}') || null
+      if(!guideInfo){
+        guideInfo = {teacherBottom:true}
+      }else{
+        guideInfo.teacherBottom = true
+      }
+      localStorage.setItem('guideInfo',JSON.stringify(guideInfo))
+      tipShow.value = false
+    //  localStorage.setItem('endC')
+    }
+    return () => (
+      <Popup teleport="body" overlay={false} closeOnClickOverlay={false} class={["popup-custom", styles.guidePopup]} v-model:show={tipShow.value}>
+      <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={{
+                display: index === data.step ? "" : "none",
+                left: `${item.eleRect?.left}px`,
+                top: `${item.eleRect?.top}px`,
+              }}
+            >
+              <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]}
+                      style={{ "border-color": "#fff" }}
+                  
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </div>
+                
+                  </>
+                ) : (
+                  <Button class={styles.teacherBtn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 239 - 0
src/page-instrument/custom-plugins/guide-page/teacher-top.tsx

@@ -0,0 +1,239 @@
+import { Button, Popup } from "vant";
+import { } from "vant";
+import { defineComponent, nextTick, onMounted, reactive, ref, watch } from "vue";
+import styles from "./index.module.less";
+import { getImage } from "./images";
+
+export default defineComponent({
+  name: "teacherTop-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("teacherTop1.png"),
+          handStyle: {
+            top: "0.91rem",
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'3.63rem',
+            height:'2.28rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("teacherTop2.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.15rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'4.20rem',
+            height:'2.28rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("teacherTop3.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.17rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'5.15rem',
+            height:'2.28rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("teacherTop4.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'4.39rem',
+            height:'2.28rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("teacherTop5.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'4.58rem',
+            height:'2.28rem',
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-0.7rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("teacherTop6.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "1.32rem",
+            width:'4.01rem',
+            height:'2.28rem',
+            left:'-3.2rem'
+          },
+          btnsStyle: {
+            top: "2.8rem",
+            left:'-1.8rem'
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).teacherTop){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`teacherTop${data.step}`)
+      const ele: HTMLElement = document.getElementById(`teacherTop-${data.step}`)!;
+      if (ele) {
+        if (ele.style.display === 'none'){
+					handleNext()
+					return
+				}
+        const eleRect = ele.getBoundingClientRect();
+        data.box = {
+          left: eleRect.x + "px",
+          top: eleRect.y + "px",
+          width: eleRect.width + "px",
+          height: eleRect.height + "px",
+        };
+      }
+    };
+    onMounted(() => {
+      getStepELe();
+    });
+
+
+    const handleNext = () => {
+      if (data.step >= 5) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+    
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}') || null
+      if(!guideInfo){
+        guideInfo = {teacherTop:true}
+      }else{
+        guideInfo.teacherTop = true
+      }
+      localStorage.setItem('guideInfo',JSON.stringify(guideInfo))
+      tipShow.value = false
+    //  localStorage.setItem('endC')
+    }
+    return () => (
+      <Popup teleport="body" overlay={false} closeOnClickOverlay={false} class={["popup-custom", styles.guidePopup]} v-model:show={tipShow.value}>
+      <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={{
+                display: index === data.step ? "" : "none",
+                left: `${item.eleRect?.left}px`,
+                top: `${item.eleRect?.top}px`,
+              }}
+            >
+              <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]}
+                      style={{ "border-color": "#fff" }}
+                  
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </div>
+                
+                  </>
+                ) : (
+                  <Button class={styles.teacherBtn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 40 - 9
src/page-instrument/header-top/index.tsx

@@ -22,6 +22,8 @@ import MusicType from "./music-type";
 import ModeTypeMode from "../component/mode-type-mode";
 import { getQuery } from "/src/utils/queryString";
 import { storeData } from "/src/store";
+import TeacherTop from "../custom-plugins/guide-page/teacher-top";
+import StudentTop from '../custom-plugins/guide-page/student-top'
 
 /** 头部数据和方法 */
 export const headTopData = reactive({
@@ -60,6 +62,9 @@ export default defineComponent({
 	name: "header-top",
 	emits: ["close"],
 	setup(props, { emit }) {
+		// 是否显示引导
+		const showGuide = ref(false)
+		const showStudentGuide = ref(false)
 		/** 设置按钮 */
 		const settingBtn = computed(() => {
 			// 音频播放中 禁用
@@ -208,6 +213,17 @@ export default defineComponent({
 			};
 		});
 
+		const isAllBtns = computed(()=>{
+			const flag = converBtn.value.display&&speedBtn.value.display&&selectBtn.value.display&&originBtn.value.display&&toggleBtn.value.display&&showGuide.value
+			console.log(flag,'flag',converBtn.value.display,speedBtn.value.display,selectBtn.value.display,originBtn.value.display,toggleBtn.value.display,showGuide.value)
+			return flag
+		})
+
+		const isAllBtnsStudent =computed(()=>{
+			const flag = converBtn.value.display&&speedBtn.value.display&&selectBtn.value.display&&originBtn.value.display&&toggleBtn.value.display&&showStudentGuide.value
+		
+			return flag
+		})
 		/** 返回 */
 		const handleBack = () => {
 			emit("close");
@@ -251,6 +267,11 @@ export default defineComponent({
 		onMounted(() => {
 			getQueryModelSetModelType();
 			window.addEventListener("message", changePlay);
+			if (state.platform === IPlatform.PC) {
+				showGuide.value = true
+			}else{
+				showStudentGuide.value = true
+			}
 		});
 
 		onUnmounted(() => {
@@ -259,6 +280,8 @@ export default defineComponent({
 
 		return () => (
 			<>
+		
+			<div>
 				<div class={[styles.headerTop]}>
 					<div class={[styles.back, "headTopBackBtn", !headTopData.showBack && styles.hidenBack]} onClick={handleBack}>
 						<img src={iconBack} />
@@ -266,8 +289,9 @@ export default defineComponent({
 					<Title class="pcTitle" text={state.examSongName} rightView={false} />
 
 					<div class={styles.headRight}>
+					
 						<div
-							id="tips-step-1"
+							id={state.platform === IPlatform.PC?"teacherTop-0":'studnetT-0'}
 							style={{ display: toggleBtn.value.display ? "" : "none" }}
 							class={[styles.btn, toggleBtn.value.disabled && styles.disabled]}
 							onClick={() => {
@@ -280,7 +304,8 @@ export default defineComponent({
 						</div>
 
 						<div
-							id="tips-step-2"
+						id={state.platform === IPlatform.PC?"teacherTop-1":'studnetT-1'}
+				
 							style={{ display: originBtn.value.display ? "" : "none" }}
 							class={[styles.btn, originBtn.value.disabled && styles.disabled]}
 							onClick={() => {
@@ -300,7 +325,8 @@ export default defineComponent({
 							<span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
 						</div>
 						<div
-							id="tips-step-3"
+							id={state.platform === IPlatform.PC?"teacherTop-2":'studnetT-2'}
+				
 							style={{ display: selectBtn.value.display ? "" : "none" }}
 							class={[styles.btn, selectBtn.value.disabled && styles.disabled]}
 							onClick={() => handleChangeSection()}
@@ -323,7 +349,7 @@ export default defineComponent({
 							<span>选段</span>
 						</div>
 						<div
-							id="tips-step-4"
+								id={state.platform === IPlatform.PC?"teacherTop-3":'studnetT-3'}
 							style={{ display: fingeringBtn.value.display ? "" : "none" }}
 							class={[styles.btn, fingeringBtn.value.disabled && styles.disabled]}
 							onClick={() => {
@@ -352,7 +378,7 @@ export default defineComponent({
 							{{
 								reference: () => (
 									<div
-										id="tips-step-5"
+									id={state.platform === IPlatform.PC?"teacherTop-4":'studnetT-4'}
 										style={{ display: speedBtn.value.display ? "" : "none" }}
 										class={[styles.btn, speedBtn.value.disabled && styles.disabled]}
 										onClick={(e: Event) => {
@@ -378,7 +404,7 @@ export default defineComponent({
 							{{
 								reference: () => (
 									<div
-										id="tips-step-6"
+									id={state.platform === IPlatform.PC?"teacherTop-5":'studnetT-5'}
 										style={{ display: converBtn.value.display ? "" : "none" }}
 										class={[styles.btn, converBtn.value.disabled && styles.disabled]}
 										onClick={(e: Event) => {
@@ -386,7 +412,7 @@ export default defineComponent({
 											headData.musicTypeShow = !headData.musicTypeShow;
 										}}
 									>
-										<img class={styles.iconBtn} src={headImg("icon_zhuanpu.svg")} />
+										<img  class={styles.iconBtn} src={headImg("icon_zhuanpu.svg")} />
 										<span>{state.musicRenderType === "staff" ? "转简谱" : "转五线谱"}</span>
 									</div>
 								),
@@ -395,7 +421,7 @@ export default defineComponent({
 						</Popover>
 
 						<div
-							id="tips-step-7"
+							id={state.platform === IPlatform.PC?"teacherTop-6":'studnetT-6'}
 							style={{ display: settingBtn.value.display ? "" : "none" }}
 							class={[styles.btn, settingBtn.value.disabled && styles.disabled]}
 							onClick={() => (headTopData.settingMode = true)}
@@ -408,7 +434,7 @@ export default defineComponent({
 
 				{/* 播放按钮 */}
 				<div
-					id="tips-step-8"
+					id='studnetT-7'
 					style={{ display: playBtn.value.display ? "" : "none" }}
 					class={[
 						styles.btn,
@@ -467,6 +493,11 @@ export default defineComponent({
 
 				{/* 模式切换 */}
 				<ModeTypeMode />
+				{/* isAllBtns */}
+				{isAllBtns.value&&<TeacherTop></TeacherTop>}
+				{isAllBtnsStudent.value&&<StudentTop></StudentTop>}
+				</div>
+	
 			</>
 		);
 	},