| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- <template>
- <view class="scoreboard-page">
- <view class="page-header">
- <text class="page-title">实时积分榜</text>
- <text class="page-desc" v-if="className">{{ className }}</text>
- </view>
- <view v-if="board.length === 0" class="empty-state">
- <text class="empty-text">暂无积分数据</text>
- </view>
- <view class="rank-list">
- <view class="rank-item" v-for="(item, idx) in board" :key="idx" :class="rankClass(idx)">
- <view class="rank-num">
- <text v-if="idx < 3" class="rank-medal">{{ ['🥇','🥈','🥉'][idx] }}</text>
- <text v-else class="rank-index">{{ idx + 1 }}</text>
- </view>
- <view class="rank-info">
- <text class="rank-name">{{ item.groupName }}</text>
- <text class="rank-slogan" v-if="item.slogan">{{ item.slogan }}</text>
- <text class="rank-members">{{ item.memberCount }}人</text>
- </view>
- <view class="rank-score">
- <text class="score-num">{{ item.total }}</text>
- <text class="score-label">分</text>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { getScoreboard, getClassInfo } from '@/utils/api.js'
- import { guardPage } from '@/utils/guard.js'
- export default {
- data() {
- return {
- board: [],
- className: ''
- }
- },
- onShow() {
- if (!guardPage()) return
- this.loadData()
- },
- methods: {
- loadData() {
- var self = this
- var classId = self.$store.state.classId
- var doLoad = function(cid) {
- return getScoreboard(cid).then(function(resp) {
- self.board = resp.data || []
- })
- }
- if (classId) {
- doLoad(classId)
- getClassInfo().then(function(resp) {
- if (resp.data) self.className = resp.data.name
- }).catch(function() {})
- } else {
- getClassInfo().then(function(resp) {
- if (resp.data) {
- self.className = resp.data.name
- self.$store.commit('setClassId', resp.data.id)
- return doLoad(resp.data.id)
- }
- }).catch(function() {})
- }
- },
- rankClass(idx) {
- if (idx === 0) return 'rank-gold'
- if (idx === 1) return 'rank-silver'
- if (idx === 2) return 'rank-bronze'
- return ''
- }
- }
- }
- </script>
- <style scoped>
- .scoreboard-page { min-height: 100vh; background: #F5F5F5; padding: 24rpx 32rpx; }
- .page-header { margin-bottom: 32rpx; }
- .page-title { display: block; font-size: 40rpx; font-weight: 700; color: #1E293B; margin-bottom: 8rpx; }
- .page-desc { display: block; font-size: 26rpx; color: #64748B; }
- .empty-state { text-align: center; padding: 80rpx 0; }
- .empty-text { font-size: 28rpx; color: #94A3B8; }
- .rank-list { display: flex; flex-direction: column; gap: 16rpx; }
- .rank-item { display: flex; align-items: center; background: #FFF; border-radius: 16rpx; padding: 24rpx; }
- .rank-gold { background: linear-gradient(135deg, #FFF7ED, #FFFBEB); border: 2rpx solid #FDE68A; }
- .rank-silver { background: linear-gradient(135deg, #F8FAFC, #F1F5F9); border: 2rpx solid #E2E8F0; }
- .rank-bronze { background: linear-gradient(135deg, #FFF7ED, #FEF3E2); border: 2rpx solid #FED7AA; }
- .rank-num { width: 80rpx; text-align: center; margin-right: 16rpx; }
- .rank-medal { font-size: 40rpx; }
- .rank-index { font-size: 32rpx; font-weight: 700; color: #94A3B8; }
- .rank-info { flex: 1; }
- .rank-name { display: block; font-size: 30rpx; font-weight: 600; color: #1E293B; }
- .rank-slogan { display: block; font-size: 24rpx; color: #F97316; margin-top: 4rpx; }
- .rank-members { display: block; font-size: 22rpx; color: #94A3B8; margin-top: 4rpx; }
- .rank-score { text-align: right; }
- .score-num { font-size: 40rpx; font-weight: 700; color: #F97316; }
- .score-label { font-size: 22rpx; color: #64748B; margin-left: 4rpx; }
- </style>
|