| 
					
				 | 
			
			
				@@ -0,0 +1,250 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Button, Cell, Empty, Image, Tab, Tabs } from 'vant' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { computed, defineComponent, onMounted, reactive, ref } from 'vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import styles from './index.module.less' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import IconTrophy from './image/icon-trophy.png' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import IconEmtry from './image/icon-emtry.png' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import request from '@/helpers/request' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { useRoute, useRouter } from 'vue-router' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { state as userInfo } from '@/state' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+interface IMusicItem { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  loaded: boolean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  musicSheetName: string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  musicSubject: string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  musicSheetId: number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  evaluationId: number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rankingList: any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  [_: string]: any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export default defineComponent({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  name: 'leaderboard', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  setup() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const route = useRoute() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const router = useRouter() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const state = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tabIndex: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      musicList: [] as IMusicItem[] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const getMusicList = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data: { activityMusicVoList, shareUrl } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } = await request.post( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          `/api-student/open/activity/info/${route.query.id}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Array.isArray(activityMusicVoList)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          state.musicList = activityMusicVoList.map(n => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n.rankingList = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n.loaded = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return n 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        img.value = shareUrl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } catch (error) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const getData = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (state.musicList[state.tabIndex].loaded) return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const { data } = await request.get( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          '/api-student/open/activityEvaluationRecord/queryRankingList', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            params: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              activityPlanId: route.query.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              activityEvaluationId: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                state.musicList[state.tabIndex].evaluationId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              limit: 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Array.isArray(data.rankingList)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          state.musicList[state.tabIndex].rankingList = data.rankingList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          state.musicList[state.tabIndex].loaded = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } catch (error) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const img = ref() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const imgShow = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const imgHeight = ref(42) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const openActive = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      router.back() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //   router.replace({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //     path: '/track-review-activity', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //     query: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //       id: route.query.id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //   }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    onMounted(async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      await getMusicList() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      await getData() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const user = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!state.musicList[state.tabIndex]) return {} as any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const userdata = userInfo.user.data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!userdata.userId) return {} as any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const rank = state.musicList[state.tabIndex] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const item = rank?.rankingList?.find(n => n.userId == userdata.userId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      let step = rank?.rankingList?.findIndex(n => n.userId == userdata.userId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      step = step > -1 ? step + 1 : 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        join: rank.join, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        score: rank.score, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        isTop: item ? true : false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        heardUrl: userdata.heardUrl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        username: userdata.username, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        userId: userdata.userId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        step 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return () => ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div class={styles.leaderboard}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class={styles.container}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div class={styles.headImg}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <Image 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              width="100%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              fit="cover" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              src={img.value} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              onLoad={img => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                imgHeight.value = img.target.height 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                imgShow.value = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          {imgShow.value && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <Tabs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              v-model:active={state.tabIndex} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              class={styles.tabs} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              animated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              swipeable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              titleInactiveColor="#fff" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              titleActiveColor="rgba(224,146,144,1)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              onChange={index => getData()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              {state.musicList.map((item: IMusicItem) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <Tab title={item.musicSheetName}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      class={styles.tabContent} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      style={{ height: `calc(100vh - ${imgHeight.value}px)` }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <div class={styles.itemContent}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        <div class={styles.item}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <div class={styles.left}>排名</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <div class={styles.center}>昵称</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <div class={styles.right}>评分</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        {item.rankingList.map((n: any, index: number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          const t = (index + 1).toString().padStart(2, '0') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          const time = (n.joinDate + '').split(' ')[0] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            <div class={styles.item}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              <div class={styles.left}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                {index == 0 ? <Image src={IconTrophy} /> : t} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              <div class={styles.center}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                <Image 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  width="34px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  height="34px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  fit="cover" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  round 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  src={n.userAvatar} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                <div class={styles.user}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  <div class={styles.name}>{n.username}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  <div class={styles.tag}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    <span>{n.userSubject}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              <div class={styles.right}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                <div class={styles.fraction}>{n.score}分</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                <div class={styles.time}>{time}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        })} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        {!item.rankingList.length && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <Empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            image={IconEmtry} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            description="该曲目暂无排名喔~" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        )} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </Tab> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              })} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </Tabs> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          )} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          {user.value.userId && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <div class={styles.activeUser}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <Cell 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                center 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                title={user.value.username} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                v-slots={{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  icon: () => ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <Image 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      class={styles.avator} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      fit="cover" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      round 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      src={user.value.heardUrl} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  ), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  label: () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (user.value.join) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      if (user.value.isTop) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            您的评测已上榜! 当前排名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            <span style={{ color: '#FA6400' }}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              {' '} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              {user.value.step} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            </span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          <div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            您的评测暂未上榜,快去 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            <span style={{ color: '#FA6400' }}>挑战</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            吧! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      return <div>您尚未报名参赛</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  value: () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (user.value.join) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        <span class={styles.num}>{user.value.score}分</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        <Button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          class={styles.btn} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          round 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          size="small" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          type="primary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          onClick={() => openActive()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          立刻挑战 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        </Button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          )} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}) 
			 |