update:体测报告&课堂报告

This commit is contained in:
ltx 2026-05-28 16:40:52 +08:00
parent 2c4e90559e
commit a95d5b1e90
7 changed files with 395 additions and 1099 deletions

View File

@ -14,9 +14,9 @@ let loadingStatus = false;
console.log(process.env.NODE_ENV, 'process.env.NODE_ENV')
if (process.env.NODE_ENV == 'development') {
// axios.defaults.baseURL = 'http://101.132.164.149:9991/';
// axios.defaults.baseURL = 'http://8.153.108.90:9991/'; //测试(直连会触发 CORS,改用 Vite proxy)
axios.defaults.baseURL = 'http://8.153.108.90:9991/'; //测试(直连会触发 CORS,改用 Vite proxy)
// axios.defaults.baseURL = '/dev-api/'; //测试(通过 Vite 代理转发,避免 CORS)
axios.defaults.baseURL = 'https://smartsports.yuedongsports.com/'; //正式
// axios.defaults.baseURL = 'https://smartsports.yuedongsports.com/'; //正式
// axios.defaults.baseURL = 'http://192.168.0.146:9991/'; //汤龙本地
// axios.defaults.baseURL = 'http://47.101.60.251:9991/';
// axios.defaults.baseURL = 'http://localhost:9991/';

View File

@ -305,8 +305,21 @@ const studentKey = ref(0)
const studentList = ref([])
const studentListLoading = ref(false)
function switchTab(tab: string) {
async function switchTab(tab: string) {
activeTab.value = tab
if (tab === 'grade') {
await nextTick()
if (!loading.value.stats) {
averageBar(data.value.averageBarData)
classBar(data.value.classBarData)
}
if (!loading.value.level) {
levelChart(data.value.levelChartData)
}
if (!loading.value.trend) {
trendEcharts(data.value.chartsData3)
}
}
}
async function onGradeTabChange(val: any) {
@ -1953,7 +1966,7 @@ function toViewStudentDetail(val) {
// ──── 嵌入子报告 ────
.embeddedReport {
width: 100%;
margin-top: 0 !important;
// margin-top: 0 !important;
// 重置子组件外边距,让它与当前页风格一致
:deep(.workOrder),
:deep(.StudentDataStatistics) {

View File

@ -1,14 +1,5 @@
<template>
<template>
<div class="StudentDataStatistics">
<div class="ipt">
<div class="one">
<p>展示数据:</p>
<el-select v-model="data.selectData" placeholder="Select" style="width: 240px">
<el-option v-for="item in data.selectOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
</div>
<div class="top">
<div class="left">
<div class="leftImg">
@ -35,9 +26,7 @@
<div class="title">
<p>近5节课心率变化</p>
</div>
<div class="heartChange" id="heartChange">
</div>
<div id="heartChange"></div>
</div>
</div>
<div class="cont1">
@ -45,21 +34,19 @@
<div class="title">
<div class="head">
<div class="left">
<p>个人成绩趋势</p>
</div>
<div class="right">
<span>项目:</span>
<el-select v-model="data.trendProject" placeholder="请选择" style="width: 240px"
<el-select v-model="data.trendProject" placeholder="请选择" style="width: 200px"
@change="changeTrendProject">
<el-option v-for="item in data.projectData" :key="item.categoryId"
:label="item.categoryName" :value="item.categoryId" />
</el-select>
</div>
</div>
<div class="barChart" id="barChart">
</div>
</div>
<div id="barChart"></div>
</div>
<div class="cont1Right">
<div class="title">
@ -69,17 +56,15 @@
</div>
<div class="right">
<span>项目:</span>
<el-select v-model="data.personal" placeholder="请选择" style="width: 240px"
<el-select v-model="data.personal" placeholder="请选择" style="width: 200px"
@change="changePersonal">
<el-option v-for="item in data.projectData" :key="item.categoryId"
:label="item.categoryName" :value="item.categoryId" />
</el-select>
</div>
</div>
<div class="levelbarChart" id="levelbarChart">
</div>
</div>
<div id="levelbarChart"></div>
</div>
</div>
<div class="cont3">
@ -127,7 +112,7 @@
</template>
<script lang="ts" setup>
import { ref, onMounted, computed, onBeforeUnmount, markRaw } from 'vue';
import { ref, onMounted, computed, onBeforeUnmount, markRaw, nextTick } from 'vue';
import * as echarts from 'echarts';
import * as _api from '@/api/grade.js'
import { useRoute } from 'vue-router';
@ -342,6 +327,7 @@ async function initApi(val) {
data.value.heartChangeData.ChartCont.xData.push(i)
data.value.heartChangeData.ChartCont.seriesData.push(res.data.heartRateData[i])
}
await nextTick()
heartEcharts(data.value.heartChangeData)
data.value.personalgradeData.xData = res.data.testResultCompare.axisX
res.data.testResultCompare.axisY?.map((i) => {
@ -350,6 +336,7 @@ async function initApi(val) {
})
await nextTick()
personalGradeBar(data.value.personalgradeData)
} else {
ElMessage.error(res.message)
@ -370,6 +357,7 @@ async function initTestResultAvg1(a, b, c) {
data.value.averageBarData.xData.push(i)
data.value.averageBarData.yData.push(res.data[i])
}
await nextTick()
personalBar(data.value.averageBarData)
}
} catch (error) {
@ -386,6 +374,7 @@ async function initTestResultContrast(a, b, c) {
data.value.personalBarData.xData.push(i)
data.value.personalBarData.yData.push(res.data[i])
}
await nextTick()
personalBar(data.value.personalBarData)
}
} catch (error) {
@ -400,6 +389,7 @@ async function initResultTrends1(a, b, c, d) {
console.log(res, 'initResultTrends1')
data.value.chartsData3.ChartCont.xData = res.data.axisX
data.value.chartsData3.ChartCont.seriesData = res.data.axisY
await nextTick()
trendEcharts(data.value.chartsData3)
}
} catch (error) {
@ -913,62 +903,47 @@ function trendEcharts(val) {
<style lang="less" scoped>
.StudentDataStatistics {
width: calc(100% - 24px);
width: 100%;
height: auto;
margin: 12px;
.ipt {
width: calc(100%);
height: 40px;
display: flex;
align-items: center;
justify-content: right;
background: #FFFFFF;
border-radius: 8px;
margin-bottom: 10px;
margin-top: 16px;
.one {
display: flex;
align-items: center;
margin-right: 20px;
p {
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
margin-right: 10px;
}
}
}
.top {
width: 100%;
height: 300px;
height: auto;
min-height: 280px;
display: flex;
align-items: center;
align-items: stretch;
gap: 16px;
.left {
width: calc(100% - 1150px);
height: 100%;
flex: 0 0 auto;
width: 320px;
min-height: 240px;
background: #FFFFFF;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
padding: 20px;
box-sizing: border-box;
.leftImg {
flex-shrink: 0;
img {
width: 200px;
height: 200px;
border-radius: 14px;
margin-left: 30px;
margin-right: 30px;
width: 80px;
height: 80px;
border-radius: 12px;
margin-right: 16px;
object-fit: cover;
}
}
.rightCont {
flex: 1;
.rightContTop,
.rightContBottom {
height: 40px;
height: 36px;
font-size: 14px;
font-family: PingFangSC;
font-weight: 500;
@ -977,10 +952,10 @@ function trendEcharts(val) {
align-items: center;
p {
width: 125px;
flex: 1;
span {
margin-left: 5px;
color: rgba(0, 0, 0, 0.65);
}
}
}
@ -988,24 +963,26 @@ function trendEcharts(val) {
.rightContFoot {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 12px;
p {
width: calc(100% / 2.5);
height: 24px;
border-radius: 12px;
flex: 1;
min-width: 80px;
height: 28px;
border-radius: 14px;
text-align: center;
line-height: 24px;
line-height: 28px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(255, 255, 255, 0.85);
color: rgba(255, 255, 255, 0.95);
cursor: pointer;
}
p:nth-of-type(1),
p:nth-of-type(3) {
background: #4188FE;
margin-right: 10px;
}
p:nth-of-type(2),
@ -1017,18 +994,21 @@ function trendEcharts(val) {
}
.right {
width: 1150px;
height: 100%;
// display: flex;
// align-items: center;
flex: 1;
min-width: 0;
background: #FFFFFF;
border-radius: 8px;
margin-left: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding-bottom: 16px;
.title {
width: 100%;
height: 40px;
height: 48px;
display: flex;
align-items: center;
padding-left: 20px;
border-bottom: 1px solid #F5F5F5;
box-sizing: border-box;
p {
font-family: PingFangSC;
@ -1040,185 +1020,134 @@ function trendEcharts(val) {
#heartChange {
width: 100%;
height: 250px;
height: 220px;
}
}
}
.cont1 {
width: 100%;
height: 300px;
height: auto;
min-height: 330px;
display: flex;
align-items: center;
// margin-left: 5px;
margin-top: 20px;
align-items: stretch;
gap: 16px;
margin-top: 16px;
.cont1Left,
.cont1Right {
width: calc(100% / 2);
height: 100%;
flex: 1;
min-width: 0;
background: #FFFFFF;
border-radius: 8px;
// display: flex;
margin-right: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding-bottom: 16px;
.title {
width: 100%;
height: 40px;
// display: flex;
min-height: 48px;
padding: 0 20px;
border-bottom: 1px solid #F5F5F5;
margin-bottom: 4px;
box-sizing: border-box;
p {
.head {
width: 100%;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
}
#barChart {
width: 100%;
height: 250px;
}
#levelbarChart {
width: 100%;
height: 250px;
}
}
.cont1Left {
.head {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 10px;
.right {
width: auto;
height: 48px;
display: flex;
align-items: center;
margin-right: 20px;
justify-content: space-between;
span {
display: inline-block;
.left p {
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
}
}
}
.cont1Right {
// margin-left: 10px !important;
margin-right: 0 !important;
.title {
.head {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
margin-right: 20px;
gap: 8px;
span {
display: inline-block;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-right: 5px;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
}
}
}
#barChart {
width: 100%;
height: 260px;
}
#levelbarChart {
width: 100%;
height: 260px;
}
}
}
.cont3,
.cont4 {
width: 100%;
height: 350px;
height: auto;
min-height: 350px;
background: #FFFFFF;
border-radius: 8px;
margin-left: 5px;
margin-top: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
margin-top: 16px;
// .title {
// }
.title {
width: 100%;
height: 60px;
min-height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #F5F5F5;
padding: 8px 20px;
box-sizing: border-box;
p {
width: auto;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
.right {
display: flex;
align-items: center;
margin-right: 20px;
span {
display: inline-block;
.left {
p {
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-right: 5px;
}
}
}
.cont3Chart {
width: 100%;
height: 300px;
}
.cont4Chart {
width: 100%;
height: 300px;
}
}
.cont4 {
.title {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
margin-right: 20px;
gap: 16px;
.one {
display: flex;
align-items: center;
gap: 8px;
p {
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
}
}
}
}
.cont3Chart,
.cont4Chart {
width: 100%;
height: 280px;
}
}
}
</style>
</style>

View File

@ -1,14 +1,5 @@
<template>
<div class="workOrder">
<div class="ipt">
<div class="one">
<p>展示数据:</p>
<el-select v-model="data.selectData" placeholder="Select" style="width: 240px">
<el-option v-for="item in data.selectOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
</div>
<template>
<div class="workOrder1">
<div class="list">
<div class="listOne" v-for="(item, index) in data.listData" :key="index">
<div class="left">
@ -24,11 +15,8 @@
<div class="cont1Left">
<div class="title">
<p>班级体测平均成绩</p>
<div class="barChart" id="barChart">
</div>
</div>
<div id="barChart"></div>
</div>
<div class="cont1Right">
<div class="title">
@ -38,17 +26,15 @@
</div>
<div class="right">
<span>项目:</span>
<el-select v-model="data.project" placeholder="请选择" style="width: 240px"
<el-select v-model="data.project" placeholder="请选择" style="width: 200px"
@change="changeProject">
<el-option v-for="item in data.projectData" :key="item.categoryId"
:label="item.categoryName" :value="item.categoryId" />
</el-select>
</div>
</div>
<div class="levelbarChart" id="levelbarChart">
</div>
</div>
<div id="levelbarChart"></div>
</div>
</div>
<div class="cont3">
@ -101,7 +87,7 @@
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeMount, onBeforeUnmount, markRaw } from 'vue';
import { ref, onMounted, onBeforeMount, onBeforeUnmount, markRaw, nextTick } from 'vue';
import * as echarts from 'echarts';
import { useRoute } from 'vue-router';
import * as _api from '@/api/grade.js';
@ -273,7 +259,7 @@ onMounted(() => {
data.value.gradeId = route.params.gradeId ? route.params.gradeId : JSON.parse(localStorage.getItem('classId')).gradeId
console.log(data.value.classId, 'classId')
console.log(data.value.gradeId, 'gradeId')
data.value.gradeId = data.value.gradeId ? data.value.gradeId : 1
data.value.gradeId = data.value.gradeId ? data.value.gradeId : '1'
initApi(data.value.classId)
initCategoryList(data.value.gradeId)
initTestResultRankRate(data.value.gradeId, data.value.classId, data.value.rank)
@ -332,6 +318,7 @@ async function initApi(val) {
data.value.averageBarData.xData.push(i)
data.value.averageBarData.yData.push(res.data.testResultAvg[i].toFixed(0))
}
await nextTick()
averageBar(data.value.averageBarData)
data.value.tableNeed.tableData = res.data.classDetailsList
data.value.tableNeed.tableData?.map((i, ind) => {
@ -368,6 +355,7 @@ async function initTestResultRankRate(a, b, c) {
data.value.classBarData.yData1.push(i.femaleValue)
data.value.classBarData.yData2.push(i.overallValue)
})
await nextTick()
classBar(data.value.classBarData)
}
} catch (error) {
@ -384,6 +372,7 @@ async function initClassCategoryRankRatio(a, b, c) {
for (let i in res.data) {
data.value.levelChartData.seriesData.push({ value: (res.data[i] * 100).toFixed(0), name: i })
}
await nextTick()
levelChart(data.value.levelChartData)
}
} catch (error) {
@ -398,6 +387,7 @@ async function initClassResultTrends(a, b, c, d) {
// console.log(res.data, 'res,initClassResultTrends')
data.value.chartsData3.ChartCont.xData = res.data.axisX
data.value.chartsData3.ChartCont.seriesData = res.data.axisY
await nextTick()
trendEcharts(data.value.chartsData3)
}
} catch (error) {
@ -865,119 +855,54 @@ function trendEcharts(val) {
</script>
<style lang="less" scoped>
.workOrder {
width: calc(100% - 40px);
.workOrder1 {
width: 100%;
height: auto;
margin: 20px;
.ipt {
width: calc(100% - 15px);
height: 40px;
display: flex;
align-items: center;
justify-content: right;
background: #FFFFFF;
border-radius: 8px;
.one {
display: flex;
align-items: center;
margin-right: 20px;
p {
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
margin-right: 10px;
}
}
}
.head {
width: 100%;
height: 40px;
display: flex;
align-items: center;
margin-left: 5px;
.one {
width: 330px;
height: 40px;
display: flex;
align-items: center;
background: #FFFFFF;
border-radius: 8px;
// margin-left: 20px;
margin-right: 20px;
p {
width: 84px;
height: 40px;
border: 1px solid rgba(0, 0, 0, 0.15);
text-align: center;
line-height: 40px;
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
border-right: 0px;
border-radius: 4px 0px 0px 4px;
}
.m-2 {
width: 246px;
// height: 60px;
:deep(.el-input__wrapper) {
height: 40px;
border-radius: 0 4px 4px 0;
}
}
}
}
.list {
width: 100%;
height: 122px;
height: auto;
min-height: 100px;
display: flex;
align-items: center;
margin-top: 20px;
margin-left: 5px;
align-items: stretch;
flex-wrap: wrap;
gap: 16px;
margin-top: 16px;
.listOne {
width: 263px;
height: 122px;
flex: 1;
min-width: 180px;
height: 100px;
background: #FFFFFF;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
margin-right: 20px;
.left {
width: 68px;
height: 68px;
background: rgba(0, 86, 221, 0.25);
border-radius: 14px;
width: 60px;
height: 60px;
background: linear-gradient(135deg, rgba(65, 136, 254, 0.2), rgba(65, 136, 254, 0.08));
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin: 27px 32px;
margin: 20px 20px;
flex-shrink: 0;
img {
width: 44px;
height: 44px;
width: 36px;
height: 36px;
}
}
.right {
p:nth-of-type(1) {
height: 15px;
height: auto;
font-family: DINAlternate;
font-weight: 900;
font-size: 24px;
font-size: 22px;
color: #4188FE;
margin-top: 10px;
}
p:nth-of-type(2) {
@ -992,402 +917,128 @@ function trendEcharts(val) {
.cont1 {
width: 100%;
height: 300px;
height: auto;
min-height: 330px;
display: flex;
align-items: center;
margin-left: 5px;
margin-top: 20px;
align-items: stretch;
gap: 16px;
margin-top: 16px;
.cont1Left,
.cont1Right {
width: 820px;
height: 100%;
flex: 1;
min-width: 0;
height: auto;
background: #FFFFFF;
border-radius: 8px;
// display: flex;
margin-right: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding-bottom: 16px;
.title {
width: 100%;
height: 40px;
// display: flex;
height: auto;
min-height: 48px;
display: flex;
align-items: center;
padding: 0 20px;
border-bottom: 1px solid #F5F5F5;
margin-bottom: 4px;
box-sizing: border-box;
p {
width: 100%;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
}
#barChart {
width: 100%;
height: 250px;
}
#levelbarChart {
width: 100%;
height: 250px;
}
// .contList {
// width: 546px;
// height: 100%;
// display: flex;
// flex-wrap: wrap;
// .descript {
// width: 235px;
// height: 75px;
// background: rgba(0, 86, 221, 0.25);
// border-radius: 8px;
// margin-top: 20px;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
// margin-right: 25px;
// p:nth-of-type(1) {
// height: 0px;
// font-family: DINAlternate;
// font-weight: 900;
// font-size: 24px;
// color: #4188FE;
// margin-top: 8px;
// }
// p:nth-of-type(2) {
// font-family: PingFangSC;
// font-weight: 400;
// font-size: 14px;
// color: #666566;
// }
// }
// .descript:nth-of-type(3),
// .descript:nth-of-type(4) {
// margin-top: -5px;
// }
// }
}
.cont1Right {
.title {
.head {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left p {
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
.right {
display: flex;
align-items: center;
margin-right: 20px;
gap: 8px;
span {
display: inline-block;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-right: 5px;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
}
}
}
}
}
.cont2 {
width: 100%;
height: 350px;
display: flex;
margin-top: 20px;
margin-left: 5px;
.cont2Left {
width: 820px;
height: 350px;
background: #FFFFFF;
border-radius: 8px;
margin-right: 20px;
.title {
#barChart {
width: 100%;
height: 60px;
display: flex;
align-items: center;
p {
width: calc(100% - 240px);
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
.tabList {
width: 240px;
height: 30px;
display: flex;
align-items: center;
p {
width: 83px;
height: 24px;
background: #FAFAFA;
// background: #4188FE;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
text-align: center;
line-height: 24px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(120, 118, 118, 0.85);
margin-left: 20px;
margin-top: 20px;
cursor: pointer;
}
.active {
background: #4188FE;
color: rgba(255, 255, 255, 0.85);
}
}
height: 260px;
}
.centerOneCont {
#levelbarChart {
width: 100%;
height: 25px;
display: flex;
align-items: center;
margin-left: 20px;
margin-top: 30px;
.left {
.average {
width: 300px;
height: 300px;
margin-top: 180px;
}
}
.right {
width: 410px;
margin-top: 180px;
.one {
width: 100%;
height: 50px;
margin-bottom: 20px;
margin-left: 20px;
position: relative;
.head {
width: 100%;
height: 30px;
display: flex;
align-items: center;
// justify-content: space-between;
p,
h5 {
font-family: PingFangSC;
font-weight: 500;
font-size: 14px;
color: #2C2C2C;
}
h5 {
margin-left: 10px;
}
p::before {
content: ' ';
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 21%;
left: 0px;
}
p {
margin-left: 13px;
}
}
.bodyCont {
width: calc(100% - 60px);
height: 25px;
display: flex;
margin-top: -10px;
p {
font-family: PingFangSC;
font-weight: 500;
font-size: 12px;
color: #868A95;
margin-right: 27px;
}
}
.chart {
width: 410px;
height: 100%;
}
}
.one:nth-of-type(1) {
.head {
p::before {
background-color: #00DAAA;
}
}
}
.one:nth-of-type(2) {
.head {
p::before {
background-color: #7BADFF;
}
}
}
.one:nth-of-type(3) {
.head {
p::before {
background-color: #FFD271;
}
}
}
.one:nth-of-type(4) {
.head {
p::before {
background-color: #FE7B9B;
}
}
}
}
}
}
.cont2Right {
width: 820px;
height: 350px;
background: #FFFFFF;
border-radius: 8px;
.title {
width: 100%;
height: 60px;
display: flex;
align-items: center;
p {
width: calc(100% - 240px);
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
.tabList {
width: 240px;
height: 30px;
display: flex;
align-items: center;
p {
width: 83px;
height: 24px;
background: #FAFAFA;
// background: #4188FE;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
text-align: center;
line-height: 24px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(120, 118, 118, 0.85);
margin-left: 20px;
margin-top: 20px;
cursor: pointer;
}
.active {
background: #4188FE;
color: rgba(255, 255, 255, 0.85);
}
}
}
.centerThreeChart {
width: 100%;
height: 300px;
height: 260px;
}
}
}
.cont3,
.cont4 {
width: 1665px;
height: 350px;
width: 100%;
height: auto;
min-height: 350px;
background: #FFFFFF;
border-radius: 8px;
margin-left: 5px;
margin-top: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
margin-top: 16px;
.title {
width: 100%;
height: 60px;
height: auto;
min-height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #F5F5F5;
padding: 8px 20px;
box-sizing: border-box;
.left {
p {
width: auto;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
}
.right {
display: flex;
align-items: center;
margin-right: 20px;
gap: 16px;
.one {
display: flex;
align-items: center;
gap: 8px;
p {
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
}
}
@ -1396,46 +1047,28 @@ function trendEcharts(val) {
.cont3Chart,
.cont4Chart {
width: 100%;
height: 300px;
}
}
.cont4 {
.title {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
margin-right: 20px;
.one {
display: flex;
align-items: center;
margin-left: 20px;
}
}
height: 280px;
}
}
.tableCont {
width: calc(100% - 15px);
margin: 0 auto;
margin-top: 20px;
width: 100%;
margin-top: 16px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
p {
width: auto;
height: 40px;
line-height: 40px;
height: 56px;
line-height: 56px;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
border-bottom: 1px solid #F5F5F5;
}
}
}
</style>
</style>

View File

@ -16,6 +16,7 @@
<p class="reset" @click="reset">重置</p>
<p class="search" @click="search">查询</p>
<!-- <p class="search" @click="add">新增</p> -->
<p class="export-btn" @click="openExportDialog">导出报告</p>
</div>
</div>
<commonTable :tableNeed="data.classroomModeData.tableNeed" @changeSize="changePage"
@ -26,9 +27,21 @@
<tableDetail :data="data.classroomModeData" v-if="data.classroomModeData.refreshTable" @changeSize="changePage"
@handleSizeChange="handleSizeChange" @handle-size-change="handleSizeChange" @toview="toView">
</tableDetail> -->
<!-- </div> -->
<!-- </div> -->
</div>
</div>
<!-- 导出报告弹出框 -->
<el-dialog v-model="exportDialogVisible" title="导出报告" width="520px" :close-on-click-modal="false">
<div class="export-dialog-body">
<span class="export-label">选择时间段:</span>
<el-date-picker v-model="exportTimeRange" type="datetimerange" range-separator="至"
start-placeholder="开始日期时间" end-placeholder="结束日期时间" value-format="YYYY-MM-DD HH:mm:ss" />
</div>
<template #footer>
<el-button @click="exportDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="exportLoading" @click="confirmExport">确认导出</el-button>
</template>
</el-dialog>
<!-- 详情弹窗 -->
<commonDialog :list="data.dialogData" @cancle="cancle" @confirm="confirm">
<template #cont>
@ -58,10 +71,12 @@ import * as _api1 from '@/api/grade';
import { ElMessage } from 'element-plus';
import * as echarts from 'echarts';
import { useRouter } from 'vue-router';
import axios from 'axios';
let router = useRouter();
const options = ref([
])
const options = ref([])
const exportDialogVisible = ref(false)
const exportTimeRange = ref([])
const exportLoading = ref(false)
const data = ref({
finishData: [],
unFinishData: [],
@ -611,6 +626,43 @@ async function GetGradeNames() {
}
// 打开导出报告弹出框
function openExportDialog() {
exportTimeRange.value = []
exportDialogVisible.value = true
}
// 确认导出
const confirmExport = async () => {
if (!exportTimeRange.value || exportTimeRange.value.length !== 2) {
ElMessage.warning('请选择时间段')
return
}
const [startTime, endTime] = exportTimeRange.value
exportLoading.value = true
axios({
method: "get",
url: `/api/ShangWaiMao/ExportHeartRateData?StartTime=${startTime}&EndTime=${endTime}`,
// data: data,
responseType: "blob",
}).then((res) => {
const blob = new Blob([res.data]);
const fileName = `数据报告.xlsx`;
if ("download" in document.createElement("a")) {
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
exportLoading.value = false
exportDialogVisible.value = false
ElMessage.success('导出成功')
}
});
}
function cancle() {
data.value.dialogData.dialogVisible = false
}
@ -762,6 +814,22 @@ function processChartData(rawData) {
</script>
<style lang="less" scoped>
.export-dialog-body {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 0;
.export-label {
white-space: nowrap;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
}
:deep(.el-date-editor) {
flex: 1;
}
}
.dialogManage {
@ -885,6 +953,23 @@ function processChartData(rawData) {
user-select: none;
margin-right: 20px;
}
.export-btn {
width: 95px;
height: 40px;
background: #52C41A;
border-radius: 8px;
border: 1px solid rgba(0, 0, 0, 0.15);
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: #fff;
text-align: center;
line-height: 40px;
cursor: pointer;
user-select: none;
margin-right: 20px;
}
}
}

View File

@ -1,14 +1,5 @@
<template>
<div class="workOrder">
<div class="ipt">
<div class="one">
<p>展示数据:</p>
<el-select v-model="data.selectData" placeholder="Select" style="width: 240px">
<el-option v-for="item in data.selectOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
</div>
<template>
<div class="workOrder1">
<div class="list">
<div class="listOne" v-for="(item, index) in data.listData" :key="index">
<div class="left">
@ -34,11 +25,8 @@
@change="changeClassroomMode"></el-cascader>
</div>
</div>
<div class="barChart" id="barChart">
</div>
</div>
<div id="barChart"></div>
</div>
<div class="cont1Right">
<div class="title">
@ -48,17 +36,15 @@
</div>
<div class="right">
<span>日期:</span>
<el-select v-model="data.calender" placeholder="请选择" style="width: 240px"
<el-select v-model="data.calender" placeholder="请选择" style="width: 200px"
@change=changeCalender>
<el-option v-for="item in data.calenderData" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
</div>
<div class="levelbarChart" id="levelbarChart">
</div>
</div>
<div id="levelbarChart"></div>
</div>
</div>
<div class="cont3">
@ -99,7 +85,7 @@
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeMount, onBeforeUnmount, markRaw } from 'vue';
import { ref, onMounted, onBeforeMount, onBeforeUnmount, markRaw, nextTick } from 'vue';
import * as echarts from 'echarts';
import { useRoute } from 'vue-router';
import * as _api from '@/api/grade.js';
@ -326,6 +312,7 @@ async function initTeacherDataStats(val) {
data.value.classBarData.yData2.push((i.overallValue * 100).toFixed(0))
})
await nextTick()
classBar(data.value.classBarData)
data.value.tableNeed.tableData = res.data.teacherDetailsList
data.value.tableNeed.tableData.map((i, ind) => {
@ -396,6 +383,7 @@ async function initTestResultAvg(val) {
data.value.averageBarData.xData.push(i)
data.value.averageBarData.yData.push(res.data[i].toFixed(0))
}
await nextTick()
averageBar(data.value.averageBarData)
}
} else {
@ -415,6 +403,7 @@ async function initClassTeachingCountRatio(a, b) {
for (let i in res.data) {
data.value.levelChartData.seriesData.push({ value: res.data[i], name: i })
}
await nextTick()
levelChart(data.value.levelChartData)
}
} else {
@ -857,119 +846,53 @@ function trendEcharts(val) {
</script>
<style lang="less" scoped>
.workOrder {
width: calc(100% - 40px);
.workOrder1 {
width: 100%;
height: auto;
margin: 20px;
.ipt {
width: calc(100% - 15px);
height: 40px;
display: flex;
align-items: center;
justify-content: right;
background: #FFFFFF;
border-radius: 8px;
.one {
display: flex;
align-items: center;
margin-right: 20px;
p {
font-family: PingFangSC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
margin-right: 10px;
}
}
}
// .head {
// width: 100%;
// height: 40px;
// display: flex;
// align-items: center;
// margin-left: 5px;
// .one {
// width: 330px;
// height: 40px;
// display: flex;
// align-items: center;
// background: #FFFFFF;
// border-radius: 8px;
// // margin-left: 20px;
// margin-right: 20px;
// p {
// width: 84px;
// height: 40px;
// border: 1px solid rgba(0, 0, 0, 0.15);
// text-align: center;
// line-height: 40px;
// font-family: PingFangSC;
// font-weight: 400;
// font-size: 14px;
// color: rgba(0, 0, 0, 0.85);
// border-right: 0px;
// border-radius: 4px 0px 0px 4px;
// }
// .m-2 {
// width: 246px;
// // height: 60px;
// :deep(.el-input__wrapper) {
// height: 40px;
// border-radius: 0 4px 4px 0;
// }
// }
// }
// }
.list {
width: 100%;
height: 122px;
height: auto;
min-height: 100px;
display: flex;
align-items: center;
margin-top: 20px;
margin-left: 5px;
align-items: stretch;
flex-wrap: wrap;
gap: 16px;
margin-top: 16px;
.listOne {
width: 263px;
height: 122px;
flex: 1;
min-width: 180px;
height: 100px;
background: #FFFFFF;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
margin-right: 20px;
.left {
width: 68px;
height: 68px;
background: rgba(0, 86, 221, 0.25);
border-radius: 14px;
width: 60px;
height: 60px;
background: linear-gradient(135deg, rgba(65, 136, 254, 0.2), rgba(65, 136, 254, 0.08));
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin: 27px 32px;
margin: 20px;
flex-shrink: 0;
img {
width: 44px;
height: 44px;
width: 36px;
height: 36px;
}
}
.right {
p:nth-of-type(1) {
height: 15px;
font-family: DINAlternate;
font-weight: 900;
font-size: 24px;
font-size: 22px;
color: #4188FE;
margin-top: 10px;
}
p:nth-of-type(2) {
@ -984,409 +907,122 @@ function trendEcharts(val) {
.cont1 {
width: 100%;
height: 300px;
height: auto;
min-height: 330px;
display: flex;
align-items: center;
margin-left: 5px;
margin-top: 20px;
align-items: stretch;
gap: 16px;
margin-top: 16px;
.cont1Left,
.cont1Right {
width: 820px;
height: 100%;
flex: 1;
min-width: 0;
background: #FFFFFF;
border-radius: 8px;
// display: flex;
margin-right: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding-bottom: 16px;
.title {
width: 100%;
height: 40px;
// display: flex;
min-height: 48px;
padding: 0 20px;
border-bottom: 1px solid #F5F5F5;
margin-bottom: 4px;
box-sizing: border-box;
p {
.head {
width: 100%;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
}
#barChart {
width: 100%;
height: 250px;
}
#levelbarChart {
width: 100%;
height: 250px;
}
}
.cont1Left {
.head {
display: flex;
align-items: center;
justify-content: space-between;
.right {
height: 48px;
display: flex;
align-items: center;
margin-right: 20px;
justify-content: space-between;
span {
display: inline-block;
.left p {
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
}
}
}
.cont1Right {
.title {
.head {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
margin-right: 20px;
gap: 8px;
span {
display: inline-block;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-right: 5px;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
}
}
}
#barChart {
width: 100%;
height: 260px;
}
#levelbarChart {
width: 100%;
height: 260px;
}
}
}
.cont2 {
.cont3 {
width: 100%;
height: 350px;
display: flex;
margin-top: 20px;
margin-left: 5px;
.cont2Left {
width: 820px;
height: 350px;
background: #FFFFFF;
border-radius: 8px;
margin-right: 20px;
.title {
width: 100%;
height: 60px;
display: flex;
align-items: center;
p {
width: calc(100% - 240px);
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
.tabList {
width: 240px;
height: 30px;
display: flex;
align-items: center;
p {
width: 83px;
height: 24px;
background: #FAFAFA;
// background: #4188FE;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
text-align: center;
line-height: 24px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(120, 118, 118, 0.85);
margin-left: 20px;
margin-top: 20px;
cursor: pointer;
}
.active {
background: #4188FE;
color: rgba(255, 255, 255, 0.85);
}
}
}
.centerOneCont {
width: 100%;
height: 25px;
display: flex;
align-items: center;
margin-left: 20px;
margin-top: 30px;
.left {
.average {
width: 300px;
height: 300px;
margin-top: 180px;
}
}
.right {
width: 410px;
margin-top: 180px;
.one {
width: 100%;
height: 50px;
margin-bottom: 20px;
margin-left: 20px;
position: relative;
.head {
width: 100%;
height: 30px;
display: flex;
align-items: center;
// justify-content: space-between;
p,
h5 {
font-family: PingFangSC;
font-weight: 500;
font-size: 14px;
color: #2C2C2C;
}
h5 {
margin-left: 10px;
}
p::before {
content: ' ';
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 21%;
left: 0px;
}
p {
margin-left: 13px;
}
}
.bodyCont {
width: calc(100% - 60px);
height: 25px;
display: flex;
margin-top: -10px;
p {
font-family: PingFangSC;
font-weight: 500;
font-size: 12px;
color: #868A95;
margin-right: 27px;
}
}
.chart {
width: 410px;
height: 100%;
}
}
.one:nth-of-type(1) {
.head {
p::before {
background-color: #00DAAA;
}
}
}
.one:nth-of-type(2) {
.head {
p::before {
background-color: #7BADFF;
}
}
}
.one:nth-of-type(3) {
.head {
p::before {
background-color: #FFD271;
}
}
}
.one:nth-of-type(4) {
.head {
p::before {
background-color: #FE7B9B;
}
}
}
}
}
}
.cont2Right {
width: 820px;
height: 350px;
background: #FFFFFF;
border-radius: 8px;
.title {
width: 100%;
height: 60px;
display: flex;
align-items: center;
p {
width: calc(100% - 240px);
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
.tabList {
width: 240px;
height: 30px;
display: flex;
align-items: center;
p {
width: 83px;
height: 24px;
background: #FAFAFA;
// background: #4188FE;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
text-align: center;
line-height: 24px;
font-size: 12px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(120, 118, 118, 0.85);
margin-left: 20px;
margin-top: 20px;
cursor: pointer;
}
.active {
background: #4188FE;
color: rgba(255, 255, 255, 0.85);
}
}
}
.centerThreeChart {
width: 100%;
height: 300px;
}
}
}
.cont3,
.cont4 {
width: 1665px;
height: 350px;
height: auto;
min-height: 350px;
background: #FFFFFF;
border-radius: 8px;
margin-left: 5px;
margin-top: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
margin-top: 16px;
.title {
width: 100%;
height: 60px;
min-height: 56px;
display: flex;
align-items: center;
border-bottom: 1px solid #F5F5F5;
padding: 8px 20px;
box-sizing: border-box;
p {
width: auto;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
}
}
.cont3Chart,
.cont4Chart {
.cont3Chart {
width: 100%;
height: 300px;
}
}
.cont4 {
.title {
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
align-items: center;
margin-right: 20px;
.one {
display: flex;
align-items: center;
}
}
height: 280px;
}
}
.tableCont {
width: calc(100% - 15px);
margin: 0 auto;
margin-top: 20px;
width: 100%;
margin-top: 16px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
p {
width: auto;
height: 40px;
line-height: 40px;
height: 56px;
line-height: 56px;
font-family: PingFangSC;
font-weight: 600;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
margin-left: 20px;
border-bottom: 1px solid #F5F5F5;
}
}
}
</style>
</style>

View File

@ -15,7 +15,7 @@ export default ({ mode }: ConfigEnv) => {
console.log(`ENV:`, ENV)
return defineConfig({
base: 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/web/samart-static/202605071031/',
base: 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/web/samart-static/202605281600/',
server: {
host: '0.0.0.0',
// https: false,