|
@@ -1,471 +0,0 @@
|
|
-<template>
|
|
|
|
- <div class="d-flex flex-column">
|
|
|
|
- <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa" @update:modelValue="handleChange">
|
|
|
|
- <v-tab v-for="k in tabList" :value="k.value" :key="k.value">{{ k.label }}</v-tab>
|
|
|
|
- </v-tabs>
|
|
|
|
- <!-- <Screen :tab="tab" @search="handleScreen" @reset="handleScreenReset" @select="handleSelect" @change="handleChangeBounty"></Screen> -->
|
|
|
|
- <v-tabs-window v-model="tab" class="mt-1">
|
|
|
|
- <v-tabs-window-item v-for="k in tabList" :value="k.value" :key="k.value">
|
|
|
|
- <CtTable
|
|
|
|
- class="mt-3"
|
|
|
|
- :items="k.items"
|
|
|
|
- :headers="headers"
|
|
|
|
- :loading="false"
|
|
|
|
- :elevation="0"
|
|
|
|
- height="60vh"
|
|
|
|
- :disableSort="true"
|
|
|
|
- :isTools="false"
|
|
|
|
- :showPage="true"
|
|
|
|
- :total="k.total"
|
|
|
|
- :page-info="k.pageInfo"
|
|
|
|
- itemKey="id"
|
|
|
|
- @pageHandleChange="handleChangePage"
|
|
|
|
- >
|
|
|
|
- <template #studentId="{ item }">
|
|
|
|
- <div class="d-flex align-center">
|
|
|
|
- <v-badge
|
|
|
|
- v-if="item.student?.studentSex"
|
|
|
|
- bordered
|
|
|
|
- offset-y="6"
|
|
|
|
- :color="item.student?.studentSex === '男' ? '#1867c0' : 'error'"
|
|
|
|
- :icon="item.student?.studentSex === '男' ? 'mdi-gender-male' : 'mdi-gender-female'"
|
|
|
|
- >
|
|
|
|
- <v-avatar size="40" :image="getUserAvatar(item.student.studentHeadImg, item.student.studentSex)"></v-avatar>
|
|
|
|
- </v-badge>
|
|
|
|
- <v-avatar v-else size="40" :image="getUserAvatar(item.student.studentHeadImg, item.student.sex)"></v-avatar>
|
|
|
|
- <span class="ml-3">{{ item?.student?.studentName }}</span>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <template #major="{ item }">
|
|
|
|
- {{ item.student?.majorName }}
|
|
|
|
- {{ item.student?.majorName && item.student?.schoolDepartmentName ? ' - ' : '' }}
|
|
|
|
- {{ item.student?.schoolDepartmentName }}
|
|
|
|
- </template>
|
|
|
|
- <template #status="{ item}">
|
|
|
|
- {{ statusType[item.status] }}
|
|
|
|
- </template>
|
|
|
|
- <template #actions="{ item }">
|
|
|
|
- <v-btn color="primary" variant="text" @click="handlePreviewResume(item)">查看附件</v-btn>
|
|
|
|
- <template v-if="tab === 0">
|
|
|
|
- <v-btn color="primary" variant="text" @click="handleInterviewInvite(item)">邀请面试</v-btn>
|
|
|
|
- </template>
|
|
|
|
- <template v-if="tab === 1">
|
|
|
|
- <v-btn v-if="[21,22].includes(item.status)" color="primary " variant="text" @click="handleEliminate(item)">不合适</v-btn>
|
|
|
|
- <v-btn v-if="item.status === 22" color="primary" variant="text" @click="handleEnterByEnterprise(item)">入职</v-btn>
|
|
|
|
- </template>
|
|
|
|
- <v-btn v-if="item.status === 2" color="primary" variant="text" @click="handleEditJoinDate(item)">修改到岗时间</v-btn>
|
|
|
|
- </template>
|
|
|
|
- </CtTable>
|
|
|
|
- </v-tabs-window-item>
|
|
|
|
- </v-tabs-window>
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- <!-- 邀请面试 -->
|
|
|
|
- <CtDialog
|
|
|
|
- :visible="showInvite"
|
|
|
|
- :widthType="4"
|
|
|
|
- titleClass="text-h6"
|
|
|
|
- title="面试信息"
|
|
|
|
- @close="showInvite = false"
|
|
|
|
- @submit="handleEditSubmit"
|
|
|
|
- >
|
|
|
|
- <CtForm ref="CtFormInviteRef" :items="formItems" style="height: 500px;"></CtForm>
|
|
|
|
- </CtDialog>
|
|
|
|
-
|
|
|
|
- <!-- 入职 -->
|
|
|
|
- <CtDialog
|
|
|
|
- :visible="showAccess"
|
|
|
|
- :widthType="4"
|
|
|
|
- titleClass="text-h6"
|
|
|
|
- title="入职信息"
|
|
|
|
- @close="showAccess = false"
|
|
|
|
- @submit="handleAccess"
|
|
|
|
- >
|
|
|
|
- <CtForm ref="CtFormAccessRef" :items="AccessItems" style="height: 500px;"></CtForm>
|
|
|
|
- </CtDialog>
|
|
|
|
-
|
|
|
|
- <!-- 修改到岗时间 -->
|
|
|
|
- <CtDialog
|
|
|
|
- :visible="showEditJoinDate"
|
|
|
|
- :widthType="4"
|
|
|
|
- titleClass="text-h6"
|
|
|
|
- title="修改到岗时间"
|
|
|
|
- @close="showEditJoinDate = false"
|
|
|
|
- @submit="handleSubmitEditJoinDate"
|
|
|
|
- >
|
|
|
|
- <DatePicker v-model="editJoinDateItems.value" :item="editJoinDateItems"></DatePicker>
|
|
|
|
- </CtDialog>
|
|
|
|
-
|
|
|
|
- <!-- 不合适 -->
|
|
|
|
- <CtDialog
|
|
|
|
- :visible="showReject"
|
|
|
|
- :widthType="4"
|
|
|
|
- titleClass="text-h6"
|
|
|
|
- title="拒绝理由"
|
|
|
|
- @close="showReject = false"
|
|
|
|
- @submit="handleReject"
|
|
|
|
- >
|
|
|
|
- <CtForm ref="CtFormRejectRef" :items="rejectItems"></CtForm>
|
|
|
|
- </CtDialog>
|
|
|
|
- </div>
|
|
|
|
-</template>
|
|
|
|
-
|
|
|
|
-<script setup>
|
|
|
|
-defineOptions({ name: 'jobFairResume'})
|
|
|
|
-import { computed, ref } from 'vue'
|
|
|
|
-import { useRoute } from 'vue-router'
|
|
|
|
-import { useI18n } from '@/hooks/web/useI18n'
|
|
|
|
-import Snackbar from '@/plugins/snackbar'
|
|
|
|
-import { getResumeList, resumeCancel, resumeAccept, resumeInterview, updateJoinDate } from '@/api/recruit/enterprise/jobFair'
|
|
|
|
-import { useUserStore } from '@/store/user'
|
|
|
|
-import { getDict } from '@/hooks/web/useDictionaries'
|
|
|
|
-import { previewFile } from '@/utils'
|
|
|
|
-import { getUserAvatar } from '@/utils/avatar'
|
|
|
|
-import DatePicker from '@/components/FormUI/datePicker'
|
|
|
|
-import { timesTampChange } from '@/utils/date'
|
|
|
|
-import { formatName } from '@/utils/getText'
|
|
|
|
-import { getInterviewInviteDefaultTime } from '@/utils/date'
|
|
|
|
-
|
|
|
|
-const userStore = useUserStore()
|
|
|
|
-const route = useRoute()
|
|
|
|
-const { t } = useI18n()
|
|
|
|
-
|
|
|
|
-const statusType = {
|
|
|
|
- 0:'学生投递',
|
|
|
|
- 1:'企业邀请',
|
|
|
|
- 2:'同意入职',
|
|
|
|
- 3:'老师邀请',
|
|
|
|
- 4:'待学生确认入职',
|
|
|
|
- 14:'取消申请',
|
|
|
|
- 15:'不合适',
|
|
|
|
- 16:'学生拒绝老师邀请',
|
|
|
|
- 17:'学生实习结束',
|
|
|
|
- 20:'撤回投递',
|
|
|
|
- 21:'已邀约',
|
|
|
|
- 22:'学生同意面试邀请',
|
|
|
|
- 23:'学生拒绝面试邀请'
|
|
|
|
-}
|
|
|
|
-const tab = ref(0)
|
|
|
|
-const tabList = ref([
|
|
|
|
- {
|
|
|
|
- label: '投递简历',
|
|
|
|
- value: 0,
|
|
|
|
- statuss: [0],
|
|
|
|
- items: [],
|
|
|
|
- total: 0,
|
|
|
|
- pageInfo: {
|
|
|
|
- current: 1,
|
|
|
|
- size: 10
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- label: '面试邀约',
|
|
|
|
- value: 1,
|
|
|
|
- statuss: [4, 21, 22, 23],
|
|
|
|
- items: [],
|
|
|
|
- total: 0,
|
|
|
|
- pageInfo: {
|
|
|
|
- current: 1,
|
|
|
|
- size: 10
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- label: '已入职',
|
|
|
|
- value: 2,
|
|
|
|
- statuss: [2],
|
|
|
|
- items: [],
|
|
|
|
- total: 0,
|
|
|
|
- pageInfo: {
|
|
|
|
- current: 1,
|
|
|
|
- size: 10
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- label: '不合适',
|
|
|
|
- value: 3,
|
|
|
|
- statuss: [15],
|
|
|
|
- items: [],
|
|
|
|
- total: 0,
|
|
|
|
- pageInfo: {
|
|
|
|
- current: 1,
|
|
|
|
- size: 10
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-])
|
|
|
|
-
|
|
|
|
-const headers = computed(() => {
|
|
|
|
- const item = [
|
|
|
|
- { title: '姓名', value: 'studentId', sortable: false },
|
|
|
|
- { title: '学校', value: 'student.schoolName', sortable: false },
|
|
|
|
- { title: '专业', value: 'major', sortable: false },
|
|
|
|
- { title: '应聘职位', key: 'enterpriseRecruit.enterpriseRecruitJobName', sortable: false, value: item => formatName(item?.enterpriseRecruit?.enterpriseRecruitJobName) },
|
|
|
|
- { title: '岗位薪资',
|
|
|
|
- key: 'pay',
|
|
|
|
- value: ({ enterpriseRecruit }) => {
|
|
|
|
- if (!enterpriseRecruit) {
|
|
|
|
- return '面议'
|
|
|
|
- }
|
|
|
|
- const { payFrom, payTo, payUnit } = enterpriseRecruit
|
|
|
|
- return `${payFrom}${payFrom && payTo ? '-' : ''}${payTo}${payUnit ? '/' : ''}${payUnit}`
|
|
|
|
- },
|
|
|
|
- sortable: false
|
|
|
|
- },
|
|
|
|
- { title: '联系电话', value: 'student.phone', sortable: false },
|
|
|
|
- { title: '到岗时间', key: 'jobJoinDate', sortable: false, value: item => timesTampChange(item.jobJoinDate, 'Y-M-D') },
|
|
|
|
- { title: '状态', value: 'status', sortable: false },
|
|
|
|
- { title: '操作', value: 'actions', sortable: false }
|
|
|
|
- ]
|
|
|
|
- return item
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
-const CtFormInviteRef = ref()
|
|
|
|
-const CtFormRejectRef = ref()
|
|
|
|
-const CtFormAccessRef = ref()
|
|
|
|
-
|
|
|
|
-const formItems = ref({
|
|
|
|
- options: [
|
|
|
|
- {
|
|
|
|
- type: 'datePicker',
|
|
|
|
- mode: 'datetime',
|
|
|
|
- labelWidth: 78,
|
|
|
|
- value: '',
|
|
|
|
- key: 'interviewDate',
|
|
|
|
- label: '面试时间 *',
|
|
|
|
- value: getInterviewInviteDefaultTime().timeStamp,
|
|
|
|
- format: "YYYY/MM/DD HH:mm",
|
|
|
|
- defaultTime: getInterviewInviteDefaultTime().time,
|
|
|
|
- flexStyle: 'mb-7',
|
|
|
|
- disabledDate: true,
|
|
|
|
- rules: [v => !!v || '请选择面试时间']
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- type: 'text',
|
|
|
|
- key: 'name',
|
|
|
|
- value: '',
|
|
|
|
- noParam: true,
|
|
|
|
- disabled: true,
|
|
|
|
- label: '面试者'
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- type: 'text',
|
|
|
|
- key: 'position',
|
|
|
|
- value: '',
|
|
|
|
- noParam: true,
|
|
|
|
- disabled: true,
|
|
|
|
- label: '面试岗位'
|
|
|
|
- }
|
|
|
|
- ]
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
-const rejectItems = ref({
|
|
|
|
- options: [
|
|
|
|
- {
|
|
|
|
- type: 'textarea',
|
|
|
|
- key: 'refuseMsg',
|
|
|
|
- label: '拒绝理由 *',
|
|
|
|
- rules: [v => !!v || '请填写拒绝理由']
|
|
|
|
- }
|
|
|
|
- ]
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
-const AccessItems = ref({
|
|
|
|
- options: [
|
|
|
|
- {
|
|
|
|
- type: 'datePicker',
|
|
|
|
- mode: 'datetime',
|
|
|
|
- labelWidth: 78,
|
|
|
|
- value: '',
|
|
|
|
- key: 'jobJoinDate',
|
|
|
|
- label: '到岗时间 *',
|
|
|
|
- format: "YYYY/MM/DD HH:mm",
|
|
|
|
- flexStyle: 'mb-7',
|
|
|
|
- disabledDate: true,
|
|
|
|
- rules: [v => !!v || '请选择到岗时间']
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- type: 'text',
|
|
|
|
- key: 'name',
|
|
|
|
- value: '',
|
|
|
|
- noParam: true,
|
|
|
|
- disabled: true,
|
|
|
|
- label: '入职人员'
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- type: 'text',
|
|
|
|
- key: 'position',
|
|
|
|
- value: '',
|
|
|
|
- noParam: true,
|
|
|
|
- disabled: true,
|
|
|
|
- label: '入职岗位'
|
|
|
|
- }
|
|
|
|
- ]
|
|
|
|
-})
|
|
|
|
-const editJoinDateItems = ref({
|
|
|
|
- value: '',
|
|
|
|
- id: '',
|
|
|
|
- mode: 'date',
|
|
|
|
- placeholder: '请选择要修改的到岗时间',
|
|
|
|
- teleported: true,
|
|
|
|
- disabledDate: true
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
-const loading = ref(false)
|
|
|
|
-const itemData = ref({})
|
|
|
|
-const showInvite = ref(false)
|
|
|
|
-const showReject = ref(false)
|
|
|
|
-const showAccess = ref(false)
|
|
|
|
-const showEditJoinDate = ref(false)
|
|
|
|
-
|
|
|
|
-// 状态字典
|
|
|
|
-const statusList = ref([])
|
|
|
|
-
|
|
|
|
-getDict('menduner_interview_invite_status').then(({data}) => {
|
|
|
|
- if (data && data.length) statusList.value = data
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
-const handleChangePage = (index) => {
|
|
|
|
- tabList.value[tab.value].pageInfo.current = index
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const handleChange = () => {
|
|
|
|
- tabList.value[tab.value].pageInfo.current = 1
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// 查看简历
|
|
|
|
-const handlePreviewResume = async (item) => {
|
|
|
|
- const url = item.studentInfoVo?.studentBiographicalNotes?.fileUrl
|
|
|
|
- if (!url) return
|
|
|
|
- previewFile(url)
|
|
|
|
-}
|
|
|
|
-// 邀请面试
|
|
|
|
-const handleInterviewInvite = (item) => {
|
|
|
|
- formItems.value.options.forEach(e => {
|
|
|
|
- if (e.key === 'name') {
|
|
|
|
- e.value = item.student?.studentName
|
|
|
|
- }
|
|
|
|
- if (e.key === 'position') {
|
|
|
|
- e.value = item.enterpriseRecruit.enterpriseRecruitJobName
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- itemData.value = item
|
|
|
|
- showInvite.value = true
|
|
|
|
-}
|
|
|
|
-// 提交邀请
|
|
|
|
-const handleEditSubmit = async () => {
|
|
|
|
- const { valid } = await CtFormInviteRef.value.formRef.validate()
|
|
|
|
- if (!valid) return
|
|
|
|
- const query = formItems.value.options.reduce((acc, cur) => {
|
|
|
|
- if (cur.noParam) {
|
|
|
|
- return acc
|
|
|
|
- }
|
|
|
|
- acc[cur.key] = cur.value
|
|
|
|
- return acc
|
|
|
|
- }, {
|
|
|
|
- practiceSubmitRecordId: itemData.value.practiceSubmitRecordId,
|
|
|
|
- studentId: itemData.value.studentId
|
|
|
|
- })
|
|
|
|
- if (!query?.interviewDate) return Snackbar.warning('请选择邀请时间')
|
|
|
|
-
|
|
|
|
- await resumeInterview(query)
|
|
|
|
-
|
|
|
|
- Snackbar.success(t('common.operationSuccessful'))
|
|
|
|
- showInvite.value = false
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const handleEliminate = (item) => {
|
|
|
|
- itemData.value = item
|
|
|
|
- showReject.value = true
|
|
|
|
-}
|
|
|
|
-// 不合适
|
|
|
|
-const handleReject = async () => {
|
|
|
|
- const { valid } = await CtFormRejectRef.value.formRef.validate()
|
|
|
|
- if (!valid) return
|
|
|
|
- const query = rejectItems.value.options.reduce((acc, cur) => {
|
|
|
|
- acc[cur.key] = cur.value
|
|
|
|
- return acc
|
|
|
|
- }, {
|
|
|
|
- practiceSubmitRecordId: itemData.value.practiceSubmitRecordId,
|
|
|
|
- enterpriseId: itemData.value.enterpriseId
|
|
|
|
- })
|
|
|
|
- await resumeCancel(query)
|
|
|
|
-
|
|
|
|
- Snackbar.success(t('common.operationSuccessful'))
|
|
|
|
- showReject.value = false
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// 入职
|
|
|
|
-const handleEnterByEnterprise = async (item) => {
|
|
|
|
- AccessItems.value.options.forEach(e => {
|
|
|
|
- if (e.key === 'name') {
|
|
|
|
- e.value = item.student?.studentName
|
|
|
|
- }
|
|
|
|
- if (e.key === 'position') {
|
|
|
|
- e.value = item.enterpriseRecruit.enterpriseRecruitJobName
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- itemData.value = item
|
|
|
|
- showAccess.value = true
|
|
|
|
-}
|
|
|
|
-const handleAccess = async () => {
|
|
|
|
- const { valid } = await CtFormAccessRef.value.formRef.validate()
|
|
|
|
- if (!valid) return
|
|
|
|
- const query = AccessItems.value.options.reduce((acc, cur) => {
|
|
|
|
- if (cur.noParam) {
|
|
|
|
- return acc
|
|
|
|
- }
|
|
|
|
- acc[cur.key] = cur.value
|
|
|
|
- return acc
|
|
|
|
- }, {
|
|
|
|
- practiceSubmitRecordId: itemData.value.practiceSubmitRecordId,
|
|
|
|
- studentId: itemData.value.studentId
|
|
|
|
- })
|
|
|
|
- await resumeAccept(query)
|
|
|
|
- Snackbar.success(t('common.operationSuccessful'))
|
|
|
|
- showAccess.value = false
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// 修改到岗时间
|
|
|
|
-const handleEditJoinDate = (item) => {
|
|
|
|
- editJoinDateItems.value.id = item.practiceSubmitRecordId
|
|
|
|
- editJoinDateItems.value.value = item.jobJoinDate
|
|
|
|
- showEditJoinDate.value = true
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const handleSubmitEditJoinDate = async () => {
|
|
|
|
- if (!editJoinDateItems.value.value) return Snackbar.warning('请选择要修改的日期')
|
|
|
|
- await updateJoinDate({ jobJoinDate: editJoinDateItems.value.value, practiceSubmitRecordId: editJoinDateItems.value.id })
|
|
|
|
-
|
|
|
|
- Snackbar.success('修改成功')
|
|
|
|
- editJoinDateItems.value.value = ''
|
|
|
|
- editJoinDateItems.value.id = ''
|
|
|
|
- showEditJoinDate.value = false
|
|
|
|
- getList()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const getList = async () => {
|
|
|
|
- loading.value = true
|
|
|
|
- try {
|
|
|
|
- const res = await getResumeList({
|
|
|
|
- ...tabList.value[tab.value].pageInfo,
|
|
|
|
- jobFairId: route.params.id,
|
|
|
|
- enterpriseId: userStore.entBaseInfo.enterpriseId,
|
|
|
|
- statuss: tabList.value[tab.value].statuss
|
|
|
|
- })
|
|
|
|
- tabList.value[tab.value].items = res.records
|
|
|
|
- tabList.value[tab.value].total = res.total
|
|
|
|
- } finally {
|
|
|
|
- loading.value = false
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-getList()
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
-<style scoped lang="scss">
|
|
|
|
-
|
|
|
|
-</style>
|
|
|