学习进度统计

This commit is contained in:
2025-11-17 13:16:12 +08:00
parent cb401eebe1
commit 4b167058b6
15 changed files with 213 additions and 66 deletions

View File

@@ -3,7 +3,7 @@
<div class="progress-header">
<div class="header-left">
<h3 class="progress-title">学习进度</h3>
<p class="update-time">更新时间2025-09-25 18:30:00</p>
<p class="update-time">更新时间{{ updateTime || '-' }}</p>
</div>
<div class="tab-buttons">
<button v-for="(tab, index) in tabs" :key="index" :class="['tab-btn', { active: activeTab === index }]"
@@ -21,38 +21,51 @@
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';
import type { EChartsOption } from 'echarts';
import dayjs from 'dayjs';
import { learningTaskApi } from '@/apis/study/learning-task';
const tabs = ref(['今日', '近一周', '近一月']);
const activeTab = ref(0);
const chartRef = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
// 模拟不同时间段的数据
const chartDataMap = {
0: [
{ name: '党史', value: 43, highlight: false },
{ name: '理论', value: 58, highlight: false },
{ name: '政策', value: 34, highlight: false },
{ name: '思政', value: 20, highlight: false },
{ name: '文化', value: 52, highlight: true }
],
1: [
{ name: '党史', value: 68, highlight: true },
{ name: '理论', value: 52, highlight: false },
{ name: '政策', value: 45, highlight: false },
{ name: '思政', value: 38, highlight: false },
{ name: '文化', value: 41, highlight: false }
],
2: [
{ name: '党史', value: 85, highlight: true },
{ name: '理论', value: 72, highlight: false },
{ name: '政策', value: 58, highlight: false },
{ name: '思政', value: 65, highlight: false },
{ name: '文化', value: 43, highlight: false }
]
};
// 后端返回的数据结构映射为图表数据
const chartData = ref<{ name: string; value: number; highlight: boolean }[]>([]);
const chartData = computed(() => chartDataMap[activeTab.value as keyof typeof chartDataMap]);
const updateTime = ref('');
async function loadStatistics() {
// 根据当前 tab 计算时间范围
const now = dayjs();
let start: dayjs.Dayjs;
if (activeTab.value === 0) {
// 今日:从今天 00:00:00 到现在
start = now.startOf('day');
} else if (activeTab.value === 1) {
// 近一周:过去 7 天
start = now.subtract(6, 'day').startOf('day');
} else {
// 近一月:过去 30 天
start = now.subtract(29, 'day').startOf('day');
}
const startTime = start.format('YYYY-MM-DD HH:mm:ss');
const endTime = now.format('YYYY-MM-DD HH:mm:ss');
const res = await learningTaskApi.getMyStatistics(startTime, endTime);
if (res.code === 200 && res.data) {
const list = (res.data.tagProgressList || []) as { tagName: string; avgProgress: number }[];
chartData.value = list.map(item => ({
name: item.tagName,
value: Number(item.avgProgress ?? 0),
highlight: false,
}));
updateTime.value = now.format('YYYY-MM-DD HH:mm:ss');
} else {
chartData.value = [];
}
}
// 图表配置
function getChartOption(): EChartsOption {
@@ -155,8 +168,9 @@ function handleResize() {
}
// 处理标签切换
function handleTabChange(index: number) {
async function handleTabChange(index: number) {
activeTab.value = index;
await loadStatistics();
if (chartInstance) {
chartInstance.setOption(chartOption.value, true);
}
@@ -169,8 +183,12 @@ watch(() => chartOption.value, () => {
}
}, { deep: true });
onMounted(() => {
onMounted(async () => {
initChart();
await loadStatistics();
if (chartInstance) {
chartInstance.setOption(chartOption.value, true);
}
});
onUnmounted(() => {

View File

@@ -62,13 +62,14 @@
</div>
<div class="form-group">
<label class="form-label">任务分类标签</label>
<label class="form-label required">任务分类标签</label>
<select
v-model="selectedTagID"
class="form-input form-select"
@change="handleTagChange"
@blur="validateTag"
>
<option value="">请选择分类标签可选</option>
<option value="">请选择分类标签</option>
<option
v-for="tag in availableTags"
:key="tag.tagID"
@@ -77,6 +78,7 @@
{{ tag.name }}
</option>
</select>
<span v-if="errors.tag" class="error-msg">{{ errors.tag }}</span>
<div v-if="selectedTag" class="selected-tag-preview">
<div class="tag-badge" :style="{ backgroundColor: selectedTag.color || '#409eff' }">
{{ selectedTag.name }}
@@ -350,7 +352,8 @@ const taskData = ref<TaskVO>({
const errors = ref({
name: '',
startTime: '',
endTime: ''
endTime: '',
tag: ''
});
// 选中的数据
@@ -732,6 +735,7 @@ function handleTagChange() {
} else {
selectedTag.value = null;
}
validateTag();
}
// 表单验证
@@ -744,6 +748,15 @@ function validateTaskName() {
return true;
}
function validateTag() {
if (!selectedTagID.value) {
errors.value.tag = '请选择任务分类标签';
return false;
}
errors.value.tag = '';
return true;
}
function validateTime() {
if (!taskData.value.learningTask.startTime) {
errors.value.startTime = '请选择开始时间';
@@ -765,8 +778,9 @@ function validateTime() {
function validateForm() {
const isNameValid = validateTaskName();
const isTimeValid = validateTime();
const isTagValid = validateTag();
if (!isNameValid || !isTimeValid) {
if (!isNameValid || !isTimeValid || !isTagValid) {
return false;
}