|
@@ -45,7 +45,7 @@
|
|
|
<template v-slot:title="{ title }">
|
|
|
<div v-if="!isEnterprise" class="mt-2 d-flex align-center">
|
|
|
{{ title }}
|
|
|
- <div class="ml-3 color-666 font-size-14 enterprise-name ellipsis" v-ellipse-tooltip :style="{'color': val.channel.channelID === info?.channel?.channelID ? '#00897B' : '#666'}">
|
|
|
+ <div class="ml-3 color-666 font-size-14 enterprise-name ellipsis" v-ellipse-tooltip :style="{'color': val.channel.channelID === info?.channel?.channelID ? '#00B760' : '#666'}">
|
|
|
{{ formatName(val.userInfoVo?.userInfoResp?.enterpriseAnotherName) }}
|
|
|
<span class="line" v-if="val.userInfoVo?.userInfoResp?.postNameCn && val.userInfoVo?.userInfoResp?.enterpriseAnotherName"></span>
|
|
|
{{ val.userInfoVo?.userInfoResp?.postNameCn }}
|
|
@@ -135,13 +135,15 @@
|
|
|
@close="showUploadDialog = false"
|
|
|
@submit="handleSubmitAttachment"
|
|
|
>
|
|
|
+ <div class="color-warning mb-3" style="font-size: 13px;">* 仅支持.doc, .docx, .pdf文件且大小不能超过20MB</div>
|
|
|
<CtForm ref="CtFormRef" :items="formItems">
|
|
|
<template #uploadFile="{ item }">
|
|
|
<TextInput v-model="item.value" :item="item" @click="openFileInput"></TextInput>
|
|
|
<File ref="uploadFile" @success="handleUploadResume"></File>
|
|
|
</template>
|
|
|
</CtForm>
|
|
|
- <div class="color-666" style="font-size: 13px;">* 仅支持.doc, .docx, .pdf文件且大小不能超过20MB</div>
|
|
|
+ <!-- 学生-实习到岗信息 -->
|
|
|
+ <studentDeliveryForm v-if="baseInfo?.type && Number(baseInfo.type) === 1" ref="studentDeliveryFormRef" />
|
|
|
</CtDialog>
|
|
|
|
|
|
<!-- 面试邀请 -->
|
|
@@ -156,10 +158,28 @@
|
|
|
<CtDialog :visible="showSelectPosition" :widthType="2" titleClass="text-h6" title="选择要求简历的职位" @close="showSelectPosition = false" @submit="handleRequestResumeSubmit">
|
|
|
<CtForm v-if="showSelectPosition" ref="requestFromRef" :items="requestFormItems"></CtForm>
|
|
|
</CtDialog>
|
|
|
+ <!-- 发送简历-选择要发送的职位 -->
|
|
|
+ <CtDialog :visible="openPositionSelectDialog" :widthType="2" titleClass="text-h6" title="请选择要投递的职位" @close="openPositionSelectDialog = false" @submit="selectPositionSubmit">
|
|
|
+ <div style="position: relative; min-height: 200px">
|
|
|
+ <v-radio-group v-model="selectJobId">
|
|
|
+ <div v-for="val in rightEntPositionList" :key="val.value" class="d-flex align-center radioBox" >
|
|
|
+ <v-radio :label="val.label" :value="val.value" color="primary"></v-radio>
|
|
|
+ <span class="defaultLink mx-3" style="font-size: 14px;" @click.stop="positionDetail(val)">预览</span>
|
|
|
+ </div>
|
|
|
+ </v-radio-group>
|
|
|
+ </div>
|
|
|
+ <v-btn
|
|
|
+ variant="text"
|
|
|
+ color="primary"
|
|
|
+ @click="changePositionData"
|
|
|
+ >
|
|
|
+ {{ positionListIsEnd ? '没有更多职位了~ 再选一遍' : '换一批'}} <v-icon size="16">mdi-refresh</v-icon>
|
|
|
+ </v-btn>
|
|
|
+ </CtDialog>
|
|
|
|
|
|
<!-- 选择附件简历投递 -->
|
|
|
<CtDialog :visible="showResume" :widthType="2" titleClass="text-h6" title="发送简历" @close="showResume = false; selectResume = null; enRequestPositionInfo = {}" @submit="handleSubmitResume">
|
|
|
- <div style="position: relative; min-height: 200px">
|
|
|
+ <div style="position: relative;">
|
|
|
<v-radio-group v-model="selectResume">
|
|
|
<div v-for="val in resumeList" :key="val.id" class="d-flex align-center radioBox">
|
|
|
<v-radio :label="val.title" :value="val.id" color="primary"></v-radio>
|
|
@@ -167,7 +187,9 @@
|
|
|
</div>
|
|
|
</v-radio-group>
|
|
|
</div>
|
|
|
+ <studentDeliveryForm v-if="isStudent" ref="studentDeliveryFormRef" />
|
|
|
</CtDialog>
|
|
|
+ <Loading :visible="pageLoading" />
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
@@ -180,7 +202,7 @@ import { useRoute } from 'vue-router'
|
|
|
import Chatting from './components/chatting.vue'
|
|
|
import { initConnect, send, initChart, getMoreMessages, checkConversation } from '@/hooks/web/useIM'
|
|
|
import { useI18n } from '@/hooks/web/useI18n'
|
|
|
-import { getPositionDetails, jobCvRelCheckSend, jobCvRelSend, jobCvRelHireSend } from '@/api/position'
|
|
|
+import { getPositionDetails, jobCvRelCheckSend, jobCvRelSend, jobCvRelHireSend, getJobAdvertisedSearch } from '@/api/position'
|
|
|
import { getInterviewInviteListByInviteUserId, getMessageType } from '@/api/common'
|
|
|
// import { getUserInfo } from '@/api/personal/user'
|
|
|
import { getBaseInfo } from '@/api/common'
|
|
@@ -201,6 +223,7 @@ import { dealDictArrayData } from '@/utils/position'
|
|
|
import { previewFile } from '@/utils'
|
|
|
import { timesTampChange } from '@/utils/date'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
+import studentDeliveryForm from '@/views/recruit/personal/components/studentDeliveryForm.vue'
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
const chatRef = ref()
|
|
@@ -217,6 +240,9 @@ const channelItem = ref(null)
|
|
|
const messageItems = ref([])
|
|
|
const pageSize = ref(1)
|
|
|
const hasMore = ref(false)
|
|
|
+const studentDeliveryFormRef = ref()
|
|
|
+const baseInfo = ref(localStorage.getItem('baseInfo') ? JSON.parse(localStorage.getItem('baseInfo')) : {})
|
|
|
+const isStudent = ref(baseInfo.value?.type && Number(baseInfo.value.type) === 1)
|
|
|
|
|
|
const positionList = ref([])
|
|
|
const showTip = ref(false)
|
|
@@ -411,6 +437,8 @@ async function getMessageTypeSync () {
|
|
|
}
|
|
|
})
|
|
|
if (!data.records || !data.records.length) {
|
|
|
+ positionInfo.value = {}
|
|
|
+ handleChangeSendResumeStatus(false)
|
|
|
return
|
|
|
}
|
|
|
const _item = data.records.pop()
|
|
@@ -491,10 +519,68 @@ const handleUploadResume = async (url, title, filename) => {
|
|
|
obj.truthValue = url
|
|
|
}
|
|
|
|
|
|
+const changePositionData = () => {
|
|
|
+ positionListParams.value.pageNo = positionListIsEnd.value ? 1 : positionListParams.value.pageNo + 1
|
|
|
+ getRecruitPositionList()
|
|
|
+}
|
|
|
+
|
|
|
+const positionDetail = (val) => {
|
|
|
+ const id = val.value
|
|
|
+ if (!id) return
|
|
|
+ window.open(`/recruit/personal/position/details/${id}`)
|
|
|
+}
|
|
|
+
|
|
|
+// 选中职位并投递
|
|
|
+const selectJobId = ref('')
|
|
|
+const selectPositionSubmit = async () => {
|
|
|
+ // 投递
|
|
|
+ openPositionSelectDialog.value = false
|
|
|
+ handleSendResume(handleSendResumeItem)
|
|
|
+}
|
|
|
+
|
|
|
+const rightEntPositionTotal = ref(0)
|
|
|
+const rightEntPositionList = ref([])
|
|
|
+const positionListParams = ref({ pageNo: 1, pageSize: 5 })
|
|
|
+const openPositionSelectDialog = ref(false)
|
|
|
+const pageLoading = ref(false)
|
|
|
+const positionListIsEnd = computed(() => positionListParams.value.pageNo * positionListParams.value.pageSize >= rightEntPositionTotal.value)
|
|
|
+// 职位列表
|
|
|
+const getRecruitPositionList = async () => {
|
|
|
+ const enterpriseId = info.value?.enterpriseId || null
|
|
|
+ if (!enterpriseId) return Snackbar.warning('访问企业错误!')
|
|
|
+
|
|
|
+ pageLoading.value = true
|
|
|
+ const { list, total: number } = await getJobAdvertisedSearch({ ...positionListParams.value, enterpriseId })
|
|
|
+ if (!list.length) return Snackbar.warning('企业暂无招聘中的职位,无法进行投递!')
|
|
|
+
|
|
|
+ rightEntPositionTotal.value = number
|
|
|
+ rightEntPositionList.value = list.map(j => {
|
|
|
+ const e = j?.job || null
|
|
|
+ if (!e) return e
|
|
|
+ const salary = e.payFrom && e.payTo ? `${e.payFrom ? e.payFrom + '-' : ''}${e.payTo}${e.payName ? '/' + e.payName : ''}` : '面议'
|
|
|
+ return {
|
|
|
+ label: `${formatName(e.name)}_${e.areaName ? e.area?.str : '全国'} ${salary}`,
|
|
|
+ value: e.id,
|
|
|
+ data: e
|
|
|
+ }
|
|
|
+ }).filter(Boolean)
|
|
|
+
|
|
|
+ setTimeout(() => { pageLoading.value = false }, 300)
|
|
|
+}
|
|
|
+
|
|
|
// 获取简历
|
|
|
const showUploadDialog = ref(false)
|
|
|
const enRequestPositionInfo = ref({}) // 企业求简历时选中的职位信息
|
|
|
+let handleSendResumeItem = null
|
|
|
async function handleSendResume (item) {
|
|
|
+ const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id
|
|
|
+ if (!jobId && !selectJobId.value && import.meta.env.VITE_NODE_ENV !== 'production') {
|
|
|
+ // 没有基于职位接收到的沟通,弹出职位列表让求职者选择。否则无法投递简历。
|
|
|
+ handleSendResumeItem = item
|
|
|
+ await getRecruitPositionList()
|
|
|
+ if (rightEntPositionTotal.value) openPositionSelectDialog.value = true
|
|
|
+ return
|
|
|
+ }
|
|
|
try {
|
|
|
item.loading = true
|
|
|
// 获取简历列表
|
|
@@ -550,85 +636,112 @@ const handleSubmitAttachment = async () => {
|
|
|
obj[e.key] = e.truthValue || e.value
|
|
|
})
|
|
|
if (!obj.title || !obj.url) return
|
|
|
- await savePersonResumeCv(obj)
|
|
|
- const text = {
|
|
|
- remark: '发送简历',
|
|
|
- query: {
|
|
|
- src: obj.url,
|
|
|
- title: obj.title
|
|
|
- },
|
|
|
- type: 1
|
|
|
+
|
|
|
+ // 学生实习到岗信息
|
|
|
+ let practice = {}
|
|
|
+ if (isStudent.value) {
|
|
|
+ practice = studentDeliveryFormRef.value.getQueryParams()
|
|
|
+ console.log(practice, '上传简历-到岗信息')
|
|
|
}
|
|
|
- if (enRequestPositionInfo.value) text.query.positionInfo = enRequestPositionInfo.value
|
|
|
- send (JSON.stringify(text), channelItem.value, 105)
|
|
|
+ if (isStudent.value && (!practice?.practiceStartTime || !practice?.practiceEndTime)) return Snackbar.warning('请完善实习到岗信息')
|
|
|
+
|
|
|
+ // 保存附件
|
|
|
+ await savePersonResumeCv(obj)
|
|
|
|
|
|
// 简历投递至简历库
|
|
|
if (isEmployment.value !== '-1') {
|
|
|
- await jobCvRelHireSend({
|
|
|
- jobId: positionInfo.value.id,
|
|
|
+ let params = {
|
|
|
+ jobId: positionInfo.value.id || selectJobId.value,
|
|
|
url: obj.url,
|
|
|
recommendUserId: isEmployment.value
|
|
|
- })
|
|
|
+ }
|
|
|
+ // 如果是学生则需要带上实习信息
|
|
|
+ if (practice && Object.keys(practice).length > 0) params = Object.assign(params, practice)
|
|
|
+ await jobCvRelHireSend(params)
|
|
|
} else {
|
|
|
- const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id
|
|
|
+ const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id || selectJobId.value
|
|
|
const type = (enRequestPositionInfo.value && Object.keys(enRequestPositionInfo.value).length ? enRequestPositionInfo.value.hire : positionInfo.value.hire) ? 1 : 0
|
|
|
- const params = {
|
|
|
+ let params = {
|
|
|
jobId,
|
|
|
title: obj.title,
|
|
|
url: obj.url,
|
|
|
type
|
|
|
}
|
|
|
- // 参与招聘会的职位需传递招聘会id
|
|
|
- // if (jobFairId.value) params.jobFairId = jobFairId.value
|
|
|
-
|
|
|
+ // 如果是学生则需要带上实习信息
|
|
|
+ if (practice && Object.keys(practice).length > 0) params = Object.assign(params, practice)
|
|
|
await jobCvRelSend(params)
|
|
|
}
|
|
|
handleChangeSendResumeStatus(true)
|
|
|
showUploadDialog.value = false
|
|
|
- enRequestPositionInfo.value = {}
|
|
|
-}
|
|
|
|
|
|
-async function handleSubmitResume () {
|
|
|
- if (!selectResume.value) {
|
|
|
- Snackbar.error(t('resume.selectResumeToSubmit'))
|
|
|
- return
|
|
|
- }
|
|
|
- const _info = resumeList.value.find((item) => item.id === selectResume.value)
|
|
|
const text = {
|
|
|
remark: '发送简历',
|
|
|
query: {
|
|
|
- src: _info.url,
|
|
|
- title: _info.title,
|
|
|
- id: _info.id,
|
|
|
+ src: obj.url,
|
|
|
+ title: obj.title
|
|
|
},
|
|
|
type: 1
|
|
|
}
|
|
|
if (enRequestPositionInfo.value) text.query.positionInfo = enRequestPositionInfo.value
|
|
|
send (JSON.stringify(text), channelItem.value, 105)
|
|
|
|
|
|
+ enRequestPositionInfo.value = {}
|
|
|
+}
|
|
|
+
|
|
|
+async function handleSubmitResume () {
|
|
|
+ if (!selectResume.value) {
|
|
|
+ Snackbar.warning(t('resume.selectResumeToSubmit'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const _info = resumeList.value.find((item) => item.id === selectResume.value)
|
|
|
+
|
|
|
+ // 学生实习到岗信息
|
|
|
+ let practice = {}
|
|
|
+ if (isStudent.value) {
|
|
|
+ practice = studentDeliveryFormRef.value.getQueryParams()
|
|
|
+ console.log(practice, '选择简历-到岗信息')
|
|
|
+ }
|
|
|
+ if (isStudent.value && (!practice?.practiceStartTime || !practice?.practiceEndTime)) return Snackbar.warning('请完善实习到岗信息')
|
|
|
+
|
|
|
// 简历投递至简历库
|
|
|
if (isEmployment.value !== '-1') {
|
|
|
- await jobCvRelHireSend({
|
|
|
- jobId: positionInfo.value.id,
|
|
|
+ let params = {
|
|
|
+ jobId: positionInfo.value.id || selectJobId.value,
|
|
|
url: _info.url,
|
|
|
recommendUserId: isEmployment.value
|
|
|
- })
|
|
|
+ }
|
|
|
+ // 如果是学生则需要带上实习信息
|
|
|
+ if (practice && Object.keys(practice).length > 0) params = Object.assign(params, practice)
|
|
|
+ await jobCvRelHireSend(params)
|
|
|
} else {
|
|
|
- const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id
|
|
|
+ const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id || selectJobId.value
|
|
|
const type = (enRequestPositionInfo.value && Object.keys(enRequestPositionInfo.value).length ? enRequestPositionInfo.value.hire : positionInfo.value.hire) ? 1 : 0
|
|
|
- const params = {
|
|
|
+ let params = {
|
|
|
jobId,
|
|
|
title: _info.title,
|
|
|
url: _info.url,
|
|
|
type
|
|
|
}
|
|
|
- // 参与招聘会的职位需传递招聘会id
|
|
|
- // if (jobFairId.value) params.jobFairId = jobFairId.value
|
|
|
+ // 如果是学生则需要带上实习信息
|
|
|
+ if (practice && Object.keys(practice).length > 0) params = Object.assign(params, practice)
|
|
|
|
|
|
await jobCvRelSend(params)
|
|
|
}
|
|
|
handleChangeSendResumeStatus(true)
|
|
|
showResume.value = false
|
|
|
+
|
|
|
+ const text = {
|
|
|
+ remark: '发送简历',
|
|
|
+ query: {
|
|
|
+ src: _info.url,
|
|
|
+ title: _info.title,
|
|
|
+ id: _info.id,
|
|
|
+ },
|
|
|
+ type: 1
|
|
|
+ }
|
|
|
+ if (enRequestPositionInfo.value) text.query.positionInfo = enRequestPositionInfo.value
|
|
|
+ send (JSON.stringify(text), channelItem.value, 105)
|
|
|
+
|
|
|
enRequestPositionInfo.value = {}
|
|
|
}
|
|
|
|