教师端统计页面1版
parent
36d9eab00b
commit
245581822c
|
|
@ -4,7 +4,6 @@
|
|||
<div class="header-left">
|
||||
<h2 class="main-title">教师端作业统计概览</h2>
|
||||
</div>
|
||||
|
||||
<div class="header-center">
|
||||
<el-select v-model="currentClass" class="tech-select main-selector">
|
||||
<el-option label="高一(1)班" value="1" />
|
||||
|
|
@ -12,7 +11,6 @@
|
|||
<el-option label="高一(3)班" value="3" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
<el-select v-model="currentSubject" class="tech-select subject-selector">
|
||||
<el-option label="英语" value="english" />
|
||||
|
|
@ -52,36 +50,86 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="15" class="margin-top-20 equal-height-row">
|
||||
<el-col :span="12">
|
||||
<div class="data-box full-height">
|
||||
<div class="box-title">各题错误率排行 (Top 5)</div>
|
||||
<div class="error-rank-list">
|
||||
<div v-for="(item, index) in errorRank" :key="index" class="rank-item">
|
||||
<span class="rank-no">{{ index + 1 }}. {{ item.name }}</span>
|
||||
<div class="progress-bg">
|
||||
<div class="progress-bar" :style="{ width: item.rate + '%' }"></div>
|
||||
<div class="extension-tabs margin-top-20">
|
||||
<el-tabs v-model="activeTab" type="border-card" class="custom-tabs">
|
||||
<el-tab-pane label="学情预警" name="warning">
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="14">
|
||||
<div class="inner-box">
|
||||
<div class="sub-title">成绩波动趋势</div>
|
||||
<div ref="trendChartRef" style="height: 250px"></div>
|
||||
</div>
|
||||
<div class="rank-tag">{{ item.rate }}%</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<div class="inner-box">
|
||||
<div class="sub-title">需关注学生 (近期下滑)</div>
|
||||
<div class="warning-list">
|
||||
<div v-for="stu in warningStudents" :key="stu.name" class="warning-item">
|
||||
<span class="stu-name">{{ stu.name }}</span>
|
||||
<span class="stu-desc">连续{{ stu.count }}次表现下降</span>
|
||||
<el-tag size="small" type="danger">风险</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="知识点分析" name="knowledge">
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="12">
|
||||
<div class="inner-box">
|
||||
<div class="sub-title">核心能力雷达</div>
|
||||
<div ref="radarChartRef" style="height: 250px"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="inner-box">
|
||||
<div class="sub-title">薄弱知识点 Top 3</div>
|
||||
<div class="weak-points">
|
||||
<div class="point-card">1. 虚拟语气 (正确率 42%)</div>
|
||||
<div class="point-card">2. 介词搭配 (正确率 55%)</div>
|
||||
<div class="point-card">3. 长难句理解 (正确率 58%)</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="作业质量" name="quality">
|
||||
<div class="inner-box">
|
||||
<el-row :gutter="20" class="quality-stats">
|
||||
<el-col :span="8">
|
||||
<div class="q-item">
|
||||
<div class="q-label">平均用时</div>
|
||||
<div class="q-val">45 min</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="q-item">
|
||||
<div class="q-label">晚间 11点后提交</div>
|
||||
<div class="q-val" style="color: #ff4d4f">12 人</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="q-item">
|
||||
<div class="q-label">有效互动率</div>
|
||||
<div class="q-val">78%</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="data-box full-height">
|
||||
<div class="box-title">待催促名单 (表格)</div>
|
||||
<el-table :data="urgeList" class="custom-table" size="small">
|
||||
<el-table-column prop="name" label="姓名" align="center" />
|
||||
<el-table-column prop="reason" label="未交详情" align="center" />
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default>
|
||||
<el-button type="primary" size="small" plain class="urge-btn">催一下</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="报告生成" name="report">
|
||||
<div class="report-area">
|
||||
<p>系统已基于本周数据分析,为该班级生成了 50 份个性化学习周报。</p>
|
||||
<el-button type="primary" class="urge-btn">一键推送到家长端</el-button>
|
||||
<el-button type="success" plain>预览班级分析报告 (PDF)</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -89,14 +137,18 @@
|
|||
import { ref, onMounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
// --- 默认值设置:确保进入页面即有显示 ---
|
||||
const currentClass = ref('3')
|
||||
const currentSubject = ref('english')
|
||||
const activeTab = ref('warning')
|
||||
|
||||
// 图表引用
|
||||
const barChartRef = ref(null)
|
||||
const pieChartRef = ref(null)
|
||||
const miniPieRef = ref(null)
|
||||
const trendChartRef = ref(null)
|
||||
const radarChartRef = ref(null)
|
||||
|
||||
// 模拟数据
|
||||
const stats = [
|
||||
{ label: '应交数', value: '50', icon: '👥', color: '#00a2ff', bgColor: 'rgba(0,162,255,0.1)' },
|
||||
{ label: '实交数', value: '42', icon: '📝', color: '#4caf50', bgColor: 'rgba(76,175,80,0.1)' },
|
||||
|
|
@ -104,67 +156,40 @@ const stats = [
|
|||
{ label: '批改率', value: '90%', icon: '✔️', color: '#00bcd4', bgColor: 'rgba(0,188,212,0.1)' }
|
||||
]
|
||||
|
||||
const errorRank = [
|
||||
{ name: '完形填空', rate: 80 },
|
||||
{ name: '语法填空', rate: 65 },
|
||||
{ name: '阅读理解A', rate: 50 },
|
||||
{ name: '单词拼写', rate: 35 },
|
||||
{ name: '作文', rate: 20 }
|
||||
]
|
||||
|
||||
const urgeList = [
|
||||
{ name: '张三', reason: '连续2次未交' },
|
||||
{ name: '李四', reason: '连续1次未交' },
|
||||
{ name: '王五', reason: '共3次未交' }
|
||||
const warningStudents = [
|
||||
{ name: '王同学', count: 3 },
|
||||
{ name: '李同学', count: 2 },
|
||||
{ name: '赵同学', count: 2 }
|
||||
]
|
||||
|
||||
onMounted(() => {
|
||||
renderCharts()
|
||||
renderBaseCharts()
|
||||
renderExtensionCharts()
|
||||
})
|
||||
|
||||
const renderCharts = () => {
|
||||
const renderBaseCharts = () => {
|
||||
// 原有的基础图表逻辑
|
||||
const bar = echarts.init(barChartRef.value)
|
||||
bar.setOption({
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'none' } },
|
||||
grid: { top: '15%', bottom: '15%', left: '8%', right: '5%' },
|
||||
xAxis: {
|
||||
data: ['<60', '60-70', '70-80', '80-90', '>90'],
|
||||
axisLine: { lineStyle: { color: 'rgba(0,162,255,0.2)' } },
|
||||
axisLabel: { color: '#8899aa' }
|
||||
},
|
||||
xAxis: { data: ['<60', '60-70', '70-80', '80-90', '>90'], axisLabel: { color: '#8899aa' } },
|
||||
yAxis: {
|
||||
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.05)' } },
|
||||
axisLabel: { color: '#8899aa' }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: [3, 8, 15, 20, 4],
|
||||
barWidth: 20,
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#00e5ff' },
|
||||
{ offset: 1, color: '#0072ff' }
|
||||
]),
|
||||
borderRadius: [4, 4, 0, 0]
|
||||
}
|
||||
}
|
||||
]
|
||||
series: [{ type: 'bar', data: [3, 8, 15, 20, 4], itemStyle: { color: '#00e5ff' } }]
|
||||
})
|
||||
|
||||
const pieData = [
|
||||
{ value: 16, name: '未交' },
|
||||
{ value: 84, name: '已交' }
|
||||
]
|
||||
const pie = echarts.init(pieChartRef.value)
|
||||
pie.setOption({
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['45%', '70%'],
|
||||
data: pieData,
|
||||
label: { show: true, formatter: '{b}\n{d}%', color: '#8899aa' },
|
||||
itemStyle: { color: (p) => (p.name === '已交' ? '#00e5ff' : 'rgba(0, 114, 255, 0.4)') }
|
||||
data: [
|
||||
{ value: 16, name: '未交' },
|
||||
{ value: 84, name: '已交' }
|
||||
],
|
||||
label: { color: '#8899aa' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -176,9 +201,48 @@ const renderCharts = () => {
|
|||
type: 'pie',
|
||||
radius: ['70%', '100%'],
|
||||
silent: true,
|
||||
data: pieData,
|
||||
label: { show: false },
|
||||
itemStyle: { color: (p) => (p.name === '已交' ? '#00e5ff' : 'rgba(0, 114, 255, 0.4)') }
|
||||
data: [
|
||||
{ value: 16, name: '未交' },
|
||||
{ value: 84, name: '已交' }
|
||||
],
|
||||
label: { show: false }
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
const renderExtensionCharts = () => {
|
||||
// 1. 学情趋势折线图
|
||||
const trend = echarts.init(trendChartRef.value)
|
||||
trend.setOption({
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['周一', '周二', '周三', '周四', '周五'],
|
||||
axisLabel: { color: '#8899aa' }
|
||||
},
|
||||
yAxis: { type: 'value', axisLabel: { color: '#8899aa' }, splitLine: { show: false } },
|
||||
series: [{ data: [82, 85, 84, 88, 85], type: 'line', smooth: true, color: '#00e5ff' }]
|
||||
})
|
||||
|
||||
// 2. 知识点掌握雷达图
|
||||
const radar = echarts.init(radarChartRef.value)
|
||||
radar.setOption({
|
||||
radar: {
|
||||
indicator: [
|
||||
{ name: '词汇', max: 100 },
|
||||
{ name: '语法', max: 100 },
|
||||
{ name: '阅读', max: 100 },
|
||||
{ name: '写作', max: 100 },
|
||||
{ name: '听力', max: 100 }
|
||||
],
|
||||
axisName: { color: '#8899aa' }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'radar',
|
||||
data: [{ value: [85, 60, 90, 75, 80], name: '班级能力值' }],
|
||||
itemStyle: { color: '#ff9800' },
|
||||
areaStyle: { color: 'rgba(255,152,0,0.3)' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -193,11 +257,11 @@ const renderCharts = () => {
|
|||
color: #fff;
|
||||
|
||||
.header-section {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 25px;
|
||||
position: relative;
|
||||
.main-title {
|
||||
color: #00e5ff;
|
||||
font-size: 24px;
|
||||
|
|
@ -215,7 +279,6 @@ const renderCharts = () => {
|
|||
.el-input__wrapper {
|
||||
background-color: rgba(0, 162, 255, 0.05) !important;
|
||||
box-shadow: 0 0 0 1px rgba(0, 162, 255, 0.4) inset !important;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.el-input__inner {
|
||||
color: #00e5ff !important;
|
||||
|
|
@ -242,16 +305,10 @@ const renderCharts = () => {
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 12px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.label {
|
||||
font-size: 13px;
|
||||
color: #8899aa;
|
||||
}
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,97 +317,100 @@ const renderCharts = () => {
|
|||
border: 1px solid rgba(0, 162, 255, 0.15);
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
&.relative {
|
||||
position: relative;
|
||||
}
|
||||
.box-title {
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
border-left: 4px solid #00a2ff;
|
||||
padding-left: 10px;
|
||||
margin-bottom: 15px;
|
||||
color: #e0e6ed;
|
||||
}
|
||||
}
|
||||
|
||||
.mini-pie-wrapper {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
padding: 4px;
|
||||
border: 1px dashed rgba(0, 229, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.chart-height {
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.error-rank-list .rank-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
.rank-no {
|
||||
width: 90px;
|
||||
color: #8899aa;
|
||||
font-size: 13px;
|
||||
/* 拓展 Tabs 样式定制 */
|
||||
.custom-tabs {
|
||||
background: rgba(255, 255, 255, 0.02) !important;
|
||||
border: 1px solid rgba(0, 162, 255, 0.15) !important;
|
||||
:deep(.el-tabs__header) {
|
||||
background-color: rgba(0, 162, 255, 0.05) !important;
|
||||
border-bottom: 1px solid rgba(0, 162, 255, 0.15) !important;
|
||||
}
|
||||
.progress-bg {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: #1a2f45;
|
||||
margin: 0 15px;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, #0072ff, #00e5ff);
|
||||
:deep(.el-tabs__item) {
|
||||
color: #8899aa !important;
|
||||
&.is-active {
|
||||
color: #00e5ff !important;
|
||||
background-color: rgba(0, 162, 255, 0.1) !important;
|
||||
}
|
||||
}
|
||||
.rank-tag {
|
||||
background: rgba(0, 229, 255, 0.1);
|
||||
border: 1px solid rgba(0, 229, 255, 0.3);
|
||||
color: #00e5ff;
|
||||
padding: 1px 8px;
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
min-width: 42px;
|
||||
text-align: center;
|
||||
.inner-box {
|
||||
padding: 10px;
|
||||
.sub-title {
|
||||
font-size: 14px;
|
||||
color: #00e5ff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-table {
|
||||
background: transparent !important;
|
||||
--el-table-bg-color: transparent !important;
|
||||
--el-table-tr-bg-color: transparent !important;
|
||||
--el-table-header-bg-color: rgba(0, 162, 255, 0.05) !important;
|
||||
--el-table-border-color: rgba(0, 162, 255, 0.1) !important;
|
||||
:deep(th.el-table__cell) {
|
||||
border-bottom: none !important;
|
||||
color: #00e5ff;
|
||||
.warning-list .warning-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background: rgba(255, 77, 79, 0.05);
|
||||
margin-bottom: 8px;
|
||||
border-radius: 4px;
|
||||
.stu-name {
|
||||
color: #e0e6ed;
|
||||
}
|
||||
:deep(td.el-table__cell) {
|
||||
border-bottom: 1px solid rgba(0, 162, 255, 0.05) !important;
|
||||
.stu-desc {
|
||||
font-size: 12px;
|
||||
color: #8899aa;
|
||||
}
|
||||
}
|
||||
|
||||
.equal-height-row {
|
||||
display: flex;
|
||||
& > .el-col {
|
||||
display: flex;
|
||||
.point-card {
|
||||
background: rgba(0, 229, 255, 0.05);
|
||||
border: 1px solid rgba(0, 229, 255, 0.1);
|
||||
padding: 12px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 4px;
|
||||
color: #e0e6ed;
|
||||
}
|
||||
|
||||
.quality-stats .q-item {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border-radius: 8px;
|
||||
.q-label {
|
||||
color: #8899aa;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.full-height {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.q-val {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #00e5ff;
|
||||
}
|
||||
}
|
||||
|
||||
.report-area {
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
p {
|
||||
margin-bottom: 20px;
|
||||
color: #8899aa;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-height {
|
||||
height: 210px;
|
||||
}
|
||||
.margin-top-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.urge-btn {
|
||||
background: rgba(0, 162, 255, 0.2);
|
||||
border-color: #00a2ff;
|
||||
color: #00e5ff;
|
||||
background: rgba(0, 162, 255, 0.1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue