新增教练端,实现业务闭环:会员登录注册→查询团课→预约团课→扫码签到→教练端开课→记录实际开课时间→教练端结课→记录实际结课时间→后台查询数据
This commit is contained in:
@@ -50,9 +50,9 @@
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="6">
|
||||
<el-card shadow="hover" class="stat-card stat-card--info">
|
||||
<div class="stat-card__label">签到总数</div>
|
||||
<div class="stat-card__value">{{ summary?.signInStatistics?.totalSignIns ?? '-' }}</div>
|
||||
<el-card shadow="hover" class="stat-card stat-card--danger">
|
||||
<div class="stat-card__label">教练违规</div>
|
||||
<div class="stat-card__value">{{ summary?.coachStatistics?.totalViolations ?? '-' }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -192,12 +192,65 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<!-- ========== 教练统计明细 ========== -->
|
||||
<el-card class="section-card">
|
||||
<template #header>
|
||||
<span class="section-title">教练统计</span>
|
||||
</template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">教练总数</span>
|
||||
<span class="metric-value">{{ summary?.coachStatistics?.totalCoaches ?? '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">违规教练</span>
|
||||
<span class="metric-value" :class="{ 'metric-value--danger': (summary?.coachStatistics?.violatedCoaches ?? 0) > 0 }">
|
||||
{{ summary?.coachStatistics?.violatedCoaches ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">开课总数</span>
|
||||
<span class="metric-value">{{ summary?.coachStatistics?.totalCourses ?? '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">迟到</span>
|
||||
<span class="metric-value" :class="{ 'metric-value--warn': (summary?.coachStatistics?.lateCount ?? 0) > 0 }">
|
||||
{{ summary?.coachStatistics?.lateCount ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">缺席</span>
|
||||
<span class="metric-value" :class="{ 'metric-value--danger': (summary?.coachStatistics?.absentCount ?? 0) > 0 }">
|
||||
{{ summary?.coachStatistics?.absentCount ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="4">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">未手动结课</span>
|
||||
<span class="metric-value" :class="{ 'metric-value--warn': (summary?.coachStatistics?.notManualEndCount ?? 0) > 0 }">
|
||||
{{ summary?.coachStatistics?.notManualEndCount ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { statisticsApi, type StatisticsSummary } from '@/api/statistics.api'
|
||||
@@ -278,8 +331,20 @@ const handleExport = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
let statsTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
onMounted(() => {
|
||||
fetchSummary()
|
||||
statsTimer = setInterval(() => {
|
||||
fetchSummary()
|
||||
}, 60_000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (statsTimer !== null) {
|
||||
clearInterval(statsTimer)
|
||||
statsTimer = null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -350,6 +415,7 @@ onMounted(() => {
|
||||
.stat-card--success .stat-card__value { color: #67c23a; }
|
||||
.stat-card--warning .stat-card__value { color: #e6a23c; }
|
||||
.stat-card--info .stat-card__value { color: #909399; }
|
||||
.stat-card--danger .stat-card__value { color: #f56c6c; }
|
||||
|
||||
/* ---- 明细分区 ---- */
|
||||
.section-card {
|
||||
@@ -380,6 +446,14 @@ onMounted(() => {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.metric-value--warn {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.metric-value--danger {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.rate-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user