Преглед изворни кода

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner into dev

lifanagju_citu пре 7 месеци
родитељ
комит
ada65240d5

+ 1 - 1
src/components/Upload/file.vue

@@ -43,7 +43,7 @@ const handleUploadFile = async (e) => {
   formData.append('file', file)
   const { data } = await uploadFile(formData)
   if (!data) return
-  emits('success', data, arr[0])
+  emits('success', data, arr[0], file.name)
 }
 
 defineExpose({

+ 4 - 2
src/components/headSearch/index.vue

@@ -35,7 +35,8 @@
         style="height: 100%; line-height: 100%;"
         @keyup.enter="handleSearch"
       ></v-text-field>
-      <div class="searchBtn" @click="handleSearch">搜索</div>
+      <!-- <div class="searchBtn" @click="handleSearch">搜索</div> -->
+      <v-btn class="searchBtn" @click="handleSearch">搜索</v-btn>
     </div>
   </div>
 </template>
@@ -117,7 +118,8 @@ const handleClickJob = (val) => {
   }
   .searchBtn {
     width: 100px;
-    height: 50px; line-height: 48px;
+    height: 50px;
+    line-height: 48px;
     text-align: center;
     font-size: 18px;
     color: #fff;

+ 5 - 12
src/views/login/components/editPassword.vue

@@ -23,7 +23,7 @@
         prepend-inner-icon="mdi-lock-outline" 
         :append-inner-icon="show ? 'mdi-eye-outline' : 'mdi-eye-off-outline'"
         :type="show ? 'text' : 'password'"
-        :rules="secondaryConfirmation"
+        :rules="[v=> !!v || '请再次输入密码', confirmPassword]"
         @click:append-inner="show = !show"
       ></v-text-field>
     </v-form>
@@ -67,23 +67,16 @@ const loading = ref(false)
 const passwordType = ref(false)
 const phoneRef = ref()
 
-const secondaryConfirmation = ref([
-  value => {
-    if (value) return true
-    return '请再次输入密码'
-  },
-  value => {
-    if (value === query.password) return true
-    return '两次输入密码不一致'
-  }
-])
-
 // 密码效验
 const regex = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}$/
 const validPassword = computed(() => {
   return regex.test(query.password) || '请输入8-16位数由数字、大小写字母组成的密码'
 })
 
+const confirmPassword = computed(() => {
+  return query.checkPassword === query.password || '两次输入密码不一致'
+})
+
 
 const handleClose = () => {
   query = {

+ 7 - 6
src/views/login/index.vue

@@ -1,15 +1,15 @@
 <template>
   <div class="login-box">
     <div class="login-content">
-      <div class="text-end pr-5 pt-5">
+      <!-- <div class="text-end pr-5 pt-5">
         <span class="color-error cursor-pointer text-decoration-underline" @click="router.push('/register/selected')">还没有登录账户?去注册</span>
-      </div>
-      <div class="login-content-box mb-10">
+      </div> -->
+      <div class="login-content-box my-10">
         <div class="login-tab">
           <v-tabs v-model="tab" align-tabs="center" color="primary" class="mb-10">
             <v-tab :value="1">验证码</v-tab>
             <v-tab :value="2">账号</v-tab>
-            <v-tab :value="3">二维码</v-tab>
+            <!-- <v-tab :value="3">二维码</v-tab> -->
           </v-tabs>
           <v-window v-model="tab">
               <!-- 验证码登录 -->
@@ -20,16 +20,17 @@
             <v-window-item :value="2">
               <passwordFrom ref="passRef" @handleEnter="handleLogin"></passwordFrom>
             </v-window-item>
-            <v-window-item :value="3">
+            <!-- <v-window-item :value="3">
               <div class="d-flex align-center flex-column">
                 <span class="text-decoration-underline">微信扫描二维码进行登录</span>
                 <v-img src="https://minio.citupro.com/dev/menduner/login-qrCode.png" width="150" height="150"></v-img>
               </div>
-            </v-window-item>
+            </v-window-item> -->
           </v-window>
         </div>
         <div class="font-size-14 tips">
           <span class="float-left color-666 cursor-pointer" v-if="tab === 2" @click="router.push('/forgotPassword')">忘记密码</span>
+          <span class="float-right color-error cursor-pointer text-decoration-underline" @click="router.push('/register/selected')">还没有登录账户?去注册</span>
         </div>
         <v-btn :loading="loginLoading" color="primary" class="white--text mt-5" min-width="350" @click="handleLogin">
           {{ $t('login.login') }}

+ 68 - 10
src/views/recruit/components/message/index.vue

@@ -123,7 +123,24 @@
     </div>
   </div>
 
-  <File ref="uploadFile" @success="handleUploadResume"></File>
+  <!-- 附件上传 -->
+  <CtDialog
+    :visible="showUploadDialog"
+    :widthType="2"
+    :footer="true"
+    title="附件简历上传"
+    titleClass="text-h6"
+    @close="showUploadDialog = false"
+    @submit="handleSubmitAttachment"
+  >
+    <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文件</div>
+  </CtDialog>
 
   <CtDialog :visible="showInvite" :widthType="2" titleClass="text-h6" title="邀请面试" @close="showInvite = false" @submit="handleSubmit">
     <InvitePage v-if="showInvite" ref="inviteRef" :item-data="itemData" :position="positionList"></InvitePage>
@@ -192,10 +209,31 @@ const itemData = ref({})
 const inviteRef = ref()
 
 // 发送简历
-const uploadFile = ref()
 const showResume = ref(false)
 const resumeList = ref([])
 const selectResume = ref(null)
+// 上传附件简历
+const CtFormRef = ref()
+const formItems = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'title',
+      value: '',
+      label: '附件简历名称 *',
+      rules: [v => !!v || '请输入附件简历名称']
+    },
+    {
+      slotName: 'uploadFile',
+      key: 'url',
+      value: '',
+      truthValue: '',
+      label: '点击上传附件简历 *',
+      outline: true,
+      rules: [v => !!v || '请上传您的附件简历']
+    }
+  ]
+})
 
 // 求职者面试列表
 const interview = ref([])
