lifanagju_citu пре 10 месеци
родитељ
комит
5a09a12f93

+ 1 - 0
src/locales/en.js

@@ -214,6 +214,7 @@ export default {
     deleteAttachment: 'Are you sure to delete this attachment?',
     uploadFiveCopies: 'Upload up to 5 copies',
     selectResumeToSubmit: 'Please select the resume to be submitted',
+    selectLocalFile: 'Select local file',
     resumeYetSubmit: 'You have not uploaded your resume yet. Please upload your resume first before submitting it',
     alreadyResume: 'You have already submitted your resume, please do not resubmit it',
     deliverySuccess: 'Delivery successful',

+ 1 - 0
src/locales/zh-CN.js

@@ -214,6 +214,7 @@ export default {
     deleteAttachment: '是否确认删除此附件?',
     uploadFiveCopies: '最多上传5份',
     selectResumeToSubmit: '请选择要投递的简历',
+    selectLocalFile: '选择本地简历进行投递',
     resumeYetSubmit: '您还未上传过简历,请先上传简历后再投递',
     alreadyResume: '您已投递过简历,请勿重复投递',
     deliverySuccess: '投递成功',

+ 6 - 1
src/views/recruit/personal/position/components/jobDetails/selectResumeDialog.vue

@@ -8,6 +8,7 @@
     @close="emit('close')"
     @submit="emit('submit', selectResume)"
   >
+    <div class="defaultLink ml-3 mb-3" style="font-size: 15px;" @click="emit('selectLocalFile')">{{ $t('resume.selectLocalFile') }}</div>
     <v-radio-group v-model="selectResume">
       <v-radio v-for="val in list" :key="val.id" :value="val.id" :label="val.title" color="primary"></v-radio>
     </v-radio-group>
@@ -20,13 +21,17 @@ import { defineEmits, watch, computed, ref } from 'vue'
 defineOptions({name: 'position-details-selectResumeDialog'})
 
 const props = defineProps({
+  selectLocalFile: {
+    type: Boolean,
+    default: false
+  },
   list: {
     type: Array,
     default: () => []
   },
   modelValue: [Boolean, Number]
 })
-const emit = defineEmits(['update:modelValue', 'handleToUpload', 'submit', 'close'])
+const emit = defineEmits(['update:modelValue', 'handleToUpload', 'submit', 'close', 'selectLocalFile'])
 const show = computed(() => {
   return props.modelValue
 })

+ 52 - 36
src/views/recruit/personal/shareJob/components/login.vue

@@ -1,28 +1,43 @@
-<!--  -->
+<!-- 快速登录/注册 -->
 <template>
-  <div class="my-5">
-    <phoneFrom ref="phoneRef" @handleEnter="handleLogin"></phoneFrom>
-    <v-btn :loading="loginLoading" color="primary" class="white--text mt-5" min-width="350" @click="handleLogin">
-      {{ $t('login.register') }}
-    </v-btn>
-  </div>
+  <CtDialog
+    :visible="openDialog"
+    :widthType="2"
+    :footer="false"
+    titleClass="text-h6"
+    title="快速登录"
+    @close="openDialog = false"
+  >
+    <!-- <quickLogin :jobId="jobId" @loginSuccess="loginSuccess"></quickLogin> -->
+    <div class="my-5">
+      <phoneFrom ref="phoneRef" @handleEnter="handleLogin"></phoneFrom>
+      <v-btn :loading="loginLoading" color="primary" class="white--text mt-5" min-width="350" @click="handleLogin">
+        {{ $t('login.register') }}
+      </v-btn>
+    </div>
+  </CtDialog>
 </template>
 
 <script setup>
 import phoneFrom from '@/components/VerificationCode'
 import { useUserStore } from '@/store/user'; const userStore = useUserStore()
-import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
-import Snackbar from '@/plugins/snackbar'
-import { ref } from 'vue'
+// import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
+// import Snackbar from '@/plugins/snackbar'
+import { nextTick, ref } from 'vue'
 defineOptions({name: 'shareJob-login'})
 const emit = defineEmits(['loginSuccess'])
 
+const openDialog = ref(false)
+nextTick(() => {
+  openDialog.value = true
+})
+
 // 验证码登录
 const phoneRef = ref()
 const loginLoading = ref(false)
 
-const timer = ref(null)
-const baseInfo = ref(null)
+// const timer = ref(null)
+// const baseInfo = ref(null)
 const handleLogin = async () => {
   localStorage.removeItem('currentRole')
   const { valid } = await phoneRef.value.phoneForm.validate()
@@ -31,36 +46,37 @@ const handleLogin = async () => {
   try {
     const params = { ...phoneRef.value.loginData } // 只能验证码登录
     await userStore.handleSmsLogin(params)
-    // 查询用户基本信息
-    timer.value = setInterval(() => { getUserInfoVerify() }, 1000)
-    // 十秒后停止获取清除timer
-    setTimeout(() => { if (!baseInfo.value) getUserInfoFail() }, 10000);
+    emit('loginSuccess')
+    // // 查询用户基本信息
+    // timer.value = setInterval(() => { getUserInfoVerify() }, 1000)
+    // // 十秒后停止获取清除timer
+    // setTimeout(() => { if (!baseInfo.value) getUserInfoFail() }, 10000);
   } catch (error) {
     console.error('error', error)
   }
 }
 
-// 查询用户基本信息失败 
-const getUserInfoVerify = () => {
-  if (baseInfo.value) {
-    clearInterval(timer.value)
-    timer.value = null
-    loginLoading.value = false
-    const keyArr = ['name', 'phone', 'jobStatus', 'expType', 'eduType'] // 必填人才信息
-    const baseInfoReady = keyArr.every(e => baseInfo.value[e] && baseInfo.value[e] !== 0) // 校验必填人才信息
-    const obj = { baseInfoReady, baseInfo: baseInfo.value, keyArr }
-    emit('loginSuccess', obj)
-  }
-  baseInfo.value = JSON.parse(localStorage.getItem('baseInfo'))
-}
+// // 查询用户基本信息失败 
+// const getUserInfoVerify = () => {
+//   if (baseInfo.value) {
+//     clearInterval(timer.value)
+//     timer.value = null
+//     loginLoading.value = false
+//     const keyArr = ['name', 'phone', 'jobStatus', 'expType', 'eduType'] // 必填人才信息
+//     const baseInfoReady = keyArr.every(e => baseInfo.value[e] && baseInfo.value[e] !== 0) // 校验必填人才信息
+//     const obj = { baseInfoReady, baseInfo: baseInfo.value, keyArr }
+//     emit('loginSuccess', obj)
+//   }
+//   baseInfo.value = JSON.parse(localStorage.getItem('baseInfo'))
+// }
 
-// 查询用户基本信息失败 
-const getUserInfoFail = () => {
-  clearInterval(timer.value)
-  timer.value = null
-  loginLoading.value = false
-  Snackbar.success(t('login.getUserInfoFailed')+','+t('login.loginAgain'))
-}
+// // 查询用户基本信息失败 
+// const getUserInfoFail = () => {
+//   clearInterval(timer.value)
+//   timer.value = null
+//   loginLoading.value = false
+//   Snackbar.success(t('login.getUserInfoFailed')+','+t('login.loginAgain'))
+// }
 </script>
 <style lang="scss" scoped>
 </style>

+ 111 - 0
src/views/recruit/personal/shareJob/form/simpleInfo.vue

@@ -0,0 +1,111 @@
+<template>
+  <div style="width: 100%;">
+    <CtForm ref="formPageRef" :items="items"></CtForm>
+  </div>
+</template>
+
+<script setup>
+import { getDict } from '@/hooks/web/useDictionaries'
+defineOptions({name: 'shareJob-form-baseInfo'})
+import { reactive, ref, defineExpose } from 'vue'
+
+const formPageRef = ref()
+let query = reactive({})
+
+const items = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'name',
+      value: '',
+      default: null,
+      label: '姓名 *',
+      outlined: true,
+      rules: [v => !!v || '请输入姓名']
+    },
+    {
+      type: 'text',
+      key: 'phone',
+      value: '',
+      clearable: true,
+      label: '联系手机号 *',
+      rules: [v => !!v || '请填写联系手机号']
+    },
+    {
+      type: 'autocomplete',
+      key: 'jobStatus',
+      value: '',
+      default: null,
+      label: '求职状态 *',
+      outlined: true,
+      itemText: 'label',
+      itemValue: 'value',
+      dictTypeName: 'menduner_job_status',
+      rules: [v => !!v || '请选择求职状态'],
+      items: []
+    },
+    {
+      type: 'autocomplete',
+      key: 'expType',
+      value: '',
+      default: null,
+      label: '工作经验 *',
+      outlined: true,
+      itemText: 'label',
+      itemValue: 'value',
+      dictTypeName: 'menduner_exp_type',
+      rules: [v => !!v || '请选择工作经验'],
+      items: []
+    },
+    {
+      type: 'autocomplete',
+      key: 'eduType',
+      value: '',
+      default: null,
+      label: '最高学历 *',
+      outlined: true,
+      itemText: 'label',
+      itemValue: 'value',
+      dictTypeName: 'menduner_education_type',
+      rules: [v => !!v || '请选择最高学历'],
+      items: []
+    },
+  ]
+})
+
+// 获取字典内容
+const getDictData = async (dictTypeName) => {
+  const item = items.value.options.find(e => e.dictTypeName === dictTypeName)
+  if (item) {
+    const { data } = await getDict(dictTypeName)
+    item.items = data
+  }
+}
+
+items.value.options.forEach((e) => {
+  if (e.dictTypeName) getDictData(e.dictTypeName) // 查字典set options
+  // formItems回显
+  // const infoExist = baseInfo.value && Object.keys(baseInfo.value).length
+  // if (infoExist && baseInfo.value[e.key]) e.value = baseInfo.value[e.key]
+  // // 日期相关
+  // if (e.type === 'datepicker') e.value = timesTampChange(e.value).slice(0, 10)
+  // // 所在城市回显
+  // if (infoExist && e.nameKey) e[e.nameKey] = baseInfo.value[e.nameKey]
+})
+
+const getQuery = async () => {
+  const { valid } = await formPageRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  items.value.options.forEach(e => {
+    if (Object.prototype.hasOwnProperty.call(e, 'data')) return obj[e.key] = e.data
+    obj[e.key] = e.value
+  })
+  query = Object.assign(query, obj)
+  return query
+}
+
+defineExpose({
+  getQuery
+})
+</script>

+ 89 - 0
src/views/recruit/personal/shareJob/form/upload.vue

@@ -0,0 +1,89 @@
+<template>
+  <div style="width: 100%;">
+    <CtForm ref="formPageRef" :items="items"></CtForm>
+  </div>
+</template>
+
+<script setup>
+defineOptions({name: 'shareJob-form-upload'})
+import { reactive, ref, defineExpose } from 'vue'
+import { useI18n } from '@/hooks/web/useI18n'
+import { uploadFile } from '@/api/common'
+import Snackbar from '@/plugins/snackbar'
+
+const { t }  = useI18n()
+const formPageRef = ref()
+let query = reactive({})
+
+// 上传简历
+const typeList = ['pdf', 'doc', 'docx']
+const handleUpload = async (e) => {
+  const file = e
+  const size = file.size
+  if (size / (1024*1024) > 10) {
+    Snackbar.warning(t('common.fileSizeExceed'))
+    return
+  }
+  const arr = file.name.split('.')
+  if (typeList.indexOf(arr[arr.length - 1]) < 0) {
+    Snackbar.warning(t('common.fileFormatIncorrect'))
+    return
+  }
+  const formData = new FormData()
+  formData.append('file', file)
+  const { data } = await uploadFile(formData)
+  if (!data) return
+  const urlItem = items.value.options.find(e => e.key === 'url')
+  if (urlItem) urlItem.data = data
+  query.fileName = file.name
+}
+
+const items = ref({
+  options: [
+    // {
+    //   type: 'text',
+    //   key: 'name',
+    //   value: '',
+    //   clearable: true,
+    //   label: '姓名 *',
+    //   rules: [v => !!v || '请填写姓名']
+    // },
+    // {
+    //   type: 'text',
+    //   key: 'phone',
+    //   value: '',
+    //   clearable: true,
+    //   label: '手机号码 *',
+    //   rules: [v => !!v || '请填写手机号码']
+    // },
+    {
+      type: 'upload',
+      key: 'url',
+      value: null,
+      data: '',
+      label: '简历 *',
+      accept: '.doc, .docx, .pdf',
+      placeholder: '请上传简历',
+      rules: [v => !!v || '请上传简历'],
+      change: handleUpload
+    }
+  ]
+})
+
+
+const getQuery = async () => {
+  const { valid } = await formPageRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  items.value.options.forEach(e => {
+    if (Object.prototype.hasOwnProperty.call(e, 'data')) return obj[e.key] = e.data
+    obj[e.key] = e.value
+  })
+  query = Object.assign(query, obj)
+  return query
+}
+
+defineExpose({
+  getQuery
+})
+</script>

+ 86 - 27
src/views/recruit/personal/shareJob/index.vue

@@ -62,21 +62,48 @@
         </div>
         <div class="text-center my-10">
           <v-btn class="mr-2 radius button-item" color="success" variant="outlined" target="_blank" to="/recruit/personal/position">{{ $t('position.moreBtn') }}</v-btn>
-          <v-btn class="radius button-item" color="primary" :disabled="delivery" @click="handleDelivery">{{ delivery ? $t('position.delivered') : $t('position.submitResume') }}</v-btn>
+          <v-btn class="radius button-item" color="primary" :disabled="delivery" @click="sendResumeProcessVerify">{{ delivery ? $t('position.delivered') : $t('position.submitResume') }}</v-btn>
         </div>
       </div>
     </v-card>
+
+    <!-- 快速登录/注册 -->
+    <login-page
+      v-if="sendResume.showLogin"
+      :jobId="jobId"
+      @loginSuccess="loginSuccess"
+      @close="handleClose('showLogin')"
+    ></login-page>
+
+    <!-- 快速填写简易人才信息 -->
+    <simple-page
+      v-if="sendResume.showSimpleInfo"
+      @simpleInfoReady="simpleInfoReadyFun"
+      @close="handleClose('showSimpleInfo')"
+    ></simple-page>
+
+    <!-- 选择简历 -->
+    <select-page
+      v-if="sendResume.showSelect"
+      :hire="info?.hire"
+      :jobId="jobId"
+      :userId="sharedById"
+      @refresh="handleCheckJobDelivery"
+      @close="handleClose('showSelect')"
+      ref="selectRef"
+    ></select-page>
+
     <!-- 简历投递 -->
