Browse Source

Merge branch 'ktyq-test-new' of http://git.dayaedu.com/liushengqiang/music-score into ktyq-test-new

TIANYONG 1 year ago
parent
commit
a7ff4b4ed3

+ 1 - 0
src/page-instrument/component/mode-type-mode/index.tsx

@@ -48,6 +48,7 @@ export default defineComponent({
       // console.log("🚀 ~ student:", student);
       if (storeData.user.vipMember) {
         data.showVip = false;
+        state.isVip = false;
         openGuid();
       }
     };

BIN
src/page-instrument/custom-plugins/guide-driver/images/evaluating/e4.png


BIN
src/page-instrument/custom-plugins/guide-driver/images/practise/d10.png


+ 60 - 0
src/page-instrument/custom-plugins/guide-driver/index.less

@@ -17,6 +17,10 @@
   background-size: contain;
   background-color: transparent !important;
 }
+.popoverClass .driver-popover-prev-btn {
+  font-weight: 600;
+  font-size: 13px;
+}
 
 .popoverClass .driver-popover-next-btn:hover,
 .popoverClass .driver-popover-prev-btn:hover,
@@ -184,6 +188,13 @@
     right: 24px;
     bottom: -48px;
   }
+
+  &.popoverClose {
+    .driver-popover-next-btn {
+      bottom: 0;
+      right: 0;
+    }
+  }
 }
 
 .popoverClass9 {
@@ -193,6 +204,19 @@
   background-size: contain;
 }
 
+.popoverClass10 {
+  width: 264px;
+  height: 245px;
+  background: url("./images/practise/d10.png") no-repeat center;
+  background-size: contain;
+
+  .driver-popover-next-btn {
+    right: 24px;
+    bottom: 23px;
+  }
+}
+
+
 .popoverClose {
   .driver-popover-navigation-btns {
     position: absolute;
@@ -241,6 +265,18 @@
   }
 }
 
+.popoverClassF2 {
+  width: 264px;
+  height: 245px;
+  background: url("./images/follow/f2.png") no-repeat center;
+  background-size: contain;
+
+  .driver-popover-next-btn {
+    right: 24px;
+    bottom: 23px;
+  }
+}
+
 .popoverClassE1 {
   width: 257px;
   height: 247px;
@@ -253,6 +289,30 @@
   }
 }
 
+.popoverClassE2 {
+  width: 257px;
+  height: 235px;
+  background: url("./images/evaluating/e4.png") no-repeat center;
+  background-size: contain;
+
+  .driver-popover-next-btn {
+    right: 17px;
+    bottom: 22px;
+  }
+}
+
+.popoverClassE3 {
+  width: 264px;
+  height: 245px;
+  background: url("./images/evaluating/e2.png") no-repeat center;
+  background-size: contain;
+
+  .driver-popover-next-btn {
+    right: 24px;
+    bottom: 23px;
+  }
+}
+
 .popoverClassER1 {
   width: 257px;
   height: 178px;

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


+ 321 - 206
src/page-instrument/custom-plugins/guide-driver/index.tsx

@@ -1,4 +1,4 @@
-import { Teleport, defineComponent, nextTick, onMounted, ref } from "vue";
+import { PropType, Teleport, defineComponent, nextTick, onMounted, ref } from "vue";
 import { Config, DriveStep, PopoverDOM, State, driver } from "driver.js";
 import "driver.js/dist/driver.css";
 import state from "/src/state";
@@ -12,10 +12,28 @@ const endGuide = (guideInfo: any) => {
   }
 };
 
+/**
+ * 按钮状态
+ */
+type ButtonStatus = {
+  /** 声部状态 */
+  subjectStatus?: Boolean;
+  /** 练习模式 */
+  modelTypeStatus?: Boolean;
+};
+
 /** 练习模式 */
 export const PractiseDriver = defineComponent({
   name: "PractiseDriver",
-  setup() {
+  props: {
+    // 按钮状态
+    statusAll: {
+      type: Object as PropType<ButtonStatus>,
+      default: () => {},
+    },
+  },
+  setup(props) {
+    const driverNextStatus = ref(false);
     // 初始化部分引导位置
     const driverInitialPosition = (popover: PopoverDOM, options: { config: Config; state: State }) => {
       options.config.stageRadius = 5;
@@ -27,27 +45,19 @@ export const PractiseDriver = defineComponent({
     };
 
     const driverOptions = (): Config => {
-      let length = state.setting.displayFingering ? 9 : 8;
+      // 指法
+      let length = state.setting.displayFingering ? 10 : 9;
+      // 声部
+      if (!props.statusAll.subjectStatus) {
+        length -= 1;
+      }
+      // 练习模式
+      if(!props.statusAll.modelTypeStatus) {
+        length -= 1;
+      }
+
+      console.log(props.statusAll, 'statusAll', length)
 
-      // 乐器方向不一样引导位置不一样
-      const instrumentDirection: DriveStep = {
-        element: ".driver-7",
-        popover: {
-          title: "",
-          description: "",
-          popoverClass: `popoverClass ${state.fingeringInfo.direction === "transverse" ? "popoverClass7" : "popoverClass7-1"}`,
-          align: state.fingeringInfo.direction === "transverse" ? "start" : "center",
-          side: state.fingeringInfo.direction === "transverse" ? "top" : "left",
-          nextBtnText: "下一步7/" + length,
-          showButtons: ["next"],
-          onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
-            if (state.fingeringInfo.direction === "transverse") driverInitialPosition(popover, options);
-          },
-          onCloseClick: () => {
-            onDriverClose();
-          },
-        },
-      };
       let options: Config = {
         showProgress: false,
         allowClose: false,
@@ -56,6 +66,12 @@ export const PractiseDriver = defineComponent({
         onCloseClick: () => {
           onDriverClose();
         },
+        onHighlightStarted: () => {
+          driverNextStatus.value = true;
+        },
+        onHighlighted: () => {
+          driverNextStatus.value = false;
+        },
         steps: [
           {
             element: ".driver-1",
@@ -65,7 +81,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass1",
               align: "end",
               side: "top",
-              nextBtnText: "下一步1/" + length,
+              nextBtnText: `下一步 (1/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 options.config.stageRadius = 1000;
@@ -81,7 +97,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass2",
               align: "start",
               side: "top",
-              nextBtnText: "下一步2/" + length,
+              nextBtnText: `下一步 (2/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
@@ -96,7 +112,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass3",
               align: "start",
               side: "top",
-              nextBtnText: "下一步3/" + length,
+              nextBtnText: `下一步 (3/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
@@ -111,7 +127,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass4",
               align: "start",
               side: "top",
-              nextBtnText: "下一步4/" + length,
+              nextBtnText: `下一步 (4/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
@@ -126,22 +142,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass5",
               align: "start",
               side: "top",
-              nextBtnText: "下一步5/" + length,
-              showButtons: ["next"],
-              onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
-                driverInitialPosition(popover, options);
-              },
-            },
-          },
-          {
-            element: ".driver-6",
-            popover: {
-              title: "",
-              description: "",
-              popoverClass: "popoverClass popoverClass6",
-              align: "start",
-              side: "top",
-              nextBtnText: "下一步6/" + length,
+              nextBtnText: `下一步 (5/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
@@ -150,58 +151,92 @@ export const PractiseDriver = defineComponent({
           },
         ] as DriveStep[],
       };
+
+
+      if (props.statusAll.subjectStatus) {
+        options.steps?.push({
+          element: ".driver-10",
+          popover: {
+            title: "",
+            description: "",
+            popoverClass: "popoverClass popoverClass10",
+            align: "start",
+            side: "top",
+            nextBtnText: `下一步 (${options.steps.length + 1}/${length})`,
+            showButtons: ["next"],
+            onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+              driverInitialPosition(popover, options);
+            },
+          },
+        });
+      }
+
+      options.steps?.push({
+        element: ".driver-6",
+        popover: {
+          title: "",
+          description: "",
+          popoverClass: "popoverClass popoverClass6",
+          align: "start",
+          side: "top",
+          nextBtnText: `下一步 (${options.steps.length + 1}/${length})`, //"下一步6/" + length,
+          showButtons: ["next"],
+          onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+            driverInitialPosition(popover, options);
+          },
+        },
+      });
       // 是否有指法图
       if (state.setting.displayFingering) {
-        options.steps?.push(
-          instrumentDirection,
-          {
-            element: ".driver-8",
-            popover: {
-              title: "",
-              description: "",
-              popoverClass: "popoverClass popoverClass8",
-              align: "start",
-              side: "bottom",
-              nextBtnText: "下一步8/" + length,
-              showButtons: ["next"],
-              onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
-                options.config.stageRadius = 1000;
-                options.config.stagePadding = 0;
-                try {
-                  const rect = options.state.activeElement?.getBoundingClientRect();
-                  popover.wrapper.style.marginLeft = (rect?.width || 0) / 2 - 4 + "px";
-                } catch {}
-              },
+        // 乐器方向不一样引导位置不一样
+        options.steps?.push({
+          element: ".driver-7",
+          popover: {
+            title: "",
+            description: "",
+            popoverClass: `popoverClass ${state.fingeringInfo.direction === "transverse" ? "popoverClass7" : "popoverClass7-1"}`,
+            align: state.fingeringInfo.direction === "transverse" ? "start" : "center",
+            side: state.fingeringInfo.direction === "transverse" ? "top" : "left",
+            nextBtnText: `下一步 (${options.steps?.length + 1}/${length})`,
+            showButtons: ["next"],
+            onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+              if (state.fingeringInfo.direction === "transverse") driverInitialPosition(popover, options);
+            },
+            onCloseClick: () => {
+              onDriverClose();
             },
           },
-          {
-            element: ".driver/" + length,
-            popover: {
-              title: "",
-              description: "",
-              popoverClass: "popoverClass popoverClass9 popoverClose",
-              align: "end",
-              side: "bottom",
-              prevBtnText: "再看一遍",
-              doneBtnText: "完成",
-              showButtons: ["next", "previous"],
-              onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
-                options.config.stageRadius = 1000;
-                options.config.stagePadding = 0;
-                try {
-                  const rect = options.state.activeElement?.getBoundingClientRect();
-                  popover.wrapper.style.marginLeft = -((rect?.width || 0) / 2 - 8) + "px";
-                } catch {}
-              },
-              onPrevClick: () => {
-                driverObj.drive(0);
-              },
-              onNextClick: () => {
-                onDriverClose();
-              },
+        });
+      }
+
+      if(props.statusAll.modelTypeStatus) {
+        options.steps?.push({
+          element: ".driver-8",
+          popover: {
+            title: "",
+            description: "",
+            popoverClass: "popoverClass popoverClass8 popoverClose",
+            align: "start",
+            side: "bottom",
+            prevBtnText: "再看一遍",
+            doneBtnText: "完成",
+            showButtons: ["next", "previous"],
+            onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+              options.config.stageRadius = 1000;
+              options.config.stagePadding = 0;
+              try {
+                const rect = options.state.activeElement?.getBoundingClientRect();
+                popover.wrapper.style.marginLeft = (rect?.width || 0) / 2 - 4 + "px";
+              } catch {}
             },
-          }
-        );
+            onPrevClick: () => {
+              driverObj.drive(0);
+            },
+            onNextClick: () => {
+              onDriverClose();
+            },
+          },
+        });
       } else {
         options.steps?.push(
           {
@@ -212,7 +247,7 @@ export const PractiseDriver = defineComponent({
               popoverClass: "popoverClass popoverClass8",
               align: "start",
               side: "bottom",
-              nextBtnText: "下一步8/9",
+              nextBtnText: `下一步 (${options.steps.length + 1}/${length})`,
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 options.config.stageRadius = 1000;
@@ -253,19 +288,22 @@ export const PractiseDriver = defineComponent({
           }
         );
       }
+
       return options;
     };
 
     let driverObj: any;
 
     const handleClickOutside = (event: any) => {
-      if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
-        if (driverObj.isLastStep()) {
-          onDriverClose();
-        } else {
-          driverObj.moveNext(); // 跳转到下一步
+        // 如果高亮没有结束则下进行下一步
+        if (driverNextStatus.value) return;
+        if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
+          if (driverObj.isLastStep()) {
+            onDriverClose();
+          } else {
+            driverObj.moveNext(); // 跳转到下一步
+          }
         }
-      }
     };
 
     const guideInfo = ref({} as any);
@@ -287,8 +325,9 @@ export const PractiseDriver = defineComponent({
           document.addEventListener("click", handleClickOutside, true);
           driverObj = driver(driverOptions());
           nextTick(() => {
-            driverObj.drive(0);
+            driverObj.drive();
             showCloseBtn.value = true;
+            state.hasDriverPop = true;
           });
         }
       } catch (e) {
@@ -309,6 +348,7 @@ export const PractiseDriver = defineComponent({
       driverObj.destroy();
       document.querySelector(".driver-popover-close-btn-custom")?.remove();
       document.removeEventListener("click", handleClickOutside);
+      state.hasDriverPop = false
     };
 
     return () => (
@@ -329,7 +369,15 @@ export const PractiseDriver = defineComponent({
 /** 跟练模式 */
 export const FollowDriver = defineComponent({
   name: "FollowDriver",
-  setup() {
+  props: {
+    // 按钮状态
+    statusAll: {
+      type: Object as PropType<ButtonStatus>,
+      default: () => {},
+    },
+  },
+  setup(props) {
+    const driverNextStatus = ref(false);
     // 初始化部分引导位置
     const driverInitialPosition = (popover: PopoverDOM, options: { config: Config; state: State }) => {
       options.config.stageRadius = 5;
@@ -340,11 +388,22 @@ export const FollowDriver = defineComponent({
       } catch {}
     };
 
+    // 声部
+    let length = props.statusAll.subjectStatus ? 4 : 3;
     const driverOptions: Config = {
       showProgress: false,
       allowClose: false,
       popoverOffset: 3,
       disableActiveInteraction: true,
+      onCloseClick: () => {
+        onDriverClose();
+      },
+      onHighlightStarted: () => {
+        driverNextStatus.value = true;
+      },
+      onHighlighted: () => {
+        driverNextStatus.value = false;
+      },
       steps: [
         {
           element: ".follow-1",
@@ -354,15 +413,12 @@ export const FollowDriver = defineComponent({
             popoverClass: "popoverClass popoverClassF1",
             align: "end",
             side: "top",
-            nextBtnText: "下一步1/3",
+            nextBtnText: `下一步 (1/${length})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               options.config.stageRadius = 1000;
               options.config.stagePadding = 0;
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
@@ -370,50 +426,64 @@ export const FollowDriver = defineComponent({
           popover: {
             title: "",
             description: "",
-            popoverClass: "popoverClass popoverClass5",
+            popoverClass: "popoverClass popoverClassF2",
             align: "start",
             side: "top",
-            nextBtnText: "下一步2/3",
+            nextBtnText: `下一步 (2/${length})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options);
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
-          },
-        },
-        {
-          element: ".driver-6",
-          popover: {
-            title: "",
-            description: "",
-            popoverClass: "popoverClass popoverClass6 popoverClose",
-            align: "start",
-            side: "top",
-            prevBtnText: "再看一遍",
-            doneBtnText: "完成",
-            showButtons: ["next", "previous"],
-            onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
-              driverInitialPosition(popover, options);
-            },
-            onPrevClick: () => {
-              driverObj.drive(0);
-            },
-            onNextClick: () => {
-              onDriverClose();
-            },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
       ],
     };
 
+    if (props.statusAll.subjectStatus) {
+      driverOptions.steps?.push({
+        element: ".driver-10",
+        popover: {
+          title: "",
+          description: "",
+          popoverClass: "popoverClass popoverClass10",
+          align: "start",
+          side: "top",
+          nextBtnText: `下一步 (${driverOptions.steps.length + 1}/${length})`,
+          showButtons: ["next"],
+          onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+            driverInitialPosition(popover, options);
+          },
+        },
+      });
+    }
+
+    driverOptions.steps?.push({
+      element: ".driver-6",
+      popover: {
+        title: "",
+        description: "",
+        popoverClass: "popoverClass popoverClass6 popoverClose",
+        align: "start",
+        side: "top",
+        prevBtnText: "再看一遍",
+        doneBtnText: "完成",
+        showButtons: ["next", "previous"],
+        onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+          driverInitialPosition(popover, options);
+        },
+        onPrevClick: () => {
+          driverObj.drive(0);
+        },
+        onNextClick: () => {
+          onDriverClose();
+        },
+      },
+    });
+
     let driverObj: any;
 
     const handleClickOutside = (event: any) => {
+      if (driverNextStatus.value) return;
       if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
         if (driverObj.isLastStep()) {
           onDriverClose();
@@ -438,10 +508,11 @@ export const FollowDriver = defineComponent({
         }
         if (!(guideInfo.value && guideInfo.value.followDriver)) {
           document.addEventListener("click", handleClickOutside, true);
-          driverObj = driver(driverOptions);
           nextTick(() => {
+            driverObj = driver(driverOptions);
             driverObj.drive(0);
             showCloseBtn.value = true;
+            state.hasDriverPop = true;
           });
         }
       } catch (e) {
@@ -462,6 +533,7 @@ export const FollowDriver = defineComponent({
       driverObj.destroy();
       document.querySelector(".driver-popover-close-btn-custom")?.remove();
       document.removeEventListener("click", handleClickOutside);
+      state.hasDriverPop = false
     };
 
     return () => (
@@ -482,7 +554,15 @@ export const FollowDriver = defineComponent({
 // 评测模式
 export const EvaluatingDriver = defineComponent({
   name: "EvaluatingDriver",
-  setup() {
+  props: {
+    // 按钮状态
+    statusAll: {
+      type: Object as PropType<ButtonStatus>,
+      default: () => {},
+    },
+  },
+  setup(props) {
+    const driverNextStatus = ref(false);
     // 初始化部分引导位置
     const driverInitialPosition = (popover: PopoverDOM, options: { config: Config; state: State }) => {
       options.config.stageRadius = 5;
@@ -493,11 +573,23 @@ export const EvaluatingDriver = defineComponent({
       } catch {}
     };
 
+    // 声部
+    let length = props.statusAll.subjectStatus ? 5 : 4;
+
     const driverOptions: Config = {
       showProgress: false,
       allowClose: false,
       popoverOffset: 3,
       disableActiveInteraction: true,
+      onCloseClick: () => {
+        onDriverClose();
+      },
+      onHighlightStarted: () => {
+        driverNextStatus.value = true;
+      },
+      onHighlighted: () => {
+        driverNextStatus.value = false;
+      },
       steps: [
         {
           element: ".evaluting-1",
@@ -507,65 +599,92 @@ export const EvaluatingDriver = defineComponent({
             popoverClass: "popoverClass popoverClassE1",
             align: "end",
             side: "top",
-            nextBtnText: "下一步1/3",
+            nextBtnText: `下一步 (1/${length})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               options.config.stageRadius = 1000;
               options.config.stagePadding = 0;
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
-          element: ".driver-5",
+          element: ".driver-4",
           popover: {
             title: "",
             description: "",
-            popoverClass: "popoverClass popoverClass5",
+            popoverClass: "popoverClass popoverClassE2",
             align: "start",
             side: "top",
-            nextBtnText: "下一步2/3",
+            nextBtnText: `下一步 (2/${length})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options);
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
-          element: ".driver-6",
+          element: ".driver-5",
           popover: {
             title: "",
             description: "",
-            popoverClass: "popoverClass popoverClass6 popoverClose",
+            popoverClass: "popoverClass popoverClass5",
             align: "start",
             side: "top",
-            prevBtnText: "再看一遍",
-            doneBtnText: "完成",
-            showButtons: ["next", "previous"],
+            nextBtnText: `下一步 (3/${length})`,
+            showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options);
             },
-            onPrevClick: () => {
-              driverObj.drive(0);
-            },
-            onNextClick: () => {
-              onDriverClose();
-            },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
       ],
     };
+
+    if (props.statusAll.subjectStatus) {
+      driverOptions.steps?.push({
+        element: ".driver-10",
+        popover: {
+          title: "",
+          description: "",
+          popoverClass: "popoverClass popoverClass10",
+          align: "start",
+          side: "top",
+          nextBtnText: `下一步 (${driverOptions.steps.length + 1}/${length})`,
+          showButtons: ["next"],
+          onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+            driverInitialPosition(popover, options);
+          },
+        },
+      });
+    }
+
+    driverOptions.steps?.push({
+      element: ".driver-6",
+      popover: {
+        title: "",
+        description: "",
+        popoverClass: "popoverClass popoverClass6 popoverClose",
+        align: "start",
+        side: "top",
+        prevBtnText: "再看一遍",
+        doneBtnText: "完成",
+        showButtons: ["next", "previous"],
+        onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
+          driverInitialPosition(popover, options);
+        },
+        onPrevClick: () => {
+          driverObj.drive(0);
+        },
+        onNextClick: () => {
+          onDriverClose();
+        },
+      },
+    });
+
     let driverObj: any;
 
     const handleClickOutside = (event: any) => {
+      if (driverNextStatus.value) return;
       if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
         if (driverObj.isLastStep()) {
           onDriverClose();
@@ -591,10 +710,11 @@ export const EvaluatingDriver = defineComponent({
         }
         if (!(guideInfo.value && guideInfo.value.evaluatingDriver)) {
           document.addEventListener("click", handleClickOutside, true);
-          driverObj = driver(driverOptions);
           nextTick(() => {
+            driverObj = driver(driverOptions);
             driverObj.drive(0);
             showCloseBtn.value = true;
+            state.hasDriverPop = true;
           });
         } else {
           driverObj.destroy();
@@ -615,7 +735,9 @@ export const EvaluatingDriver = defineComponent({
       }
       endGuide(guideInfo.value);
       driverObj?.destroy();
+      document.querySelector(".driver-popover-close-btn-custom")?.remove();
       document.removeEventListener("click", handleClickOutside);
+      state.hasDriverPop = false;
     };
 
     return () => (
@@ -637,6 +759,7 @@ export const EvaluatingDriver = defineComponent({
 export const EvaluatingResultDriver = defineComponent({
   name: "EvaluatingResultDriver",
   setup() {
+    const driverNextStatus = ref(false);
     // 初始化部分引导位置
     const driverInitialPosition = (popover: PopoverDOM, options: { config: Config; state: State }, position = 1) => {
       options.config.stageRadius = 1000;
@@ -652,6 +775,15 @@ export const EvaluatingResultDriver = defineComponent({
       allowClose: false,
       popoverOffset: 3,
       disableActiveInteraction: true,
+      onCloseClick: () => {
+        onDriverClose();
+      },
+      onHighlightStarted: () => {
+        driverNextStatus.value = true;
+      },
+      onHighlighted: () => {
+        driverNextStatus.value = false;
+      },
       steps: [
         {
           element: ".evaluting-result-1",
@@ -661,15 +793,12 @@ export const EvaluatingResultDriver = defineComponent({
             popoverClass: "popoverClass popoverClassER1",
             align: "start",
             side: "right",
-            nextBtnText: "下一步1/4",
+            nextBtnText: "下一步 (1/4)",
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               options.config.stageRadius = 12;
               options.config.stagePadding = 10;
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
@@ -680,7 +809,7 @@ export const EvaluatingResultDriver = defineComponent({
             popoverClass: "popoverClass popoverClassER2",
             align: "start",
             side: "top",
-            nextBtnText: "下一步2/4",
+            nextBtnText: "下一步 (2/4)",
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               options.config.stageRadius = 1000;
@@ -690,9 +819,6 @@ export const EvaluatingResultDriver = defineComponent({
                 popover.wrapper.style.marginLeft = (rect?.width || 0) / 2 - 4 + "px";
               } catch {}
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
@@ -703,14 +829,11 @@ export const EvaluatingResultDriver = defineComponent({
             popoverClass: "popoverClass popoverClassER3",
             align: "end",
             side: "top",
-            nextBtnText: "下一步3/4",
+            nextBtnText: "下一步 (3/4)",
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options, -1);
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
@@ -733,9 +856,6 @@ export const EvaluatingResultDriver = defineComponent({
             onNextClick: () => {
               onDriverClose();
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
       ],
@@ -743,6 +863,7 @@ export const EvaluatingResultDriver = defineComponent({
     let driverObj: any;
 
     const handleClickOutside = (event: any) => {
+      if (driverNextStatus.value) return;
       if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
         if (driverObj.isLastStep()) {
           onDriverClose();
@@ -767,10 +888,11 @@ export const EvaluatingResultDriver = defineComponent({
         }
         if (!(guideInfo.value && guideInfo.value.evaluatingResultDriver)) {
           document.addEventListener("click", handleClickOutside, true);
-          driverObj = driver(driverOptions);
           nextTick(() => {
+            driverObj = driver(driverOptions);
             driverObj.drive(0);
             showCloseBtn.value = true;
+            state.hasDriverPop = true;
           });
         }
       } catch (e) {
@@ -778,7 +900,11 @@ export const EvaluatingResultDriver = defineComponent({
       }
     };
 
-    getAllGuidance();
+    onMounted(() => {
+      nextTick(() => {
+        getAllGuidance();
+      })
+    })
 
     // 结束关闭弹窗
     const onDriverClose = () => {
@@ -791,6 +917,7 @@ export const EvaluatingResultDriver = defineComponent({
       driverObj.destroy();
       document.querySelector(".driver-popover-close-btn-custom")?.remove();
       document.removeEventListener("click", handleClickOutside);
+      state.hasDriverPop = false
     };
 
     return () => (
@@ -819,6 +946,7 @@ export const EvaluatingReportDriver = defineComponent({
     },
   },
   setup(props) {
+    const driverNextStatus = ref(false);
     // state.isPercussion 是否为打击乐
     // 初始化部分引导位置
     const driverInitialPosition = (popover: PopoverDOM, options: { config: Config; state: State }, position = 1) => {
@@ -843,14 +971,11 @@ export const EvaluatingReportDriver = defineComponent({
               popoverClass: "popoverClass popoverClassReport2",
               align: "start",
               side: "bottom",
-              nextBtnText: "下一步1/2",
+              nextBtnText: "下一步 (1/2)",
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
               },
-              onCloseClick: () => {
-                onDriverClose();
-              },
             },
           },
           {
@@ -878,9 +1003,6 @@ export const EvaluatingReportDriver = defineComponent({
               onNextClick: () => {
                 onDriverClose();
               },
-              onCloseClick: () => {
-                onDriverClose();
-              },
             },
           },
         ];
@@ -905,9 +1027,6 @@ export const EvaluatingReportDriver = defineComponent({
               onNextClick: () => {
                 onDriverClose();
               },
-              onCloseClick: () => {
-                onDriverClose();
-              },
             },
           },
         ];
@@ -923,14 +1042,11 @@ export const EvaluatingReportDriver = defineComponent({
             popoverClass: "popoverClass popoverClassReport1",
             align: "start",
             side: "bottom",
-            nextBtnText: "下一步1/" + count,
+            nextBtnText: `下一步 (1/${count})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options);
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
         {
@@ -941,14 +1057,11 @@ export const EvaluatingReportDriver = defineComponent({
             popoverClass: "popoverClass popoverClassReport2",
             align: "start",
             side: "bottom",
-            nextBtnText: "下一步2/" + count,
+            nextBtnText: `下一步 (2/${count})`,
             showButtons: ["next"],
             onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
               driverInitialPosition(popover, options);
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         },
       ];
@@ -962,14 +1075,11 @@ export const EvaluatingReportDriver = defineComponent({
               popoverClass: "popoverClass popoverClassReport3",
               align: "start",
               side: "bottom",
-              nextBtnText: "下一步3/4",
+              nextBtnText: "下一步 (3/4)",
               showButtons: ["next"],
               onPopoverRender: (popover: PopoverDOM, options: { config: Config; state: State }) => {
                 driverInitialPosition(popover, options);
               },
-              onCloseClick: () => {
-                onDriverClose();
-              },
             },
           },
           {
@@ -997,9 +1107,6 @@ export const EvaluatingReportDriver = defineComponent({
               onNextClick: () => {
                 onDriverClose();
               },
-              onCloseClick: () => {
-                onDriverClose();
-              },
             },
           }
         );
@@ -1024,9 +1131,6 @@ export const EvaluatingReportDriver = defineComponent({
             onNextClick: () => {
               onDriverClose();
             },
-            onCloseClick: () => {
-              onDriverClose();
-            },
           },
         });
       }
@@ -1037,6 +1141,15 @@ export const EvaluatingReportDriver = defineComponent({
       allowClose: false,
       popoverOffset: 3,
       disableActiveInteraction: true,
+      onCloseClick: () => {
+        onDriverClose();
+      },
+      onHighlightStarted: () => {
+        driverNextStatus.value = true;
+      },
+      onHighlighted: () => {
+        driverNextStatus.value = false;
+      },
       steps: steps,
     };
 
@@ -1045,6 +1158,7 @@ export const EvaluatingReportDriver = defineComponent({
     const guideInfo = ref({} as any);
 
     const handleClickOutside = (event: any) => {
+      if (driverNextStatus.value) return;
       if (driverObj.isActive() && (event.target.nodeName === "path" || event.target.classList.contains("driver-popover") || event.target.classList.contains("driver-overlay"))) {
         if (driverObj.isLastStep()) {
           onDriverClose();
@@ -1069,10 +1183,10 @@ export const EvaluatingReportDriver = defineComponent({
         if (!(guideInfo.value && guideInfo.value.evaluatingReportDriver)) {
           // 监听点击事件以实现点击空白区域跳转到下一步
           document.addEventListener("click", handleClickOutside, true);
-          driverObj = driver(driverOptions);
           nextTick(() => {
+            driverObj = driver(driverOptions);
             driverObj.drive();
-
+            state.hasDriverPop = true;
             showCloseBtn.value = true;
           });
         }
@@ -1094,6 +1208,7 @@ export const EvaluatingReportDriver = defineComponent({
       driverObj.destroy();
       document.querySelector(".driver-popover-close-btn-custom")?.remove();
       document.removeEventListener("click", handleClickOutside);
+      state.hasDriverPop = false
     };
 
     return () => (

+ 4 - 0
src/page-instrument/evaluat-model/evaluat-result/index.tsx

@@ -27,6 +27,7 @@ import { browser, getBehaviorId } from "/src/utils";
 import { api_musicPracticeRecordSave } from "../../api";
 import { getAudioDuration } from "/src/view/audio-list";
 import { debounce } from "/src/utils";
+import { EvaluatingResultDriver } from "../../custom-plugins/guide-driver";
 
 export default defineComponent({
   name: "evaluatResult",
@@ -184,6 +185,9 @@ export default defineComponent({
                 <img src={ckzpImg} class={[styles.ctrlsBtn, "evaluting-result-4", data.saveLoading ? styles.disablued : ""]} onClick={() => emit("close", "look")} />
               </div>
             </div>
+
+            {/* 评测模式-结果弹窗 功能引导 加载音频完成 不是会员 */}
+            {evaluatingData.resulstMode && !evaluatingData.hideResultModal && !evaluatingData.earphoneMode && !query.isCbs && state.audioDone && !state.isVip && <EvaluatingResultDriver />}
           </div>
         )}
       </>

+ 1 - 1
src/page-instrument/header-top/index.tsx

@@ -871,4 +871,4 @@ export default defineComponent({
       </>
     );
   },
-});
+});

+ 103 - 110
src/page-instrument/header-top/modeView.tsx

@@ -1,116 +1,109 @@
-import { defineComponent, onMounted, watch, reactive, ref, nextTick } from "vue"
-import styles from "./index.module.less"
-import backImg from "./image/back.png"
-import nameImg from "./image/zt.png"
-import lxMode from "./image/lxMode.json"
-import glMode from "./image/glMode.json"
-import pcMode from "./image/pcMode.json"
-import { headTopData } from "./index"
-import TheVip from "../custom-plugins/the-vip"
-import { getQuery } from "/src/utils/queryString"
-import { storeData } from "/src/store"
-import state from "/src/state"
-import { studentQueryUserInfo } from "../api"
-import { usePageVisibility } from "@vant/use"
+import { defineComponent, onMounted, watch, reactive, ref, nextTick } from "vue";
+import styles from "./index.module.less";
+import backImg from "./image/back.png";
+import nameImg from "./image/zt.png";
+import lxMode from "./image/lxMode.json";
+import glMode from "./image/glMode.json";
+import pcMode from "./image/pcMode.json";
+import { headTopData } from "./index";
+import TheVip from "../custom-plugins/the-vip";
+import { getQuery } from "/src/utils/queryString";
+import { storeData } from "/src/store";
+import state from "/src/state";
+import { studentQueryUserInfo } from "../api";
+import { usePageVisibility } from "@vant/use";
 import { Vue3Lottie } from "vue3-lottie";
 
 export default defineComponent({
-   name: "modeView",
-   setup() {
-      const query = getQuery()
-      const data = reactive({
-         showPC: false,
-         showStudent: false,
-         showVip: false
-      })
-      const modeImgDom1 = ref()
-      const modeImgDom2 = ref()
-      const modeImgDom3 = ref()
-      const openGuid = () => {
-         // 加载后 判断 端口号 加载对应的引导
-         if (storeData.platformType !== "STUDENT" || storeData.user.clientType !== "STUDENT") {
-            // PC
-            data.showPC = true
-         } else {
-            // 从课堂乐器学生端课件预览默认不显示会员
-            if (storeData.user.vipMember || state.paymentType === "FREE" || query.showCourseMember === "true") {
-               // 学生端
-               data.showStudent = true
-            } else {
-               // vip
-               data.showVip = true
-            }
-         }
+  name: "modeView",
+  setup() {
+    const query = getQuery();
+    const data = reactive({
+      showPC: false,
+      showStudent: false,
+      showVip: false,
+    });
+    const modeImgDom1 = ref();
+    const modeImgDom2 = ref();
+    const modeImgDom3 = ref();
+    const openGuid = () => {
+      // 加载后 判断 端口号 加载对应的引导
+      if (storeData.platformType !== "STUDENT" || storeData.user.clientType !== "STUDENT") {
+        // PC
+        data.showPC = true;
+      } else {
+        // 从课堂乐器学生端课件预览默认不显示会员
+        if (storeData.user.vipMember || state.paymentType === "FREE" || query.showCourseMember === "true") {
+          // 学生端
+          data.showStudent = true;
+        } else {
+          // vip
+          data.showVip = true;
+          state.isVip = true;
+        }
       }
+    };
 
-      const getUserInfo = async () => {
-         const res = await studentQueryUserInfo()
-         const student = res?.data || {}
-         storeData.user.vipMember = student.vipMember
-         // console.log("🚀 ~ student:", student);
-         if (storeData.user.vipMember) {
-            data.showVip = false
-            openGuid()
-         }
+    const getUserInfo = async () => {
+      const res = await studentQueryUserInfo();
+      const student = res?.data || {};
+      storeData.user.vipMember = student.vipMember;
+      // console.log("🚀 ~ student:", student);
+      if (storeData.user.vipMember) {
+        data.showVip = false;
+        state.isVip = false;
+        openGuid();
       }
-      const pageVisible = usePageVisibility()
-      watch(
-         () => pageVisible.value,
-         val => {
-            if (val === "visible") {
-               if (storeData.user.vipMember) return
-               console.log("页面显示")
-               getUserInfo()
-            }
-         }
-      )
-      watch(() => headTopData.modeType, (value,oldValue) => {
-         // headTopData.modeType 值 刚开始是 ""  所以 第一次切换时候不触发播放动画
-         if(!oldValue) return
-         nextTick(()=>{
-            if(value === "show"){
-               modeImgDom1.value?.pause()
-               modeImgDom2.value?.pause()
-               modeImgDom3.value?.pause()
-            }else if(value === "init"){
-               modeImgDom1.value?.play()
-               modeImgDom2.value?.play()
-               modeImgDom3.value?.play()
-            }
-         })
-      })
-      onMounted(() => {
-         openGuid()
-      })
-      return () => (
-         <div class={[styles.modeView, headTopData.modeType !== "init" && styles.hidden]}>
-            <img
-               src={backImg}
-               class={styles.back}
-               onClick={() => {
-                  headTopData.modeType = "show"
-               }}
-            />
-            <img src={nameImg} class={styles.name} />
-            <div
-               class={[
-                  styles.modeBox,
-                  ((!state.isPercussion && !state.enableEvaluation) ||
-                     (state.isPercussion && state.enableEvaluation) ||
-                     (state.isPercussion && !state.enableEvaluation)) &&
-                     styles.twoModeBox
-               ]}
-            >
-               <Vue3Lottie ref={modeImgDom1} class={styles.modeImg} animationData={lxMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("practise")}></Vue3Lottie>
-               {
-                  !state.isPercussion && <Vue3Lottie ref={modeImgDom2} class={styles.modeImg} animationData={glMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("follow")}></Vue3Lottie>
-               }
-               {
-                  state.enableEvaluation && <Vue3Lottie ref={modeImgDom3} class={styles.modeImg} animationData={pcMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("evaluating")}></Vue3Lottie>
-               }
-            </div>
-            {data.showVip && <TheVip />}
-         </div>
-      )
-   }
-})
+    };
+    const pageVisible = usePageVisibility();
+    watch(
+      () => pageVisible.value,
+      (val) => {
+        if (val === "visible") {
+          if (storeData.user.vipMember) return;
+          console.log("页面显示");
+          getUserInfo();
+        }
+      }
+    );
+    watch(
+      () => headTopData.modeType,
+      (value, oldValue) => {
+        // headTopData.modeType 值 刚开始是 ""  所以 第一次切换时候不触发播放动画
+        if (!oldValue) return;
+        nextTick(() => {
+          if (value === "show") {
+            modeImgDom1.value?.pause();
+            modeImgDom2.value?.pause();
+            modeImgDom3.value?.pause();
+          } else if (value === "init") {
+            modeImgDom1.value?.play();
+            modeImgDom2.value?.play();
+            modeImgDom3.value?.play();
+          }
+        });
+      }
+    );
+    onMounted(() => {
+      openGuid();
+    });
+    return () => (
+      <div class={[styles.modeView, headTopData.modeType !== "init" && styles.hidden]}>
+        <img
+          src={backImg}
+          class={styles.back}
+          onClick={() => {
+            headTopData.modeType = "show";
+          }}
+        />
+        <img src={nameImg} class={styles.name} />
+        <div class={[styles.modeBox, ((!state.isPercussion && !state.enableEvaluation) || (state.isPercussion && state.enableEvaluation) || (state.isPercussion && !state.enableEvaluation)) && styles.twoModeBox]}>
+          <Vue3Lottie ref={modeImgDom1} class={styles.modeImg} animationData={lxMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("practise")}></Vue3Lottie>
+          {!state.isPercussion && <Vue3Lottie ref={modeImgDom2} class={styles.modeImg} animationData={glMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("follow")}></Vue3Lottie>}
+          {state.enableEvaluation && <Vue3Lottie ref={modeImgDom3} class={styles.modeImg} animationData={pcMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("evaluating")}></Vue3Lottie>}
+        </div>
+        {data.showVip && <TheVip />}
+      </div>
+    );
+  },
+});