merge code pull
This commit is contained in:
@@ -49,6 +49,7 @@ import { ref, reactive } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { putBackObj } from '/@/api/recruit/recruitstudentsignup'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
@@ -119,8 +120,8 @@ const init = async (formData: any, pageData: any) => {
|
||||
checkInStatusData.value = []
|
||||
|
||||
try {
|
||||
const data = await getTypeValue('check_in_status')
|
||||
checkInStatusData.value = data.data || []
|
||||
const dictData = await getDicts('check_in_status')
|
||||
checkInStatusData.value = dictData.data || []
|
||||
} catch (error) {
|
||||
console.error('获取字典数据失败', error)
|
||||
}
|
||||
|
||||
@@ -1,32 +1,87 @@
|
||||
<!--
|
||||
- Copyright (c) 2018-2025, cyweb All rights reserved.
|
||||
-
|
||||
- Redistribution and use in source and binary forms, with or without
|
||||
- modification, are permitted provided that the following conditions are met:
|
||||
-
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
- this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
- notice, this list of conditions and the following disclaimer in the
|
||||
- documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of the pig4cloud.com developer nor the names of its
|
||||
- contributors may be used to endorse or promote products derived from
|
||||
- this software without specific prior written permission.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form :model="queryForm" inline>
|
||||
<el-form-item label="">
|
||||
<el-form :model="queryForm" inline ref="searchFormRef">
|
||||
<el-form-item label="关键词">
|
||||
<el-input
|
||||
v-model="queryForm.searchTotal"
|
||||
clearable
|
||||
placeholder="请输入姓名/身份证号/家庭联系人"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="queryForm.deptCode"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择学院"
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="入学年份" prop="grade">
|
||||
<el-select
|
||||
v-model="queryForm.grade"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择入学年份"
|
||||
style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in planList"
|
||||
:key="item.id"
|
||||
:label="item.year"
|
||||
:value="item.year"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="queryForm.classCode"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择班级"
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="报到状态" prop="checkInStatus">
|
||||
<el-select
|
||||
v-model="queryForm.checkInStatus"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择报到状态"
|
||||
style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in checkInStatusData"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="住宿申请" prop="isDormApply">
|
||||
<el-select
|
||||
v-model="queryForm.isDormApply"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择住宿申请"
|
||||
style="width: 150px">
|
||||
<el-option label="未通过" value="0" />
|
||||
<el-option label="申请通过" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" class="ml10" @click="resetQuery">重置</el-button>
|
||||
@@ -60,7 +115,7 @@
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="classCode" label="班级" align="center" width="80" show-overflow-tooltip />
|
||||
<el-table-column label="姓名/学号" align="center" width="150" show-overflow-tooltip>
|
||||
<el-table-column label="姓名/学号" align="center" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.name" :no="scope.row.stuNo" />
|
||||
</template>
|
||||
@@ -78,32 +133,99 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isDormApply" label="住宿申请" align="center" width="100">
|
||||
<el-table-column prop="isRoom" label="是否住宿" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isDormApply == '1'" type="success">通过</el-tag>
|
||||
<el-tag v-else-if="scope.row.isDormApply == '0'" type="info">未通过</el-tag>
|
||||
<template v-if="scope.row.isRoom == '1'">
|
||||
<DetailPopover
|
||||
title="住宿信息"
|
||||
:title-icon="InfoFilled"
|
||||
:width="320"
|
||||
:items="[
|
||||
{
|
||||
label: '住宿申请',
|
||||
layout: 'horizontal'
|
||||
},
|
||||
{
|
||||
label: '宿舍号',
|
||||
layout: 'horizontal'
|
||||
},
|
||||
{
|
||||
label: '床位号',
|
||||
layout: 'horizontal'
|
||||
}
|
||||
]">
|
||||
<template #reference>
|
||||
<el-tag type="success" class="dorm-tag">
|
||||
{{ getStatusConfig(yes_no_type, scope.row.isRoom)?.label }}
|
||||
<el-icon class="info-icon"><InfoFilled /></el-icon>
|
||||
</el-tag>
|
||||
</template>
|
||||
<!-- 住宿申请状态 -->
|
||||
<template #content-0>
|
||||
<div class="dorm-apply-content">
|
||||
<ClickableTag
|
||||
v-if="scope.row.isDormApply == '1'"
|
||||
type="success"
|
||||
size="small"
|
||||
:left-icon="CircleCheck"
|
||||
:right-icon="null">
|
||||
申请通过
|
||||
</ClickableTag>
|
||||
<ClickableTag
|
||||
v-else-if="scope.row.isDormApply == '0'"
|
||||
type="danger"
|
||||
size="small"
|
||||
:left-icon="CircleClose"
|
||||
:right-icon="null">
|
||||
未通过
|
||||
</ClickableTag>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 宿舍号 -->
|
||||
<template #content-1>
|
||||
<div class="dorm-room-content">
|
||||
<span :class="scope.row.roomNo ? 'room-text' : 'empty-text'">
|
||||
{{ scope.row.roomNo || '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 床位号 -->
|
||||
<template #content-2>
|
||||
<el-tag v-if="scope.row.bedNo" size="small" type="sucess" effect="dark">
|
||||
{{ scope.row.bedNo }}号
|
||||
</el-tag>
|
||||
</template>
|
||||
</DetailPopover>
|
||||
</template>
|
||||
<span v-else>{{ getStatusConfig(yes_no_type, scope.row.isRoom)?.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isRoom" label="是否住宿" align="center" width="100">
|
||||
<el-table-column prop="degreeOfEducation" label="文化程度" align="center" show-overflow-tooltip >
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.isRoom === '1' ? '是' : scope.row.isRoom === '0' ? '否' : '' }}</span>
|
||||
<span>{{ getStatusConfig(eduList, scope.row.degreeOfEducation)?.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roomNo" label="宿舍号" align="center" width="80" show-overflow-tooltip />
|
||||
<el-table-column prop="bedNo" label="床位号" align="center" width="80" show-overflow-tooltip />
|
||||
<el-table-column prop="degreeOfEducation" label="文化程度" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="residenceDetail" label="居住地址" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="parentName" label="家庭联系人" width="100" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="parentTelOne" label="家长电话1" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="parentTelTwo" label="家长电话2" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="家长电话" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.parentTelOne || scope.row.parentTelTwo" class="parent-tel">
|
||||
<span v-if="scope.row.parentTelOne" class="tel-item">{{ scope.row.parentTelOne }}</span>
|
||||
<span v-if="scope.row.parentTelOne && scope.row.parentTelTwo" class="tel-separator">/</span>
|
||||
<span v-if="scope.row.parentTelTwo" class="tel-item">{{ scope.row.parentTelTwo }}</span>
|
||||
</div>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="permissions.recruit_newstucheckin_edit"
|
||||
v-auth="'recruit_newstucheckin_edit'"
|
||||
type="primary"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
icon="EditPen"
|
||||
@click="handleCheckIn(scope.row)"
|
||||
>
|
||||
报到
|
||||
@@ -132,13 +254,23 @@ import { useUserInfo } from '/@/stores/userInfo'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { fetchList } from '/@/api/recruit/newstucheckin'
|
||||
import { getTypeValue } from '/@/api/admin/dict'
|
||||
import { getDictsByTypes } from '/@/api/admin/dict'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import request from '/@/utils/request'
|
||||
import { getStatusConfig } from '/@/config/global'
|
||||
import { getDeptList, getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||
import DetailPopover from '/@/components/DetailPopover/index.vue'
|
||||
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||
import { InfoFilled, CircleCheck, CircleClose, HomeFilled, Grid } from '@element-plus/icons-vue'
|
||||
|
||||
const StuCheckIn = defineAsyncComponent(() => import('./stu-check-in.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const GenderTag = defineAsyncComponent(() => import('/@/components/GenderTag/index.vue'))
|
||||
|
||||
// 是否住宿字典
|
||||
const { yes_no_type } = useDict('yes_no_type')
|
||||
|
||||
// 使用 Pinia store
|
||||
const userInfoStore = useUserInfo()
|
||||
const { userInfos } = storeToRefs(userInfoStore)
|
||||
@@ -155,15 +287,29 @@ const permissions = computed(() => {
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
|
||||
// 文化程度字典数据
|
||||
const eduList = ref<any[]>([])
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const stuCheckInRef = ref()
|
||||
|
||||
// 导出加载状态
|
||||
const exportLoading = ref(false)
|
||||
|
||||
// 数据列表
|
||||
const deptList = ref<any[]>([])
|
||||
const planList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
deptCode: '',
|
||||
grade: '',
|
||||
classCode: '',
|
||||
checkInStatus: '',
|
||||
isDormApply: '',
|
||||
searchTotal: ''
|
||||
})
|
||||
|
||||
@@ -176,6 +322,11 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
deptCode: queryForm.deptCode,
|
||||
grade: queryForm.grade,
|
||||
classCode: queryForm.classCode,
|
||||
checkInStatus: queryForm.checkInStatus,
|
||||
isDormApply: queryForm.isDormApply,
|
||||
searchTotal: queryForm.searchTotal
|
||||
})
|
||||
return {
|
||||
@@ -198,6 +349,12 @@ const getCheckInStatusLabel = (value: string) => {
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
queryForm.deptCode = ''
|
||||
queryForm.grade = ''
|
||||
queryForm.classCode = ''
|
||||
queryForm.checkInStatus = ''
|
||||
queryForm.isDormApply = ''
|
||||
queryForm.searchTotal = ''
|
||||
getDataList()
|
||||
}
|
||||
@@ -256,20 +413,123 @@ const handleExportOut = async () => {
|
||||
}
|
||||
|
||||
// 查询报到状态字典
|
||||
const getCheckInStatusData = async () => {
|
||||
const getDictsData = async () => {
|
||||
try {
|
||||
const data = await getTypeValue('check_in_status')
|
||||
checkInStatusData.value = data.data || []
|
||||
const data = await getDictsByTypes(['check_in_status','finance_student_source'])
|
||||
checkInStatusData.value = data.data.check_in_status || []
|
||||
eduList.value = data.data.finance_student_source || []
|
||||
} catch (error) {
|
||||
// 获取报到状态字典失败
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
const init = async () => {
|
||||
try {
|
||||
// 获取学院列表
|
||||
const deptData = await getDeptList()
|
||||
deptList.value = deptData.data || []
|
||||
|
||||
// 获取入学年份列表(招生计划)
|
||||
const planData = await getList()
|
||||
planList.value = planData.data || []
|
||||
|
||||
// 获取班级列表
|
||||
const classData = await getClassListByRole()
|
||||
classList.value = classData.data || []
|
||||
|
||||
// 获取字典数据
|
||||
await getDictsData()
|
||||
|
||||
getDataList()
|
||||
} catch (error) {
|
||||
message.error('初始化失败')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCheckInStatusData()
|
||||
getDataList()
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.parent-tel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
|
||||
.tel-item {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.tel-separator {
|
||||
color: #909399;
|
||||
margin: 0 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.dorm-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
// 住宿申请状态内容
|
||||
.dorm-apply-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 宿舍号内容
|
||||
.dorm-room-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
.room-icon {
|
||||
color: var(--el-color-primary);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.room-text {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
// 床位号内容
|
||||
.dorm-bed-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
.bed-icon {
|
||||
color: var(--el-color-primary);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.bed-text {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog v-model="newStuCheckInDialog" width="40%">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px"
|
||||
<el-dialog v-model="newStuCheckInDialog" width="600" title="新生报到">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px"
|
||||
class="demo-ruleForm">
|
||||
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="form.name" style=" width: 80%"></el-input>
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-select v-model="form.gender" placeholder="请选择性别" style=" width: 80%">
|
||||
<el-option
|
||||
v-for="item in genderData"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-radio-group v-model="form.gender">
|
||||
<el-radio v-for="item in genderData" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="form.idNumber" style=" width: 80%"></el-input>
|
||||
<el-input v-model="form.idNumber"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="报到状态" prop="checkInStatus">
|
||||
<el-select v-model="form.checkInStatus" filterable placeholder="请选择报到状态" style=" width: 80% ">
|
||||
<el-select v-model="form.checkInStatus" filterable placeholder="请选择报到状态">
|
||||
<el-option
|
||||
v-for="item in checkInStatusData"
|
||||
:key="item.value"
|
||||
@@ -35,7 +29,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否住宿" prop="isRoom" v-if="isRoomTab">
|
||||
<el-select v-model="form.isRoom" filterable placeholder="是否住宿" style=" width: 80% ">
|
||||
<el-select v-model="form.isRoom" filterable placeholder="是否住宿">
|
||||
<el-option
|
||||
v-for="item in yesOrNoData"
|
||||
:key="item.value"
|
||||
@@ -54,7 +48,6 @@
|
||||
:remote-method="remoteMethod"
|
||||
@change="handleRoomNoChange"
|
||||
:loading="loading"
|
||||
style=" width: 80% "
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roomNoList"
|
||||
@@ -66,7 +59,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="床号" prop="bedNo" v-if="isRoomTab && form.isRoom=='1'">
|
||||
<el-select v-model="form.bedNo" filterable placeholder="请选择床号" style=" width: 80% " :key="bedNoKey">
|
||||
<el-select v-model="form.bedNo" filterable placeholder="请选择床号" :key="bedNoKey">
|
||||
<el-option
|
||||
v-for="item in bedNoData"
|
||||
:key="item.bedNo"
|
||||
@@ -78,13 +71,13 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" :rows="2" style=" width: 80%"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="checkIn" v-loading="submitLoading">确定</el-button>
|
||||
<el-button @click="newStuCheckInDialog = false">取消</el-button>
|
||||
<el-input v-model="form.remarks" :rows="2"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="newStuCheckInDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="checkIn" :loading="submitLoading">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@@ -92,10 +85,12 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { getDataByRoomNo } from "/@/api/stuwork/dormroom"
|
||||
import { fearchRoomStuNum } from "/@/api/stuwork/dormroomstudent"
|
||||
import { getDicts } from "/@/api/admin/dict"
|
||||
import { putObj } from '@/api/recruit/newstucheckin'
|
||||
import { putObj } from '/@/api/recruit/newstucheckin'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import { getDataByRoomNo } from '/@/api/stuwork/dormroom'
|
||||
const { sexy:genderData ,yes_no_type:yesOrNoData} = useDict('sexy','yes_no_type')
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
@@ -118,15 +113,7 @@ const loading = ref(false)
|
||||
const isRoomTab = ref(false)
|
||||
const bedNoKey = ref(0) // 用于强制更新床号选择器
|
||||
|
||||
const yesOrNoData = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '是', value: '1' }
|
||||
]
|
||||
|
||||
const genderData = [
|
||||
{ label: '女', value: '2' },
|
||||
{ label: '男', value: '1' }
|
||||
]
|
||||
|
||||
const submitLoading = ref(false)
|
||||
|
||||
@@ -225,7 +212,6 @@ const init = (formData: any, pageData: any) => {
|
||||
getDicts('check_in_status').then(data => {
|
||||
checkInStatusData.value = data.data
|
||||
})
|
||||
console.log("OKKK")
|
||||
}
|
||||
|
||||
// 报到提交
|
||||
@@ -255,8 +241,6 @@ const remoteMethod = (query: string) => {
|
||||
loading.value = true
|
||||
getDataByRoomNo(data).then(data => {
|
||||
roomNoList.value = data.data
|
||||
console.log("this.roomNoList")
|
||||
console.log(roomNoList.value)
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
@@ -266,8 +250,7 @@ const remoteMethod = (query: string) => {
|
||||
|
||||
// 查询此房间为几人间
|
||||
const fearchRoomStuNums = (roomNo: string) => {
|
||||
const data = { "roomNo": roomNo }
|
||||
fearchRoomStuNum(data).then(data => {
|
||||
fearchRoomStuNum(roomNo).then(data => {
|
||||
bedNoData.value = data.data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ import { getObj, addObjStu, putObj } from '/@/api/recruit/recruitprestudent'
|
||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import { queryAllTeacherByRecruit } from '/@/api/professional/professionaluser/teacherbase'
|
||||
import { verifyIdCardAll, verifyPhone, verifyAdmissionNumber } from '/@/utils/toolsValidate'
|
||||
import { verifyPhone, verifyAdmissionNumber } from '/@/utils/toolsValidate'
|
||||
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
@@ -379,17 +379,7 @@ const dataRule = {
|
||||
}
|
||||
],
|
||||
idCard: [
|
||||
{ required: true, message: '身份证不能为空', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value && !verifyIdCardAll(value)) {
|
||||
callback(new Error('请输入正确的身份证号码'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
{ required: true, message: '身份证不能为空', trigger: 'blur' }
|
||||
],
|
||||
admission: [
|
||||
{ required: true, message: '准考证不能为空', trigger: 'blur' },
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -294,14 +294,6 @@
|
||||
icon="Download"
|
||||
@click="handleExport()">名单导出
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
class="ml10"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
v-auth="'recruit_send_img'"
|
||||
@click="handleSendImg()">图片同步
|
||||
</el-button> -->
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
@@ -637,23 +629,17 @@
|
||||
<!-- 支付二维码弹窗 -->
|
||||
<PayQrcodeDialog ref="payQrcodeDialogRef" @refresh="getDataList"></PayQrcodeDialog>
|
||||
|
||||
<!-- 延迟缴费弹窗 -->
|
||||
<DelayPayTimeDialog ref="delayPayTimeDialogRef" @refresh="getDataList"></DelayPayTimeDialog>
|
||||
|
||||
|
||||
<!-- 录取通知书弹窗 -->
|
||||
<AdmissionNoticeDialog ref="admissionNoticeDialogRef" @refresh="getDataList"></AdmissionNoticeDialog>
|
||||
|
||||
<DormFW ref="dormFWRef"></DormFW>
|
||||
<ShowMap ref="baiduMapRef"></ShowMap>
|
||||
<InterviewForm ref="interviewFormRef" @refresh="getDataList"></InterviewForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="recruitstudentsignup">
|
||||
import { ref, reactive, onMounted, nextTick, defineAsyncComponent, watch } from 'vue'
|
||||
import { Edit, Check, DocumentChecked, Close, Switch, Tickets, Document, Upload, Warning, User, CircleCheck, CircleClose, Clock, WarningFilled } from '@element-plus/icons-vue'
|
||||
import { Edit, Check, DocumentChecked, Close, Switch, Tickets, Document, Warning, User, CircleCheck } from '@element-plus/icons-vue'
|
||||
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
@@ -661,27 +647,20 @@ import { auth } from '/@/utils/authFunction'
|
||||
import axios from 'axios'
|
||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||
import {
|
||||
delObj,
|
||||
exportZip,
|
||||
fetchList,
|
||||
leaveSchool,
|
||||
rePush as rePushApi,
|
||||
yjOut,
|
||||
oneClass,
|
||||
oneStuNo,
|
||||
tbStuWork,
|
||||
sendImg,
|
||||
pushCity as pushCityApi
|
||||
pushCity as pushCityApi,
|
||||
resetSign as resetSignApi
|
||||
} from '/@/api/recruit/recruitstudentsignup'
|
||||
import { getLabelValue, getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel'
|
||||
import { getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel'
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { listPlanByCondition as planMajor } from "/@/api/recruit/recruitstudentplan";
|
||||
import { getDictsByTypes } from "/@/api/admin/dict";
|
||||
import { getUserListByRole } from "/@/api/admin/user";
|
||||
import { queryTeacherBaseByNo } from "/@/api/professional/professionaluser/teacherbase";
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import {
|
||||
ROLE_CODE,
|
||||
PUSHED_STATUS_LIST,
|
||||
NOTICE_SEND_STATUS_LIST,
|
||||
RECRUIT_MATERIAL_STATUS_LIST,
|
||||
@@ -697,11 +676,8 @@ import { showLoading, hideLoading } from '/@/api/asset/loading'
|
||||
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
||||
const MajorChange = defineAsyncComponent(() => import('./majorChange.vue'))
|
||||
const Update = defineAsyncComponent(() => import('./update.vue'))
|
||||
const DormFW = defineAsyncComponent(() => import('./dormFW.vue'))
|
||||
const ShowMap = defineAsyncComponent(() => import('./showMap.vue'))
|
||||
const InterviewForm = defineAsyncComponent(() => import('/@/views/recruit/recruitstudentsignup/interviewForm.vue'))
|
||||
const PayQrcodeDialog = defineAsyncComponent(() => import('./PayQrcodeDialog.vue'))
|
||||
const DelayPayTimeDialog = defineAsyncComponent(() => import('./DelayPayTimeDialog.vue'))
|
||||
const AdmissionNoticeDialog = defineAsyncComponent(() => import('./AdmissionNoticeDialog.vue'))
|
||||
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'))
|
||||
|
||||
@@ -715,11 +691,8 @@ const searchFormRef = ref()
|
||||
const addOrUpdateRef = ref()
|
||||
const majorChangeRef = ref()
|
||||
const updateRef = ref()
|
||||
const dormFWRef = ref()
|
||||
const baiduMapRef = ref()
|
||||
const interviewFormRef = ref()
|
||||
const payQrcodeDialogRef = ref()
|
||||
const delayPayTimeDialogRef = ref()
|
||||
const admissionNoticeDialogRef = ref()
|
||||
|
||||
// 搜索表单显示状态
|
||||
@@ -728,7 +701,7 @@ const showSearch = ref(true)
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
zlsh: '',
|
||||
groupId: '',
|
||||
groupId: '',
|
||||
deptCode: '',
|
||||
confirmedMajor: '',
|
||||
degreeOfEducation: '',
|
||||
@@ -739,13 +712,13 @@ const dataForm = reactive({
|
||||
isNewCity: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
lqStartDate: '',
|
||||
lqEndDate: '',
|
||||
lqStartDate: '',
|
||||
lqEndDate: '',
|
||||
paystatus: '',
|
||||
graPic: '',
|
||||
pushed: '',
|
||||
wishMajorOne: '',
|
||||
isTb: '',
|
||||
isTb: '',
|
||||
cityExamType: '',
|
||||
interview: '',
|
||||
type: '',
|
||||
@@ -775,7 +748,6 @@ const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTa
|
||||
// 弹窗状态(已移除,组件内部通过 v-model="visible" 控制)
|
||||
|
||||
// 列表数据
|
||||
const auditorList = ref<any[]>([])
|
||||
const planList = ref<any[]>([])
|
||||
const eduList = ref<any[]>([])
|
||||
const planMajorList = ref<any[]>([])
|
||||
@@ -836,60 +808,15 @@ const remoteTeacherByQuery = (query: string) => {
|
||||
teacherList.value = []
|
||||
})
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
// 发送图片
|
||||
const handleSendImg = () => {
|
||||
messageBox.confirm('是否确认同步招生图片到市平台?请谨慎操作').then(() => {
|
||||
return sendImg()
|
||||
}).then(() => {
|
||||
message.success('同步图片请求已发起,请耐心等待')
|
||||
}).catch(() => {
|
||||
hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
// 同步学工
|
||||
const handleTbStuWork = () => {
|
||||
if (dataForm.groupId == '') {
|
||||
message.warning('招生计划不能为空')
|
||||
return
|
||||
}
|
||||
messageBox.confirm('是否确认同步学工?请谨慎操作').then(() => {
|
||||
showLoading()
|
||||
return tbStuWork(dataForm)
|
||||
}).then(() => {
|
||||
hideLoading()
|
||||
message.success('同步完成')
|
||||
}).catch(() => {
|
||||
hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
// 一键分配班级和学号
|
||||
const handleOneClassAndStuNo = () => {
|
||||
if (dataForm.groupId == '') {
|
||||
message.warning('招生计划不能为空')
|
||||
return
|
||||
}
|
||||
messageBox.confirm('是否确认一键分配班级和学号?请谨慎操作').then(() => {
|
||||
showLoading()
|
||||
return Promise.all([oneClass(dataForm), oneStuNo(dataForm)])
|
||||
}).then(() => {
|
||||
hideLoading()
|
||||
message.success('分配完成')
|
||||
}).catch(() => {
|
||||
hideLoading()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 下载zip
|
||||
const downZip = () => {
|
||||
if (dataForm.groupId == '') {
|
||||
message.warning('招生计划不能为空')
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
showLoading()
|
||||
exportZip(dataForm).then(res => {
|
||||
hideLoading()
|
||||
@@ -907,45 +834,6 @@ const downZip = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 百度地图
|
||||
const baiduMap = (row: any) => {
|
||||
// 组件内部通过 v-model="visible" 控制显示
|
||||
nextTick(() => {
|
||||
baiduMapRef.value?.init(row)
|
||||
})
|
||||
}
|
||||
|
||||
// 设置宿舍
|
||||
const setDormFW = () => {
|
||||
// 组件内部通过 v-model="visible" 控制显示
|
||||
nextTick(() => {
|
||||
dormFWRef.value?.init()
|
||||
})
|
||||
}
|
||||
|
||||
// 一键判断是否超出住宿范围
|
||||
const handleYjOut = () => {
|
||||
if (dataForm.groupId == '') {
|
||||
message.warning('招生计划不能为空')
|
||||
return
|
||||
}
|
||||
messageBox.confirm('是否确认一键判断是否超出住宿范围?请谨慎操作').then(() => {
|
||||
return yjOut({ groupId: dataForm.groupId })
|
||||
}).then(() => {
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
})
|
||||
}
|
||||
|
||||
// 导出审核
|
||||
const handleExportAudit = (type: number) => {
|
||||
if (dataForm.groupId == '') {
|
||||
message.warning('招生计划不能为空')
|
||||
return
|
||||
}
|
||||
downFile(type)
|
||||
}
|
||||
|
||||
// 导出Excel
|
||||
const exportExcel = (form: any, url: string) => {
|
||||
return axios({
|
||||
@@ -959,23 +847,6 @@ const exportExcel = (form: any, url: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 导出文件
|
||||
const downFile = (type: number) => {
|
||||
dataForm.type = String(type)
|
||||
exportExcel(dataForm, '/recruit/recruitstudentsignup/exportExcel').then(res => {
|
||||
const blob = new Blob([res.data])
|
||||
const fileName = type == 1 ? '延迟缴费名单导出.xlsx' : '超时缴费名单导出.xlsx'
|
||||
const elink = document.createElement('a')
|
||||
elink.download = fileName
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href)
|
||||
document.body.removeChild(elink)
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
if (dataForm.groupId == '') {
|
||||
@@ -994,11 +865,6 @@ const handleExport = () => {
|
||||
document.body.removeChild(elink)
|
||||
}).catch(() => {})
|
||||
}
|
||||
// 去重
|
||||
const unique = (arr: any[]) => {
|
||||
const rese = new Map()
|
||||
return arr.filter((item) => !rese.has(item.username) && rese.set(item.username, 1))
|
||||
}
|
||||
|
||||
// 切换专业
|
||||
const chanMajor = () => {
|
||||
@@ -1016,8 +882,8 @@ const handleFilter = () => {
|
||||
}
|
||||
|
||||
// 获取数据列表
|
||||
const handleAddData=()=>{
|
||||
addOrUpdateRef.value?.init(null, 1)
|
||||
const handleAddData = ()=>{
|
||||
addOrUpdateRef.value?.init(null, 1, dataForm.groupId)
|
||||
}
|
||||
|
||||
// 新增 / 修改
|
||||
@@ -1039,7 +905,7 @@ const edit = (id: string) => {
|
||||
const majorChange = (id: string) => {
|
||||
nextTick(() => {
|
||||
majorChangeRef.value?.init(id)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 退学
|
||||
@@ -1049,17 +915,17 @@ const handleUpdate = (id: string, groupId: string, feeAgency: string) => {
|
||||
}).then(() => {
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 删除
|
||||
const deleteHandle = (id: string) => {
|
||||
messageBox.confirm('是否确认删除本条数据?请谨慎操作').then(() => {
|
||||
return delObj(id)
|
||||
// 复学
|
||||
const reEntry = (id: string) => {
|
||||
messageBox.confirm('是否确认复学操作?请谨慎操作').then(() => {
|
||||
return resetSignApi({ id })
|
||||
}).then(() => {
|
||||
message.success('删除成功')
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
@@ -1093,18 +959,11 @@ const handlePushCity = (id: string) => {
|
||||
|
||||
// 重新推送
|
||||
const handleRePush = (row: any) => {
|
||||
// messageBox.confirm('是否确认重新推送本条数据?请谨慎操作').then(() => {
|
||||
// return rePushApi({ id: row.id })
|
||||
// }).then(() => {
|
||||
// message.success('推送成功')
|
||||
// getDataList()
|
||||
// })
|
||||
}
|
||||
|
||||
// 延迟缴费
|
||||
const delayPayTimeSet = (row: any) => {
|
||||
nextTick(() => {
|
||||
delayPayTimeDialogRef.value?.init(row)
|
||||
messageBox.confirm('是否确认重新推送本条数据?请谨慎操作').then(() => {
|
||||
return rePushApi({ id: row.id })
|
||||
}).then(() => {
|
||||
message.success('推送成功')
|
||||
getDataList()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1149,6 +1008,13 @@ const getActionMenuItems = (row: any) => {
|
||||
icon: Close,
|
||||
visible: () => auth('recruit_recruitstudentsignup_leaveSchool') && row.canQuit
|
||||
},
|
||||
// 复学
|
||||
{
|
||||
command: 'reEntry',
|
||||
label: '复学',
|
||||
icon: Check,
|
||||
visible: () => auth('recruit_resetsign') && row.canReset
|
||||
},
|
||||
{
|
||||
command: 'majorChange',
|
||||
label: '调整专业',
|
||||
@@ -1203,6 +1069,9 @@ const handleMoreCommand = (command: string, row: any) => {
|
||||
case 'leaveSchool':
|
||||
handleUpdate(row.id, row.groupId, row.feeAgency)
|
||||
break
|
||||
case 'reEntry':
|
||||
reEntry(row.id)
|
||||
break
|
||||
case 'majorChange':
|
||||
majorChange(row.id)
|
||||
break
|
||||
@@ -1251,19 +1120,7 @@ const init = async () => {
|
||||
cityExamTypeList.value = res.data.recruit_city_exam_type || []
|
||||
isOutList.value = res.data.recruit_data_source || []
|
||||
})
|
||||
|
||||
// 所有经办人
|
||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT_SECOND).then((res: any) => {
|
||||
auditorList.value = res.data || []
|
||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT).then((re: any) => {
|
||||
if (re.data) {
|
||||
re.data.forEach((r: any) => {
|
||||
auditorList.value.push(r)
|
||||
})
|
||||
}
|
||||
auditorList.value = unique(auditorList.value)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 监听招生计划变化
|
||||
@@ -1293,14 +1150,6 @@ onMounted(() => {
|
||||
|
||||
.major-icon {
|
||||
color: var(--el-color-primary);
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.major-text {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,14 +1158,6 @@ onMounted(() => {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
// 面试结果样式
|
||||
.interview-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
// 面试详情弹窗样式
|
||||
.interview-detail-popover {
|
||||
.detail-title {
|
||||
@@ -1543,89 +1384,4 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 旧样式保留(如果其他地方还在使用)
|
||||
.material-check-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 4px 0;
|
||||
|
||||
.check-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
line-height: 1.5;
|
||||
|
||||
.check-label {
|
||||
color: #606266;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
gap: 4px;
|
||||
line-height: 1;
|
||||
|
||||
.tag-icon {
|
||||
font-size: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.material-status {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
|
||||
.material-tag {
|
||||
margin: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.no-upload-text {
|
||||
color: #67c23a;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.check-remark {
|
||||
margin-top: 4px;
|
||||
|
||||
.remark-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
|
||||
.remark-icon {
|
||||
color: #f56c6c;
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.remark-text {
|
||||
color: #f56c6c;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
display: inline-block;
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
header-align="center"
|
||||
align="center"
|
||||
width="100"
|
||||
label="是否同步">
|
||||
label="是否已同步">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getYesNoType(scope.row.isTb)?.type">
|
||||
{{ getYesNoType(scope.row.isTb)?.label }}
|
||||
@@ -376,7 +376,7 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="changeClassVisible=false">关 闭</el-button>
|
||||
<el-button @click="changeClassVisible=false">取消</el-button>
|
||||
<el-button @click="changeClassInfoHandle" type="primary">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -387,8 +387,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick, onMounted, defineAsyncComponent } from 'vue'
|
||||
import { Search, ZoomIn, Edit } from '@element-plus/icons-vue'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
@@ -400,14 +398,14 @@ import {
|
||||
oneClass,
|
||||
oneStuNo,
|
||||
changeClassInfo,
|
||||
getMajorClass
|
||||
getMajorClass,
|
||||
queryAllRecruitUser
|
||||
} from '/@/api/recruit/recruitstudentsignup'
|
||||
import { getLabelValueByProps } from '/@/utils/dictLabel'
|
||||
import { getClassListByRole, getDeptList } from "/@/api/basic/basicclass"
|
||||
import {listPlanByCondition as planMajor} from "/@/api/recruit/recruitstudentplan"
|
||||
import { getDictsByTypes } from "/@/api/admin/dict"
|
||||
import { getUserListByRole } from "/@/api/admin/user"
|
||||
import { ROLE_CODE, PUSHED_STATUS_LIST, PAY_STATUS_LIST, getStatusConfig } from "/@/config/global"
|
||||
import { PUSHED_STATUS_LIST, PAY_STATUS_LIST, getStatusConfig } from "/@/config/global"
|
||||
import { showLoading, hideLoading } from '/@/api/asset/loading'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
|
||||
@@ -642,22 +640,11 @@ const init = () => {
|
||||
})
|
||||
|
||||
// 所有经办人
|
||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT_SECOND).then((res: any) => {
|
||||
auditorList.value = res.data
|
||||
getUserListByRole(ROLE_CODE.ROLE_RECRUIT).then((re: any) => {
|
||||
re.data.forEach((r: any) => {
|
||||
auditorList.value.push(r)
|
||||
})
|
||||
auditorList.value = unique(auditorList.value)
|
||||
})
|
||||
queryAllRecruitUser().then((res: any) => {
|
||||
auditorList.value = res.data || []
|
||||
})
|
||||
}
|
||||
|
||||
const unique = (arr: any[]) => {
|
||||
const rese = new Map()
|
||||
return arr.filter((item) => !rese.has(item.username) && rese.set(item.username, 1))
|
||||
}
|
||||
|
||||
const chanMajor = () => {
|
||||
planMajorList.value = []
|
||||
planMajor({ groupId: dataForm.groupId }).then((data: any) => {
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" width="60%" :title="`面试审核(${row.name})`">
|
||||
<el-row>
|
||||
<el-radio v-model="status" label="1">通过</el-radio>
|
||||
<el-radio v-model="status" label="-1">未通过</el-radio>
|
||||
</el-row>
|
||||
<el-row v-if="status == '-1'">
|
||||
<br />
|
||||
<el-input type="textarea" v-model="reason" placeholder="请输入未通过的原因"></el-input>
|
||||
</el-row>
|
||||
<el-dialog v-model="visible" width="600" :title="`面试审核(${row.name})`">
|
||||
<el-form ref="dataFormRef" :model="dataForm" :rules="dataRule" label-width="120px">
|
||||
<el-form-item label="面试结果" prop="interview">
|
||||
<el-radio-group v-model="dataForm.interview" @change="handleInterviewChange">
|
||||
<el-radio :label="item.value" v-for="item in interviewDicList" :key="item.value">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="未通过原因" prop="interviewReason" v-if="dataForm.interview == '-1'">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="dataForm.interviewReason"
|
||||
placeholder="请输入未通过的原因"
|
||||
:rows="4">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="confirm"><span>确认</span></el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
// @ts-ignore
|
||||
import global from "@/components/tools/commondict.vue"
|
||||
import { interview } from "@/api/recruit/recruitstudentsignup"
|
||||
import { interview } from "/@/api/recruit/recruitstudentsignup"
|
||||
import { INTERVIEW_DIC_LIST } from '/@/config/global'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
|
||||
const interviewDicList = INTERVIEW_DIC_LIST.filter((item) => item.value != '0')
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
|
||||
@@ -36,31 +44,60 @@ const emit = defineEmits<{
|
||||
// 响应式数据
|
||||
const visible = ref(false)
|
||||
const row = reactive<any>({})
|
||||
const status = ref('1')
|
||||
const reason = ref('')
|
||||
const dataFormRef = ref<FormInstance>()
|
||||
const dataForm = reactive({
|
||||
interview: '1',
|
||||
interviewReason: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const dataRule = reactive({
|
||||
interview: [
|
||||
{ required: true, message: '请选择面试结果', trigger: 'change' }
|
||||
],
|
||||
interviewReason: [] as any[]
|
||||
})
|
||||
|
||||
// 初始化
|
||||
const init = (rowData: any) => {
|
||||
visible.value = true
|
||||
Object.assign(row, rowData)
|
||||
status.value = rowData.interview || '1'
|
||||
reason.value = rowData.interviewReason || ''
|
||||
dataForm.interview = rowData.interview || '1'
|
||||
dataForm.interviewReason = rowData.interviewReason || ''
|
||||
// 重置表单验证状态
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
// 面试结果改变
|
||||
const handleInterviewChange = () => {
|
||||
dataForm.interviewReason = ''
|
||||
if(dataForm.interview == '-1'){
|
||||
dataRule.interviewReason = [
|
||||
{ required: true, message: '请输入未通过的原因', trigger: 'blur' }
|
||||
]
|
||||
} else {
|
||||
dataRule.interviewReason = []
|
||||
}
|
||||
}
|
||||
|
||||
// 确认
|
||||
const confirm = () => {
|
||||
if (!status.value || (status.value == '-1' && !reason.value)) {
|
||||
message.warning('请选择通过还是未通过,未通过请输入原因')
|
||||
return
|
||||
} else {
|
||||
interview({ "id": row.id, "interview": status.value, "interviewReason": reason.value }).then(() => {
|
||||
dataFormRef.value?.validate((valid: boolean) => {
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
interview({
|
||||
"id": row.id,
|
||||
"interview": dataForm.interview,
|
||||
"interviewReason": dataForm.interviewReason
|
||||
}).then(() => {
|
||||
message.success('操作成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
}).catch(() => {
|
||||
message.error('操作失败')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法给父组件
|
||||
@@ -70,7 +107,5 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input type="text" v-model="dataForm.name" :disabled="type != 1"></el-input>
|
||||
<el-input type="text" v-model="dataForm.name" disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="身份证号" prop="idNumber">
|
||||
<el-input type="text" v-model="dataForm.idNumber" :disabled="type != 2"></el-input>
|
||||
<el-input type="text" v-model="dataForm.idNumber" disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -46,7 +46,7 @@
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="原录取专业" prop="confirmedMajor">
|
||||
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" :disabled="type != 1" @change="changeM(dataForm.confirmedMajor)">
|
||||
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" disabled>
|
||||
<el-option
|
||||
v-for="item in planMajorList"
|
||||
:key="item.majorCode"
|
||||
@@ -75,26 +75,26 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学费" prop="feeTuition">
|
||||
<el-input-number v-model="dataForm.feeTuition" controls-position="right" :min="0" :max="999999" :step-strictly="true" :disabled="type == 2"></el-input-number>
|
||||
<el-input-number v-model="dataForm.feeTuition" controls-position="right" :min="0" :max="999999" :step-strictly="true" disabled></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="代办费" prop="feeAgency">
|
||||
<el-input-number v-model="dataForm.feeAgency" controls-position="right" :min="0" :max="999999" :step-strictly="true" :disabled="type == 2"></el-input-number>
|
||||
<el-input-number v-model="dataForm.feeAgency" controls-position="right" :min="0" :max="999999" :step-strictly="true" disabled></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="总费用" prop="allMoney">
|
||||
<span style="color: red">{{ dataForm.feeTuition + dataForm.feeAgency }}</span>
|
||||
<span style="color: red">{{ Number(dataForm.feeTuition) + Number(dataForm.feeAgency) }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="审核备注" prop="auditRemarks">
|
||||
<el-input type="textarea" v-model="dataForm.auditRemarks" placeholder="审核备注" :rows="2"></el-input>
|
||||
<el-form-item label="备注" prop="auditRemarks">
|
||||
<el-input type="textarea" v-model="dataForm.auditRemarks" placeholder="备注" :rows="2"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -110,17 +110,18 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useMessageBox, useMessage } from '/@/hooks/message'
|
||||
import { getObj, changeMajor } from '/@/api/recruit/recruitstudentsignup'
|
||||
import { getList } from "/@/api/recruit/recruitstudentplangroup"
|
||||
import { listByEdu } from "/@/api/recruit/recruitstudentplan"
|
||||
import { getDicts } from "/@/api/admin/dict"
|
||||
import { list as scoreList } from "/@/api/recruit/recruitstudentplancorrectscoreconfig"
|
||||
import { getStatusConfig, AUDIT_STATUS_LIST } from '/@/config/global'
|
||||
|
||||
const auditStatusList = AUDIT_STATUS_LIST
|
||||
// 消息提示 hooks
|
||||
const messageBox = useMessageBox()
|
||||
|
||||
const message = useMessage()
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshDataList'): void
|
||||
@@ -133,11 +134,9 @@ const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const canSubmit = ref(false)
|
||||
const title = ref("")
|
||||
const type = ref<number | null>(null)
|
||||
const planList = ref<any[]>([])
|
||||
const planMajorList = ref<any[]>([])
|
||||
const agencyFeeList = ref<any[]>([])
|
||||
const tuitionFeeList = ref<any[]>([])
|
||||
const schoolCodeList = ref<any[]>([])
|
||||
|
||||
const dataForm = reactive({
|
||||
@@ -210,7 +209,7 @@ const dataForm = reactive({
|
||||
feeAgency: 0
|
||||
})
|
||||
|
||||
const dataRule = {
|
||||
const dataRule = reactive({
|
||||
groupId: [
|
||||
{ required: true, message: '招生计划不能为空', trigger: 'change' }
|
||||
],
|
||||
@@ -229,7 +228,7 @@ const dataRule = {
|
||||
newConfirmedMajor: [
|
||||
{ required: true, message: '新录取专业不能为空', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
@@ -238,56 +237,45 @@ const initData = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 改变新专业
|
||||
const changeCM = (id: string) => {
|
||||
if (id) {
|
||||
let flag = false
|
||||
planMajorList.value.forEach((e: any) => {
|
||||
if (dataForm.newConfirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
|
||||
flag = true
|
||||
}
|
||||
})
|
||||
if (String(dataForm.degreeOfEducation) == "1") {
|
||||
dataForm.feeTuition = 0
|
||||
tuitionFeeList.value.forEach((e: any) => {
|
||||
if (e.label == "0" && flag) {
|
||||
dataForm.feeTuition = e.value
|
||||
}
|
||||
})
|
||||
}
|
||||
// 根据新专业和文化程度更新学费
|
||||
const updateTuitionByNewMajorAndEducation = () => {
|
||||
if (!dataForm.newConfirmedMajor || !dataForm.degreeOfEducation) {
|
||||
return
|
||||
}
|
||||
|
||||
// 查找选中的新专业
|
||||
const selectedMajor = planMajorList.value.find((major: any) => major.majorCode === dataForm.newConfirmedMajor)
|
||||
if (!selectedMajor) {
|
||||
return
|
||||
}
|
||||
|
||||
// 根据文化程度选择对应的学费字段
|
||||
// '1' = 初中 -> czFee
|
||||
// '2' = 高中 -> gzFee
|
||||
// '3' = 技职校 -> jzxFee
|
||||
if (dataForm.degreeOfEducation === '1' && selectedMajor.czFee !== undefined && selectedMajor.czFee !== null) {
|
||||
dataForm.feeTuition = selectedMajor.czFee
|
||||
} else if (dataForm.degreeOfEducation === '2' && selectedMajor.gzFee !== undefined && selectedMajor.gzFee !== null) {
|
||||
dataForm.feeTuition = selectedMajor.gzFee
|
||||
} else if (dataForm.degreeOfEducation === '3' && selectedMajor.jzxFee !== undefined && selectedMajor.jzxFee !== null) {
|
||||
dataForm.feeTuition = selectedMajor.jzxFee
|
||||
}
|
||||
}
|
||||
|
||||
// 改变原专业
|
||||
const changeM = (id: string) => {
|
||||
// 改变新专业
|
||||
const changeCM = (id: string) => {
|
||||
if (id) {
|
||||
dataForm.confirmedMajor = id
|
||||
// 是初中生并且是中德班
|
||||
let flag = false
|
||||
planMajorList.value.forEach((e: any) => {
|
||||
if (dataForm.confirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
|
||||
flag = true
|
||||
}
|
||||
})
|
||||
if (String(dataForm.degreeOfEducation) == "1") {
|
||||
dataForm.feeTuition = 0
|
||||
tuitionFeeList.value.forEach((e: any) => {
|
||||
if (e.label == "0" && flag) {
|
||||
dataForm.feeTuition = e.value
|
||||
}
|
||||
})
|
||||
}
|
||||
// 从新专业中获取学费
|
||||
updateTuitionByNewMajorAndEducation()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 表单提交
|
||||
const dataFormSubmit = async () => {
|
||||
const titleText = "确认调整录取专业么?"
|
||||
if (dataForm.confirmedMajor == dataForm.newConfirmedMajor) {
|
||||
ElNotification.error({
|
||||
title: '错误',
|
||||
message: '新专业不能和原专业相同'
|
||||
})
|
||||
message.error('新专业不能和原专业相同')
|
||||
return
|
||||
}
|
||||
try {
|
||||
@@ -297,10 +285,7 @@ const dataFormSubmit = async () => {
|
||||
canSubmit.value = false
|
||||
if (dataForm.id) {
|
||||
changeMajor(dataForm).then(() => {
|
||||
ElNotification.success({
|
||||
title: '成功',
|
||||
message: '操作成功'
|
||||
})
|
||||
message.success('操作成功')
|
||||
visible.value = false
|
||||
emit('refreshDataList')
|
||||
}).catch(() => {
|
||||
@@ -316,7 +301,7 @@ const dataFormSubmit = async () => {
|
||||
|
||||
// 初始化方法
|
||||
const init = (id: string | null) => {
|
||||
dataForm.id = id || null
|
||||
dataForm.id = id || ""
|
||||
visible.value = true
|
||||
canSubmit.value = true
|
||||
initData()
|
||||
@@ -326,48 +311,43 @@ const init = (id: string | null) => {
|
||||
// 获取数据字典代办费
|
||||
getDicts('agency_fee').then((res: any) => {
|
||||
agencyFeeList.value = res.data
|
||||
// 获取数据字典学费
|
||||
getDicts('tuition_fee').then((res: any) => {
|
||||
tuitionFeeList.value = res.data
|
||||
getObj(dataForm.id).then((response: any) => {
|
||||
Object.assign(dataForm, response.data)
|
||||
title.value = dataForm.serialNumber
|
||||
// 获取文化程度对应的专业
|
||||
planMajorList.value = []
|
||||
getObj(dataForm.id).then((response: any) => {
|
||||
Object.assign(dataForm, response.data)
|
||||
title.value = dataForm.serialNumber
|
||||
// 获取文化程度对应的专业
|
||||
planMajorList.value = []
|
||||
|
||||
agencyFeeList.value.forEach((e: any) => {
|
||||
if (String(dataForm.degreeOfEducation) == String(e.label)) {
|
||||
dataForm.feeAgency = e.value
|
||||
}
|
||||
})
|
||||
tuitionFeeList.value.forEach((e: any) => {
|
||||
if (String(dataForm.degreeOfEducation) == String(e.label) && (String(dataForm.degreeOfEducation) != "1")) {
|
||||
dataForm.feeTuition = e.value
|
||||
}
|
||||
})
|
||||
listByEdu({ groupId: dataForm.groupId, degreeOfEducation: dataForm.degreeOfEducation }).then((e: any) => {
|
||||
planMajorList.value = e.data
|
||||
})
|
||||
agencyFeeList.value.forEach((e: any) => {
|
||||
if (String(dataForm.degreeOfEducation) == String(e.label)) {
|
||||
dataForm.feeAgency = e.value
|
||||
}
|
||||
})
|
||||
listByEdu({ groupId: dataForm.groupId, degreeOfEducation: dataForm.degreeOfEducation }).then((e: any) => {
|
||||
planMajorList.value = e.data
|
||||
// 加载专业列表后,如果已有新专业,更新学费
|
||||
if (dataForm.newConfirmedMajor) {
|
||||
updateTuitionByNewMajorAndEducation()
|
||||
}
|
||||
// 获取招生计划下的学校和分数线
|
||||
scoreList({ groupId: dataForm.groupId }).then((data: any) => {
|
||||
schoolCodeList.value = data.data
|
||||
})
|
||||
|
||||
if ("1" == dataForm.degreeOfEducation) {
|
||||
title.value = "C" + title.value
|
||||
} else if ("2" == dataForm.degreeOfEducation) {
|
||||
title.value = "G" + title.value
|
||||
} else if ("3" == dataForm.degreeOfEducation) {
|
||||
title.value = "J" + title.value
|
||||
const educationPrefixMap: Record<string, string> = {
|
||||
'1': 'C', // 初中
|
||||
'2': 'G', // 高中
|
||||
'3': 'J' // 技职校
|
||||
}
|
||||
const prefix = educationPrefixMap[String(dataForm.degreeOfEducation)]
|
||||
if (prefix) {
|
||||
title.value = prefix + title.value
|
||||
}
|
||||
// 从字典数据获取录取状态标签
|
||||
const auditStatusConfig = getStatusConfig(auditStatusList, dataForm.auditStatus)
|
||||
if (auditStatusConfig && auditStatusConfig.label) {
|
||||
title.value = auditStatusConfig.label + " " + title.value
|
||||
}
|
||||
|
||||
if ("-20" == dataForm.auditStatus) {
|
||||
title.value = "未录取 " + title.value
|
||||
} else if ("0" == dataForm.auditStatus) {
|
||||
title.value = "待审核 " + title.value
|
||||
} else if ("20" == dataForm.auditStatus) {
|
||||
title.value = "已录取 " + title.value
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
:close-on-click-modal="false"
|
||||
v-model="visible"
|
||||
append-to-body
|
||||
width="900px">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataFormRef" @keyup.enter="dataFormSubmit"
|
||||
width="70%">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataFormRef" @keyup.enter="() => dataFormSubmit('1')"
|
||||
label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="招生计划" prop="groupId">
|
||||
<el-select v-model="dataForm.groupId" filterable :disabled="!!dataForm.id"
|
||||
placeholder="请选择招生计划">
|
||||
@@ -21,14 +21,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input type="text" v-model="dataForm.name" :disabled="type != 1"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="联系人" prop="contactName">
|
||||
<el-select v-model="dataForm.contactName" filterable clearable placeholder="" :disabled="!(permissions.recruit_recruitprestudent_dj_sure || dataForm.auditStatus != '20')">
|
||||
<el-option
|
||||
@@ -41,90 +39,92 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="成绩单" prop="scorePhoto">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
list-type="picture-card"
|
||||
:action="uploadUrl"
|
||||
class="avatar-uploader"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:data="uploadData"
|
||||
:file-list="fileList"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="removeHandler"
|
||||
:http-request="httpRequest"
|
||||
:on-success="uploadSuccess">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
<div v-if="dataForm.scorePhoto" class="avatar-wrapper">
|
||||
<img :src="baseUrl + dataForm.scorePhoto" class="avatar"/>
|
||||
</div>
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="毕业证" prop="graPic">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
list-type="picture-card"
|
||||
:action="uploadUrl"
|
||||
class="avatar-uploader"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:data="uploadData"
|
||||
:file-list="graPicList"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="remove2Handler"
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload2Success">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
<div v-if="dataForm.graPic" class="avatar-wrapper">
|
||||
<img :src="baseUrl + dataForm.graPic" class="avatar"/>
|
||||
</div>
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="在常营业执照" prop="yyPic">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
list-type="picture-card"
|
||||
:action="uploadUrl"
|
||||
class="avatar-uploader"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:data="uploadData"
|
||||
:file-list="yyPicList"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="remove3Handler"
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload3Success">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
<div v-if="dataForm.yyPic" class="avatar-wrapper">
|
||||
<img :src="baseUrl + dataForm.yyPic" class="avatar"/>
|
||||
</div>
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="在常社保证明" prop="sbPic">
|
||||
<el-upload
|
||||
:action="uploadUrl"
|
||||
class="avatar-uploader"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:data="uploadData"
|
||||
:show-file-list="false"
|
||||
:before-upload="beforeUpload"
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload5Success">
|
||||
<div v-if="dataForm.sbPic" class="avatar-wrapper">
|
||||
<img :src="baseUrl + dataForm.sbPic" class="avatar"/>
|
||||
</div>
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="在常就业社保证明" prop="sbPic">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
list-type="picture-card"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:data="uploadData"
|
||||
:file-list="sbPicList"
|
||||
:before-upload="beforeUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="remove5Handler"
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload5Success">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
<el-col >
|
||||
<el-form-item label="在常租赁合同/房产证明" prop="housePic">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
:action="uploadUrl"
|
||||
list-type="picture-card"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
@@ -137,14 +137,17 @@
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload4Success">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
<template #tip>
|
||||
<div>最多上传5张</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-col>
|
||||
<el-form-item label="户口本" prop="householdPic">
|
||||
<el-upload
|
||||
action="/recruit/file/uploadAttachment"
|
||||
:action="uploadUrl"
|
||||
list-type="picture-card"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
@@ -157,6 +160,9 @@
|
||||
:http-request="httpRequest"
|
||||
:on-success="upload6Success">
|
||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
<template #tip>
|
||||
<div>最多上传5张</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -173,8 +179,8 @@
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit('1')" v-auth="'recruit_recruitstudentsignup_edit'" v-if="canSubmit">保存</el-button>
|
||||
<el-button type="success" plain @click="dataFormSubmit('2')" v-auth="'signup_material_exam'" v-if="canSubmit">通过</el-button>
|
||||
<el-button type="danger" plain @click="dataFormSubmit('3')" v-auth="'signup_material_exam'" v-if="canSubmit">驳回</el-button>
|
||||
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('2')" v-auth="'signup_material_exam'" v-if="canSubmit">通过</el-button>
|
||||
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('3')" v-auth="'signup_material_exam'" v-if="canSubmit">驳回</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -187,18 +193,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick, computed, onMounted } from 'vue'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useUserInfo } from '/@/stores/userInfo'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import axios from 'axios'
|
||||
import { getObj, materialExam } from '/@/api/recruit/recruitstudentsignup'
|
||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||
import { queryAllTeacher } from '/@/api/professional/professionaluser/teacherbase'
|
||||
import { AUDIT_STATUS_LIST, getStatusConfig } from '/@/config/global'
|
||||
|
||||
const auditStatusList = AUDIT_STATUS_LIST
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
|
||||
// 使用 Pinia store
|
||||
const userInfoStore = useUserInfo()
|
||||
const { userInfos } = storeToRefs(userInfoStore)
|
||||
const baseUrl = import.meta.env.VITE_API_URL
|
||||
const uploadUrl = baseUrl + '/recruit/file/uploadAttachment'
|
||||
|
||||
// 创建权限对象
|
||||
const permissions = computed(() => {
|
||||
@@ -234,20 +247,7 @@ const type = ref<number | null>(null)
|
||||
const contactNameList = ref<any[]>([])
|
||||
const planList = ref<any[]>([])
|
||||
|
||||
const form = reactive({
|
||||
attachment: '',
|
||||
graPic: "",
|
||||
yyPic: "",
|
||||
housePic: "",
|
||||
sbPic: "",
|
||||
hkPic: ""
|
||||
})
|
||||
|
||||
const fileList = ref<any[]>([])
|
||||
const graPicList = ref<any[]>([])
|
||||
const yyPicList = ref<any[]>([])
|
||||
const houseList = ref<any[]>([])
|
||||
const sbPicList = ref<any[]>([])
|
||||
const hkPicList = ref<any[]>([])
|
||||
|
||||
const fileReader = ref<FileReader | null>(null)
|
||||
@@ -259,69 +259,18 @@ const dataForm = reactive({
|
||||
zlshRemark: "",
|
||||
groupId: "",
|
||||
name: "",
|
||||
oldName: "",
|
||||
gender: "",
|
||||
nationality: "",
|
||||
degreeOfEducation: "",
|
||||
isLeagueMember: "",
|
||||
schoolOfGraduation: "",
|
||||
isAccommodation: "",
|
||||
examRegistrationNumbers: "",
|
||||
isMinimumLivingSecurity: "",
|
||||
score: "",
|
||||
postcode: "",
|
||||
residenceType: "",
|
||||
correctedScore: "",
|
||||
placeScore: "",
|
||||
schoolFrom: "",
|
||||
idNumber: "",
|
||||
residenceProvince: "",
|
||||
residenceCity: "",
|
||||
residenceArea: "",
|
||||
residenceDetail: "",
|
||||
homeAddressProvince: "",
|
||||
homeAddressCity: "",
|
||||
homeAddressArea: "",
|
||||
homeAddressDetail: "",
|
||||
parentName: "",
|
||||
parentTelOne: "",
|
||||
parentTelTwo: "",
|
||||
selfTel: "",
|
||||
wishMajorOne: "",
|
||||
wishMajorTwo: "",
|
||||
wishMajorThree: "",
|
||||
confirmedMajor: "",
|
||||
sevenMajor: "",
|
||||
sixMajor: "",
|
||||
fiveMajor: "",
|
||||
fourMajor: "",
|
||||
threeMajor: "",
|
||||
twoMajor: "",
|
||||
feeContribute: 0,
|
||||
contactName: "",
|
||||
scorePhoto: "",
|
||||
graPic: "",
|
||||
yyPic: "",
|
||||
housePic: "",
|
||||
sbPic: "",
|
||||
contactName: "",
|
||||
oldSerialNumber: "",
|
||||
colorDiscrimination: "",
|
||||
nutrition: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
pastMedicalHistory: "",
|
||||
eyesightLeft: "",
|
||||
eyesightRight: "",
|
||||
correctEyesightLeft: "",
|
||||
correctEyesightRight: "",
|
||||
remarks: "",
|
||||
auditRemarks: "",
|
||||
serialNumber: "",
|
||||
auditStatus: "",
|
||||
schoolCode: "",
|
||||
newConfirmedMajor: "",
|
||||
householdPic: "",
|
||||
zlsh: ""
|
||||
zlsh: "",
|
||||
// 以下字段从后端获取,用于显示和判断
|
||||
serialNumber: "",
|
||||
degreeOfEducation: "",
|
||||
auditStatus: ""
|
||||
})
|
||||
|
||||
const dataRule = {
|
||||
@@ -348,7 +297,7 @@ const dataRule = {
|
||||
// 初始化 FileReader
|
||||
onMounted(() => {
|
||||
if (!window.FileReader) {
|
||||
console.error('Your browser does not support FileReader API!')
|
||||
message.error('您的浏览器不支持 FileReader API!')
|
||||
} else {
|
||||
fileReader.value = new FileReader()
|
||||
}
|
||||
@@ -358,10 +307,7 @@ onMounted(() => {
|
||||
const beforeUpload = (file: File) => {
|
||||
const isLt5M = file.size < 10 * 1024 * 1024
|
||||
if (!isLt5M) {
|
||||
ElNotification.error({
|
||||
title: '错误',
|
||||
message: '文件大小不能超过10M'
|
||||
})
|
||||
message.error('文件大小不能超过10M')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -373,68 +319,28 @@ const handlePictureCardPreview = (file: any) => {
|
||||
dialogUploadVisible.value = true
|
||||
}
|
||||
|
||||
// 移除文件处理
|
||||
const removeHandler = (file: any) => {
|
||||
const index = fileList.value.findIndex((item: any) => item.url === file.url)
|
||||
if (index > -1) {
|
||||
fileList.value.splice(index, 1)
|
||||
|
||||
// 通用移除文件处理(多文件)
|
||||
const handleRemoveMultiple = (fileList: any[], dataFormField: string) => {
|
||||
return (file: any) => {
|
||||
const arr: any[] = []
|
||||
const strArr: string[] = []
|
||||
const dataFormObj = dataForm as any
|
||||
fileList.forEach((e: any) => {
|
||||
if (e.url != file.url) {
|
||||
arr.push(e)
|
||||
// 保存时使用原始路径
|
||||
strArr.push(e.originalUrl || (e.url.startsWith(baseUrl) ? e.url.substring(baseUrl.length) : e.url))
|
||||
}
|
||||
})
|
||||
fileList.splice(0, fileList.length, ...arr)
|
||||
dataFormObj[dataFormField] = strArr.join(",")
|
||||
}
|
||||
form.attachment = ""
|
||||
dataForm.scorePhoto = ""
|
||||
}
|
||||
|
||||
const remove2Handler = (file: any) => {
|
||||
const index = graPicList.value.findIndex((item: any) => item.url === file.url)
|
||||
if (index > -1) {
|
||||
graPicList.value.splice(index, 1)
|
||||
}
|
||||
form.graPic = ""
|
||||
dataForm.graPic = ""
|
||||
}
|
||||
|
||||
const remove3Handler = (file: any) => {
|
||||
const index = yyPicList.value.findIndex((item: any) => item.url === file.url)
|
||||
if (index > -1) {
|
||||
yyPicList.value.splice(index, 1)
|
||||
}
|
||||
form.yyPic = ""
|
||||
dataForm.yyPic = ""
|
||||
}
|
||||
|
||||
const remove4Handler = (file: any) => {
|
||||
const arr: any[] = []
|
||||
const strArr: string[] = []
|
||||
houseList.value.forEach((e: any) => {
|
||||
if (e.url != file.url) {
|
||||
arr.push(e)
|
||||
strArr.push(e.url)
|
||||
}
|
||||
})
|
||||
houseList.value = arr
|
||||
dataForm.housePic = strArr.join(",")
|
||||
}
|
||||
|
||||
const remove5Handler = (file: any) => {
|
||||
const index = sbPicList.value.findIndex((item: any) => item.url === file.url)
|
||||
if (index > -1) {
|
||||
sbPicList.value.splice(index, 1)
|
||||
}
|
||||
form.sbPic = ""
|
||||
dataForm.sbPic = ""
|
||||
}
|
||||
|
||||
const remove6Handler = (file: any) => {
|
||||
const arr: any[] = []
|
||||
const strArr: string[] = []
|
||||
hkPicList.value.forEach((e: any) => {
|
||||
if (e.url != file.url) {
|
||||
arr.push(e)
|
||||
strArr.push(e.url)
|
||||
}
|
||||
})
|
||||
hkPicList.value = arr
|
||||
dataForm.householdPic = strArr.join(",")
|
||||
}
|
||||
// 移除文件处理(多图上传)
|
||||
const remove4Handler = handleRemoveMultiple(houseList.value, 'housePic')
|
||||
const remove6Handler = handleRemoveMultiple(hkPicList.value, 'householdPic')
|
||||
|
||||
// 自定义上传请求
|
||||
const httpRequest = (options: any) => {
|
||||
@@ -444,8 +350,9 @@ const httpRequest = (options: any) => {
|
||||
fileReader.value.onload = () => {
|
||||
const base64Str = fileReader.value?.result as string
|
||||
const config = {
|
||||
url: '/recruit/file/uploadAttachment',
|
||||
url: uploadUrl,
|
||||
method: 'post',
|
||||
headers: headers.value,
|
||||
data: {
|
||||
base64Str: base64Str.split(',')[1]
|
||||
},
|
||||
@@ -466,66 +373,39 @@ const httpRequest = (options: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 通用上传成功回调(单文件 - avatar模式)
|
||||
const handleUploadSuccess = (dataFormField: string) => {
|
||||
return (res: any) => {
|
||||
const fileUrl = res.data.fileUrl
|
||||
const dataFormObj = dataForm as any
|
||||
dataFormObj[dataFormField] = fileUrl
|
||||
}
|
||||
}
|
||||
|
||||
// 通用上传成功回调(多文件)
|
||||
const handleUploadSuccessMultiple = (fileList: any[], dataFormField: string) => {
|
||||
return (res: any) => {
|
||||
const fileUrl = res.data.fileUrl // 后端返回的原始路径
|
||||
const dataFormObj = dataForm as any
|
||||
// 添加到文件列表,显示时添加 baseUrl 前缀,同时保存原始路径用于提交
|
||||
fileList.push({ url: baseUrl + fileUrl, name: '', originalUrl: fileUrl })
|
||||
// 保存时使用原始路径
|
||||
const arr: string[] = []
|
||||
fileList.forEach((e: any) => {
|
||||
// 优先使用保存的原始路径,如果没有则从 url 中提取
|
||||
arr.push(e.originalUrl || (e.url.startsWith(baseUrl) ? e.url.substring(baseUrl.length) : e.url))
|
||||
})
|
||||
dataFormObj[dataFormField] = arr.join(",")
|
||||
}
|
||||
}
|
||||
|
||||
// 上传成功回调
|
||||
const uploadSuccess = (res: any, file: any) => {
|
||||
form.attachment = res.data.fileUrl
|
||||
if (fileList.value.length > 0) {
|
||||
fileList.value[0] = { url: form.attachment, name: "" }
|
||||
} else {
|
||||
fileList.value.push({ url: form.attachment, name: "" })
|
||||
}
|
||||
dataForm.scorePhoto = form.attachment
|
||||
}
|
||||
|
||||
const upload2Success = (res: any, file: any) => {
|
||||
form.graPic = res.data.fileUrl
|
||||
if (graPicList.value.length > 0) {
|
||||
graPicList.value[0] = { url: form.graPic, name: "" }
|
||||
} else {
|
||||
graPicList.value.push({ url: form.graPic, name: "" })
|
||||
}
|
||||
dataForm.graPic = form.graPic
|
||||
}
|
||||
|
||||
const upload3Success = (res: any, file: any) => {
|
||||
form.yyPic = res.data.fileUrl
|
||||
if (yyPicList.value.length > 0) {
|
||||
yyPicList.value[0] = { url: form.yyPic, name: "" }
|
||||
} else {
|
||||
yyPicList.value.push({ url: form.yyPic, name: "" })
|
||||
}
|
||||
dataForm.yyPic = form.yyPic
|
||||
}
|
||||
|
||||
const upload4Success = (res: any, file: any) => {
|
||||
form.housePic = res.data.fileUrl
|
||||
houseList.value.push({ url: form.housePic })
|
||||
const arr: string[] = []
|
||||
houseList.value.forEach((e: any) => {
|
||||
arr.push(e.url)
|
||||
})
|
||||
dataForm.housePic = arr.join(",")
|
||||
}
|
||||
|
||||
const upload5Success = (res: any, file: any) => {
|
||||
form.sbPic = res.data.fileUrl
|
||||
if (sbPicList.value.length > 0) {
|
||||
sbPicList.value[0] = { url: form.sbPic, name: "" }
|
||||
} else {
|
||||
sbPicList.value.push({ url: form.sbPic, name: "" })
|
||||
}
|
||||
dataForm.sbPic = form.sbPic
|
||||
}
|
||||
|
||||
const upload6Success = (res: any, file: any) => {
|
||||
form.hkPic = res.data.fileUrl
|
||||
hkPicList.value.push({ url: form.hkPic })
|
||||
const arr: string[] = []
|
||||
hkPicList.value.forEach((e: any) => {
|
||||
arr.push(e.url)
|
||||
})
|
||||
dataForm.householdPic = arr.join(",")
|
||||
}
|
||||
const uploadSuccess = handleUploadSuccess('scorePhoto')
|
||||
const upload2Success = handleUploadSuccess('graPic')
|
||||
const upload3Success = handleUploadSuccess('yyPic')
|
||||
const upload4Success = handleUploadSuccessMultiple(houseList.value, 'housePic')
|
||||
const upload5Success = handleUploadSuccess('sbPic')
|
||||
const upload6Success = handleUploadSuccessMultiple(hkPicList.value, 'householdPic')
|
||||
|
||||
// 初始化数据
|
||||
const initData = () => {
|
||||
@@ -540,20 +420,14 @@ const initData = () => {
|
||||
|
||||
// 表单提交
|
||||
const dataFormSubmit = (submitType: string) => {
|
||||
if (dataForm.zlshRemark == '' && submitType == '3') {
|
||||
ElNotification.error({
|
||||
title: '错误',
|
||||
message: '请填写驳回理由'
|
||||
})
|
||||
if ((dataForm.zlshRemark == '' || !dataForm.zlshRemark) && submitType == '3') {
|
||||
message.error('请填写驳回理由')
|
||||
return
|
||||
}
|
||||
dataForm.zlsh = submitType
|
||||
canSubmit.value = false
|
||||
materialExam(dataForm).then(() => {
|
||||
ElNotification.success({
|
||||
title: '成功',
|
||||
message: '操作成功'
|
||||
})
|
||||
message.success('操作成功')
|
||||
visible.value = false
|
||||
emit('refreshDataList')
|
||||
}).catch(() => {
|
||||
@@ -563,7 +437,7 @@ const dataFormSubmit = (submitType: string) => {
|
||||
|
||||
// 初始化方法
|
||||
const init = (id: string | null) => {
|
||||
dataForm.id = id || null
|
||||
dataForm.id = id || ""
|
||||
visible.value = true
|
||||
canSubmit.value = true
|
||||
initData()
|
||||
@@ -571,54 +445,44 @@ const init = (id: string | null) => {
|
||||
dataFormRef.value?.resetFields()
|
||||
if (dataForm.id) {
|
||||
getObj(dataForm.id).then((response: any) => {
|
||||
fileList.value = []
|
||||
graPicList.value = []
|
||||
yyPicList.value = []
|
||||
// 清空多图上传的列表
|
||||
houseList.value = []
|
||||
sbPicList.value = []
|
||||
hkPicList.value = []
|
||||
Object.assign(dataForm, response.data)
|
||||
title.value = dataForm.serialNumber
|
||||
if (dataForm.scorePhoto != '') {
|
||||
fileList.value.push({ url: dataForm.scorePhoto, name: "" })
|
||||
}
|
||||
if (dataForm.graPic != '') {
|
||||
graPicList.value.push({ url: dataForm.graPic, name: "" })
|
||||
}
|
||||
if (dataForm.yyPic != '') {
|
||||
yyPicList.value.push({ url: dataForm.yyPic, name: "" })
|
||||
}
|
||||
if (dataForm.housePic != '') {
|
||||
const arr = dataForm.housePic.split(",")
|
||||
// avatar 模式直接使用 dataForm 中的字段,不需要 fileList
|
||||
// 多图上传需要初始化列表
|
||||
if (dataForm.housePic && dataForm.housePic != '') {
|
||||
const arr = dataForm.housePic.split(",").filter((item: string) => item && item.trim())
|
||||
arr.forEach((e: string) => {
|
||||
houseList.value.push({ url: e })
|
||||
// 保存原始路径,显示时添加 baseUrl 前缀
|
||||
houseList.value.push({ url: baseUrl + e, name: '', originalUrl: e })
|
||||
})
|
||||
}
|
||||
if (dataForm.sbPic != '') {
|
||||
sbPicList.value.push({ url: dataForm.sbPic, name: "" })
|
||||
}
|
||||
if (dataForm.householdPic != '') {
|
||||
const arr2 = dataForm.householdPic.split(",")
|
||||
if (dataForm.householdPic && dataForm.householdPic != '') {
|
||||
const arr2 = dataForm.householdPic.split(",").filter((item: string) => item && item.trim())
|
||||
arr2.forEach((e: string) => {
|
||||
hkPicList.value.push({ url: e })
|
||||
// 保存原始路径,显示时添加 baseUrl 前缀
|
||||
hkPicList.value.push({ url: baseUrl + e, name: '', originalUrl: e })
|
||||
})
|
||||
}
|
||||
|
||||
if ("1" == String(dataForm.degreeOfEducation)) {
|
||||
title.value = "C" + title.value
|
||||
} else if ("2" == String(dataForm.degreeOfEducation)) {
|
||||
title.value = "G" + title.value
|
||||
} else if ("3" == String(dataForm.degreeOfEducation)) {
|
||||
title.value = "J" + title.value
|
||||
const educationPrefixMap: Record<string, string> = {
|
||||
'1': 'C', // 初中
|
||||
'2': 'G', // 高中
|
||||
'3': 'J' // 技职校
|
||||
}
|
||||
const prefix = educationPrefixMap[String(dataForm.degreeOfEducation)]
|
||||
if (prefix) {
|
||||
title.value = prefix + title.value
|
||||
}
|
||||
contactNameflag.value = false
|
||||
if ("-20" == String(dataForm.auditStatus)) {
|
||||
title.value = "未录取 " + title.value
|
||||
} else if ("0" == String(dataForm.auditStatus)) {
|
||||
title.value = "待审核 " + title.value
|
||||
} else if ("20" == String(dataForm.auditStatus)) {
|
||||
title.value = "已录取 " + title.value
|
||||
contactNameflag.value = true
|
||||
const auditStatusConfig = getStatusConfig(auditStatusList, dataForm.auditStatus)
|
||||
if (auditStatusConfig) {
|
||||
title.value = auditStatusConfig.label + " " + title.value
|
||||
if (auditStatusConfig.value == '20') {
|
||||
contactNameflag.value = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -637,16 +501,42 @@ defineExpose({
|
||||
margin-bottom:18px!important;
|
||||
}
|
||||
}
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.avatar-uploader {
|
||||
:deep(.el-upload) {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
line-height: 148px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar-wrapper {
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
.avatar {
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
display: block;
|
||||
object-fit: cover;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
<!--
|
||||
- Copyright (c) 2018-2025, cyweb All rights reserved.
|
||||
-
|
||||
- Redistribution and use in source and binary forms, with or without
|
||||
- modification, are permitted provided that the following conditions are met:
|
||||
-
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
- this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
- notice, this list of conditions and the following disclaimer in the
|
||||
- documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of the pig4cloud.com developer nor the names of its
|
||||
- contributors may be used to endorse or promote products derived from
|
||||
- this software without specific prior written permission.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
@@ -60,37 +43,120 @@
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="type" label="异动类型" align="center" show-overflow-tooltip>
|
||||
<el-table-column prop="type" label="异动类型" width="100" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getTypeLabel(scope.row.type) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="姓名[唯一号]" width="140" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="majorChangeInfo" label="专业变更情况" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="学费变更情况" align="center">
|
||||
<el-table-column prop="dbName" label="费用类型" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="dbOldValue" label="原费用" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="dbNewValue" label="新费用" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="dbType" label="变更类型" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="dbChangeValue" label="变更金额" align="center" show-overflow-tooltip />
|
||||
</el-table-column>
|
||||
<el-table-column label="分数变更情况" align="center">
|
||||
<el-table-column prop="scoreName" label="分数类型" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="scoreOldValue" label="原分值" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="scoreNewValue" label="新分值" align="center" show-overflow-tooltip />
|
||||
</el-table-column>
|
||||
<el-table-column prop="createBy" label="异动发起人" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="createDate" label="异动时间" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="remarks" label="备注信息" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="isMajorChange" label="异动审核" width="110" align="center" show-overflow-tooltip>
|
||||
<el-table-column prop="name" label="姓名[唯一号]" min-width="160" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="majorChangeInfo" label="专业变更情况" min-width="180" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.isMajorChange" :options="auditStateOptions" />
|
||||
<DetailPopover
|
||||
v-if="scope.row.newMajorInfo || scope.row.oldMajorInfo"
|
||||
title="专业变更详情"
|
||||
:title-icon="InfoFilled"
|
||||
:width="320"
|
||||
:items="(() => {
|
||||
const items = []
|
||||
if (scope.row.oldMajorInfo) {
|
||||
items.push({ label: '旧专业', content: scope.row.oldMajorInfo })
|
||||
}
|
||||
if (scope.row.newMajorInfo) {
|
||||
items.push({ label: '新专业', content: scope.row.newMajorInfo, contentClass: 'new-major' })
|
||||
}
|
||||
return items
|
||||
})()">
|
||||
<template #reference>
|
||||
<span class="major-change-link">
|
||||
{{ scope.row.newMajorInfo || '查看详情' }}
|
||||
<el-icon class="title-icon"><InfoFilled /></el-icon>
|
||||
</span>
|
||||
</template>
|
||||
</DetailPopover>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="代办费变更情况" min-width="130" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="new-fee">{{ scope.row.newAgencyFee }}</span> / <span class="old-fee">{{ scope.row.oldAgencyFee }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学费变更情况" min-width="140" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="new-fee">{{ scope.row.newFeeTuition }}</span> / <span class="old-fee">{{ scope.row.oldFeeTuition }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分数变更情况" min-width="130" align="center">
|
||||
<template #default="scope">
|
||||
<span class="new-fee">{{ scope.row.newCorrectedScore }}</span> / <span class="old-fee">{{ scope.row.oldCorrectedScore }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createBy" label="异动发起人" min-width="120" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="异动时间" min-width="180" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="isMajorChange" label="异动审核" min-width="110" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<template v-if="getStatusConfig(auditStateOptions, scope.row.isMajorChange)">
|
||||
<!-- 有备注信息时,使用 popover 包裹 ClickableTag -->
|
||||
<DetailPopover
|
||||
v-if="scope.row.remarks"
|
||||
title="异动审核详情"
|
||||
:width="300"
|
||||
:items="[
|
||||
{
|
||||
label: '审核状态',
|
||||
layout: 'horizontal',
|
||||
content: getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label
|
||||
},
|
||||
{
|
||||
label: '备注信息',
|
||||
content: scope.row.remarks,
|
||||
contentClass: 'reason-content'
|
||||
}
|
||||
]">
|
||||
<template #reference>
|
||||
<ClickableTag
|
||||
width="80"
|
||||
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon">
|
||||
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-0>
|
||||
<ClickableTag
|
||||
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon"
|
||||
:right-icon="null">
|
||||
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-1>
|
||||
<div class="reason-content">
|
||||
<el-icon class="reason-icon"><Warning /></el-icon>
|
||||
<span>{{ scope.row.remarks }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</DetailPopover>
|
||||
|
||||
<!-- 没有备注信息时,直接显示 ClickableTag -->
|
||||
<ClickableTag
|
||||
v-else
|
||||
width="80"
|
||||
:type="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.type || 'info'"
|
||||
:left-icon="getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.icon"
|
||||
:right-icon="null">
|
||||
{{ getStatusConfig(auditStateOptions, scope.row.isMajorChange)?.label }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
|
||||
<!-- 无状态 -->
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="permissions.recruit_recruitstudentsignupturnover_edit && scope.row.isMajorChange == '1'"
|
||||
v-auth="'recruit_recruitstudentsignupturnover_edit'"
|
||||
v-if="scope.row.isMajorChange == '1'"
|
||||
type="primary"
|
||||
link
|
||||
icon="EditPen"
|
||||
@@ -111,9 +177,9 @@
|
||||
|
||||
<!-- 异动审核弹窗 -->
|
||||
<el-dialog v-model="majorChangeVisible" title="异动审核" width="600px">
|
||||
<el-form :model="exarmForm" ref="exarmFormRef" label-width="80px" :rules="dataRule">
|
||||
<el-form :model="exarmForm" ref="exarmFormRef" label-width="100px" :rules="dataRule">
|
||||
<el-form-item label="审核结果" prop="isMajorChange">
|
||||
<el-select v-model="exarmForm.isMajorChange" filterable clearable placeholder="请选择审核结果" style="width: 100%">
|
||||
<el-select v-model="exarmForm.isMajorChange" filterable clearable placeholder="请选择审核结果">
|
||||
<el-option
|
||||
v-for="item in isMajorChangeList"
|
||||
:key="item.value"
|
||||
@@ -125,7 +191,7 @@
|
||||
<el-form-item label="审核意见" prop="remarks">
|
||||
<el-input
|
||||
type="textarea"
|
||||
placeholder="请输入审核内容"
|
||||
placeholder="请输入审核意见"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
style="width: 100%"
|
||||
v-model="exarmForm.remarks"
|
||||
@@ -145,29 +211,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="recruitstudentsignupturnover">
|
||||
import { ref, reactive, computed, onMounted, defineAsyncComponent } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useUserInfo } from '/@/stores/userInfo'
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { fetchList, putObj } from '/@/api/recruit/recruitstudentsignupturnover'
|
||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||
import type { StateOption } from '/@/components/AuditState/index.vue'
|
||||
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
|
||||
// 使用 Pinia store
|
||||
const userInfoStore = useUserInfo()
|
||||
const { userInfos } = storeToRefs(userInfoStore)
|
||||
|
||||
// 创建权限对象
|
||||
const permissions = computed(() => {
|
||||
const perms: Record<string, boolean> = {}
|
||||
userInfos.value.authBtnList.forEach((perm: string) => {
|
||||
perms[perm] = true
|
||||
})
|
||||
return perms
|
||||
})
|
||||
import ClickableTag from '/@/components/ClickableTag/index.vue'
|
||||
import DetailPopover from '/@/components/DetailPopover/index.vue'
|
||||
import { Warning, InfoFilled } from '@element-plus/icons-vue'
|
||||
import { TURNOVER_AUDIT_STATUS_LIST, getStatusConfig } from '/@/config/global'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
@@ -182,14 +235,11 @@ const majorChangeVisible = ref(false)
|
||||
|
||||
// 数据
|
||||
const planList = ref<any[]>([])
|
||||
const typeList = ref([{ label: '专业变更', value: '1' }, { label: '退学', value: '2' }])
|
||||
// 使用字典 recruit_change_type
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 审核状态选项配置(用于 AuditState 组件和检索条件)
|
||||
const auditStateOptions = ref<StateOption[]>([
|
||||
{ value: '1', label: '待审核', type: 'warning', icon: 'fa-regular fa-clock', effect: 'light' },
|
||||
{ value: '2', label: '驳回', type: 'danger', icon: 'fa-solid fa-circle-xmark', effect: 'dark' },
|
||||
{ value: '3', label: '通过', type: 'success', icon: 'fa-solid fa-circle-check', effect: 'dark' }
|
||||
])
|
||||
// 审核状态选项配置(用于 ClickableTag 组件和检索条件)
|
||||
const auditStateOptions = ref<any[]>(TURNOVER_AUDIT_STATUS_LIST)
|
||||
|
||||
// 从 auditStateOptions 派生检索条件列表(只包含 label 和 value)
|
||||
const majorChangeList = computed(() => {
|
||||
@@ -202,7 +252,7 @@ const majorChangeList = computed(() => {
|
||||
// 审核弹窗中的选项(只包含通过和驳回)
|
||||
const isMajorChangeList = computed(() => {
|
||||
return auditStateOptions.value
|
||||
.filter(item => item.value === '2' || item.value === '3')
|
||||
.filter(item => item.value !== '1')
|
||||
.map(item => ({
|
||||
label: item.label,
|
||||
value: item.value
|
||||
@@ -234,7 +284,7 @@ const dataRule = {
|
||||
|
||||
// 获取异动类型标签
|
||||
const getTypeLabel = (type: string) => {
|
||||
const item = typeList.value.find(item => item.value === type)
|
||||
const item = typeList.value.find((it: any) => String(it.value) === String(type))
|
||||
return item ? item.label : ''
|
||||
}
|
||||
|
||||
@@ -265,9 +315,12 @@ const init = async () => {
|
||||
if (planList.value.length > 0) {
|
||||
queryForm.groupId = planList.value[0].id
|
||||
}
|
||||
const typeData = await getDicts('recruit_change_type')
|
||||
typeList.value = typeData.data || []
|
||||
getDataList()
|
||||
} catch (error) {
|
||||
message.error('初始化失败')
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('初始化失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,8 +348,9 @@ const update = async () => {
|
||||
message.success('审核成功')
|
||||
majorChangeVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
message.error(error.msg || '审核失败')
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,4 +372,69 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.new-fee {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.old-fee {
|
||||
text-decoration: line-through;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
// 备注内容样式(用于 DetailPopover 的插槽内容)
|
||||
.reason-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background-color: #fef0f0;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #f56c6c;
|
||||
|
||||
.reason-icon {
|
||||
color: #f56c6c;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #f56c6c;
|
||||
line-height: 1.6;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 专业变更链接样式
|
||||
.major-change-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--el-color-primary);
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary-light-3);
|
||||
}
|
||||
.title-icon {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
// 新专业样式(用于 DetailPopover 的内容类)
|
||||
.new-major {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user