🔧 显示问题修复: - 修复参与学生人数显示布局问题,优化number-gauge-combined容器 - 调整迷你仪表盘尺寸从60px到45px,适配紧凑布局 - 优化数字显示样式,使用clamp()确保响应式适配 - 完善ECharts仪表盘配置,简化为迷你版本显示 🎯 功能按钮完善: - 实现"生成报告"和"历史记录"按钮完整功能 - 集成权限验证系统,需要教师权限才能访问 - 添加智能权限提示,未登录时引导用户登录 - 保持按钮原有美观样式,权限不足时仅显示小锁图标 🎨 界面文本优化: - 清理Login.vue中的"演示"字样,改为"登录" - 移除版权信息中的"演示版本"标识 - 优化组件中的演示相关文本,提升专业性 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2578 lines
57 KiB
Vue
2578 lines
57 KiB
Vue
<template>
|
|
<div class="big-screen-container">
|
|
<!-- 背景动画效果 -->
|
|
<div class="background-animation">
|
|
<div class="particle-network"></div>
|
|
</div>
|
|
|
|
<!-- 主标题区域 -->
|
|
<div class="header-section">
|
|
<h1 class="main-title">学生能力评价画像系统</h1>
|
|
<div class="subtitle">STUDENT CAPABILITY EVALUATION PORTRAIT</div>
|
|
<div class="current-time">{{ currentTime }}</div>
|
|
</div>
|
|
|
|
<!-- 主要内容区域 -->
|
|
<div class="main-content">
|
|
<!-- 左侧区域 -->
|
|
<div class="left-section">
|
|
<!-- 成绩分布 -->
|
|
<div class="module-container grade-distribution">
|
|
<div class="module-header">
|
|
<el-icon><TrendCharts /></el-icon>
|
|
<span>成绩分布</span>
|
|
</div>
|
|
<div ref="gradeChart" class="chart-container"></div>
|
|
</div>
|
|
|
|
<!-- 能力矩阵三角形 -->
|
|
<div class="module-container ability-matrix">
|
|
<div class="module-header">
|
|
<el-icon><Grid /></el-icon>
|
|
<span>能力矩阵</span>
|
|
</div>
|
|
<div ref="abilityChart" class="chart-container"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 中间区域 -->
|
|
<div class="center-section">
|
|
<!-- 核心指标展示区 -->
|
|
<div class="module-container core-metrics">
|
|
<div class="metrics-layout">
|
|
<!-- 左侧大区域 - 学生人数和仪表盘 -->
|
|
<div class="metric-main-area">
|
|
<div class="main-metric-header">
|
|
<el-icon><UserFilled /></el-icon>
|
|
<span>参与实习学生人数</span>
|
|
<div class="real-time-indicator">
|
|
<div class="pulse-dot"></div>
|
|
<span>实时</span>
|
|
</div>
|
|
</div>
|
|
<div class="main-metric-content ultra-compact">
|
|
<div class="metric-integrated-display">
|
|
<div class="number-gauge-combined">
|
|
<div class="number-display-section">
|
|
<div class="big-number">{{ studentCount }}</div>
|
|
<div class="number-unit">人</div>
|
|
</div>
|
|
<div ref="gaugeChart" class="gauge-mini"></div>
|
|
</div>
|
|
<div class="stats-grid-compact">
|
|
<div class="stat-pill">
|
|
<span class="stat-icon">📈</span>
|
|
<div class="stat-data">
|
|
<span class="stat-value positive">+12%</span>
|
|
<span class="stat-label">较上月</span>
|
|
</div>
|
|
</div>
|
|
<div class="stat-pill">
|
|
<span class="stat-icon">👥</span>
|
|
<div class="stat-data">
|
|
<span class="stat-value">+18人</span>
|
|
<span class="stat-label">新增</span>
|
|
</div>
|
|
</div>
|
|
<div class="stat-pill">
|
|
<span class="stat-icon">🎯</span>
|
|
<div class="stat-data">
|
|
<span class="stat-value">92%</span>
|
|
<span class="stat-label">活跃率</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 右侧指标墙 - 自适应显示 -->
|
|
<div class="metrics-wall">
|
|
<div class="wall-grid adaptive">
|
|
<!-- 完成率卡片 -->
|
|
<div class="wall-card completion-rate compact">
|
|
<div class="wall-icon">
|
|
<el-icon><TrendCharts /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">87.5%</div>
|
|
<div class="wall-label">完成率</div>
|
|
<div class="wall-trend positive">↗ +5.2%</div>
|
|
</div>
|
|
<div class="wall-progress mini">
|
|
<div class="progress-ring">
|
|
<div class="progress-fill" style="--progress: 87.5%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 平均评分卡片 -->
|
|
<div class="wall-card average-score compact">
|
|
<div class="wall-icon">
|
|
<el-icon><StarFilled /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">82.3</div>
|
|
<div class="wall-label">评分</div>
|
|
<div class="wall-trend positive">↗ +2.1%</div>
|
|
</div>
|
|
<div class="wall-rating mini">
|
|
<div class="stars">★★★★☆</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 活跃课程数 -->
|
|
<div class="wall-card active-courses compact">
|
|
<div class="wall-icon">
|
|
<el-icon><Reading /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">24</div>
|
|
<div class="wall-label">课程</div>
|
|
<div class="wall-trend positive">↗ +8%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 教师参与度 -->
|
|
<div class="wall-card teacher-participation compact">
|
|
<div class="wall-icon">
|
|
<el-icon><UserFilled /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">32</div>
|
|
<div class="wall-label">教师</div>
|
|
<div class="wall-trend positive">↗ +6%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 企业合作数 -->
|
|
<div class="wall-card enterprise-cooperation compact">
|
|
<div class="wall-icon">
|
|
<el-icon><OfficeBuilding /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">18</div>
|
|
<div class="wall-label">企业</div>
|
|
<div class="wall-trend positive">↗ +12%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 评价总数 -->
|
|
<div class="wall-card total-evaluations compact">
|
|
<div class="wall-icon">
|
|
<el-icon><DocumentChecked /></el-icon>
|
|
</div>
|
|
<div class="wall-content">
|
|
<div class="wall-number">1,247</div>
|
|
<div class="wall-label">评价</div>
|
|
<div class="wall-trend positive">↗ +15%</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 详细数据统计 -->
|
|
<div class="module-container detailed-stats">
|
|
<div class="module-header">
|
|
<el-icon><DataAnalysis /></el-icon>
|
|
<span>实习数据统计</span>
|
|
<div class="header-extra">
|
|
<span class="update-time">实时更新</span>
|
|
<div class="status-indicator"></div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-overview">
|
|
<div class="overview-item">
|
|
<div class="overview-icon">
|
|
<el-icon><Reading /></el-icon>
|
|
</div>
|
|
<div class="overview-content">
|
|
<div class="overview-number">24</div>
|
|
<div class="overview-label">实习课程</div>
|
|
<div class="overview-trend">
|
|
<span class="trend-value">+5%</span>
|
|
<el-icon><Top /></el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="overview-item">
|
|
<div class="overview-icon">
|
|
<el-icon><OfficeBuilding /></el-icon>
|
|
</div>
|
|
<div class="overview-content">
|
|
<div class="overview-number">8</div>
|
|
<div class="overview-label">专业覆盖</div>
|
|
<div class="overview-trend">
|
|
<span class="trend-value">+2</span>
|
|
<el-icon><Top /></el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="overview-item">
|
|
<div class="overview-icon">
|
|
<el-icon><UserFilled /></el-icon>
|
|
</div>
|
|
<div class="overview-content">
|
|
<div class="overview-number">32</div>
|
|
<div class="overview-label">辅导老师</div>
|
|
<div class="overview-trend">
|
|
<span class="trend-value">+8%</span>
|
|
<el-icon><Top /></el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="overview-item">
|
|
<div class="overview-icon">
|
|
<el-icon><School /></el-icon>
|
|
</div>
|
|
<div class="overview-content">
|
|
<div class="overview-number">18</div>
|
|
<div class="overview-label">合作企业</div>
|
|
<div class="overview-trend">
|
|
<span class="trend-value">+3</span>
|
|
<el-icon><Top /></el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="stats-chart">
|
|
<div ref="trendChart" class="trend-container"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 右侧区域 -->
|
|
<div class="right-section">
|
|
<!-- 学生名单 -->
|
|
<div class="module-container student-list">
|
|
<div class="module-header ultra-compact">
|
|
<el-icon><List /></el-icon>
|
|
<span>学生名单</span>
|
|
<div class="header-counter">共{{ studentList.length }}人</div>
|
|
</div>
|
|
<div class="student-table-enhanced">
|
|
<div class="table-header-enhanced">
|
|
<span>姓名</span>
|
|
<span>学号</span>
|
|
<span>状态</span>
|
|
<span>操作</span>
|
|
</div>
|
|
<div class="table-body-enhanced">
|
|
<div class="table-row-enhanced" v-for="student in studentList" :key="student.id">
|
|
<div class="student-info">
|
|
<div class="student-avatar">{{ student.name.charAt(0) }}</div>
|
|
<span class="student-name">{{ student.name }}</span>
|
|
</div>
|
|
<span class="student-id">{{ student.studentId }}</span>
|
|
<div class="student-status">
|
|
<span class="status-badge completed">已完成</span>
|
|
<span class="grade-indicator">{{ student.grade }}</span>
|
|
</div>
|
|
<div class="action-group">
|
|
<button class="action-btn primary" @click="viewReport(student.id)">
|
|
<el-icon><Document /></el-icon>
|
|
</button>
|
|
<button class="action-btn secondary">
|
|
<el-icon><View /></el-icon>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 多维度检测 -->
|
|
<div class="module-container multi-dimension">
|
|
<div class="module-header ultra-compact">
|
|
<el-icon><Monitor /></el-icon>
|
|
<span>智能分析</span>
|
|
<div class="analysis-status">
|
|
<div class="status-dot active"></div>
|
|
<span>就绪</span>
|
|
</div>
|
|
</div>
|
|
<div class="analysis-grid">
|
|
<div class="analysis-card" @click="analyzeDimension('image')">
|
|
<div class="card-icon image">
|
|
<el-icon><Picture /></el-icon>
|
|
</div>
|
|
<div class="card-content">
|
|
<span class="card-title">影像</span>
|
|
<span class="card-subtitle">AI视觉分析</span>
|
|
</div>
|
|
<div class="card-indicator">
|
|
<div class="progress-ring small">
|
|
<div class="progress-fill" style="--progress: 85%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="analysis-card" @click="analyzeDimension('audio')">
|
|
<div class="card-icon audio">
|
|
<el-icon><Microphone /></el-icon>
|
|
</div>
|
|
<div class="card-content">
|
|
<span class="card-title">音频</span>
|
|
<span class="card-subtitle">语音识别</span>
|
|
</div>
|
|
<div class="card-indicator">
|
|
<div class="progress-ring small">
|
|
<div class="progress-fill" style="--progress: 72%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="analysis-card" @click="analyzeDimension('text')">
|
|
<div class="card-icon text">
|
|
<el-icon><Edit /></el-icon>
|
|
</div>
|
|
<div class="card-content">
|
|
<span class="card-title">文本</span>
|
|
<span class="card-subtitle">NLP分析</span>
|
|
</div>
|
|
<div class="card-indicator">
|
|
<div class="progress-ring small">
|
|
<div class="progress-fill" style="--progress: 94%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 底部操作按钮 -->
|
|
<div class="action-buttons-enhanced">
|
|
<button
|
|
class="action-btn-large primary"
|
|
:class="{ 'requires-auth': !authStore.isLoggedIn || authStore.user?.role !== 'teacher' }"
|
|
@click="generateReport"
|
|
:title="!authStore.isLoggedIn ? '需要登录教师账号' : authStore.user?.role !== 'teacher' ? '需要教师权限' : '生成学生评价报告'"
|
|
>
|
|
<el-icon><DocumentAdd /></el-icon>
|
|
<span>生成报告</span>
|
|
</button>
|
|
<button
|
|
class="action-btn-large secondary"
|
|
:class="{ 'requires-auth': !authStore.isLoggedIn || authStore.user?.role !== 'teacher' }"
|
|
@click="viewHistory"
|
|
:title="!authStore.isLoggedIn ? '需要登录教师账号' : authStore.user?.role !== 'teacher' ? '需要教师权限' : '查看历史评价记录'"
|
|
>
|
|
<el-icon><Clock /></el-icon>
|
|
<span>历史记录</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, onMounted, onUnmounted, reactive } from 'vue'
|
|
import * as echarts from 'echarts'
|
|
import { useRouter } from 'vue-router'
|
|
import { ElMessage } from 'element-plus'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import { mockStudents, mockPortraitData, generateChartData, generateStatsData, bigScreenData } from '@/utils/mockData'
|
|
|
|
export default {
|
|
name: 'BigScreenPortrait',
|
|
setup() {
|
|
const router = useRouter()
|
|
const authStore = useAuthStore()
|
|
const currentTime = ref('')
|
|
const studentCount = ref(156)
|
|
const studentList = ref([])
|
|
const practiceStats = ref([])
|
|
|
|
// 图表实例
|
|
const gradeChart = ref(null)
|
|
const abilityChart = ref(null)
|
|
const gaugeChart = ref(null)
|
|
const trendChart = ref(null)
|
|
|
|
let chartInstances = []
|
|
let timer = null
|
|
|
|
// 初始化数据
|
|
const initData = () => {
|
|
studentList.value = mockStudents.slice(0, 8)
|
|
practiceStats.value = bigScreenData.practiceStats
|
|
studentCount.value = bigScreenData.realTimeData.studentCount
|
|
// 检查登录状态
|
|
authStore.checkAuth()
|
|
}
|
|
|
|
// 权限检查和导航的通用方法
|
|
const checkPermissionAndNavigate = (targetPath, requiredRole = null) => {
|
|
if (!authStore.isLoggedIn) {
|
|
ElMessage.warning('请先登录以使用此功能')
|
|
router.push('/')
|
|
return false
|
|
}
|
|
|
|
if (requiredRole && authStore.user?.role !== requiredRole) {
|
|
ElMessage.warning('权限不足,需要教师账号才能访问此功能')
|
|
return false
|
|
}
|
|
|
|
router.push(targetPath)
|
|
return true
|
|
}
|
|
|
|
// 更新时间
|
|
const updateTime = () => {
|
|
const now = new Date()
|
|
currentTime.value = now.toLocaleString('zh-CN', {
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit'
|
|
})
|
|
}
|
|
|
|
// 初始化成绩分布图表
|
|
const initGradeChart = () => {
|
|
const chart = echarts.init(gradeChart.value)
|
|
const data = bigScreenData.gradeDistribution
|
|
|
|
const option = {
|
|
backgroundColor: 'transparent',
|
|
grid: {
|
|
left: '10%',
|
|
right: '10%',
|
|
top: '15%',
|
|
bottom: '15%'
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: data.map(item => item.grade),
|
|
axisLine: {
|
|
lineStyle: { color: '#3b82f6' }
|
|
},
|
|
axisLabel: {
|
|
color: '#e2e8f0',
|
|
fontSize: 12,
|
|
rotate: 45
|
|
}
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLine: {
|
|
lineStyle: { color: '#3b82f6' }
|
|
},
|
|
axisLabel: {
|
|
color: '#e2e8f0',
|
|
fontSize: 12
|
|
},
|
|
splitLine: {
|
|
lineStyle: { color: 'rgba(59, 130, 246, 0.2)' }
|
|
}
|
|
},
|
|
series: [{
|
|
data: data.map((item, index) => ({
|
|
value: item.count,
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: item.color },
|
|
{ offset: 1, color: `${item.color}80` }
|
|
]),
|
|
borderRadius: [4, 4, 0, 0]
|
|
}
|
|
})),
|
|
type: 'bar',
|
|
barWidth: '50%',
|
|
label: {
|
|
show: true,
|
|
position: 'top',
|
|
color: '#e2e8f0',
|
|
fontSize: 14,
|
|
fontWeight: 'bold',
|
|
formatter: '{c}人'
|
|
},
|
|
animationDuration: 2000,
|
|
animationEasing: 'elasticOut'
|
|
}]
|
|
}
|
|
|
|
chart.setOption(option)
|
|
chartInstances.push(chart)
|
|
}
|
|
|
|
// 初始化能力矩阵图表
|
|
const initAbilityChart = () => {
|
|
const chart = echarts.init(abilityChart.value)
|
|
const abilityData = bigScreenData.abilityMatrix
|
|
|
|
const option = {
|
|
backgroundColor: 'transparent',
|
|
radar: {
|
|
indicator: abilityData.dimensions.map(dim => ({
|
|
name: dim,
|
|
max: 100
|
|
})),
|
|
center: ['50%', '50%'],
|
|
radius: '70%',
|
|
axisName: {
|
|
color: '#e2e8f0',
|
|
fontSize: 14,
|
|
fontWeight: 'bold',
|
|
backgroundColor: 'rgba(30, 58, 138, 0.8)',
|
|
borderRadius: 4,
|
|
padding: [4, 8]
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
color: 'rgba(59, 130, 246, 0.3)',
|
|
width: 2
|
|
}
|
|
},
|
|
splitArea: {
|
|
areaStyle: {
|
|
color: [
|
|
'rgba(6, 182, 212, 0.1)',
|
|
'rgba(6, 182, 212, 0.2)',
|
|
'rgba(59, 130, 246, 0.1)',
|
|
'rgba(59, 130, 246, 0.2)'
|
|
]
|
|
}
|
|
},
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: 'rgba(59, 130, 246, 0.5)',
|
|
width: 2
|
|
}
|
|
}
|
|
},
|
|
series: [{
|
|
type: 'radar',
|
|
data: abilityData.students.map((student, index) => ({
|
|
value: student.values,
|
|
name: student.name,
|
|
areaStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: `${student.color}80` },
|
|
{ offset: 1, color: `${student.color}20` }
|
|
])
|
|
},
|
|
lineStyle: {
|
|
color: student.color,
|
|
width: 3,
|
|
shadowBlur: 10,
|
|
shadowColor: student.color
|
|
},
|
|
symbol: 'circle',
|
|
symbolSize: 10,
|
|
itemStyle: {
|
|
color: student.color,
|
|
borderColor: '#fff',
|
|
borderWidth: 2,
|
|
shadowBlur: 10,
|
|
shadowColor: student.color
|
|
}
|
|
})),
|
|
animationDuration: 2000,
|
|
animationEasing: 'elasticOut'
|
|
}],
|
|
legend: {
|
|
data: abilityData.students.map(s => s.name),
|
|
textStyle: {
|
|
color: '#e2e8f0',
|
|
fontSize: 12
|
|
},
|
|
bottom: 10,
|
|
itemWidth: 20,
|
|
itemHeight: 10
|
|
}
|
|
}
|
|
|
|
chart.setOption(option)
|
|
chartInstances.push(chart)
|
|
}
|
|
|
|
// 初始化仪表盘图表(迷你版)
|
|
const initGaugeChart = () => {
|
|
const chart = echarts.init(gaugeChart.value)
|
|
|
|
const option = {
|
|
backgroundColor: 'transparent',
|
|
series: [{
|
|
type: 'gauge',
|
|
startAngle: 200,
|
|
endAngle: -20,
|
|
center: ['50%', '60%'],
|
|
radius: '85%',
|
|
min: 0,
|
|
max: 200,
|
|
splitNumber: 2,
|
|
itemStyle: {
|
|
color: '#06b6d4'
|
|
},
|
|
progress: {
|
|
show: true,
|
|
width: 8,
|
|
roundCap: true,
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
{ offset: 0, color: '#06b6d4' },
|
|
{ offset: 1, color: '#3b82f6' }
|
|
])
|
|
}
|
|
},
|
|
pointer: {
|
|
show: false
|
|
},
|
|
axisLine: {
|
|
lineStyle: {
|
|
width: 8,
|
|
color: [[1, 'rgba(59, 130, 246, 0.15)']]
|
|
}
|
|
},
|
|
axisTick: {
|
|
show: false
|
|
},
|
|
splitLine: {
|
|
show: false
|
|
},
|
|
axisLabel: {
|
|
show: false
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: studentCount.value,
|
|
name: ''
|
|
}],
|
|
animationDuration: 2000
|
|
}]
|
|
}
|
|
|
|
chart.setOption(option)
|
|
chartInstances.push(chart)
|
|
}
|
|
|
|
// 初始化趋势图表
|
|
const initTrendChart = () => {
|
|
const chart = echarts.init(trendChart.value)
|
|
|
|
const option = {
|
|
backgroundColor: 'transparent',
|
|
grid: {
|
|
left: '5%',
|
|
right: '5%',
|
|
top: '10%',
|
|
bottom: '15%'
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
|
axisLine: { show: false },
|
|
axisTick: { show: false },
|
|
axisLabel: {
|
|
color: '#94a3b8',
|
|
fontSize: 10
|
|
}
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLine: { show: false },
|
|
axisTick: { show: false },
|
|
axisLabel: { show: false },
|
|
splitLine: { show: false }
|
|
},
|
|
series: [{
|
|
data: [120, 132, 145, 134, 156, 165],
|
|
type: 'line',
|
|
smooth: true,
|
|
lineStyle: {
|
|
color: '#06b6d4',
|
|
width: 3,
|
|
shadowBlur: 10,
|
|
shadowColor: '#06b6d4'
|
|
},
|
|
areaStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: 'rgba(6, 182, 212, 0.3)' },
|
|
{ offset: 1, color: 'rgba(6, 182, 212, 0.05)' }
|
|
])
|
|
},
|
|
symbol: 'circle',
|
|
symbolSize: 6,
|
|
itemStyle: {
|
|
color: '#06b6d4',
|
|
borderColor: '#fff',
|
|
borderWidth: 2
|
|
},
|
|
animationDuration: 2000
|
|
}]
|
|
}
|
|
|
|
chart.setOption(option)
|
|
chartInstances.push(chart)
|
|
}
|
|
|
|
// 查看报告
|
|
const viewReport = (studentId) => {
|
|
router.push(`/report/${studentId}`)
|
|
}
|
|
|
|
// 多维度分析
|
|
const analyzeDimension = (type) => {
|
|
ElMessage.success(`正在分析${type === 'image' ? '影像' : type === 'audio' ? '音频' : '文本'}数据...`)
|
|
}
|
|
|
|
// 生成报告 - 跳转到报告中心
|
|
const generateReport = () => {
|
|
checkPermissionAndNavigate('/home/reports', 'teacher')
|
|
}
|
|
|
|
// 查看历史记录 - 跳转到报告中心
|
|
const viewHistory = () => {
|
|
checkPermissionAndNavigate('/home/reports', 'teacher')
|
|
}
|
|
|
|
// 窗口大小调整处理
|
|
const handleResize = () => {
|
|
chartInstances.forEach(chart => {
|
|
chart.resize()
|
|
})
|
|
}
|
|
|
|
// 初始化
|
|
onMounted(() => {
|
|
initData()
|
|
updateTime()
|
|
timer = setInterval(updateTime, 1000)
|
|
|
|
setTimeout(() => {
|
|
initGradeChart()
|
|
initAbilityChart()
|
|
initGaugeChart()
|
|
initTrendChart()
|
|
}, 100)
|
|
|
|
window.addEventListener('resize', handleResize)
|
|
})
|
|
|
|
// 清理
|
|
onUnmounted(() => {
|
|
if (timer) clearInterval(timer)
|
|
window.removeEventListener('resize', handleResize)
|
|
chartInstances.forEach(chart => {
|
|
chart.dispose()
|
|
})
|
|
})
|
|
|
|
return {
|
|
currentTime,
|
|
studentCount,
|
|
studentList,
|
|
practiceStats,
|
|
gradeChart,
|
|
abilityChart,
|
|
gaugeChart,
|
|
trendChart,
|
|
authStore,
|
|
viewReport,
|
|
analyzeDimension,
|
|
generateReport,
|
|
viewHistory
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.big-screen-container {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background: linear-gradient(135deg, #0a1027 0%, #1e3a8a 50%, #1e40af 100%);
|
|
position: relative;
|
|
overflow: hidden;
|
|
font-family: 'Arial', sans-serif;
|
|
}
|
|
|
|
/* 背景动画效果 */
|
|
.background-animation {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 1;
|
|
}
|
|
|
|
.particle-network {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-image:
|
|
radial-gradient(circle at 20% 80%, rgba(59, 130, 246, 0.1) 0%, transparent 50%),
|
|
radial-gradient(circle at 80% 20%, rgba(6, 182, 212, 0.1) 0%, transparent 50%),
|
|
radial-gradient(circle at 40% 40%, rgba(16, 185, 129, 0.05) 0%, transparent 50%);
|
|
animation: particleFloat 20s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes particleFloat {
|
|
0%, 100% { transform: translateY(0px) rotate(0deg); }
|
|
50% { transform: translateY(-20px) rotate(180deg); }
|
|
}
|
|
|
|
/* 标题区域 */
|
|
.header-section {
|
|
position: relative;
|
|
z-index: 10;
|
|
text-align: center;
|
|
padding: 12px 0;
|
|
background: var(--primary-alpha-heavy);
|
|
backdrop-filter: var(--glass-blur);
|
|
border-bottom: 1px solid rgba(59, 130, 246, 0.3);
|
|
}
|
|
|
|
.main-title {
|
|
font-size: 36px;
|
|
font-weight: bold;
|
|
color: #e2e8f0;
|
|
margin: 0;
|
|
text-shadow: 0 0 15px rgba(59, 130, 246, 0.6);
|
|
background: linear-gradient(45deg, var(--secondary), var(--primary-light), var(--purple));
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
}
|
|
|
|
.subtitle {
|
|
font-size: 14px;
|
|
color: var(--gray-light);
|
|
margin: 6px 0;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.current-time {
|
|
position: absolute;
|
|
right: 20px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
font-size: 12px;
|
|
color: #e2e8f0;
|
|
background: var(--primary-alpha-heavy);
|
|
padding: 4px 10px;
|
|
border-radius: var(--radius-xl);
|
|
border: 1px solid rgba(59, 130, 246, 0.25);
|
|
}
|
|
|
|
/* 主内容区域 - 优化间距和布局 */
|
|
.main-content {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1.3fr 0.9fr;
|
|
gap: 10px;
|
|
padding: 10px;
|
|
height: calc(100vh - 100px);
|
|
position: relative;
|
|
z-index: 5;
|
|
}
|
|
|
|
/* 模块容器 - 减少内边距 */
|
|
.module-container {
|
|
background: rgba(30, 58, 138, 0.15);
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: var(--radius-md);
|
|
padding: 12px;
|
|
backdrop-filter: blur(10px);
|
|
box-shadow: var(--shadow-md);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.module-container::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, transparent 50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.module-container.compact {
|
|
padding: 10px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.module-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
color: #e2e8f0;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.module-header .el-icon {
|
|
font-size: 18px;
|
|
color: var(--secondary);
|
|
}
|
|
|
|
/* 图表容器 */
|
|
.chart-container {
|
|
width: 100%;
|
|
height: 250px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.gauge-container {
|
|
width: 100%;
|
|
height: 200px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.gauge-container.compact {
|
|
height: 120px;
|
|
}
|
|
|
|
/* 左侧区域 - 紧凑布局 */
|
|
.left-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.grade-distribution {
|
|
flex: 1;
|
|
}
|
|
|
|
.ability-matrix {
|
|
flex: 1;
|
|
}
|
|
|
|
/* 中间区域 - 紧凑布局 */
|
|
.center-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* SOTA标准优化样式 */
|
|
|
|
/* 超紧凑布局 */
|
|
.main-metric-content.ultra-compact {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
height: 100%;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.metric-integrated-display {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
height: 100%;
|
|
}
|
|
|
|
.number-gauge-combined {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
background: var(--primary-alpha-medium);
|
|
border-radius: var(--radius-md);
|
|
padding: 10px 15px;
|
|
border: 1px solid rgba(59, 130, 246, 0.2);
|
|
min-height: 70px;
|
|
}
|
|
|
|
.number-display-section {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 6px;
|
|
flex: 1;
|
|
}
|
|
|
|
.gauge-mini {
|
|
width: 45px;
|
|
height: 45px;
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.stats-grid-compact {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 4px;
|
|
flex: 1;
|
|
}
|
|
|
|
.stat-pill {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
background: var(--primary-alpha-heavy);
|
|
border: 1px solid rgba(59, 130, 246, 0.25);
|
|
border-radius: var(--radius-lg);
|
|
padding: 6px 10px;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.stat-pill:hover {
|
|
background: var(--primary-alpha-heavy);
|
|
border-color: rgba(59, 130, 246, 0.4);
|
|
transform: translateX(2px);
|
|
}
|
|
|
|
.stat-icon {
|
|
font-size: 12px;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.stat-data {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1px;
|
|
}
|
|
|
|
.stat-data .stat-value {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
.stat-data .stat-label {
|
|
font-size: 9px;
|
|
color: #94a3b8;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* 核心指标展示区 */
|
|
.core-metrics {
|
|
flex: 1;
|
|
}
|
|
|
|
.metrics-layout {
|
|
display: grid;
|
|
grid-template-columns: 1.4fr 1fr;
|
|
gap: 12px;
|
|
height: 100%;
|
|
}
|
|
|
|
.metric-main-area {
|
|
background: rgba(30, 58, 138, 0.2);
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: var(--radius-md);
|
|
padding: 15px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.metric-main-area::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, transparent 50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.metric-main-area:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 12px 40px rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
.main-metric-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.main-metric-header .el-icon {
|
|
font-size: 20px;
|
|
color: #06b6d4;
|
|
}
|
|
|
|
.main-metric-header span {
|
|
font-size: 16px;
|
|
color: #e2e8f0;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.real-time-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
margin-left: auto;
|
|
font-size: 10px;
|
|
color: var(--success);
|
|
background: var(--success-alpha-medium);
|
|
padding: 3px 6px;
|
|
border-radius: var(--radius-lg);
|
|
border: 1px solid rgba(16, 185, 129, 0.25);
|
|
}
|
|
|
|
.pulse-dot {
|
|
width: 5px;
|
|
height: 5px;
|
|
background: var(--success);
|
|
border-radius: 50%;
|
|
animation: pulse 1.5s infinite;
|
|
}
|
|
|
|
.main-metric-content {
|
|
display: flex;
|
|
gap: 12px;
|
|
flex: 1;
|
|
align-items: center;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.main-metric-content.compact {
|
|
gap: 10px;
|
|
align-items: center;
|
|
}
|
|
|
|
.main-metric-content.compact .metric-number-section {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.main-metric-content.compact .metric-chart-section {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.metric-number-section {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.number-display {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 8px;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: clamp(28px, 2.8vw, 36px);
|
|
font-weight: 700;
|
|
color: #e2e8f0;
|
|
text-shadow: 0 0 15px rgba(6, 182, 212, 0.5);
|
|
line-height: 1;
|
|
letter-spacing: -0.5px;
|
|
}
|
|
|
|
.number-unit {
|
|
font-size: 16px;
|
|
color: #94a3b8;
|
|
font-weight: 500;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.number-stats {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.stat-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.stat-label {
|
|
color: #94a3b8;
|
|
}
|
|
|
|
.stat-value {
|
|
color: #e2e8f0;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.stat-value.positive {
|
|
color: #10b981;
|
|
}
|
|
|
|
.metric-chart-section {
|
|
width: 200px;
|
|
height: 150px;
|
|
}
|
|
|
|
/* 指标墙 */
|
|
.metrics-wall {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
height: 100%;
|
|
}
|
|
|
|
.wall-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-auto-rows: minmax(50px, 1fr);
|
|
gap: 6px;
|
|
height: 100%;
|
|
}
|
|
|
|
.wall-grid.adaptive {
|
|
gap: 4px;
|
|
grid-template-rows: repeat(3, 1fr);
|
|
}
|
|
|
|
.wall-card {
|
|
background: rgba(30, 58, 138, 0.12);
|
|
border: 1px solid rgba(59, 130, 246, 0.18);
|
|
border-radius: var(--radius-sm);
|
|
padding: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.wall-card:hover {
|
|
background: rgba(30, 58, 138, 0.25);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1);
|
|
}
|
|
|
|
.wall-card.compact {
|
|
padding: 6px 8px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.wall-icon {
|
|
font-size: 14px;
|
|
color: var(--secondary);
|
|
margin-bottom: 4px;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.wall-card.compact .wall-icon {
|
|
font-size: 12px;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.wall-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.wall-number {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
margin-bottom: 2px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.wall-card.compact .wall-number {
|
|
font-size: 16px;
|
|
margin-bottom: 1px;
|
|
}
|
|
|
|
.wall-label {
|
|
font-size: 10px;
|
|
color: #94a3b8;
|
|
margin-bottom: 3px;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.wall-card.compact .wall-label {
|
|
font-size: 9px;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.wall-trend {
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.wall-card.compact .wall-trend {
|
|
font-size: 9px;
|
|
}
|
|
|
|
.wall-trend.positive {
|
|
color: var(--success);
|
|
}
|
|
|
|
.wall-trend.negative {
|
|
color: var(--danger);
|
|
}
|
|
|
|
/* 特殊卡片样式 */
|
|
.wall-progress {
|
|
position: absolute;
|
|
top: 10px;
|
|
right: 10px;
|
|
}
|
|
|
|
.wall-progress.mini {
|
|
top: 6px;
|
|
right: 6px;
|
|
}
|
|
|
|
.progress-ring {
|
|
width: 32px;
|
|
height: 32px;
|
|
position: relative;
|
|
}
|
|
|
|
.wall-progress.mini .progress-ring {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
.progress-ring::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
right: 2px;
|
|
bottom: 2px;
|
|
border: 2px solid rgba(59, 130, 246, 0.2);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.wall-progress.mini .progress-ring::before {
|
|
border-width: 1px;
|
|
}
|
|
|
|
.progress-ring::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
border: 3px solid transparent;
|
|
border-top: 3px solid #06b6d4;
|
|
border-right: 3px solid #06b6d4;
|
|
border-radius: 50%;
|
|
transform: rotate(-45deg);
|
|
animation: rotateProgress 2s linear infinite;
|
|
}
|
|
|
|
.wall-progress.mini .progress-ring::after {
|
|
border-width: 2px;
|
|
}
|
|
|
|
@keyframes rotateProgress {
|
|
from { transform: rotate(-45deg); }
|
|
to { transform: rotate(315deg); }
|
|
}
|
|
|
|
.wall-rating {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.wall-rating.mini {
|
|
margin-top: 3px;
|
|
}
|
|
|
|
.wall-rating.mini .stars {
|
|
font-size: 10px;
|
|
}
|
|
|
|
.stars {
|
|
color: #f59e0b;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.rating-text {
|
|
font-size: 10px;
|
|
color: #94a3b8;
|
|
}
|
|
|
|
/* 多维度检测按钮优化 */
|
|
.dimension-buttons {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 4px;
|
|
margin-bottom: 8px;
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* 分析网格 */
|
|
.analysis-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 6px;
|
|
margin-bottom: 12px;
|
|
flex: 1;
|
|
}
|
|
|
|
.analysis-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 8px 10px;
|
|
background: var(--primary-alpha-medium);
|
|
border: 1px solid rgba(59, 130, 246, 0.25);
|
|
border-radius: var(--radius-md);
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.analysis-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, transparent 50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.analysis-card:hover {
|
|
background: var(--primary-alpha-heavy);
|
|
border-color: rgba(59, 130, 246, 0.4);
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
.card-icon {
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: var(--radius-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 14px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.card-icon.image {
|
|
background: linear-gradient(135deg, #f59e0b, #f97316);
|
|
color: white;
|
|
}
|
|
|
|
.card-icon.audio {
|
|
background: linear-gradient(135deg, #8b5cf6, #a855f7);
|
|
color: white;
|
|
}
|
|
|
|
.card-icon.text {
|
|
background: linear-gradient(135deg, #10b981, #059669);
|
|
color: white;
|
|
}
|
|
|
|
.card-content {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.card-title {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
.card-subtitle {
|
|
font-size: 9px;
|
|
color: var(--gray-light);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.card-indicator {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.progress-ring.small {
|
|
width: 20px;
|
|
height: 20px;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-ring.small::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
right: 2px;
|
|
bottom: 2px;
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.progress-ring.small .progress-fill {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
border: 2px solid transparent;
|
|
border-top: 2px solid var(--secondary);
|
|
border-right: 2px solid var(--secondary);
|
|
border-radius: 50%;
|
|
transform: rotate(-45deg);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* 增强型操作按钮 */
|
|
.action-buttons-enhanced {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 6px;
|
|
margin-top: auto;
|
|
}
|
|
|
|
.action-btn-large {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 4px;
|
|
padding: 8px 10px;
|
|
border: none;
|
|
border-radius: var(--radius-md);
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.action-btn-large::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
|
transition: left 0.5s;
|
|
}
|
|
|
|
.action-btn-large:hover::before {
|
|
left: 100%;
|
|
}
|
|
|
|
.action-btn-large.primary {
|
|
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
|
color: white;
|
|
}
|
|
|
|
.action-btn-large.primary:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
.action-btn-large.secondary {
|
|
background: linear-gradient(135deg, var(--gray), var(--gray-light));
|
|
color: white;
|
|
}
|
|
|
|
.action-btn-large.secondary:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.action-btn-large .el-icon {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.action-btn-large span {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
/* 权限相关样式 - 只在权限不足时显示限制样式 */
|
|
.action-btn-large.requires-auth {
|
|
position: relative;
|
|
}
|
|
|
|
.action-btn-large.requires-auth::after {
|
|
content: '🔒';
|
|
position: absolute;
|
|
top: -5px;
|
|
right: -5px;
|
|
background: var(--warning);
|
|
color: white;
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 10px;
|
|
border: 2px solid var(--bg-primary);
|
|
z-index: 10;
|
|
}
|
|
|
|
.dimension-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 6px 8px;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(6, 182, 212, 0.15) 100%);
|
|
border: 1px solid rgba(59, 130, 246, 0.25);
|
|
border-radius: var(--radius-sm);
|
|
color: #e2e8f0;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
font-size: 11px;
|
|
min-height: 32px;
|
|
}
|
|
|
|
.dimension-btn:hover {
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.3) 0%, rgba(6, 182, 212, 0.3) 100%);
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
.dimension-btn .el-icon {
|
|
font-size: 12px;
|
|
color: var(--secondary);
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.wall-mini-chart {
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.mini-bars {
|
|
display: flex;
|
|
align-items: end;
|
|
gap: 2px;
|
|
height: 20px;
|
|
}
|
|
|
|
.bar {
|
|
width: 4px;
|
|
background: linear-gradient(to top, #06b6d4, #3b82f6);
|
|
border-radius: 2px;
|
|
animation: barGrow 1s ease-out;
|
|
}
|
|
|
|
@keyframes barGrow {
|
|
from { height: 0; }
|
|
to { height: var(--height); }
|
|
}
|
|
|
|
.wall-avatar-list {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.avatar-circle {
|
|
width: 16px;
|
|
height: 16px;
|
|
border-radius: 50%;
|
|
background: linear-gradient(135deg, #06b6d4, #3b82f6);
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
}
|
|
|
|
.avatar-more {
|
|
font-size: 10px;
|
|
color: #94a3b8;
|
|
background: rgba(147, 197, 253, 0.2);
|
|
padding: 2px 4px;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.wall-enterprise-icons {
|
|
display: flex;
|
|
gap: 4px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.enterprise-icon {
|
|
font-size: 14px;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.wall-evaluation-status {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.status-item {
|
|
font-size: 10px;
|
|
padding: 2px 4px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.status-item.completed {
|
|
color: #10b981;
|
|
background: rgba(16, 185, 129, 0.2);
|
|
}
|
|
|
|
.status-item.pending {
|
|
color: #f59e0b;
|
|
background: rgba(245, 158, 11, 0.2);
|
|
}
|
|
|
|
/* 操作按钮优化 */
|
|
.action-buttons {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 6px;
|
|
margin-top: 8px;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.action-buttons .el-button {
|
|
background: linear-gradient(135deg, var(--primary-light) 0%, var(--secondary) 100%);
|
|
border: none;
|
|
color: white;
|
|
font-weight: 500;
|
|
transition: var(--transition);
|
|
padding: 4px 8px;
|
|
font-size: 10px;
|
|
height: 28px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.action-buttons .el-button:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-md);
|
|
opacity: 0.95;
|
|
}
|
|
|
|
.action-buttons .el-button.el-button--info {
|
|
background: linear-gradient(135deg, var(--gray) 0%, var(--gray-light) 100%);
|
|
}
|
|
|
|
/* 详细数据统计 */
|
|
.detailed-stats {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.header-extra {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-left: auto;
|
|
}
|
|
|
|
.update-time {
|
|
font-size: 11px;
|
|
color: var(--gray-light);
|
|
background: var(--primary-alpha-heavy);
|
|
padding: 3px 6px;
|
|
border-radius: var(--radius-lg);
|
|
}
|
|
|
|
.status-indicator {
|
|
width: 6px;
|
|
height: 6px;
|
|
background: var(--success);
|
|
border-radius: 50%;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.stats-overview {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 10px;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.overview-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px;
|
|
background: var(--primary-alpha-medium);
|
|
border-radius: var(--radius-sm);
|
|
border: 1px solid rgba(59, 130, 246, 0.18);
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.overview-item:hover {
|
|
background: var(--primary-alpha-heavy);
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.overview-icon {
|
|
font-size: 20px;
|
|
color: var(--secondary);
|
|
background: var(--secondary-alpha-heavy);
|
|
padding: 6px;
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
.overview-number {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
margin-bottom: 1px;
|
|
}
|
|
|
|
.overview-label {
|
|
font-size: 11px;
|
|
color: var(--gray-light);
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.overview-trend {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
font-size: 11px;
|
|
color: var(--success);
|
|
}
|
|
|
|
.trend-value {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.stats-chart {
|
|
height: 100px;
|
|
background: var(--primary-alpha-medium);
|
|
border-radius: var(--radius-sm);
|
|
border: 1px solid rgba(59, 130, 246, 0.15);
|
|
}
|
|
|
|
.trend-container {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
/* 右侧区域 - 优化布局 */
|
|
.right-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
height: 100%;
|
|
}
|
|
|
|
.student-list {
|
|
flex: 1.3;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
max-height: 65%;
|
|
}
|
|
|
|
.multi-dimension {
|
|
flex: 0.7;
|
|
min-height: 180px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
max-height: 35%;
|
|
}
|
|
|
|
/* 多维度检测按钮 */
|
|
.dimension-buttons {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.dimension-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 12px 16px;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(6, 182, 212, 0.2) 100%);
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: 8px;
|
|
color: #e2e8f0;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.dimension-btn:hover {
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.3) 0%, rgba(6, 182, 212, 0.3) 100%);
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
.dimension-btn .el-icon {
|
|
font-size: 16px;
|
|
color: #06b6d4;
|
|
}
|
|
|
|
/* 操作按钮 */
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.action-buttons .el-button {
|
|
flex: 1;
|
|
background: linear-gradient(135deg, #3b82f6 0%, #06b6d4 100%);
|
|
border: none;
|
|
color: white;
|
|
font-weight: bold;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.action-buttons .el-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 20px rgba(59, 130, 246, 0.3);
|
|
}
|
|
|
|
.action-buttons .el-button.el-button--info {
|
|
background: linear-gradient(135deg, var(--gray) 0%, var(--gray-light) 100%);
|
|
}
|
|
|
|
/* 学生表格 - 紧凑设计 */
|
|
.student-table {
|
|
background: rgba(30, 58, 138, 0.08);
|
|
border-radius: var(--radius-sm);
|
|
overflow: hidden;
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
border: 1px solid rgba(59, 130, 246, 0.15);
|
|
}
|
|
|
|
/* 增强型学生表格 */
|
|
.student-table-enhanced {
|
|
background: var(--primary-alpha-medium);
|
|
border-radius: var(--radius-md);
|
|
overflow: hidden;
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
border: 1px solid rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
.table-header-enhanced {
|
|
display: grid;
|
|
grid-template-columns: 1.5fr 1fr 1fr 0.8fr;
|
|
gap: 8px;
|
|
padding: 8px 12px;
|
|
background: var(--primary-alpha-heavy);
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
font-size: 11px;
|
|
flex: 0 0 auto;
|
|
border-bottom: 1px solid rgba(59, 130, 246, 0.3);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.table-body-enhanced {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
padding: 4px;
|
|
}
|
|
|
|
.table-row-enhanced {
|
|
display: grid;
|
|
grid-template-columns: 1.5fr 1fr 1fr 0.8fr;
|
|
gap: 8px;
|
|
padding: 8px 12px;
|
|
margin: 2px 0;
|
|
border-radius: var(--radius-sm);
|
|
color: #e2e8f0;
|
|
font-size: 11px;
|
|
align-items: center;
|
|
transition: var(--transition);
|
|
background: var(--primary-alpha-light);
|
|
border: 1px solid transparent;
|
|
}
|
|
|
|
.table-row-enhanced:hover {
|
|
background: var(--primary-alpha-medium);
|
|
border-color: rgba(59, 130, 246, 0.3);
|
|
transform: translateX(2px);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.student-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.student-avatar {
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
background: var(--secondary);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.student-name {
|
|
font-weight: 500;
|
|
}
|
|
|
|
.student-id {
|
|
font-family: monospace;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.student-status {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.status-badge {
|
|
padding: 2px 6px;
|
|
border-radius: var(--radius-lg);
|
|
font-size: 9px;
|
|
font-weight: 500;
|
|
text-align: center;
|
|
}
|
|
|
|
.status-badge.completed {
|
|
background: var(--success-alpha-medium);
|
|
color: var(--success);
|
|
border: 1px solid rgba(16, 185, 129, 0.2);
|
|
}
|
|
|
|
.grade-indicator {
|
|
font-size: 8px;
|
|
color: var(--gray-light);
|
|
text-align: center;
|
|
}
|
|
|
|
.action-group {
|
|
display: flex;
|
|
gap: 4px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.action-btn {
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: var(--radius-sm);
|
|
border: none;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
font-size: 10px;
|
|
}
|
|
|
|
.action-btn.primary {
|
|
background: var(--secondary-alpha-medium);
|
|
color: var(--secondary);
|
|
border: 1px solid rgba(6, 182, 212, 0.2);
|
|
}
|
|
|
|
.action-btn.primary:hover {
|
|
background: var(--secondary-alpha-heavy);
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.action-btn.secondary {
|
|
background: var(--gray-alpha-medium);
|
|
color: var(--gray-light);
|
|
border: 1px solid rgba(148, 163, 184, 0.2);
|
|
}
|
|
|
|
.action-btn.secondary:hover {
|
|
background: var(--gray-alpha-heavy);
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.table-header {
|
|
display: grid;
|
|
grid-template-columns: 0.8fr 1fr 0.6fr 0.8fr;
|
|
gap: 4px;
|
|
padding: 8px 10px;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.25) 0%, rgba(6, 182, 212, 0.2) 100%);
|
|
font-weight: 600;
|
|
color: #e2e8f0;
|
|
font-size: 11px;
|
|
flex: 0 0 auto;
|
|
border-bottom: 1px solid rgba(59, 130, 246, 0.3);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.table-body {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
max-height: 100%;
|
|
padding: 4px;
|
|
}
|
|
|
|
.table-row {
|
|
display: grid;
|
|
grid-template-columns: 0.8fr 1fr 0.6fr 0.8fr;
|
|
gap: 4px;
|
|
padding: 8px 10px;
|
|
margin: 2px 4px;
|
|
border-radius: var(--radius-sm);
|
|
color: #e2e8f0;
|
|
font-size: 11px;
|
|
align-items: center;
|
|
transition: var(--transition);
|
|
background: rgba(30, 58, 138, 0.05);
|
|
border: 1px solid transparent;
|
|
}
|
|
|
|
.table-row:hover {
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(6, 182, 212, 0.1) 100%);
|
|
border-color: rgba(59, 130, 246, 0.2);
|
|
transform: translateX(2px);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.table-row:last-child {
|
|
border-bottom: none;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.report-link {
|
|
color: var(--secondary);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
padding: 3px 6px;
|
|
border-radius: var(--radius-sm);
|
|
background: rgba(6, 182, 212, 0.1);
|
|
border: 1px solid rgba(6, 182, 212, 0.2);
|
|
transition: var(--transition);
|
|
font-size: 10px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.report-link:hover {
|
|
color: var(--secondary-light);
|
|
background: rgba(6, 182, 212, 0.2);
|
|
border-color: rgba(6, 182, 212, 0.4);
|
|
transform: scale(1.05);
|
|
box-shadow: 0 2px 8px rgba(6, 182, 212, 0.3);
|
|
}
|
|
|
|
/* 多维度检测按钮 */
|
|
.dimension-buttons {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.dimension-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 12px 16px;
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(6, 182, 212, 0.2) 100%);
|
|
border: 1px solid rgba(59, 130, 246, 0.3);
|
|
border-radius: 8px;
|
|
color: #e2e8f0;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.dimension-btn:hover {
|
|
background: linear-gradient(135deg, rgba(59, 130, 246, 0.3) 0%, rgba(6, 182, 212, 0.3) 100%);
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
.dimension-btn .el-icon {
|
|
font-size: 16px;
|
|
color: #06b6d4;
|
|
}
|
|
|
|
/* 操作按钮 */
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.action-buttons .el-button {
|
|
flex: 1;
|
|
background: linear-gradient(135deg, #3b82f6 0%, #06b6d4 100%);
|
|
border: none;
|
|
color: white;
|
|
font-weight: bold;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.action-buttons .el-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 20px rgba(59, 130, 246, 0.3);
|
|
}
|
|
|
|
.action-buttons .el-button.el-button--info {
|
|
background: linear-gradient(135deg, var(--gray) 0%, var(--gray-light) 100%);
|
|
}
|
|
|
|
/* 自适应组件优化 */
|
|
@media (max-width: 1600px) {
|
|
.chart-container {
|
|
height: 250px;
|
|
}
|
|
|
|
.gauge-container {
|
|
height: 180px;
|
|
}
|
|
|
|
.dimension-btn {
|
|
font-size: 12px;
|
|
padding: 8px 10px;
|
|
}
|
|
|
|
.action-buttons .el-button {
|
|
font-size: 11px;
|
|
height: 32px;
|
|
padding: 6px 10px;
|
|
}
|
|
}
|
|
|
|
/* 模块标题紧凑模式 */
|
|
.module-header.compact {
|
|
margin-bottom: 10px;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.module-header.compact .el-icon {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.module-header.ultra-compact {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 8px;
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.module-header.ultra-compact .el-icon {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.header-counter {
|
|
background: var(--success-alpha-medium);
|
|
color: var(--success);
|
|
padding: 2px 6px;
|
|
border-radius: var(--radius-lg);
|
|
font-size: 10px;
|
|
font-weight: 500;
|
|
border: 1px solid rgba(16, 185, 129, 0.2);
|
|
}
|
|
|
|
.analysis-status {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 10px;
|
|
color: var(--success);
|
|
}
|
|
|
|
.status-dot {
|
|
width: 4px;
|
|
height: 4px;
|
|
border-radius: 50%;
|
|
background: var(--success);
|
|
}
|
|
|
|
.status-dot.active {
|
|
animation: pulse 1.5s infinite;
|
|
}
|
|
.table-body::-webkit-scrollbar,
|
|
.table-body-enhanced::-webkit-scrollbar {
|
|
width: 4px;
|
|
}
|
|
|
|
.table-body::-webkit-scrollbar-track,
|
|
.table-body-enhanced::-webkit-scrollbar-track {
|
|
background: var(--primary-alpha-light);
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.table-body::-webkit-scrollbar-thumb,
|
|
.table-body-enhanced::-webkit-scrollbar-thumb {
|
|
background: var(--secondary-alpha-medium);
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.table-body::-webkit-scrollbar-thumb:hover,
|
|
.table-body-enhanced::-webkit-scrollbar-thumb:hover {
|
|
background: var(--secondary-alpha-heavy);
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 1920px) {
|
|
.main-content {
|
|
padding: 12px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.module-container {
|
|
padding: 12px;
|
|
}
|
|
|
|
.main-title {
|
|
font-size: 32px;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: 42px;
|
|
}
|
|
|
|
.wall-card.compact {
|
|
padding: 6px;
|
|
}
|
|
|
|
.wall-card.compact .wall-number {
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1600px) {
|
|
.main-content {
|
|
grid-template-columns: 1fr 1.2fr 0.8fr;
|
|
gap: 8px;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: clamp(24px, 2.4vw, 32px);
|
|
}
|
|
|
|
.number-unit {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.gauge-mini {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
|
|
.number-gauge-combined {
|
|
padding: 8px 12px;
|
|
min-height: 60px;
|
|
}
|
|
|
|
.wall-card.compact .wall-number {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.wall-card.compact .wall-label {
|
|
font-size: 9px;
|
|
}
|
|
|
|
.metrics-layout {
|
|
grid-template-columns: 1.3fr 1fr;
|
|
}
|
|
|
|
.main-metric-content.compact {
|
|
flex-direction: row;
|
|
gap: 8px;
|
|
}
|
|
|
|
.metric-chart-section {
|
|
width: 100%;
|
|
height: 100px;
|
|
}
|
|
|
|
.chart-container {
|
|
height: 220px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1366px) {
|
|
.main-content {
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: auto auto auto;
|
|
}
|
|
|
|
.main-title {
|
|
font-size: 28px;
|
|
}
|
|
|
|
.subtitle {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: 42px;
|
|
}
|
|
|
|
.wall-grid.adaptive {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
grid-template-rows: repeat(2, 1fr);
|
|
}
|
|
|
|
.stats-overview {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.metrics-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.table-row {
|
|
font-size: 11px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1024px) {
|
|
.main-content {
|
|
padding: 10px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.module-container {
|
|
padding: 12px;
|
|
}
|
|
|
|
.wall-grid.adaptive {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-template-rows: repeat(3, 1fr);
|
|
}
|
|
|
|
.stats-overview {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: clamp(20px, 2vw, 28px);
|
|
}
|
|
|
|
.number-unit {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.gauge-mini {
|
|
width: 35px;
|
|
height: 35px;
|
|
}
|
|
|
|
.number-gauge-combined {
|
|
padding: 6px 10px;
|
|
min-height: 50px;
|
|
gap: 8px;
|
|
}
|
|
|
|
.main-metric-header {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.real-time-indicator {
|
|
margin-left: 0;
|
|
margin-top: 5px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.main-content {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.header-section {
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
text-align: center;
|
|
}
|
|
|
|
.current-time {
|
|
position: static;
|
|
transform: none;
|
|
}
|
|
|
|
.wall-grid.adaptive {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.metrics-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.main-metric-content.compact {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.stats-overview {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.module-header {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.big-number {
|
|
font-size: 32px;
|
|
}
|
|
}
|
|
|
|
/* 加载动画 */
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.module-container {
|
|
animation: fadeIn 0.8s ease-out;
|
|
}
|
|
|
|
.module-container:nth-child(1) { animation-delay: 0.1s; }
|
|
.module-container:nth-child(2) { animation-delay: 0.2s; }
|
|
.module-container:nth-child(3) { animation-delay: 0.3s; }
|
|
.module-container:nth-child(4) { animation-delay: 0.4s; }
|
|
.module-container:nth-child(5) { animation-delay: 0.5s; }
|
|
.module-container:nth-child(6) { animation-delay: 0.6s; }
|
|
</style> |