Przeglądaj źródła

切换招聘者获取用户信息以及获取令牌,根据令牌退出登录

Xiao_123 11 miesięcy temu
rodzic
commit
931a8fdb4d

+ 15 - 0
src/api/common/index.js

@@ -64,6 +64,13 @@ export const logout = async () => {
   })
 }
 
+// 根据令牌退出登录
+export const logoutToken = async (token) => {
+  return await request.post({
+    url: `/app-api/menduner/system/auth/logout-token?token=${token}`
+  })
+}
+
 
 // 修改密码
 export const updatePassword = async (data) => {
@@ -162,4 +169,12 @@ export const getHotArea = async () => {
 // 上传文件
 export const uploadFile = async (data) => {
   return await request.upload({ url: '/app-api/infra/file/upload', data })
+}
+
+// 获取当前登录的企业用户信息
+export const getEnterprisingUserInfo = async (params) => {
+  return await request.get({
+    url: '/app-admin-api/menduner/system/user/get',
+    params
+  })
 }

+ 18 - 2
src/api/enterprise.js

@@ -55,7 +55,7 @@ export const enterpriseClick = async (data) => {
   })
 }
 
-// 牛人管理-列表
+// 招聘端-牛人管理-列表
 export const getPersonCvPage = async (params) => {
   return await request.get({
     url: '/app-admin-api/menduner/system/person-cv/page',
@@ -63,9 +63,25 @@ export const getPersonCvPage = async (params) => {
   })
 }
 
-// 牛人管理-获取发布的职位列表
+// 招聘端-牛人管理-获取发布的职位列表
 export const getJobAdvertised = async () => {
   return await request.get({
     url: '/app-admin-api/menduner/system/job-advertised/list'
   })
+}
+
+// 招聘端-保存用户基本信息
+export const saveUserInfo = async (data) => {
+  return await request.post({
+    url: '/app-admin-api/menduner/system/user/save',
+    data
+  })
+}
+
+// 招聘端-获取人才的在线简历详情
+export const getPersonCvDetail = async (params) => {
+  return await request.get({
+    url: '/app-admin-api/menduner/system/person-cv/detail',
+    params
+  })
 }

+ 0 - 8
src/api/personal/user.js

@@ -39,11 +39,3 @@ export const getUserRegisterEnterpriseApply = async (params) => {
     params
   })
 }
-
-// 获取当前登录的企业用户信息
-export const getEnterprisingUserInfo = async (params) => {
-  return await request.get({
-    url: '/app-admin-api/menduner/system/enterprise-user-bind/get/user',
-    params
-  })
-}

+ 9 - 8
src/layout/company/navBar.vue

@@ -14,8 +14,8 @@
         
         <div class="d-flex user-nav">
           <div class="d-flex align-center cursor-pointer" @click="handleEnterpriseClick">
-            <v-img @click="enterpriseClick(2)" rounded width="40" height="40" src="https://minio.citupro.com/dev/menduner/7.png" ></v-img>
-            <span @click="enterpriseClick(1)" class="ml-3">广州辞图科技有限公司</span>
+            <v-img @click="enterpriseClick(2)" rounded width="40" height="40" :src="baseInfo?.logoUrl || 'https://minio.citupro.com/dev/menduner/7.png'" ></v-img>
+            <span @click="enterpriseClick(1)" class="ml-3">{{ baseInfo?.enterpriseName || $t('sys.tourist') }}</span>
           </div>
           <div class="line"></div>
           
@@ -25,7 +25,7 @@
               <template v-slot:activator="{ props }">
                 <div class="d-flex ml-5 pl-2 align-center cursor-pointer" v-bind="props" @click="handleToPersonalCenter">
                   <v-avatar>
-                    <v-img alt="" :src="baseInfo?.avatar ?? 'https://minio.citupro.com/dev/menduner/7.png'"></v-img>
+                    <v-img alt="" :src="baseInfo?.avatar || 'https://minio.citupro.com/dev/menduner/7.png'"></v-img>
                   </v-avatar>
                   <div class="ml-2">{{ baseInfo?.name ?? $t('sys.tourist') }}</div>
                 </div>
@@ -97,10 +97,6 @@ import { useRouter } from 'vue-router'
 const router = useRouter()
 const handleLogoClick = () => { router.push({ path: '/enterprise'}) }
 
-// const changeRole = () => {
-//   router.push({ path: '/' })
-// }
-
 const handleToPersonalCenter = () => {
   // router.push({ path: '/personalCenter' })
 }
@@ -123,7 +119,12 @@ const items = ref([
   { title: t('setting.switchToJobSeeker'), icon: 'mdi-swap-horizontal', change: handleLogout },
   { title: t('setting.logOut'), icon: 'mdi-logout', change: handleLogout }
 ])