-    <handleDeliveryCom
+    <!-- <handleDeliveryCom
       v-if="showHandleDelivery"
       :jobId="jobId"
       :hire="info?.hire"
       :userId="sharedById"
       :baseInfo="baseInfo"
       @refresh="handleCheckJobDelivery"
-    ></handleDeliveryCom>
+    ></handleDeliveryCom> -->
     <!-- 快速登录 -->
-    <CtDialog
+    <!-- <CtDialog
       :visible="showQuickResumeDialog"
       :widthType="2"
       :footer="false"
@@ -85,17 +112,20 @@
       @close="showQuickResumeDialog = false"
     >
       <quickLogin :jobId="jobId" @loginSuccess="loginSuccess"></quickLogin>
-    </CtDialog>
+    </CtDialog> -->
   </div>
 </template>
 
 <script setup>
 defineOptions({name: 'recruit-personal-shareJob-index'})
-import { onMounted, ref } from 'vue';
+import loginPage from './components/login.vue'
+import simplePage from './sendResume/simple.vue'
+import selectPage from './sendResume/select.vue'
+import { onMounted, reactive, ref } from 'vue';
 import { getPositionDetails, jobCvRelCheckSend, getPersonJobUnfavorite, getPersonJobFavorite, getJobFavoriteCheck } from '@/api/position'
 import { dealDictObjData } from '@/utils/position'
-import handleDeliveryCom from './components/handleDeliveryCom.vue'
-import quickLogin from './components/quickLogin.vue'
+// import handleDeliveryCom from './components/handleDeliveryCom.vue'
+// import quickLogin from './components/quickLogin.vue'
 import { getPersonalToken } from '@/utils/auth'
 import Snackbar from '@/plugins/snackbar'
 import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
