index.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { Button, Dialog, Grid, GridItem, Popup, Toast } from 'vant'
  2. import { defineComponent, ref, toRefs } from 'vue'
  3. import styles from './index.module.less'
  4. import iconTitle from './icons/title.svg'
  5. import iconCancel from './icons/cancel.png'
  6. import iconConfirm from './icons/confirm.png'
  7. import Content from './content'
  8. import SettingState from '/src/pages/detail/setting-state'
  9. import { IPostMessage, postMessage } from '/src/helpers/native-message'
  10. import detailState from '/src/pages/detail/state'
  11. import { browser } from '/src/helpers/utils'
  12. import runtime, * as RuntimeUtils from '/src/pages/detail/runtime'
  13. export const evaluatingShow = ref<boolean>(false)
  14. const open = ref(false)
  15. export type ResultContent = {
  16. /* 节奏 */
  17. cadence: number
  18. /* 完整性 */
  19. integrity: number
  20. /* 音调 */
  21. intonation: number
  22. playTime: number
  23. recordId: number
  24. /** 评测记录ID */
  25. recordIdStr: string
  26. /* 分数 */
  27. score: number
  28. }
  29. /** 合成音频传伴奏弹窗 */
  30. const api_openAdjustRecording = (content: any) => {
  31. postMessage({
  32. api: "openAdjustRecording",
  33. content,
  34. });
  35. };
  36. //效音组件
  37. export default defineComponent({
  38. name: 'ColexiuEvaluating',
  39. props: {
  40. data: {
  41. type: Object as () => ResultContent | null,
  42. default: () => null,
  43. },
  44. },
  45. emits: ['restart'],
  46. setup(props) {
  47. const confirmShow = ref<boolean>(false)
  48. const sendUploadMessage = (res?: IPostMessage) => {
  49. postMessage({
  50. api: 'proxyServiceMessage',
  51. content: {
  52. header: {
  53. commond: 'videoUpload',
  54. status: 200,
  55. type: 'SOUND_COMPARE',
  56. },
  57. body: {
  58. filePath: res?.content?.filePath,
  59. recordId: props.data?.recordIdStr,
  60. },
  61. },
  62. })
  63. }
  64. const videoUpdate = () => {
  65. if (SettingState.sett.camera && SettingState.eva.save) {
  66. postMessage(
  67. {
  68. api: 'videoUpdate',
  69. },
  70. (res) => {
  71. console.log('保存视频', res)
  72. confirmShow.value = false
  73. if (res?.content) {
  74. if (res.content.type === 'error') {
  75. Toast(res.content.message)
  76. return
  77. }
  78. sendUploadMessage(res)
  79. }
  80. }
  81. )
  82. } else {
  83. confirmShow.value = false
  84. sendUploadMessage()
  85. Toast.success('上传成功')
  86. }
  87. }
  88. /** 评测结果按钮处理 */
  89. const handleEvaluatResult = () => {
  90. const browserInfo = browser()
  91. // 如果音频是midi格式,走之前的逻辑
  92. if (detailState.isAppPlay) {
  93. confirmShow.value = true
  94. } else {
  95. if (props.data?.recordIdStr) {
  96. // 上传云端
  97. api_openAdjustRecording({
  98. recordId: String(props.data?.recordIdStr),
  99. title: detailState.activeDetail?.musicSheetName || "曲谱演奏",
  100. coverImg: detailState.activeDetail?.titleImg || '',
  101. speedRate: parseFloat(runtime.basePlayRate.toFixed(2)), // 播放倍率
  102. // firstNoteTime: detailState.firstNoteTime,
  103. });
  104. }
  105. }
  106. }
  107. return () => {
  108. return (
  109. <div>
  110. <Popup
  111. position="bottom"
  112. v-model:show={evaluatingShow.value}
  113. onOpen={() => (open.value = true)}
  114. onClosed={() => (open.value = false)}
  115. teleport="body"
  116. style={{ backgroundColor: 'transparent' }}
  117. >
  118. {open && (
  119. <Content
  120. data={props.data}
  121. onUpload={handleEvaluatResult}
  122. onRestart={() => (evaluatingShow.value = false)}
  123. />
  124. )}
  125. </Popup>
  126. <Dialog.Component
  127. teleport="body"
  128. class={styles.confirm}
  129. style={{
  130. overflow: 'initial',
  131. }}
  132. vSlots={{
  133. title: () => <img class={styles.iconTitle} src={iconTitle} />,
  134. footer: () => (
  135. <div class={styles.footer}>
  136. <img src={iconCancel} onClick={() => (confirmShow.value = false)} />
  137. <img src={iconConfirm} onClick={videoUpdate} />
  138. </div>
  139. ),
  140. }}
  141. v-model:show={confirmShow.value}
  142. message={`评测${SettingState.sett.camera && SettingState.eva.save ? '音视频' : '音频'}是否保存演奏?`}
  143. />
  144. </div>
  145. )
  146. }
  147. },
  148. })