Browse Source

Merge branch 'guide' into dev

mo 2 years ago
parent
commit
eeb35f5ee3
33 changed files with 1453 additions and 350 deletions
  1. 0 1
      src/components/m-sticky/index.tsx
  2. 191 0
      src/custom-plugins/guide-page/coai-guide.tsx
  3. 141 0
      src/custom-plugins/guide-page/courseware-detail.tsx
  4. 195 0
      src/custom-plugins/guide-page/courseware-list.tsx
  5. BIN
      src/custom-plugins/guide-page/images/coai-1.png
  6. BIN
      src/custom-plugins/guide-page/images/coai-2.png
  7. BIN
      src/custom-plugins/guide-page/images/coai-3.png
  8. BIN
      src/custom-plugins/guide-page/images/coai-4.png
  9. BIN
      src/custom-plugins/guide-page/images/courseware-detail1.png
  10. BIN
      src/custom-plugins/guide-page/images/courseware-detail2.png
  11. BIN
      src/custom-plugins/guide-page/images/courseware-list1.png
  12. BIN
      src/custom-plugins/guide-page/images/courseware-list2.png
  13. BIN
      src/custom-plugins/guide-page/images/courseware-list3.png
  14. BIN
      src/custom-plugins/guide-page/images/courseware-list4.png
  15. BIN
      src/custom-plugins/guide-page/images/guideNext.png
  16. 9 0
      src/custom-plugins/guide-page/images/index.ts
  17. BIN
      src/custom-plugins/guide-page/images/indexDot.png
  18. BIN
      src/custom-plugins/guide-page/images/knowledge1.png
  19. BIN
      src/custom-plugins/guide-page/images/knowledge2.png
  20. BIN
      src/custom-plugins/guide-page/images/knowledge3.png
  21. BIN
      src/custom-plugins/guide-page/images/woring1.png
  22. BIN
      src/custom-plugins/guide-page/images/woring2.png
  23. BIN
      src/custom-plugins/guide-page/images/woring3.png
  24. 115 0
      src/custom-plugins/guide-page/index.module.less
  25. 178 0
      src/custom-plugins/guide-page/knowledge-guide.tsx
  26. 178 0
      src/custom-plugins/guide-page/woring-guide.tsx
  27. 299 277
      src/views/co-ai/index.module.less
  28. 39 26
      src/views/co-ai/index.tsx
  29. 22 7
      src/views/courseware-list/component/book/index.tsx
  30. 50 24
      src/views/courseware-list/index.tsx
  31. 10 7
      src/views/knowledge-library/index.module.less
  32. 21 7
      src/views/knowledge-library/index.tsx
  33. 5 1
      src/views/knowledge-library/wroing-book/index.tsx

+ 0 - 1
src/components/m-sticky/index.tsx

