Browse Source

排行榜开发

林旭祥 8 months ago
parent
commit
985c1cdaca

+ 19 - 0
src/api/module/ranking.ts

@@ -0,0 +1,19 @@
+import req from '../request';
+
+export default {
+  examlistShow: (data: any) => {
+    return req({
+      url: '/exam/examlist_show',
+      method: 'get',
+      data: data
+    });
+  },
+
+  studentRanking: (data: any) => {
+    return req({
+      url: '/schpanel/student_rank_list',
+      method: 'get',
+      data: data
+    });
+  }
+};

BIN
src/assets/images/ranking/arrow.png


BIN
src/assets/images/ranking/btn-left.png


BIN
src/assets/images/ranking/btn-right.png


BIN
src/assets/images/ranking/logo.png


BIN
src/assets/images/ranking/mao.png


BIN
src/assets/images/ranking/noData.png


BIN
src/assets/images/ranking/pai1.png


BIN
src/assets/images/ranking/pai2.png


BIN
src/assets/images/ranking/pai3.png


BIN
src/assets/images/ranking/ranking.png


+ 35 - 9
src/components/Header/index.vue

@@ -1,13 +1,18 @@
 <template>
-  <div class="close" @click="confirmExit"></div>
-  <div class="toolList">
-    <div class="li">{{ date }}</div>
-    <div class="li btn speck" :class="{ 'on': voice, 'off': !voice }" @click="getVoice"></div>
-    <div class="li btn screen" :class="{ 'on': screen, 'off': !screen }" @click="getFullScreen"></div>
-  </div>
-  <div class="logo"> <img src="@/assets/images/logo.png">
-    </img>
-    <div class="title" v-if="parameter.project"><i></i><span>{{ dic.project[parameter.project] || "" }}</span></div>
+  <div>
+    <div class="close" @click="confirmExit"></div>
+    <div class="toolList">
+      <div class="li">{{ date }}</div>
+      <div class="li btn speck" :class="{ 'on': voice, 'off': !voice }" @click="getVoice"></div>
+      <div class="li btn screen" :class="{ 'on': screen, 'off': !screen }" @click="getFullScreen"></div>
+    </div>
+    <div class="ranking" v-if="props.type == 'ranking'">
+      <img src="@/assets/images/ranking/ranking.png" />
+    </div>
+    <div class="logo" v-else>
+      <img src="@/assets/images/logo.png" />
+      <div class="title" v-if="parameter.project"><i></i><span>{{ dic.project[parameter.project] || "" }}</span></div>
+    </div>
   </div>
 </template>
 <script setup lang="ts">
@@ -18,6 +23,15 @@ const emit = defineEmits(['confirmExit']);
 const router = useRouter();
 const route = useRoute();
 const dic: any = dataDictionary;
