Files
hzdyjs/web/src/views/jcbt/workStudyApplication/collegeReview/components/AllApplications.vue
T
2025-08-12 16:52:10 +08:00

304 lines
8.9 KiB
Vue

<template>
<div class="all-applications">
<!-- 搜索表单 -->
<el-card class="search-card" shadow="never">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="search-form">
<el-form-item label="岗位名称" prop="positionName">
<el-input v-model="queryParams.positionName" placeholder="请输入岗位名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="学生姓名" prop="studentName">
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="学号" prop="studentNo">
<el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable style="width: 200px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="申请状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择申请状态" clearable style="width: 200px">
<el-option v-for="option in statusOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</el-form-item>
<el-form-item label="申请日期" prop="applicationDate">
<el-date-picker
v-model="queryParams.applicationDate"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
style="width: 240px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 数据表格 -->
<el-card class="table-card" shadow="never">
<div class="table-header">
<div class="table-title">
<el-icon><List /></el-icon>
所有申请列表
</div>
</div>
<el-table v-loading="loading" :data="applicationList" row-key="id" stripe>
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="岗位名称" prop="positionName" min-width="120" show-overflow-tooltip />
<el-table-column label="学生信息" min-width="160">
<template #default="{ row }">
<div class="student-info">
<div class="name">{{ row.studentName }}</div>
<div class="detail">{{ row.studentNo }} | {{ row.className }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="专业年级" min-width="140">
<template #default="{ row }">
<div>{{ row.majorName }}</div>
<div class="text-gray">{{ row.grade }}</div>
</template>
</el-table-column>
<el-table-column label="联系方式" min-width="120">
<template #default="{ row }">
<div>{{ row.contactPhone }}</div>
<div class="text-gray">{{ row.email }}</div>
</template>
</el-table-column>
<el-table-column label="申请理由" prop="applicationReason" min-width="200" show-overflow-tooltip />
<el-table-column label="申请状态" width="120" align="center">
<template #default="{ row }">
<el-tag :type="getStatusTagType(row.status)" effect="plain" size="small">
{{ getStatusText(row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="申请时间" prop="applicationDate" width="110" align="center" />
<el-table-column label="审核时间" width="130" align="center">
<template #default="{ row }">
<span v-if="row.collegeReviewTime">{{ row.collegeReviewTime }}</span>
<span v-else class="text-gray">-</span>
</template>
</el-table-column>
<el-table-column label="审核意见" min-width="150" show-overflow-tooltip>
<template #default="{ row }">
<span v-if="row.collegeReviewComment">{{ row.collegeReviewComment }}</span>
<span v-else class="text-gray">-</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="120" align="center">
<template #default="{ row }">
<el-button type="primary" size="small" icon="View" @click="handleDetail(row)"> 详情 </el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 详情对话框 -->
<ApplicationDetail v-model:visible="detailDialog.visible" :application-id="detailDialog.applicationId" @refresh="getList" />
</div>
</template>
<script setup lang="ts" name="AllApplications">
import { ref, reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Search, List, View } from '@element-plus/icons-vue';
import {
listCollegeApplications,
getApplicationOptions,
type WorkStudyApplicationVO,
type WorkStudyApplicationQuery,
type OptionsVO
} from '@/api/jcbt/workStudyApplicationCollegeReview';
import ApplicationDetail from './ApplicationDetail.vue';
// 响应式数据
const loading = ref(false);
const applicationList = ref<WorkStudyApplicationVO[]>([]);
const total = ref(0);
const statusOptions = ref<Array<{ label: string; value: string }>>([]);
const queryRef = ref();
// 查询参数
const queryParams = ref<WorkStudyApplicationQuery>({
pageNum: 1,
pageSize: 10,
positionName: '',
studentName: '',
studentNo: '',
status: '',
applicationDate: ''
});
// 详情对话框数据
const detailDialog = reactive({
visible: false,
applicationId: ''
});
// 获取所有申请列表
const getList = async () => {
loading.value = true;
try {
const { data } = await listCollegeApplications(queryParams.value);
applicationList.value = data.rows || [];
total.value = data.total || 0;
} catch (error) {
console.error('获取申请列表失败:', error);
ElMessage.error('获取数据失败');
} finally {
loading.value = false;
}
};
// 获取选项数据
const getOptions = async () => {
try {
const { data } = await getApplicationOptions();
statusOptions.value = data.statusOptions || [];
} catch (error) {
console.error('获取选项数据失败:', error);
}
};
// 搜索
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
// 重置搜索
const resetQuery = () => {
queryRef.value.resetFields();
queryParams.value = {
pageNum: 1,
pageSize: 10,
positionName: '',
studentName: '',
studentNo: '',
status: '',
applicationDate: ''
};
getList();
};
// 查看详情
const handleDetail = (row: WorkStudyApplicationVO) => {
detailDialog.visible = true;
detailDialog.applicationId = row.id as string;
};
// 获取状态标签类型
const getStatusTagType = (status: string) => {
const typeMap: Record<string, string> = {
'SUBMITTED': 'info',
'COLLEGE_APPROVED': 'success',
'COLLEGE_REJECTED': 'danger',
'FINAL_APPROVED': 'success',
'FINAL_REJECTED': 'danger',
'CANCELLED': 'info'
};
return typeMap[status] || 'info';
};
// 获取状态文本
const getStatusText = (status: string) => {
const textMap: Record<string, string> = {
'SUBMITTED': '已提交',
'COLLEGE_APPROVED': '学院已通过',
'COLLEGE_REJECTED': '学院已拒绝',
'FINAL_APPROVED': '最终通过',
'FINAL_REJECTED': '最终拒绝',
'CANCELLED': '已取消'
};
return textMap[status] || status;
};
// 暴露方法给父组件调用
defineExpose({
getList
});
// 初始化
onMounted(() => {
getOptions();
getList();
});
</script>
<style scoped lang="scss">
.all-applications {
.search-card {
margin-bottom: 16px;
border: none;
:deep(.el-card__body) {
padding: 20px;
}
}
.search-form {
.el-form-item {
margin-bottom: 0;
}
}
.table-card {
border: none;
:deep(.el-card__body) {
padding: 0;
}
}
.table-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 20px 16px;
border-bottom: 1px solid #ebeef5;
.table-title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 600;
color: #303133;
.el-icon {
margin-right: 8px;
color: #409eff;
}
}
}
.el-table {
border-top: none;
}
.student-info {
.name {
font-weight: 500;
color: #303133;
margin-bottom: 2px;
}
.detail {
font-size: 12px;
color: #909399;
}
}
.text-gray {
color: #909399;
font-size: 12px;
}
}
</style>