@@ -328,16 +366,29 @@ const handleUpdate = (val) => {
   send(val.value, channelItem.value)
 }
 
+// 选择文件
+const uploadFile = ref()
+const openFileInput = () => {
+  uploadFile.value.trigger()
+}
+
+// 上传附件
+const handleUploadResume = async (url, title, filename) => {
+  const obj = formItems.value.options.find(e => e.key === 'url')
+  obj.value = filename
+  obj.truthValue = url
+}
+
 // 获取简历
+const showUploadDialog = ref(false)
 async function handleSendResume (item) {
   try {
     item.loading = true
-    // showResume.value = true
     // 获取简历列表
     const result = await getPersonResumeCv()
     if (result.length === 0) {
-      Snackbar.error(t('resume.resumeYetSubmit'))
-      uploadFile.value.trigger()
+      Snackbar.warning(t('resume.resumeYetSubmit'))
+      showUploadDialog.value = true
       return
     }
     resumeList.value = result
@@ -360,14 +411,21 @@ async function handleSendResume (item) {
  */
 
 // 没有上传过简历的弹窗上传并发送给对方
-const handleUploadResume = async (url, title) => {
-  if (!url || !title) return
-  await savePersonResumeCv({ title, url })
+const handleSubmitAttachment = async () => {
+  const { valid } = await CtFormRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  formItems.value.options.forEach(e => {
+    obj[e.key] = e.truthValue || e.value
+  })
+  if (!obj.title || !obj.url) return
+  await savePersonResumeCv(obj)
+  showUploadDialog.value = false
   const text = {
     remark: '发送简历',
     query: {
-      src: url,
-      title
+      src: obj.url,
+      title: obj.title
     },
     type: 1
   }

+ 9 - 9
src/views/recruit/entRegister/register.vue

@@ -146,15 +146,15 @@ const formItems = ref({
       type: 'text',
       key: 'email',
       value: email ? email : '',
-      label: '联系邮箱(可用于企业招聘登录) *',
+      label: '企业邮箱 *',
       rules: [
         value => {
           if (value) return true
-          return '请输入联系邮箱'
+          return '请输入企业邮箱'
         },
         value => {
           if (checkEmail(value)) return true
-          return '请输入正确的电子邮箱'
+          return '请输入正确的企业邮箱'
         }
       ]
     },
@@ -163,13 +163,13 @@ const formItems = ref({
       key: 'password',
       value: '',
       appendInnerIcon: 'mdi-eye-off-outline',
-      label: '邮箱登录密码(用于企业招聘邮箱登录) *',
-      placeholder: '请输入邮箱登录密码(用于企业招聘邮箱登录)',
+      label: '账户登录密码 *',
+      placeholder: '请输入账户登录密码',
       appendInnerClick: handlePassword,
       rules: [
         value => {
           if (value) return true
-          return '请输入邮箱登录密码(用于企业招聘邮箱登录)'
+          return '请输入账户登录密码'
         },
         value => {
           if (/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}$/.test(value)) return true
@@ -182,13 +182,13 @@ const formItems = ref({
       key: 'passwordConfirm',
       value: '',
       appendInnerIcon: 'mdi-eye-off-outline',
-      label: '请再次输入邮箱登录密码 *',
-      placeholder: '请再次输入邮箱登录密码',
+      label: '请再次输入账户登录密码 *',
+      placeholder: '请再次输入账户登录密码',
       appendInnerClick: handleSecondConfirm,
       rules: [
         value => {
           if (value) return true
-          return '请再次输入密码(用于企业招聘邮箱登录)'
+          return '请再次输入密码'
         },
         value => {
           if (value === formItems.value.options.find(e => e.key === 'password').value) return true

+ 8 - 2
src/views/recruit/enterprise/hirePosition/components/baseInfo.vue

@@ -32,7 +32,7 @@
           </template>
           <jobTypeCard class="jobTypeCardBox" :select="[query.positionId].filter(Boolean)" :isSingle="true" @handleJobClick="handleJobClickItem"></jobTypeCard>
         </v-menu>
-        <v-btn class="ml-3 half-button" color="primary" style="margin-top: 2px;" @click="useJobTemplate(item)">岗位模板</v-btn>
+        <v-btn v-if="showTemplateBtn" class="ml-3 half-button" color="primary" style="margin-top: 2px;" @click="useJobTemplate(item)">岗位模板</v-btn>
       </template>
     </CtForm>
 
@@ -56,6 +56,7 @@ const props = defineProps({
   itemData: Object
 })
 
+const showTemplateBtn = ref(true)
 const show = ref(false)
 const ratio = ref({})
 
@@ -168,6 +169,7 @@ const handleJobClickItem = (list, name) => {
     positionId.value = ''
     return
   }
+  showTemplateBtn.value = true
   query.positionId = list[0]
   positionId.value = name
 }
@@ -180,7 +182,11 @@ const useJobTemplate = async () => {
   if (!query.positionId) return Snackbar.warning('请先选择职位类型')
   // 获取职位模板内容-赋值
   const res = await getRecruitPositionDetails(query.positionId)
-  if (!res || !res.content || !res.requirement) return Snackbar.warning('此职位类型没有可使用的模板!')
+  if (!res || !res.content || !res.requirement) {
+    Snackbar.warning('此职位类型没有可使用的模板!')
+    showTemplateBtn.value = false
+    return
+  }
   const content =  items.value.options.find(e => e.key === 'content')
   const requirement =  items.value.options.find(e => e.key === 'requirement')
   if ((content && content.value) || (requirement && requirement.value)) {

+ 1 - 1
src/views/recruit/enterprise/interviewManagement/components/invite.vue

@@ -1,5 +1,5 @@
 <template>
-  <CtForm ref="CtFormRef" :items="formItems" style="height: 420px;">
+  <CtForm ref="CtFormRef" :items="formItems" style="height: 500px;">
     <template #time="{ item }">
       <VueDatePicker 
         v-model="item.value"

+ 1 - 1
src/views/recruit/enterprise/personnelManagement/components/invite.vue

@@ -1,5 +1,5 @@
 <template>
-  <CtForm ref="CtFormRef" :items="formItems" style="height: 420px;">
+  <CtForm ref="CtFormRef" :items="formItems" style="height: 500px;">
     <template #time="{ item }">
       <VueDatePicker 
         v-model="item.value"

+ 12 - 6
src/views/recruit/enterprise/positionManagement/components/baseInfo.vue

@@ -13,7 +13,7 @@
           </template>
           <jobTypeCard class="jobTypeCardBox" :select="[query.positionId].filter(Boolean)" :isSingle="true" @handleJobClick="handleJobClickItem"></jobTypeCard>
         </v-menu>
-        <v-btn class="ml-3 half-button" color="primary" style="margin-top: 2px;" @click="useJobTemplate(item)">岗位模板</v-btn>
+        <v-btn v-if="showTemplateBtn" class="ml-3 half-button" color="primary" style="margin-top: 2px;" @click="useJobTemplate(item)">岗位模板</v-btn>
       </template>
     </CtForm>
   </div>
@@ -26,7 +26,11 @@ import { reactive, ref, watch } from 'vue'
 import textUI from '@/components/FormUI/TextInput'
 import jobTypeCard from '@/components/jobTypeCard'
 import { getRecruitPositionDetails } from '@/api/recruit/enterprise/position'
+import Confirm from '@/plugins/confirm'
+import Snackbar from '@/plugins/snackbar'
+import { useI18n } from '@/hooks/web/useI18n';
 
+const { t } = useI18n()
 const props = defineProps({
   itemData: Object
 })
@@ -35,6 +39,7 @@ const getValue = (key) => {
   return items.value.options.find(e => e.key === key)
 }
 
+const showTemplateBtn = ref(true)
 const formPageRef = ref()
 let query = reactive({})
 
@@ -113,19 +118,20 @@ const handleJobClickItem = (list, name) => {
     positionId.value = ''
     return
   }
+  showTemplateBtn.value = true
   query.positionId = list[0]
   positionId.value = name
 }
 
-// 岗位模板
-import Confirm from '@/plugins/confirm'
-import Snackbar from '@/plugins/snackbar'
-import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
 const useJobTemplate = async () => {
   if (!query.positionId) return Snackbar.warning('请先选择职位类型')
   // 获取职位模板内容-赋值
   const res = await getRecruitPositionDetails(query.positionId)
-  if (!res || !res.content || !res.requirement) return Snackbar.warning('此职位类型没有可使用的模板!')
+  if (!res || !res.content || !res.requirement) {
+    Snackbar.warning('此职位类型没有可使用的模板!')
+    showTemplateBtn.value = false
+    return
+  }
   const content =  items.value.options.find(e => e.key === 'content')
   const requirement =  items.value.options.find(e => e.key === 'requirement')
   if ((content && content.value) || (requirement && requirement.value)) {

+ 7 - 1
src/views/recruit/enterprise/positionManagement/components/item.vue

@@ -33,7 +33,13 @@
           </div>
         </div>
         <div class="d-flex align-center">
-          <v-btn v-if="tab === 1" class="ml-3" color="primary" @click="handleAction(2, '', val)">{{ $t('common.refresh') + $t('common.position') }}</v-btn>
+          <v-tooltip text="刷新职位后,发布时间为最新的">
+            <template v-slot:activator="{ props }">
+              <v-btn v-if="tab === 1" class="ml-3" v-bind="props" color="primary" @click="handleAction(2, '', val)" append-icon="mdi-help-circle-outline">
+                {{ $t('common.refresh') + $t('common.position') }}
+              </v-btn>
+            </template>
+          </v-tooltip>
           <v-btn v-if="tab === 2" color="primary" @click="handleAction(1, '', val)">{{ $t('common.activatePosition') }}</v-btn>
         </div>
       </div>

+ 1 - 1
src/views/recruit/enterprise/resume/components/invite.vue

@@ -1,5 +1,5 @@
 <template>
-  <CtForm ref="CtFormRef" :items="formItems">
+  <CtForm ref="CtFormRef" :items="formItems" style="height: 500px;">
     <template #time="{ item }">
       <VueDatePicker 
         v-model="item.value"

+ 1 - 1
src/views/recruit/enterprise/resume/components/public.vue

@@ -1,5 +1,5 @@
 <template>
-  <CtForm ref="CtFormRef" :items="formItems">
+  <CtForm ref="CtFormRef" :items="formItems" style="height: 500px;">
     <template #time="{ item }">
       <VueDatePicker 
         v-model="item.value"

+ 1 - 1
src/views/recruit/enterprise/resume/components/table.vue

@@ -33,7 +33,7 @@
         <v-btn v-if="tab === 0" color="primary" variant="text" @click="handleInterviewInvite(item)">邀请面试</v-btn>
         <v-btn v-if="tab === 0" color="primary" variant="text" @click="handleToCommunicate(item)">立即沟通</v-btn>
         <v-btn v-if="tab === 0 || tab === 1" color="primary" variant="text" @click="handleEliminate(item)">不合适</v-btn>
-        <v-btn v-if="!item.inTalentPool && (tab === 1 || tab === 2 || tab === 3)" color="primary" variant="text" @click="handleJoinToTalentPool(item)">加入精英储备</v-btn>
+        <v-btn v-if="!item.inTalentPool && (tab === 1 || tab === 2 || tab === 3)" color="primary" variant="text" @click="handleJoinToTalentPool(item)">加入储备</v-btn>
         <v-btn v-if="tab === 1 && (item.status === '3' || item.status === '4')" color="primary" variant="text" @click="handleEnterByEnterprise(item)">入职</v-btn>
         <v-btn v-if="tab === 4" color="primary" variant="text" @click="handleCancelEliminate(item)">取消不合适</v-btn>
         <v-btn v-if="tab === 2 && item?.job?.hire" color="primary" variant="text" @click="handleSettlement(item)">结算</v-btn>

+ 78 - 12
src/views/recruit/personal/PersonalCenter/resume/attachment/index.vue

@@ -1,11 +1,8 @@
 <template>
-  <div class="resume-box">
+  <div class="resume-box" style="position: relative; height: 100%;">
     <div class="resume-header">
       <div class="resume-title">附件简历</div>
-      <v-btn variant="text" color="primary" prepend-icon="mdi-plus-box" @click="openFileInput">
-        上传
-        <File ref="uploadFile" @success="handleUploadResume"></File>
-      </v-btn>
+      <v-btn variant="text" color="primary" prepend-icon="mdi-plus-box" @click="handleAdd">上传</v-btn>
     </div>
     <p class="font-size-14 color-999">最多只能上传5份附件简历</p>
     <div v-if="attachmentList.length" class="mt-5">
@@ -24,8 +21,26 @@
         </div>
       </div>
     </div>
-    <div v-else class="resumeNoDataText">请上传您的附件简历</div>
+    <div v-else class="resumeNoDataText tips">请上传您的附件简历</div>
   </div>
+
+  <CtDialog
+    :visible="showUploadDialog"
+    :widthType="2"
+    :footer="true"
+    title="附件简历上传"
+    titleClass="text-h6"
+    @close="showUploadDialog = false"
+    @submit="handleSubmit"
+  >
+    <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文件</div>
+  </CtDialog>
 </template>
 
 <script setup>
@@ -34,12 +49,34 @@ import { ref } from 'vue'
 import Snackbar from '@/plugins/snackbar'
 import Confirm from '@/plugins/confirm'
 import { useI18n } from '@/hooks/web/useI18n'
-import { getPersonResumeCv, savePersonResumeCv, deletePersonResumeCv } from '@/api/recruit/personal/resume'
+import { getPersonResumeCv, deletePersonResumeCv, savePersonResumeCv } from '@/api/recruit/personal/resume'
 import { getBlob, saveAs } from '@/utils'
 import { previewFile } from '@/utils'
 
 const { t } = useI18n()
 
+const CtFormRef = ref()
+const formItems = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'title',
+      value: '',
+      label: '附件简历名称 *',
+      rules: [v => !!v || '请输入附件简历名称']
+    },
+    {
+      slotName: 'uploadFile',
+      key: 'url',
+      value: '',
+      truthValue: '',
+      label: '点击上传附件简历 *',
+      outline: true,
+      rules: [v => !!v || '请上传您的附件简历']
+    }
+  ]
+})
+
 // 获取附件
 const attachmentList = ref([])
 const getList = async () => {
@@ -51,16 +88,39 @@ getList()
 // 选择文件
 const uploadFile = ref()
 const openFileInput = () => {
-  if (attachmentList.value.length >= 5) return Snackbar.warning(t('resume.uploadFiveCopies'))
   uploadFile.value.trigger()
 }
 
 // 上传附件
-const handleUploadResume = async (url, title) => {
-  if (!url || !title) return
-  Snackbar.success(t('common.uploadSucMsg'))
-  await savePersonResumeCv({ title, url })
+const handleUploadResume = async (url, title, filename) => {
+  const obj = formItems.value.options.find(e => e.key === 'url')
+  obj.value = filename
+  obj.truthValue = url
+}
+
+const showUploadDialog = ref(false)
+const handleAdd = () => {
+  if (attachmentList.value.length >= 5) return Snackbar.warning(t('resume.uploadFiveCopies'))
+  formItems.value.options.forEach(e => {
+    e.value = ''
+    e.truthValue = ''
+  })
+  showUploadDialog.value = true
+}
+
+// 上传附件
+const handleSubmit = async () => {
+  const { valid } = await CtFormRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  formItems.value.options.forEach(e => {
+    obj[e.key] = e.truthValue || e.value
+  })
+  if (!obj.title || !obj.url) return
+  await savePersonResumeCv(obj)
   getList()
+  showUploadDialog.value = false
+  Snackbar.success(t('common.uploadSucMsg'))
 }
 
 // 删除
@@ -98,4 +158,10 @@ const handleDownload = (k) => {
     color: var(--color-999);
   }
 }
+.tips {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
 </style>

+ 68 - 27
src/views/recruit/personal/position/components/details.vue

@@ -99,7 +99,23 @@
     </div>
 
     <!-- 简历上传 -->
-    <File ref="uploadFile" @success="handleUploadResume"></File>
+    <CtDialog
+      :visible="showUploadDialog"
+      :widthType="2"
+      :footer="true"
+      title="附件简历上传"
+      titleClass="text-h6"
+      @close="showUploadDialog = false"
+      @submit="handleUploadSubmit"
+    >
+      <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文件</div>
+    </CtDialog>
 
     <!-- 选择简历 -->
     <selectResumeDialog v-model="showResume" :list="resumeList" @submit="handleSubmit" @close="handleClose"></selectResumeDialog>
@@ -112,7 +128,6 @@
     >
       <div>
         <div class="mb-3">微信分享:保存图片分享给好友</div>
-        <!-- <div class="mb-3">方式一:保存图片分享给好友</div> -->
         <div class="d-flex align-center flex-column">
           <v-img :src="previewSrc" width="200" height="250"></v-img>
           <div class="mt-5">
@@ -121,13 +136,6 @@
           </div>
         </div>
       </div>
-      <!-- <div class="mt-10">
-        <div class="mb-3">方式二:复制以下链接分享给好友</div>
-        <div class="pa-4" style="background-color: #f0f0f0; border-radius: 8px;">{{ shareUrlTxt }}</div>
-        <div class="text-center">
-          <v-btn class="mt-5 ml-3" color="primary" variant="outlined" v-clipboard="() => shareUrlTxt" @click="copyText">点击复制分享链接</v-btn>
-        </div>
-      </div> -->
       <template #footer>
         <v-divider></v-divider>
         <div>
@@ -178,6 +186,29 @@ const loading = ref(false)
 const showLogin = ref(false)
 const previewSrc = ref('')
 const showPreview = ref(false)
+// 附件简历上传
+const CtFormRef = ref()
+const showUploadDialog = ref(false)
+const formItems = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'title',
+      value: '',
+      label: '附件简历名称 *',
+      rules: [v => !!v || '请输入附件简历名称']
+    },
+    {
+      slotName: 'uploadFile',
+      key: 'url',
+      value: '',
+      truthValue: '',
+      label: '点击上传附件简历 *',
+      outline: true,
+      rules: [v => !!v || '请上传您的附件简历']
+    }
+  ]
+})
 
 const share = ref()
 // 生成图片
@@ -281,15 +312,6 @@ const handleShare = async () => {
   shareDialog.value = true
 }
 
-// 复制分享链接
-// const accessUrl = import.meta.env.VITE_ACCESS_BASE_URL
-// const shareUrlTxt = computed(() => {
-//   return accessUrl + shareUrl.value
-// })
-// const copyText = () => {
-//   Snackbar.success('复制成功')
-// }
-
 // 收藏&取消收藏职位
 const handleCollection = async () => {
   const api = isCollection.value ? getPersonJobUnfavorite : getPersonJobFavorite
@@ -297,18 +319,37 @@ const handleCollection = async () => {
   await getCollectionStatus()
 }
 
-// 投递简历时,若当前用户没有简历列表则弹窗上传简历以及投递
+// 选择文件
 const uploadFile = ref()
-const handleUploadResume = async (url, title) => {
-  if (!url || !title) return
-  // 简历上传
-  await savePersonResumeCv({ title, url })
-  // 简历投递
-  await jobCvRelSend({ jobId: id, title, url, type: info.value.hire ? 1 : 0 })
+const openFileInput = () => {
+  uploadFile.value.trigger()
+}
+
+// 上传附件
+const handleUploadResume = async (url, title, filename) => {
+  const obj = formItems.value.options.find(e => e.key === 'url')
+  obj.value = filename
+  obj.truthValue = url
+}
+
+// 上传附件
+const handleUploadSubmit = async () => {
+  const { valid } = await CtFormRef.value.formRef.validate()
+  if (!valid) return
+  const obj = {}
+  formItems.value.options.forEach(e => {
+    obj[e.key] = e.truthValue || e.value
+  })
+  if (!obj.title || !obj.url) return
+  loading.value = true
+  await savePersonResumeCv(obj)
+  await jobCvRelSend({ jobId: id, title: obj.title, url: obj.url, type: info.value.hire ? 1 : 0 })
+  showUploadDialog.value = false
   setTimeout(() => {
     Snackbar.success(t('resume.deliverySuccess'))
     deliveryCheck()
-  }, 3000)
+    loading.value = false
+  }, 1000)
 }
 
 const showResume = ref(false)
@@ -323,7 +364,7 @@ const handleDelivery = async () => {
   // 没有上传过简历的先去上传
   if (!result.length) {
     Snackbar.warning('您还未上传过简历,请先上传简历')
-    uploadFile.value.trigger()
+    showUploadDialog.value = true
     return
   }
   showResume.value = true

+ 11 - 20
src/views/recruit/personal/shareJob/form/upload.vue

@@ -1,7 +1,7 @@
 <template>
   <div style="width: 100%;">
-    <div class="color-666 mb-3" style="font-size: 13px;">* 仅支持.doc, .docx, .pdf文件</div>
     <CtForm ref="formPageRef" :items="items"></CtForm>
+    <div class="color-666 mb-3" style="font-size: 13px;">* 仅支持.doc, .docx, .pdf文件</div>
   </div>
 </template>
 
@@ -41,31 +41,22 @@ const handleUpload = async (e) => {
 
 const items = ref({
   options: [
-    // {
-    //   type: 'text',
-    //   key: 'name',
-    //   value: '',
-    //   clearable: true,
-    //   label: '姓名 *',
-    //   rules: [v => !!v || '请填写姓名']
-    // },
-    // {
-    //   type: 'phoneNumber',
-    //   key: 'phone',
-    //   value: '',
-    //   clearable: true,
-    //   label: '手机号码 *',
-    //   rules: [v => !!v || '请填写手机号码']
-    // },
+    {
+      type: 'text',
+      key: 'title',
+      value: null,
+      label: '附件简历名称 *',
+      rules: [v => !!v || '请填写附件简历名称']
+    },
     {
       type: 'upload',
       key: 'url',
       value: null,
       data: '',
-      label: '简历 *',
+      label: '附件简历 *',
       accept: '.doc, .docx, .pdf',
-      placeholder: '请上传简历',
-      rules: [v => !!v || '请上传简历'],
+      placeholder: '请上传附件简历',
+      rules: [v => !!v || '请上传附件简历'],
       change: handleUpload
     }
   ]

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

@@ -16,11 +16,11 @@
     titleClass="text-h6"
     submitText="立即投递"
     @close="openUploadDialog = false"
-    title="选择简历"
+    title="附件简历上传"
     @submit="uploadFileSubmit"
   >
   <uploadForm ref="uploadFormRef"></uploadForm>
-  <div class="color-666" style="font-size: 13px;">提示:立即投递会将已上传的简历进行投递</div>
+  <div class="color-warning" style="font-size: 13px;">提示:立即投递会将已上传的简历进行投递</div>
   </CtDialog>
 </template>
 
@@ -73,8 +73,8 @@ const openUploadDialog = ref(false)
 // 上传附件-提交
 const uploadFileSubmit = async () => {
   const obj = await uploadFormRef.value.getQuery()
-  if (!obj?.url || !obj?.fileName) return Snackbar.warning(t('resume.selectResumeToSubmit'))
-  const query = { title: obj.fileName, url: obj.url }
+  if (!obj?.url || !obj?.title) return Snackbar.warning(t('resume.selectResumeToSubmit'))
+  const query = { title: obj.title, url: obj.url }
   await savePersonResumeCv(query)
   handleSubmit(query, '上传的文件提交_直接投递')
 }