Просмотр исходного кода

Merge branch 'gyt-feature-tianyong' into online

TIANYONG 1 год назад
Родитель
Сommit
6bdcf1a846
55 измененных файлов с 1536 добавлено и 188 удалено
  1. 1 1
      src/helpers/native-message.ts
  2. 0 0
      src/pages/detail/CheckDelayPopup/image/bg.json
  3. BIN
      src/pages/detail/CheckDelayPopup/image/delay_btn_icon1.png
  4. BIN
      src/pages/detail/CheckDelayPopup/image/delay_btn_icon2.png
  5. BIN
      src/pages/detail/CheckDelayPopup/image/icon-back.png
  6. BIN
      src/pages/detail/CheckDelayPopup/image/icon_backBtn.png
  7. 6 0
      src/pages/detail/CheckDelayPopup/image/index.ts
  8. 0 0
      src/pages/detail/CheckDelayPopup/image/left_ adorn.json
  9. 0 0
      src/pages/detail/CheckDelayPopup/image/right_ adorn.json
  10. 0 0
      src/pages/detail/CheckDelayPopup/image/step1_icon.json
  11. 0 0
      src/pages/detail/CheckDelayPopup/image/step2_icon.json
  12. 0 0
      src/pages/detail/CheckDelayPopup/image/step3_icon.json
  13. 0 0
      src/pages/detail/CheckDelayPopup/image/step4_icon.json
  14. 0 0
      src/pages/detail/CheckDelayPopup/image/step5_icon.json
  15. BIN
      src/pages/detail/CheckDelayPopup/image/step_state_icon1.png
  16. BIN
      src/pages/detail/CheckDelayPopup/image/step_state_icon2.png
  17. BIN
      src/pages/detail/CheckDelayPopup/image/step_state_icon3.png
  18. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon1.png
  19. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon2.png
  20. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon3.png
  21. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon4.png
  22. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon5.png
  23. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon5_1.png
  24. BIN
      src/pages/detail/CheckDelayPopup/image/step_tips_icon5_2.png
  25. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon.png
  26. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon_1.png
  27. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon_2.png
  28. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon_3.png
  29. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon_4.png
  30. BIN
      src/pages/detail/CheckDelayPopup/image/step_top_icon_5.png
  31. 439 0
      src/pages/detail/CheckDelayPopup/index.module.less
  32. 125 0
      src/pages/detail/CheckDelayPopup/index.tsx
  33. BIN
      src/pages/detail/Headphone/image/icon_btn.png
  34. BIN
      src/pages/detail/Headphone/image/icon_top.png
  35. 50 0
      src/pages/detail/Headphone/index.module.less
  36. 32 0
      src/pages/detail/Headphone/index.tsx
  37. 0 0
      src/pages/detail/PhoneTip/data.json
  38. BIN
      src/pages/detail/PhoneTip/icon_tip.png
  39. 23 0
      src/pages/detail/PhoneTip/index.module.less
  40. 23 0
      src/pages/detail/PhoneTip/index.tsx
  41. 455 152
      src/pages/detail/evaluating/index.tsx
  42. 1 1
      src/pages/detail/helpers.ts
  43. 34 4
      src/pages/detail/runtime.ts
  44. 1 1
      src/pages/detail/setting-popup/set.tsx
  45. 1 1
      src/pages/detail/setting-state.ts
  46. 0 0
      src/subpages/colexiu/buttons/data/start_new.json
  47. 0 0
      src/subpages/colexiu/buttons/data/starting_new.json
  48. 324 22
      src/subpages/colexiu/buttons/evaluating.tsx
  49. 9 1
      src/subpages/colexiu/buttons/index.module.less
  50. 1 0
      src/subpages/colexiu/buttons/index.tsx
  51. 7 1
      src/subpages/colexiu/index.tsx
  52. 1 1
      src/subpages/colexiu/popups/evaluating/index.module.less
  53. BIN
      src/subpages/colexiu/popups/permission/icons/earphone.png
  54. 1 1
      src/subpages/colexiu/popups/setting/evaluat.tsx
  55. 2 2
      src/subpages/colexiu/uses/use-evaluat.ts

+ 1 - 1
src/helpers/native-message.ts

