SYN/pc/pages/user/enrollment.vue

606 lines
24 KiB
Vue

<template>
<div class="px-[30px] py-5 user-info min-h-full flex flex-col">
<div v-if="submission" class="border-b border-br pb-5">
<span class="text-2xl font-medium">注册状态</span>
</div>
<el-card
v-if="submission"
class="!border-none mb-4 flex-1"
shadow="never"
>
<div class="status-info mt-4">
<!-- 改为步骤条展示 -->
<div class="mb-6">
<div class="text-tx-secondary text-sm mb-4">状态进度</div>
<el-steps
:active="activeStep"
finish-status="success"
class="w-full"
>
<el-step
v-for="(step, index) in statusConfig.steps"
:key="index"
:title="stepTitles[index]"
:description="getStepDescription(index)"
:status="getStepStatus(index)"
/>
</el-steps>
</div>
<!-- 显示拒绝原因 -->
<div v-if="rejectionReason" class="text-danger mt-4">
<i class="el-icon-error mr-2"></i>
拒绝原因:{{ rejectionReason }}
</div>
</div>
</el-card>
<div class="border-b border-br pb-5">
<span class="text-2xl font-medium">{{
submission ? '信息查看' : '新生报名'
}}</span>
</div>
<el-card class="!border-none mb-4" shadow="never">
<div class="lg:flex gap-6">
<!-- 基本信息表单 -->
<el-card class="!border-none flex-1" shadow="never">
<el-form
layout="vertical"
:model="studentData.baseInfo"
class="mt-4"
>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<el-form-item label="学生姓名">
<el-input
v-model="studentData.baseInfo.name"
placeholder="请输入姓名"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="性别">
<el-radio-group
v-model="studentData.baseInfo.gender"
:disabled="submission"
>
<el-radio :label="0">男</el-radio>
<el-radio :label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="身份证号">
<el-input
v-model="studentData.baseInfo.idCard"
placeholder="请输入18位身份证号"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="出生日期">
<el-date-picker
v-model="studentData.baseInfo.birthday"
type="datetime"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请输入出生日期"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="联系方式">
<el-input
v-model="studentData.baseInfo.phone"
placeholder="请输入手机号码"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="电子邮箱">
<el-input
v-model="studentData.baseInfo.email"
placeholder="请输入电子邮箱"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="籍贯">
<el-input
v-model="studentData.baseInfo.nativePlace"
placeholder="请输入籍贯"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="民族">
<el-input
v-model="studentData.baseInfo.nationality"
placeholder="请输入民族"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="政治面貌">
<el-select
v-model="
studentData.baseInfo.politicalStatus
"
clearable
:disabled="submission"
>
<el-option label="群众" :value="0" />
<el-option label="团员" :value="1" />
<el-option label="党员" :value="2" />
<el-option label="其他" :value="3" />
</el-select>
</el-form-item>
<el-form-item label="毕业年份">
<el-input-number
v-model="
studentData.baseInfo.graduationYear
"
placeholder="请输入毕业年份"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="毕业院校">
<el-input
v-model="
studentData.baseInfo.previousSchool
"
placeholder="请输入毕业院校"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="学校类型">
<el-select
v-model="studentData.baseInfo.schoolType"
clearable
:disabled="submission"
>
<el-option label="普通高中" :value="1" />
<el-option label="职业高中" :value="2" />
<el-option label="中专" :value="3" />
<el-option label="大专" :value="4" />
<el-option label="本科" :value="5" />
<el-option label="其他" :value="6" />
</el-select>
</el-form-item>
<el-form-item label="学历">
<el-select
v-model="
studentData.baseInfo
.academicQualification
"
clearable
:disabled="submission"
>
<el-option label="初中" :value="1" />
<el-option label="高中" :value="2" />
<el-option label="中专" :value="3" />
<el-option label="大专" :value="4" />
<el-option label="本科" :value="5" />
<el-option label="硕士" :value="6" />
<el-option label="博士" :value="7" />
</el-select>
</el-form-item>
<el-form-item label="邮政编码">
<el-input
v-model="studentData.baseInfo.postalCode"
placeholder="请输入邮政编码"
:disabled="submission"
/>
</el-form-item>
<el-form-item
label="家庭住址"
class="md:col-span-2"
>
<el-input
v-model="studentData.baseInfo.homeAddress"
placeholder="请输入详细家庭住址"
type="textarea"
rows="3"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="紧急联系人">
<el-input
v-model="
studentData.baseInfo.emergencyContact
"
placeholder="请输入紧急联系人姓名"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="紧急联系电话">
<el-input
v-model="
studentData.baseInfo.emergencyPhone
"
placeholder="请输入紧急联系人电话"
:disabled="submission"
/>
</el-form-item>
<el-form-item label="与紧急联系人关系">
<el-input
v-model="studentData.baseInfo.relationship"
placeholder="请输入与紧急联系人的关系"
:disabled="submission"
/>
</el-form-item>
</div>
</el-form>
</el-card>
</div>
</el-card>
<!-- 注册状态信息 -->
<el-card class="!border-none mb-4 flex-1" shadow="never">
<div v-if="!submission" class="mt-6">
<el-button type="primary" block @click="handleSave">
保存信息
</el-button>
<el-button
class="ml-4"
type="success"
block
@click="handleShowConfirmDialog"
:disabled="statusConfig.steps[0].completed"
>
提交报名
</el-button>
</div>
</el-card>
<!-- 确认弹窗 -->
<el-dialog
title="确认提交"
v-model="showConfirmDialog"
width="600px"
:before-close="handleCloseDialog"
>
<div class="mb-4 text-warning">
<i class="el-icon-warning mr-2"></i>
提交信息后不可修改,请检查后确认
</div>
<el-descriptions :column="1" border>
<el-descriptions-item label="学生姓名">{{
confirmInfo.name
}}</el-descriptions-item>
<el-descriptions-item label="性别">{{
confirmInfo.gender === 0 ? '男' : '女'
}}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{
confirmInfo.idCard
}}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{
confirmInfo.birthday
}}</el-descriptions-item>
<el-descriptions-item label="民族">{{
confirmInfo.nationality
}}</el-descriptions-item>
<el-descriptions-item label="联系方式"
>电话:{{ confirmInfo.phone }} 邮箱:{{
confirmInfo.email
}}</el-descriptions-item
>
<el-descriptions-item label="籍贯">{{
confirmInfo.nativePlace
}}</el-descriptions-item>
<el-descriptions-item label="政治面貌">
{{
confirmInfo.politicalStatus === 0
? '群众'
: confirmInfo.politicalStatus === 1
? '团员'
: confirmInfo.politicalStatus === 2
? '党员'
: '其他'
}}
</el-descriptions-item>
<el-descriptions-item label="家庭住址">{{
confirmInfo.homeAddress
}}</el-descriptions-item>
<el-descriptions-item label="毕业年份">{{
confirmInfo.graduationYear
}}</el-descriptions-item>
<el-descriptions-item label="毕业院校">{{
confirmInfo.previousSchool
}}</el-descriptions-item>
<el-descriptions-item label="学校类型">
{{
confirmInfo.schoolType === 1
? '普通高中'
: confirmInfo.schoolType === 2
? '职业高中'
: confirmInfo.schoolType === 3
? '中专'
: confirmInfo.schoolType === 4
? '大专'
: confirmInfo.schoolType === 5
? '本科'
: '其他'
}}
</el-descriptions-item>
<el-descriptions-item label="学历">
{{
confirmInfo.academicQualification === 1
? '初中'
: confirmInfo.academicQualification === 2
? '高中'
: confirmInfo.academicQualification === 3
? '中专'
: confirmInfo.academicQualification === 4
? '大专'
: confirmInfo.academicQualification === 5
? '本科'
: confirmInfo.academicQualification === 6
? '硕士'
: '博士'
}}
</el-descriptions-item>
<el-descriptions-item label="邮政编码">{{
confirmInfo.postalCode
}}</el-descriptions-item>
<el-descriptions-item label="紧急联系人">{{
confirmInfo.emergencyContact
}}</el-descriptions-item>
<el-descriptions-item label="紧急联系电话">{{
confirmInfo.emergencyPhone
}}</el-descriptions-item>
<el-descriptions-item label="与紧急联系人关系">{{
confirmInfo.relationship
}}</el-descriptions-item>
</el-descriptions>
<template #footer>
<el-button @click="handleCloseDialog">取消</el-button>
<el-button type="primary" @click="handleConfirmSubmit">
确认提交
</el-button>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, computed, onMounted, ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
import {
getStudentBaseInfo,
updateStudentBaseInfo,
getEnrollmentProcessStatus,
submitEnrollmentInfo
} from '@/api/enrollment'
definePageMeta({
module: 'personal',
auth: true
})
// 步骤标题与后端状态对应
const stepTitles = ['报名', '材料审核', '录取', '缴费']
const showConfirmDialog = ref(false)
const submission = ref(false) // 提交状态
const rejectionReason = ref('') // 拒绝原因
const confirmInfo = ref({
name: '',
gender: 0,
idCard: '',
birthday: '',
nationality: '',
phone: '',
email: '',
homeAddress: '',
nativePlace: '',
politicalStatus: 0,
previousSchool: '',
schoolType: null,
academicQualification: null,
postalCode: '',
graduationYear: 2025,
emergencyContact: '',
emergencyPhone: '',
relationship: ''
})
// 学生信息数据
const studentData = reactive({
baseInfo: {
id: '',
name: '',
gender: 0,
idCard: '',
birthday: '',
nationality: '',
phone: '',
email: '',
homeAddress: '',
nativePlace: '',
politicalStatus: 0,
previousSchool: '',
schoolType: '',
academicQualification: '',
postalCode: '',
graduationYear: 2025,
emergencyContact: '',
emergencyPhone: '',
relationship: ''
},
additionalInfo: {
enrollYear: '',
major: '',
education: ''
}
})
// 状态配置 - 与后端返回字段对应
const statusConfig = reactive({
steps: [
{ completed: false, time: 0, status: 0 }, // 报名
{ completed: false, time: 0, status: 0 }, // 材料审核
{ completed: false, time: 0, status: 0 }, // 录取
{ completed: false, time: 0, status: 0 } // 缴费
],
applicationNumber: '' // 报名编号
})
// 格式化时间戳为日期
const formatTime = (timestamp: number) => {
if (!timestamp) return ''
const date = new Date(timestamp)
return date.toLocaleDateString()
}
// 获取步骤描述
const getStepDescription = (index: number) => {
const step = statusConfig.steps[index]
const timeStr = formatTime(step.time)
if (index === 0) {
return step.completed ? `已完成${timeStr}` : '状态异常'
} else if (index === 1) {
if (step.status === 0) return '待审核'
if (step.status === 1) return `审核通过 ${timeStr}`
if (step.status === 2) return `审核不通过 ${timeStr}`
} else if (index === 2) {
if (step.status === 0) return '待审核'
if (step.status === 1) return `已录取 ${timeStr}`
if (step.status === 2) return `未录取 ${timeStr}`
} else if (index === 3) {
if (step.status === 0) return '未缴费'
if (step.status === 1) return `已缴费 ${timeStr}`
}
return ''
}
// 显示确认弹窗并加载信息
const handleShowConfirmDialog = async () => {
try {
const info = await getStudentBaseInfo()
confirmInfo.value = info
showConfirmDialog.value = true
} catch (error) {
ElMessage.error('获取信息失败,请稍后重试')
console.error('获取确认信息失败:', error)
}
}
// 关闭弹窗
const handleCloseDialog = () => {
showConfirmDialog.value = false
}
// 确认提交
const handleConfirmSubmit = async () => {
try {
await submitEnrollmentInfo()
showConfirmDialog.value = false
// 刷新状态
await loadProcessStatus()
submission.value = true
ElMessage.success('报名提交成功')
} catch (error) {
ElMessage.error('报名提交失败,请稍后重试')
console.error('提交报名信息失败:', error)
}
}
// 加载流程状态
const loadProcessStatus = async () => {
try {
const statusRes = await getEnrollmentProcessStatus()
if (statusRes) {
submission.value = true
// 保存报名编号
statusConfig.applicationNumber = statusRes.applicationNumber || ''
// 处理拒绝原因
rejectionReason.value = statusRes.rejectionReason || ''
// 映射状态到步骤
// 步骤1: 报名
statusConfig.steps[0] = {
completed: statusRes.applicationNumber,
time: statusRes.applicationTime,
status: statusRes.applicationTime > 0 ? 1 : 0
}
// 步骤2: 材料审核
statusConfig.steps[1] = {
completed: statusRes.approvalStatus === 1,
time: statusRes.applicationTime,
status: statusRes.approvalStatus
}
// 步骤3: 录取
statusConfig.steps[2] = {
completed: statusRes.admissionStatus === 1,
time: statusRes.admissionTime,
status: statusRes.admissionStatus
}
// 步骤4: 缴费入学
statusConfig.steps[3] = {
completed: statusRes.paymentStatus === 1,
time: statusRes.paymentTime,
status: statusRes.paymentStatus
}
}
} catch (error) {
console.error('刷新状态失败:', error)
}
}
// 动态推导当前激活的步骤
const activeStep = computed(() => {
// 检查是否有步骤被拒绝
if (
statusConfig.steps[1].status === 2 ||
statusConfig.steps[2].status === 2
) {
return statusConfig.steps[1].status === 2 ? 1 : 2
}
const count = completedStepCount.value
// 如果所有步骤都完成,激活最后一步;否则激活下一个待完成的步骤
return count >= statusConfig.steps.length
? statusConfig.steps.length - 1
: count
})
// 获取步骤状态
const getStepStatus = (index: number) => {
// 已完成步骤
if (statusConfig.steps[index].completed) {
return 'finish'
}
// 被拒绝的步骤
if (
(index === 1 && statusConfig.steps[index].status === 2) ||
(index === 2 && statusConfig.steps[index].status === 2)
) {
return 'error'
}
// 当前激活步骤
return index === activeStep.value ? 'process' : 'wait'
}
// 计算已完成的步骤数量
const completedStepCount = computed(() => {
return statusConfig.steps.filter((step) => step.completed).length
})
// 保存信息
const handleSave = async () => {
try {
await updateStudentBaseInfo(studentData.baseInfo)
ElMessage.success('信息保存成功')
} catch (error) {
ElMessage.error('保存失败,请稍后重试')
console.error('更新信息失败:', error)
}
}
// 页面挂载时加载数据
onMounted(async () => {
try {
// 1. 加载学生基本信息
const studentInfoRes = await getStudentBaseInfo()
Object.assign(studentData.baseInfo, studentInfoRes)
if (studentInfoRes.id) {
studentData.baseInfo.id = studentInfoRes.id
}
// 2. 加载报名流程状态
await loadProcessStatus()
} catch (error) {
ElMessage.error('数据加载失败,请稍后重试')
console.error('获取初始数据失败:', error)
}
})
</script>
<style lang="scss" scoped></style>