| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- <template>
- <div class="learning-statistics">
- <div class="stat-picker">
- <a-range-picker v-model:value="dateRange" style="width: 240px" />
- </div>
- <!-- 顶部统计卡片 -->
- <div class="stat-cards">
- <a-card class="stat-card">
- <div class="stat-title">学习人数</div>
- <div class="stat-value">{{ statData.studentCount }}<span class="stat-unit">人</span></div>
- <div class="stat-desc">较上周 +1000</div>
- </a-card>
- <a-card class="stat-card">
- <div class="stat-title">学习总时长</div>
- <div class="stat-value">{{ statData.totalStudyTime }}<span class="stat-unit">小时</span></div>
- <div class="stat-desc">较上周 -200</div>
- </a-card>
- <a-card class="stat-card">
- <div class="stat-title">人均学习时长</div>
- <div class="stat-value">{{ statData.avgStudyTime }}<span class="stat-unit">小时</span></div>
- <div class="stat-desc">较上周 +40</div>
- </a-card>
- <a-card class="stat-card">
- <div class="stat-title">完课率</div>
- <div class="stat-value">{{ statData.completionRate }}<span class="stat-unit">%</span></div>
- <div class="stat-desc">较上周 -200</div>
- </a-card>
- </div>
- <!-- 学习人数趋势图 -->
- <div class="chart-section">
- <a-card class="chart-card">
- <div class="chart-title">学习人数趋势</div>
- <div ref="mainChartRef" style="height: 260px; width: 100%"></div>
- <div class="chart-legend">
- <span class="legend-item blue">学习人数</span>
- <span class="legend-item">学习时长</span>
- <span class="legend-item">人均学习时长</span>
- <span class="legend-item">完课率</span>
- </div>
- </a-card>
- </div>
- <!-- 学习时段平均人数分布 -->
- <div class="chart-section">
- <a-card class="chart-card">
- <div class="chart-title">学习时段平均人数分布</div>
- <div ref="timeChartRef" style="height: 220px; width: 100%"></div>
- <div class="chart-legend">
- <span class="legend-item blue">学习人数</span>
- </div>
- </a-card>
- </div>
- <!-- 用户学习数据表格 -->
- <div class="user-table-section">
- <div class="table-toolbar">
- <a-input-search
- v-model:value="searchValue"
- placeholder="姓名/学号/手机"
- style="width: 200px; margin-right: 12px"
- />
- <a-select v-model:value="selectedClass" placeholder="选择学生班别" style="width: 160px; margin-right: 12px">
- <a-select-option value="">全部班级</a-select-option>
- <a-select-option value="一班">一班</a-select-option>
- <a-select-option value="二班">二班</a-select-option>
- </a-select>
- <a-select v-model:value="selectedStatus" placeholder="状态筛选" style="width: 120px; margin-right: 12px">
- <a-select-option value="">全部状态</a-select-option>
- <a-select-option value="正常">正常</a-select-option>
- <a-select-option value="异常">异常</a-select-option>
- </a-select>
- <a-button type="primary" style="margin-right: 8px">导出</a-button>
- <a-button>重置</a-button>
- </div>
- <a-table
- :columns="columns"
- :data-source="tableData"
- :pagination="pagination"
- row-key="id"
- bordered
- size="middle"
- style="margin-top: 16px"
- >
- <template #bodyCell="{ column }">
- <template v-if="column.key === 'action'">
- <a-space>
- <a-button type="link" size="small">详情</a-button>
- <a-button type="link" size="small">编辑</a-button>
- <a-button type="link" size="small">导出</a-button>
- <a-button type="link" size="small" danger>删除</a-button>
- </a-space>
- </template>
- </template>
- </a-table>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, onMounted } from 'vue'
- import * as echarts from 'echarts'
- const statData = ref({
- studentCount: 900,
- totalStudyTime: 1800,
- avgStudyTime: 2.0,
- completionRate: 20
- })
- const dateRange = ref([])
- const mainChartRef = ref(null)
- const timeChartRef = ref(null)
- const mainChartOption = {
- tooltip: { trigger: 'axis' },
- grid: { left: 40, right: 20, top: 40, bottom: 40 },
- xAxis: {
- type: 'category',
- data: ['03-01', '03-02', '03-03', '03-04', '03-05', '03-06', '03-07']
- },
- yAxis: { type: 'value' },
- series: [
- {
- name: '学习人数',
- type: 'line',
- data: [200, 220, 210, 500, 230, 210, 200],
- smooth: true,
- areaStyle: { color: 'rgba(52,122,255,0.08)' },
- lineStyle: { color: '#347aff', width: 3 },
- itemStyle: { color: '#347aff' },
- markLine: {
- data: [{ xAxis: '03-04' }],
- lineStyle: { color: '#347aff', type: 'dashed' },
- label: { show: false }
- },
- symbolSize: 8
- }
- ]
- }
- const timeChartOption = {
- tooltip: { trigger: 'axis' },
- grid: { left: 40, right: 20, top: 40, bottom: 40 },
- xAxis: {
- type: 'category',
- data: ['00:00', '00:04', '00:08', '00:12', '00:16', '00:20', '00:24']
- },
- yAxis: { type: 'value' },
- series: [
- {
- name: '学习人数',
- type: 'line',
- data: [1000, 1200, 1100, 1520, 1400, 1200, 1000],
- smooth: true,
- areaStyle: { color: 'rgba(52,122,255,0.08)' },
- lineStyle: { color: '#347aff', width: 3 },
- itemStyle: { color: '#347aff' },
- markLine: {
- data: [{ xAxis: '00:12' }],
- lineStyle: { color: '#347aff', type: 'dashed' },
- label: { show: false }
- },
- symbolSize: 8
- }
- ]
- }
- const searchValue = ref('')
- const selectedClass = ref('')
- const selectedStatus = ref('')
- const columns = [
- { title: '学号/账号', dataIndex: 'id', key: 'id', align: 'center' },
- { title: '姓名', dataIndex: 'name', key: 'name', align: 'center' },
- { title: '进度', dataIndex: 'progress', key: 'progress', align: 'center' },
- { title: '速率', dataIndex: 'rate', key: 'rate', align: 'center' },
- { title: '今日学习时长', dataIndex: 'todayTime', key: 'todayTime', align: 'center' },
- { title: '累计学习时长', dataIndex: 'totalTime', key: 'totalTime', align: 'center' },
- { title: '首次学习时间', dataIndex: 'firstTime', key: 'firstTime', align: 'center' },
- { title: '最近登录', dataIndex: 'lastLogin', key: 'lastLogin', align: 'center' },
- { title: '操作', key: 'action', align: 'center' }
- ]
- const tableData = ref(
- Array.from({ length: 10 }).map((_, i) => ({
- id: `xy00000${i + 1}`,
- name: '张小刚',
- progress: '20%',
- rate: '20%',
- todayTime: '1h30min',
- totalTime: '13h30min',
- firstTime: '2020-11-25 23:26:08',
- lastLogin: '2020-11-25 23:26:08'
- }))
- )
- const pagination = {
- pageSize: 10,
- total: 50,
- showTotal: (total) => `共${total}条`,
- showQuickJumper: true,
- showSizeChanger: true
- }
- onMounted(() => {
- if (mainChartRef.value) {
- const chart = echarts.init(mainChartRef.value)
- chart.setOption(mainChartOption)
- }
- if (timeChartRef.value) {
- const chart = echarts.init(timeChartRef.value)
- chart.setOption(timeChartOption)
- }
- })
- </script>
- <style lang="less" scoped>
- .learning-statistics {
- width: 1200px;
- margin: 0 auto;
- height: calc(100vh - 400px);
- overflow: auto;
- .stat-cards {
- display: flex;
- align-items: flex-start;
- margin-bottom: 24px;
- .stat-card {
- flex: 1;
- margin-right: 16px;
- border-radius: 12px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
- border: none;
- .stat-title {
- font-size: 16px;
- color: #888;
- margin-bottom: 8px;
- }
- .stat-value {
- font-size: 32px;
- font-weight: 600;
- color: #222;
- .stat-unit {
- font-size: 16px;
- margin-left: 4px;
- }
- }
- .stat-desc {
- color: #aaa;
- font-size: 13px;
- margin-top: 8px;
- }
- }
- .stat-card:last-child {
- margin-right: 0;
- }
- }
- .stat-picker {
- display: flex;
- flex-direction: row-reverse;
- margin: 10px 0;
- }
- .chart-section {
- margin-bottom: 24px;
- .chart-card {
- border-radius: 12px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
- border: none;
- padding-bottom: 12px;
- .chart-title {
- font-size: 16px;
- font-weight: 600;
- color: #222;
- margin-bottom: 12px;
- }
- .chart-legend {
- margin-top: 8px;
- .legend-item {
- display: inline-block;
- margin-right: 24px;
- font-size: 14px;
- color: #888;
- &.blue {
- color: #347aff;
- font-weight: 600;
- }
- }
- }
- }
- }
- .user-table-section {
- background: #fff;
- border-radius: 12px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
- padding: 24px 24px 12px 24px;
- .table-toolbar {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
- }
- }
- }
- </style>
|