@@ -65,7 +65,7 @@ const browserInfo = browser()
 
 if (browserInfo.isApp) {
   window.addEventListener('message', (evt) => {
-    console.log('app回调', evt?.data)
+    // console.log('app回调', evt?.data)
     try {
       const data = evt.data ? (typeof evt.data === 'object' ? evt.data : JSON.parse(evt.data)) : {}
       const uuid = data.content?.uuid || data.uuid

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/bg.json


BIN
src/pages/detail/CheckDelayPopup/image/delay_btn_icon1.png


BIN
src/pages/detail/CheckDelayPopup/image/delay_btn_icon2.png


BIN
src/pages/detail/CheckDelayPopup/image/icon-back.png


BIN
src/pages/detail/CheckDelayPopup/image/icon_backBtn.png


+ 6 - 0
src/pages/detail/CheckDelayPopup/image/index.ts

@@ -0,0 +1,6 @@
+//@ts-ignore
+const modules = import.meta.globEager("./*.png");
+export const getDelayImage = (name: string | number) => {
+    const src = modules[`./icon${name}.png`]
+	return src ? src.default : ''
+};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/left_ adorn.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/right_ adorn.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/step1_icon.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/step2_icon.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/step3_icon.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/step4_icon.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/CheckDelayPopup/image/step5_icon.json


BIN
src/pages/detail/CheckDelayPopup/image/step_state_icon1.png


BIN
src/pages/detail/CheckDelayPopup/image/step_state_icon2.png


BIN
src/pages/detail/CheckDelayPopup/image/step_state_icon3.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon1.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon2.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon3.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon4.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon5.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon5_1.png


BIN
src/pages/detail/CheckDelayPopup/image/step_tips_icon5_2.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon_1.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon_2.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon_3.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon_4.png


BIN
src/pages/detail/CheckDelayPopup/image/step_top_icon_5.png


+ 439 - 0
src/pages/detail/CheckDelayPopup/index.module.less

@@ -0,0 +1,439 @@
+.delayContainer {
+    position: relative;
+    width: 100vw;
+    height: 100vh;
+    overflow: hidden;
+    background-size: 110% 110%;
+    background-position: center center;
+    background-repeat: no-repeat;
+    .delayBg {
+        position: relative;
+        width: 140%;
+        height: 110%;
+        top: -5%;
+        left: -20%;
+    }
+    .delayAdorn {
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%,-50%);
+        pointer-events: none;
+        width: 100%;
+    }
+    .leftAdorn {
+        position: fixed;
+        left: 0;
+        bottom: 0;
+        width: 1.66rem;
+    }
+    .rightAdorn {
+        position: fixed;
+        right: 0;
+        bottom: 0;
+        width: 1.28rem;
+    }
+}
+
+.animationContainer {
+    perspective: 500px;
+    pointer-events: none;
+}
+
+.delayBackBtn {
+    position: absolute;
+    left: 16px;
+    top: 13px;
+    display: block;
+    width: 15px;
+    height: 15px;
+}
+
+.delayContent {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    animation: delayContentFrame infinite 10s ease-in-out both;
+    pointer-events: none;
+
+    .iconContent {
+        display: block;
+        width: 237px;
+        height: 167px;
+    }
+
+    .iconDuihua {
+        position: absolute;
+        top: -4px;
+        left: 143px;
+        display: block;
+        transform-origin: left bottom;
+        animation: iconDuihuaScale .5s linear both;
+    }
+    .iconDuihua_delay{
+        animation-delay: .7s;
+    }
+
+    .iconDuihua1 {
+        width: 160px;
+        height: 45px;
+    }
+
+    .iconDuihua2 {
+        width: 141px;
+        height: 39px;
+    }
+
+    .iconDuihua3 {
+        width: 164px;
+        height: 37px;
+    }
+
+    .iconDianchi {
+        display: block;
+        position: absolute;
+        left: 43px;
+        bottom: -21px;
+        width: 150px;
+        height: 44px;
+    }
+
+    .iconDianchiActive {
+        display: block;
+        position: absolute;
+        left: 52px;
+        bottom: -8px;
+        width: 132px;
+        height: 22px;
+        pointer-events: auto;
+    }
+}
+
+
+.delayBody {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%,100%);
+    .delayBox {
+        width: 4.68rem;
+        position: relative;
+        .dbTop {
+            position: absolute;
+            left: 50%;
+            transform: translate(-50%, -40%);
+            .topIcon {
+                width: 2.99rem;
+                height: 0.39rem;
+            }
+            .topDots {
+                position: absolute;
+                left: 0;
+                top: 0;
+                width: 100%;
+                height: 90%;
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                padding: 0 0.22rem;
+                img {
+                    width: 0.2rem;
+                    height: 0.2rem;
+                }
+                .aniDot3 {
+                    position: relative;
+                    width: 0.2rem;
+                    height: 0.2rem;
+                    background-image: url('./image/step_state_icon3.png');
+                    background-size: 100% 100%;
+                    background-position: center center;
+                    background-repeat: no-repeat;
+                    animation: aniBg 1.8s step-end infinite;
+                }
+            }
+        }
+        .dbContext {
+            width: 4.68rem;
+            height: 0.95rem;
+        }
+        .dbBtn {
+            position: absolute;
+            right: 0.21rem;
+            bottom: 0.23rem;
+            width: 1.21rem;
+            height: 0.35rem;
+            cursor: pointer;
+            z-index: 999;
+        }
+    }
+}
+.heartbeat {
+    animation: heartbeat 1.5s ease-in-out infinite both;
+}
+
+@keyframes heartbeat {
+    from {
+        transform: scale(1);
+        transform-origin: center center;
+        animation-timing-function: ease-out;
+    }
+
+    10% {
+        -webkit-transform: scale(0.91);
+        transform: scale(0.91);
+        animation-timing-function: ease-in;
+    }
+
+    17% {
+        transform: scale(0.98);
+        animation-timing-function: ease-out;
+    }
+
+    33% {
+        transform: scale(0.87);
+        animation-timing-function: ease-in;
+    }
+
+    45% {
+        transform: scale(1);
+        animation-timing-function: ease-out;
+    }
+}
+@keyframes aniBg {
+    0% {
+        background-image: url('./image/step_state_icon3.png');
+    }
+
+    25% {
+        background-image: url('./image/step_state_icon1.png');
+    }
+
+    50% {
+        background-image: url('./image/step_state_icon3.png');
+    }
+
+    75% {
+        background-image: url('./image/step_state_icon1.png');
+    }
+
+    100% {
+        background-image: url('./image/step_state_icon3.png');
+    }
+}
+
+@keyframes delayContentFrame {
+    0% {
+        top: 47%;
+    }
+
+    50% {
+        top: 53%;
+    }
+
+    100% {
+        top: 47%
+    }
+}
+
+.delayImage {
+    display: block;
+    position: absolute;
+}
+
+.icon1 {
+    left: 119px;
+    top: 12px;
+    width: 59px;
+    height: 49px;
+    animation: icon1 infinite 5s linear;
+}
+
+@keyframes icon1 {
+    0% {
+        transform: translateY(-6px);
+    }
+
+    50% {
+        transform: translateY(6px);
+    }
+
+    100% {
+        transform: translateY(-6px);
+    }
+}
+
+.icon2 {
+    left: 186px;
+    top: 18px;
+    width: 34px;
+    height: 42px;
+    animation: icon3 infinite 1.5s linear;
+}
+
+.icon3 {
+    left: 167px;
+    top: 66px;
+    width: 12px;
+    height: 12px;
+    animation: icon3 infinite 2s linear;
+}
+
+@keyframes icon3 {
+    0% {
+        transform: scale(1.3);
+    }
+
+    50% {
+        transform: scale(1);
+    }
+
+    100% {
+        transform: scale(1.3);
+    }
+}
+
+.icon4 {
+    left: 108px;
+    top: 97px;
+    width: 49px;
+    height: 50px;
+    animation: icon3 infinite 2s 1s linear;
+}
+
+.icon5 {
+    left: -20px;
+    top: 148px;
+    width: 106px;
+    height: 55px;
+}
+
+.icon6 {
+    left: 53px;
+    top: 0px;
+    width: 84px;
+    height: 118px;
+    animation: icon6 2s linear infinite;
+}
+
+@keyframes icon6 {
+    100% {
+        transform: translate(-30vw, 50vh);
+        opacity: .5;
+    }
+}
+
+.icon7 {
+    right: 72px;
+    top: -40px;
+    width: 50px;
+    height: 40px;
+    animation: icon7 12s linear 2s infinite;
+}
+
+@keyframes icon7 {
+    100% {
+        transform: translate(-70vw, 120vh);
+    }
+}
+
+.icon8 {
+    right: -37px;
+    top: 0;
+    width: 37px;
+    height: 31px;
+    animation: icon8 8s linear infinite;
+}
+
+@keyframes icon8 {
+    100% {
+        transform: translate(-70vw, 100vh);
+    }
+}
+
+.icon9 {
+    right: -11px;
+    top: 19px;
+    width: 84px;
+    height: 118px;
+    animation: icon9 2s linear infinite;
+}
+
+@keyframes icon9 {
+    100% {
+        transform: translate(-30vw, 50vh);
+        opacity: .5;
+    }
+}
+
+.icon10 {
+    right: 7px;
+    top: 55px;
+    width: 27px;
+    height: 22px;
+}
+
+.icon11 {
+    right: -30px;
+    top: 136px;
+    width: 102px;
+    height: 106px;
+    transform-style: preserve-3d;
+    animation: icon11 60s linear infinite;
+}
+
+@keyframes icon11 {
+    100% {
+        transform: rotate(360deg);
+    }
+}
+
+.icon12 {
+    left: 0;
+    top: 0;
+    width: 100%;
+}
+
+.heartbeat {
+    animation: heartbeat 1.5s ease-in-out infinite both;
+}
+
+@keyframes heartbeat {
+    from {
+        transform: scale(1);
+        transform-origin: center center;
+        animation-timing-function: ease-out;
+    }
+
+    10% {
+        -webkit-transform: scale(0.91);
+        transform: scale(0.91);
+        animation-timing-function: ease-in;
+    }
+
+    17% {
+        transform: scale(0.98);
+        animation-timing-function: ease-out;
+    }
+
+    33% {
+        transform: scale(0.87);
+        animation-timing-function: ease-in;
+    }
+
+    45% {
+        transform: scale(1);
+        animation-timing-function: ease-out;
+    }
+}
+@keyframes iconDuihuaScale {
+    0% {
+        transform: scale(.5);
+        opacity: 0;
+    }
+
+    100% {
+        transform: scale(1);
+        opacity: 1;
+    }
+}

+ 125 - 0
src/pages/detail/CheckDelayPopup/index.tsx

@@ -0,0 +1,125 @@
+import { PropType, defineComponent, onMounted, watch } from "vue";
+import { Vue3Lottie } from 'vue3-lottie'
+import styles from "./index.module.less";
+import delay_bg from "./image/bg.json"
+import left_adorn from "./image/left_ adorn.json"
+import right_adorn from "./image/right_ adorn.json"
+import step1 from "./image/step1_icon.json"
+import step2 from "./image/step2_icon.json"
+import step3 from "./image/step3_icon.json"
+import step4 from "./image/step4_icon.json"
+import step5 from "./image/step5_icon.json"
+import step_tips_1 from "./image/step_tips_icon1.png"
+import step_tips_2 from "./image/step_tips_icon2.png"
+import step_tips_3 from "./image/step_tips_icon3.png"
+import step_tips_4 from "./image/step_tips_icon4.png"
+import step_tips_5 from "./image/step_tips_icon5.png"
+import step_tips_5_1 from "./image/step_tips_icon5_1.png"
+import step_tips_5_2 from "./image/step_tips_icon5_2.png"
+import step_top_icon from "./image/step_top_icon.png"
+import step_top_icon_1 from "./image/step_top_icon_1.png"
+import step_top_icon_2 from "./image/step_top_icon_2.png"
+import step_top_icon_3 from "./image/step_top_icon_3.png"
+import step_top_icon_4 from "./image/step_top_icon_4.png"
+import step_top_icon_5 from "./image/step_top_icon_5.png"
+import step_btn_1 from "./image/delay_btn_icon1.png"
+import step_btn_2 from "./image/delay_btn_icon2.png"
+import setp_dot_1 from './image/step_state_icon1.png'
+import setp_dot_2 from './image/step_state_icon2.png'
+import setp_dot_3 from './image/step_state_icon3.png'
+import iconBack from './image/icon-back.png'
+
+interface IDelayData {
+	/** 延迟时间 */
+	time: number;
+	/** 检测次数 */
+	count: number;
+	/** 耳机状态 */
+	erji: boolean;
+	checkStatus: "init" | "ing" | "error";
+	step: number;
+	earPhoneType: string;
+}
+
+/** 延迟检测组件 */
+export default defineComponent({
+	name: "CheckDelayPopup",
+	emits: ["close", "startCheckDelay", "load", "back"],
+	props: {
+		delayData: {
+			type: Object as PropType<IDelayData>,
+			default: () => ({ time: 0, count: 0 }),
+		},
+	},
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.delayContainer}>
+				<Vue3Lottie class={styles.delayBg} animationData={delay_bg}></Vue3Lottie>
+				<Vue3Lottie class={styles.leftAdorn} animationData={left_adorn}></Vue3Lottie>
+				<Vue3Lottie class={styles.rightAdorn} animationData={right_adorn}></Vue3Lottie>
+				{/*返回按钮*/}
+				<img class={styles.delayBackBtn} src={iconBack} onClick={() => emit("back")} />
+				<Vue3Lottie class={styles.delayAdorn} animationData={step1} style={{ display: props.delayData.step <= 2 ? '' : 'none' }}></Vue3Lottie>
+				<Vue3Lottie class={styles.delayAdorn} animationData={step2} style={{ display: props.delayData.step === 3 ? '' : 'none' }}></Vue3Lottie>
+				<Vue3Lottie class={styles.delayAdorn} animationData={step3} style={{ display: props.delayData.step === 4 ? '' : 'none' }}></Vue3Lottie>
+				<Vue3Lottie class={styles.delayAdorn} animationData={step4} style={{ display: props.delayData.step === 5 ? '' : 'none' }}></Vue3Lottie>
+				<Vue3Lottie class={styles.delayAdorn} animationData={step5} style={{ display: props.delayData.step >= 6 ? '' : 'none' }}></Vue3Lottie>
+				<div class={styles.delayBody}>
+					<div class={styles.delayBox}>
+						<div class={styles.dbTop}>
+							<img class={styles.topIcon} src={props.delayData.step <= 3 ? step_top_icon_1 : props.delayData.step === 4 ? step_top_icon_2 : props.delayData.step === 5 ? step_top_icon_3 : 
+								props.delayData.step >= 6 && props.delayData.earPhoneType !== "有线耳机" ? step_top_icon_4 : props.delayData.step >= 6 && props.delayData.earPhoneType === "有线耳机" ? step_top_icon_5 : '' } />
+							{
+								props.delayData.step <= 2 ? 
+								<div class={styles.topDots}>
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+								</div>
+								: props.delayData.step === 3 ? 
+								<div class={styles.topDots}>
+									<span class={styles.aniDot3} ></span>
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+								</div>		
+								: props.delayData.step === 4 ? 
+								<div class={styles.topDots}>
+									<img src={setp_dot_2} />
+									<span class={styles.aniDot3} ></span>
+									<img src={setp_dot_1} />
+									<img src={setp_dot_1} />
+								</div>	
+								: props.delayData.step === 5 ? 
+								<div class={styles.topDots}>
+									<img src={setp_dot_2} />
+									<img src={setp_dot_2} />
+									<span class={styles.aniDot3} ></span>
+									<img src={setp_dot_1} />
+								</div>	
+								: 
+								<div class={styles.topDots}>
+									<img src={setp_dot_2} />
+									<img src={setp_dot_2} />
+									<img src={setp_dot_2} />
+									<span class={styles.aniDot3} ></span>
+								</div>																															
+							}
+
+						</div>
+						<img class={styles.dbContext} src={step_tips_1} style={{ display: props.delayData.step <= 2 ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_2} style={{ display: props.delayData.step === 3 ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_3} style={{ display: props.delayData.step === 4 ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_4} style={{ display: props.delayData.step === 5 ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_5} style={{ display: props.delayData.step >= 6 && !props.delayData.erji ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_5_1} style={{ display: props.delayData.step >= 6 && props.delayData.erji && props.delayData.earPhoneType !== "有线耳机" ? '' : 'none' }} />
+						<img class={styles.dbContext} src={step_tips_5_2} style={{ display: props.delayData.step >= 6 && props.delayData.erji && props.delayData.earPhoneType === "有线耳机" ? '' : 'none' }} />
+						<img class={[styles.dbBtn, styles.heartbeat]} src={step_btn_1} style={{ display: props.delayData.step <= 2 ? '' : 'none' }} onClick={() => emit("startCheckDelay")} />
+						<img class={[styles.dbBtn, styles.heartbeat]} src={step_btn_2} style={{ display: props.delayData.step >= 6 ? '' : 'none' }} onClick={() => {emit("close")}} />
+					</div>
+				</div>
+			</div>
+		);
+	},
+});

BIN
src/pages/detail/Headphone/image/icon_btn.png


BIN
src/pages/detail/Headphone/image/icon_top.png


+ 50 - 0
src/pages/detail/Headphone/index.module.less

@@ -0,0 +1,50 @@
+.popup {
+    background: transparent;
+}
+
+.container {
+    width: 172px;
+}
+
+.avatar {
+    display: block;
+    width: 100%;
+    height: 78px;
+    position: relative;
+    z-index: 1;
+}
+
+.content {
+    position: relative;
+    top: -7px;
+    width: 100%;
+    height: 96px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-evenly;
+    align-items: center;
+    background: #fff;
+    border-radius: 0 0 13px 13px;
+
+    .title {
+        font-size: 12px;
+        font-weight: 500;
+        color: #044962;
+        line-height: 17px;
+    }
+
+    .des {
+        font-size: 9px;
+        font-weight: 400;
+        color: #777777;
+        line-height: 13px;
+    }
+
+    .btn {
+        width: 91px;
+        height: 25px;
+        &:active {
+            opacity: .8;
+        }
+    }
+}

+ 32 - 0
src/pages/detail/Headphone/index.tsx

@@ -0,0 +1,32 @@
+import { Popup } from "vant";
+import { defineComponent, reactive } from "vue";
+import icon_btn from "./image/icon_btn.png";
+import icon_top from "./image/icon_top.png";
+import styles from "./index.module.less";
+
+/** 耳机提示框 */
+export const HeadphoneData = reactive({
+	open: false,
+	toggle(value = true) {
+		this.open = value;
+	}
+});
+
+export default defineComponent({
+	name: "Headphone",
+	emits: ["close"],
+	setup(props, { expose, emit }) {
+		return () => (
+			<Popup teleport="body" class={["popup-scale", styles.popup]} transition="van-scale" show={HeadphoneData.open} onClose={() => emit("close")}>
+				<div class={styles.container}>
+					<img class={styles.avatar} src={icon_top} />
+					<div class={styles.content}>
+						<div class={styles.title}>请佩戴有线耳机</div>
+						<div class={styles.des}>佩戴有线耳机可以保证评测更准确~</div>
+						<img class={styles.btn} src={icon_btn} onClick={() => HeadphoneData.toggle(false)} />
+					</div>
+				</div>
+			</Popup>
+		);
+	},
+});

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/pages/detail/PhoneTip/data.json


BIN
src/pages/detail/PhoneTip/icon_tip.png


+ 23 - 0
src/pages/detail/PhoneTip/index.module.less

@@ -0,0 +1,23 @@
+.box{
+    position: fixed;
+    bottom: -5px;
+    right: 15px;
+    width: 95px;
+    height: 80px;
+    pointer-events: none;
+    transition: all 1s;
+    transform-origin: bottom right;
+    transform: scale(0);
+    opacity: 0;
+}
+.iconTip{
+    position: absolute;
+    left: -90%;
+    top: -22%;
+    width: 131px;
+    height: 51px;
+}
+.animate__scale{
+    opacity: 1;
+    transform: scale(1);
+}

+ 23 - 0
src/pages/detail/PhoneTip/index.tsx

@@ -0,0 +1,23 @@
+import { defineComponent, onMounted } from "vue";
+import styles from "./index.module.less";
+import { Vue3Lottie } from "vue3-lottie";
+import data from "./data.json";
+import icon_tip from './icon_tip.png'
+
+export default defineComponent({
+	name: "PhoneTip",
+    props: {
+        show: {
+            type: Boolean,
+            default: false
+        }
+    },
+	setup(props) {
+		return () => (
+			<div id="PhoneTipContent" class={[styles.box, props.show ? styles.animate__scale : '']}>
+                <img class={styles.iconTip} src={icon_tip} />
+				<Vue3Lottie animationData={data} speed={2}></Vue3Lottie>
+			</div>
+		);
+	},
+});

+ 455 - 152
src/pages/detail/evaluating/index.tsx

@@ -22,14 +22,43 @@ import {
   listenerMessage,
   removeListenerMessage,
   IPostMessage,
+  CallBack
 } from '/src/helpers/native-message'
 import SettingState from '/src/pages/detail/setting-state'
 import { getLeveByScore, getLeveByScoreMeasure } from './helper'
 import styles from './index.module.less'
 import { browser, getRequestHostname } from '/src/helpers/utils'
+import CheckDelayPopup from "../CheckDelayPopup";
+import Headphone, { HeadphoneData } from "../Headphone";
+import PhoneTip from "../PhoneTip";
 
 const browserInfo = browser()
 
+/** 初始化评测音频 */
+export const evaluatCreateMusicPlayer = () => {
+	return new Promise((resolve) => {
+		// 初始化曲谱音频 和效音音频
+		postMessage(
+      {
+        api: "createMusicPlayer",
+        content: {
+          musicSrc: runtime.songs.background || runtime.songs.music, // 曲谱音频url
+          tuneSrc: "https://oss.dayaedu.com/cloud-coach/1686725501654check_music1_(1).mp3", //效音音频url
+        },
+      },
+      () => {
+        if (browserInfo.ios) {
+          resolve(true);
+        }
+      }
+    );
+		// 安卓不需要
+		if(!browserInfo.ios){
+			resolve(true)
+		}
+	})
+}
+
 let player: any = null
 
 let backtime = 0
@@ -72,6 +101,24 @@ export const resetPlayer = () => {
   }
 }
 
+/** 监听评测弹窗是否隐藏保存演奏按钮 */
+const hideComplexButton = (callback: CallBack, listen?: boolean) => {
+	if (listen) {
+		listenerMessage("hideComplexButton", callback);
+	} else {
+		removeListenerMessage("hideComplexButton", callback);
+	}
+};
+
+// 隐藏存演奏按钮
+const handleComplexButton = (res?: IPostMessage) => {
+	console.log('监听是否隐藏上传云端按钮', res)
+	if (res?.content) {
+		const { header, body } = res.content;
+		detailState.isHideEvaluatReportSaveBtn = true
+	}
+};
+
 export default defineComponent({
   name: 'evaluating',
   data() {
@@ -97,6 +144,22 @@ export default defineComponent({
       shareLoadedPngData: null as null | string,
       isSaveVideo: SettingState.sett.camera && SettingState.eva.save,
       tuningStatus: false,
+			/** 延迟数据 */
+			delayData: {
+				/** 是否强制检测 */
+				isForce: true,
+				/** 弹窗 */
+				open: false,
+				/** 延迟次数 */
+				count: 0,
+				/** 延迟时间 */
+				time: 0,
+				/** 耳机状态 */
+				erji: false,
+				/** 检测状态 */
+				checkStatus: 'init' as 'init' | 'ing' | 'error',
+        step: 1,
+			},      
     }
   },
   computed: {
@@ -435,7 +498,7 @@ export default defineComponent({
         ) {
           skip = true
         }
-        console.log(note.measureOpenIndex, item.measureOpenIndex, note)
+        // console.log(note.measureOpenIndex, item.measureOpenIndex, note)
         // console.log("skip", skip)
         const data = {
           timeStamp: (start * 1000) / rate,
@@ -461,159 +524,233 @@ export default defineComponent({
         this.cancel(data?.content.reson)
       }
     },
-    sendResult(evt?: IPostMessage) {
-      console.log('sendResult', evt)
-      if (evt?.content) {
-        const data = evt?.content?.body
-        if (evt?.content.header.commond === 'overall') {
-          Toast.clear()
-          this.res = data
-          this.endloading = false
-          RuntimeUtils.event.emit('onEvaluationResult', data)
-        } else if (evt?.content.header.commond === 'checkDone') {
-          this.checkStatus = true
-          // postMessage({
-          //   api: 'endSoundCheck'
-          // })
-        } else if (evt?.content.header.commond === 'checking') {
-          // this.trend = evt?.content?.body?.trend
-          this.frequency = evt?.content?.body?.frequency
-        } else {
-          const getBeforeNote = (index: number) => {
-            while (index >= 0) {
-              const item = state.times[index]
-              if (item.stave) {
-                return item
-              }
-              index--
-            }
-          }
-          const setEvaluatings = (
-            note: any,
-            data: any,
-            dontTransition = false
-          ) => {
-            const startNote = getBoundingBoxByverticalNote(note)
-            state.evaluatings = {
-              ...state.evaluatings,
-              [startNote.measureIndex]: {
-                ...startNote,
-                ...getLeveByScoreMeasure(data.score),
-                score: data.score,
-                dontTransition,
-              },
-            }
-          }
+    // sendResult(evt?: IPostMessage) {
+    //   console.log('sendResult', evt)
+    //   if (evt?.content) {
+    //     const data = evt?.content?.body
+    //     if (evt?.content.header.commond === 'overall') {
+    //       Toast.clear()
+    //       this.res = data
+    //       this.endloading = false
+    //       RuntimeUtils.event.emit('onEvaluationResult', data)
+    //     } else if (evt?.content.header.commond === 'checkDone') {
+    //       this.checkStatus = true
+    //       // postMessage({
+    //       //   api: 'endSoundCheck'
+    //       // })
+    //     } else if (evt?.content.header.commond === 'checking') {
+    //       // this.trend = evt?.content?.body?.trend
+    //       this.frequency = evt?.content?.body?.frequency
+    //     } else {
+    //       const getBeforeNote = (index: number) => {
+    //         while (index >= 0) {
+    //           const item = state.times[index]
+    //           if (item.stave) {
+    //             return item
+    //           }
+    //           index--
+    //         }
+    //       }
+    //       const setEvaluatings = (
+    //         note: any,
+    //         data: any,
+    //         dontTransition = false
+    //       ) => {
+    //         const startNote = getBoundingBoxByverticalNote(note)
+    //         state.evaluatings = {
+    //           ...state.evaluatings,
+    //           [startNote.measureIndex]: {
+    //             ...startNote,
+    //             ...getLeveByScoreMeasure(data.score),
+    //             score: data.score,
+    //             dontTransition,
+    //           },
+    //         }
+    //       }
 
-          for (let index = 0; index < state.times.length; index++) {
-            let time = state.times[index]
-            if (
-              data.measureRenderIndex ==
-              time.noteElement.sourceMeasure.measureListIndex
-            ) {
-              if (!time.stave) {
-                const ntime = getBeforeNote(index)
-                // console.log('ntime', ntime)
-                if (ntime) {
-                  time = ntime
-                }
-              }
-              // if (state.evaluatings[data.measureRenderIndex]) {
-              //   // 重复问题,老数据移除
-              //   state.evaluatings = {
-              //     ...state.evaluatings,
-              //     [data.measureRenderIndex]: undefined
-              //   }
-              // }
-              // console.log('sendResult', data, time, time.noteElement.tie)
+    //       for (let index = 0; index < state.times.length; index++) {
+    //         let time = state.times[index]
+    //         if (
+    //           data.measureRenderIndex ==
+    //           time.noteElement.sourceMeasure.measureListIndex
+    //         ) {
+    //           if (!time.stave) {
+    //             const ntime = getBeforeNote(index)
+    //             // console.log('ntime', ntime)
+    //             if (ntime) {
+    //               time = ntime
+    //             }
+    //           }
+    //           // if (state.evaluatings[data.measureRenderIndex]) {
+    //           //   // 重复问题,老数据移除
+    //           //   state.evaluatings = {
+    //           //     ...state.evaluatings,
+    //           //     [data.measureRenderIndex]: undefined
+    //           //   }
+    //           // }
+    //           // console.log('sendResult', data, time, time.noteElement.tie)
 
-              // const startNote = getBoundingBoxByverticalNote(time)
-              // const endNote = getBoundingBoxByverticalNote(getNoteByMeasuresSlursStart(time))//getParentNote
+    //           // const startNote = getBoundingBoxByverticalNote(time)
+    //           // const endNote = getBoundingBoxByverticalNote(getNoteByMeasuresSlursStart(time))//getParentNote
 
-              // if (!time.noteElement.tie) continue
-              // for (const item of time.noteElement.tie.notes) {
-              //   const note = getParentNote(item)
-              //   if (!note) continue
-              //   const startNote = getBoundingBoxByverticalNote(note)
-              //   state.evaluatings = {
-              //     ...state.evaluatings,
-              //     [startNote.measureIndex]: {
-              //       ...startNote,
-              //       ...getLeveByScoreMeasure(data.score),
-              //       score: data.score,
-              //       dontTransition: item !== time.noteElement.tie.StartNote,
-              //     },
-              //   }
-              // }
+    //           // if (!time.noteElement.tie) continue
+    //           // for (const item of time.noteElement.tie.notes) {
+    //           //   const note = getParentNote(item)
+    //           //   if (!note) continue
+    //           //   const startNote = getBoundingBoxByverticalNote(note)
+    //           //   state.evaluatings = {
+    //           //     ...state.evaluatings,
+    //           //     [startNote.measureIndex]: {
+    //           //       ...startNote,
+    //           //       ...getLeveByScoreMeasure(data.score),
+    //           //       score: data.score,
+    //           //       dontTransition: item !== time.noteElement.tie.StartNote,
+    //           //     },
+    //           //   }
+    //           // }
 
-              if (!time.noteElement.tie) {
-                setEvaluatings(time, data)
-              } else {
-                for (const item of time.noteElement.tie.notes) {
-                  const note = getParentNote(item)
-                  if (!note) continue
-                  setEvaluatings(
-                    note,
-                    data,
-                    item !== time.noteElement.tie.StartNote
-                  )
-                  // const startNote = getBoundingBoxByverticalNote(note)
-                  // state.evaluatings = {
-                  //   ...state.evaluatings,
-                  //   [startNote.measureIndex]: {
-                  //     ...startNote,
-                  //     ...getLeveByScoreMeasure(data.score),
-                  //     score: data.score,
-                  //     dontTransition: item !== time.noteElement.tie.StartNote,
-                  //   },
-                  // }
-                }
-              }
+    //           if (!time.noteElement.tie) {
+    //             setEvaluatings(time, data)
+    //           } else {
+    //             for (const item of time.noteElement.tie.notes) {
+    //               const note = getParentNote(item)
+    //               if (!note) continue
+    //               setEvaluatings(
+    //                 note,
+    //                 data,
+    //                 item !== time.noteElement.tie.StartNote
+    //               )
+    //               // const startNote = getBoundingBoxByverticalNote(note)
+    //               // state.evaluatings = {
+    //               //   ...state.evaluatings,
+    //               //   [startNote.measureIndex]: {
+    //               //     ...startNote,
+    //               //     ...getLeveByScoreMeasure(data.score),
+    //               //     score: data.score,
+    //               //     dontTransition: item !== time.noteElement.tie.StartNote,
+    //               //   },
+    //               // }
+    //             }
+    //           }
 
-              // if (startNote.measureIndex !== endNote.measureIndex) {
-              //   state.evaluatings = {
-              //     ...state.evaluatings,
-              //     [endNote.measureIndex]: {
-              //       ...endNote,
-              //       ...getLeveByScoreMeasure(data.score),
-              //       score: data.score,
-              //       dontTransition: true
-              //     },
-              //   }
-              // }
-              break
-            }
-          }
-          // for (const time of state.times) {
-          //   if (data.measureRenderIndex == time.noteElement.sourceMeasure.measureListIndex) {
-          //     if (state.evaluatings[data.measureRenderIndex]) return
-          //     const startNote = getBoundingBoxByverticalNote(time)
-          //     const endNote = getBoundingBoxByverticalNote(getNoteBySlursStart(time, true, 'end'))
-          //     state.evaluatings = {
-          //       ...state.evaluatings,
-          //       [startNote.measureIndex]: {
-          //         ...startNote,
-          //         ...getLeveByScoreMeasure(data.score),
-          //         score: data.score,
-          //       },
-          //     }
-          //     if (startNote.measureIndex !== endNote.measureIndex) {
-          //       state.evaluatings = {
-          //         ...state.evaluatings,
-          //         [endNote.measureIndex]: {
-          //           ...endNote,
-          //           ...getLeveByScoreMeasure(data.score),
-          //           score: data.score,
-          //           dontTransition: true
-          //         },
-          //       }
-          //     }
-          //     break
-          //   }
-          // }
-        }
-      }
-    },
+    //           // if (startNote.measureIndex !== endNote.measureIndex) {
+    //           //   state.evaluatings = {
+    //           //     ...state.evaluatings,
+    //           //     [endNote.measureIndex]: {
+    //           //       ...endNote,
+    //           //       ...getLeveByScoreMeasure(data.score),
+    //           //       score: data.score,
+    //           //       dontTransition: true
+    //           //     },
+    //           //   }
+    //           // }
+    //           break
+    //         }
+    //       }
+    //       // for (const time of state.times) {
+    //       //   if (data.measureRenderIndex == time.noteElement.sourceMeasure.measureListIndex) {
+    //       //     if (state.evaluatings[data.measureRenderIndex]) return
+    //       //     const startNote = getBoundingBoxByverticalNote(time)
+    //       //     const endNote = getBoundingBoxByverticalNote(getNoteBySlursStart(time, true, 'end'))
+    //       //     state.evaluatings = {
+    //       //       ...state.evaluatings,
+    //       //       [startNote.measureIndex]: {
+    //       //         ...startNote,
+    //       //         ...getLeveByScoreMeasure(data.score),
+    //       //         score: data.score,
+    //       //       },
+    //       //     }
+    //       //     if (startNote.measureIndex !== endNote.measureIndex) {
+    //       //       state.evaluatings = {
+    //       //         ...state.evaluatings,
+    //       //         [endNote.measureIndex]: {
+    //       //           ...endNote,
+    //       //           ...getLeveByScoreMeasure(data.score),
+    //       //           score: data.score,
+    //       //           dontTransition: true
+    //       //         },
+    //       //       }
+    //       //     }
+    //       //     break
+    //       //   }
+    //       // }
+    //     }
+    //   }
+    // },
+
+		sendResult(evt?: IPostMessage) {
+			console.log("sendResult", evt);
+			if (evt?.content) {
+				const data = evt?.content?.body;
+				if (evt?.content.header.commond === "overall") {
+					detailState.isHideEvaluatReportSaveBtn = false;
+					Toast.clear();
+					this.res = data;
+					this.endloading = false;
+					RuntimeUtils.event.emit("onEvaluationResult", data);
+				} else if (evt?.content.header.commond === "checkDone") {
+					this.checkStatus = true;
+				} else if (evt?.content.header.commond === "checking") {
+					this.frequency = evt?.content?.body?.frequency;
+				} else if (evt?.content.header.commond === "recordEnd") {
+					if (this.delayData.checkStatus !== 'ing') return
+					this.delayData.count++;
+					if (this.delayData.count >= 2) {
+						this.handleToggleTune('finishTune');
+						return;
+					}
+					setTimeout(() => {
+						this.startTune()
+					}, 100)
+				} else {
+					const getBeforeNote = (index: number) => {
+						while (index >= 0) {
+							const item = state.times[index];
+							if (item.stave) {
+								return item;
+							}
+							index--;
+						}
+					};
+					const setEvaluatings = (note: any, data: any, dontTransition = false) => {
+						const startNote = getBoundingBoxByverticalNote(note);
+						state.evaluatings = {
+							...state.evaluatings,
+							[startNote.measureIndex]: {
+								...startNote,
+								...getLeveByScoreMeasure(data.score),
+								score: data.score,
+								dontTransition,
+							},
+						};
+					};
+
+					for (let index = 0; index < state.times.length; index++) {
+						let time = state.times[index];
+						if (data.measureRenderIndex == time.noteElement.sourceMeasure.measureListIndex) {
+							if (!time.stave) {
+								const ntime = getBeforeNote(index);
+								// console.log('ntime', ntime)
+								if (ntime) {
+									time = ntime;
+								}
+							}
+
+							if (!time.noteElement.tie) {
+								setEvaluatings(time, data);
+							} else {
+								for (const item of time.noteElement.tie.notes) {
+									const note = getParentNote(item);
+									if (!note) continue;
+									setEvaluatings(note, data, item !== time.noteElement.tie.StartNote);
+								}
+							}
+							break;
+						}
+					}
+				}
+			}
+		},
     setWiredStatus(res?: IPostMessage) {
       this.erjiShow = !res?.content.checkIsWired
       this.tuningStatus = true
@@ -741,10 +878,153 @@ export default defineComponent({
         data.cadence = this.res?.cadence
         data.integrity = this.res?.integrity
       }
-      return `${
-        location.origin
-      }/accompany/share-evaluating/index.html?${qs.stringify(data)}`
+      // return `${location.origin}/accompany/share-evaluating/index.html?${qs.stringify(data)}`
+      return ''
     },
+
+
+		/** 评测效验 */
+		async checkEvaluating() {
+			this.delayData.erji = await this.getWiredStatus();
+			this.delayData.time = await this.getDeviceDelay();
+			// 没有设备延迟数据,显示检测组件,并持续检测耳机状态
+			if (!this.delayData.time || this.delayData.isForce) {
+				this.delayData.open = runtime.delayCheckFirst && this.$route.query.evaluatingRecord ? false : true
+				this.delayData.count = 0;
+				if (runtime.delayCheckFirst && this.$route.query.evaluatingRecord) {
+					this.closeErji()
+				}
+				return;
+			}
+			this.handleCheckDelayEnd()
+		},    
+    /** 获取设备延迟 */
+		getDeviceDelay(): Promise<number> {
+			return new Promise((resolve) => {
+				const timer = setTimeout(() => {
+					resolve(0);
+				}, 1000)
+				postMessage({
+					api: "getDeviceDelay",
+				}, (res) => {
+					const delay = res?.content?.value > 0 ? res?.content?.value : 0;
+					clearTimeout(timer)
+					resolve(delay);
+				});
+			});
+		},
+		/** 获取耳机状态 */
+		getWiredStatus(): Promise<boolean> {
+			return new Promise((resolve) => {
+				const timer = setTimeout(() => {
+					resolve(false);
+				}, 1000)
+				postMessage({
+					api: "isWiredHeadsetOn",
+				}, (res) => {
+					const checkIsWired = res?.content?.checkIsWired ? true : false;
+          if (checkIsWired) {
+            if (this.delayData.step <= 5) {
+              this.delayData.step = 3
+            }
+          } else {
+            if (this.delayData.step === 2 || this.delayData.step === 3) {
+              this.delayData.step = 4
+            }
+          }
+					clearTimeout(timer)
+					resolve(checkIsWired);
+				});
+			});
+		},  
+		/** 持续检测耳机状态 */
+    checkWiredStatus() {
+      console.log('耳机状态',this.delayData.checkStatus)
+			// 设备检测结束,停止获取耳机状态
+			if (this.delayData.checkStatus !== 'ing' || this.delayData.open === false) {
+				return
+			}
+			setTimeout(async () => {
+				this.delayData.erji = await this.getWiredStatus();
+				if (this.delayData.erji) {
+					this.delayData.count = 0;
+					this.delayData.time = 0;
+					this.delayData.checkStatus = 'error'
+				}
+				this.checkWiredStatus();
+			}, 1000)
+		},    
+		/** 开始效音 */
+		startTune() {
+			// 带了耳机,停止播放效音
+			if (this.delayData.erji) return;
+			this.handleToggleTune('start')
+			setTimeout(() => {
+				this.handleToggleTune('stop')
+			}, 1500)
+		},      
+		/** 设备延迟检测结束 */
+		handleCheckDelayEnd() {
+			if (this.delayData.erji) {
+				this.closeErji();
+			} else {
+				this.erjiShow = true;
+				HeadphoneData.toggle();
+			}
+		},
+		/** 切换效音 */
+		handleToggleTune(state: 'start' | 'stop' | 'finishTune'){
+			if (state === 'start') {
+        this.delayData.step = 5
+				// 开始效音
+				postMessage({
+					api: "startTune",
+					content: {
+						count: this.delayData.count + '',
+					}
+				})
+			} else if (state === 'stop') {
+				// 结束效音,触发时机: 1.监听后台效音返回 2.点击跳过效音或关闭效音
+				postMessage({
+					api: "endTune"
+				})
+			} else if (state === 'finishTune') {
+        this.delayData.step = 6
+				// 效音完成
+				postMessage({
+					api: "finishTune",
+				}, (res) => {
+					const result = res?.content?.result //1成功 0失败
+					// Toast('检测延迟完成')
+					// setTimeout(() => {
+					// 	this.delayData.open = false
+					// }, 500)
+				})
+			}
+			
+		},    
+		/** 停止设备延迟检测 */
+		handleStopCheckDelay() {
+			runtime.delayCheckFirst = true
+			this.delayData.open = false
+			this.delayData.checkStatus = 'init'
+			this.handleToggleTune('stop')
+			this.close();
+		},    
+		/** 开始检测设备延迟 */
+		async handleStartCheckDelay(){
+			if (this.delayData.checkStatus === 'ing') return;
+      this.delayData.step = 2
+			this.delayData.erji = await this.getWiredStatus();
+			if (this.delayData.erji) {
+				this.delayData.checkStatus = 'error'
+				return;
+			}
+			this.delayData.checkStatus = 'ing';
+			this.startTune();
+			this.checkWiredStatus();
+		},
+
   },
   mounted() {
     if (!SettingState.eva.mute) {
@@ -783,6 +1063,9 @@ export default defineComponent({
       },
       this.setWiredStatus
     )
+    hideComplexButton(handleComplexButton, true);
+    // 开始效验
+		this.checkEvaluating()
   },
   unmounted() {
     state.mode = this.oldMode
@@ -1053,6 +1336,26 @@ export default defineComponent({
             </div>
           ) : null}
         </Popup>
+
+				{/* 延迟检测窗口 */}
+				<Popup 
+					teleport="body"
+					class="popup-scale" 
+					transition="van-scale" 
+					overlay={false}
+					show={this.delayData.open}
+					onClose={() => this.handleCheckDelayEnd()}
+				>
+					<CheckDelayPopup 
+						delayData={this.delayData}
+						onStartCheckDelay={() => this.handleStartCheckDelay()}
+						onClose={() => this.handleStopCheckDelay()} 
+					/>
+				</Popup>
+
+				{/* <Headphone onClose={this.closeErji} />
+				<PhoneTip show={!this.delayData.erji && runtime.evaluatingTips} /> */}
+
       </div>
     )
   },

+ 1 - 1
src/pages/detail/helpers.ts

@@ -158,7 +158,7 @@ const tranTime = (str: string = '') => {
   return `1970-01-01 00:${result}0`
 }
 export const getAllNodes = (osmd: any) => {
-  console.log(9999, osmd)
+  //console.log(9999, osmd)
   const detailId = getLinkId()
   let fixtime = browserInfo.huawei ? 0.08 : 0 //getFixTime()
   const allNotes: any[] = []

+ 34 - 4
src/pages/detail/runtime.ts

@@ -132,7 +132,14 @@ const state = reactive({
   /** 第几分轨 */
   partIndex: 0,
   /** 当前音符index */
-  activeIndex: 0
+  activeIndex: 0,
+  /** 音频播放结束钩子 */
+  playEndCallback: {
+    /** 结束评测 */
+    endEvaluat: () => {}
+  } as {[key: string]: () => void},  
+  /** 阶段评测,延迟检测是否检测过 */
+  delayCheckFirst: false,  
 })
 
 const syncStepIndex = (i: number) => {
@@ -222,7 +229,7 @@ export const getActiveMidiId = () => {
  * 修改原音或伴奏
  * @param val IMode
  */
-export const changeMode = async (val: IMode) => {
+export const changeMode = async (val: IMode, type?: string | undefined) => {
   const cm: IMode = val === 'background' ? 'music' : 'background'
   // console.log(!state.songs[val], val, cm)
   if (detailState.activeDetail.isAppPlay) {
@@ -258,8 +265,13 @@ export const changeMode = async (val: IMode) => {
   //   return
   // }
   state.mode = val
-  state.audiosInstance?.setMute(true, state.songs[cm])
-  state.audiosInstance?.setMute(false, state.songs[val])
+  if (type === 'all') {
+    state.audiosInstance?.setMute(true, state.songs[cm])
+    state.audiosInstance?.setMute(true, state.songs[val])
+  } else {
+    state.audiosInstance?.setMute(true, state.songs[cm])
+    state.audiosInstance?.setMute(false, state.songs[val])
+  }
 }
 
 export const changeAllMode = () => {
@@ -964,6 +976,24 @@ export const setAudioInit = () => {
     refreshView()
     // })
   })
+  // 监听评测曲谱音频播放进度,返回
+  listenerMessage("playProgress", (res) => {
+    const time = res?.content.currentTime / 1000
+    requestAnimationFrame(async () => {
+      if (state.playState === 'play') {
+        state.currentTimeNum = time
+        refreshPlayer(time)
+        refreshIndex(time)
+        // 播放到最后一秒,停止播放
+        if (res?.content?.totalDuration > 1000 && res?.content?.currentTime >= res?.content?.totalDuration) {
+          state.playState = 'pause'
+          state.playEndCallback.endEvaluat()
+          ended(new Event('ended'))
+        }
+      }
+      refreshView()
+    })
+  });
   state.audiosInstance.event.on('timeupdate', () => {
     state.currentTimeNum = state.audiosInstance.currentTime
     state.currentTime = formatTime(state.audiosInstance.currentTime)

+ 1 - 1
src/pages/detail/setting-popup/set.tsx

@@ -36,7 +36,7 @@ export default defineComponent({
           }}
         />
         <Cell
-          title="校音提醒"
+          title="延迟检测"
           vSlots={{
             extra: () => (
               <Switch

+ 1 - 1
src/pages/detail/setting-state.ts

@@ -11,7 +11,7 @@ export interface SettingState {
 export type iSett = {
   /** 护眼模式 */
   eyeProtection: boolean
-  /** 校音提醒 */
+  /** 延迟检测 */
   tuning: boolean
   /** 摄像头 */
   camera: boolean

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/subpages/colexiu/buttons/data/start_new.json


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/subpages/colexiu/buttons/data/starting_new.json


+ 324 - 22
src/subpages/colexiu/buttons/evaluating.tsx

@@ -1,5 +1,5 @@
-import { Button, Toast } from 'vant'
-import { defineComponent, onBeforeUnmount, onMounted, Ref, ref, Teleport, Transition } from 'vue'
+import { Button, Toast, Popup } from 'vant'
+import { defineComponent, onBeforeUnmount, onMounted, Ref, ref, Teleport, Transition, reactive } from 'vue'
 import '@dotlottie/player-component'
 import detailState, { isRhythmicExercises } from '/src/pages/detail/state'
 import SettingState from '/src/pages/detail/setting-state'
@@ -21,10 +21,41 @@ import Evaluating, { evaluatingShow } from '../popups/evaluating'
 // @ts-ignore
 import styles from './index.module.less'
 import { Vue3Lottie } from 'vue3-lottie'
-import startData from './data/start.json'
-import startingData from './data/starting.json'
+import startData from './data/start_new.json'
+import startingData from './data/starting_new.json'
 import { unitTestData } from '../unitTest'
 import iconEvaluatingStart from './icons/icon-evaluatingStart.png'
+import qs from 'query-string'
+import CheckDelayPopup from "/src/pages/detail/CheckDelayPopup";
+import Headphone, { HeadphoneData } from "/src/pages/detail/Headphone";
+import { modelType } from './index'
+
+/** 初始化评测音频 */
+export const evaluatCreateMusicPlayer = () => {
+	return new Promise((resolve) => {
+		// 初始化曲谱音频 和效音音频
+		postMessage(
+      {
+        api: "createMusicPlayer",
+        content: {
+          musicSrc: runtime.songs.background || runtime.songs.music, // 曲谱音频url
+          tuneSrc: "https://oss.dayaedu.com/cloud-coach/1686725501654check_music1_(1).mp3", //效音音频url
+        },
+      },
+      () => {
+        if (browserInfo.ios) {
+          resolve(true);
+        }
+      }
+    );
+		// 安卓不需要
+		if(!browserInfo.ios){
+			resolve(true)
+		}
+	})
+}
+
+const searchParams: any = qs.parse(location.search)
 
 /**
  * 节拍器时长
@@ -44,6 +75,200 @@ const playUrl: Ref<string> = ref('')
 const endResult = ref(null)
 const browserInfo = browser()
 const scoreList: any[] = []
+let calculateInfo: any = {}
+/** 延迟数据 */
+const delayData =  reactive({
+  /** 是否强制检测 */
+  isForce: true,
+  /** 弹窗 */
+  open: false,
+  /** 延迟次数 */
+  count: 0,
+  /** 延迟时间 */
+  time: 0,
+  /** 耳机状态 */
+  erji: false,
+  /** 检测状态 */
+  checkStatus: 'init' as 'init' | 'ing' | 'error',
+  step: 1,
+  earPhoneType: "" as "" | "有线耳机" | "蓝牙耳机",
+})
+  /** 获取耳机状态 */
+  const getWiredStatus = (): Promise<boolean> => {
+    return new Promise((resolve) => {
+      const timer = setTimeout(() => {
+        resolve(false);
+      }, 1000)
+      postMessage({
+        api: "isWiredHeadsetOn",
+      }, (res) => {
+        delayData.earPhoneType = res?.content?.type || "";
+        const checkIsWired = res?.content?.checkIsWired ? true : false;
+        if (checkIsWired) {
+          if (delayData.step <= 5) {
+            delayData.step = 3
+          }
+        } else {
+          if (delayData.step === 2) {
+            delayData.step = 4
+          }
+        }
+        clearTimeout(timer)
+        resolve(checkIsWired);
+      });
+    });
+  }
+
+  const closeErji = () => {
+    //
+  }
+
+  /** 获取设备延迟 */
+  const getDeviceDelay = (): Promise<number> => {
+    return new Promise((resolve) => {
+      const timer = setTimeout(() => {
+        resolve(0);
+      }, 1000)
+      postMessage({
+        api: "getDeviceDelay",
+      }, (res) => {
+        const delay = res?.content?.value > 0 ? res?.content?.value : 0;
+        clearTimeout(timer)
+        resolve(delay);
+      });
+    });
+  }
+  /** 设备延迟检测结束 */
+  const handleCheckDelayEnd = () => {
+    if (delayData.erji) {
+      closeErji();
+    } else {
+      // this.erjiShow = true;
+      HeadphoneData.toggle();
+    }
+  }
+  /** 评测效验 */
+  const checkEvaluating = async () => {
+    delayData.erji = await getWiredStatus();
+    delayData.time = await getDeviceDelay();
+    // 没有设备延迟数据,显示检测组件,并持续检测耳机状态
+    if (!delayData.time || delayData.isForce) {
+      delayData.open = (runtime.delayCheckFirst && searchParams.evaluatingRecord || !SettingState.sett.tuning) ? false : true
+      delayData.count = 0;
+      checkWiredStatus();
+      if (runtime.delayCheckFirst && searchParams.evaluatingRecord) {
+        // closeErji()
+      }
+      return;
+    }
+    handleCheckDelayEnd()
+  }  
+
+
+		/** 持续检测耳机状态 */
+    const checkWiredStatus = () => {
+      console.log('耳机状态',delayData.checkStatus, delayData.step)
+			// 设备检测结束,停止获取耳机状态
+			// if (delayData.checkStatus !== 'ing' || delayData.open === false) {
+			// 	return
+			// }
+      if (delayData.open === false) {
+				return
+			}
+			setTimeout(async () => {
+				delayData.erji = await getWiredStatus();
+				if (delayData.erji) {
+					delayData.count = 0;
+					delayData.time = 0;
+					// delayData.checkStatus = 'error'
+				} else {
+          if (delayData.step === 3) {
+            delayData.step = 1
+            delayData.checkStatus = 'init'
+          }
+        }
+				checkWiredStatus();
+			}, 1000)
+		}  
+		/** 切换效音 */
+		const handleToggleTune = (state: 'start' | 'stop' | 'finishTune') => {
+			if (state === 'start') {
+        delayData.step = 5
+				// 开始效音
+				postMessage({
+					api: "startTune",
+					content: {
+						count: delayData.count + '',
+					}
+				}, (res) => {
+          // 用户没有授权,需要重置状态
+          if (res?.content?.reson) {
+            delayData.step = 1
+            delayData.checkStatus = 'init'
+          } else {
+            setTimeout(() => {
+              handleToggleTune('stop')
+            }, 1500)
+          }
+        })
+			} else if (state === 'stop') {
+				// 结束效音,触发时机: 1.监听后台效音返回 2.点击跳过效音或关闭效音
+				postMessage({
+					api: "endTune"
+				})
+			} else if (state === 'finishTune') {
+        delayData.step = 6
+				// 效音完成
+				postMessage({
+					api: "finishTune",
+				}, (res) => {
+					const result = res?.content?.result //1成功 0失败
+					// Toast('检测延迟完成')
+					// setTimeout(() => {
+					// 	delayData.open = false
+					// }, 500)
+				})
+			}
+			
+		}    
+		/** 开始效音 */
+		const startTune = () => {
+			// 带了耳机,停止播放效音
+			if (delayData.erji) return;
+			handleToggleTune('start')
+		}     
+		/** 停止设备延迟检测 */
+		const handleStopCheckDelay = () => {
+			runtime.delayCheckFirst = true
+			delayData.open = false
+      setTimeout(() => {
+        delayData.checkStatus = 'init'
+        delayData.step = 1
+      }, 500);
+			handleToggleTune('stop')
+			// this.close();
+		} 
+    const handleDelayBack = () => {
+      modelType.value = 'init'
+      delayData.open = false
+			delayData.checkStatus = 'init'
+      delayData.step = 1
+			handleToggleTune('stop')
+    }
+		/** 开始检测设备延迟 */
+		const handleStartCheckDelay = async () => {
+			if (delayData.checkStatus === 'ing') return;
+      delayData.step = 2
+			delayData.erji = await getWiredStatus();
+			if (delayData.erji) {
+				delayData.checkStatus = 'error'
+				return;
+			}
+			delayData.checkStatus = 'ing';
+      setTimeout(() => {
+        startTune()
+      }, 2000)
+		}
 
 // frequency 频率, amplitude 振幅, decibels 分贝
 type TCriteria = "frequency" | "amplitude" | "decibels";
@@ -87,6 +312,8 @@ const formatTimes = () => {
   // 阶段评测前一个节拍的标示
   let preLyricsContent = ''
   let preTimes = []
+  let unitTestIdx = 0
+  let preTime = 0
   if (unitTestData.isSelectMeasureMode) {
     const startIndex = detailState.times.findIndex(
       (n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[0].NoteToGraphicalNoteObjectId
@@ -94,6 +321,9 @@ const formatTimes = () => {
     const endIndex = detailState.times.findIndex(
       (n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[1].NoteToGraphicalNoteObjectId
     )
+    if (startIndex > 1) {
+      preTime = detailState.times[startIndex-1].time * 1000
+    }
     times = detailState.times.filter((n: any, index: number) => {
       return index >= startIndex && index <= endIndex
     })
@@ -103,6 +333,7 @@ const formatTimes = () => {
     starTime = times[0].sourceRelativeTime || times[0].relativeTime
     actualBeatLength = startIndex == 0 && !detailState.needTick ? actualBeatLength : 0
     // console.log("🚀 ~ times", times, '开始小节', startIndex, actualBeatLength)
+    unitTestIdx = startIndex
   }
   // 找到阶段评测,开始小节前面最近的是play或者listen的小节
   if (preTimes.length) {
@@ -122,6 +353,7 @@ const formatTimes = () => {
   }
   let measureIndex = -1
   let recordMeasure = -1
+  let firstNoteTime = unitTestIdx > 1 ? preTime : 0
   for (let index = 0; index < times.length; index++) {
     const item = times[index]
     const note = getNoteByMeasuresSlursStart(item)
@@ -174,18 +406,23 @@ const formatTimes = () => {
       denominator: note.noteElement?.Length.denominator,
       isOrnament: !!note?.voiceEntry?.ornamentContainer,
     }
+    // console.log('时间1111', data)
     datas.push(data)
   }
-  return datas
+  return {
+    datas,
+    firstNoteTime
+  }
 }
 const connect = async () => {
   const search = useOriginSearch()
   connentLoading.value = true
   const behaviorId = sessionStorage.getItem('behaviorId') || search.behaviorId || initBehaviorId
   const rate = runtime.speed / detailState.baseSpeed //1
-
+  calculateInfo = formatTimes()
   const content = {
-    musicXmlInfos: formatTimes(),
+    musicXmlInfos: calculateInfo.datas,
+    firstNoteTime: calculateInfo.firstNoteTime,
     subjectId: detailState.subjectId ? detailState.subjectId : detailState.isPercussion ? 1 : detailState.subjectId,
     detailId: detailState.activeDetail?.id,
     examSongId: search.id,
@@ -196,7 +433,7 @@ const connect = async () => {
     clientId: 'STUDENT',
     hertz: SettingState.sett.hertz,
     feature: 'EVALUATION',
-    practiceSource: search.unitId ? 'UNIT_TEST' : 'PRACTICE',
+    practiceSource: (search.resourceType && search.resourceType === 'practice') ? 'UNIT_TEST_PRACTICE' : search.unitId ? 'UNIT_TEST' : 'PRACTICE',
     // 这里定义的是数字但是因为是通过input输入所以强制转化一次
     reactionTimeMs: parseFloat('' + SettingState.eva.reactionTimeMs) || 0,
     speed: runtime.speed,
@@ -264,27 +501,28 @@ const cancelTheEvaluation = () => {
     RuntimeUtils.clearIntervalTimeline()
     RuntimeUtils.setCurrentTime(0)
     Toast.clear()
-  }, 200);
+  }, 500);
 }
 
 const stopPlay = () => {
   console.log('调用stopPlay')
-  if (!connentLoading.value) {
+  if (!connentLoading.value && evaluating.value) {
     cancelTheEvaluation()
   }
   startButtonShow.value = true
   connentLoading.value = false
   evaluating.value = false
+  modelType.value = 'init'
 }
 export const evaluatStopPlay = stopPlay
 
 const startPlay = () => {
   console.log('连接服务成功,开始播放', new Date().getTime() - runtime.clickTime)
-  if (!SettingState.eva.mute) {
-    RuntimeUtils.changeAllMode()
-  } else {
-    RuntimeUtils.changeMode('background')
-  }
+  // if (!SettingState.eva.mute) {
+  //   RuntimeUtils.changeAllMode()
+  // } else {
+  //   RuntimeUtils.changeMode('background')
+  // }
   startButtonShow.value = false
   RuntimeUtils.setPlayState()
 }
@@ -307,9 +545,10 @@ const setPlayer = async () => {
   })
   try {
     await connect()
-    startPlay()
+    //startPlay()
     setTimeout(() => {
       console.log('关闭弹窗')
+      startButtonShow.value = false
       Toast.clear()
       hint.close()
     }, 100)
@@ -317,6 +556,7 @@ const setPlayer = async () => {
     runtime.evaluatingStatus = false
     Toast.clear()
   }
+  evaluatStart()
 }
 
 const togglePlay = () => {
@@ -391,7 +631,7 @@ const playerStop = () => {
       }
     )
     RuntimeUtils.endCapture()
-  },200)
+  }, 500);
 }
 export const evaluatPlayerStop = playerStop
 
@@ -435,11 +675,16 @@ const evaluatStart = () => {
   postMessage(
     {
       api: 'startRecording',
+      content: {
+        accompanimentState: SettingState.eva.mute ? 1 : 0,
+        firstNoteTime: calculateInfo.firstNoteTime || 0,
+      }
     },
     () => {
       // console.log('开始录音app回调时间', Date.now())
       backtime = Date.now()
       evaluating.value = true
+      runtime.playState = "play";
       if (detailState.activeDetail?.midiUrl) {
         console.log('midiUrl', detailState.activeDetail?.midiUrl)
         setTimeout(() => {
@@ -451,6 +696,11 @@ const evaluatStart = () => {
   RuntimeUtils.startCapture()
 }
 
+  /** 音频播放完结束评测 */
+  const playEnd_endEvalute = () => {
+    playerStop()
+  }
+
 /**
  * 酷乐秀活动接口,Url中有设置并且仅在学生端提评分交数据
  * 管乐团单元测验, url中有单元测验ID仅在学生端提评分交数据
@@ -500,6 +750,16 @@ const sendResult = (evt?: IPostMessage) => {
       // 此处已经在校音中单独监听不做处理
     } else if (evt?.content.header.commond === 'checking') {
       // 此处已经在校音中单独监听不做处理
+    } else if (evt?.content.header.commond === "recordEnd") {
+      if (delayData.checkStatus !== 'ing') return
+        delayData.count++;
+      if (delayData.count >= 2) {
+        handleToggleTune('finishTune');
+        return;
+      }
+      setTimeout(() => {
+        startTune()
+      }, 100)
     } else {
       const getBeforeNote = (index: number) => {
         while (index >= 0) {
@@ -602,22 +862,44 @@ export const submitMaxScore = () => {
     })
   }
 }
+/**
+ * 木管(长笛 萨克斯 单簧管)乐器一级的2、3、6测评要放原音音频
+ * 铜管乐器一级的1a,1b,5,6测评要放原音音频
+ */
+const getMusicMode = (): RuntimeUtils.IMode => {
+	const muguan = [2, 4, 5, 6];
+	const tongguan = [12, 13, 14, 15, 17];
+	if (muguan.includes(detailState.subjectId) && (detailState.activeDetail?.examSongName || "").search(/[^\u0000-\u00FF](1-2|1-3|1-6)/gi) > -1) {
+		return "music";
+	}
+	if (tongguan.includes(detailState.subjectId) && (detailState.activeDetail?.examSongName || "").search(/[^\u0000-\u00FF](1-1-1|1-1-2|1-5|1-6)/gi) > -1) {
+		return "music";
+	}
+	if ([23, 113, 121].includes(detailState.subjectId)) {
+		return "music";
+	}
+	return "background";
+};
 
 export default defineComponent({
   name: 'ColexiuButtonEvaluating',
   setup(props, { expose }) {
     onMounted(async () => {
       console.log('进入评测模块')
+      if (!SettingState.eva.mute) {
+        RuntimeUtils.changeAllMode();
+      } else {
+        RuntimeUtils.changeMode('background', 'all')
+      }
       handleCheckEvaluatStatus()
       // 如果为单元测验和课后训练,不清楚选段数据
       if (!unitTestData.isSelectMeasureMode) {
         detailState.section = []
         detailState.sectionStatus = false
       }
-      RuntimeUtils.changeAllMode()
       playUrl.value = runtime.songs.background || (runtime.songs.music as string)
-      runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('play', timeupdate)
-      runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('timeupdate', onProgress)
+      // runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('play', timeupdate)
+      // runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('timeupdate', onProgress)
       // RuntimeUtils.event.on('next-click', playerStop)
       RuntimeUtils.event.on('ended', endevent)
       listenerMessage('sendResult', sendResult)
@@ -625,12 +907,15 @@ export default defineComponent({
       listenerMessage('cloudTimeUpdae', onProgress)
       RuntimeUtils.event.on('tickDestroy', cloudMetronome)
       RuntimeUtils.event.on('tickEnd', evaluatStart)
+      runtime.playEndCallback.endEvaluat = playEnd_endEvalute
       hideComplexButton(handleComplexButton, true);
+      // 开始效验
+		  checkEvaluating()
     })
 
     onBeforeUnmount(() => {
-      runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('play', timeupdate)
-      runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('timeupdate', onProgress)
+      // runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('play', timeupdate)
+      // runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('timeupdate', onProgress)
       // RuntimeUtils.event.off('next-click', playerStop)
       RuntimeUtils.event.off('ended', endevent)
       RuntimeUtils.event.off('tickDestroy', cloudMetronome)
@@ -690,6 +975,23 @@ export default defineComponent({
               <Vue3Lottie class={styles.inRadioIcon} animationData={startingData}></Vue3Lottie>
             </div>
           )}
+
+        {/* 延迟检测窗口 */}
+				<Popup 
+					teleport="body"
+					class="popup-scale" 
+					transition="van-scale" 
+					overlay={false}
+					show={delayData.open}
+					onClose={() => handleCheckDelayEnd()}
+				>
+					<CheckDelayPopup 
+						delayData={delayData}
+						onStartCheckDelay={() => handleStartCheckDelay()}
+						onClose={() => handleStopCheckDelay()} 
+            onBack={() => handleDelayBack()}
+					/>
+				</Popup>
         </Teleport>
       )
     }

+ 9 - 1
src/subpages/colexiu/buttons/index.module.less

@@ -483,4 +483,12 @@ body {
       min-width: fit-content;
     }
   }
-}
+}
+
+body {
+  :global {
+    .popup-scale {
+      margin: 0 !important;
+    }
+  }
+}

+ 1 - 0
src/subpages/colexiu/buttons/index.tsx

@@ -111,6 +111,7 @@ export const onChangeModelType = (type: IModelType) => {
     RuntimeUtils.changeSpeed(detailState.activeDetail?.originalSpeed, false)
     // 评测模式
     runtime.evaluatingStatus = true
+    modelType.value = type
   } else {
     const speeds = store.get('speeds') || {}
     const search = useOriginSearch()

+ 7 - 1
src/subpages/colexiu/index.tsx

@@ -49,6 +49,7 @@ import { musicInfo } from './state'
 import ToggleMusicSheet from './plugins/toggleMusicSheet'
 import request from '/src/helpers/request'
 import Metronome, { metronomeData } from '/src/helpers/metronome'
+import Evaluating, { evaluatCreateMusicPlayer } from '/src/pages/detail/evaluating'
 
 // json化曲谱的note信息和svg
 export const musicJSON = reactive({
@@ -300,6 +301,7 @@ export default defineComponent({
           RuntimeUtils.refreshView();``
         }
       })
+      evaluatCreateMusicPlayer()
     }
 
     const onStartRender = async () => {
@@ -439,7 +441,11 @@ export default defineComponent({
             {tipShow.value && !error && <Tips />}
           </div>
           {/* 效音 */}
-          <Transition name="van-slide-up">{soundEffectShow.value && <SoundEffect />}</Transition>
+          {/* <Transition name="van-slide-up">{soundEffectShow.value && <SoundEffect />}</Transition> */}
+
+          {/* {runtime.evaluatingStatus && !detailState.renderLoading ? (
+            <Evaluating />
+          ) : null} */}
 
           {/* 单元测验选段 */}
           {!renderLoading.value && <UnitTest />}

+ 1 - 1
src/subpages/colexiu/popups/evaluating/index.module.less

@@ -250,7 +250,7 @@
 .headerButton {
   position: absolute;
   right: -60px;
-  top: -26px;
+  top: -6px;
   display: flex;
   justify-content: space-between;
   align-items: center;

BIN
src/subpages/colexiu/popups/permission/icons/earphone.png


+ 1 - 1
src/subpages/colexiu/popups/setting/evaluat.tsx

@@ -26,7 +26,7 @@ export default defineComponent({
               </RadioGroup>
             </Cell>
             <Divider />
-            <Cell center border={false} title="校音提醒">
+            <Cell center border={false} title="延迟检测">
               <Switch v-model={SettingState.sett.tuning} {...switchProps}>
                 off
               </Switch>

+ 2 - 2
src/subpages/colexiu/uses/use-evaluat.ts

@@ -53,8 +53,8 @@ export const handleCheckEvaluatStatus = () => {
   // postMessage({ api: 'isWiredHeadsetOn' }, setWiredStatus)
   postMessage({ api: 'isWiredHeadsetOn' }, (evt) => {
     // console.log('🚀 ~ 耳机状态', evt)
-    permissionPopup.active = 'earphone'
-    permissionPopup.show = !evt?.content.checkIsWired
+    // permissionPopup.active = 'earphone'
+    // permissionPopup.show = !evt?.content.checkIsWired
   })
 }
 

Некоторые файлы не были показаны из-за большого количества измененных файлов