林旭祥 před 3 týdny
rodič
revize
4bfb396978

+ 10 - 0
src/api/module/common.ts

@@ -205,4 +205,14 @@ export default {
       data: data
     });
   },
+
+  //获取学生成绩
+  studentReport: (data: any) => {
+    return req({
+      url: '/report/index',
+      method: 'get',
+      data: data
+    });
+  },
+
 };

binární
src/assets/images/common/back.png


binární
src/assets/images/common/xian.png


+ 1 - 0
src/router/index.ts

@@ -32,6 +32,7 @@ const router = createRouter({
         { path: '/sunshineRun', component: () => import('@/views/sunshineRun/index.vue') },
         { path: '/game', component: () => import('@/views/game/index.vue') },
         { path: '/game/square', component: () => import('@/views/game/square.vue') },
+        { path: '/score', component: () => import('@/views/score/index.vue') },
       ]
     }
   ]

+ 13 - 7
src/views/analysis/components/run.vue

@@ -260,10 +260,8 @@ const stepsChart = () => {
   }, 200);
 };
 
-
-onBeforeMount(() => {
-  query.value = route.query;
-  details.value = JSON.parse(JSON.stringify(props.detailsData));
+//初始化
+const getInitialize = () => {
   let typeLists = [];
   let speedLists = [];
   let strideLists = [];
@@ -298,12 +296,20 @@ onBeforeMount(() => {
   strideList.value = strideLists;
   stepsList.value = stepsLists;
   fullAvgRateList.value = fullAvgRateLists;
+};
+
+onBeforeMount(() => {
+  query.value = route.query;
+  details.value = JSON.parse(JSON.stringify(props.detailsData));
+  // if (['runa800', 'runa1000', 'runwb800', 'runwb1000'].includes(query.value.exam_name)) {
+	// 	getInitialize();
+	// }
 })
 
 onMounted(() => {
-  speedChart();
-  strideChart();
-  stepsChart();
+  // speedChart();
+  // strideChart();
+  // stepsChart();
 })
 </script>
 

+ 8 - 4
src/views/analysis/components/runa.vue

@@ -312,10 +312,8 @@ const stepsChart = () => {
   }, 200);
 };
 
-
-onBeforeMount(() => {
-  query.value = route.query;
-  details.value = JSON.parse(JSON.stringify(props.detailsData));
+//初始化
+const getInitialize = () => {
   let typeLists = [];
   let speedLists = [];
   let strideLists = [];
@@ -350,6 +348,12 @@ onBeforeMount(() => {
   strideList.value = strideLists;
   stepsList.value = stepsLists;
   fullAvgRateList.value = fullAvgRateLists;
+};
+
+onBeforeMount(() => {
+  query.value = route.query;
+  details.value = JSON.parse(JSON.stringify(props.detailsData));
+  getInitialize();
 })
 
 onMounted(() => {

+ 83 - 26
src/views/analysis/detail.vue

@@ -1,5 +1,8 @@
 <template>
   <div class="main">
+    <view class="back" @click="getBack" style="background: #efefef;">
+      <view class="backBtn">返回</view>
+    </view>
     <div class="main-a">
       <div class="main-a-title">
         <div class="project">{{ details.examsName }}</div>
@@ -30,12 +33,12 @@
               src="@/assets/images/analysis/run1000.png" />
             <img v-if="query.exam_name == 'basketball' ||
               query.exam_name == 'basketballv1'
-              " src="@/assets/images/analysis/basketball.png" />
+            " src="@/assets/images/analysis/basketball.png" />
             <img v-if="query.exam_name == 'football' || query.exam_name == 'footballv1'
-              " src="@/assets/images/analysis/football.png" />
+            " src="@/assets/images/analysis/football.png" />
             <img v-if="query.exam_name == 'badminton' ||
               query.exam_name == 'badmintonv1'
-              " src="@/assets/images/analysis/badminton.png" />
+            " src="@/assets/images/analysis/badminton.png" />
             <img v-if="query.exam_name == 'pingpong'" src="@/assets/images/analysis/pingpong.png" />
             <img v-if="query.exam_name == 'volleyball'" src="@/assets/images/analysis/volleyball.png" />
             <img v-if="query.exam_name == 'volleyballv1'" src="@/assets/images/analysis/volleyball.png" />
@@ -46,6 +49,7 @@
             <img v-if="query.exam_name == 'jumpingjack'" src="@/assets/images/analysis/jumpingjack.png" />
             <img v-if="query.exam_name == 'highknees'" src="@/assets/images/analysis/highknees.png" />
             <img v-if="query.exam_name == 'longjump'" src="@/assets/images/analysis/longjump.png" />
+            <img v-if="query.exam_name == 'skiprope'" src="@/assets/images/analysis/skiprope.png" />
             <div class="svg-box" v-if="details.score">
               <svg class="svg" width="100%" height="100%" viewBox="0 0 400 400">
                 <!-- 1圈 -->
@@ -86,12 +90,12 @@
             width:
               (details.std.scores[1] - details.std.scores[0]) * 100 + '%',
           }">及格</span><span class="c" :style="{
-  width:
-    (details.std.scores[2] - details.std.scores[1]) * 100 + '%',
-}">良好</span><span class="d" :style="{
-  width:
-    (details.std.scores[3] - details.std.scores[2]) * 100 + '%',
-}">优秀</span>
+            width:
+              (details.std.scores[2] - details.std.scores[1]) * 100 + '%',
+          }">良好</span><span class="d" :style="{
+            width:
+              (details.std.scores[3] - details.std.scores[2]) * 100 + '%',
+          }">优秀</span>
         </div>
         <div class="drawingItem" v-else>
           <span class="a">不及格</span><span class="b">及格</span><span class="c">良好</span><span class="d">优秀</span>
@@ -153,30 +157,30 @@
     <div class="main-c" v-if="JSON.stringify(details) != '{}'">
       <!--立定跳远-->
       <Jump :detailsData="details" v-if="JSON.stringify(details) != '{}' && ['jump'].includes(query.exam_name)
-        " />
+      " />
       <!--实心球-->
       <SolidBall :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['solidball'].includes(query.exam_name)
-        " />
+      " />
       <!--脚环跑步-->
       <Runa :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
-        ['runa800', 'runa1000'].includes(query.exam_name)
-        " />
+        ['runa800', 'runa1000', 'runwb800', 'runwb1000'].includes(query.exam_name)
+      " />
       <!--跑步-->
       <Run :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['run50', 'run60', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8'].includes(query.exam_name)
-        " />
+      " />
       <!--仰卧起坐-->
       <SitUp :detailsData="details" v-if="JSON.stringify(details) != '{}' && ['situp'].includes(query.exam_name)
-        " />
+      " />
       <!--引体向上-->
       <PullUp :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['pullup'].includes(query.exam_name)
-        " />
+      " />
       <!--跳绳类-->
       <RopeSkipping :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['jumprope', 'jumpingjack', 'highknees', 'skiprope'].includes(query.exam_name)
-        " />
+      " />
       <!--球类-->
       <Balls :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         [
@@ -190,21 +194,21 @@
           'badminton',
           'pingpong',
         ].includes(query.exam_name)
-        " />
+      " />
       <!--斜身引体-->
       <SidePullUp :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['sidepullup'].includes(query.exam_name)
-        " />
+      " />
       <!--三级蛙跳-->
       <TriJump :detailsData="details" v-if="JSON.stringify(details) != '{}' && ['trijump'].includes(query.exam_name)
-        " />
+      " />
       <!--铅球-->
       <ShotPut :detailsData="details" v-if="JSON.stringify(details) != '{}' &&
         ['shotput'].includes(query.exam_name)
-        " />
+      " />
       <!--急行跳远-->
       <LongJump :detailsData="details" v-if="JSON.stringify(details) != '{}' && ['longjump'].includes(query.exam_name)
-        " />
+      " />
       <div class="tip">
         <!-- 温馨提示:<br />
         因为光线或人员遮挡等环境问题,导致测试数据偶尔有偏差,最终解释权归卓浦士科技所有。<br />客服热线:<a
@@ -229,9 +233,10 @@ import RopeSkipping from "./components/ropeSkipping.vue";
 import SidePullUp from "./components/sidePullUp.vue";
 import TriJump from "./components/triJump.vue";
 import ShotPut from "./components/shotPut.vue";
+const { proxy } = getCurrentInstance() as any;
+const router = useRouter();
 const route = useRoute();
 const dic: any = dataDictionary;
-const { proxy } = getCurrentInstance() as any;
 const data = reactive<any>({
   query: {},
   details: {},
@@ -254,7 +259,12 @@ const getTestExamDetails = () => {
       details.value = res.data || {};
       getDetails();
     })
-    .catch(() => { });
+    .catch(() => {
+      proxy?.$modal.msgWarning('无效报告');
+      setTimeout(() => {
+        getBack();
+      }, 1500)
+    });
 };
 
 /**
@@ -272,7 +282,12 @@ const getTrainExamDetails = () => {
       details.value = res.data || {};
       getDetails();
     })
-    .catch(() => { });
+    .catch(() => {
+      proxy?.$modal.msgWarning('无效报告');
+      setTimeout(() => {
+        getBack();
+      }, 1500)
+    });
 };
 
 /**
@@ -332,6 +347,11 @@ const getDetails = () => {
   }
 };
 
+//返回
+const getBack = () => {
+  router.go(-1);
+};
+
 onBeforeMount(() => {
   query.value = route.query;
   if (query.value.test_key) {
@@ -357,8 +377,45 @@ onMounted(() => {
 
 .main {
   background: #efefef;
-  height: 100vh;
+  height: calc(100vh - 10vh - 20px);
   overflow-y: scroll;
+  overflow-x: hidden;
+	padding-bottom: 20px;
+	padding-top: 10vh;
+
+  .back {
+	position: fixed;
+	top: 0;
+	width: 100%;
+	height: 10vh;
+	line-height: 10vh;
+	display: flex;
+	align-items: center;
+	justify-content: flex-start;
+	box-sizing: border-box;
+	padding: 0 1.5rem;
+	cursor: pointer;
+	z-index: 2;
+}
+
+  .back::before {
+    content: "";
+    width: 100%;
+    height: 0.4vw;
+    position: absolute;
+    bottom: 0px;
+    left: 0;
+    background: url("@/assets/images/common/xian.png") center bottom no-repeat;
+    background-size: 100% 100%;
+  }
+
+  .backBtn {
+    font-size: 3.8vh;
+    color: #97d4a4;
+    padding-left: calc(2vh + 24px);
+    background: url("@/assets/images/common/back.png") left center no-repeat;
+    background-size: 2vh 3.8vh;
+  }
 
   .main-a {
     padding: 1.5rem 1.5rem 0 1.5rem;

+ 368 - 0
src/views/score/index.vue

@@ -0,0 +1,368 @@
+<template>
+  <div class="result bg">
+    <div class="resultMain">
+      <div class="resultCenter">
+        <div class="top">
+          <div class="topLeft">
+            <div class="pic">
+              <img class="image" :src="parameter.pic ? parameter.pic : '../../static/images/train/noImg.png'"></img>
+            </div>
+            <div class="name">{{ parameter.name }}</div>
+          </div>
+        </div>
+        <div class="bottom">
+          <div class="type">
+            <div class="li more">
+              <el-select class="select" v-model="project" :popper-append-to-body="false" placeholder="请选择"
+                @change="getProject" clearable>
+                <el-option v-for="item in projectList" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </div>
+            <div class="li"> 成绩 </div>
+            <div class="li more"> 日期 </div>
+            <div class="li"> 报告 </div>
+          </div>
+          <div class="list">
+            <div ref="scrollRef" @scroll="getNext" class="scrollBox">
+              <div class="ul" v-for="(item, index) in reportList" :key="index">
+                <div class="li"> {{ item.title }} </div>
+                <div class="li"> {{ item.result }} </div>
+                <div class="li date"> {{ item.date }} </div>
+                <div class="li url" @click="openReport(item)"> 查看 </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div @click="getBack" class="btn">退 出</div>
+    </div>
+  </div>
+</template>
+<script setup lang="ts">
+import dayjs from 'dayjs';
+import dataDictionary from '@/utils/dataDictionary';
+const scrollRef = ref();
+const { proxy } = getCurrentInstance() as any;
+const router = useRouter();
+const route = useRoute();
+const dic: any = dataDictionary;
+const data = reactive<any>({
+  parameter: {
+    id: 0,
+    name: "",
+    student_number: "",
+    pic: "",
+  },
+  reportList: [],
+  page: {
+    current: 1,
+    size: 30,
+    pages: 1,
+  },
+  projectList: [{
+    label: "项目",
+    value: null,
+  },],
+  project: '',
+  date: "",
+});
+
+const { parameter, reportList, page, projectList, project, date } = toRefs(data);
+
+//筛选日期
+const bindDateChange = (e: any) => {
+  date.value = e.detail.value;
+  getListData();
+};
+
+//取消选择日期
+const bindDateCancel = () => {
+  date.value = "";
+  getListData();
+};
+
+//筛选项目
+const getProject = (e: any) => {
+  getListData();
+};
+
+//初始数据
+const getListData = () => {
+  //返回的时候重新请求更多页码数据
+  if (page.value.current > 1) {
+    page.value.size = page.value.size * page.value.current;
+  }
+  page.value.current = 1; //页面初始化
+  getReportList(); //获取数据
+};
+
+//成绩列表
+const getReportList = () => {
+  if (!parameter.value.id) {
+    return false;
+  }
+  let myInfo: any = localStorage.getItem('userInfo');
+  let userInfo = JSON.parse(myInfo);
+  let params: any = {
+    school_id: userInfo.school_id,
+    student_ids: parameter.value.id,
+    page: page.value.current,
+    per_page: page.value.size,
+  };
+  if (project.value) {
+    params.exam_name = project.value;
+  }
+  if (date.value == "") {
+    params.start_date = "2021-01-01";
+    delete params.end_date;
+  } else {
+    params.start_date = date.value;
+    params.end_date = date.value;
+  }
+  proxy?.$http.common.studentReport(params).then((res: any) => {
+    if (res.status == 200) {
+      let list = res.data.map((item: any) => {
+        item.title = dic.project[item.exam_name];
+        let result = null;
+        if (["trijump", "solidball", "shotput", "longjump"].includes(item.exam_name)) {
+          result = (Math.round(item.result) / 100).toFixed(2);
+        } else if (["basketballv1", "footballv1"].includes(item.exam_name)) {
+          result = proxy?.$utils.runTime(item.result, true, false);
+        } else {
+          result = item.result;
+        }
+        if (['run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'runwb800', 'runwb1000'].includes(item.exam_name)) {
+          item.result = proxy?.$utils.runTime(item.result, false, false);
+        } else {
+          item.result = result + dic.unit[item.exam_name];
+        }
+        item.date = dayjs.unix(item.ctime).format("YYYY-MM-DD");
+        return item;
+      });
+      page.value.current == 1 ?
+        (reportList.value = list) :
+        reportList.value.push(...list);
+      getPages(res.total);
+    }
+  });
+};
+
+//测试报告
+const openReport = (data: any) => {
+  let result_ids = data.result_id;
+  let exam_name = data.exam_name;
+  let student_id = data.student_id;
+  if (!result_ids || !exam_name) {
+    proxy?.$modal.msgWarning('缺少参数');
+    return false;
+  }
+  let obj = {
+    result_ids: result_ids,
+    exam_name: exam_name,
+    student_id: student_id
+  }
+  router.push({ path: '/analysis/detail', query: obj });
+};
+
+//下一页
+const getNext = () => {
+  if (page.value.current == page.value.pages) {
+    return false;
+  }
+  page.value.current++;
+  getReportList();
+};
+
+//计算页码
+const getPages = (data: any) => {
+  page.value.pages = Math.ceil(data / page.value.size);
+};
+
+//返回
+const getBack = () => {
+  router.go(-1);
+};
+
+onBeforeMount(() => {
+  parameter.value = route.query;
+  //重组项目为数组
+  for (let i in dic.project) {
+    projectList.value.push({
+      label: dic.project[i],
+      value: i,
+    })
+  }
+  getListData();
+});
+
+onMounted(() => {
+
+});
+</script>
+<style lang="scss">
+.result {
+  min-height: 100vh;
+}
+
+.resultMain {
+  padding-top: 6vh;
+}
+
+.resultCenter {
+  width: 90%;
+  height: 80vh;
+  background: #ffffff;
+  border-radius: 25px;
+  margin: 0 auto 2vh;
+  box-shadow: 0 0 15px #ffffff80;
+  overflow: hidden;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+}
+
+.top {
+  width: 100%;
+  height: 12vh;
+  background-color: #b0ffac;
+  background-image: url("~@/static/images/home/btnbg2.png");
+  background-size: 100% 100%;
+  background-repeat: repeat;
+  display: flex;
+  align-items: center;
+}
+
+.top .topLeft {
+  display: flex;
+  align-items: center;
+  padding: 0 15px;
+}
+
+.top .topLeft .pic {
+  width: 8vh;
+  height: 8vh;
+  overflow: hidden;
+  border-radius: 50%;
+  border: 2px solid #ffffff;
+}
+
+.top .topLeft .pic .image {
+  width: 100%;
+  height: 100%;
+}
+
+.top .topLeft .name {
+  font-size: 3.2vh;
+  color: #fff;
+  margin-left: 3vw;
+}
+
+.bottom {
+  display: flex;
+  flex-direction: column;
+  height: calc(100% - 12vh);
+}
+
+.type {
+  height: 5vh;
+  display: flex;
+  text-align: center;
+  background: #f3f3f3;
+  color: #63cacc;
+  font-size: 2vh;
+  padding: 0 4px;
+}
+
+.type .li {
+  width: 25%;
+  padding: 8px 3px;
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.type .more::before {
+  content: "";
+  width: 0;
+  height: 0;
+  display: block;
+  border: 0.7vh;
+  border-style: solid;
+  border-color: #63cacc transparent transparent transparent;
+  margin-top: 0.8vh;
+  margin-right: 2px;
+}
+
+
+.list {
+  text-align: center;
+  font-size: 2vh;
+  padding: 0 4px;
+  height: calc(100% - 5vh);
+}
+
+.list .ul {
+  display: flex;
+}
+
+.list .ul .li {
+  width: 25%;
+  padding: 8px 3px;
+  flex: 1;
+  word-break: break-all;
+  flex-direction: column;
+}
+
+.list .ul .date {
+  font-size: 1.8vh;
+}
+
+.list .ul .url {
+  color: #90dba4;
+}
+
+.type .li:nth-of-type(1),
+.list .ul .li:nth-of-type(1) {
+  flex-grow: 1;
+}
+
+.type .li:nth-of-type(2),
+.list .ul .li:nth-of-type(2) {
+  flex-grow: 1.4;
+}
+
+.type .li:nth-of-type(3),
+.list .ul .li:nth-of-type(3) {
+  flex-grow: 1.4;
+}
+
+.type .li:nth-of-type(4),
+.list .ul .li:nth-of-type(4) {
+  flex-grow: 1;
+}
+
+.type .li:nth-of-type(5),
+.list .ul .li:nth-of-type(5) {
+  flex-grow: 0.7;
+}
+
+.scrollBox {
+  height: 98%;
+}
+
+.btn {
+  width: 90%;
+  height: 7vh;
+  line-height: 7vh;
+  text-align: center;
+  color: #fff;
+  font-size: 2.2vh;
+  margin: 0 auto;
+  background: url("~@/static/images/train/areabg2.png") center center repeat-y;
+  background-size: 100% 100%;
+  border-radius: 2.1vh;
+  box-shadow: 0px 0px 15px #ffffff80;
+  cursor: pointer;
+}
+</style>