navBar.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <template>
  2. <div>
  3. <v-toolbar
  4. class="banner"
  5. density="compact"
  6. style="padding-left: 0px;height: 50px;font-size: 15px;"
  7. >
  8. <div class="innerBox d-flex justify-space-between">
  9. <div>
  10. <div class="nav-logo mr-3 mt-1 cursor-pointer d-flex align-center" @click="router.push('/recruitHome')">
  11. <v-img src="../../assets/logo.png" aspect-ratio="16/9" cover :width="90" style="height: 40px"></v-img>
  12. <span class="ml-2" style="margin-top: 6px;" :class="{'active-route' : route.path === '/recruitHome'}">首页</span>
  13. </div>
  14. <!-- <div class="nav-city">
  15. <p class="nav-city-box">
  16. <v-icon color="primary">mdi-map-marker</v-icon>
  17. <span class="nav-city-selected">广州</span>
  18. <span class="switchover-city nav-city-selected">[{{ $t('sys.switchCities') }}]</span>
  19. </p>
  20. </div> -->
  21. <div class="menuList">
  22. <div v-for="val in navList" :key="val.name" class="mr-3">
  23. <template v-if="val.children">
  24. <defineListPage v-bind="$attrs" :title="val.title" :list="val.children" @emitClick="handleClick" :closeOnContentClick="true"></defineListPage>
  25. </template>
  26. <template v-else>
  27. <span class="cursor-pointer menuList-first-title" :class="{'active-route' : route.path === val.path || route.path.includes(val.path)}" @click="handleClick(val, true)">{{ val.title }}</span>
  28. </template>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="d-flex user-nav">
  33. <div class="btns d-flex align-center" v-if="!getToken() && showLoginBtn">
  34. <v-btn class="half-button" border color="primary" size="small" @click="handleLogin">{{ $t('login.loginOrRegister') }}</v-btn>
  35. </div>
  36. <!-- 头像用户名 -->
  37. <div class="d-flex align-center color-333" v-if="getToken()">
  38. <span class="cursor-pointer mr-5 commonHover" @click="handleSwitch">我要招聘</span>
  39. <span class="cursor-pointer commonHover" :class="{'active-route': routeActive === 6}" @click="router.push({ path: paths[6] })">
  40. <span class="mr-3">
  41. 现金:{{ userAccount?.balance && userAccount?.balance > 0 ? (userAccount?.balance / 100.0).toFixed(2) : 0 }}
  42. <span style="color: #00000000;">1</span>
  43. 积分:{{ userAccount?.point || 0 }}
  44. </span>
  45. <span class="mr-3 ml-3"></span>
  46. </span>
  47. <v-menu open-on-hover>
  48. <template v-slot:activator="{ props }">
  49. <div class="d-flex ml-3 align-center cursor-pointer" :class="{'active-route': routeActive === 5}" v-bind="props" @click="handleToPersonalCenter">
  50. <v-avatar>
  51. <v-img alt="John" :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)"></v-img>
  52. </v-avatar>
  53. <div class="ml-3 commonHover">
  54. {{ baseInfo?.name || userInfo.phone }}
  55. <v-icon :color="routeActive === 5 ? '#008979' : '#333'" size="30">mdi-menu-down</v-icon>
  56. </div>
  57. </div>
  58. </template>
  59. <v-list>
  60. <v-list-item v-for="(item, index) in items" :key="index" @click="item.change">
  61. <template v-slot:prepend>
  62. <v-icon :icon="item.icon"></v-icon>
  63. </template>
  64. <v-list-item-title>{{ item.title }}</v-list-item-title>
  65. </v-list-item>
  66. </v-list>
  67. </v-menu>
  68. </div>
  69. <!-- 语言切换 -->
  70. <!-- <v-menu>
  71. <template v-slot:activator="{ props }">
  72. <v-btn
  73. class="ml-3"
  74. color="primary"
  75. icon="mdi-translate"
  76. size="small"
  77. v-bind="props"
  78. >
  79. </v-btn>
  80. </template>
  81. <v-list density="compact" color="primary">
  82. <v-list-item
  83. v-for="item in localeStore.localeMap"
  84. :key="item.name"
  85. :value="item.lang"
  86. :active="localeStore.currentLocale.lang === item.lang"
  87. @click="handleChangeLocale(item)"
  88. >
  89. <v-list-item-title>{{ item.name }}</v-list-item-title>
  90. </v-list-item>
  91. </v-list>
  92. </v-menu> -->
  93. <div class="d-flex align-center" v-if="showBall">
  94. <message-notification v-if="showBall" :path="paths[3]" class="commonHover2" :class="{'active-route': routeActive === 3}"></message-notification>
  95. </div>
  96. </div>
  97. </div>
  98. </v-toolbar>
  99. <CtDialog :visible="show" title="请选择要切换的公司账号" :footer="true" widthType="2" @close="show = false" @submit="switchSubmit">
  100. <v-radio-group v-model="radios" :hide-details="true">
  101. <v-radio v-for="item in enterpriseList" :key="item.enterpriseId" color="primary" :label="item.enterpriseName" :value="item.enterpriseId"></v-radio>
  102. </v-radio-group>
  103. <!-- <v-btn :loading="loading1" color="primary" variant="text" @click="newRegistering">{{ btnType ? '注册新企业' : '查看申请进度' }}</v-btn> -->
  104. <div class="text-end pr-5 pt-5">
  105. <span class="color-error cursor-pointer text-decoration-underline" @click="newRegistering">{{ btnType ? '都不是我要的?去注册新企业' : '查看申请进度' }}</span>
  106. </div>
  107. </CtDialog>
  108. </div>
  109. </template>
  110. <script setup>
  111. import { computed, onMounted, ref } from 'vue'
  112. import { getToken } from '@/utils/auth'
  113. import { useUserStore } from '@/store/user'
  114. // import { useLocaleStore } from '@/store/locale'
  115. import { useI18n } from '@/hooks/web/useI18n'
  116. import CtDialog from '@/components/CtDialog'
  117. import { useRoute } from 'vue-router'; const route = useRoute()
  118. import { useRouter } from 'vue-router'; const router = useRouter()
  119. import { getUserBindEnterpriseList, getUserRegisterEnterpriseApply } from '@/api/personal/user'
  120. import MessageNotification from '../message.vue'
  121. import { getUserAvatar } from '@/utils/avatar'
  122. import defineListPage from '@/views/entrances/navBar/components/defineListPage'
  123. defineOptions({ name: 'personal-navbar' })
  124. defineProps({
  125. showLoginBtn: {
  126. type: Boolean,
  127. default: true
  128. },
  129. sticky: {
  130. type: Boolean,
  131. default: true
  132. }
  133. })
  134. const showBall = ref(false)
  135. onMounted(() => {
  136. if (getToken()) {
  137. showBall.value = true
  138. }
  139. })
  140. // const useIM = useIMStore()
  141. const { t } = useI18n()
  142. // const localeStore = useLocaleStore()
  143. const userStore = useUserStore()
  144. const paths = [ // 有选中样式-路由列表
  145. '/recruitHome', // 0
  146. '/recruit/personal/position', // 1
  147. '/recruit/personal/company', // 2
  148. '/recruit/personal/message', // 3
  149. '/recruit/personal/myWallet', // 4
  150. '/recruit/personal/personalCenter', // 5
  151. '/recruit/personal/personalCenter/wallet', // 6
  152. ]
  153. const navList = [
  154. // {
  155. // title: '招聘',
  156. // children: [
  157. // {
  158. // title: '门墩儿招聘',
  159. // appList: [
  160. // [{ title: '职位', path: paths[1] }, { title: '公司', path: paths[2] }]
  161. // ]
  162. // }
  163. // ]
  164. // },
  165. { title: '门墩儿招聘', path: '/recruit/personal/recommend', noLeaving: true },
  166. { title: '门墩儿猎头', path: '/headhunting' },
  167. { title: '门墩儿商城', path: '/mall' },
  168. { title: '火苗儿校企' },
  169. // { title: '产业联合会' },
  170. // { title: '数据' },
  171. { title: '了解门墩儿', path: '/about' }
  172. ]
  173. const handleClick = (e, status) => {
  174. if (!e.path) return
  175. if (status && !e.noLeaving) window.open(e.path)
  176. else router.push(e.path)
  177. }
  178. const routeActive = computed(() => {
  179. const index = paths.findIndex(item => item === route.path)
  180. return index
  181. })
  182. const show = ref(false)
  183. const radios = ref(null)
  184. const enterpriseList = ref([])
  185. // 切换为招聘者
  186. const handleSwitch = async () => {
  187. await getApplyInfo() // 查询申请信息(注册进度)
  188. const data = await getUserBindEnterpriseList() // 申请通过才有数据,否则空数组
  189. enterpriseList.value = data || []
  190. if (data?.length) {
  191. radios.value = data[0].enterpriseId
  192. show.value = true
  193. } else {
  194. // router.push('recruit/enterpriseRegister')
  195. newRegistering() // 既没有存在的企业 又没有申请数据 》 进入注册页面
  196. }
  197. }
  198. // 切换提交
  199. const switchSubmit = async () => {
  200. // await logout() // 先退出个人登录
  201. localStorage.setItem('enterpriseId', radios.value)
  202. // 跳转企业路由 且验证是否已完善必填基本信息
  203. window.location.href = '/enterpriseVerification'
  204. // 获取企业账号令牌以及企业用户个人信息
  205. // await userStore.changeRole(radios.value)
  206. }
  207. const btnType = ref(0)
  208. // 查看用户是否有在申请中的数据
  209. const getApplyInfo = async () => {
  210. const data = await getUserRegisterEnterpriseApply()
  211. localStorage.setItem('userApplyInfo', JSON.stringify(data))
  212. const status = data?.status || null // 有数据说明有申请
  213. // 0: 有等待审核的数据或者审核不通过的数据 >查看申请进度
  214. // 1: 没有正在审核的数据 >注册新企业
  215. btnType.value = (status === '0' || status === '2') ? 0 : 1
  216. }
  217. // 注册/查看申请进度
  218. const loading1 = ref(false)
  219. const newRegistering = () => {
  220. loading1.value = true
  221. const path = btnType.value ? '/recruit/entRegister' : '/recruit/entRegister/inReview'
  222. router.replace({ path })
  223. }
  224. const handleToPersonalCenter = () => {
  225. router.push({ path: paths[5] })
  226. }
  227. // 退出登录
  228. const handleLogout = async () => {
  229. await userStore.userLogout(1)
  230. showBall.value = false
  231. if (route.path === '/recruitHome') location.reload()
  232. else router.push({ path: '/recruitHome' })
  233. }
  234. const items = ref([
  235. { title: t('setting.accountSettings'), icon: 'mdi-cog-outline', change: () => router.push({ path: '/recruit/personal/personalCenter/accountSettings' }) },
  236. { title: t('setting.logOut'), icon: 'mdi-logout', change: handleLogout }
  237. ])
  238. let baseInfo = ref(JSON.parse(localStorage.getItem('baseInfo')) || {}) // 人才信息
  239. let userInfo = ref(JSON.parse(localStorage.getItem('userInfo')) || {})
  240. let userAccount = ref(JSON.parse(localStorage.getItem('userAccount')) || {}) // 账户信息
  241. userStore.$subscribe((mutation, state) => {
  242. if (Object.keys(state.baseInfo).length) baseInfo.value = state.baseInfo
  243. if (state.userInfo && Object.keys(state.userInfo).length) userInfo.value = state?.userInfo
  244. if (Object.keys(state.userAccount).length) userAccount.value = state.userAccount
  245. })
  246. const handleLogin = () => {
  247. router.push({ path: '/login' })
  248. }
  249. // 语言切换
  250. // const handleChangeLocale = (item) => {
  251. // localeStore.setCurrentLocale(item)
  252. // location.reload()
  253. // }
  254. </script>
  255. <style lang="scss" scoped>
  256. @import '@/styles/personal/navBar.scss'
  257. </style>