+
+//父值
+const props = defineProps({
+  type: {
+    type: String,
+    default: ""
+  },
+});
+
 const data = reactive<any>({
   timerManager: {},//计时器管理
   parameter: {},//参数
@@ -74,6 +88,18 @@ onBeforeMount(() => {
 $topPadding: 5.19rem;
 $waiPadding: 6.51rem;
 
+.ranking {
+  position: absolute;
+  left: $waiPadding;
+  top: calc($topPadding - 2rem);
+  display: flex;
+  align-items: center;
+
+  img {
+    width: 27rem;
+  }
+}
+
 .logo {
   position: absolute;
   left: $waiPadding;

+ 2 - 1
src/router/index.ts

@@ -17,7 +17,8 @@ const router = createRouter({
         { path: '/train/run', component: () => import('@/views/train/run.vue') },
         { path: '/train/multiple', component: () => import('@/views/train/multiple.vue') },
         { path: '/set', component: () => import('@/views/set/index.vue') },
-        { path: '/set/config', component: () => import('@/views/set/config.vue') }
+        { path: '/set/config', component: () => import('@/views/set/config.vue') },
+        { path: '/ranking', component: () => import('@/views/ranking/index.vue') }
       ]
     }
   ]

+ 0 - 8
src/types/auto-imports.d.ts

@@ -296,10 +296,6 @@ declare module 'vue' {
   interface GlobalComponents {}
   interface ComponentCustomProperties {
     readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
-    readonly ElLoading: UnwrapRef<typeof import('element-plus/es')['ElLoading']>
-    readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']>
-    readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']>
-    readonly ElNotification: UnwrapRef<typeof import('element-plus/es')['ElNotification']>
     readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
     readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
     readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
@@ -579,10 +575,6 @@ declare module '@vue/runtime-core' {
   interface GlobalComponents {}
   interface ComponentCustomProperties {
     readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
-    readonly ElLoading: UnwrapRef<typeof import('element-plus/es')['ElLoading']>
-    readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']>
-    readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']>
-    readonly ElNotification: UnwrapRef<typeof import('element-plus/es')['ElNotification']>
     readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
     readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
     readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>

+ 1 - 0
src/types/components.d.ts

@@ -11,6 +11,7 @@ declare module 'vue' {
     copy: typeof import('./../components/OptionWindow copy/index.vue')['default']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']

+ 90 - 0
src/utils/dataDictionary.ts

@@ -123,6 +123,7 @@ let data = {
     run1000: '秒',
     runa800: '秒',
     runa1000: '秒',
+    basketballv1: '秒',
     situp: '个',
     pullup: '个',
     sidepullup: '个',
@@ -168,6 +169,95 @@ let data = {
     runa800: 'result',
     runa1000: 'result'
   },
+
+  gradeLists: [
+    {
+      label: '小学',
+      value: 1,
+      child: [
+        { value: 'one', label: '一年级' },
+        { value: 'two', label: '二年级' },
+        { value: 'three', label: '三年级' },
+        { value: 'four', label: '四年级' },
+        { value: 'five', label: '五年级' },
+        { value: 'six', label: '六年级' }
+      ]
+    },
+    {
+      label: '初中',
+      value: 2,
+      child: [
+        { value: 'm_one', label: '初一' },
+        { value: 'm_two', label: '初二' },
+        { value: 'm_three', label: '初三' }
+      ]
+    },
+    {
+      label: '高中',
+      value: 3,
+      child: [
+        { value: 'h_one', label: '高一' },
+        { value: 'h_two', label: '高二' },
+        { value: 'h_three', label: '高三' }
+      ]
+    },
+    {
+      label: '大学',
+      value: 4,
+      child: [
+        { value: 'u_one', label: '大一' },
+        { value: 'u_two', label: '大二' },
+        { value: 'u_three', label: '大三' },
+        { value: 'u_four', label: '大四' }
+      ]
+    },
+    {
+      label: '小学初中',
+      value: 5,
+      child: [
+        { value: 'one', label: '一年级' },
+        { value: 'two', label: '二年级' },
+        { value: 'three', label: '三年级' },
+        { value: 'four', label: '四年级' },
+        { value: 'five', label: '五年级' },
+        { value: 'six', label: '六年级' },
+        { value: 'm_one', label: '初一' },
+        { value: 'm_two', label: '初二' },
+        { value: 'm_three', label: '初三' }
+      ]
+    },
+    {
+      label: '初中高中',
+      value: 6,
+      child: [
+        { value: 'm_one', label: '初一' },
+        { value: 'm_two', label: '初二' },
+        { value: 'm_three', label: '初三' },
+        { value: 'h_one', label: '高一' },
+        { value: 'h_two', label: '高二' },
+        { value: 'h_three', label: '高三' }
+      ]
+    },
+    {
+      label: '小学初中高中',
+      value: 7,
+      child: [
+        { value: 'one', label: '一年级' },
+        { value: 'two', label: '二年级' },
+        { value: 'three', label: '三年级' },
+        { value: 'four', label: '四年级' },
+        { value: 'five', label: '五年级' },
+        { value: 'six', label: '六年级' },
+        { value: 'm_one', label: '初一' },
+        { value: 'm_two', label: '初二' },
+        { value: 'm_three', label: '初三' },
+        { value: 'h_one', label: '高一' },
+        { value: 'h_two', label: '高二' },
+        { value: 'h_three', label: '高三' }
+      ]
+    }
+  ],
+
   projectNote: {
     jump: '<p><span style="color: #13ED84">预摆:</span>上下肢动作协调配合,摆动时一伸二屈降重心,上体稍前倾。</p><p><span style="color: #13ED84">空展体:</span>蹬地快速有力,腿蹬和手摆要协调,空中展体要充分,待身体完全展开后,收腹屈膝。</p><p><span style="color: #13ED84">落地缓冲:</span>小腿前伸的时机把握好,曲腿前伸臂后摆,落地后往前不往后。</p>',
     longjump:

+ 2 - 2
src/utils/index.ts

@@ -79,9 +79,9 @@ let utils = {
   /**
    * 跑步成绩格式化
    */
-  runTime: (times: any, noMin = false, type: boolean, lang: any = 0) => {
+  runTime: (times: any, noMin: boolean = false, type: boolean, lang: any = 0) => {
     if (times != undefined && times.toString().indexOf('.') != -1) {
-      times = Math.round((times + Number.EPSILON) * 100) / 100;
+      times = Math.round((Number(times) + Number.EPSILON) * 100) / 100;
     }
     if (type) {
       if (times <= 0) {

+ 1522 - 0
src/views/ranking/index.vue

@@ -0,0 +1,1522 @@
+<template>
+  <div>
+    <Header @confirmExit="confirmExit" type="ranking"></Header>
+    <div class="ranking">
+      <div class="top">
+        <div class="top-left">
+          <div class="title1">{{ pageType == 1 ? "运动风云榜" : pageType == 2 ? currentClass.name : "" }} · {{
+            projectObj.title
+          }}</div>
+          <div class="title2" @click="choiceClassWindow = true">{{ pageType == 1 ? "切换到班级榜" : pageType == 2 ? "切换到班级" :
+            "" }}</div>
+        </div>
+        <div class="tab">
+          <ul>
+            <li @click="clickType(1)" :class="{ current: type == 1 }">男生</li>
+            <li @click="clickType(2)" :class="{ current: type == 2 }">女生</li>
+          </ul>
+          <dl>
+            <dt @click="getDateType(4)" :class="{ current: date.type == 4 }">上周</dt>
+            <dt @click="getDateType(1)" :class="{ current: date.type == 1 }">本周</dt>
+            <dt @click="getDateType(2)" :class="{ current: date.type == 2 }">月榜</dt>
+            <dt @click="getDateType(3)" :class="{ current: date.type == 3 }">季度榜</dt>
+          </dl>
+        </div>
+      </div>
+      <div class="mainBox">
+        <div class="main" v-show="pageType == 1 ? true : false">
+          <div class="swiperBox">
+            <!--年级排名开始-->
+            <swiper ref="refSwiper" :slides-per-view="3" :slides-per-group="3" :space-between="10">
+              <swiper-slide v-for="(item, index) in gradeData" :key="index">
+                <div class="item">
+                  <div class="gradeTitle">{{ item.label }}</div>
+                  <ul :ref="(el: any) => { multipleItemRef(el, item.value) }" @scroll="getScroll($event, item.value)">
+                    <li :data-items="JSON.stringify(items)" v-for="items in item.list" :key="items.student_id"
+                      @click="showPerson(items)">
+                      <div class="left">
+                        <i class="pai"
+                          :class="{ 'pai1': items.rank == 1, 'pai2': items.rank == 2, 'pai3': items.rank == 3 }">{{
+                            items.rank }}</i>
+
+                        <div class="userInfo">
+                          <div class="touxiang">
+                            <img v-if="items.logo_url" :src="items.logo_url" />
+                            <img v-else :src="logo" />
+                          </div>
+                          <div class="nameBox">
+                            <span class="studentName">{{ items.student_name }}</span>
+                            <span class="className">{{ items.class_name }}</span>
+                          </div>
+                        </div>
+                      </div>
+                      <div class="right" v-if="['basketballv1'].includes(projectObj.exam_name)">
+                        <div class="score">{{ proxy?.$utils.runTime(items.result, true, false) }}
+                        </div>
+                      </div>
+                      <div class="right" v-else>
+                        <div class="score">{{ items.result }}
+                        </div>
+                        <div class="unit">{{ items.unit }}</div>
+                      </div>
+                    </li>
+                  </ul>
+                </div>
+              </swiper-slide>
+            </swiper>
+            <!-- 如果需要导航按钮 -->
+            <div class="swiper-button-prev swiper-btn-left" slot="button-prev" @click="getStopPlaying()"></div>
+            <div class="swiper-button-next swiper-btn-right" slot="button-next" @click="getStopPlaying()"></div>
+            <!--年级排名结束-->
+          </div>
+        </div>
+        <div class="main" v-show="pageType == 2 ? true : false">
+          <div class="main-a">
+            <!--学生排行榜-->
+            <div class="main-a-center" v-if="studentTop.length">
+              <div class="item" :class="{ one: index == 0, two: index == 1, three: index == 2 }"
+                @click="showPerson(item)" v-for="(item, index) in studentTop" :key="index">
+                <div class="touxiang">
+                  <img v-if="item.logo_url" :src="item.logo_url" />
+                  <img v-else :src="logo" />
+                </div>
+                <div class="txt">
+                  <div class="number">NO.{{ item.rank }}</div>
+                  <div class="studentName">{{ item.student_name }}</div>
+                  <div class="scoreBox" v-if="['basketballv1'].includes(projectObj.exam_name)">
+                    <div class="score">{{
+                      proxy?.$utils.runTime(item.result, true, false) }}</div>
+                  </div>
+                  <div class="scoreBox" v-else>
+                    <div class="score">{{ item.result }}</div>
+                    <div class="unit">{{ item.unit }}</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="noData" v-else>
+              <div>
+                <img src="~@/assets/images/ranking/noData.png" />
+                <span>暂无更多数据</span>
+              </div>
+            </div>
+          </div>
+          <div class="main-b">
+            <div class="btn-left" @click="getPrevious"></div>
+            <div class="main-b-center">
+              <div class="columns" v-for="(item, index) in studentList" :key="index">
+                <transition name="fade" mode="out-in">
+                  <ul v-if="item.length">
+                    <li v-for="(items, indexs) in item" :key="indexs" @click="showPerson(items)">
+                      <div class="txt">
+                        <i>{{ items.rank }}</i>
+                        <div class="studentName">{{ items.student_name }}</div>
+                        <div class="right" v-if="['basketballv1'].includes(projectObj.exam_name)">
+                          <div class="score">{{ proxy?.$utils.runTime(items.result, true, false) }}
+                          </div>
+                        </div>
+                        <div class="right" v-else>
+                          <div class="score">{{ items.result }}
+                          </div>
+                          <div class="unit">{{ items.unit }}</div>
+                        </div>
+                      </div>
+                    </li>
+                  </ul>
+                  <div class="noData" v-else>
+                    <div>
+                      <img src="~@/assets/images/ranking/noData.png" />
+                      <span>暂无更多数据</span>
+                    </div>
+                  </div>
+                </transition>
+              </div>
+            </div>
+            <div class="btn-right" @click="getNext"></div>
+          </div>
+        </div>
+        <div class="footer">
+          <div class="tab">
+            <ul>
+              <li @click="clickProject(item)" :class="{ current: projectObj.exam_name == item.exam_name }"
+                v-for="item in projectList" :key="item.exam_name">
+                {{ item.title }}
+              </li>
+            </ul>
+          </div>
+        </div>
+      </div>
+      <div class="choiceClass" v-if="choiceClassWindow">
+        <div class="choiceClass-content">
+          <div v-for="(item, index) in classList" :key="item.value">
+            <div class="classTitle">{{ item.label }}</div>
+            <ul>
+              <li @click="openClassPage(items)" v-for="(items, indexs) in item.child" :key="items.id">
+                {{ items.name }}
+              </li>
+            </ul>
+          </div>
+        </div>
+        <div class="choiceClass-btn-box">
+          <div class="choiceClass-btn choiceClass-btn-all" @click="openAllPage">
+            全部排名
+          </div>
+          <div class="choiceClass-btn" @click="choiceClassWindow = false">
+            关闭
+          </div>
+        </div>
+      </div>
+
+
+      <el-dialog :custom-class="'custom-dialog compare-dialog'" :visible.sync="isShowPerson"
+        :before-close="closePerson">
+        <!-- <div>
+          <PersonDetail ref="personDetail" :type="projectObj.exam_name" :displayType="1" @close="closePerson"
+            @delRefresh="getData" />
+        </div> -->
+      </el-dialog>
+
+    </div>
+  </div>
+</template>
+
+<script setup name="Ranking" lang="ts">
+import { Swiper, SwiperSlide } from 'swiper/vue';
+import dataDictionary from "@/utils/dataDictionary"
+import 'dayjs/locale/zh-cn'
+import dayjs from 'dayjs'
+import weekOfYear from 'dayjs/plugin/weekOfYear'
+import 'swiper/css';
+dayjs.locale('zh-cn')
+dayjs.extend(weekOfYear)
+const { proxy } = getCurrentInstance() as any;
+const router = useRouter();
+const refSwiper = ref();
+
+const data = reactive<any>({
+  pageType: 1,//1年级排名2班级排名
+  currentDate: "",
+  projectList: [], //项目列表
+  projectObj: {}, //当前项目
+  studentTop: [], //学生前三
+  studentList: [], //学生排名列表
+  studentPage: {
+    current: 1,
+    size: 15,
+    pages: 1,
+  }, //学生分页
+  type: 1, //1男生2女生
+  timer: null, //定时器状态
+  countDownTimer: null, //倒计时状态
+  countDown: null, //倒计时20秒
+  logo: "",
+  gradeType: [],
+  gradeData: [],
+  classList: [],
+  multipleItemRefList: [],
+  currentClass: {},
+  classIdKeyObj: {},
+  choiceClassWindow: false,
+  isShowPerson: false,
+  date: {
+    type: 0, //1周2月3季度
+    start: "",
+    end: "",
+  },
+  debounceTime: '', //防抖状态
+  swiperOption: {
+    // 设置垂直轮播vertical,  水平轮播 horizontal
+    direction: "horizontal",
+    // 轮播图间距
+    spaceBetween: 30,
+    // 循环模式选项
+    loop: false,
+    slidesPerView: 3,
+    slidesPerGroup: 3,
+    initialSlide: 1,
+    speed: 1600,
+    //  自动滑动
+    autoplay: {
+      delay: 30000,
+      // 如果设置为true,当切换到最后一个slide时停止自动切换。
+      stopOnLastSlide: false,
+      // 如果设置为false,用户操作swiper之后自动切换不会停止,每次都会重新启动autoplay
+      disableOnInteraction: false,
+    },
+    // 轮播图的切换前进后退按钮,如果想放在轮播图中可以看swiper官方文档,这里写在了轮播外
+    navigation: {
+      nextEl: ".swiper-button-next",
+      prevEl: ".swiper-button-prev",
+    },
+    on: {
+    },
+  },
+});
+
+const {
+  pageType,
+  currentDate,
+  projectList,
+  projectObj,
+  studentTop,
+  studentList,
+  studentPage,
+  type,
+  timer,
+  countDownTimer,
+  countDown,
+  logo,
+  gradeType,
+  gradeData,
+  classList,
+  multipleItemRefList,
+  currentClass,
+  classIdKeyObj,
+  choiceClassWindow,
+  isShowPerson,
+  date,
+  debounceTime,
+  swiperOption
+
+} = toRefs(data);
+
+/**
+ * 创建组件实例
+*/
+const multipleItemRef = (el: any, grade: any) => {
+  multipleItemRefList.value[grade] = el;
+}
+
+
+//获取年级列表
+const getClass = () => {
+  let params = {
+    page: 1,
+    per_page: 9999,
+  };
+  proxy?.$http.common.classList(params)
+    .then((res: any) => {
+      // 重新排序一次
+      let list: any = [];
+      dataDictionary.gradeList.forEach((item) => {
+        res.data.forEach((items: any) => {
+          // classIdKeyObj.value[items.id] = items
+          if (items.grade == item.value) {
+            list.push(items);
+          }
+        })
+      });
+      let myClassList = gradeType.value.map((item: any) => {
+        let newList = list.filter((items: any) => {
+          return items.grade == item.value;
+        })
+        item.child = newList || [];
+        return item;
+      });
+      classList.value = myClassList;
+    })
+};
+
+//获取项目
+const getProject = () => {
+  let params = {};
+  proxy?.$http.ranking.examlistShow(params).then((res: any) => {
+    if (res.status == 200) {
+      let dic: any = dataDictionary.project;
+      let list = res.data.map((item: any) => {
+        item.title = dic[item.exam_name];
+        return item;
+      });
+      projectList.value = list;
+      if (list.length) {
+        projectObj.value = list[0];
+        getData();
+        getAutoplay();
+      }
+    }
+  });
+};
+
+//自动切换排行榜
+const getAutoplay = () => {
+  // refSwiper.value.autoplay.start();
+  let qieTime = swiperOption.value.autoplay.delay * (gradeData.value.length / swiperOption.value.slidesPerGroup);//切换项目时间
+  timer.value = setInterval((res: any) => {
+    //切换类型
+    let type1 = JSON.parse(JSON.stringify(type.value));
+    if (type1 == 1) {
+      type.value = 2;
+    }
+    if (type1 == 2) {
+      type.value = 1;
+    }
+    //切换项目归为1后切换项目
+    if (type.value == 1) {
+      let projectIndex = projectList.value.findIndex((item: any) => {
+        return item.exam_name == projectObj.value.exam_name;
+      });
+      if (projectIndex + 1 == projectList.value.length) {
+        //最后一个就重新开始
+        projectObj.value = projectList.value[0];
+      } else {
+        //项目从左到右
+        projectObj.value = projectList.value[projectIndex + 1];
+      }
+    }
+    getData();
+  }, qieTime);
+};
+
+//停止切换排行榜
+const getStopPlaying = (myTime?: any) => {
+  clearInterval(timer.value);
+  clearInterval(countDownTimer.value);
+  // refSwiper.value.$swiper.autoplay.stop();
+  //30秒后重新自动运行
+  countDown.value = myTime || 20;
+  countDownTimer.value = setInterval((res: any) => {
+    countDown.value--;
+    console.log("即将启动自动切换", countDown.value);
+    if (countDown.value <= 0) {
+      getAutoplay();
+      clearInterval(countDownTimer.value);
+    }
+  }, 1000);
+};
+
+//请求数据
+
+const getData = () => {
+  if (pageType.value == 1) {
+    gradeData.value.forEach((item: any, index: any) => {
+      gradeData.value[index].page.current = 1;
+    })
+    getIniGrade();
+  }
+  if (pageType.value == 2) {
+    studentPage.value.current = 1;
+    getGoodStudent();
+    getStudentList();
+  }
+};
+
+//各项目的学生前三
+
+
+const getGoodStudent = () => {
+  studentTop.value = [];
+  let params: any = {
+    exam_name: projectObj.value.exam_name,
+    page: 1,
+    per_page: 3,
+  };
+  if (date.value.type != 0) {
+    params.start_date = date.value.start;
+    params.end_date = date.value.end;
+  }
+  if (type.value == 1) {
+    params.gender = 1;
+  }
+  if (type.value == 2) {
+    params.gender = 0;
+  }
+  if (pageType.value == 2) {
+    params.class_id = currentClass.value.id;
+  }
+  proxy?.$http.ranking.studentRanking(params).then((res: any) => {
+    if (res.status == 200) {
+      let list = res.data.map((item: any) => {
+        if (projectObj.value.exam_name == 'solidball' || projectObj.value.exam_name == 'shotball') {
+          item.result = item.result / 100
+        }
+        let result = null;
+        if (item.result.toString().indexOf(".") != -1) {
+          if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
+            result = item.result.toFixed(2)
+          } else {
+            result = item.result.toFixed(1);
+          }
+        } else {
+          result = item.result
+        }
+        item.result = result;
+        let dic: any = dataDictionary.unit;
+        item.unit = dic[projectObj.value.exam_name];
+        return item
+      });
+      studentTop.value = list;
+    }
+  });
+};
+
+//各项目的学生排名列表
+const getStudentList = () => {
+  let params: any = {
+    exam_name: projectObj.value.exam_name,
+    page: studentPage.value.current,
+    per_page: studentPage.value.size,
+    offset: 3,
+  };
+  if (date.value.type != 0) {
+    params.start_date = date.value.start;
+    params.end_date = date.value.end;
+  }
+  if (type.value == 1) {
+    params.gender = 1;
+  }
+  if (type.value == 2) {
+    params.gender = 0;
+  }
+  if (pageType.value == 2) {
+    params.class_id = currentClass.value.id;
+  }
+  proxy?.$http.ranking.studentRanking(params).then((res: any) => {
+    if (res.status == 200) {
+      let list: any = [[], [], []];
+      let num = studentPage.value.size / 3;
+      res.data
+        .map((item: any) => {
+          if (projectObj.value.exam_name == 'solidball' || projectObj.value.exam_name == 'shotball') {
+            item.result = item.result / 100
+          }
+          let result = null;
+          if (item.result.toString().indexOf(".") != -1) {
+            if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1'].includes(projectObj.value.exam_name)) {
+              result = item.result.toFixed(2)
+            } else {
+              result = item.result.toFixed(1);
+            }
+          } else {
+            result = item.result
+          }
+          item.result = result;
+          let dic: any = dataDictionary.unit;
+          item.unit = dic[projectObj.value.exam_name];
+          return item
+        })
+        .forEach((item: any, index: any) => {
+          if (index >= 0 && index <= num * 1 - 1) {
+            list[0].push(item);
+          }
+          if (index >= num && index <= num * 2 - 1) {
+            list[1].push(item);
+          }
+          if (index >= num * 2 && index <= num * 3 - 1) {
+            list[2].push(item);
+          }
+        });
+      studentList.value = list;
+      getPages(res.total);
+    }
+  });
+};
+
+//获取班级排名
+const getGradeList = (grade: any) => {
+  let index = gradeData.value.findIndex((item: any) => {
+    return item.value == grade;
+  })
+  let params: any = {
+    exam_name: projectObj.value.exam_name,
+    page: gradeData.value[index].page.current,
+    per_page: gradeData.value[index].page.size,
+    grade: grade,
+  };
+  if (date.value.type != 0) {
+    params.start_date = date.value.start;
+    params.end_date = date.value.end;
+  }
+  if (type.value == 1) {
+    params.gender = 1;
+  }
+  if (type.value == 2) {
+    params.gender = 0;
+  }
+  proxy?.$http.ranking.studentRanking(params).then((res: any) => {
+    if (res.status == 200) {
+      let list = res.data
+        .map((item: any) => {
+          if (projectObj.value.exam_name == 'solidball' || projectObj.value.exam_name == 'shotball') {
+            item.result = item.result / 100
+          }
+          let result = null;
+          if (item.result.toString().indexOf(".") != -1) {
+            if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
+              result = item.result.toFixed(2)
+            } else {
+              result = item.result.toFixed(1);
+            }
+          } else {
+            result = item.result
+          }
+          item.result = result;
+          let dic: any = dataDictionary.unit;
+          item.unit = dic[projectObj.value.exam_name];
+          return item
+        })
+      gradeData.value[index].page.current == 1 ?
+        (gradeData.value[index].list = list) :
+        gradeData.value[index].list.push(...list);
+      getGradePages(res.total, grade);
+    }
+  });
+};
+
+//年级排名
+const getIniGrade = () => {
+  gradeData.value = [];
+  gradeType.value.forEach((item: any) => {
+    //构建年级数据结构
+    let obj: any = {
+      label: item.label,
+      value: item.value,
+      page: {
+        current: 1,
+        size: 15,
+        pages: 1,
+      },
+      list: [],
+    }
+    gradeData.value.push(obj);
+    getGradeList(item.value);
+  })
+};
+
+const getScroll = (event?: any, grade?: any) => {
+  getStopPlaying();//滚动的停止执行切换
+  let index = gradeData.value.findIndex((item: any) => {
+    return item.value == grade;
+  })
+  if (gradeData.value[index].page.current == gradeData.value[index].page.pages) {
+    return false;
+  }
+  let obj = multipleItemRefList.value[grade];
+  let scrollHeight = obj.scrollHeight;
+  let scrollTop = obj.scrollTop;
+  let clientHeight = obj.clientHeight;
+  //提前100高度加载数据
+  if (scrollTop + clientHeight + 100 >= scrollHeight) {
+    console.log('到底了!')
+    //继续加载下一页
+    if (debounceTime.value) {
+      clearTimeout(debounceTime.value)
+    }
+    debounceTime.value = setTimeout(() => {
+      gradeData.value[index].page.current++;
+      getGradeList(grade);
+    }, 500)
+  } else {
+    console.log('没到底')
+  }
+};
+
+
+const openAllPage = () => {
+  pageType.value = 1;
+  choiceClassWindow.value = false;
+};
+
+
+const openClassPage = (data: any) => {
+  currentClass.value = data;
+  pageType.value = 2;
+  getData();
+  choiceClassWindow.value = false;
+};
+
+//切换排行榜
+const clickType = (data: any) => {
+  type.value = data;
+  getData();
+  getStopPlaying();
+};
+
+//切换项目
+
+const clickProject = (data: any) => {
+  projectObj.value = data;
+  getData();
+  getStopPlaying();
+};
+
+//时间类型
+
+
+const getDateType = (data: any) => {
+  date.value.type = data;
+  getTypeTime();
+  getData();
+  getStopPlaying();
+};
+
+//时间转化
+const getTypeTime = () => {
+  //本周
+  if (date.value.type == 1) {
+    date.value.start = dayjs()
+      .startOf("week")
+      .format("YYYY-MM-DD");
+    date.value.end = dayjs()
+      .endOf("week")
+      .format("YYYY-MM-DD");
+  }
+  //月
+  if (date.value.type == 2) {
+    date.value.start = dayjs().startOf("month").format("YYYY-MM-DD");
+    date.value.end = dayjs().endOf("month").format("YYYY-MM-DD");
+  }
+  //季度
+  if (date.value.type == 3) {
+    let month = dayjs().month() + 1;
+    let jiduArr = [
+      [1, 3],
+      [4, 6],
+      [7, 9],
+      [10, 12]
+    ];
+    let start = 0;
+    let end = 0;
+    let index = 0;
+    if (month >= 1 && month <= 3) {
+      index = 0
+    }
+    if (month >= 4 && month <= 6) {
+      index = 1
+    }
+    if (month >= 7 && month <= 9) {
+      index = 2
+    }
+    if (month >= 10 && month <= 12) {
+      index = 3
+    }
+    start = jiduArr[index][0] - 1;
+    end = jiduArr[index][1] - 1;
+    date.value.start = dayjs().month(start).startOf("month").format("YYYY-MM-DD");
+    date.value.end = dayjs().month(end).endOf("month").format("YYYY-MM-DD");
+  }
+  //上周
+  if (date.value.type == 4) {
+    date.value.start = dayjs()
+      .add(-1, "week").startOf("week")
+      .format("YYYY-MM-DD");
+    date.value.end = dayjs()
+      .add(-1, "week").startOf("week")
+      .endOf("week")
+      .format("YYYY-MM-DD");
+  }
+  //年
+  if (date.value.type == 5) {
+    date.value.start = dayjs().startOf("year").format("YYYY-MM-DD");
+    date.value.end = dayjs().endOf("year").format("YYYY-MM-DD");
+  }
+};
+
+//上一页
+const getPrevious = () => {
+  if (studentPage.value.current == 1) {
+    return false;
+  }
+  studentPage.value.current--;
+  getStudentList();
+  getStopPlaying();
+};
+
+//下一页
+const getNext = () => {
+  if (studentPage.value.current == studentPage.value.pages) {
+    return false;
+  }
+  studentPage.value.current++;
+  getStudentList();
+  getStopPlaying();
+};
+
+//计算页码
+const getPages = (data: any) => {
+  studentPage.value.pages = Math.ceil(data / studentPage.value.size);
+};
+
+//计算年级页码
+const getGradePages = (data: any, grade: any) => {
+  let index = gradeData.value.findIndex((item: any) => {
+    return item.value == grade;
+  })
+  gradeData.value[index].page.pages = Math.ceil(data / gradeData.value[index].page.size);
+};
+
+//更新时间
+const setDate = () => {
+  //currentDate.value = getDate();
+  setTimeout(setDate, 1000);
+};
+
+//查看详情
+const showPerson = (data: any) => {
+
+};
+
+//关闭弹窗
+const closePerson = () => {
+
+};
+
+/**
+ * 返回
+*/
+const confirmExit = () => {
+  router.go(-1);
+};
+
+onBeforeMount(() => {
+  const myInfo: any = localStorage.getItem("userInfo");
+  const userinfo = JSON.parse(myInfo)
+  logo.value = userinfo.avatar_url;
+  let obj: any = dataDictionary.gradeLists.find((item) => {
+    return item.value == userinfo.category;
+  })
+  gradeType.value = obj.child;
+  getClass();
+})
+
+onMounted(() => {
+  getTypeTime();
+  getProject();
+})
+
+onUnmounted(() => {
+  clearInterval(timer.value);
+  clearInterval(countDownTimer.value);
+})
+</script>
+
+<style lang="scss" scoped>
+html {
+  font-size: calc(100vw / 106);
+}
+
+ul,
+ol {
+  margin: 0;
+  padding: 0;
+}
+
+ul li {
+  list-style: none;
+}
+
+$waiPadding: 6.51rem;
+
+.ranking {
+  width: calc(100% - ($waiPadding * 2));
+  padding-top: 9rem;
+  margin: 0 auto;
+  display: flex;
+  flex-direction: column;
+
+  .top {
+    width: 100%;
+    color: #ffffff;
+    margin-bottom: 1vh;
+    display: flex;
+    justify-content: space-between;
+
+    .top-left {
+      display: flex;
+      align-items: flex-end;
+
+      .title1 {
+        font-size: 3.14rem;
+        line-height: 1;
+        color: #00FFE8;
+        margin-right: 1.49rem;
+
+      }
+
+      .title2 {
+        font-size: 1.65rem;
+        line-height: 1;
+        color: #F9F9F9;
+        padding-right: 2.2rem;
+        background: url("@/assets/images/ranking/arrow.png") right center no-repeat;
+        background-size: 1.5rem 1.1rem;
+        cursor: pointer;
+      }
+    }
+
+    .tab {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+
+      ul {
+        display: flex;
+        margin: 0;
+        margin-right: 20px;
+        border: 1px solid #E1E4E7;
+        border-radius: 2.3rem;
+        overflow: hidden;
+        box-sizing: border-box;
+
+        li {
+          height: 4.6vh;
+          line-height: 4.6vh;
+          padding: 0 20px;
+          font-size: 1.2rem;
+          color: #E1E4E7;
+          cursor: pointer;
+
+        }
+
+        .current {
+          color: #1A293A;
+          background: radial-gradient(239% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
+        }
+      }
+
+      dl {
+        display: flex;
+        margin: 0;
+        background: radial-gradient(96% 96% at 2% 32%, #FFFFFF 0%, #FCFDFD 54%, #E1E4E7 100%);
+        border-radius: 2.3vh;
+        height: 4.6vh;
+
+        dt {
+          height: 4.6vh;
+          line-height: 4.6vh;
+          padding: 0 25px;
+          border-radius: 2.3vh;
+          font-size: 1.2rem;
+          color: #1A293A;
+          cursor: pointer;
+        }
+
+        .current {
+          background: radial-gradient(239% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
+        }
+      }
+    }
+  }
+
+  .mainBox {
+    border-radius: 1.6rem;
+    background: linear-gradient(67deg, #092941 -85%, #2A484B 96%);
+    box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.3);
+
+    .main {
+      height: calc(80vh - 9rem);
+      display: flex;
+      flex-direction: column;
+      padding: 2vh 2vh 0 2vh;
+      box-sizing: border-box;
+
+      .main-a {
+        width: 100%;
+        height: 27vh;
+        position: relative;
+        margin-bottom: 2.5vh;
+        display: flex;
+
+        .main-a-center {
+          display: flex;
+          justify-content: space-around;
+          align-items: flex-end;
+          width: 100%;
+          box-sizing: border-box;
+
+          .item {
+            width: calc(100%/3 - 10px);
+            height: 100%;
+            color: #ffffff;
+            border-radius: 1.66rem;
+            box-sizing: border-box;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 1.9rem;
+            cursor: pointer;
+
+            .touxiang {
+              width: 16vh;
+              height: 16vh;
+              box-sizing: border-box;
+              border-radius: 50%;
+              background: #ffffff;
+              border: 5px solid rgba(26, 41, 58, 0.6315);
+              flex-shrink: 0;
+              margin-right: 15px;
+              position: relative;
+
+              img {
+                border-radius: 50%;
+                width: 100%;
+                height: 100%;
+                overflow: hidden;
+              }
+
+              &::before {
+                content: "";
+                width: 6vh;
+                height: 4vh;
+                display: flex;
+                position: absolute;
+                left: 50%;
+                margin-left: -3vh;
+                top: calc(-4vh - 5px);
+                background-size: 100% 100%;
+                background-position: center center;
+                background-repeat: no-repeat;
+                background-image: url("@/assets/images/ranking/mao.png");
+              }
+            }
+          }
+
+          .txt {
+            display: flex;
+            justify-content: space-between;
+            flex-direction: column;
+
+            .number {
+              color: #1A293A;
+              font-size: 5.35rem;
+              font-family: 'Saira-ExtraBold';
+              line-height: 1;
+              margin-bottom: 5px;
+            }
+
+            .studentName {
+              display: block;
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              line-height: 1;
+              text-align: center;
+              border-radius: 3rem;
+              padding: 0.5rem 0;
+              background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.6571) 100%);
+              color: #1A293A;
+              box-sizing: border-box;
+              border: 1px solid #FFFFFF;
+              margin-bottom: 5px;
+            }
+
+            .scoreBox {
+              display: flex;
+              line-height: 1;
+              align-items: center;
+              justify-content: center;
+              color: #1A293A;
+
+              .score {
+                font-size: 3.53rem;
+                font-family: 'Saira-ExtraBold';
+              }
+
+              .unit {
+                font-size: 2rem;
+                margin-left: 4px;
+              }
+            }
+          }
+        }
+
+        .one {
+          background: radial-gradient(87% 129% at 96% 5%, #FAFF28 0%, #FFDC22 100%);
+        }
+
+        .two {
+          background: radial-gradient(66% 97% at 96% 5%, #61FFC7 0%, #8BFF69 100%);
+        }
+
+        .three {
+          background: radial-gradient(65% 96% at 96% 5%, #7BFFF1 0%, #67FFC6 100%);
+        }
+      }
+    }
+
+    .main-b {
+      width: 100%;
+      height: 40vh;
+      position: relative;
+      display: flex;
+
+      .main-b-center {
+        width: 100%;
+        height: 100%;
+        padding: 0px;
+        box-sizing: border-box;
+        display: flex;
+
+        .columns {
+          height: 100%;
+          width: calc(100% / 3);
+          flex: 1;
+          box-sizing: border-box;
+          padding: 0px 1.8rem;
+          display: flex;
+          border-right: 1.5px solid #48677E;
+          flex-shrink: 0;
+
+          &:last-child {
+            border: none;
+          }
+
+          ul {
+            width: 100%;
+
+            li {
+              height: 20%;
+              color: #ffffff;
+              font-size: 1.6rem;
+              overflow: hidden;
+              display: flex;
+              align-items: center;
+              cursor: pointer;
+              border-bottom: 1px solid #979797;
+              box-sizing: border-box;
+
+              .txt {
+                width: 100%;
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+
+
+                i {
+                  font-size: 1.65rem;
+                  min-width: 2.5rem;
+                  margin-right: 1.5rem;
+                  font-style: normal;
+                  text-align: center;
+                  color: #13ED84;
+                  font-family: 'Saira-ExtraBold';
+                }
+
+                .studentName {
+                  max-width: 20rem;
+                  font-size: 1.65rem;
+                  color: #F9F9F9;
+                  display: block;
+                  white-space: nowrap;
+                  overflow: hidden;
+                  text-overflow: ellipsis;
+                  flex: 1;
+                }
+
+                .right {
+                  display: flex;
+                  line-height: 1;
+                  align-items: center;
+                  justify-content: center;
+                  color: #F9F9F9;
+
+                  .score {
+                    font-size: 1.3rem;
+                    font-family: 'Saira-ExtraBold';
+                  }
+
+                  .unit {
+                    font-size: 0.8rem;
+                    margin-left: 4px;
+                  }
+                }
+              }
+
+              &:last-child {
+                border: none
+              }
+            }
+          }
+        }
+      }
+
+      .btn-left {
+        cursor: pointer;
+        width: 20px;
+        height: 60px;
+        margin-left: 0px;
+        background: url("@/assets/images/ranking/btn-left.png") center center no-repeat;
+        background-size: 15px 29px;
+        flex-shrink: 0;
+        position: absolute;
+        left: 0;
+        top: 50%;
+        margin-top: -30px;
+      }
+
+      .btn-right {
+        cursor: pointer;
+        width: 20px;
+        height: 60px;
+        margin-right: 0px;
+        background: url("@/assets/images/ranking/btn-right.png") center center no-repeat;
+        background-size: 15px 29px;
+        flex-shrink: 0;
+        position: absolute;
+        right: 0;
+        top: 50%;
+        margin-top: -30px;
+      }
+
+
+    }
+
+    .swiperBox {
+      width: 100%;
+
+      .item {
+        .gradeTitle {
+          height: 6vh;
+          line-height: 6vh;
+          width: 100%;
+          text-align: center;
+          color: #1A293A;
+          font-size: 1.65rem;
+          background: radial-gradient(120% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
+          border-top-left-radius: 1.6rem;
+          border-top-right-radius: 1.6rem;
+        }
+
+        ul {
+          height: calc(80vh - 9rem - 2vh - 6vh);
+          margin-bottom: 0.5vh;
+          overflow-y: scroll;
+          overflow-x: hidden;
+          border-left: 1px solid #48677E;
+          border-right: 1px solid #48677E;
+          box-sizing: border-box;
+
+          li {
+            * {
+              pointer-events: none;
+            }
+
+            height: 8.2vh;
+            display: flex;
+            align-items: center;
+            padding: 0px 30px;
+            color: #ffffff;
+            justify-content: space-between;
+            cursor: pointer;
+            border-bottom: 1px solid #48677E;
+
+            .left {
+              display: flex;
+
+              i {
+                font-size: 1.1rem;
+                min-width: 2.5rem;
+                margin-right: 1rem;
+                font-style: normal;
+                text-align: center;
+                color: #13ED84;
+                font-family: 'Saira-ExtraBold';
+              }
+
+
+              .pai {
+                width: 3.5rem;
+                height: 2.5rem;
+                box-sizing: border-box;
+                padding-top: 0.9rem;
+                color: #FFFFFF;
+              }
+
+              .pai1 {
+                background: url("@/assets/images/ranking/pai1.png") left center no-repeat;
+                background-size: 100% 100%;
+              }
+
+              .pai2 {
+                background: url("@/assets/images/ranking/pai2.png") left center no-repeat;
+                background-size: 100% 100%;
+              }
+
+              .pai3 {
+                background: url("@/assets/images/ranking/pai3.png") left center no-repeat;
+                background-size: 100% 100%;
+              }
+
+              .userInfo {
+                display: flex;
+
+                .touxiang {
+                  width: 6vh;
+                  height: 6vh;
+                  box-sizing: border-box;
+                  border-radius: 50%;
+                  background: #ffffff;
+                  margin-left: 10px;
+                  margin-right: 13px;
+
+                  img {
+                    border-radius: 50%;
+                    width: 100%;
+                    height: 100%;
+                    overflow: hidden;
+                  }
+                }
+
+                .nameBox {
+                  display: flex;
+                  text-align: left;
+                  flex-direction: column;
+
+                  .studentName {
+                    color: #F9F9F9;
+                    font-size: 1rem;
+                    margin-bottom: 0.5vh;
+                  }
+
+                  .className {
+                    font-size: 0.8rem;
+                    color: #13ED84;
+                  }
+                }
+              }
+
+            }
+
+            .right {
+              display: flex;
+              line-height: 1;
+              align-items: center;
+              justify-content: center;
+              color: #F9F9F9;
+
+              .score {
+                font-size: 1.3rem;
+                font-family: 'Saira-ExtraBold';
+              }
+
+              .unit {
+                font-size: 0.8rem;
+                margin-left: 4px;
+              }
+            }
+
+          }
+
+          &::-webkit-scrollbar {
+            width: 8px;
+          }
+
+          &::-webkit-scrollbar-thumb {
+            border-width: 2px;
+            border-radius: 4px;
+            border-style: dashed;
+            border-color: transparent;
+            background: rgb(27, 72, 92);
+            background-clip: padding-box;
+          }
+
+          &::-webkit-scrollbar-button:hover {
+            border-radius: 5px;
+            background: rgba(26, 62, 78, 1);
+          }
+        }
+      }
+    }
+
+    .noData {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      flex-direction: column;
+      font-size: 1rem;
+      color: #ffffff;
+      text-align: center;
+      margin: 0 auto;
+
+      img {
+        max-width: 70%;
+        margin-bottom: 10px;
+      }
+
+      span {
+        display: block;
+      }
+    }
+
+    .swiper-btn-left {
+      width: 1.7rem;
+      height: 2.2rem;
+      display: block;
+      background: url("~@/assets/images/ranking/btn-left2.png") left center no-repeat;
+      background-size: 100% 100%;
+
+      &::after {
+        display: none;
+      }
+    }
+
+    .swiper-btn-right {
+      width: 1.7rem;
+      height: 2.2rem;
+      display: block;
+      background: url("~@/assets/images/ranking/btn-right2.png") left center no-repeat;
+      background-size: 100% 100%;
+
+      &::after {
+        display: none;
+      }
+    }
+
+  }
+
+  .footer {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    border-top: 1px solid #979797;
+    overflow: hidden;
+    box-sizing: border-box;
+    padding: 0 2vh;
+
+    .tab {
+      width: 100%;
+      padding-top: 1.5rem;
+
+      ul {
+        display: flex;
+        padding-bottom: 0.1rem;
+        overflow-x: scroll;
+
+        li {
+          height: 4.6vh;
+          line-height: 4.6vh;
+          padding: 0 20px;
+          font-size: 1.2rem;
+          color: #F9F9F9;
+          margin: 0 0.6rem;
+          border-radius: 2.3vh;
+          cursor: pointer;
+          flex-shrink: 0;
+
+          &:hover {
+            background: #00FFE8;
+            color: #1A293A;
+          }
+        }
+
+        .current {
+          background: #00FFE8;
+          color: #1A293A;
+        }
+
+        &::-webkit-scrollbar {
+          width: 6px;
+
+        }
+
+        &::-webkit-scrollbar-thumb {
+          border-radius: 3px;
+          border-style: dashed;
+          border-color: transparent;
+          background: rgb(27, 72, 92);
+          background-clip: padding-box;
+        }
+
+        &::-webkit-scrollbar-button:hover {
+          border-radius: 3px;
+          background: rgba(26, 62, 78, 1);
+        }
+
+      }
+    }
+  }
+}
+
+
+.choiceClass {
+  width: calc(100% - ($waiPadding * 2));
+  position: absolute;
+  z-index: 2;
+  top: 10vh;
+  left: var($waiPadding);
+  background: rgba(11, 29, 39, 0.9);
+  border-radius: 10px;
+  padding: 20px;
+  box-sizing: border-box;
+  box-shadow: rgba(57, 187, 187, 0.48) 0px 0px 10px 10px inset;
+  border: 2px solid rgb(57, 187, 187);
+
+  .choiceClass-content {
+    color: #ffffff;
+    display: flex;
+    justify-content: space-around;
+
+    .classTitle {
+      font-size: 1.4rem;
+      margin-bottom: 20px;
+    }
+
+    ul {
+      height: 67vh;
+      margin-bottom: 2vh;
+      overflow-y: scroll;
+
+      li {
+        font-size: 1.2rem;
+        padding: 10px 0;
+        cursor: pointer;
+
+        &:hover {
+          color: #0936a3;
+        }
+      }
+
+      &::-webkit-scrollbar {
+        width: 10px;
+      }
+
+      &::-webkit-scrollbar-thumb {
+        border-width: 2px;
+        border-radius: 4px;
+        border-style: dashed;
+        border-color: transparent;
+        background-color: rgba(26, 62, 78, 0.5);
+        background-clip: padding-box;
+      }
+
+      &::-webkit-scrollbar-button:hover {
+        border-radius: 6px;
+        background: rgba(26, 62, 78, 1);
+      }
+    }
+  }
+
+
+  .choiceClass-btn-box {
+    display: flex;
+    justify-content: center;
+
+    .choiceClass-btn {
+      margin: 0 15px;
+      text-align: center;
+      width: 100px;
+      background: #39bbbb;
+      height: 35px;
+      line-height: 35px;
+      color: #fff;
+      cursor: pointer;
+    }
+
+    .choiceClass-btn-all {
+      background: rgba(13, 90, 245, 0.5);
+    }
+  }
+}
+
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.5s;
+}
+
+.fade-enter,
+.fade-leave-to
+
+/* .fade-leave-active below version 2.1.8 */
+  {
+  opacity: 0;
+}
+</style>

+ 5 - 3
src/views/train/run.vue

@@ -8,7 +8,7 @@
     </transition>
     <div class="main">
       <template v-if="isLongRun">
-        <swiper :slides-per-view="2" :space-between="20">
+        <swiper :slides-per-view="2" :slides-per-group="2" :space-between="20">
           <swiper-slide v-for="(items, indexs) in testListArr " :key="indexs">
             <div class="main-left main-left2">
               <div class="trackItem">
@@ -454,7 +454,7 @@ const getClearTimer = (data?: any) => {
 */
 const getChooseStudent = (track: number) => {
   if (examState.value < 41) {
-    proxy?.$modal.msgWarning("请点击开始人脸识别");
+    proxy?.$modal.msgWarning("请点击开始识别");
     return false;
   }
   if (examState.value == 43) {
@@ -488,7 +488,9 @@ const returnStudent = (data: any) => {
     return currentTrack.value == item.track;
   })
   faceStudentList.value[newIndex] = { ...faceStudentList.value[newIndex], ...obj };
-  speckText(`第${currentTrack.value == 2 ? '二' : currentTrack.value}道, ${data.name}`);
+  if (!isLongRun.value) {
+    speckText(`第${currentTrack.value == 2 ? '二' : currentTrack.value}道, ${data.name}`);
+  }
   currentTrack.value = null;
 };
 

+ 1 - 7
src/views/train/test.vue

@@ -118,7 +118,7 @@
               </div>
             </div>
             <div class="right" v-if="['basketballv1'].includes(parameter.project)">
-              <div class="score">{{ proxy?.$utils.runTime(item.result, true, 1) }}
+              <div class="score">{{ proxy?.$utils.runTime(item.result, true, false) }}
               </div>
             </div>
             <div class="right" v-else>
@@ -1262,11 +1262,5 @@ $waiPadding: 6.51rem;
       }
     }
   }
-
-
-}
-
-.chengji {
-  font-family: "Saira Black";
 }
 </style>