Files
tra-app/src/pages/charts/index.vue
T
2025-11-19 20:45:00 +08:00

598 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="exam-ranking">
<!-- <image src="@/static/images/charts/bg-top.png" mode="aspectFit" class="bg-box"></image> -->
<view class="bg-box"></view>
<view class="ranking-box">
<view class="nav-div">
<view class="back_div" @click="backRouter()">
<view class="back-icon"></view>
</view>
</view>
<view class="title-view">
<!-- <view class="title-info">考试排行榜</view> -->
<image class="title-image" src="@/static/images/charts/text.png" mode="aspectFit"></image>
<!-- <view class="title-desc">吾日三省吾身传不习乎</view> -->
<image class="cup-image" src="@/static/images/charts/cup.png" mode="aspectFit"></image>
</view>
<view class="ranking-body">
<view class="tabs-view">
<uv-tabs :list="tabList" @click="changeTab" :scrollable="false" :current="chooseTyp" active-style="font-weight:bold; color:#000;"
class="font_pf my_tabs" :inactive-style="{ color: '#333333', fontSize: '30rpx', fontWeight: '500' }"
:activeStyle="{ color: '#333333', fontSize: '30rpx', fontWeight: '600' }"></uv-tabs>
<uv-tabs :list="tabSecList" @click="changeTabSec" :scrollable="false" :current="chooseTypSec"
active-style="font-weight:bold; color:#000;" class="font_pf my_tabs2"
:inactive-style="{ color: '#333333', fontSize: '24rpx', fontWeight: '500' }"
:activeStyle="{ color: '#0066FF', fontSize: '24rpx', fontWeight: '500' }" :lineColor="`#06f`"></uv-tabs>
<!-- :lineColor="`url(${LineBg}) 2% 2%`" -->
<uv-scroll-list class="tags-view" :indicator="false">
<uv-tags :text="item.label" v-for="item in tagsList" :key="item.value" size="medium" :bgColor="'#f6f8fa'"
:borderColor="activeTag === item.value ? '#06f' : '#f6f8fa'"
:color="activeTag === item.value ? '#06f' : '#333'" @click="chooseTag(item)"
:class="activeTag === item.value ? 'tags-item active-tags-item' : 'tags-item'"></uv-tags>
</uv-scroll-list>
</view>
<view class="list-header list-item">
<view class="rank-column">排名</view>
<view class="user-column">用户名/所属机构</view>
<view class="score-column">{{activeNameSec}}</view>
</view>
<scroll-view :scroll-y="true" class="scroll-items-view">
<view v-for="(item,index) in userList" :class="['list-item', 'item-'+(index+1)]">
<view class="rank-column">
{{item.ranking}}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview v-if="item.ossAddr" class="avatar-image" :src="item.ossAddr" mode="aspectFit"></image-preview>
<image v-else class="avatar-image" :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">{{item.userName}}</view>
<view class="user-org">{{item.orgName}}</view>
</view>
<view class="score-column">{{item.grade}}</view>
</view>
<list-no-data v-if="userList.length == 0">暂无数据</list-no-data>
</scroll-view>
</view>
<view class="ranking-self">
<view class="list-header list-item">
<view class="rank-column">我的排名
</view>
</view>
<view class="list-item item-me">
<view class="rank-column">
{{userRankObj.ranking}}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview v-if="userRankObj.ossAddr" class="avatar-image" :src="userRankObj.ossAddr" mode="aspectFit"></image-preview>
<image class="avatar-image" v-else :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">{{userRankObj.userName}}</view>
<view class="user-org">{{userRankObj.orgName}}</view>
</view>
<view class="score-column">{{userRankObj.grade}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { defaultAvatar } from "@/enum.js"
// 我的排行榜
import { getUserInfo } from '@/common/common';
import { leaderBoardApi } from '@/api/charts.js'
import {
reactive,
ref,
computed,
nextTick,
onMounted,
watch
} from 'vue';
import common from '@/common/common';
export default {
data() {
return {
crsId: '',
papersId : '',
defaultAvatarSrc: defaultAvatar,
chooseTyp: 0,
chooseTypSec: 0,
tagsList:[{
label: '本周',
value: 'WEEK',
},{
label: '本月',
value: 'MONTH',
},{
label: '本年',
value: 'YEAR',
}],
activeTag: 'WEEK',
rankList: []
}
},
// onLoad(params){
// this.getList()
// },
onShow(){
this.getList()
},
computed: {
tabList() {
return [{
name: '课程排行榜',
value: 0,
key: '01'
},{
name: 'AI陪练排行榜',
value: 1,
key: '02'
},{
name: '考试排行榜',
value: 2,
key: '03'
}]
},
tabSecList() {
let _arr = []
if(this.chooseTyp === 0){
_arr = [
{
name: '学习时长',
value: 0,
},
{
name: '练习完成次数',
value: 1
},
{
name: '考试通过次数',
value: 2
},
{
name: '完成课程数',
value: 3
}
]
} else if(this.chooseTyp === 1){
_arr = [
{
name: '练习通过次数',
value: 0
},
{
name: '考试通过次数',
value: 1
},
{
name: '完成AI陪练数',
value: 2
}
]
} else if(this.chooseTyp === 2){
_arr = [
{
name: '考试通过次数',
value: 0
},
{
name: '完成考试数',
value: 1
}
]
}
return _arr
},
activeNameSec(){
if(this.tabSecList.length >= this.chooseTypSec){
return this.tabSecList[this.chooseTypSec].name|| '--'
}else{
return '--'
}
},
userRankObj(){
if(this.rankList.length >= this.chooseTypSec){
return this.rankList[this.chooseTypSec] || {}
}else{
return {}
}
},
userList(){
return this.userRankObj.rankingListVos || []
},
},
methods: {
getList(){
leaderBoardApi({
leaderBoardType: this.tabList[this.chooseTyp].key,
timeType: this.activeTag
}).then(res=>{
console.log(res)
this.rankList = res.body||[]
})
},
changeTab(item){
if(this.chooseTyp === item.value) return
this.chooseTyp = item.value
this.chooseTypSec = 0
this.getList()
},
changeTabSec(item){
this.chooseTypSec = item.value
},
chooseTag (item){
this.activeTag = item.value
this.getList()
},
backRouter(){
common.navigateBack()
}
}
}
</script>
<style scoped lang="scss">
$top-height: var(--status-bar-height);
.exam-ranking {
position: relative;
height: 100vh;
width: 100vw;
overflow: hidden;
box-sizing: border-box;
padding-top: $top-height;
// background:url(@/static/images/examRanking/bg.png) no-repeat top center;
.bg-box {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 400rpx;
background: linear-gradient(0deg , #F8F8FA 0%, #6DA7FF 100%);
z-index: 1;
}
.ranking-box {
height: calc(100% - $top-height);
overflow: hidden;
position: absolute;
top: $top-height;
width: 100%;
z-index: 2;
}
.nav-div {
position: relative;
overflow: hidden;
height: 70rpx;
.back_div {
margin-right: 10rpx;
position: absolute;
left: 25rpx;
top: 0;
padding: 15rpx;
.back-icon {
position: relative;
width: 40rpx;
height: 40rpx;
cursor: pointer;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::after {
top: 25%;
left: 25%;
width: 40%;
height: 40%;
border-top: 4rpx solid #000;
border-left: 4rpx solid #000;
transform: rotate(-45deg);
}
}
}
.title-view {
height: 180rpx;
position: relative;
padding-top: 20rpx;
.cup-image {
position: absolute;
right: 46rpx;
bottom: -33rpx;
width: 208rpx;
height: 208rpx;
z-index: 0;
}
.title-desc {
color: #666;
line-height: 34rpx;
font-size: 25rpx;
}
.title-image {
width: 230rpx;
height: 111rpx;
position: absolute;
bottom: 20rpx;
left: 46rpx;
}
}
.ranking-body {
height: calc(100% - 170rpx - 180rpx - 70rpx);
overflow: hidden;
background-color: #fff;
border-radius: 31rpx 31rpx 0 0;
padding-top: 20rpx;
box-sizing: border-box;
position: relative;
z-index: 2;
.scroll-items-view{
height: calc(100% - 308rpx);
}
}
.list-item {
height: 108rpx;
border-bottom: 2rpx solid #efefef;
overflow: hidden;
&.list-header {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-size: 25rpx;
border-bottom: 0;
.rank-column {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
font-style: initial;
text-indent: 0;
}
.user-column {
padding: 0;
}
.score-column {
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
}
}
&.item-1 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #fbf9f5 0%, #fffffd 100%);
.rank-column{
color: #ffffff00;
background: url(@/static/images/examRanking/no-1.png) no-repeat ;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-2 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #f4f8f9 0%, #f7fbfe 100%);
.rank-column{
color: #ffffff00;
background: url(@/static/images/examRanking/no-2.png) no-repeat ;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-3 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #faf6f5 0%, #fcfbfc 100%);
.rank-column{
color: #ffffff00;
background: url(@/static/images/examRanking/no-3.png) no-repeat ;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-me{
border-bottom: 0;
.rank-column {
color: #06f;
}
}
.rank-column {
width: 170rpx;
padding-left: 40rpx;
float: left;
font-weight: 600;
line-height: 92rpx;
height: 108rpx;
color: #333;
font-size: 38rpx;
font-style: italic;
text-indent: 8rpx;
}
.user-column {
width: 375rpx;
float: left;
padding: 15rpx 0;
.avatar-box{
width: 77rpx;
height: 77rpx;
overflow: hidden;
float: left;
background-color: #eee;
border-radius: 50%;
.avatar-image{
width: 77rpx;
height: 77rpx;
}
}
.user-name{
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 40rpx;
line-height: 40rpx;
font-size: 29rpx;
color: #000;
font-weight: 500;
}
.user-org{
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 34rpx;
line-height: 34rpx;
font-size: 25rpx;
color: #999;
}
}
.score-column {
width: 150rpx;
text-align: right;
float: left;
font-weight: 600;
line-height: 108rpx;
color: #333;
font-size: 31rpx;
white-space: nowrap;
}
}
.ranking-self {
height: 170rpx;
overflow: hidden;
background-color: #f5f9ff;
padding-top: 4rpx;
}
}
.tags-view {
height: 84rpx;
display: block;
padding: 15rpx 20rpx 15rpx 20rpx;
box-sizing: border-box;
white-space: nowrap;
// border-bottom: 2rpx solid #eee;
.tags-item {
margin-right: 30rpx;
display: inline-block;
&.active-tags-item {
position: relative;
overflow: hidden;
border-radius: 4rpx;
overflow: hidden;
&::before {
content: '';
display: block;
width: 40rpx;
height: 40rpx;
position: absolute;
right: -20rpx;
bottom: -20rpx;
transform: rotateZ(-45deg);
background-color: #06f;
overflow: hidden;
z-index: 10;
}
&::after {
content: '';
display: block;
width: 8rpx;
height: 4rpx;
position: absolute;
right: 3rpx;
bottom: 8rpx;
transform: rotateZ(-45deg);
border-left: 1px solid #fff;
border-bottom: 1px solid #fff;
z-index: 11;
}
}
::v-deep .uv-tags {
padding: 0 20rpx;
.uv-tags__text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200rpx;
}
}
}
}
.my_tabs {
// 解决这个圆角的图片,开穿透
:deep(.uv-tabs__wrapper__nav__line) {
// height: 30rpx !important;
// left: 60rpx;
// background-size: 24rpx !important;
// background-repeat: no-repeat !important;
background: linear-gradient(90deg, #06f 0%, rgb(0, 159, 255) 50%, rgb(255, 255, 255) 100%) !important;
}
:deep(.uv-tabs__wrapper__nav__item) {
padding: 0 30rpx !important;
}
}
.my_tabs2 {
// 解决这个圆角的图片,开穿透
:deep(.uv-tabs__wrapper__nav__line) {
background-size: 24rpx !important;
background: linear-gradient(90deg, #06f 0%, rgb(0, 159, 255) 50%, rgb(255, 255, 255) 100%) !important;
}
:deep(.uv-tabs__wrapper__nav__item) {
padding: 0 20rpx !important;
}
}
</style>