@@ -136,17 +166,18 @@ const getCollectionStatus = async () => {
   isCollection.value = data
 }
 
-const handleLogin = () => {
-  showQuickResumeDialog.value = true
-  showHandleDelivery.value = !showQuickResumeDialog.value
-}
+// const handleLogin = () => {
+//   showQuickResumeDialog.value = true
+//   showHandleDelivery.value = !showQuickResumeDialog.value
+// }
 
 // 收藏&取消收藏职位
 const handleCollection = async () => {
   // 效验登录状态
   if (!getPersonalToken()) {
     actions.value = true
-    handleLogin()
+    // handleLogin()
+    sendResume.showLogin = true
     return
   }
   if (!jobId) return
@@ -175,20 +206,10 @@ const desc = [
   { mdi: 'mdi-clock-time-ten-outline', value: 'expName' }
 ]
 
-// handleClick 投递简历
-const showQuickResumeDialog = ref(false)
-const showHandleDelivery = ref(false)
-const handleDelivery = () => {
-  if (getPersonalToken()) {
-    showHandleDelivery.value = true
-    showQuickResumeDialog.value = !showHandleDelivery.value
-  } else handleLogin()
-}
 
 // 快速登录成功
-const baseInfo = ref({ baseInfoReady: false, baseInfo: {}, keyArr: [] })
-const loginSuccess = async (info) => {
-  showQuickResumeDialog.value = false // 关闭快速登录弹窗
+const loginSuccess = async () => {
+  sendResume.showLogin = false // 关闭快速登录弹窗
   // actions为true则是收藏时的登录,不需要弹窗选择简历
   if (actions.value) {
     actions.value = false
@@ -198,8 +219,46 @@ const loginSuccess = async (info) => {
   }
   const bool = await handleCheckJobDelivery()
   if (bool) return Snackbar.warning(t('resume.alreadyResume'))
-  baseInfo.value = info
-  showHandleDelivery.value = true // 校验流程
+  sendResumeProcessVerify()
+}
+
+// 简易人才信息
+const simpleInfoReady = ref(false)
+const simpleInfoReadyFun = () => {
+  sendResume.showSimpleInfo = false
+  simpleInfoReady.value = true
+  sendResumeProcessVerify()
+}
+const sendResume = reactive({
+  showLogin: false,
+  showSimpleInfo: false,
+  showSelect: false,
+})
+
+// 流程校准
+const sendResumeProcessVerify = async () => {
+  try { // 1.登录 2.具备人才信息 3.有无附件简历,无则上传
+    // 未登录
+    if (!getPersonalToken()) {
+      sendResume.showLogin = true
+      return
+    }
+    // 已登录
+    // * 必填人才信息不完全 -> 不符合快速投递,进入完善人才信息流程
+    if (!simpleInfoReady.value) {
+      sendResume.showSimpleInfo = true
+      return
+    }
+    // * 简历列表
+    // if (!) sendResume.showSelect = true
+    sendResume.showSelect = true
+  } catch (error) {
+    console.error('error', error)
+  }
+}
+
+const handleClose = (key) => {
+  sendResume[key] = false // 弹窗关闭,重置绑定数据
 }
 </script>
 

+ 0 - 10
src/views/recruit/personal/shareJob/sendResume/form/baseInfo.vue

@@ -1,10 +0,0 @@
-<!--  -->
-<template>
-  <div>vue3PageInit</div>
-</template>
-
-<script setup>
-defineOptions({name: 'shareJob-form-baseInfo'})
-</script>
-<style lang="scss" scoped>
-</style>

+ 0 - 10
src/views/recruit/personal/shareJob/sendResume/form/upload.vue

@@ -1,10 +0,0 @@
-<!--  -->
-<template>
-  <div>vue3PageInit</div>
-</template>
-
-<script setup>
-defineOptions({name: 'shareJob-form-upload'})
-</script>
-<style lang="scss" scoped>
-</style>

+ 95 - 1
src/views/recruit/personal/shareJob/sendResume/select.vue

@@ -1,10 +1,104 @@
 <!-- 选择简历 -->
 <template>
-  <div>vue3PageInit</div>
+  <selectResumeDialog
+    v-model="showResume"
+    :list="resumeList"
+    :selectLocalFile="true"
+    @selectLocalFile="selectLocalFileClick"
+    @submit="handleSubmit"
+    @close="handleClose"
+  ></selectResumeDialog>
+  <CtDialog
+    :visible="openUploadDialog"
+    :widthType="2"
+    titleClass="text-h6"
+    @close="openUploadDialog = false"
+    title="选择本地简历"
+    @submit="uploadFileSubmit"
+  >
+    <uploadForm ref="uploadFormRef"></uploadForm>
+    <div class="color-error" style="font-size: 13px;">* 点击下方提交按钮即 将已上传的简历进行投递</div>
+  </CtDialog>
 </template>
 
 <script setup>
+// 上传附件
+import uploadForm from '../form/upload.vue'
+import { savePersonResumeCv } from '@/api/resume'
+// 选择简历
+import selectResumeDialog from '@/views/recruit/personal/position/components/jobDetails/selectResumeDialog'
+import { hireJobCvDelivery } from '@/api/recruit/personal/shareJob'
+import { jobCvRelSend } from '@/api/position'
+import { getPersonResumeCv } from '@/api/resume'
+import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
+import Snackbar from '@/plugins/snackbar'
+import { ref } from 'vue'
 defineOptions({name: 'shareJob-sendResume-select'})
+const emit = defineEmits(['refresh', 'close'])
+const props = defineProps({
+  jobId: {
+    type: String,
+    default: ''
+  },
+  hire: {
+    type: Boolean,
+    default: false
+  },
+  userId: {
+    type: String,
+    default: ''
+  },
+})
+
+const resumeList = ref([])
+const getResumeList = async () => {
+  const data = await getPersonResumeCv()
+  if (!data?.length) {
+    openUploadDialog.value = true
+  }
+  resumeList.value = data
+  showResume.value = true
+}
+getResumeList()
+
+const uploadFormRef = ref()
+const openUploadDialog = ref(false)
+// 上传附件-提交
+const uploadFileSubmit = async () => {
+  const obj = await uploadFormRef.value.getQuery()
+  await savePersonResumeCv({ title: obj.fileName, url: obj.url })
+  handleSubmit(obj, '上传的文件提交_直接投递')
+}
+
+const selectLocalFileClick = () => {
+  openUploadDialog.value = true
+}
+
+const showResume = ref(false)
+const selectResume = ref()
+const handleSubmit = async (val, type = '') =>{
+  selectResume.value = val
+  if (!selectResume.value) return Snackbar.warning(t('resume.selectResumeToSubmit'))
+  const obj = type ? val : resumeList.value.find(e => e.id === selectResume.value)
+  if (!obj && !type) return Snackbar.warning(t('resume.selectedResumeNotExist'))
+
+  // 区分普通职位跟众聘职位投递
+  if (props.hire) await hireJobCvDelivery({ jobId: props.jobId, recommendUserId: props.userId, url: obj.url })
+  else await jobCvRelSend({ jobId: props.jobId, title: obj.title, url: obj.url })
+  Snackbar.success(t('resume.deliverySuccess'))
+  // setTimeout(() => {
+  // }, 3000)
+  emit('refresh')
+  handleClose()
+}
+
+const handleClose = () => {
+  showResume.value = false
+  openUploadDialog.value = false
+  selectResume.value = null
+  emit('close')
+}
+
 </script>
 <style lang="scss" scoped>
 </style>

+ 66 - 0
src/views/recruit/personal/shareJob/sendResume/simple.vue

@@ -0,0 +1,66 @@
+<!-- 快速填写-简易人才信息 -->
+<template>
+  <CtDialog
+    :visible="openDialog"
+    :widthType="2"
+    :footer="false"
+    titleClass="text-h6"
+    title="快速填写"
+    @close="openDialog = false"
+    @submit="simpleInfoSubmit"
+  >
+    <simpleInfoForm ref="formRef"></simpleInfoForm>
+  </CtDialog>
+</template>
+
+<script setup>
+import simpleInfoForm from '../form/simpleInfo.vue'
+import { savePersonSimpleInfo } from '@/api/recruit/personal/shareJob'
+import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
+import Snackbar from '@/plugins/snackbar'
+import { ref } from 'vue'
+defineOptions({name: 'shareJob-sendResume-simple'})
+const emit = defineEmits(['simpleInfoReady'])
+
+const openDialog = ref(false) // 默认不打开弹窗,先检验simpleInfoReady
+const info = ref(null)
+
+// 查询用户基本信息
+const timer = ref(null)
+timer.value = setInterval(() => { getUserInfoVerify() }, 1000)
+// 十秒后停止获取清除timer
+setTimeout(() => { if (!info.value) getUserInfoFail() }, 10000);
+
+// 查询用户基本信息
+const getUserInfoVerify = () => {
+  if (info.value) {
+    clearInterval(timer.value); timer.value = null
+    const keyArr = ['name', 'phone', 'jobStatus', 'expType', 'eduType'] // 必填人才信息
+    const simpleInfoReady = keyArr.every(e => info.value[e] && info.value[e] !== 0) // 校验必填人才信息
+    if (simpleInfoReady) emit('simpleInfoReady') // 存在
+    else openDialog.value = true // 不存在
+  }
+  info.value = JSON.parse(localStorage.getItem('baseInfo'))
+}
+
+// 查询用户基本信息-失败 
+const getUserInfoFail = () => {
+  clearInterval(timer.value); timer.value = null
+  Snackbar.success(t('login.getUserInfoFailed')+','+t('login.loginAgain'))
+}
+
+const formRef = ref()
+const simpleInfoSubmit = async () => {
+  try {
+    const obj = await formRef.value.getQuery()
+    await savePersonSimpleInfo(obj)
+    localStorage.setItem('simpleInfo', JSON.stringify(obj))
+    openDialog.value = false
+    emit('simpleInfoReady')
+  } catch (error) {
+    console.error('error', error)
+  }
+}
+</script>
+<style lang="scss" scoped>
+</style>

+ 27 - 2
src/views/recruit/personal/shareJob/sendResume/upload.vue

@@ -1,10 +1,35 @@
-<!-- 上传简历 -->
+<!-- 上传简历(弃用) -->
 <template>
-  <div>vue3PageInit</div>
+  <CtDialog
+    :visible="openDialog"
+    :widthType="2"
+    titleClass="text-h6"
+    @close="openDialog = false"
+    title="选择本地简历"
+    @submit="uploadFileSubmit"
+  >
+    <uploadForm ref="formRef"></uploadForm>
+    <div class="color-error" style="font-size: 13px;">* 点击下方提交按钮即 将已上传的简历进行投递</div>
+  </CtDialog>
 </template>
 
 <script setup>
+import uploadForm from '../form/upload.vue'
+import { savePersonResumeCv } from '@/api/resume'
+import { nextTick, ref } from 'vue'
 defineOptions({name: 'shareJob-sendResume-upload'})
+const emit = defineEmits(['uploadSuccess'])
+const openDialog = ref(false)
+nextTick(() => {
+  openDialog.value = true
+})
+
+const formRef = ref()
+const uploadFileSubmit = async () => {
+  const obj = await formRef.value.getQuery()
+  await savePersonResumeCv({ title: obj.fileName, url: obj.url })
+  emit('uploadSuccess', obj)
+}
 </script>
 <style lang="scss" scoped>
 </style>

+ 27 - 0
src/views/recruit/personal/shareJob/until/send.js

@@ -0,0 +1,27 @@
+
+import { hireJobCvDelivery } from '@/api/recruit/personal/shareJob'
+import { jobCvRelSend } from '@/api/position'
+
+export const sendResumeUntil = async (query) => {
+  const {
+    hire = false,
+    recommendUserId = '',
+    jobId = '',
+    url = '',
+    title = '',
+  } = query
+
+  try {
+    // 区分普通职位跟众聘职位投递
+    const api = hire ? jobCvRelSend : hireJobCvDelivery
+    const params = hire ? {
+      jobId, recommendUserId, url
+    } : {
+      jobId, title, url
+    }
+    const data = await api(params)
+    return data
+  } catch (error) {
+    console.error(error.msg)
+  }
+}