@@ -49,7 +49,6 @@ export default defineComponent({
     const __initHeight = (height: any) => {
       forms.sectionStyle.height = `${height}px`;
       forms.heightV = height;
-
       // 设置名称
       document.documentElement.style.setProperty(props.varName, `${height}px`);
       emit('barHeight', height);

+ 191 - 0
src/custom-plugins/guide-page/coai-guide.tsx

@@ -0,0 +1,191 @@
+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: "coai-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("coai-1.png"),
+          handStyle: {
+            top: "0.91rem",
+          },
+          imgStyle: {
+            top: "1.5rem",
+          },
+          btnsStyle: {
+            top: "4.5rem",
+            left:'1rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("coai-2.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.15rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-4rem",
+
+          },
+          btnsStyle: {
+            top: "-1.3rem",
+            left:'1.3rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("coai-3.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'0.17rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-4rem",
+
+          },
+          btnsStyle: {
+            top: "-1.3rem",
+            left:'1.3rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("coai-4.png"),
+          handStyle: {
+            top: "-1.39rem",
+            left:'1.4rem',
+            transform: 'rotate(180deg)'
+          },
+          imgStyle: {
+            top: "-4rem",
+            left:'-3.2rem',
+
+          },
+          btnsStyle: {
+            top: "-0.85rem",
+            left: "-3rem",
+            "justify-content": "center",
+            padding: 0,
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).coaiGuide){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`coai-${data.step}`)
+      const ele: HTMLElement = document.getElementById(`coai-${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 = {coaiGuide:true}
+      }else{
+        guideInfo.coaiGuide = 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 ? (
+                  <>
+                    <Button
+                      class={styles.btn}
+                      round
+                      color="transparent"
+                      style={{ "border-color": "#fff" }}
+                      type="primary"
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </Button>
+                    <Button class={[styles.btn,styles.endBtn]} round type="primary" onClick={() =>endGuide()}>
+                      完成
+                    </Button>
+                  </>
+                ) : (
+                  <Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 141 - 0
src/custom-plugins/guide-page/courseware-detail.tsx

@@ -0,0 +1,141 @@
+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: "courseware-detail",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("courseware-detail1.png"),
+          handStyle: {
+            top: "-0.4rem",
+            left:"1.1rem",
+            transform: 'rotate(-90deg)'
+          },
+          imgStyle: {
+            top: "-1.3rem",
+            left:"2.2rem",
+          },
+          btnsStyle: {
+            top: "1.5rem",
+            left:"3.5rem",
+          },
+        },
+
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).coursewareDetail){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`coursewareDetail-${data.step}`)
+      const ele: HTMLElement = document.getElementById(`coursewareDetail-${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 = {coursewareDetail:true}
+      }else{
+        guideInfo.coursewareDetail = 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 ? (
+                  <>
+                    {/* <Button
+                      class={styles.btn}
+                      round
+                      color="transparent"
+                      style={{ "border-color": "#fff" }}
+                      type="primary"
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </Button> */}
+                    <Button class={[styles.btn,styles.endBtn]} round type="primary" onClick={() =>endGuide()}>
+                      完成
+                    </Button>
+                  </>
+                ) : (
+                  <Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 195 - 0
src/custom-plugins/guide-page/courseware-list.tsx

@@ -0,0 +1,195 @@
+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: "courseware-list",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("courseware-list1.png"),
+          handStyle: {
+            top: "1.5rem",
+            left:"3.8rem",
+            transform: 'rotate(-90deg)'
+          },
+          imgStyle: {
+            top: ".7rem",
+            left:"4.8rem",
+          },
+          btnsStyle: {
+            top: "3.5rem",
+            left:"6rem",
+          },
+        },
+        {
+          ele: "",
+          img: getImage("courseware-list2.png"),
+          handStyle: {
+            top: "-.3rem",
+            left:"1.3rem",
+            transform: 'rotate(-90deg)'
+          },
+          imgStyle: {
+            top: "-1.2rem",
+            left:"2.4rem",
+
+          },
+          btnsStyle: {
+            top: "1.6rem",
+            left:'3.6rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("courseware-list3.png"),
+          handStyle: {
+            bottom: "-2rem",
+            left:'0.5rem',
+
+          },
+          imgStyle: {
+            top: "1.2rem",
+            left:'-2rem'
+          },
+          btnsStyle: {
+            top:"4.2rem",
+            left:'-0.5rem',
+          },
+        },
+        {
+          ele: "",
+          img: getImage("courseware-list4.png"),
+          handStyle: {
+            top: ".9rem",
+            left:'1rem',
+
+          },
+          imgStyle: {
+            top: "1.1rem",
+            left:'-4.6rem',
+
+          },
+          btnsStyle: {
+            top: "4rem",
+            left: "-4.5rem",
+            "justify-content": "center",
+            padding: 0,
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+   const guideInfo = localStorage.getItem('guideInfo')
+   if(guideInfo&&JSON.parse(guideInfo).courseware){
+    tipShow.value =false
+   }else {
+    tipShow.value =true
+   }
+    const getStepELe = () => {
+      console.log(`courseware-${data.step}`)
+      const ele: HTMLElement = document.getElementById(`courseware-${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 = {courseware:true}
+      }else{
+        guideInfo.courseware = 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 ? (
+                  <>
+                    <Button
+                      class={styles.btn}
+                      round
+                      color="transparent"
+                      style={{ "border-color": "#fff" }}
+                      type="primary"
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </Button>
+                    <Button class={[styles.btn,styles.endBtn]} round type="primary" onClick={() =>endGuide()}>
+                      完成
+                    </Button>
+                  </>
+                ) : (
+                  <Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

BIN
src/custom-plugins/guide-page/images/coai-1.png


BIN
src/custom-plugins/guide-page/images/coai-2.png


BIN
src/custom-plugins/guide-page/images/coai-3.png


BIN
src/custom-plugins/guide-page/images/coai-4.png


BIN
src/custom-plugins/guide-page/images/courseware-detail1.png


BIN
src/custom-plugins/guide-page/images/courseware-detail2.png


BIN
src/custom-plugins/guide-page/images/courseware-list1.png


BIN
src/custom-plugins/guide-page/images/courseware-list2.png


BIN
src/custom-plugins/guide-page/images/courseware-list3.png


BIN
src/custom-plugins/guide-page/images/courseware-list4.png


BIN
src/custom-plugins/guide-page/images/guideNext.png


+ 9 - 0
src/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/custom-plugins/guide-page/images/indexDot.png


BIN
src/custom-plugins/guide-page/images/knowledge1.png


BIN
src/custom-plugins/guide-page/images/knowledge2.png


BIN
src/custom-plugins/guide-page/images/knowledge3.png


BIN
src/custom-plugins/guide-page/images/woring1.png


BIN
src/custom-plugins/guide-page/images/woring2.png


BIN
src/custom-plugins/guide-page/images/woring3.png


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

@@ -0,0 +1,115 @@
+.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: 10;
+
+  .img {
+    position: absolute;
+    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;
+    }
+  }
+}
+
+@keyframes myscale {
+  0% {
+    transform: scale(0.9);
+  }
+
+  50% {
+    transform: scale(1);
+  }
+
+  100% {
+    transform: scale(0.9);
+  }
+}

+ 178 - 0
src/custom-plugins/guide-page/knowledge-guide.tsx

@@ -0,0 +1,178 @@
+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";
+import { useRect } from "@vant/use";
+
+export default defineComponent({
+  name: "knowledge-guide",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("knowledge1.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'1.5rem'
+          },
+          imgStyle: {
+            top: "1.9rem",
+          },
+          btnsStyle: {
+            top: "4.5rem",
+            left:'1rem'
+          },
+        },
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("knowledge2.png"),
+          handStyle: {
+            top: "1.3rem",
+            left:'1.5rem'
+          },
+          imgStyle: {
+            top: "1.9rem",
+            left:'-1.5rem'
+          },
+          btnsStyle: {
+            top: "4.5rem",
+
+          },
+        },
+        {
+          ele: "",
+          img: getImage("knowledge3.png"),
+          handStyle: {
+            top: "4.1rem",
+            left:'3.6rem',
+
+          },
+          imgStyle: {
+            top: "4.8rem",
+            left:'1.2rem',
+          },
+          btnsStyle: {
+            top: "7.5rem",
+            left:'1.3rem',
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+
+    const getStepELe = () => {
+      console.log(`knowledge-${data.step}`)
+      const ele: HTMLElement = document.getElementById(`knowledge-${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(() => {
+      setTimeout(()=>{
+        const guideInfo = localStorage.getItem('guideInfo')
+        if(guideInfo&&JSON.parse(guideInfo).knowledge){
+         tipShow.value =false
+        }else {
+         tipShow.value =true
+        }
+        getStepELe();
+      },300)
+
+    });
+
+    const handleNext = () => {
+      if (data.step >= 3) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}')
+
+      if(!guideInfo){
+        guideInfo = {knowledge:true}
+      }else{
+        guideInfo.knowledge = 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,styles.right]}
+          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 ? (
+                  <>
+                    <Button
+                      class={styles.btn}
+                      round
+                      color="transparent"
+                      style={{ "border-color": "#fff" }}
+                      type="primary"
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </Button>
+                    <Button class={[styles.btn,styles.endBtn]} round type="primary" onClick={() =>endGuide()}>
+                      完成
+                    </Button>
+                  </>
+                ) : (
+                  <Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 178 - 0
src/custom-plugins/guide-page/woring-guide.tsx

@@ -0,0 +1,178 @@
+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";
+import { useRect } from "@vant/use";
+
+export default defineComponent({
+  name: "woring",
+  emits: ["close"],
+  setup(props, { emit }) {
+    const data = reactive({
+      box: {},
+      show: false,
+      steps: [
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("woring1.png"),
+          handStyle: {
+            top: "2.7rem",
+            left:'4.5rem'
+          },
+          imgStyle: {
+            top: "3.3rem",
+            left:'2.1rem'
+          },
+          btnsStyle: {
+            top: "6.2rem",
+            left:'3.5rem'
+          },
+        },
+        {
+          ele: "",
+          eleRect: {} as DOMRect,
+          img: getImage("woring2.png"),
+          handStyle: {
+            top: "2.7rem",
+            left:'4.5rem'
+          },
+          imgStyle: {
+            top: "3.3rem",
+            left:'2.1rem'
+          },
+          btnsStyle: {
+            top: "6.2rem",
+            left:'3.5rem'
+          },
+        },
+        {
+          ele: "",
+          img: getImage("woring3.png"),
+          handStyle: {
+            top: "2.7rem",
+            left:'4.5rem'
+          },
+          imgStyle: {
+            top: "3.3rem",
+            left:'2.1rem'
+          },
+          btnsStyle: {
+            top: "6.2rem",
+            left:'2.5rem'
+          },
+        },
+      ],
+      step: 0,
+    });
+    const tipShow = ref(false)
+
+    const getStepELe = () => {
+
+      const ele: HTMLElement = document.getElementById(`woring-${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(() => {
+      setTimeout(()=>{
+        const guideInfo = localStorage.getItem('guideInfo')
+        if(guideInfo&&JSON.parse(guideInfo).woring){
+         tipShow.value =false
+        }else {
+         tipShow.value =true
+        }
+        getStepELe();
+      },300)
+
+    });
+
+    const handleNext = () => {
+      if (data.step >= 3) {
+       endGuide();
+        return;
+      }
+      data.step = data.step + 1;
+      getStepELe();
+    };
+
+    const endGuide = ()=>{
+      let guideInfo = JSON.parse(localStorage.getItem('guideInfo') || '{}')
+
+      if(!guideInfo){
+        guideInfo = {woring:true}
+      }else{
+        guideInfo.woring = 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,styles.right]}
+          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 ? (
+                  <>
+                    <Button
+                      class={styles.btn}
+                      round
+                      color="transparent"
+                      style={{ "border-color": "#fff" }}
+                      type="primary"
+                      onClick={() => {
+                        data.step = 0;
+                        getStepELe();
+                      }}
+                    >
+                      再看一遍
+                    </Button>
+                    <Button class={[styles.btn,styles.endBtn]} round type="primary" onClick={() =>endGuide()}>
+                      完成
+                    </Button>
+                  </>
+                ) : (
+                  <Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+
+                    下一步 ({data.step + 1}/{data.steps.length})
+                  </Button>
+                )}
+              </div>
+            </div>
+          ))}
+        </div>
+      </div>
+      </Popup>
+    );
+  },
+});

+ 299 - 277
src/views/co-ai/index.module.less

@@ -1,360 +1,382 @@
 .back {
-    position: fixed;
-    left: 15px;
-    top: 17px;
-    width: 31px;
-    height: 31px;
+  position: fixed;
+  left: 15px;
+  top: 17px;
+  width: 31px;
+  height: 31px;
 
-    &>img {
-        width: 100%;
-        height: 100%;
-        object-fit: cover;
-    }
+  & > img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
 
-    &:active {
-        opacity: .8;
-    }
+  &:active {
+    opacity: 0.8;
+  }
 }
 
 .container {
-    background: url('../../common/images/icon_bg.png') no-repeat center center / cover;
-    padding: 47px 12px 20px 54px;
-    height: 100vh;
-    overflow: hidden;
+  background: url('../../common/images/icon_bg.png') no-repeat center center /
+    cover;
+  padding: 47px 12px 20px 54px;
+  height: 100vh;
+  overflow: hidden;
 }
 
 .content {
-    display: flex;
-    height: calc(100vh - 67px);
-    overflow: hidden;
+  display: flex;
+  height: calc(100vh - 67px);
+  overflow: hidden;
 }
 
 .opacityBg {
-    background: linear-gradient(134deg, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0.34) 100%);
-    border-radius: 18px;
-    border: 2px solid #fff;
+  background: linear-gradient(
+    134deg,
+    rgba(255, 255, 255, 0.75) 0%,
+    rgba(255, 255, 255, 0.34) 100%
+  );
+  border-radius: 18px;
+  border: 2px solid #fff;
 }
 
 .leftContent {
-    position: relative;
-    display: flex;
-    width: 45%;
+  position: relative;
+  display: flex;
+  width: 45%;
 }
 
 .leftBg {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 95px;
-    height: 100%;
-    background: linear-gradient(48deg, #43B2FF 0%, #159AF7 100%);
-    border: 2Px solid #fff;
-    border-radius: 18px 9px 0 18px;
-    z-index: 1;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 95px;
+  height: 100%;
+  background: linear-gradient(48deg, #43b2ff 0%, #159af7 100%);
+  border: 2px solid #fff;
+  border-radius: 18px 9px 0 18px;
+  z-index: 1;
 }
 
 .leftBg2 {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: calc(100% - 12px);
-    height: 100%;
-    background: linear-gradient(134deg, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0.34) 100%);
-    border-radius: 18px;
-    border: 2Px solid #fff;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: calc(100% - 12px);
+  height: 100%;
+  background: linear-gradient(
+    134deg,
+    rgba(255, 255, 255, 0.75) 0%,
+    rgba(255, 255, 255, 0.34) 100%
+  );
+  border-radius: 18px;
+  border: 2px solid #fff;
 }
 
 .types {
+  position: relative;
+  top: 2px;
+  width: 95px;
+  height: calc(100% - 4px);
+  padding: 4px 0;
+  overflow-x: hidden;
+  overflow-y: auto;
+  border-radius: 18px;
+  z-index: 1;
+  flex-shrink: 0;
+
+  &::-webkit-scrollbar {
+    width: 0;
+    display: none;
+  }
+
+  .type {
     position: relative;
-    top: 2Px;
-    width: 95px;
-    height: calc(100% - 4Px);
-    padding: 4px 0;
-    overflow-x: hidden;
-    overflow-y: auto;
-    border-radius: 18px;
-    z-index: 1;
-    flex-shrink: 0;
-
-    &::-webkit-scrollbar {
-        width: 0;
-        display: none;
+    padding: 4px 12px;
+
+    &.typeActive {
+      .typeImg {
+        padding: 6px;
+        border-color: #99ffd0;
+        animation: scaleBtn 1s ease-in-out;
+      }
     }
+  }
 
-    .type {
-        position: relative;
-        padding: 4px 12px;
-
-        &.typeActive {
-            .typeImg {
-                padding: 6px;
-                border-color: #99FFD0;
-                animation: scaleBtn 1s ease-in-out;
-            }
-        }
-    }
-
-    .typeImg {
-        border: 2px solid transparent;
-        border-radius: 6px;
-        height: 95px;
-        transition: .3s;
+  .typeImg {
+    border: 2px solid transparent;
+    border-radius: 6px;
+    height: 95px;
+    transition: 0.3s;
 
-        &:active {
-            transform: scale(0.8);
-        }
-    }
-
-    .typeIcon {
-        display: block;
-        width: 100%;
-        height: 100%;
-        object-fit: cover;
-        opacity: 0;
-        transition: opacity .3s;
+    &:active {
+      transform: scale(0.8);
     }
+  }
 
-    .typeIcon[loaded="true"] {
-        opacity: 1;
-    }
+  .typeIcon {
+    display: block;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    opacity: 0;
+    transition: opacity 0.3s;
+  }
+
+  .typeIcon[loaded='true'] {
+    opacity: 1;
+  }
 }
 
 .center {
-    flex: 1;
-    position: relative;
-    padding-right: 12px;
-    height: 100%;
-    overflow: hidden;
-
-    :global {
-        .van-search {
-            padding: 6px 9px;
-            width: 100%;
-            z-index: 1;
-        }
-        .van-field__control::-webkit-input-placeholder{
-            font-size: 12Px;
-        }
+  flex: 1;
+  position: relative;
+  padding-right: 12px;
+  height: 100%;
+  overflow: hidden;
+  .centerSearch {
+    padding: 6px 9px;
+  }
+  :global {
+    #coai-0 {
+      .van-search {
+        width: 100%;
+        z-index: 1;
+        padding: 0px 0px;
+      }
+      .van-field__control::-webkit-input-placeholder {
+        font-size: 12px;
+      }
     }
+  }
 }
 
 .musicContent {
-    width: 100%;
-    height: calc(100% - var(--van-search-input-height) - 12px - 2Px);
-    padding: 6px 12px 12px 12px;
-    overflow-x: hidden;
-    overflow-y: auto;
-
-    &::-webkit-scrollbar {
-        width: 0;
-        display: none;
-    }
+  width: 100%;
+  height: calc(100% - var(--van-search-input-height) - 12px - 2px);
+  padding: 6px 12px 12px 12px;
+  overflow-x: hidden;
+  overflow-y: auto;
+
+  &::-webkit-scrollbar {
+    width: 0;
+    display: none;
+  }
 }
-.searchNotice{
-    position: fixed;
-    padding: 0;
-    pointer-events: none;
-    :global{
-        .van-notice-bar{
-            padding: 0;
-            height: 100%;
-        }
+.searchNotice {
+  position: fixed;
+  padding: 0;
+  pointer-events: none;
+  :global {
+    .van-notice-bar {
+      padding: 0;
+      height: 100%;
     }
+  }
 }
-.searchNoticeShow{
-    :global{
-        .van-field__control{
-            opacity: 0;
-        }
+.searchNoticeShow {
+  :global {
+    .van-field__control {
+      opacity: 0;
     }
+  }
 }
 .musicItem {
-    position: relative;
-    display: flex;
-    align-items: center;
-    border: 3px solid #fff;
-    border-radius: 9px;
-    margin-bottom: 6px;
-    background-color: #fff;
-    padding: 4px;
-    transition: all .3s;
-    overflow: hidden;
-    --van-notice-bar-text-color: #333;
-
-    &.disableNotic {
-        :global {
-            .van-notice-bar__content {
-                transition-duration: 0s !important;
-                transform: none !important;
-            }
-        }
+  position: relative;
+  display: flex;
+  align-items: center;
+  border: 3px solid #fff;
+  border-radius: 9px;
+  margin-bottom: 6px;
+  background-color: #fff;
+  padding: 4px;
+  transition: all 0.3s;
+  overflow: hidden;
+  --van-notice-bar-text-color: #333;
+
+  &.disableNotic {
+    :global {
+      .van-notice-bar__content {
+        transition-duration: 0s !important;
+        transform: none !important;
+      }
     }
+  }
+
+  &.musicActive {
+    border-width: 3px;
+    background: linear-gradient(180deg, #ffffff 0%, #bfe1ff 100%);
+    transform: scale(1.05);
+    box-shadow: 0px 2px 4px 0px rgba(73, 159, 228, 1);
+    --van-notice-bar-text-color: rgba(73, 159, 228, 1);
 
-    &.musicActive {
-        border-width: 3px;
-        background: linear-gradient(180deg, #FFFFFF 0%, #BFE1FF 100%);
-        transform: scale(1.05);
-        box-shadow: 0px 2px 4px 0px rgba(73, 159, 228, 1);
-        --van-notice-bar-text-color: rgba(73, 159, 228, 1);
-
-        :global {
-            .van-notice-bar__content {
-                transition-property: transform;
-            }
-        }
+    :global {
+      .van-notice-bar__content {
+        transition-property: transform;
+      }
     }
+  }
+
+  .musicAvtor {
+    display: block;
+    width: 7.2vw;
+    height: 7.2vw;
+    border-radius: 10px;
+    object-fit: cover;
+    flex-shrink: 0;
+    margin-right: 1vw;
+    opacity: 0;
+    transition: opacity 0.3s;
+  }
+
+  .musicAvtor[loaded='true'] {
+    opacity: 1;
+  }
 
-    .musicAvtor {
-        display: block;
-        width: 7.2vw;
-        height: 7.2vw;
-        border-radius: 10Px;
-        object-fit: cover;
-        flex-shrink: 0;
-        margin-right: 1vw;
-        opacity: 0;
-        transition: opacity .3s;
+  .musicInfo {
+    flex: 1;
+
+    .musicName {
+      font-weight: 600;
+      color: #333;
+      margin-bottom: 3px;
+    }
+
+    .noticeBar {
+      padding: 0;
+      height: 28px;
     }
 
-    .musicAvtor[loaded="true"] {
-        opacity: 1;
+    .musicDes {
+      width: 100%;
+      display: flex;
+      align-items: center;
     }
 
-    .musicInfo {
-        flex: 1;
-
-        .musicName {
-            font-weight: 600;
-            color: #333;
-            margin-bottom: 3px;
-        }
-
-        .noticeBar {
-            padding: 0;
-            height: 28px;
-        }
-
-        .musicDes {
-            width: 100%;
-            display: flex;
-            align-items: center;
-        }
-
-        .musicFavitor {
-            border: 1px solid #FFC5C5;
-            color: #FF6A6A;
-            padding: 1px 3px 1px 14px;
-            border-radius: 4px;
-            background-color: #FFF8F7;
-            background-image: url('./image/icon_hot.svg');
-            background-repeat: no-repeat;
-            background-size: auto 70%;
-            background-position: 2px center;
-            margin-right: 4px;
-        }
-
-        .musicAuthor {
-            flex: 1;
-            font-size: 12px;
-            font-weight: 400;
-            color: #777;
-            line-height: 12px;
-            max-width: 9vw;
-        }
+    .musicFavitor {
+      border: 1px solid #ffc5c5;
+      color: #ff6a6a;
+      padding: 1px 3px 1px 14px;
+      border-radius: 4px;
+      background-color: #fff8f7;
+      background-image: url('./image/icon_hot.svg');
+      background-repeat: no-repeat;
+      background-size: auto 70%;
+      background-position: 2px center;
+      margin-right: 4px;
     }
 
-    .musicIcon {
-        flex-shrink: 0;
-        margin-right: 4px;
+    .musicAuthor {
+      flex: 1;
+      font-size: 12px;
+      font-weight: 400;
+      color: #777;
+      line-height: 12px;
+      max-width: 9vw;
     }
+  }
+
+  .musicIcon {
+    flex-shrink: 0;
+    margin-right: 4px;
+  }
 }
 
 .right {
-    position: relative;
-    background: #fff;
-    overflow: hidden;
-    border: none;
-    width: 55%;
+  position: relative;
+  background: #fff;
+  overflow: hidden;
+  border: none;
+  width: 55%;
 }
 
 .right-musicName {
-    font-size: 15px;
-    font-weight: 500;
-    color: #131415;
-    line-height: 20px;
-    text-align: center;
-    padding: 12px 0;
+  font-size: 15px;
+  font-weight: 500;
+  color: #131415;
+  line-height: 20px;
+  text-align: center;
+  padding: 12px 0;
 }
 
 .staff {
-    width: 100%;
+  width: 100%;
 }
 
 .rightBtns {
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    padding: 0 8px 18px 8px;
-    display: flex;
-    align-items: flex-end;
-    height: 78px;
-    background: #fff;
-    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #C1EEFF 100%);
-    border-radius: 0 0 18px 18px;
-
-    &>img {
-        margin: 0 4px;
-        height: 30px;
-        transition: .3s;
-
-        &:active {
-            transform: scale(0.6);
-        }
-    }
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  padding: 0 8px 18px 8px;
+  display: flex;
+  align-items: flex-end;
+  height: 78px;
+  background: #fff;
+  background-image: linear-gradient(
+    180deg,
+    rgba(255, 255, 255, 0) 0%,
+    #c1eeff 100%
+  );
+  border-radius: 0 0 18px 18px;
+
+  & > img {
+    margin: 0 4px;
+    height: 30px;
+    transition: 0.3s;
 
-    &>img:last-child {
-        margin-left: auto;
-        animation: scaleBtn 1s ease-in-out infinite;
+    &:active {
+      transform: scale(0.6);
     }
+  }
+  .rightBtnsRight {
+    transition: 0.3s;
+    margin: 0 4px;
+    padding: 5px 10px 0;
+    margin-left: auto;
+    img {
+      height: 30px;
+      animation: scaleBtn 1s ease-in-out infinite;
+    }
+  }
 }
 
 @keyframes scaleBtn {
-    0% {
-        transform: scale(1);
-    }
+  0% {
+    transform: scale(1);
+  }
 
-    50% {
-        transform: scale(1.1);
-    }
+  50% {
+    transform: scale(1.1);
+  }
 
-    100% {
-        transform: scale(1);
-    }
+  100% {
+    transform: scale(1);
+  }
 }
 
 @keyframes displayIcon {
-    to {
-        opacity: 1;
-    }
+  to {
+    opacity: 1;
+  }
 }
 
 .loadingWrap {
-    display: flex;
-    justify-content: center;
-    min-height: 80Px;
+  display: flex;
+  justify-content: center;
+  min-height: 80px;
 }
 
 .empty {
-    :global {
-        .van-empty__image {
-            width: 100%;
-            height: initial;
-        }
-
-        .van-empty__description {
-            color: #fff;
-            padding: 0;
-        }
+  :global {
+    .van-empty__image {
+      width: 100%;
+      height: initial;
     }
-}
+
+    .van-empty__description {
+      color: #fff;
+      padding: 0;
+    }
+  }
+}

+ 39 - 26
src/views/co-ai/index.tsx

@@ -33,6 +33,7 @@ import html2canvas from 'html2canvas';
 import { api_musicSheetCategoriesPage, api_musicSheetPage } from './api';
 import { state } from '@/state';
 import MEmpty from '@/components/m-empty';
+import Coaiguide from '@/custom-plugins/guide-page/coai-guide'
 import { usePageVisibility } from '@vant/use';
 export default defineComponent({
   name: 'co-ai',
@@ -79,9 +80,8 @@ export default defineComponent({
     };
     /** 去云教练 */
     const handleGoto = () => {
-      let src = `${location.origin}/instrument?id=${
-        data.musics[data.musicIndex]?.id
-      }`;
+      let src = `${location.origin}/instrument?id=${data.musics[data.musicIndex]?.id
+        }`;
       console.log(src);
       postMessage({
         api: 'openAccompanyWebView',
@@ -202,6 +202,7 @@ export default defineComponent({
       });
       setSearchBox();
     });
+
     return () => (
       <div class={styles.container}>
         <div class={styles.back} onClick={goback}>
@@ -218,7 +219,7 @@ export default defineComponent({
                     class={[
                       styles.type,
                       musicForms.musicSheetCategoriesId === item.id &&
-                        styles.typeActive
+                      styles.typeActive
                     ]}
                     onClick={() => {
                       musicForms.musicSheetCategoriesId = item.id;
@@ -239,26 +240,30 @@ export default defineComponent({
               })}
             </div>
             <div class={styles.center}>
-              <MSearch
-                class={["searchNotice", data.searchNoticeShow ? styles.searchNoticeShow : '']}
-                shape="round"
-                background="transparent"
-                clearable={false}
-                placeholder="请输入关键字"
-                onFocus={() => (data.searchNoticeShow = false)}
-                onBlur={(val) => {
-                  musicForms.keyword = val;
-                  requestAnimationFrame(() => {
-                    requestAnimationFrame(() => {
-                      data.searchNoticeShow = true;
-                    });
-                  });
-                }}
-                onSearch={val => {
-                  musicForms.keyword = val;
-                  handleReset();
-                }}
-              />
+              <div class={styles.centerSearch}>
+                <div id="coai-0">
+                  <MSearch
+
+                    class={["searchNotice", data.searchNoticeShow ? styles.searchNoticeShow : '']}
+                    shape="round"
+                    background="transparent"
+                    clearable={false}
+                    placeholder="请输入关键字"
+                    onFocus={() => (data.searchNoticeShow = false)}
+                    onBlur={(val) => {
+                      musicForms.keyword = val;
+                      requestAnimationFrame(() => {
+                        requestAnimationFrame(() => {
+                          data.searchNoticeShow = true;
+                        });
+                      });
+                    }}
+                    onSearch={val => {
+                      musicForms.keyword = val;
+                      handleReset();
+                    }}
+                  />
+                </div></div>
               <div class={styles.musicContent}>
                 {data.musics.map((item: any, index: number) => {
                   return (
@@ -352,11 +357,17 @@ export default defineComponent({
 
             <div class={styles.rightBtns}>
               <img
+                id="coai-1"
                 src={data.isShowJianpu ? icon_jianpuActive : icon_jianpu}
                 onClick={() => (data.isShowJianpu = !data.isShowJianpu)}
               />
-              <img src={icon_down} onClick={handleSave} />
-              <img src={icons.icon_start} onClick={() => handleGoto()} />
+              <img id="coai-2" src={icon_down} onClick={handleSave} />
+              <div class={styles.rightBtnsRight} id="coai-3">
+                <img src={icons.icon_start} onClick={() => handleGoto()} />
+              </div>
+
+
+
             </div>
           </div>
         </div>
@@ -370,6 +381,8 @@ export default defineComponent({
             />
           </div>
         )}
+
+        <Coaiguide ></Coaiguide>
       </div>
     );
   }

+ 22 - 7
src/views/courseware-list/component/book/index.tsx

@@ -4,7 +4,8 @@ import {
   nextTick,
   onMounted,
   reactive,
-  watch
+  watch,
+  ref
 } from 'vue';
 import styles from './index.module.less';
 import icon_back from '../../image/icon_back.svg';
@@ -13,7 +14,7 @@ import { useRouter } from 'vue-router';
 import { postMessage } from '@/helpers/native-message';
 import { showToast } from 'vant';
 import queryString from 'query-string';
-
+import CoursewareDetail from '@/custom-plugins/guide-page/courseware-detail'
 export default defineComponent({
   name: 'the-book',
   props: {
@@ -40,6 +41,7 @@ export default defineComponent({
       transform: '',
       list: [] as any[][]
     });
+    const showGuide = ref(false)
     const handleCreate = (key: string, url: string) => {
       return new Promise((resolve, reject) => {
         const _s = document.head.querySelector(`script[data-key="${key}"]`);
@@ -100,14 +102,21 @@ export default defineComponent({
         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);
+
+              setTimeout(() => {
+                showGuide.value = true;
+              }, 1500)
             });
           });
         });
@@ -216,8 +225,9 @@ export default defineComponent({
                   <div class="page">
                     <div class="gradient"></div>
                     <div class={styles.wrap}>
-                      {list.map((item: any) => {
-                        return (
+                      {list.map((item: any, index: number) => {
+                        return <>
+
                           <div
                             class={[styles.item, item.id && styles.des]}
                             onTouchstart={(e: TouchEvent) => {
@@ -227,12 +237,13 @@ export default defineComponent({
                               e.stopPropagation();
                               handleOpenPlay(item);
                             }}>
-                            <div class={styles.name}>{item.name}</div>
+                            <div class={styles.name} >{item.name}</div>
                             {item.id ? (
-                              <img class={styles.icon} src={icon_play} />
+                              <img id={index == 1 ? 'coursewareDetail-0' : ''} class={styles.icon} src={icon_play} />
                             ) : null}
                           </div>
-                        );
+
+                        </>
                       })}
                     </div>
                   </div>
@@ -244,7 +255,11 @@ export default defineComponent({
             </div>
           )}
         </div>
+        {showGuide.value ? <CoursewareDetail></CoursewareDetail> : null}
+
       </div>
     );
   }
 });
+
+

+ 50 - 24
src/views/courseware-list/index.tsx

@@ -23,7 +23,7 @@ import TheFavorite from '@/components/the-favorite';
 import { useRouter } from 'vue-router';
 import TheBook from './component/book';
 import { postMessage } from '@/helpers/native-message';
-
+import CoursewareList from '@/custom-plugins/guide-page/courseware-list'
 import './jquery.min.1.7.js';
 import './turn.js';
 import MEmpty from '@/components/m-empty';
@@ -76,7 +76,7 @@ export default defineComponent({
       forms.currentGradeNum = index;
       handleChange();
     };
-
+const isShowGuide = ref(false)
     const data = reactive({
       list: [] as any[],
       loading: false,
@@ -104,6 +104,7 @@ export default defineComponent({
         });
       }
       data.loading = false;
+      isShowGuide.value = true
     };
     const getFavoriteList = async () => {
       data.loading = true;
@@ -205,8 +206,10 @@ export default defineComponent({
             class={styles.tabs}
             v-model:active={data.tab}
             onChange={() => handleChange()}>
-            <Tab title="全部教材" name="all"></Tab>
-            <Tab title="我的收藏" name="favorite"></Tab>
+            <Tab title="全部教材"   name="all"></Tab>
+            <Tab  name="favorite" v-slots={{
+              title:() => (<div id='courseware-2'>我的收藏</div>)
+            }}></Tab>
           </Tabs>
           <Popover
             v-model:show={popoverShow.value}
@@ -215,7 +218,7 @@ export default defineComponent({
             onSelect={onSelect}>
             {{
               reference: () => (
-                <Button class={styles.downBtn} round size="small">
+                <Button class={styles.downBtn} round size="small" {...{id:'courseware-3'}} >
                   {BOOK_DATA.grades[forms.currentGradeNum].text}{' '}
                   {/* <img class={styles.icon} src={icon_arrow} /> */}
                   <svg
@@ -277,22 +280,44 @@ export default defineComponent({
                   ]}
                   key={item.key}
                   onClick={() => handleOpen(item)}>
-                  <div class={styles.containerImg}>
-                    <NImage
-                      data-id={item.id}
-                      class={[styles.cover, item.load ? styles.loaded : '']}
-                      objectFit="cover"
-                      src={item.coverImg}
-                      onLoad={() => {
-                        item.load = true;
-                      }}
-                      onError={() => {
-                        item.load = true;
-                      }}
-                    />
-                  </div>
+                    {/* courseware- */}
+                    {index==0?<NImage
+                    data-id={item.id}
+                    id='courseware-0'
+                    class={[styles.cover, item.load ? styles.loaded : '']}
+                    objectFit="cover"
+                    src={item.coverImg}
+                    onLoad={() => {
+                      item.load = true;
+                    }}
+                    onError={() => {
+                      item.load = true;
+                    }}
+                  />:        <NImage
+                  data-id={item.id}
+                  class={[styles.cover, item.load ? styles.loaded : '']}
+                  objectFit="cover"
+                  src={item.coverImg}
+                  onLoad={() => {
+                    item.load = true;
+                  }}
+                  onError={() => {
+                    item.load = true;
+                  }}
+                />}
+
                   <div class={styles.name}>{item.name}</div>
-                  <div
+                  {index==0? <div
+                   id='courseware-1'
+                    class={styles.favoriteBtn}
+                    onClick={(e: Event) => {
+                      e.stopPropagation();
+                      if (data.tab !== 'all') return;
+                      item.favoriteFlag = !item.favoriteFlag;
+                      dubounce(() => handleFavorite(item));
+                    }}>
+                    <TheFavorite isFavorite={data.tab !== 'all' ? true : item.favoriteFlag} />
+                  </div>: <div
                     class={styles.favoriteBtn}
                     onClick={(e: Event) => {
                       e.stopPropagation();
@@ -300,10 +325,9 @@ export default defineComponent({
                       item.favoriteFlag = !item.favoriteFlag;
                       dubounce(() => handleFavorite(item));
                     }}>
-                    <TheFavorite
-                      isFavorite={data.tab !== 'all' ? true : item.favoriteFlag}
-                    />
-                  </div>
+                    <TheFavorite isFavorite={data.tab !== 'all' ? true : item.favoriteFlag} />
+                  </div>}
+
                 </div>
               );
             })}
@@ -322,6 +346,8 @@ export default defineComponent({
             data.showBook = false;
           }}
         />
+        {isShowGuide.value? <CoursewareList></CoursewareList>:null}
+
       </div>
     );
   }

+ 10 - 7
src/views/knowledge-library/index.module.less

@@ -8,10 +8,10 @@
     display: flex;
     align-items: center;
     height: 24px;
-    background: #FFFFFF;
+    background: #ffffff;
     border-radius: 12px;
     font-size: 14px;
-    color: #0E71BC;
+    color: #0e71bc;
     padding: 0 8px;
 
     .iconWroing {
@@ -44,7 +44,10 @@
     display: inline-block;
     width: 139px;
     height: 49px;
-    border: none
+    border: none;
+    &:hover {
+      opacity: 0.8;
+    }
   }
 
   .btnPractice {
@@ -60,7 +63,7 @@
 }
 
 .containerSection {
-  background: #87D1F0;
+  background: #87d1f0;
   border-radius: 20px 20px 0px 0px;
   padding: 15px;
 
@@ -109,7 +112,7 @@
         height: 14px;
         border-radius: 2px;
         margin-right: 6px;
-        background: linear-gradient(to bottom, #259CFE, #3FC2FF);
+        background: linear-gradient(to bottom, #259cfe, #3fc2ff);
       }
 
       span {
@@ -125,7 +128,7 @@
     position: relative;
     max-height: 154px;
 
-    &+.unitItem {
+    & + .unitItem {
       margin-top: 12px;
     }
 
@@ -155,4 +158,4 @@
     width: 100%;
     max-height: 154px;
   }
-}
+}

+ 21 - 7
src/views/knowledge-library/index.tsx

@@ -9,7 +9,7 @@ import library1 from './images/library-1.png';
 import library2 from './images/library-2.png';
 import library3 from './images/library-3.png';
 import { useEventListener, useWindowScroll } from '@vueuse/core';
-
+import KnowledgeGuide from '@/custom-plugins/guide-page/knowledge-guide'
 export default defineComponent({
   name: 'knowledge-ligrary',
   setup() {
@@ -122,14 +122,17 @@ export default defineComponent({
         </MSticky>
 
         <div class={styles.btnGroup}>
-          <Button
+
+          <div id='knowledge-0'
             class={styles.btnPractice}
-            round
-            onClick={() => onGotoModel('PRACTICE')}></Button>
-          <Button
+
+            onClick={() => onGotoModel('PRACTICE')}></div>
+
+          <div
+            id='knowledge-1'
             class={styles.btnTest}
-            round
-            onClick={() => onGotoModel('TEST')}></Button>
+
+            onClick={() => onGotoModel('TEST')}></div>
         </div>
 
         <div class={[styles.containerSection, styles.librarySection]}>
@@ -152,6 +155,16 @@ export default defineComponent({
                           }
                         })
                       }>
+                      {index == 0 ? <Image
+                        id='knowledge-2'
+                        class={styles.unitImg}
+                        lazyLoad
+                        src={getBg(index)}
+                      /> : <Image
+                        class={styles.unitImg}
+                        lazyLoad
+                        src={getBg(index)}
+                      />}
                       <Image
                         class={styles.unitImg}
                         lazyLoad
@@ -166,6 +179,7 @@ export default defineComponent({
             ))}
           </Collapse>
         </div>
+        <KnowledgeGuide></KnowledgeGuide>
       </div>
     );
   }

+ 5 - 1
src/views/knowledge-library/wroing-book/index.tsx

@@ -10,7 +10,7 @@ import WoringStat from './images/woring-stat.png';
 import request from '@/helpers/request';
 import { browser } from '@/helpers/utils';
 import { postMessage } from '@/helpers/native-message';
-
+import WoringGuide from '@/custom-plugins/guide-page/woring-guide';
 export default defineComponent({
   name: 'wroing-book',
   setup() {
@@ -75,6 +75,7 @@ export default defineComponent({
 
         <div class={styles.woringSecgtion}>
           <Image
+            {...{ id: 'woring-0' }}
             lazyLoad
             src={WoringStat}
             class={styles.woringImg}
@@ -82,18 +83,21 @@ export default defineComponent({
           />
           {/* 错题练习 */}
           <Image
+            {...{ id: 'woring-1' }}
             lazyLoad
             src={WoringPractice}
             class={styles.woringImg}
             onClick={onErrorPractice}
           />
           <Image
+            {...{ id: 'woring-2' }}
             lazyLoad
             src={AiExam}
             class={styles.woringImg}
             onClick={() => router.push('ai-exam')}
           />
         </div>
+        <WoringGuide></WoringGuide>
       </div>
     );
   }