track-song.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import ColHeader from '@/components/col-header'
  2. import { useRect } from '@vant/use'
  3. import { useEventListener, useWindowScroll } from '@vueuse/core'
  4. import { defineComponent } from 'vue'
  5. import { Button, Cell, CellGroup, Image } from 'vant'
  6. import styles from './index.module.less'
  7. import { browser, getRandomKey } from '@/helpers/utils'
  8. import qs from 'query-string'
  9. import request from '@/helpers/request'
  10. import { postMessage } from '@/helpers/native-message'
  11. export const getAssetsHomeFile = (fileName: string) => {
  12. const path = `./images/${fileName}`
  13. const modules = import.meta.globEager('./images/*')
  14. return modules[path].default
  15. }
  16. export default defineComponent({
  17. name: 'track-song',
  18. data() {
  19. const query = this.$route.query
  20. console.log(query)
  21. const subjectName = query.subjectName || ''
  22. return {
  23. id: query.id,
  24. subjectId: query.subjectId,
  25. background: 'rgba(55, 205, 177, 0)',
  26. headColor: '#fff',
  27. height: 'auto' as any,
  28. backIconColor: 'white',
  29. title: subjectName + '曲目评测',
  30. behaviorId: getRandomKey(),
  31. musicList: [] as any,
  32. rankingScore: 0
  33. }
  34. },
  35. async mounted() {
  36. useEventListener(document, 'scroll', () => {
  37. const { y } = useWindowScroll()
  38. if (y.value > 52) {
  39. this.headColor = '#000'
  40. this.background = '#fff'
  41. this.backIconColor = 'black'
  42. } else {
  43. this.background = 'transparent'
  44. this.headColor = '#fff'
  45. this.backIconColor = 'white'
  46. }
  47. })
  48. await this.getMusicInfo()
  49. },
  50. methods: {
  51. async getMusicInfo() {
  52. try {
  53. const { data } = await request.post(
  54. '/api-student/open/activity/info/' + this.id
  55. )
  56. const activityMusicVoList = data.activityMusicVoList || []
  57. const musicList = activityMusicVoList.filter(
  58. (activity: any) => activity.subjectId == this.subjectId
  59. )
  60. this.musicList = musicList
  61. this.rankingScore = data.rankingScore || 0
  62. } catch {
  63. //
  64. }
  65. },
  66. onOpenMusic(item: any) {
  67. try {
  68. const browserInfo = browser()
  69. const url = qs.stringifyUrl({
  70. url: location.origin + '/accompany',
  71. query: {
  72. id: item.musicSheetId,
  73. behaviorId: this.behaviorId,
  74. client: browserInfo.isTeacher ? 'teacher' : 'student',
  75. setting: JSON.stringify({
  76. mode: 'EVALUATING',
  77. resets: ['SPEED'],
  78. difficulty: item.evaluationDifficulty,
  79. feeType: 'FREE',
  80. submitData: { evaluationId: item.evaluationId }
  81. })
  82. }
  83. })
  84. postMessage({
  85. api: 'openAccompanyWebView',
  86. content: {
  87. url,
  88. orientation: 0,
  89. isHideTitle: true,
  90. statusBarTextColor: false,
  91. isOpenLight: true
  92. }
  93. })
  94. } catch {
  95. //
  96. }
  97. }
  98. },
  99. computed: {
  100. allScore() {
  101. const musicList = this.musicList || []
  102. let score = 0
  103. musicList.forEach((item: any) => {
  104. score += item.score
  105. })
  106. return score
  107. },
  108. calcScore() {
  109. const allScore = this.allScore as number
  110. return Number(this.rankingScore - allScore)
  111. }
  112. },
  113. render() {
  114. return (
  115. <div class={styles.trackSong}>
  116. <div ref="headers">
  117. <ColHeader
  118. title={this.title}
  119. background={this.background}
  120. border={false}
  121. color={this.headColor}
  122. backIconColor={this.backIconColor as any}
  123. onHeaderBack={() => {
  124. this.$nextTick(() => {
  125. const { height } = useRect((this as any).$refs.headers)
  126. this.height = height
  127. // this.homeContaiterHeight = `calc(100vh - var(--van-tabs-line-height) - ${height}px - 15px)`
  128. })
  129. }}
  130. >
  131. <div class={styles.trackScore}>
  132. <div class={styles.trackCountScore}>
  133. 我的总分 <span>{this.allScore}</span>
  134. </div>
  135. <div class={styles.trackIf}>
  136. 距离要求分数还有{this.calcScore}分,继续加油!
  137. </div>
  138. <Image
  139. class={styles.trackImg}
  140. src={getAssetsHomeFile('icon_score.png')}
  141. />
  142. </div>
  143. </ColHeader>
  144. </div>
  145. <div class={styles.bg}></div>
  146. <CellGroup class={styles.cellGroup}>
  147. {this.musicList.map((item: any) => (
  148. <Cell
  149. center
  150. v-slots={{
  151. icon: () => (
  152. <Image src={item.musicImage} class={styles.musicPic} />
  153. ),
  154. title: () => (
  155. <div class={styles.musicName}>{item.musicSheetName}</div>
  156. ),
  157. label: () =>
  158. item.userId ? (
  159. <div class={[styles.labelClass, styles.labelScore]}>
  160. 我的评分:{item.score}
  161. </div>
  162. ) : (
  163. <div class={styles.labelClass}>暂无评分,快来挑战吧~</div>
  164. ),
  165. value: () => (
  166. <div class={styles.valueClass}>
  167. <Button
  168. type="primary"
  169. size="small"
  170. round
  171. color="linear-gradient(180deg, #FFA200 0%, #FF6900 100%)"
  172. onClick={() => {
  173. this.onOpenMusic(item)
  174. }}
  175. >
  176. 立刻挑战
  177. </Button>
  178. </div>
  179. )
  180. }}
  181. />
  182. ))}
  183. </CellGroup>
  184. </div>
  185. )
  186. }
  187. })