Bladeren bron

校验是否完善人才必填信息

lifanagju_citu 6 maanden geleden
bovenliggende
commit
c348f4f5e4

+ 8 - 0
src/components/Enterprise/components/positions.vue

@@ -92,6 +92,8 @@ import conditionFilter from '@/views/recruit/personal/position/components/condit
 import loginPage from '@/views/common/loginDialog.vue'
 import { getToken } from '@/utils/auth'
 import Snackbar from '@/plugins/snackbar'
+import { checkPersonBaseInfo } from '@/utils/check'
+import necessaryInfo from '@/plugins/necessaryInfo'
 
 const props = defineProps({
   info: {
@@ -259,6 +261,12 @@ const toDetails = async (info) => {
     nextFunc.value = toDetails // 登录成功后要执行的操作 (toDetails执行不成功,原因未找到)
     return
   }
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      toDetails(toDetailsInfo)
+    })
+    return
+  }
   const userId = info.contact.userId
   const enterpriseId = info.contact.enterpriseId
   const textObj = {

+ 3 - 0
src/components/Enterprise/details.vue

@@ -68,6 +68,8 @@
 
     <!-- 快速登录 -->
     <loginPage v-if="showLogin" @loginSuccess="loginSuccess" @close="loginClose"></loginPage>
+    <!-- 完善个人信息 -->
+    <!-- <fillPage v-if="showFill" @success="fillSuccess"></fillPage> -->
   </div>
 </template>
 
@@ -84,6 +86,7 @@ import { useRoute, useRouter } from 'vue-router'
 import { getToken } from '@/utils/auth'
 import Snackbar from '@/plugins/snackbar'
 import loginPage from '@/views/common/loginDialog.vue'
+// import fillPage from '@/views/common/fill/dialog.vue'
 
 const props = defineProps({
   id: {

+ 8 - 0
src/components/Position/longStrip.vue

@@ -63,6 +63,8 @@ import { ref } from 'vue'
 import { prologue, defaultText } from '@/hooks/web/useIM'
 import loginPage from '@/views/common/loginDialog.vue'
 import { getToken } from '@/utils/auth'
+import { checkPersonBaseInfo } from '@/utils/check'
+import necessaryInfo from '@/plugins/necessaryInfo'
 
 const emits = defineEmits(['refresh'])
 const { t } = useI18n()
@@ -112,6 +114,12 @@ const toDetails = async (info) => {
     nextFunc.value = toDetails // 登录成功后要执行的操作 (toDetails执行不成功,原因未找到)
     return
   }
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      toDetails(toDetailsInfo)
+    })
+    return
+  }
   const userId = info.contact.userId
   const enterpriseId = info.contact.enterpriseId
   const textObj = {

+ 1 - 1
src/permission.js

@@ -27,7 +27,7 @@ router.beforeEach(async (to, from, next) => {
     // 强制修改密码
     if (localStorage.getItem('entUpdatePassword') === 'needChange') fullScreen('entUpdatePassword')
     // 强制填写个人信息
-    else if (localStorage.getItem('necessaryInfoReady') === 'no') necessaryInfo('necessaryInfoDialog')
+    else if (localStorage.getItem('necessaryInfoReady') !== 'ready') necessaryInfo('necessaryInfoDialog')
     // 企业信息完成度提示
     else if (localStorage.getItem('checkEnterpriseBaseInfoFalseHref')) {
       const href = localStorage.getItem('checkEnterpriseBaseInfoFalseHref')

+ 10 - 8
src/plugins/necessaryInfo/components/infoForm.vue

@@ -6,9 +6,10 @@
 
 <script setup>
 import { getDict } from '@/hooks/web/useDictionaries'
-defineOptions({name: 'shareJob-form-baseInfo'})
+defineOptions({name: 'necessaryInfo-InfoForm'})
 import { reactive, ref } from 'vue'
 import { checkEmail } from '@/utils/validate'
+import { enterpriseSearchByName } from '@/api/recruit/personal/resume'
 
 const formPageRef = ref()
 let query = reactive({})
@@ -16,7 +17,7 @@ let query = reactive({})
 // 企业名称下拉列表
 const enterpriseNameInput = ref('')
 const getEnterpriseData = async (name) => {
-  const item = formItems.value.options.find(e => e.key === 'enterpriseId')
+  const item = items.value.options.find(e => e.key === 'enterpriseId')
   if (!item) return
   if (item.items?.length && (enterpriseNameInput.value === name)) return // 防抖
   item[item.itemTextName] = enterpriseNameInput.value = name
@@ -27,7 +28,7 @@ const getEnterpriseData = async (name) => {
   }
 }
 const positionSearch = (name) => {
-  const item = formItems.value.options.find(e => e.key === 'positionId')
+  const item = items.value.options.find(e => e.key === 'positionId')
   if (!item) return
   item[item.itemTextName] = name
 }
@@ -79,13 +80,14 @@ const items = ref({
     {
       type: 'datePicker',
       mode: 'date',
-      labelWidth: 110,
+      labelWidth: 80,
       key: 'birthday',
       value: '1990-01-01',
       defaultValue: new Date(1990, 1, 1),
       label: '出生日期 *',
       disabledFutureDates: true,
       format: 'YYYY/MM/DD',
+      flexStyle: 'mb-7',
       outlined: true,
       rules: [v => !!v || '请选择出生日期']
     },
@@ -94,14 +96,14 @@ const items = ref({
       key: 'enterpriseId',
       value: null,
       default: null,
-      label: '任职企业名称(没有可填暂无 *',
+      label: '任职企业名称(没有可填暂无)',
       outlined: true,
       clearable: true,
       canBeInputted: true, //
       itemTextName: 'enterpriseName',
       itemText: 'value',
       itemValue: 'key',
-      rules: [v => !!v || '任职企业名称(没有可填“暂无”)'],
+      // rules: [v => !!v || '任职企业名称(没有可填“暂无”)'],
       search: getEnterpriseData,
       items: []
     },
@@ -110,14 +112,14 @@ const items = ref({
       key: 'positionId',
       value: null,
       default: null,
-      label: '任职职位名称(没有可填暂无 *',
+      label: '任职职位名称(没有可填暂无)',
       outlined: true,
       clearable: true,
       canBeInputted: true, //
       itemTextName: 'positionName',
       itemText: 'nameCn',
       itemValue: 'id',
-      rules: [v => !!v || '任职职位名称(没有可填“暂无”)'],
+      // rules: [v => !!v || '任职职位名称(没有可填“暂无”)'],
       search: val => positionSearch(val),
       items: []
     },

+ 24 - 7
src/plugins/necessaryInfo/components/necessaryInfoDialog.vue

@@ -26,6 +26,20 @@ import { useRoute } from 'vue-router'; const route = useRoute()
 import { useRouter } from 'vue-router'; const router = useRouter()
 import Confirm from '@/plugins/confirm'
 import { onMounted, ref } from 'vue'
+import { getToken } from '@/utils/auth'
+// import Snackbar from '@/plugins/snackbar'
+
+const props = defineProps({
+  // title: String,
+  // text: String,
+  // cancel: Function,
+  sure: Function,
+  other: Function,
+  option: {
+    type: Object,
+    default: () => {}
+  }
+})
 
 const dialog = ref(false)
 onMounted(() => {
@@ -34,19 +48,21 @@ onMounted(() => {
 
 const formRef = ref()
 const simpleInfoSubmit = async () => {
+  if (!getToken()) {
+    Confirm('系统提示', '登录失效,请重新登录', { hideCancelBtn: true }).then(() => {
+      window.location.reload()
+    })
+    return
+  }
   try {
     const obj = await formRef.value.getQuery()
     if (!obj) return
     await savePersonSimpleInfo(obj)
     const info = localStorage.getItem('baseInfo') ? JSON.parse(localStorage.getItem('baseInfo')) : {}
     localStorage.setItem('baseInfo', JSON.stringify({ ...info, ...obj }))
-    localStorage.setItem('necessaryInfoReady', 'ok')
-    Confirm('系统提示', '提交成功,立即刷新', { hideCancelBtn: true }).then(() => {
-      // window.location.reload()
-      location.reload()
-    })
-    // dialog.value = false
-    // emit('simpleInfoReady')
+    localStorage.setItem('necessaryInfoReady', 'ready') //
+    dialog.value = false
+    props.sure()
   } catch (error) {
     console.error('error', error)
   }
@@ -56,6 +72,7 @@ const simpleInfoSubmit = async () => {
 const handleLogout = () => {
   Confirm('系统提示', '是否确定退出当前登录账号?').then(async () => {
     await userStore.userLogout(1)
+    props.other()
     if (!route || route.path === '/recruitHome') location.reload()
     else router.push({ path: '/recruitHome' })
   })

+ 30 - 15
src/plugins/necessaryInfo/index.js

@@ -2,21 +2,36 @@ import { createApp } from 'vue'
 import necessaryInfoDialog from './components/necessaryInfoDialog.vue'
 import vuetify from '@/plugins/vuetify'
 
-const toastMessage = (type, options)  => {
-  const componentName = type === 'necessaryInfoDialog' ? necessaryInfoDialog : null
-
-  const rootNode = document.createElement("div")
-  document.querySelector('.v-application').appendChild(rootNode)
-  const app = createApp(componentName, options)
-  app.use(vuetify)
-  app.mount(rootNode)
-  const { timeout } = options || {}
-  if ((timeout - 0)) {
-    setTimeout(() => {
-      app.unmount()
-      rootNode.remove()
-    }, (timeout-0))
-  }
+const toastMessage = (type, option = {})  => {
+  return new Promise((resolve, reject) => {
+    const componentName = type === 'necessaryInfoDialog' ? necessaryInfoDialog : null
+    const rootNode = document.createElement("div")
+      document.querySelector('.v-application').appendChild(rootNode)
+      const app = createApp(componentName, {
+        // title,
+        // text,
+        option,
+        cancel () {
+          app.unmount()
+          rootNode.remove()
+          if (option.cancelCallback) {
+            reject()
+          }
+        },
+        sure () {
+          app.unmount()
+          rootNode.remove()
+          resolve()
+        },
+        other () {
+          app.unmount()
+          rootNode.remove()
+          resolve({ otherClick: true })
+        }
+      })
+      app.use(vuetify)
+      app.mount(rootNode)
+  })
 }
 
 // 注册插件app.use()会自动执行install函数

+ 7 - 15
src/store/user.js

@@ -17,6 +17,7 @@ import Snackbar from '@/plugins/snackbar'
 import { timesTampChange } from '@/utils/date'
 import { updateEventList } from '@/utils/eventList'
 import { getBaseInfoDictOfName } from '@/utils/getText'
+import { checkPersonBaseInfo } from '@/utils/check'
 // import Confirm from '@/plugins/confirm'
 
 // import { useIMStore } from './im'
@@ -47,7 +48,7 @@ export const useUserStore = defineStore('user',
             localStorage.setItem('expiresTime', res.expiresTime) // token过期时间
             updateEventList(true) // 获取规则配置跟踪列表
             await this.getUserInfos()
-            this.getUserBaseInfos()
+            await this.getUserBaseInfos()
             resolve()
           }).catch(err => { reject(err) })
         })
@@ -64,7 +65,7 @@ export const useUserStore = defineStore('user',
             localStorage.setItem('expiresTime', res.expiresTime) // token过期时间
             updateEventList(true) // 获取规则配置跟踪列表
             await this.getUserInfos()
-            this.getUserBaseInfos()
+            await this.getUserBaseInfos()
             resolve(res)
           }).catch(err => { reject(err) })
         })
@@ -73,7 +74,7 @@ export const useUserStore = defineStore('user',
       async handlePasswordLogin(data) {
         return new Promise((resolve, reject) => {
           data.account = data.phone
-          passwordLogin(data).then(res => {
+          passwordLogin(data).then(async res => {
             if (data.isEnterprise) { // 企业邮箱登录
               localStorage.setItem('emailLoginInfo', JSON.stringify(res))
               window.location.href = '/enterpriseVerification'
@@ -85,8 +86,8 @@ export const useUserStore = defineStore('user',
               localStorage.setItem('accountInfo', JSON.stringify(res))
               localStorage.setItem('expiresTime', res.expiresTime) // token过期时间
               updateEventList(true) // 获取规则配置跟踪列表
-              this.getUserInfos()
-              this.getUserBaseInfos()
+              await this.getUserInfos()
+              await this.getUserBaseInfos()
             }
             resolve()
           }).catch(err => {
@@ -113,8 +114,8 @@ export const useUserStore = defineStore('user',
           const data = await getBaseInfo({ userId: userId || this.accountInfo.userId })
           if (!data) return localStorage.setItem('baseInfo', '{}')
           this.baseInfo = await this.getFieldText(data)
-          // this.checkPersonBaseInfo(this.baseInfo)
           localStorage.setItem('baseInfo', JSON.stringify(this.baseInfo))
+          localStorage.setItem('necessaryInfoReady', checkPersonBaseInfo(this.baseInfo) ? 'ready' : 'fddeaddc47868b4d5ca30dcda9f83cac00') // 校验是否完善人才必填信息
         } catch (error) {
           Snackbar.error(error)
         }
@@ -196,15 +197,6 @@ export const useUserStore = defineStore('user',
         return data // 方便直接获取
       },
 
-      // // 校验人才必填信息
-      // checkPersonBaseInfo (bInfo) {
-      //   let necessaryInfoReady = Boolean(bInfo && Object.keys(bInfo).length)
-      //   if (necessaryInfoReady) {
-      //     const keyArr = ['name', 'phone', 'jobStatus', 'expType', 'eduType'] // 必填人才信息
-      //     necessaryInfoReady = keyArr.every(e => bInfo[e] && bInfo[e] !== 0)
-      //   }
-      //   localStorage.setItem('necessaryInfoReady', necessaryInfoReady? 'ok':'no') // true已完成填写,false未完成填写
-      // },
       // 获取《企业基本信息》
       async checkEnterpriseBaseInfo () {
         try {

+ 11 - 2
src/utils/check.js

@@ -1,9 +1,18 @@
 // 校验是否完善人才必填信息
-export const checkPersonBaseInfo = ({ baseInfo=null }) => {
+export const checkPersonBaseInfo = (baseInfo) => {
   const info = baseInfo ? baseInfo : localStorage.getItem('baseInfo') ? JSON.parse(localStorage.getItem('baseInfo')) : {}
   if (!info || !Object.keys(info).length) return false
   //
-  const keyArr = ['name', 'phone', 'jobStatus', 'expType', 'eduType'] // 必填项目
+  const keyArr = [ // 必填项目
+    'name',
+    'sex',
+    'phone',
+    'email',
+    'birthday',
+    'jobStatus',
+    'expType',
+    'eduType'
+  ]
   const necessaryInfoReady = keyArr.every(e => info[e] && info[e] !== 0)
   return necessaryInfoReady
 }

+ 8 - 2
src/views/common/loginDialog.vue

@@ -59,6 +59,8 @@ import { useUserStore } from '@/store/user'; const userStore = useUserStore()
 import { nextTick, ref } from 'vue'
 import Verify from '@/components/Verifition'
 import Snackbar from '@/plugins/snackbar'
+import { checkPersonBaseInfo } from '@/utils/check'
+import necessaryInfo from '@/plugins/necessaryInfo'
 
 const emit = defineEmits(['loginSuccess', 'close'])
 
@@ -102,8 +104,12 @@ const handleLogin = async () => {
   }
   try {
     await userStore[api](params)
-    emit('loginSuccess')
-    // if (localStorage.getItem('necessaryInfoReady') === 'ok') emit('loginSuccess')
+    if (checkPersonBaseInfo()) emit('loginSuccess')
+    else {
+      necessaryInfo('necessaryInfoDialog').then(() => {  // 强制填写个人信息
+        emit('loginSuccess')
+      })
+    }
   } catch (error) {
     captchaStr.value = '' // 清空人机验证
     phoneRef.value && phoneRef.value.clearCaptcha() // 清空人机验证

+ 8 - 0
src/views/mall/exchange.vue

@@ -36,6 +36,8 @@ import Snackbar from '@/plugins/snackbar'
 import { redeemSubmit } from '@/api/mall'
 import { useUserStore } from '@/store/user'
 import { getDict } from '@/hooks/web/useDictionaries'
+import { checkPersonBaseInfo } from '@/utils/check'
+import necessaryInfo from '@/plugins/necessaryInfo'
 
 const emit = defineEmits(['login', 'toTaskCenter'])
 defineProps({
@@ -111,6 +113,12 @@ const handleShowDetail = (item) =>{
     emit('login')
     return
   }
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      handleShowDetail()
+    })
+    return
+  }
   detailItem.value = item
   formItems.value.options.forEach(e => {
     if (e.key !== 'contactPhone') e.hide = item.type ? false : true

+ 20 - 20
src/views/recruit/personal/home/index.vue

@@ -24,7 +24,7 @@
     </div>
   </div>
   <!-- 快速填写简易人才信息-弹窗 -->
-  <simplePage v-if="showSimplePage" :closeable="true" closeText="暂时跳过" @close="handleInfoClose" @simpleInfoReady="handleUpdateInfo"></simplePage>
+  <!-- <simplePage v-if="showSimplePage" :closeable="true" closeText="暂时跳过" @close="handleInfoClose" @simpleInfoReady="handleUpdateInfo"></simplePage> -->
   <!-- 广告弹窗 -->
   <v-dialog
     v-model="adDialog"
@@ -40,7 +40,7 @@
 
 <script setup>
 defineOptions({ name:'personal-index'})
-import simplePage from './components/simple.vue'
+// import simplePage from './components/simple.vue'
 import headSearch from '@/components/headSearch'
 import hotJobs from './components/hotJobs.vue'
 import homeJobTypeCard from './components/homeJobTypeCard'
@@ -48,8 +48,8 @@ import hotPromotedPositions from './components/hotPromotedPositions.vue'
 import PopularEnterprises from './components/popularEnterprises.vue'
 import advertisementPage from './components/advertisement/index.vue'
 import { useRouter } from 'vue-router'
-import { nextTick, onMounted, ref } from 'vue'
-import { useUserStore } from '@/store/user'
+import { onMounted, ref } from 'vue'
+// import { useUserStore } from '@/store/user'
 import { getToken } from '@/utils/auth'
 import { getRewardEventList } from '@/utils/eventList'
 
@@ -62,23 +62,23 @@ const handleSearch = (val) => {
   if (val) router.push(`/recruit/personal/position?content=${val}`)
 }
 
-const store = useUserStore()
-const simple = ref(localStorage.getItem('simpleCompleteDialogHaveBeenShow'))
-const showSimplePage = ref(false) // 只提示一次
-if (!getToken()) showSimplePage.value = false
-nextTick(() => {
-  if (getToken()) {
-    showSimplePage.value = simple.value && JSON.parse(simple.value) ? true : false
-  }
-})
-const handleInfoClose = () => {
-  localStorage.setItem('simpleCompleteDialogHaveBeenShow', false)
-}
+// const store = useUserStore()
+// const simple = ref(localStorage.getItem('simpleCompleteDialogHaveBeenShow'))
+// const showSimplePage = ref(false) // 只提示一次
+// if (!getToken()) showSimplePage.value = false
+// nextTick(() => {
+//   if (getToken()) {
+//     showSimplePage.value = simple.value && JSON.parse(simple.value) ? true : false
+//   }
+// })
+// const handleInfoClose = () => {
+//   localStorage.setItem('simpleCompleteDialogHaveBeenShow', false)
+// }
 // 更新用户基本信息
-const handleUpdateInfo = async () => {
-  handleInfoClose()
-  await store.getUserBaseInfos(null)
-}
+// const handleUpdateInfo = async () => {
+//   handleInfoClose()
+//   await store.getUserBaseInfos(null)
+// }
 
 // 广告跳转
 const handleOpenAdvertise = () => {

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

@@ -186,6 +186,8 @@ import { timesTampChange } from '@/utils/date'
 import { dealDictObjData, dealDictArrayData, commissionCalculation } from '@/utils/position'
 import { getToken } from '@/utils/auth'
 import { getUserAvatar } from '@/utils/avatar'
+import { checkPersonBaseInfo } from '@/utils/check'
+import necessaryInfo from '@/plugins/necessaryInfo'
 
 const props = defineProps({
   defaultWidth: {
@@ -208,7 +210,8 @@ const props = defineProps({
 
 const { t } = useI18n()
 const router = useRouter()
-const { id } = props.propJobId ? { id: props.propJobId } : router.currentRoute.value.params
+let { id } = props.propJobId ? { id: props.propJobId } : router.currentRoute.value.params
+if (id) id = id.toString()
 const delivery = ref(false) // 是否已投递简历
 const loading = ref(false)
 const showLogin = ref(false)
@@ -240,7 +243,7 @@ const formItems = ref({
   ]
 })
 
-const nextFunc = ref(null)
+const nextFunc = ref(null) // 登录成功或强制填写个人信息成功后回调
 let loginCloseWarningWord = ''
 // 快速登录
 const loginSuccess = () => {
@@ -337,27 +340,39 @@ getCollectionStatus()
 // 分享有礼
 const shareDialog = ref(false)
 const handleShare = async () => {
+  nextFunc.value = handleShare // 登录成功或强制填写个人信息成功后回调
   if (!getToken()) {
     showLogin.value = true // 打开快速登录弹窗
     Snackbar.warning('您还未登录,请先登录后再试')
     //
-    nextFunc.value = handleShare // 登录成功后要执行的操作
     loginCloseWarningWord = '您已取消登录,无法分享职位给好友' // 取消登录提示语
     return
   }
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      if (nextFunc.value) nextFunc.value()
+    })
+    return
+  }
   generateAndDownloadImage() // 生成海报
 }
 
 // 收藏&取消收藏职位
 const handleCollection = async () => {
+  nextFunc.value = handleCollection // 登录成功或强制填写个人信息成功后回调
   if (!getToken()) {
     showLogin.value = true // 打开快速登录弹窗
     Snackbar.warning('您还未登录,请先登录后再试')
     //
-    nextFunc.value = handleCollection // 登录成功后要执行的操作
     loginCloseWarningWord = '您已取消登录,无法收藏职位' // 取消登录提示语
     return
   }
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      if (nextFunc.value) nextFunc.value()
+    })
+    return
+  }
   const api = isCollection.value ? getPersonJobUnfavorite : getPersonJobFavorite
   await api(isCollection.value ? id : { jobId: id })
   await getCollectionStatus()
@@ -402,15 +417,21 @@ const showResume = ref(false)
 const resumeList = ref([])
 const selectResume = ref()
 const handleDelivery = async () => {
+  nextFunc.value = handleDelivery // 登录成功或强制填写个人信息成功后回调
   if (!getToken()) {
     showLogin.value = true // 打开快速登录弹窗
     Snackbar.warning('您还未登录,请先登录后再试')
     //
-    nextFunc.value = handleDelivery // 登录成功后要执行的操作
     loginCloseWarningWord = '您已取消登录,无法投递简历' // 取消登录提示语
     return
   }
   if (delivery.value) return Snackbar.warning(t('resume.alreadyResume'))
+  if (!checkPersonBaseInfo()) { // 强制填写个人信息
+    necessaryInfo('necessaryInfoDialog').then(() => {
+      if (nextFunc.value) nextFunc.value()
+    })
+    return
+  }
   const result = await getPersonResumeCv()
   resumeList.value = result
   // 没有上传过简历的先去上传
@@ -445,6 +466,7 @@ const handleSubmit = async (val) =>{
 let toDetailsInfo = {}
 // 沟通
 const toDetails = async (info) => {
+  nextFunc.value = toDetails // 登录成功或强制填写个人信息成功后回调
   if (info) toDetailsInfo = info // 快速登录弹窗回调使用
   else info = toDetailsInfo
   if (!getToken()) {
@@ -452,7 +474,6 @@ const toDetails = async (info) => {
     Snackbar.warning('您还未登录,请先登录后再试')
     //
     loginCloseWarningWord = '您已取消登录,无法对职位进行沟通' // 取消登录提示语
-    nextFunc.value = toDetails // 登录成功后要执行的操作 (toDetails执行不成功,原因未找到)
     return
   }
   try {