-const baseInfo = JSON.parse(localStorage.getItem('baseInfo')) // 人才信息
+
+// 企业logo、用户基本信息
+let baseInfo = ref(JSON.parse(localStorage.getItem('baseInfo')) || {})
+userStore.$subscribe((mutation, state) => {
+  baseInfo.value = state.baseInfo
+})
 
 // 语言切换
 const handleChangeLocale = (item) => {

+ 3 - 1
src/layout/personal/navBar.vue

@@ -131,7 +131,7 @@ const handleLogoClick = () => { router.push({ path: '/home'}) }
 const changeLoginType = async () => {
   // router.push({ path: '/login' })
   // router.push({ name: 'login', query: { loginType: 330 } })
-  const data = await getUserBindEnterpriseList() // 申请通过才数据,否则空数组
+  const data = await getUserBindEnterpriseList() // 申请通过才数据,否则空数组
   if (data?.length) {
     // localStorage.setItem('companyInfo', JSON.stringify(data))
     // changeRole()
@@ -148,6 +148,8 @@ const changeLoginType = async () => {
 // 切换为招聘者
 const toEnterprise = async (enterpriseId) => {
   await getUserBindEnterpriseList({ enterpriseId })
+  // 获取企业账号令牌以及企业用户个人信息
+  await userStore.changeRole(enterpriseId)
   router.push({ path: '/enterprise' })
 }
 // // 切换为招聘者

+ 1 - 18
src/router/modules/enterprise.js

@@ -5,7 +5,7 @@ const enterprise = [
   {
     path: '/enterprise',
     show: true,
-    redirect: '/enterprise/position',
+    redirect: '/enterprise/talentPool',
   },
   {
     path: '/enterprise/talentPool',
@@ -113,23 +113,6 @@ const enterprise = [
       }
     ]
   },
-  {
-    path: '/enterprise/infoManagement',
-    component: Layout,
-    name: 'infoManagement',
-    meta: {
-      title: '信息管理',
-      enName: 'Info Management',
-      icon: 'mdi-list-box-outline'
-    },
-    children: [
-      {
-        path: '/enterprise/infoManagement',
-        show: true,
-        component: () => import('@/views/enterprise/infoManagement/index.vue')
-      }
-    ]
-  },
   {
     path: '/enterprise/personnelManagement',
     component: Layout,

+ 25 - 6
src/store/user.js

@@ -1,8 +1,8 @@
 import { defineStore } from 'pinia'
-import { setToken, removeToken, setRefreshToken } from '@/utils/auth'
-import { smsLogin, passwordLogin, getBaseInfo, passwordLoginOfEnterprise, smsLoginOfEnterprise } from '@/api/common/index'
-import { logout } from '@/api/common/index'
-import { getUserInfo, getEnterprisingUserInfo } from '@/api/personal/user'
+import { setToken, removeToken, setRefreshToken, getToken } from '@/utils/auth'
+import { smsLogin, passwordLogin, getBaseInfo, passwordLoginOfEnterprise, smsLoginOfEnterprise, switchLoginOfEnterprise } from '@/api/common/index'
+import { getEnterprisingUserInfo, logoutToken } from '@/api/common/index'
+import { getUserInfo } from '@/api/personal/user'
 import Snackbar from '@/plugins/snackbar'
 import { timesTampChange } from '@/utils/date'
 import { getBaseInfoDictOfName } from '@/utils/getText'
@@ -91,7 +91,7 @@ export const useUserStore = defineStore('user',
       // 退出登录
       async userLogout () {
         // const loginUserPhone = this.userInfo?.phone || ''
-        await logout()
+        await logoutToken(getToken())
         removeToken()
         this.userInfo = {}
         this.baseInfo = {}
@@ -100,9 +100,28 @@ export const useUserStore = defineStore('user',
         localStorage.clear()
         // localStorage.setItem('companyInfo', companyInfo)
         // localStorage.setItem('loginUserPhone', loginUserPhone)
+      },
+      // 切换为招聘者
+      async changeRole (enterpriseId) {
+        // 先退出个人登录
+        const token = getToken()
+        await logoutToken(token)
+
+        const data = await switchLoginOfEnterprise({ enterpriseId })
+        setToken(data.accessToken)
+        setRefreshToken(data.refreshToken)
+        localStorage.setItem('accountInfo', JSON.stringify(data))
+        localStorage.setItem('expiresTime', data.expiresTime)
+        await this.getEnterpriseInfo()
+      },
+      // 获取当前登录的企业用户信息
+      async getEnterpriseInfo () {
+        const result = await getEnterprisingUserInfo()
+        this.baseInfo = result
+        localStorage.setItem('baseInfo', JSON.stringify(result))
       }
     }
-  },
+   },
   {
     persist: true
   }

+ 0 - 11
src/views/enterprise/infoManagement/index.vue

@@ -1,11 +0,0 @@
-<template>
-  <div>企业资料管理</div>
-</template>
-
-<script setup>
-defineOptions({ name: 'enterprise-info-management'})
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 145 - 2
src/views/enterprise/informationSetting/index.vue

@@ -1,11 +1,154 @@
 <template>
-  <div>个人信息设置</div>
+  <v-card class="pa-5 card-box d-flex flex-column align-center">
+    <CtForm ref="CtFormRef" :items="formItems" style="width: 700px;">
+      <template #avatar="{ item }">
+        <div class="avatarsBox" @mouseover="showIcon = true" @mouseleave="showIcon = false">
+          <v-avatar class="elevation-5" size=80 :image="item.value || 'https://minio.citupro.com/dev/menduner/7.png'"></v-avatar>
+            <div v-show="showIcon" @click="openFileInput" v-bind="$attrs" class="mdi mdi-camera-outline">
+              <input
+                type="file"
+                ref="fileInput"
+                accept="image/png, image/jpg, image/jpeg"
+                style="display: none;"
+                @change="handleUploadFile"
+              />
+            </div>
+        </div>
+      </template>
+    </CtForm>
+    <v-btn class="buttons mt-5" color="primary" @click.stop="handleSubmit">提 交</v-btn>
+  </v-card>
 </template>
 
 <script setup>
 defineOptions({ name: 'information-setting'})
+import { ref } from 'vue'
+import { saveUserInfo } from '@/api/enterprise'
+import { uploadFile } from '@/api/common'
+import { useI18n } from '@/hooks/web/useI18n'
+import { getDict } from '@/hooks/web/useDictionaries'
+import { useUserStore } from '@/store/user'
+import Snackbar from '@/plugins/snackbar'
+
+const { t } = useI18n()
+const userStore = useUserStore()
+const showIcon = ref(false)
+const CtFormRef = ref()
+const formItems = ref({
+  options: [
+    {
+      slotName: 'avatar',
+      key: 'avatar',
+      value: ''
+    },
+    {
+      type: 'ifRadio',
+      key: 'sex',
+      value: '2',
+      label: '性别',
+      width: 90,
+      dictTypeName: 'system_user_sex',
+      items: []
+    },
+    {
+      type: 'text',
+      key: 'name',
+      value: '',
+      label: '用户名 *',
+      rules: [v => !!v || '请输入用户名']
+    },
+    {
+      type: 'text',
+      key: 'phone',
+      value: '',
+      label: '手机号码 *',
+      rules: [v => !!v || '请输入手机号码']
+    },
+    {
+      type: 'text',
+      key: 'email',
+      value: '',
+      label: '电子邮箱'
+    }
+  ]
+})
+
+// 用户基本信息
+const baseInfo = ref(JSON.parse(localStorage.getItem('baseInfo')) || {})
+const query = ref({})
+// 获取字典数据以及字段回显
+formItems.value.options.forEach(item => {
+  if (item.dictTypeName) {
+    getDict(item.dictTypeName).then(({ data }) => {
+      data = data?.length && data || []
+      item.items = data
+    })
+  }
+  if (Object.keys(baseInfo).length) {
+    item.value = baseInfo.value[item.key]
+    query.value.id = baseInfo.value.id
+  }
+})
+// 监听store变化
+userStore.$subscribe((mutation, state) => {
+  baseInfo.value = state.baseInfo
+})
+
+// 选择文件
+const fileInput = ref()
+const clicked = ref(false)
+const openFileInput = () => {
+  if (clicked.value) return
+  clicked.value = true
+  fileInput.value.click()
+  clicked.value = false
+}
+
+// 上传头像
+const handleUploadFile = async (e) => {
+  const file = e.target.files[0]
+  const formData = new FormData()
+  formData.append('file', file)
+  const { data } = await uploadFile(formData)
+  if (!data) return
+  formItems.value.options.find(e => e.key === 'avatar').value = data
+}
+
+// 提交
+const handleSubmit = async () => {
+  const { valid } = await CtFormRef.value.formRef.validate()
+  if (!valid) return
+  formItems.value.options.forEach(item => {
+    query.value[item.key] = item.value
+  })
+  await saveUserInfo(query.value)
+  Snackbar.success(t('common.submittedSuccessfully'))
+  await userStore.getEnterpriseInfo()
+}
 </script>
 
 <style scoped lang="scss">
-
+.avatarsBox {
+  height: 80px;
+  width: 80px;
+  position: relative;
+  cursor: pointer;
+  margin: 32px;
+  margin-right: 40px;
+  .img {
+    width: 100%;
+    height: 100%;
+  }
+  .mdi {
+    font-size: 42px;
+    color: #fff;
+  }
+  div {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    border-radius: 50%;
+  }
+}
 </style>

+ 2 - 2
src/views/enterprise/talentPool/index.vue

@@ -21,7 +21,7 @@
           <span class="mx-10">加入时间:{{ val.createTime }}</span>
           <span>人才分类:{{ val.type }}</span>
         </div>
-        <div @click.stop="talentPoolDetails(val)" class="px-5 py-3 d-flex justify-space-between align-center">
+        <div @click.stop="talentPoolDetails(val)" class="px-5 py-3 d-flex justify-space-between align-center cursor-pointer">
           <div class="d-flex">
             <v-badge
               bordered
@@ -46,7 +46,7 @@
             <v-btn class="ml-3" color="primary" @click.stop="{}">邀请面试</v-btn>
           </div>
         </div>
-        <div class="d-flex mx-5 bottom">
+        <div class="d-flex mx-5 bottom cursor-pointer">
           <div class="experience" v-if="val.exp.length">
             <div class="second-title">工作经验</div>
             <v-timeline density="compact" align="start" side="end" truncate-line="both">