完善报名系统
This commit is contained in:
parent
43ccbf165c
commit
18be83519d
|
|
@ -0,0 +1,26 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 学生基本信息列表
|
||||||
|
export function stuBaseInfoLists(params?: Record<string, any>) {
|
||||||
|
return request.get({ url: '/stuBaseInfo/list', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 学生基本信息详情
|
||||||
|
export function stuBaseInfoDetail(params: Record<string, any>) {
|
||||||
|
return request.get({ url: '/stuBaseInfo/detail', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 学生基本信息新增
|
||||||
|
export function stuBaseInfoAdd(params: Record<string, any>) {
|
||||||
|
return request.post({ url: '/stuBaseInfo/add', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 学生基本信息编辑
|
||||||
|
export function stuBaseInfoEdit(params: Record<string, any>) {
|
||||||
|
return request.post({ url: '/stuBaseInfo/edit', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 学生基本信息删除
|
||||||
|
export function stuBaseInfoDelete(params: Record<string, any>) {
|
||||||
|
return request.post({ url: '/stuBaseInfo/del', params })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,333 @@
|
||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup
|
||||||
|
ref="popupRef"
|
||||||
|
:title="popupTitle"
|
||||||
|
:async="true"
|
||||||
|
width="550px"
|
||||||
|
:clickModalClose="true"
|
||||||
|
@confirm="handleSubmit"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
|
<el-input v-model="formData.idCard" placeholder="请输入身份证号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker
|
||||||
|
class="flex-1 !flex"
|
||||||
|
v-model="formData.birthday"
|
||||||
|
type="datetime"
|
||||||
|
clearable
|
||||||
|
value-format="YYYY-MM-DD hh:mm:ss"
|
||||||
|
placeholder="请选择出生日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="民族" prop="nationality">
|
||||||
|
<el-input v-model="formData.nationality" placeholder="请输入民族" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="政治面貌" prop="politicalStatus">
|
||||||
|
<el-radio-group v-model="formData.politicalStatus" placeholder="请选择政治面貌">
|
||||||
|
<el-radio :label="0">群众</el-radio>
|
||||||
|
<el-radio :label="1">团员</el-radio>
|
||||||
|
<el-radio :label="2">党员</el-radio>
|
||||||
|
<el-radio :label="3">其他</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号码" prop="phone">
|
||||||
|
<el-input v-model="formData.phone" placeholder="请输入手机号码" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="紧急联系人" prop="emergencyContact">
|
||||||
|
<el-input v-model="formData.emergencyContact" placeholder="请输入紧急联系人" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="紧急联系电话" prop="emergencyPhone">
|
||||||
|
<el-input v-model="formData.emergencyPhone" placeholder="请输入紧急联系电话" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="与紧急联系人关系" prop="relationship">
|
||||||
|
<el-input v-model="formData.relationship" placeholder="请输入关系" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="家庭住址" prop="homeAddress">
|
||||||
|
<el-input v-model="formData.homeAddress" placeholder="请输入家庭住址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="籍贯" prop="nativePlace">
|
||||||
|
<el-input v-model="formData.nativePlace" placeholder="请输入籍贯" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮政编码" prop="postalCode">
|
||||||
|
<el-input v-model="formData.postalCode" placeholder="请输入邮政编码" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="毕业学校" prop="previousSchool">
|
||||||
|
<el-input v-model="formData.previousSchool" placeholder="请输入毕业学校" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学校类型" prop="schoolType">
|
||||||
|
<el-select
|
||||||
|
class="flex-1"
|
||||||
|
v-model="formData.schoolType"
|
||||||
|
placeholder="请选择学校类型"
|
||||||
|
>
|
||||||
|
<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="学历" prop="academicQualification">
|
||||||
|
<el-select
|
||||||
|
class="flex-1"
|
||||||
|
v-model="formData.academicQualification"
|
||||||
|
placeholder="请选择学历"
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
|
||||||
|
import { stuBaseInfoAdd, stuBaseInfoDetail, stuBaseInfoEdit } from '@/api/stuBaseInfo'
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
defineProps({
|
||||||
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return mode.value == 'edit' ? '编辑学生基本信息' : '新增学生基本信息'
|
||||||
|
})
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
id: '',
|
||||||
|
userId: '',
|
||||||
|
name: '',
|
||||||
|
gender: '',
|
||||||
|
idCard: '',
|
||||||
|
birthday: '',
|
||||||
|
nationality: '',
|
||||||
|
politicalStatus: '',
|
||||||
|
phone: '',
|
||||||
|
email: '',
|
||||||
|
emergencyContact: '',
|
||||||
|
emergencyPhone: '',
|
||||||
|
relationship: '',
|
||||||
|
homeAddress: '',
|
||||||
|
nativePlace: '',
|
||||||
|
postalCode: '',
|
||||||
|
previousSchool: '',
|
||||||
|
schoolType: '',
|
||||||
|
graduationYear: '',
|
||||||
|
academicQualification: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules = {
|
||||||
|
id: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入主键ID',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
userId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入关联用户ID',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入姓名',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
gender: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入性别',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
idCard: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入身份证号',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
birthday: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择出生日期',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
nationality: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入民族',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
politicalStatus: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择政治面貌',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入手机号码',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入邮箱',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
emergencyContact: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入紧急联系人',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
emergencyPhone: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入紧急联系电话',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
relationship: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入与紧急联系人关系',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
homeAddress: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入家庭住址',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
nativePlace: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入籍贯',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
postalCode: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入邮政编码',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
previousSchool: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入毕业学校',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
schoolType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择学校类型',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
graduationYear: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入毕业年份',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
academicQualification: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择学历',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
majorStudied: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入原所学专业',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
const data: any = { ...formData }
|
||||||
|
mode.value == 'edit' ? await stuBaseInfoEdit(data) : await stuBaseInfoAdd(data)
|
||||||
|
popupRef.value?.close()
|
||||||
|
feedback.msgSuccess('操作成功')
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = (type = 'add') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
const setFormData = async (data: Record<string, any>) => {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDetail = async (row: Record<string, any>) => {
|
||||||
|
const data = await stuBaseInfoDetail({
|
||||||
|
id: row.id
|
||||||
|
})
|
||||||
|
setFormData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData,
|
||||||
|
getDetail
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,230 @@
|
||||||
|
<template>
|
||||||
|
<div class="index-lists">
|
||||||
|
<el-card class="!border-none" shadow="never">
|
||||||
|
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input class="w-[280px]" v-model="queryParams.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
|
<el-input class="w-[280px]" v-model="queryParams.idCard" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="民族" prop="nationality">
|
||||||
|
<el-input class="w-[280px]" v-model="queryParams.nationality" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="政治面貌" prop="politicalStatus">
|
||||||
|
<el-select v-model="queryParams.politicalStatus" class="w-[280px]" clearable>
|
||||||
|
<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="手机号码" prop="phone">
|
||||||
|
<el-input class="w-[280px]" v-model="queryParams.phone" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="籍贯" prop="nativePlace">
|
||||||
|
<el-input class="w-[280px]" v-model="queryParams.nativePlace" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="学校类型" prop="schoolType">
|
||||||
|
<el-select v-model="queryParams.schoolType" class="w-[280px]" clearable>
|
||||||
|
<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="学历" prop="academicQualification">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.academicQualification"
|
||||||
|
class="w-[280px]"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="!border-none mt-4" shadow="never">
|
||||||
|
<div>
|
||||||
|
<el-button v-perms="['stuBaseInfo:add']" type="primary" @click="handleAdd()">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Plus" />
|
||||||
|
</template>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table class="mt-4" size="large" v-loading="pager.loading" :data="pager.lists">
|
||||||
|
<el-table-column label="关联用户ID" prop="userId" min-width="100" />
|
||||||
|
<el-table-column label="姓名" prop="name" min-width="100" />
|
||||||
|
<el-table-column
|
||||||
|
label="性别"
|
||||||
|
prop="gender"
|
||||||
|
min-width="100"
|
||||||
|
:formatter="formatGender"
|
||||||
|
/>
|
||||||
|
<el-table-column label="身份证号" prop="idCard" min-width="100" />
|
||||||
|
<el-table-column label="出生日期" prop="birthday" min-width="100" />
|
||||||
|
<el-table-column label="民族" prop="nationality" min-width="100" />
|
||||||
|
<el-table-column
|
||||||
|
label="政治面貌"
|
||||||
|
prop="politicalStatus"
|
||||||
|
min-width="100"
|
||||||
|
:formatter="formatPoliticalStatus"
|
||||||
|
/>
|
||||||
|
<el-table-column label="手机号码" prop="phone" min-width="100" />
|
||||||
|
<el-table-column label="邮箱" prop="email" min-width="100" />
|
||||||
|
<el-table-column label="紧急联系人" prop="emergencyContact" min-width="100" />
|
||||||
|
<el-table-column label="紧急联系电话" prop="emergencyPhone" min-width="100" />
|
||||||
|
<el-table-column label="与紧急联系人关系" prop="relationship" min-width="100" />
|
||||||
|
<el-table-column label="家庭住址" prop="homeAddress" min-width="100" />
|
||||||
|
<el-table-column label="籍贯" prop="nativePlace" min-width="100" />
|
||||||
|
<el-table-column label="邮政编码" prop="postalCode" min-width="100" />
|
||||||
|
<el-table-column label="毕业学校" prop="previousSchool" min-width="100" />
|
||||||
|
<el-table-column
|
||||||
|
label="学校类型"
|
||||||
|
prop="schoolType"
|
||||||
|
min-width="100"
|
||||||
|
:formatter="formatSchoolType"
|
||||||
|
/>
|
||||||
|
<el-table-column label="毕业年份" prop="graduationYear" min-width="100" />
|
||||||
|
<el-table-column
|
||||||
|
label="学历"
|
||||||
|
prop="academicQualification"
|
||||||
|
min-width="100"
|
||||||
|
:formatter="formatAcademicQualification"
|
||||||
|
/>
|
||||||
|
<el-table-column label="创建时间" prop="createTime" min-width="100" />
|
||||||
|
<el-table-column label="更新时间" prop="updateTime" min-width="100" />
|
||||||
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-perms="['stuBaseInfo:edit']"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="handleEdit(row)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-perms="['stuBaseInfo:del']"
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
@click="handleDelete(row.id)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="flex justify-end mt-4">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup name="stuBaseInfo">
|
||||||
|
import { stuBaseInfoDelete, stuBaseInfoLists } from '@/api/stuBaseInfo'
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
|
||||||
|
import EditPopup from './edit.vue'
|
||||||
|
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||||
|
const showEdit = ref(false)
|
||||||
|
const queryParams = reactive({
|
||||||
|
userId: '',
|
||||||
|
name: '',
|
||||||
|
gender: '',
|
||||||
|
idCard: '',
|
||||||
|
nationality: '',
|
||||||
|
politicalStatus: '',
|
||||||
|
phone: '',
|
||||||
|
nativePlace: '',
|
||||||
|
schoolType: '',
|
||||||
|
graduationYear: '',
|
||||||
|
academicQualification: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||||
|
fetchFun: stuBaseInfoLists,
|
||||||
|
params: queryParams
|
||||||
|
})
|
||||||
|
|
||||||
|
const formatGender = (row: any, column: any, cellValue: any) => {
|
||||||
|
const genderMap: Record<string | number, string> = {
|
||||||
|
'0': '未知',
|
||||||
|
'1': '男',
|
||||||
|
'2': '女'
|
||||||
|
}
|
||||||
|
return genderMap[String(cellValue)] || cellValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatPoliticalStatus = (row: any, column: any, cellValue: any) => {
|
||||||
|
const statusMap: Record<string | number, string> = {
|
||||||
|
'0': '群众',
|
||||||
|
'1': '团员',
|
||||||
|
'2': '党员',
|
||||||
|
'3': '其他'
|
||||||
|
}
|
||||||
|
return statusMap[String(cellValue)] || cellValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatSchoolType = (row: any, column: any, cellValue: any) => {
|
||||||
|
const statusMap: Record<string | number, string> = {
|
||||||
|
'1': '普通高中',
|
||||||
|
'2': '职业高中',
|
||||||
|
'3': '中专',
|
||||||
|
'4': '大专',
|
||||||
|
'5': '本科',
|
||||||
|
'6': '其他'
|
||||||
|
}
|
||||||
|
return statusMap[String(cellValue)] || cellValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatAcademicQualification = (row: any, column: any, cellValue: any) => {
|
||||||
|
const statusMap: Record<string | number, string> = {
|
||||||
|
'1': '初中',
|
||||||
|
'2': '高中',
|
||||||
|
'3': '中专',
|
||||||
|
'4': '大专',
|
||||||
|
'5': '本科',
|
||||||
|
'6': '硕士',
|
||||||
|
'7': '博士'
|
||||||
|
}
|
||||||
|
return statusMap[String(cellValue)] || cellValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAdd = async () => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('add')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEdit = async (data: any) => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('edit')
|
||||||
|
editRef.value?.getDetail(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
await feedback.confirm('确定要删除?')
|
||||||
|
await stuBaseInfoDelete({ id })
|
||||||
|
feedback.msgSuccess('删除成功')
|
||||||
|
getLists()
|
||||||
|
}
|
||||||
|
|
||||||
|
getLists()
|
||||||
|
</script>
|
||||||
|
|
@ -18,10 +18,10 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="年级" prop="grade">
|
<el-form-item label="年级" prop="grade">
|
||||||
<el-select class="flex-1" v-model="formData.grade" placeholder="请选择年级: ">
|
<el-select class="flex-1" v-model="formData.grade" placeholder="请选择年级: ">
|
||||||
<el-option label="一年级" value="1" />
|
<el-option label="一年级" :value="1" />
|
||||||
<el-option label="二年级" value="2" />
|
<el-option label="二年级" :value="2" />
|
||||||
<el-option label="三年级" value="3" />
|
<el-option label="三年级" :value="3" />
|
||||||
<el-option label="四年级" value="4" />
|
<el-option label="四年级" :value="4" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="班级" prop="className">
|
<el-form-item label="班级" prop="className">
|
||||||
|
|
@ -36,10 +36,10 @@
|
||||||
v-model="formData.studentStatus"
|
v-model="formData.studentStatus"
|
||||||
placeholder="请选择学生状态: "
|
placeholder="请选择学生状态: "
|
||||||
>
|
>
|
||||||
<el-option label="在读" value="1" />
|
<el-option label="在读" :value="1" />
|
||||||
<el-option label="休学" value="2" />
|
<el-option label="休学" :value="2" />
|
||||||
<el-option label="毕业" value="3" />
|
<el-option label="毕业" :value="3" />
|
||||||
<el-option label="退学" value="4" />
|
<el-option label="退学" :value="4" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证号" prop="idCard">
|
<el-form-item label="身份证号" prop="idCard">
|
||||||
|
|
@ -51,9 +51,9 @@
|
||||||
v-model="formData.politicalStatus"
|
v-model="formData.politicalStatus"
|
||||||
placeholder="请选择政治面貌: "
|
placeholder="请选择政治面貌: "
|
||||||
>
|
>
|
||||||
<el-option label="党员" value="1" />
|
<el-option label="党员" :value="1" />
|
||||||
<el-option label="团员" value="2" />
|
<el-option label="团员" :value="2" />
|
||||||
<el-option label="群众" value="3" />
|
<el-option label="群众" :value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="籍贯" prop="nativePlace">
|
<el-form-item label="籍贯" prop="nativePlace">
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,7 @@
|
||||||
* @return { Promise } 包含学生基本信息的响应
|
* @return { Promise } 包含学生基本信息的响应
|
||||||
*/
|
*/
|
||||||
export function getStudentBaseInfo() {
|
export function getStudentBaseInfo() {
|
||||||
// 模拟后端数据
|
return $request.get({ url: '/enrollment/studentBaseInfo' })
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
data: {
|
|
||||||
name: '张三',
|
|
||||||
gender: 'male',
|
|
||||||
idCard: '110101201001011234',
|
|
||||||
phone: '13800138000',
|
|
||||||
address: '北京市海淀区XX街道XX小区',
|
|
||||||
emergencyContact: '李四',
|
|
||||||
emergencyPhone: '13900139000'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, 500) // 模拟网络延迟
|
|
||||||
})
|
|
||||||
// 真实接口(后端恢复后启用)
|
|
||||||
// return $request.get({ url: '/enrollment/studentInfo', params })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -29,19 +12,14 @@ export function getStudentBaseInfo() {
|
||||||
* @return { Promise } 更新结果
|
* @return { Promise } 更新结果
|
||||||
*/
|
*/
|
||||||
export function updateStudentBaseInfo(params: any) {
|
export function updateStudentBaseInfo(params: any) {
|
||||||
// 模拟后端数据
|
return $request.post({ url: '/enrollment/studentBaseInfo', params })
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
data: {
|
|
||||||
success: true,
|
|
||||||
message: '信息保存成功'
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}, 500)
|
/**
|
||||||
})
|
* @description 提交报名信息(对应"提交报名"按钮)
|
||||||
// 真实接口(后端恢复后启用)
|
*/
|
||||||
// return $request.post({ url: '/enrollment/studentInfo', params })
|
export function submitEnrollmentInfo() {
|
||||||
|
return $request.post({ url: '/enrollment/submit' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,23 +27,5 @@ export function updateStudentBaseInfo(params: any) {
|
||||||
* @return { Promise } 包含所有步骤状态的响应
|
* @return { Promise } 包含所有步骤状态的响应
|
||||||
*/
|
*/
|
||||||
export function getEnrollmentProcessStatus() {
|
export function getEnrollmentProcessStatus() {
|
||||||
// 模拟后端数据
|
return $request.get({ url: '/enrollment/processStatus' })
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
data: {
|
|
||||||
label: '审核完毕',
|
|
||||||
type: 'success',
|
|
||||||
steps: [
|
|
||||||
{ completed: true, time: '2025-05-01 10:30:00' },
|
|
||||||
{ completed: true, time: '2025-05-01 10:30:00' },
|
|
||||||
{ completed: false, time: '' },
|
|
||||||
{ completed: false, time: '' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
// 真实接口(后端恢复后启用)
|
|
||||||
// return $request.get({ url: '/enrollment/processStatus' })
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
body {
|
body {
|
||||||
@apply text-base text-tx-primary bg-page;
|
@apply text-base text-tx-primary bg-page;
|
||||||
min-width: 1200px;
|
|
||||||
}
|
}
|
||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ export const NAVBAR = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '管理后台',
|
name: '管理后台',
|
||||||
path: '/admin',
|
path: 'http://192.168.123.110:5173/workbench'
|
||||||
component: 'admin'
|
},
|
||||||
|
{
|
||||||
|
name: '接口文档',
|
||||||
|
path: 'http://192.168.123.111:8084/doc.html#/home'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<footer class="layout-footer text-center bg-[#222222] py-[30px]">
|
<footer
|
||||||
<div class="text-[#bebebe]">
|
class="layout-footer text-center bg-[#222222] py-[30px] md:py-[30px] sm:py-[15px]"
|
||||||
<!-- <NuxtLink> 关于我们 </NuxtLink>
|
>
|
||||||
| -->
|
<!-- 链接区域:添加类名方便适配,分隔符单独包裹 -->
|
||||||
<NuxtLink :to="`/policy/${PolicyAgreementEnum.SERVICE}`">
|
<div class="text-[#bebebe] footer-links">
|
||||||
|
<NuxtLink
|
||||||
|
class="footer-link"
|
||||||
|
:to="`/policy/${PolicyAgreementEnum.SERVICE}`"
|
||||||
|
>
|
||||||
用户协议
|
用户协议
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
<span class="footer-divider">|</span>
|
||||||
<NuxtLink :to="`/policy/${PolicyAgreementEnum.PRIVACY}`">
|
<NuxtLink
|
||||||
|
class="footer-link"
|
||||||
|
:to="`/policy/${PolicyAgreementEnum.PRIVACY}`"
|
||||||
|
>
|
||||||
隐私政策
|
隐私政策
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
<span class="footer-divider">|</span>
|
||||||
<NuxtLink to="/user/info"> 会员中心 </NuxtLink>
|
<NuxtLink class="footer-link" to="/user/info"> 会员中心 </NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 text-tx-secondary">
|
<!-- 版权信息:调整间距类名 -->
|
||||||
|
<div class="mt-4 sm:mt-2 text-tx-secondary copyright">
|
||||||
<a
|
<a
|
||||||
class="mx-1 hover:underline"
|
class="mx-1 sm:mx-2 sm:mb-2 hover:underline"
|
||||||
:href="item.value"
|
:href="item.value"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
v-for="item in appStore.getCopyrightConfig"
|
v-for="item in appStore.getCopyrightConfig"
|
||||||
|
|
@ -26,10 +34,53 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
import { PolicyAgreementEnum } from '@/enums/appEnums'
|
import { PolicyAgreementEnum } from '@/enums/appEnums'
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.layout-footer {
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
.footer-link {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.copyright {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.footer-links {
|
||||||
|
font-size: 12px; // 缩小字体
|
||||||
|
flex-wrap: wrap; // 允许链接换行,避免拥挤
|
||||||
|
gap: 6px 10px; // 换行后上下间距6px,左右间距10px
|
||||||
|
.footer-divider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.footer-link {
|
||||||
|
padding: 6px 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.copyright {
|
||||||
|
font-size: 11px; // 缩小版权字体
|
||||||
|
a {
|
||||||
|
display: inline-block; // 让 margin-bottom 生效
|
||||||
|
margin-bottom: 6px; // 换行后增加垂直间距
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,130 @@
|
||||||
<template>
|
<template>
|
||||||
<header class="layout-header text-white bg-primary">
|
<header class="layout-header text-white bg-primary">
|
||||||
<div class="header-contain">
|
<div class="header-contain">
|
||||||
<Logo class="flex-none mr-4" />
|
<!-- 移动端菜单按钮 -->
|
||||||
<Navbar class="w-[600px]" />
|
<button
|
||||||
|
v-if="isMobile"
|
||||||
|
@click="showMobileMenu = !showMobileMenu"
|
||||||
|
class="md:hidden mr-2 p-2 rounded-lg hover:bg-primary-dark transition-colors"
|
||||||
|
>
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
v-if="!showMobileMenu"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 6h16M4 12h16M4 18h16"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
v-else
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Logo class="flex-none mr-4" :class="{'mr-2': isMobile}" />
|
||||||
|
|
||||||
|
<!-- 桌面端导航栏 -->
|
||||||
|
<Navbar v-if="!isMobile" class="w-[600px]" />
|
||||||
|
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<Search class="mr-[40px] flex-none" />
|
|
||||||
|
<!-- 搜索框 - 移动端显示图标,点击展开 -->
|
||||||
|
<div class="relative">
|
||||||
|
<!-- 移动端搜索图标 -->
|
||||||
|
<button
|
||||||
|
v-if="isMobile && !showSearch"
|
||||||
|
@click="showSearch = true"
|
||||||
|
class="md:hidden mr-4 p-2 rounded-lg hover:bg-primary-dark transition-colors"
|
||||||
|
>
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 移动端搜索框 -->
|
||||||
|
<div
|
||||||
|
v-if="isMobile && showSearch"
|
||||||
|
class="md:hidden absolute right-0 top-0 z-10 bg-primary p-2 rounded-lg shadow-lg"
|
||||||
|
>
|
||||||
|
<Search class="w-[200px]" />
|
||||||
|
<button
|
||||||
|
@click="showSearch = false"
|
||||||
|
class="absolute -top-1 -right-1 p-1 bg-white text-primary rounded-full"
|
||||||
|
>
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 桌面端搜索框 -->
|
||||||
|
<Search v-if="!isMobile" class="mr-[40px] flex-none" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<User class="flex-none" />
|
<User class="flex-none" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 移动端导航菜单 -->
|
||||||
|
<div
|
||||||
|
v-if="isMobile && showMobileMenu"
|
||||||
|
class="md:hidden absolute top-full left-0 right-0 bg-primary shadow-lg z-50"
|
||||||
|
>
|
||||||
|
<Navbar
|
||||||
|
class="w-full"
|
||||||
|
mode="vertical"
|
||||||
|
@item-click="showMobileMenu = false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import User from './user.vue'
|
import User from './user.vue'
|
||||||
import Search from './search.vue'
|
import Search from './search.vue'
|
||||||
import Logo from './logo.vue'
|
import Logo from './logo.vue'
|
||||||
import Navbar from './navbar.vue'
|
import Navbar from './navbar.vue'
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
// 响应式判断
|
||||||
|
const isMobile = ref(false)
|
||||||
|
const showMobileMenu = ref(false)
|
||||||
|
const showSearch = ref(false)
|
||||||
|
|
||||||
|
const checkMobile = () => {
|
||||||
|
isMobile.value = window.outerWidth < 768 // Tailwind md断点
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
checkMobile()
|
||||||
|
window.addEventListener('resize', checkMobile)
|
||||||
|
// 点击外部关闭移动菜单和搜索
|
||||||
|
window.addEventListener('click', handleClickOutside)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', checkMobile)
|
||||||
|
window.removeEventListener('click', handleClickOutside)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击外部关闭移动菜单和搜索
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
const header = document.querySelector('.layout-header')
|
||||||
|
if (header && !header.contains(event.target as Node)) {
|
||||||
|
showMobileMenu.value = false
|
||||||
|
showSearch.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由变化时关闭移动菜单
|
||||||
|
const route = useRoute()
|
||||||
|
watch(() => route.path, () => {
|
||||||
|
showMobileMenu.value = false
|
||||||
|
showSearch.value = false
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -24,12 +135,19 @@ import Navbar from './navbar.vue'
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1999;
|
z-index: 1999;
|
||||||
|
|
||||||
.header-contain {
|
.header-contain {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 0 1rem;
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
--el-menu-item-font-size: var(--el-font-size-large);
|
--el-menu-item-font-size: var(--el-font-size-large);
|
||||||
--el-menu-bg-color: var(--el-color-primary);
|
--el-menu-bg-color: var(--el-color-primary);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<main class="mx-auto w-[1200px] py-4">
|
<main class="mx-auto py-4 flex" style="min-width: 62vw; min-height: 100vh">
|
||||||
|
<!-- 移动端菜单按钮 -->
|
||||||
|
<button
|
||||||
|
v-if="sidebar.length && isMobile"
|
||||||
|
@click="showMobileMenu = true"
|
||||||
|
class="fixed left-4 top-[68px] z-50 md:hidden p-2 rounded-full bg-white shadow-lg transition-all duration-300"
|
||||||
|
:class="{ '-translate-x-full': showMobileMenu, 'translate-x-0': !showMobileMenu }"
|
||||||
|
>
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 桌面端侧边栏 -->
|
||||||
<div
|
<div
|
||||||
v-if="sidebar.length"
|
v-if="sidebar.length && !isMobile"
|
||||||
class="mr-4 bg-white rounded-[8px] overflow-hidden"
|
class="hidden md:block mr-4 bg-white rounded-[8px] overflow-hidden"
|
||||||
>
|
>
|
||||||
<Menu
|
<Menu
|
||||||
:menu="sidebar"
|
:menu="sidebar"
|
||||||
|
|
@ -10,11 +23,42 @@
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 移动端抽屉式侧边栏 -->
|
||||||
|
<div
|
||||||
|
v-if="sidebar.length && isMobile"
|
||||||
|
class="fixed inset-0 z-40"
|
||||||
|
:class="{'pointer-events-none': !showMobileMenu}"
|
||||||
|
>
|
||||||
|
<!-- 遮罩层 -->
|
||||||
|
<div
|
||||||
|
v-if="showMobileMenu"
|
||||||
|
@click="showMobileMenu = false"
|
||||||
|
class="absolute inset-0 transition-opacity"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 侧边栏内容 -->
|
||||||
|
<div
|
||||||
|
class="absolute top-[60px] left-0 h-full w-64 bg-white transform transition-transform duration-300"
|
||||||
|
:class="{'translate-x-0': showMobileMenu, '-translate-x-full': !showMobileMenu}"
|
||||||
|
>
|
||||||
|
<Menu
|
||||||
|
:menu="sidebar"
|
||||||
|
:default-active="activeMenu"
|
||||||
|
mode="vertical"
|
||||||
|
@click="showMobileMenu = false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主内容区域 -->
|
||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
'layout-page flex-1 min-w-0 rounded-[8px]',
|
'layout-page flex-1 min-w-0 rounded-[8px] transition-all duration-300',
|
||||||
{
|
{
|
||||||
'bg-body': hasSidebar
|
'bg-body': hasSidebar,
|
||||||
|
'md:ml-0': !isMobile || !sidebar.length,
|
||||||
|
'ml-0': isMobile && sidebar.length
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
|
@ -22,9 +66,36 @@
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Menu from '../menu/index.vue'
|
import Menu from '../menu/index.vue'
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const activeMenu = computed<string>(() => route.meta.activeMenu ?? route.path)
|
const activeMenu = computed<string>(() => route.meta.activeMenu ?? route.path)
|
||||||
const { sidebar, hasSidebar } = useMenu()
|
const { sidebar, hasSidebar } = useMenu()
|
||||||
|
|
||||||
|
// 响应式判断
|
||||||
|
const isMobile = ref(false)
|
||||||
|
const showMobileMenu = ref(false)
|
||||||
|
|
||||||
|
const checkMobile = () => {
|
||||||
|
isMobile.value = window.outerWidth < 768 // 使用 Tailwind 的 md 断点
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
checkMobile()
|
||||||
|
window.addEventListener('resize', checkMobile)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', checkMobile)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 路由变化时关闭移动端菜单
|
||||||
|
watch(() => route.path, () => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
showMobileMenu.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<section class="layout-default min-w-[1200px]">
|
<section class="layout-default">
|
||||||
<LayoutHeader />
|
<LayoutHeader />
|
||||||
<div class="main-contain">
|
<div class="main-contain">
|
||||||
<LayoutMain class="flex-1 min-h-0 flex">
|
<LayoutMain class="flex-1 min-h-0 flex">
|
||||||
|
|
@ -22,7 +22,7 @@ const userStore = useUserStore();
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.main-contain {
|
.main-contain {
|
||||||
min-height: calc(100vh - var(--header-height));
|
min-height: 100vh;
|
||||||
@apply flex flex-col;
|
@apply flex flex-col;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="bg-white render-html p-[30px] w-[1200px] mx-auto min-h-screen">
|
<div class="bg-white render-html p-[30px] mx-auto min-h-screen">
|
||||||
<h1 class="text-center">{{ data.title }}</h1>
|
<h1 class="text-center">{{ data.title }}</h1>
|
||||||
<div class="mx-auto" v-html="data.content"></div>
|
<div class="mx-auto" v-html="data.content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,42 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="px-[30px] py-5 user-info min-h-full flex flex-col">
|
<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">
|
<div class="border-b border-br pb-5">
|
||||||
<span class="text-2xl font-medium">新生报名</span>
|
<span class="text-2xl font-medium">{{
|
||||||
|
submission ? '信息查看' : '新生报名'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="!border-none mb-4" shadow="never">
|
<el-card class="!border-none mb-4" shadow="never">
|
||||||
<div class="lg:flex gap-6">
|
<div class="lg:flex gap-6">
|
||||||
|
|
@ -17,26 +52,132 @@
|
||||||
<el-input
|
<el-input
|
||||||
v-model="studentData.baseInfo.name"
|
v-model="studentData.baseInfo.name"
|
||||||
placeholder="请输入姓名"
|
placeholder="请输入姓名"
|
||||||
|
:disabled="submission"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="性别">
|
<el-form-item label="性别">
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="studentData.baseInfo.gender"
|
v-model="studentData.baseInfo.gender"
|
||||||
|
:disabled="submission"
|
||||||
>
|
>
|
||||||
<el-radio label="male">男</el-radio>
|
<el-radio :label="0">男</el-radio>
|
||||||
<el-radio label="female">女</el-radio>
|
<el-radio :label="1">女</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证号">
|
<el-form-item label="身份证号">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="studentData.baseInfo.idCard"
|
v-model="studentData.baseInfo.idCard"
|
||||||
placeholder="请输入18位身份证号"
|
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>
|
||||||
<el-form-item label="联系方式">
|
<el-form-item label="联系方式">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="studentData.baseInfo.phone"
|
v-model="studentData.baseInfo.phone"
|
||||||
placeholder="请输入手机号码"
|
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>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -44,10 +185,11 @@
|
||||||
class="md:col-span-2"
|
class="md:col-span-2"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="studentData.baseInfo.address"
|
v-model="studentData.baseInfo.homeAddress"
|
||||||
placeholder="请输入详细家庭住址"
|
placeholder="请输入详细家庭住址"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
rows="3"
|
rows="3"
|
||||||
|
:disabled="submission"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="紧急联系人">
|
<el-form-item label="紧急联系人">
|
||||||
|
|
@ -56,6 +198,7 @@
|
||||||
studentData.baseInfo.emergencyContact
|
studentData.baseInfo.emergencyContact
|
||||||
"
|
"
|
||||||
placeholder="请输入紧急联系人姓名"
|
placeholder="请输入紧急联系人姓名"
|
||||||
|
:disabled="submission"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="紧急联系电话">
|
<el-form-item label="紧急联系电话">
|
||||||
|
|
@ -64,6 +207,14 @@
|
||||||
studentData.baseInfo.emergencyPhone
|
studentData.baseInfo.emergencyPhone
|
||||||
"
|
"
|
||||||
placeholder="请输入紧急联系人电话"
|
placeholder="请输入紧急联系人电话"
|
||||||
|
:disabled="submission"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="与紧急联系人关系">
|
||||||
|
<el-input
|
||||||
|
v-model="studentData.baseInfo.relationship"
|
||||||
|
placeholder="请输入与紧急联系人的关系"
|
||||||
|
:disabled="submission"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,83 +224,139 @@
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 注册状态信息 -->
|
<!-- 注册状态信息 -->
|
||||||
<el-card class="!border-none mb-4 flex-1" shadow="never">
|
<el-card class="!border-none mb-4 flex-1" shadow="never">
|
||||||
<template #header>
|
<div v-if="!submission" class="mt-6">
|
||||||
<span>注册状态</span>
|
<el-button type="primary" block @click="handleSave">
|
||||||
</template>
|
保存信息
|
||||||
<div class="status-info mt-4">
|
</el-button>
|
||||||
<div class="mb-6">
|
<el-button
|
||||||
<div class="text-tx-secondary text-sm mb-2">当前状态</div>
|
class="ml-4"
|
||||||
<el-tag :type="statusConfig.type">{{
|
type="success"
|
||||||
statusConfig.label
|
block
|
||||||
}}</el-tag>
|
@click="handleShowConfirmDialog"
|
||||||
</div>
|
:disabled="statusConfig.steps[0].completed"
|
||||||
<div class="mb-6">
|
|
||||||
<div class="text-tx-secondary text-sm mb-2">状态进度</div>
|
|
||||||
<el-progress
|
|
||||||
:percentage="statusConfig.progress"
|
|
||||||
:stroke-width="6"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<el-checkbox
|
|
||||||
v-model="statusConfig.steps[0].completed"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
已报名
|
|
||||||
</el-checkbox>
|
|
||||||
<span> {{ statusConfig.steps[0].time }} </span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<el-checkbox
|
|
||||||
v-model="statusConfig.steps[1].completed"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
材料审核
|
|
||||||
</el-checkbox>
|
|
||||||
<span>
|
|
||||||
{{ statusConfig.steps[1].time || '待完成' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<el-checkbox
|
|
||||||
v-model="statusConfig.steps[2].completed"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
已录取
|
|
||||||
</el-checkbox>
|
|
||||||
<span>
|
|
||||||
{{ statusConfig.steps[2].time || '待完成' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<el-checkbox
|
|
||||||
v-model="statusConfig.steps[3].completed"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
已入学
|
|
||||||
</el-checkbox>
|
|
||||||
<span>
|
|
||||||
{{ statusConfig.steps[3].time || '待完成' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-6">
|
|
||||||
<el-button type="primary" block @click="handleSave"
|
|
||||||
>保存信息</el-button
|
|
||||||
>
|
>
|
||||||
|
提交报名
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive } from 'vue'
|
import { reactive, computed, onMounted, ref } from 'vue'
|
||||||
import { ElButton } from 'element-plus'
|
import { ElButton, ElMessage } from 'element-plus'
|
||||||
import {
|
import {
|
||||||
getStudentBaseInfo,
|
getStudentBaseInfo,
|
||||||
updateStudentBaseInfo,
|
updateStudentBaseInfo,
|
||||||
getEnrollmentProcessStatus
|
getEnrollmentProcessStatus,
|
||||||
|
submitEnrollmentInfo
|
||||||
} from '@/api/enrollment'
|
} from '@/api/enrollment'
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
|
|
@ -157,16 +364,54 @@ definePageMeta({
|
||||||
auth: true
|
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({
|
const studentData = reactive({
|
||||||
baseInfo: {
|
baseInfo: {
|
||||||
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
gender: 'male',
|
gender: 0,
|
||||||
idCard: '',
|
idCard: '',
|
||||||
|
birthday: '',
|
||||||
|
nationality: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
address: '',
|
email: '',
|
||||||
|
homeAddress: '',
|
||||||
|
nativePlace: '',
|
||||||
|
politicalStatus: 0,
|
||||||
|
previousSchool: '',
|
||||||
|
schoolType: '',
|
||||||
|
academicQualification: '',
|
||||||
|
postalCode: '',
|
||||||
|
graduationYear: 2025,
|
||||||
emergencyContact: '',
|
emergencyContact: '',
|
||||||
emergencyPhone: ''
|
emergencyPhone: '',
|
||||||
|
relationship: ''
|
||||||
},
|
},
|
||||||
additionalInfo: {
|
additionalInfo: {
|
||||||
enrollYear: '',
|
enrollYear: '',
|
||||||
|
|
@ -175,58 +420,183 @@ const studentData = reactive({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 状态配置
|
// 状态配置 - 与后端返回字段对应
|
||||||
type TagType = '' | 'info' | 'success' | 'warning' | 'danger'
|
const statusConfig = reactive({
|
||||||
const statusConfig = reactive<{
|
|
||||||
label: string
|
|
||||||
type: TagType
|
|
||||||
progress: number
|
|
||||||
steps: { completed: boolean; time: string }[]
|
|
||||||
}>({
|
|
||||||
label: '未报名',
|
|
||||||
type: 'info',
|
|
||||||
get progress() {
|
|
||||||
const completedCount = this.steps.filter(
|
|
||||||
(step: { completed: any }) => step.completed
|
|
||||||
).length
|
|
||||||
return (completedCount / this.steps.length) * 100
|
|
||||||
},
|
|
||||||
steps: [
|
steps: [
|
||||||
{ completed: false, time: '' },
|
{ completed: false, time: 0, status: 0 }, // 报名
|
||||||
{ completed: false, time: '' },
|
{ completed: false, time: 0, status: 0 }, // 材料审核
|
||||||
{ completed: false, time: '' },
|
{ completed: false, time: 0, status: 0 }, // 录取
|
||||||
{ completed: false, time: '' }
|
{ completed: false, time: 0, status: 0 } // 缴费
|
||||||
]
|
],
|
||||||
|
applicationNumber: '' // 报名编号
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleSave = async () => {
|
// 格式化时间戳为日期
|
||||||
|
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 {
|
try {
|
||||||
// 调用更新API,传入表单数据(studentData.baseInfo)
|
const info = await getStudentBaseInfo()
|
||||||
const res = await updateStudentBaseInfo(studentData.baseInfo)
|
confirmInfo.value = info
|
||||||
// 接口返回成功时提示
|
showConfirmDialog.value = true
|
||||||
if (res.data.success) {
|
} catch (error) {
|
||||||
ElMessage.success(res.data.message || '信息保存成功')
|
ElMessage.error('获取信息失败,请稍后重试')
|
||||||
} else {
|
console.error('获取确认信息失败:', error)
|
||||||
ElMessage.warning(res.data.message || '保存失败,请检查数据')
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
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) {
|
} 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('保存失败,请稍后重试')
|
ElMessage.error('保存失败,请稍后重试')
|
||||||
console.error('更新信息失败:', error)
|
console.error('更新信息失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 页面挂载时加载数据
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
// 1. 获取学生基本信息并赋值
|
// 1. 加载学生基本信息
|
||||||
const studentInfoRes = await getStudentBaseInfo()
|
const studentInfoRes = await getStudentBaseInfo()
|
||||||
Object.assign(studentData.baseInfo, studentInfoRes.data)
|
Object.assign(studentData.baseInfo, studentInfoRes)
|
||||||
// 2. 获取报名流程状态并赋值
|
if (studentInfoRes.id) {
|
||||||
const statusRes = await getEnrollmentProcessStatus()
|
studentData.baseInfo.id = studentInfoRes.id
|
||||||
// 将接口返回的状态合并到statusConfig
|
}
|
||||||
Object.assign(statusConfig, statusRes.data)
|
|
||||||
|
// 2. 加载报名流程状态
|
||||||
|
await loadProcessStatus()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 处理接口调用失败(如网络错误、后端异常)
|
|
||||||
ElMessage.error('数据加载失败,请稍后重试')
|
ElMessage.error('数据加载失败,请稍后重试')
|
||||||
console.error('获取初始数据失败:', error)
|
console.error('获取初始数据失败:', error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue