Files
hzdyjs/web/src/views/jcbt/workstudy/xgreview/index.vue
T
2025-08-13 13:47:44 +08:00

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>