musicScore.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { defineComponent, ref, nextTick, onMounted, watch } from 'vue';
  2. import styles from './musicScore.module.less';
  3. import qs from 'query-string';
  4. import iconStart from '../image/icon-start.svg';
  5. import { listenerMessage, postMessage } from '@/helpers/native-message';
  6. import { Loading, Skeleton } from 'vant';
  7. import { usePageVisibility } from '@vant/use';
  8. import { useRoute } from 'vue-router';
  9. import { browser } from '@/helpers/utils';
  10. import { storage } from '@/helpers/storage';
  11. import { ACCESS_TOKEN } from '@/store/mutation-types';
  12. export default defineComponent({
  13. name: 'musicScore',
  14. props: {
  15. pageVisibility: {
  16. type: String,
  17. default: ''
  18. },
  19. show: {
  20. type: Boolean,
  21. default: false
  22. },
  23. music: {
  24. type: Object,
  25. default: () => {}
  26. },
  27. activeModel: {
  28. type: Boolean
  29. }
  30. },
  31. emits: ['setIframe'],
  32. setup(props, { emit }) {
  33. const browserInfo = browser();
  34. const route = useRoute();
  35. const isLoading = ref(false);
  36. /** 页面显示和隐藏 */
  37. watch(
  38. () => props.pageVisibility,
  39. value => {
  40. if (value == 'hidden') {
  41. isLoading.value = false;
  42. }
  43. if (value == 'hidden' && props.show) {
  44. iframeRef.value?.contentWindow?.postMessage(
  45. { api: 'setPlayState' },
  46. '*'
  47. );
  48. }
  49. }
  50. );
  51. // 是否显示当前曲谱
  52. watch(
  53. () => props.show,
  54. val => {
  55. if (!val) {
  56. iframeRef.value?.contentWindow?.postMessage(
  57. { api: 'setPlayState' },
  58. '*'
  59. );
  60. }
  61. }
  62. );
  63. const iframeRef = ref();
  64. const isLoaded = ref(false);
  65. const renderError = ref(false);
  66. const renderSuccess = ref(false);
  67. const Authorization = storage.get(ACCESS_TOKEN);
  68. const origin = /(localhost|192)/.test(location.host)
  69. ? 'https://test.lexiaoya.cn'
  70. : location.origin;
  71. let src = qs.stringifyUrl({
  72. url: origin + '/instrument',
  73. query: {
  74. id: props.music.content,
  75. modelType: 'practise',
  76. Authorization: Authorization
  77. }
  78. });
  79. const checkView = () => {
  80. fetch(src)
  81. .then(() => {
  82. renderSuccess.value = true;
  83. renderError.value = false;
  84. })
  85. .catch(err => {
  86. renderError.value = true;
  87. });
  88. };
  89. watch(props.music, () => {
  90. if (renderSuccess.value) return;
  91. renderError.value = false;
  92. if (props.music.display) {
  93. checkView();
  94. }
  95. });
  96. // 去云教练完整版
  97. const gotoAccomany = () => {
  98. if (isLoading.value) return;
  99. if (!browserInfo.ios) {
  100. isLoading.value = true;
  101. }
  102. const Authorization = storage.get(ACCESS_TOKEN);
  103. const origin = /(localhost|192)/.test(location.host)
  104. ? 'https://test.lexiaoya.cn'
  105. : location.origin;
  106. let src = qs.stringifyUrl({
  107. url: origin + '/instrument',
  108. query: {
  109. id: props.music.content,
  110. Authorization: Authorization
  111. }
  112. });
  113. postMessage(
  114. {
  115. api: 'openAccompanyWebView',
  116. content: {
  117. url: src,
  118. orientation: 0,
  119. isHideTitle: true,
  120. statusBarTextColor: false,
  121. isOpenLight: true,
  122. c_orientation: 0
  123. }
  124. },
  125. () => {
  126. if (browserInfo.ios) {
  127. isLoading.value = true;
  128. }
  129. }
  130. );
  131. };
  132. listenerMessage('webViewOnResume', () => {
  133. isLoading.value = false;
  134. });
  135. return () => (
  136. <div class={styles.musicScore}>
  137. <iframe
  138. ref={iframeRef}
  139. onLoad={(e: Event) => {
  140. emit('setIframe', iframeRef.value);
  141. isLoaded.value = true;
  142. }}
  143. class={[styles.container, 'musicIframe']}
  144. frameborder="0"
  145. src={src}></iframe>
  146. {isLoaded.value && (
  147. <div
  148. style={{
  149. display: props.activeModel ? '' : 'none'
  150. }}
  151. class={styles.startBtn}
  152. onClick={(e: Event) => {
  153. e.stopPropagation();
  154. gotoAccomany();
  155. }}>
  156. <img src={iconStart} />
  157. </div>
  158. )}
  159. <div class={styles.skeletonWrap}>
  160. <Skeleton class={styles.skeleton} row={8} />
  161. </div>
  162. </div>
  163. );
  164. }
  165. });