1198 lines
40 KiB
Vue
1198 lines
40 KiB
Vue
<template>
|
||
<div class="courseTraining">
|
||
<!-- 头部标题 -->
|
||
<div class="courseTrainingTopHead">
|
||
<p>整体数据</p>
|
||
</div>
|
||
<!-- 整体数据 -->
|
||
<div class="courseTrainingTop">
|
||
<!-- 内容1 -->
|
||
<div class="courseTrainingTopCont">
|
||
<!-- 左侧内容 -->
|
||
<div class="courseTrainingTopContLeft">
|
||
<!-- 左侧上半部分 -->
|
||
<div class="courseTrainingTopContLeftTop">
|
||
<div class="courseTrainingTopContLeftTopOne" v-for="(item, index) in data.dataOne" :key="index">
|
||
<div class="oneLeft">
|
||
<img :src="item.url" alt="">
|
||
</div>
|
||
<div class="oneRight">
|
||
<p>{{ item.num }}</p>
|
||
<p>{{ item.name }}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 左侧下半部分 -->
|
||
<div class="courseTrainingTopContLeftBottom">
|
||
<div class="oneBottom">
|
||
<div class="title">
|
||
<p>项目达标率</p>
|
||
</div>
|
||
<div class="percent">
|
||
<p>{{ data.defaultPercent }}%</p>
|
||
</div>
|
||
<el-progress class="progress" :text-inside="true" :stroke-width="12"
|
||
:percentage="data.defaultPercent" color="rgba(77, 203, 115, 0.8)">
|
||
<span></span>
|
||
</el-progress>
|
||
<div class="week">
|
||
<div class="weekOne">
|
||
<p>周同比</p>
|
||
<p>0%</p>
|
||
<p></p>
|
||
</div>
|
||
<div class="weekOne">
|
||
<p>日同比</p>
|
||
<p>0%</p>
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 右侧内容 -->
|
||
<div class="courseTrainingTopContRight">
|
||
<div class="trainNum" ref="trainNum">
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 内容2 echarts-->
|
||
<div class="courseTrainingTopCont2">
|
||
<div class="averageGrade" ref="averageGrade">
|
||
|
||
</div>
|
||
</div>
|
||
<!-- 内容3 echarts-->
|
||
<div class="courseTrainingTopCont2">
|
||
<div class="averageCourse" ref="averageCourse">
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 项目查询 -->
|
||
<div class="courseTrainingBottom">
|
||
<div class="bottomTitle">
|
||
<p>项目查询</p>
|
||
</div>
|
||
<!-- 查询行 -->
|
||
<div class="bottomSearch">
|
||
<div class="searchOne">
|
||
<p>年级-班级:</p>
|
||
<el-cascader v-model="data.cascader" placeholder="请选择" :options="data.gradeAclass" filterable />
|
||
</div>
|
||
<div class="searchOne">
|
||
<p>教师姓名:</p>
|
||
<el-input v-model="data.teacherIpt" maxlength="5" show-word-limit placeholder="请输入教师姓名" />
|
||
</div>
|
||
<div class="btn">
|
||
<p class="reset" @click="reset">重置</p>
|
||
<p class="searchBtn" @click="searchTable">查询</p>
|
||
</div>
|
||
</div>
|
||
<!-- 详细列表 -->
|
||
<div class="tableData">
|
||
<div class="tableDataHead">
|
||
<p class="limit">详细列表</p>
|
||
<p class="export" @click="exportData">导出</p>
|
||
</div>
|
||
<div class="table">
|
||
<el-table :data="data.tableData" highlight-current-row
|
||
style="width: calc(100% - 40px) ; margin:0 20px ;" fit="true"
|
||
:header-cell-style="{ 'text-align': 'center', 'font-size': '12px', 'color': '#3F404A', padding: '3px', background: '#F8F8FA', height: '50px' }"
|
||
:cell-style="getCellStyles" :row-style="{ height: '0px' }">
|
||
<el-table-column prop="orderNum" label="序号" />
|
||
<el-table-column prop="className" label="班级" />
|
||
<el-table-column prop="teacherName" label="教师姓名" />
|
||
<el-table-column prop="modelName" label="模式" />
|
||
<el-table-column prop="avgNumber" label="平均(N)" />
|
||
<el-table-column prop="centerNumber" label="中位数(N)" />
|
||
<el-table-column prop="maxNumber" label="最大(N)" />
|
||
<el-table-column prop="minNumber" label="最小(N)" />
|
||
<el-table-column prop="controlNumberProbability" label="达标率" />
|
||
<el-table-column prop="startTime" label="开始时间" />
|
||
<el-table-column label="操作">
|
||
<template #default="scope">
|
||
<p style="height: 0; display: flex; align-items: center;justify-content: center;color: #46a6ff;cursor: pointer;user-select: none;"
|
||
@click="handleClick(scope.row)">
|
||
查看详情
|
||
</p>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
</el-table>
|
||
<el-pagination class="pagination" :current-page="data.pagination.pageIndex"
|
||
:page-size="data.pagination.pageSize" :page-sizes="data.pagination.pageSizes"
|
||
layout="total, sizes, prev, pager, next, jumper" :total="data.pagination.total"
|
||
@size-change="handleSizeChange" @current-change="changeSize" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { ref, onMounted, markRaw } from 'vue';
|
||
import * as echarts from 'echarts';
|
||
import * as _api from '@/api/grade';
|
||
import * as _train from '@/api/training';
|
||
import { ElMessage } from 'element-plus';
|
||
import { useRouter } from 'vue-router';
|
||
import eventBus from '@/eventBus.js';
|
||
import axios from 'axios'
|
||
const router = useRouter();
|
||
const trainNum = ref(null) //第一个echarts
|
||
const averageGrade = ref(null) //第二个echarts
|
||
const averageCourse = ref(null)//第三个echarts
|
||
const data = ref({
|
||
dataOne: [{
|
||
id: 0,
|
||
name: '项目训练次数',
|
||
num: 37,
|
||
url: require('@/assets/images/allImg/train1.png')
|
||
}, {
|
||
id: 1,
|
||
name: '项目训练时长(秒)',
|
||
num: 5.15,
|
||
url: require('@/assets/images/allImg/train2.png')
|
||
}],
|
||
defaultPercent: 0,
|
||
echartData: {
|
||
color: ['#71D58F', '#46A6FF', '#FBDC5F', '#F28458'],
|
||
seriesData: [{
|
||
value: null,
|
||
man: null,
|
||
woman: null,
|
||
name: '优秀'
|
||
}, {
|
||
value: null,
|
||
man: null,
|
||
woman: null,
|
||
name: '良好'
|
||
}, {
|
||
value: null,
|
||
man: null,
|
||
woman: null,
|
||
name: '及格'
|
||
}, {
|
||
value: null,
|
||
man: null,
|
||
woman: null,
|
||
name: '不及格'
|
||
}]
|
||
},
|
||
averageData: {
|
||
color: ['#71D58F', '#46A6FF', '#FBDC5F', '#F28458'],
|
||
xData: [],
|
||
seriesData: [{
|
||
name: '优秀',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
label: {
|
||
show: true,
|
||
position: 'top',
|
||
formatter: function (params) {
|
||
// 假设 data 是百分比形式的数据
|
||
return `${params.value}%`;
|
||
}
|
||
},
|
||
data: []
|
||
},
|
||
{
|
||
name: '良好',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
label: {
|
||
show: true,
|
||
position: 'top',
|
||
formatter: function (params) {
|
||
// 假设 data 是百分比形式的数据
|
||
return `${params.value}%`;
|
||
}
|
||
},
|
||
data: []
|
||
},
|
||
{
|
||
name: '及格',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
label: {
|
||
show: true,
|
||
position: 'top',
|
||
formatter: function (params) {
|
||
// 假设 data 是百分比形式的数据
|
||
return `${params.value}%`;
|
||
}
|
||
},
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
data: []
|
||
}, {
|
||
name: '不及格',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
label: {
|
||
show: true,
|
||
position: 'top',
|
||
formatter: function (params) {
|
||
// 假设 data 是百分比形式的数据
|
||
return `${params.value}%`;
|
||
}
|
||
},
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
data: []
|
||
},]
|
||
},
|
||
averageCourseData: {
|
||
color: ['#46A6FF', '#F58295', '#AC7FE9'],
|
||
xData: [],
|
||
seriesData: [{
|
||
name: '男生',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
label: {
|
||
show: true,
|
||
position: 'top'
|
||
},
|
||
data: []
|
||
},
|
||
{
|
||
name: '女生',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
label: {
|
||
show: true,
|
||
position: 'top'
|
||
},
|
||
data: []
|
||
},
|
||
{
|
||
name: '总体',
|
||
type: 'bar',
|
||
barWidth: 20,
|
||
label: {
|
||
show: true,
|
||
position: 'top'
|
||
},
|
||
emphasis: {
|
||
focus: 'series'
|
||
},
|
||
data: []
|
||
},]
|
||
},
|
||
gradeAclass: [],
|
||
cascader: [],
|
||
teacherIpt: '',
|
||
tableData: [],
|
||
pagination: {
|
||
pageIndex: 1,
|
||
pageSize: 50,
|
||
total: 0,
|
||
pageSizes: [50, 100, 200, 500]
|
||
},
|
||
DataSource: null,
|
||
ItemType: 3,
|
||
StartTime: '',
|
||
EndTime: ''
|
||
})
|
||
onMounted(() => {
|
||
GetGradeNames()
|
||
GetTrainingInfoApi()
|
||
GetAttainmentRateApi()
|
||
GetScoreProportionApi()
|
||
GetGradeScoreProportionApi()
|
||
GetGradeScoreApi()
|
||
GetTrainingDataListApi()
|
||
})
|
||
// 点击重置
|
||
function reset() {
|
||
data.value.cascader = []
|
||
data.value.teacherIpt = ''
|
||
GetTrainingDataListApi()
|
||
}
|
||
// 点击查询
|
||
function searchTable() {
|
||
GetTrainingDataListApi()
|
||
}
|
||
function transformData(data) {
|
||
return data.map(grade => ({
|
||
value: grade.id,
|
||
label: grade.gradeName,
|
||
children: grade.class.map(cls => ({
|
||
value: cls.id,
|
||
label: cls.className
|
||
}))
|
||
}));
|
||
}
|
||
function getCellStyles({ row, column, rowIndex, columnIndex }) {
|
||
const prop = column.property;
|
||
return {
|
||
height: 0,
|
||
textAlign: 'center',
|
||
};
|
||
}
|
||
// 点击查看详情
|
||
function handleClick(e) {
|
||
console.log(e, 'eeeeee')
|
||
eventBus.emit('trainingDetails', e);
|
||
}
|
||
// 切换每页个数
|
||
function handleSizeChange(e) {
|
||
console.log(e, '11111')
|
||
data.value.pagination.pageSize = e
|
||
GetTrainingDataListApi()
|
||
}
|
||
// 切换页码
|
||
function changeSize(e) {
|
||
data.value.pagination.pageIndex = e
|
||
GetTrainingDataListApi()
|
||
}
|
||
|
||
// 训练信息
|
||
async function GetTrainingInfoApi() {
|
||
try {
|
||
const res = await _train.GetTrainingInfo(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime);
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
data.value.dataOne[0].num = res.data.trainingNumber
|
||
data.value.dataOne[1].num = res.data.trainingTime
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
//获取达标率
|
||
async function GetAttainmentRateApi() {
|
||
try {
|
||
const res = await _train.GetAttainmentRate(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime);
|
||
if (res.code == 200) {
|
||
if (res.data.length>0) {
|
||
data.value.defaultPercent = (res.data[0].attainmentNumber / res.data[0].totalNumber) * 100
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
// 年级平均成绩占比接口
|
||
async function GetGradeScoreProportionApi() {
|
||
try {
|
||
const res = await _train.GetGradeScoreProportion(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime);
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
console.log(res.data, 'resssssGetGradeScoreProportionApi')
|
||
res.data.map((i) => {
|
||
data.value.averageData.xData.push(i.gradeName)
|
||
data.value.averageData.seriesData[0].data.push((i.excellentNumber / i.totalNumber) * 100)
|
||
data.value.averageData.seriesData[1].data.push((i.fineNumber / i.totalNumber * 100))
|
||
data.value.averageData.seriesData[2].data.push((i.passNumber / i.totalNumber) * 100)
|
||
data.value.averageData.seriesData[3].data.push((i.noPassNumber / i.totalNumber) * 100)
|
||
})
|
||
initChartsAverage(data.value.averageData)
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
//获取累计训练成绩人数占比
|
||
async function GetScoreProportionApi() {
|
||
try {
|
||
const res = await _train.GetScoreProportion(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime);
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
console.log(res.data, 'res.GetScoreProportionApi')
|
||
res.data.map((i) => {
|
||
switch (i.scoreLevel) {
|
||
case 1:
|
||
data.value.echartData.seriesData[0].value = i.totalNumber
|
||
data.value.echartData.seriesData[0].man = i.maleNumber
|
||
data.value.echartData.seriesData[0].woman = i.femaleNumber
|
||
break
|
||
case 2:
|
||
data.value.echartData.seriesData[1].value = i.totalNumber
|
||
data.value.echartData.seriesData[1].man = i.maleNumber
|
||
data.value.echartData.seriesData[1].woman = i.femaleNumber
|
||
break
|
||
case 3:
|
||
data.value.echartData.seriesData[2].value = i.totalNumber
|
||
data.value.echartData.seriesData[2].man = i.maleNumber
|
||
data.value.echartData.seriesData[2].woman = i.femaleNumber
|
||
break
|
||
case 4:
|
||
data.value.echartData.seriesData[3].value = i.totalNumber
|
||
data.value.echartData.seriesData[3].man = i.maleNumber
|
||
data.value.echartData.seriesData[3].woman = i.femaleNumber
|
||
break
|
||
}
|
||
})
|
||
console.log(data.value.echartData, 'data.value.echartData')
|
||
initCharts(data.value.echartData)
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
// 平均跳绳个数接口
|
||
async function GetGradeScoreApi() {
|
||
try {
|
||
const res = await _train.GetGradeScore(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime);
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
console.log(res.data, 'GetGradeScoreApi')
|
||
res.data.map((i) => {
|
||
data.value.averageCourseData.xData.push(i.gradeName)
|
||
data.value.averageCourseData.seriesData[0].data.push(i.maleNumber)
|
||
data.value.averageCourseData.seriesData[1].data.push(i.femaleNumber)
|
||
data.value.averageCourseData.seriesData[2].data.push(i.totalNumber)
|
||
})
|
||
initChartsCourse(data.value.averageCourseData)
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
// 获取列表接口
|
||
async function GetTrainingDataListApi() {
|
||
console.log(data.value.cascader, 'cascader')
|
||
let GradeId = data.value.cascader ? data.value.cascader[0] : ''
|
||
let ClassId = data.value.cascader ? data.value.cascader[1] : ''
|
||
try {
|
||
const res = await _train.GetTrainingDataList(data.value.DataSource, data.value.ItemType, data.value.StartTime, data.value.EndTime, GradeId, ClassId, data.value.teacherIpt, data.value.pagination.pageIndex, data.value.pagination.pageSize);
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
console.log(res.data, 'GetTrainingDataListApi')
|
||
const startOrderNum = (data.value.pagination.pageIndex - 1) * data.value.pagination.pageSize + 1;
|
||
data.value.tableData = res.data
|
||
data.value.tableData?.map((i, ind) => {
|
||
// 为每个数据项分配序号
|
||
i.orderNum = startOrderNum + ind;
|
||
i.controlNumberProbability = `${(i.controlNumber / i.trainNumer) * 100}%`
|
||
})
|
||
data.value.pagination.total = res.data.length
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
//年级接口
|
||
async function GetGradeNames() {
|
||
try {
|
||
const res = await _api.GetGradeName();
|
||
if (res.code == 200) {
|
||
if (res.data) {
|
||
console.log(res.data, 'res.GetGradeNamesGetGradeNames')
|
||
let k = transformData(res.data)
|
||
data.value.gradeAclass = k
|
||
}
|
||
} else {
|
||
ElMessage.error(res.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('Error occurred while calling API:', error);
|
||
}
|
||
}
|
||
// 累计训练成绩人数占比echarts
|
||
function initCharts(val) {
|
||
let myChart = markRaw(echarts.init(trainNum.value));
|
||
const total = val.seriesData.reduce((sum, item) => sum + item.value, 0);
|
||
// 绘制图表
|
||
myChart.setOption({
|
||
color: val.color,
|
||
title: {
|
||
text: '累计训练成绩人数占比',
|
||
left: 'left',
|
||
top: 'top',
|
||
textStyle: {
|
||
fontSize: 15, // 主标题字体大小
|
||
fontWeight: 'bold', // 主标题字体粗细
|
||
color: '#333', // 主标题字体颜色
|
||
fontFamily: 'Arial', // 主标题字体
|
||
},
|
||
},
|
||
legend: {
|
||
orient: 'vertical',
|
||
right: 60,
|
||
top: 30,
|
||
bottom: 20,
|
||
// itemGap: 20,
|
||
icon: 'circle',
|
||
formatter: function (name) {
|
||
// const item = val.seriesData.find(d => d.name === name);
|
||
// if (!item) return name; // 防止 item 不存在的情况
|
||
// const percentage = ((item.value / total) * 100).toFixed(0);
|
||
// return `${name} ${percentage}%\n男生:${item.man} 女生:${item.woman}`;
|
||
const item = val.seriesData.find(d => d.name === name);
|
||
if (!item) return name; // 防止 item 不存在的情况
|
||
|
||
// Calculate percentage
|
||
const percentage = ((item.value / total) * 100).toFixed(0);
|
||
|
||
// Check if values are null or undefined and adjust accordingly
|
||
const manText = item.man != null ? `男生:${item.man}` : '';
|
||
const womanText = item.woman != null ? `女生:${item.woman}` : '';
|
||
|
||
// Combine the text parts
|
||
const legendText = `${name} ${percentage}%\n${manText} ${womanText}`;
|
||
|
||
// Return the formatted text
|
||
return legendText.trim();
|
||
},
|
||
textStyle: {
|
||
color: '#8C8C8C',
|
||
fontSize: 12,
|
||
lineHeight: 25,
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
type: 'pie',
|
||
radius: ['50%', '70%'],
|
||
center: ['35%', '50%'],
|
||
startAngle: 90,
|
||
// hoverAnimation: false,
|
||
// avoidLabelOverlap: false,
|
||
// animationDurationUpdate: 2000, // 更新动画时长为 1s
|
||
// animationEasingUpdate: 'cubicInOut', // 更新动画缓动效果为 'quinticInOut'
|
||
// silent: true,
|
||
label: {
|
||
color: '#000',
|
||
show: true,
|
||
position: 'outside',
|
||
formatter: function (params) {
|
||
// 使用 rich text 格式化标签
|
||
return `{name|${params.name}}\n{value|${params.value}人}`;
|
||
},
|
||
rich: {
|
||
name: {
|
||
color: '#000',
|
||
fontSize: 12,
|
||
padding: [0, 0, 10, 0],
|
||
},
|
||
value: {
|
||
color: '#333',
|
||
fontSize: 12,
|
||
},
|
||
},
|
||
},
|
||
data: val.seriesData,
|
||
emphasis: {
|
||
itemStyle: {
|
||
shadowBlur: 10,
|
||
shadowOffsetX: 0,
|
||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||
}
|
||
}
|
||
}
|
||
]
|
||
});
|
||
window.onresize = function () { // 自适应大小
|
||
myChart.resize();
|
||
};
|
||
}
|
||
// 年级平均成绩占比
|
||
function initChartsAverage(val) {
|
||
let myChart = markRaw(echarts.init(averageGrade.value));
|
||
myChart.setOption(
|
||
{
|
||
color: val.color,
|
||
title: {
|
||
text: '年级平均成绩占比',
|
||
left: 'left',
|
||
top: 'top',
|
||
padding: [20, 0, 0, 0],
|
||
textStyle: {
|
||
fontSize: 15, // 主标题字体大小
|
||
fontWeight: 'bold', // 主标题字体粗细
|
||
color: '#333', // 主标题字体颜色
|
||
fontFamily: 'Arial', // 主标题字体
|
||
},
|
||
},
|
||
legend: {
|
||
icon: "rect",
|
||
x: "center",
|
||
padding: [60, 0, 0, 0],
|
||
itemWidth: 12,
|
||
itemHeight: 6,
|
||
itemGap: 41,
|
||
textStyle: {
|
||
color: "#000",
|
||
fontSize: "12px"
|
||
}
|
||
},
|
||
grid: {
|
||
top: '30%',
|
||
left: "2%",
|
||
right: "2%",
|
||
bottom: "3%",
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: val.xData,
|
||
axisTick: {
|
||
show: false
|
||
},
|
||
axisLabel: {
|
||
//x轴文字的配置
|
||
show: true,
|
||
color: '#8C8C8C',
|
||
fontSize: 12
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: val.XaxisLineColor
|
||
}
|
||
},
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
name: '%',
|
||
nameTextStyle: {
|
||
color: "#868A95",
|
||
fontSize: 12,
|
||
padding: [0, 30, 0, 0]
|
||
},
|
||
interval: 20,
|
||
axisLabel: {
|
||
color: '#8C8C8C',
|
||
fontStyle: "normal",
|
||
fontWeight: "400",
|
||
fontSize: "12"
|
||
},
|
||
axisLine: {
|
||
show: false,
|
||
lineStyle: {
|
||
color: '#8C8C8C'
|
||
}
|
||
},
|
||
splitLine: {
|
||
//分割线配置
|
||
show: true,
|
||
},
|
||
|
||
},
|
||
series: val.seriesData
|
||
}
|
||
)
|
||
window.onresize = function () { // 自适应大小
|
||
myChart.resize();
|
||
};
|
||
}
|
||
// 平均握力
|
||
function initChartsCourse(val) {
|
||
let myChart = markRaw(echarts.init(averageCourse.value));
|
||
myChart.setOption(
|
||
{
|
||
color: val.color,
|
||
title: {
|
||
text: '平均握力',
|
||
left: 'left',
|
||
top: 'top',
|
||
padding: [20, 0, 0, 0],
|
||
textStyle: {
|
||
fontSize: 15, // 主标题字体大小
|
||
fontWeight: 'bold', // 主标题字体粗细
|
||
color: '#333', // 主标题字体颜色
|
||
fontFamily: 'Arial', // 主标题字体
|
||
},
|
||
},
|
||
legend: {
|
||
icon: "rect",
|
||
x: "center",
|
||
padding: [60, 0, 0, 0],
|
||
itemWidth: 12,
|
||
itemHeight: 6,
|
||
itemGap: 41,
|
||
textStyle: {
|
||
color: "#000",
|
||
fontSize: "12px"
|
||
}
|
||
},
|
||
grid: {
|
||
top: '30%',
|
||
left: "2%",
|
||
right: "2%",
|
||
bottom: "3%",
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: val.xData,
|
||
axisTick: {
|
||
show: false
|
||
},
|
||
axisLabel: {
|
||
//x轴文字的配置
|
||
show: true,
|
||
color: '#8C8C8C',
|
||
fontSize: 12
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: val.XaxisLineColor
|
||
}
|
||
},
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
name: 'N',
|
||
nameTextStyle: {
|
||
color: "#868A95",
|
||
fontSize: 12,
|
||
padding: [0, 30, 0, 0]
|
||
},
|
||
interval: 20,
|
||
axisLabel: {
|
||
color: '#8C8C8C',
|
||
fontStyle: "normal",
|
||
fontWeight: "400",
|
||
fontSize: "12"
|
||
},
|
||
axisLine: {
|
||
show: false,
|
||
lineStyle: {
|
||
color: '#8C8C8C'
|
||
}
|
||
},
|
||
splitLine: {
|
||
//分割线配置
|
||
show: true,
|
||
},
|
||
|
||
},
|
||
series: val.seriesData
|
||
}
|
||
)
|
||
window.onresize = function () { // 自适应大小
|
||
myChart.resize();
|
||
};
|
||
}
|
||
// 导出表格
|
||
function exportData(val) {
|
||
let GradeId = data.value.cascader ? data.value.cascader[0] : ''
|
||
let ClassId = data.value.cascader ? data.value.cascader[1] : ''
|
||
axios({
|
||
method: 'get',
|
||
url: `/api/TrainingData/TrainingDataListExport?DataSource=${data.value.DataSource}&ItemType=${data.value.ItemType}&StartTime=${data.value.StartTime}&EndTime=${data.value.EndTime}&GradeId=${GradeId}&ClassId=${ClassId}&TeacherName=${data.value.teacherIpt}&PageIndex=${data.value.pagination.pageIndex}&PageSize=${data.value.pagination.pageSize}`,
|
||
// 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)
|
||
}
|
||
})
|
||
}
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.courseTraining {
|
||
width: 100%;
|
||
height: auto;
|
||
|
||
// margin: 16px;
|
||
|
||
.courseTrainingTopHead {
|
||
width: 100%;
|
||
height: 32px;
|
||
font-size: 24px;
|
||
font-family: PingFangSC;
|
||
font-weight: 700;
|
||
color: rgba(0, 0, 0, .85);
|
||
line-height: 32px;
|
||
padding-left: 16px;
|
||
}
|
||
|
||
.courseTrainingTop {
|
||
width: 100%;
|
||
height: auto;
|
||
margin-top: 16px;
|
||
|
||
.courseTrainingTopCont {
|
||
width: 100%;
|
||
height: 328px;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.courseTrainingTopContLeft {
|
||
width: calc(100% / 2.1);
|
||
height: 100%;
|
||
margin-left: 16px;
|
||
|
||
.courseTrainingTopContLeftTop {
|
||
width: 100%;
|
||
height: 112px;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.courseTrainingTopContLeftTopOne {
|
||
width: calc(100% / 2);
|
||
height: 100%;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.oneLeft {
|
||
width: 64px;
|
||
height: 64px;
|
||
border-radius: 50%;
|
||
background-color: rgba(24, 144, 255, .8);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin: 24px;
|
||
|
||
img {
|
||
width: 40px;
|
||
height: 40px;
|
||
|
||
|
||
}
|
||
}
|
||
|
||
.oneRight {
|
||
height: 100%;
|
||
|
||
p:nth-of-type(1) {
|
||
// height: 30px;
|
||
font-size: 30px;
|
||
font-family: PingFangSC;
|
||
font-weight: 700;
|
||
color: rgba(0, 0, 0, .85);
|
||
line-height: 20px;
|
||
display: block;
|
||
}
|
||
|
||
p:nth-of-type(2) {
|
||
height: 0px;
|
||
font-size: 14px;
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
color: rgba(0, 0, 0, .45);
|
||
// line-height: 22px;
|
||
display: block;
|
||
margin-top: -15px;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.courseTrainingTopContLeftTopOne:nth-of-type(2) {
|
||
margin-left: 12px;
|
||
|
||
.oneLeft {
|
||
background: rgba(151, 95, 228, .8);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
.courseTrainingTopContLeftBottom {
|
||
width: 100%;
|
||
height: 203px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
|
||
.oneBottom {
|
||
height: 100%;
|
||
|
||
.title {
|
||
p {
|
||
height: 22px;
|
||
font-size: 14px;
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
color: rgba(0, 0, 0, .65);
|
||
padding-top: 16px;
|
||
margin-left: 16px;
|
||
}
|
||
}
|
||
|
||
|
||
.percent {
|
||
height: 36px;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 30px;
|
||
margin-bottom: 10px;
|
||
|
||
p {
|
||
font-size: 30px;
|
||
font-family: PingFangSC;
|
||
font-weight: 700;
|
||
color: #1890ff;
|
||
margin-left: 20px;
|
||
|
||
}
|
||
}
|
||
|
||
.progress {
|
||
height: 40px;
|
||
width: calc(100% - 40px);
|
||
margin: 0 auto;
|
||
border-bottom: 1px solid rgba(0, 0, 0, .1);
|
||
}
|
||
|
||
.week {
|
||
width: 100%;
|
||
height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-left: 20px;
|
||
|
||
.weekOne {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-right: 40px;
|
||
|
||
p {
|
||
font-size: 14px;
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
color: rgba(0, 0, 0, .65);
|
||
margin-right: 5px;
|
||
}
|
||
|
||
p:nth-of-type(3) {
|
||
border-top: 6px solid #52c41a;
|
||
display: inline-block;
|
||
border-left: 3px solid #fff;
|
||
border-right: 3px solid #fff;
|
||
vertical-align: middle;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
.courseTrainingTopContRight {
|
||
width: calc(100% / 2.03);
|
||
height: 328px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
margin-left: 20px;
|
||
|
||
.trainNum {
|
||
width: calc(100% - 40px);
|
||
height: 290px;
|
||
margin: 0 auto;
|
||
margin-top: 20px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.courseTrainingTopCont2 {
|
||
width: calc(100% - 30px);
|
||
height: 406px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
margin-top: 20px;
|
||
margin-left: 16px;
|
||
|
||
.averageGrade,
|
||
.averageCourse {
|
||
width: calc(100% - 40px);
|
||
height: 380px;
|
||
margin: 0 auto;
|
||
margin-top: 20px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.courseTrainingBottom {
|
||
width: 100%;
|
||
height: auto;
|
||
|
||
.bottomTitle {
|
||
width: 100%;
|
||
height: 32px;
|
||
font-size: 24px;
|
||
font-family: PingFangSC;
|
||
font-weight: 700;
|
||
color: rgba(0, 0, 0, .85);
|
||
line-height: 32px;
|
||
padding-left: 16px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.bottomSearch {
|
||
width: calc(100% - 30px);
|
||
height: 80px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin: 0 auto;
|
||
|
||
.searchOne {
|
||
width: 500px;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-left: 20px;
|
||
|
||
p {
|
||
font-size: 14px;
|
||
font-family: PingFangSC;
|
||
color: rgba(0, 0, 0, .85);
|
||
margin-right: 10px;
|
||
}
|
||
|
||
:deep(.el-cascader) {
|
||
width: 248px;
|
||
}
|
||
|
||
:deep(.el-input) {
|
||
width: 248px;
|
||
}
|
||
}
|
||
|
||
.btn {
|
||
width: 170px;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.reset {
|
||
width: 65px;
|
||
height: 32px;
|
||
background: rgb(255, 255, 255);
|
||
border-radius: 2px;
|
||
text-align: center;
|
||
line-height: 32px;
|
||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
|
||
.searchBtn {
|
||
width: 65px;
|
||
height: 32px;
|
||
background: rgb(24, 144, 255);
|
||
border-radius: 2px;
|
||
text-align: center;
|
||
line-height: 32px;
|
||
color: #fff;
|
||
margin-left: 20px;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tableData {
|
||
width: calc(100% - 30px);
|
||
height: 758px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
margin: 0 auto;
|
||
margin-top: 20px;
|
||
|
||
.tableDataHead {
|
||
width: 100%;
|
||
height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
.limit {
|
||
font-size: 16px;
|
||
font-family: PingFangSC;
|
||
font-weight: 700;
|
||
color: rgba(0, 0, 0, .8);
|
||
margin-left: 20px;
|
||
}
|
||
|
||
.export {
|
||
width: 65px;
|
||
height: 32px;
|
||
background: rgb(24, 144, 255);
|
||
border-radius: 2px;
|
||
text-align: center;
|
||
line-height: 32px;
|
||
color: #fff;
|
||
margin-right: 20px;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.table {
|
||
height: 600px;
|
||
|
||
.el-table {
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.pagination {
|
||
width: 100%;
|
||
height: 60px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: right;
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
:deep(.el-tabs__item) {
|
||
width: auto !important;
|
||
height: 25px !important;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
color: #848893;
|
||
}
|
||
</style> |