index.tsx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. import styles from "./index.module.less";
  2. import { Snackbar } from "@varlet/ui";
  3. import { closeToast, showLoadingToast, showToast, Popup } from "vant";
  4. import { defineComponent, onMounted, onUnmounted, reactive, ref, watch } from "vue";
  5. import { getLeveByScore, getLeveByScoreMeasure, IEvaluatings } from "./evaluatResult";
  6. import {
  7. cancelEvaluating,
  8. endEvaluating,
  9. endSoundCheck,
  10. getEarphone,
  11. api_proxyServiceMessage,
  12. removeResult,
  13. sendResult,
  14. startEvaluating,
  15. startSoundCheck,
  16. api_openWebView,
  17. api_startRecording,
  18. api_startRecordingCb,
  19. api_stopRecording,
  20. api_recordStartTime,
  21. api_remove_recordStartTime,
  22. api_startCapture,
  23. api_endCapture,
  24. api_getDeviceDelay,
  25. hideComplexButton,
  26. api_checkSocketStatus,
  27. addAccompanyError,
  28. removeAccompanyError,
  29. addSocketStatus,
  30. removeSocketStatus,
  31. api_disconnectSocket,
  32. api_midiMicDelay,
  33. api_cloudSetCurrentTime,
  34. api_cloudChangeSpeed,
  35. } from "/src/helpers/communication";
  36. import state, {
  37. IPlayState,
  38. clearSelection,
  39. handleStopPlay,
  40. onPlay,
  41. resetPlaybackToStart,
  42. togglePlay,
  43. } from "/src/state";
  44. import { IPostMessage } from "/src/utils/native-message";
  45. import { usePageVisibility } from "@vant/use";
  46. import { browser } from "/src/utils";
  47. import { getAudioCurrentTime, toggleMutePlayAudio, audioListStart, audioData } from "../audio-list";
  48. import { handleStartTick, tickData } from "../tick";
  49. import AbnormalPop from "../abnormal-pop";
  50. import { storeData } from "../../store";
  51. import icon_bg from '../abnormal-pop/icon_bg.svg'
  52. import icon_close from '../abnormal-pop/icon_close.svg'
  53. import icon_btn from '../abnormal-pop/icon_btn.svg'
  54. import icon_success from '../abnormal-pop/icon_success.svg'
  55. const browserInfo = browser();
  56. let socketStartTime = 0
  57. export const popImgs = {
  58. icon_bg,
  59. icon_close,
  60. icon_btn,
  61. icon_success
  62. }
  63. export const evaluatingData = reactive({
  64. /** 评测数据 */
  65. contentData: {} as any,
  66. /** 评测模块是否加载完成 */
  67. rendered: false,
  68. earphone: false, // 是否插入耳机
  69. soundEffect: false, // 是否效音
  70. soundEffectFrequency: 0, // 效音频率
  71. checkStep: 0, // 执行步骤
  72. checkEnd: false, // 检测结束
  73. earphoneMode: false, // 耳机弹窗
  74. soundEffectMode: false, // 效音弹窗
  75. websocketState: false, // websocket连接状态
  76. /**是否开始播放 */
  77. startBegin: false, // 开始
  78. backtime: 0, // 延迟时间
  79. /** 已经评测的数据 */
  80. evaluatings: {} as IEvaluatings,
  81. /** 评测结果 */
  82. resultData: {} as any,
  83. /** 评测结果弹窗 */
  84. resulstMode: false,
  85. /** 是否是完整评测 */
  86. isComplete: false,
  87. /** */
  88. isDisabledPlayMusic: false,
  89. /** socket异常状态弹窗 */
  90. socketErrorPop: false,
  91. /** 异常提示 */
  92. errorContents: '',
  93. /** socket异常状态弹窗的状态值 */
  94. socketErrorStatus: 0,
  95. /** 延迟检测,socket状态异常 */
  96. delayCheckSocketError: false,
  97. /** 异常状态,不生成评测记录,不调用保存接口 */
  98. isErrorState: false,
  99. /** accompanyError,错误类型 */
  100. accompanyErrorType: '',
  101. /** app播放结束状态,重新评测需要重置为 */
  102. isAudioPlayEnd: false,
  103. });
  104. const sendOffsetTime = async (offsetTime: number) => {
  105. const delayData = await api_getDeviceDelay();
  106. api_midiMicDelay({
  107. header: {
  108. commond: 'audioPlayStart',
  109. type: 'SOUND_COMPARE',
  110. },
  111. body: {
  112. offsetTime,
  113. micDelay: delayData?.content?.value
  114. },
  115. })
  116. }
  117. /** 点击开始评测按钮 */
  118. export const handleStartEvaluat = async () => {
  119. if (state.modeType === "evaluating") {
  120. handleCancelEvaluat();
  121. } else {
  122. if (state.platform !== 'PC') {
  123. // 评测前先检查APP端的websocket状态
  124. const res = await api_checkSocketStatus();
  125. if (res?.content?.status === "connected") {
  126. handleStopPlay();
  127. } else {
  128. // socket未连接
  129. // evaluatingData.socketErrorPop = true
  130. }
  131. } else {
  132. handleStopPlay();
  133. }
  134. }
  135. state.modeType = state.modeType === "evaluating" ? "practise" : "evaluating";
  136. if (state.modeType !== "evaluating") {
  137. // 切换到练习模式,卸载评测模块
  138. evaluatingData.rendered = false;
  139. }
  140. };
  141. /** 开始评测 & 延迟检测开始按钮 */
  142. export const startCheckDelay = async () => {
  143. // 评测前先检查APP端的websocket状态
  144. const res = await api_checkSocketStatus();
  145. if (res?.content?.status === "connected") {
  146. //
  147. return new Promise((resolve) => {
  148. resolve({checked: true})
  149. });
  150. } else {
  151. /**
  152. * socket未连接,记录此时的时间,以便于和收到socket成功链接,进行对比,对比时间小于500ms时,则连接中的状态默认显示500ms持续时间
  153. *
  154. * */
  155. socketStartTime = +new Date()
  156. evaluatingData.socketErrorPop = true
  157. evaluatingData.socketErrorStatus = 1
  158. return new Promise((resolve) => {
  159. resolve({checked: false})
  160. });
  161. }
  162. }
  163. const check_currentTime = () => {
  164. let preTime = 0;
  165. // 选段评测模式
  166. if (state.isSelectMeasureMode) {
  167. preTime = state.section[0].time * 1000;
  168. }
  169. const currentTime = getAudioCurrentTime() * 1000 - preTime;
  170. // console.log('播放进度music', currentTime, 'preTime:' + preTime)
  171. if (currentTime >= 500) {
  172. sendEvaluatingOffsetTime(500);
  173. return;
  174. }
  175. setTimeout(() => {
  176. check_currentTime();
  177. }, 10);
  178. };
  179. /** 开始播放发送延迟时间 */
  180. export const sendEvaluatingOffsetTime = async (currentTime: number) => {
  181. // 没有开始时间点, 不处理
  182. if (!evaluatingData.backtime) return;
  183. const nowTime = Date.now();
  184. const delayTime = nowTime - evaluatingData.backtime - currentTime;
  185. console.error("真正播放延迟", delayTime, "currentTime:", currentTime);
  186. await api_proxyServiceMessage({
  187. header: {
  188. commond: "audioPlayStart",
  189. type: "SOUND_COMPARE",
  190. },
  191. body: {
  192. offsetTime: delayTime < 0 ? 0 : delayTime,
  193. micDelay: 0,
  194. },
  195. });
  196. };
  197. /** 检测耳机 */
  198. export const checkUseEarphone = async () => {
  199. const res = await getEarphone();
  200. return res?.content?.checkIsWired || false;
  201. };
  202. /**
  203. * 开始录音
  204. */
  205. const handleStartSoundCheck = () => {
  206. startSoundCheck();
  207. };
  208. /** 结束录音 */
  209. export const handleEndSoundCheck = () => {
  210. endSoundCheck();
  211. };
  212. /** 连接websocket */
  213. export const connectWebsocket = async (content: any) => {
  214. evaluatingData.contentData = content;
  215. evaluatingData.websocketState = true;
  216. };
  217. /**
  218. * 执行检测
  219. */
  220. export const handlePerformDetection = async () => {
  221. // 检测完成不检测了
  222. if (evaluatingData.checkEnd) return;
  223. // 延迟检测
  224. if (evaluatingData.checkStep === 0) {
  225. evaluatingData.checkStep = 5;
  226. // 没有设备延迟数据 或 开启了效音 显示检测组件,并持续检测耳机状态
  227. if (state.setting.soundEffect) {
  228. evaluatingData.soundEffectMode = true;
  229. return;
  230. }
  231. const delayTime = await api_getDeviceDelay();
  232. console.log("🚀 ~ delayTime:", delayTime);
  233. if (!delayTime) {
  234. evaluatingData.soundEffectMode = true;
  235. return;
  236. }
  237. handlePerformDetection();
  238. return;
  239. }
  240. // 检测耳机
  241. if ((evaluatingData.checkStep = 5)) {
  242. evaluatingData.checkStep = 10;
  243. const erji = await checkUseEarphone();
  244. if (!erji) {
  245. evaluatingData.earphoneMode = true;
  246. return;
  247. }
  248. handlePerformDetection();
  249. return;
  250. }
  251. // 效音
  252. // if (evaluatingData.checkStep === 7) {
  253. // // 是否需要开启效音
  254. // evaluatingData.checkStep = 10;
  255. // if (state.setting.soundEffect && !state.isPercussion) {
  256. // evaluatingData.soundEffectMode = true;
  257. // handleStartSoundCheck();
  258. // return
  259. // }
  260. // handlePerformDetection();
  261. // return;
  262. // }
  263. // 效验完成
  264. if (evaluatingData.checkStep === 10) {
  265. evaluatingData.checkEnd = true;
  266. }
  267. };
  268. /** 记录小节分数 */
  269. export const addMeasureScore = (measureScore: any, show = true) => {
  270. // #8720 bug修复
  271. for(let idx in evaluatingData.evaluatings) {
  272. evaluatingData.evaluatings[idx].show = false
  273. }
  274. evaluatingData.evaluatings[measureScore.measureRenderIndex] = {
  275. ...measureScore,
  276. leve: getLeveByScoreMeasure(measureScore.score),
  277. show,
  278. };
  279. // console.log("🚀 ~ measureScore:", evaluatingData.evaluatings)
  280. };
  281. const handleScoreResult = (res?: IPostMessage) => {
  282. console.log('返回', res)
  283. if (res?.content) {
  284. const { header, body } = res.content;
  285. // 效音返回
  286. if (header.commond === "checking") {
  287. evaluatingData.soundEffectFrequency = body.frequency;
  288. }
  289. // 小节评分返回
  290. if (header?.commond === "measureScore") {
  291. console.log("🚀 ~ 评测返回:", res);
  292. addMeasureScore(body);
  293. }
  294. // 评测结束返回
  295. if (header?.commond === "overall") {
  296. console.log("🚀 ~ 评测返回:", res);
  297. // console.log("评测结束", body);
  298. state.isHideEvaluatReportSaveBtn = false;
  299. setTimeout(() => {
  300. evaluatingData.resulstMode = evaluatingData.isErrorState ? false : true
  301. }, 200);
  302. evaluatingData.resultData = {
  303. ...body,
  304. ...getLeveByScore(body.score),
  305. };
  306. // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData)
  307. closeToast();
  308. }
  309. }
  310. };
  311. /** 开始评测 */
  312. export const handleStartBegin = async (preTimes?: number) => {
  313. if (state.isAppPlay) {
  314. await api_cloudSetCurrentTime({
  315. currentTime: 0,
  316. songID: state.examSongId,
  317. })
  318. }
  319. evaluatingData.isComplete = false;
  320. evaluatingData.evaluatings = {};
  321. evaluatingData.resultData = {};
  322. evaluatingData.backtime = 0;
  323. resetPlaybackToStart();
  324. evaluatingData.isAudioPlayEnd = false;
  325. const res = await startEvaluating(evaluatingData.contentData);
  326. if (res?.api !== "startEvaluating") {
  327. Snackbar.error("请在APP端进行评测");
  328. evaluatingData.startBegin = false;
  329. return;
  330. }
  331. if (res?.content?.reson) {
  332. showToast(res.content?.des);
  333. evaluatingData.startBegin = false;
  334. return;
  335. }
  336. evaluatingData.startBegin = true;
  337. if (evaluatingData.isDisabledPlayMusic) {
  338. state.playState = state.playState === "paused" ? "play" : "paused";
  339. // 设置为开始播放时, 如果需要节拍,先播放节拍器
  340. if (state.playState === "play" && state.needTick) {
  341. const tickend = await handleStartTick();
  342. console.log("🚀 ~ tickend:", tickend)
  343. // 节拍器返回false, 取消播放
  344. if (!tickend) {
  345. state.playState = "paused";
  346. evaluatingData.startBegin = false;
  347. return;
  348. }
  349. }
  350. onPlay();
  351. }
  352. if (evaluatingData.isErrorState) return
  353. //开始录音
  354. // await api_startRecording({
  355. // accompanimentState: state.setting.enableAccompaniment ? 1 : 0,
  356. // firstNoteTime: preTimes || 0,
  357. // });
  358. await api_startRecordingCb({
  359. accompanimentState: state.setting.enableAccompaniment ? 1 : 0,
  360. firstNoteTime: preTimes || 0,
  361. }, () => {
  362. if (state.isAppPlay) {
  363. setTimeout(() => {
  364. sendOffsetTime(0)
  365. }, 300);
  366. }
  367. })
  368. // 如果开启了摄像头, 开启录制视频
  369. if (state.setting.camera) {
  370. console.log("开始录制视频");
  371. await api_startCapture();
  372. }
  373. // 如果是midi音频评测,需要调用cloudPlay
  374. if (state.isAppPlay) {
  375. await api_cloudChangeSpeed({
  376. speed: state.originSpeed,
  377. originalSpeed: state.originSpeed,
  378. songID: state.examSongId,
  379. });
  380. audioData.progress = 0
  381. audioListStart(state.playState);
  382. }
  383. };
  384. /** 播放音乐 */
  385. const playMusic = async () => {
  386. const playState = await togglePlay("play");
  387. // 取消播放,停止播放
  388. if (!playState) {
  389. evaluatingData.startBegin = false;
  390. handleCancelEvaluat();
  391. return;
  392. }
  393. // 检测播放进度, 计算延迟
  394. check_currentTime();
  395. // 如果开启了摄像头, 开启录制视频
  396. if (state.setting.camera) {
  397. console.log("开始录制视频");
  398. api_startCapture();
  399. }
  400. };
  401. let _audio: HTMLAudioElement;
  402. /** 录音开始,记录开始时间点 */
  403. const recordStartTimePoint = async (res?: IPostMessage) => {
  404. console.error("开始录音");
  405. // 没有开始评测,不处理
  406. if (!evaluatingData.startBegin) return;
  407. let inteveral = res?.content?.inteveral || 0;
  408. if (browserInfo.ios) {
  409. inteveral *= 1000;
  410. }
  411. evaluatingData.backtime = inteveral || Date.now();
  412. console.log(
  413. "🚀 ~ 开始时间点:",
  414. evaluatingData.backtime,
  415. "已经录的时间:",
  416. Date.now() - inteveral,
  417. "记录时间点:",
  418. Date.now()
  419. );
  420. // 是否禁播
  421. if (evaluatingData.isDisabledPlayMusic) {
  422. return;
  423. }
  424. // 开始播放
  425. playMusic();
  426. };
  427. /**
  428. * 结束评测
  429. * @param isComplete 是否完整评测
  430. * @returns
  431. */
  432. export const handleEndEvaluat = (isComplete = false) => {
  433. // 没有开始评测 , 不是评测模式 , 不评分
  434. if (!evaluatingData.startBegin || state.modeType !== "evaluating") return;
  435. // 结束录音
  436. // api_stopRecording();
  437. // 结束评测
  438. console.log('评测结束1')
  439. endEvaluating({
  440. musicScoreId: state.examSongId,
  441. });
  442. showLoadingToast({
  443. message: "评分中",
  444. duration: 0,
  445. overlay: true,
  446. overlayClass: styles.scoreMode,
  447. });
  448. setTimeout(() => {
  449. evaluatingData.startBegin = false;
  450. }, 500);
  451. evaluatingData.isComplete = isComplete;
  452. // 如果开启了摄像头, 结束录制视频
  453. if (state.setting.camera) {
  454. console.log("结束录制视频");
  455. api_endCapture();
  456. }
  457. };
  458. /**
  459. * 结束评测(手动结束评测)
  460. */
  461. export const handleEndBegin = () => {
  462. handleEndEvaluat();
  463. handleStopPlay();
  464. };
  465. /**
  466. * 取消评测
  467. */
  468. export const handleCancelEvaluat = () => {
  469. evaluatingData.evaluatings = {};
  470. evaluatingData.startBegin = false;
  471. // 关闭提示
  472. closeToast();
  473. // 取消记录
  474. api_proxyServiceMessage({
  475. header: {
  476. commond: "recordCancel",
  477. type: "SOUND_COMPARE",
  478. status: 200,
  479. },
  480. });
  481. // 取消评测
  482. cancelEvaluating();
  483. // 停止播放
  484. handleStopPlay();
  485. console.log('评测结束2')
  486. endEvaluating({
  487. musicScoreId: state.examSongId,
  488. });
  489. // 如果开启了摄像头, 结束录制视频
  490. if (state.setting.camera) {
  491. console.log("结束录制视频");
  492. api_endCapture();
  493. }
  494. };
  495. /** 查看报告 */
  496. export const handleViewReport = (
  497. key: "recordId" | "recordIdStr",
  498. type: "gym" | "colexiu" | "orchestra" | "instrument"
  499. ) => {
  500. const id = evaluatingData.resultData?.[key] || "";
  501. let url = "";
  502. switch (type) {
  503. case "gym":
  504. url = location.origin + location.pathname + "#/report/" + id;
  505. break;
  506. case "orchestra":
  507. url = location.origin + location.pathname + "report-share.html?id=" + id;
  508. break;
  509. case "instrument":
  510. url = location.origin + location.pathname + "#/evaluat-report?id=" + id + "&musicRenderType=" + state.musicRenderType;
  511. break;
  512. default:
  513. url = location.origin + location.pathname + "report-share.html?id=" + id;
  514. break;
  515. }
  516. api_openWebView({
  517. url,
  518. orientation: 0,
  519. isHideTitle: true, // 此处兼容安卓,意思为隐藏全部头部
  520. statusBarTextColor: false,
  521. isOpenLight: true,
  522. c_orientation: 0,
  523. });
  524. };
  525. // 隐藏存演奏按钮
  526. const handleComplexButton = (res?: IPostMessage) => {
  527. console.log('监听是否隐藏保存按钮', res)
  528. if (res?.content) {
  529. const { header, body } = res.content;
  530. state.isHideEvaluatReportSaveBtn = true
  531. }
  532. };
  533. // 检测到APP发送的异常信息
  534. const handleAccompanyError = (res?: IPostMessage) => {
  535. console.log('异常信息返回', res)
  536. if (res?.content) {
  537. const { type, reson } = res.content;
  538. switch (type) {
  539. case "enterBackground":
  540. // App退到后台
  541. case "playError":
  542. // 播放异常
  543. case "socketError":
  544. // socket连接断开,评测中,则取消评测
  545. // 延迟检测中
  546. if (evaluatingData.soundEffectMode) {
  547. evaluatingData.socketErrorStatus = 0
  548. evaluatingData.delayCheckSocketError = true
  549. evaluatingData.socketErrorPop = type === "socketError" ? true : false
  550. evaluatingData.accompanyErrorType = type
  551. // api_checkSocketStatus()
  552. return
  553. }
  554. // 评测中
  555. if (state.modeType === "evaluating" && evaluatingData.startBegin) {
  556. handleCancelEvaluat();
  557. }
  558. if (tickData.show) {
  559. tickData.tickEnd = true
  560. tickData.show = false
  561. }
  562. evaluatingData.socketErrorStatus = 0
  563. evaluatingData.socketErrorPop = type === "socketError" ? true : false
  564. evaluatingData.isErrorState = true
  565. evaluatingData.accompanyErrorType = type
  566. resetPlaybackToStart();
  567. break;
  568. case "recordError":
  569. // 录音异常
  570. break;
  571. default:
  572. break;
  573. }
  574. }
  575. };
  576. // 监测socket状态,是否已经成功连接
  577. const handleSocketStatus = (res?: IPostMessage) => {
  578. if (res?.content?.status === "connected") {
  579. const currentTime = +new Date()
  580. evaluatingData.delayCheckSocketError = false
  581. const diffTime = currentTime - socketStartTime
  582. if (diffTime < 1000) {
  583. const remainingTime = 1000 - diffTime
  584. console.log(remainingTime,99999)
  585. setTimeout(() => {
  586. evaluatingData.socketErrorStatus = 2
  587. }, remainingTime);
  588. }
  589. }
  590. }
  591. // 评测出现异常,再试一次
  592. const hanldeConfirmPop = async () => {
  593. api_checkSocketStatus();
  594. evaluatingData.socketErrorStatus = 1
  595. socketStartTime = +new Date()
  596. }
  597. // 关闭异常弹窗
  598. const hanldeClosePop = () => {
  599. evaluatingData.socketErrorPop = false
  600. evaluatingData.socketErrorStatus = 0
  601. }
  602. export default defineComponent({
  603. name: "evaluating",
  604. setup() {
  605. const pageVisibility = usePageVisibility();
  606. // 需要记录的数据
  607. const record_old_data = reactive({
  608. /** 指法 */
  609. finger: false,
  610. /** 原音伴奏 */
  611. play_mode: "" as IPlayState,
  612. /** 评测是否要伴奏 */
  613. enableAccompaniment: true,
  614. });
  615. /** 记录状态 */
  616. const hanlde_record = () => {
  617. // 取消指法
  618. record_old_data.finger = state.setting.displayFingering;
  619. state.setting.displayFingering = false;
  620. // 切换为伴奏
  621. record_old_data.play_mode = state.playSource;
  622. record_old_data.enableAccompaniment = state.setting.enableAccompaniment;
  623. // 如果关闭伴奏,评测静音
  624. if (!record_old_data.enableAccompaniment) {
  625. console.log("关闭伴奏");
  626. toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : "background", true);
  627. }
  628. };
  629. /** 还原状态 */
  630. const handle_reduction = () => {
  631. // 还原指法
  632. state.setting.displayFingering = record_old_data.finger;
  633. state.playSource = record_old_data.play_mode;
  634. // 如果关闭伴奏, 结束评测取消静音
  635. if (!record_old_data.enableAccompaniment) {
  636. toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : "background", false);
  637. }
  638. };
  639. watch(pageVisibility, (value) => {
  640. if (value == "hidden" && evaluatingData.startBegin) {
  641. // handleEndBegin();
  642. }
  643. });
  644. watch(
  645. () => evaluatingData.socketErrorStatus,
  646. () => {
  647. if (evaluatingData.socketErrorStatus === 2) {
  648. setTimeout(() => {
  649. evaluatingData.socketErrorPop = false
  650. // evaluatingData.socketErrorStatus = 0
  651. }, 1000);
  652. }
  653. }
  654. );
  655. onMounted(() => {
  656. resetPlaybackToStart();
  657. hanlde_record();
  658. evaluatingData.resultData = {};
  659. // evaluatingData.resulstMode = true;
  660. // evaluatingData.resultData = {...getLeveByScore(10), score: 10, intonation: 10, cadence: 30, integrity: 40}
  661. // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData)
  662. evaluatingData.evaluatings = {};
  663. evaluatingData.soundEffectFrequency = 0;
  664. evaluatingData.checkStep = 0;
  665. evaluatingData.rendered = true;
  666. sendResult(handleScoreResult);
  667. hideComplexButton(handleComplexButton, true);
  668. api_recordStartTime(recordStartTimePoint);
  669. addAccompanyError(handleAccompanyError);
  670. addSocketStatus(handleSocketStatus);
  671. // 不是选段模式评测, 就清空已选段
  672. if (!state.isSelectMeasureMode) {
  673. clearSelection();
  674. }
  675. console.log("加载评测模块成功");
  676. });
  677. onUnmounted(() => {
  678. evaluatingData.checkEnd = false;
  679. evaluatingData.rendered = false;
  680. resetPlaybackToStart();
  681. removeResult(handleScoreResult);
  682. hideComplexButton(() => {}, false);
  683. api_remove_recordStartTime(recordStartTimePoint);
  684. handle_reduction();
  685. removeAccompanyError(handleAccompanyError);
  686. removeSocketStatus(handleSocketStatus);
  687. api_disconnectSocket();
  688. console.log("卸载评测模块成功");
  689. });
  690. return () => (
  691. <div>
  692. {/** 预加载一下断网需要用到的图片 */}
  693. <div class={styles.hiddenPop}>
  694. <img src={popImgs.icon_bg} />
  695. <img src={popImgs.icon_btn} />
  696. <img src={popImgs.icon_success} />
  697. <img src={popImgs.icon_close} />
  698. </div>
  699. <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={evaluatingData.socketErrorPop}>
  700. <AbnormalPop
  701. onConfirm={hanldeConfirmPop}
  702. onClose={hanldeClosePop}
  703. />
  704. </Popup>
  705. </div>
  706. );
  707. },
  708. });