211 lines
5.2 KiB
Vue
211 lines
5.2 KiB
Vue
<template>
|
|
<div class="app-container">
|
|
<!-- 统计卡片 -->
|
|
<el-row :gutter="20" class="mb-20">
|
|
<el-col :span="6">
|
|
<el-card class="statistics-card pending">
|
|
<div class="card-content">
|
|
<div class="card-icon">
|
|
<el-icon><Clock /></el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">待审核</div>
|
|
<div class="card-value">{{ statistics.pendingCount || 0 }}</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-card class="statistics-card approved">
|
|
<div class="card-content">
|
|
<div class="card-icon">
|
|
<el-icon><Check /></el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">已通过</div>
|
|
<div class="card-value">{{ statistics.approvedCount || 0 }}</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-card class="statistics-card rejected">
|
|
<div class="card-content">
|
|
<div class="card-icon">
|
|
<el-icon><Close /></el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">已拒绝</div>
|
|
<div class="card-value">{{ statistics.rejectedCount || 0 }}</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-card class="statistics-card total">
|
|
<div class="card-content">
|
|
<div class="card-icon">
|
|
<el-icon><DataLine /></el-icon>
|
|
</div>
|
|
<div class="card-info">
|
|
<div class="card-title">总计</div>
|
|
<div class="card-value">{{ statistics.totalProcessedCount || 0 }}</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<!-- 标签页 -->
|
|
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
|
<el-tab-pane label="待审核申请" name="pending">
|
|
<PendingApplications ref="pendingRef" @refresh-statistics="getStatistics" />
|
|
</el-tab-pane>
|
|
<el-tab-pane label="所有申请" name="all">
|
|
<AllApplications ref="allRef" />
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="WorkStudyStudentAffairsReview">
|
|
import { ref, onMounted } from 'vue';
|
|
import { ElMessage } from 'element-plus';
|
|
import { Clock, Check, Close, DataLine } from '@element-plus/icons-vue';
|
|
import { getStudentAffairsStatistics, type StatisticsVO } from '@/api/jcbt/workStudyApplicationStudentAffairsReview';
|
|
import PendingApplications from './components/PendingApplications.vue';
|
|
import AllApplications from './components/AllApplications.vue';
|
|
|
|
// 响应式数据
|
|
const activeTab = ref('pending');
|
|
const statistics = ref<StatisticsVO>({});
|
|
const pendingRef = ref();
|
|
const allRef = ref();
|
|
|
|
// 获取统计数据
|
|
const getStatistics = async () => {
|
|
try {
|
|
const { data } = await getStudentAffairsStatistics();
|
|
statistics.value = data;
|
|
} catch (error: any) {
|
|
console.error('获取统计数据失败:', error);
|
|
if (error?.message?.includes('404')) {
|
|
ElMessage.error('无法获取统计数据,请检查您是否有学工处审核权限');
|
|
} else if (error?.message?.includes('403')) {
|
|
ElMessage.error('权限不足,无法访问学工处审核功能');
|
|
} else {
|
|
ElMessage.error('获取统计数据失败,请稍后重试');
|
|
}
|
|
}
|
|
};
|
|
|
|
// 标签页切换
|
|
const handleTabChange = (tabName: string) => {
|
|
activeTab.value = tabName;
|
|
if (tabName === 'pending' && pendingRef.value) {
|
|
pendingRef.value.getList();
|
|
} else if (tabName === 'all' && allRef.value) {
|
|
allRef.value.getList();
|
|
}
|
|
};
|
|
|
|
// 初始化
|
|
onMounted(() => {
|
|
getStatistics();
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.app-container {
|
|
padding: 20px;
|
|
}
|
|
|
|
.mb-20 {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.statistics-card {
|
|
border: none;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
transition: all 0.3s ease;
|
|
|
|
&:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.card-content {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 20px;
|
|
}
|
|
|
|
.card-icon {
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 16px;
|
|
font-size: 24px;
|
|
color: white;
|
|
}
|
|
|
|
.card-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.card-title {
|
|
font-size: 14px;
|
|
color: #666;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.card-value {
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
&.pending .card-icon {
|
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
}
|
|
|
|
&.approved .card-icon {
|
|
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
|
}
|
|
|
|
&.rejected .card-icon {
|
|
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
|
}
|
|
|
|
&.total .card-icon {
|
|
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
|
|
}
|
|
}
|
|
|
|
:deep(.el-tabs__header) {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
:deep(.el-tabs__nav-wrap::after) {
|
|
height: 1px;
|
|
background-color: #e4e7ed;
|
|
}
|
|
|
|
:deep(.el-tabs__active-bar) {
|
|
background-color: #409eff;
|
|
}
|
|
|
|
:deep(.el-tabs__item) {
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
|
|
&.is-active {
|
|
color: #409eff;
|
|
}
|
|
}
|
|
</style>
|