navBar.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <div>
  3. <v-toolbar
  4. class="banner"
  5. density="compact"
  6. style="padding-left: 0px;height: 50px;font-size: 14px;"
  7. >
  8. <div class="innerBox d-flex justify-space-between">
  9. <div>
  10. <div class="nav-logo" style="cursor: pointer;" @click="handleLogoClick">
  11. <v-img src="../../assets/logo.png" aspect-ratio="16/9" cover :width="90" style="height: 40px"></v-img>
  12. </div>
  13. <div class="nav-city">
  14. <p class="nav-city-box">
  15. <v-icon color="primary">mdi-map-marker</v-icon>
  16. <span class="nav-city-selected">广州</span>
  17. <span class="switchover-city nav-city-selected">[{{ $t('sys.switchCities') }}]</span>
  18. </p>
  19. </div>
  20. <div class="nav">
  21. <ul>
  22. <li v-for="k in list" :key="k.text">
  23. <a :href="k.path" style="font-size: 14px;">{{ k.text }}</a>
  24. </li>
  25. </ul>
  26. </div>
  27. </div>
  28. <div class="d-flex user-nav">
  29. <div class="btns d-flex align-center" v-if="!getToken()">
  30. <v-btn class="half-button" border color="primary" size="small" @click="handleLogin">{{ $t('login.loginOrRegister') }}</v-btn>
  31. </div>
  32. <!-- 头像用户名 -->
  33. <div class="d-flex align-center" v-if="getToken()">
  34. <span class="cursor-pointer mr-5" @click="changeLoginType">我要招聘</span>
  35. <span class="cursor-pointer" @click="router.push({ path: '/recruit/personal/myWallet' })">{{t('resume.accountWithdrawal')}}:{{ userAccount?.balance || 0 }}</span>
  36. <span class="mr-3 ml-3 cursor-pointer" @click="router.push({ path: '/recruit/personal/myWallet' })">{{t('resume.goldCoins')}}:{{ userAccount?.point || 0 }}</span>
  37. <v-menu open-on-hover>
  38. <template v-slot:activator="{ props }">
  39. <div class="d-flex ml-3 align-center cursor-pointer" v-bind="props" @click="handleToPersonalCenter">
  40. <v-avatar>
  41. <v-img alt="John" :src="baseInfo?.avatar || 'https://minio.citupro.com/dev/menduner/7.png'"></v-img>
  42. </v-avatar>
  43. <div class="ml-3">{{ baseInfo?.name || $t('sys.tourist') }}</div>
  44. </div>
  45. </template>
  46. <v-list>
  47. <v-list-item v-for="(item, index) in items" :key="index" @click="item.change">
  48. <template v-slot:prepend>
  49. <v-icon :icon="item.icon"></v-icon>
  50. </template>
  51. <v-list-item-title>{{ item.title }}</v-list-item-title>
  52. </v-list-item>
  53. </v-list>
  54. </v-menu>
  55. </div>
  56. <!-- 语言切换 -->
  57. <!-- <v-menu>
  58. <template v-slot:activator="{ props }">
  59. <v-btn
  60. class="ml-3"
  61. color="primary"
  62. icon="mdi-translate"
  63. size="small"
  64. v-bind="props"
  65. >
  66. </v-btn>
  67. </template>
  68. <v-list density="compact" color="primary">
  69. <v-list-item
  70. v-for="item in localeStore.localeMap"
  71. :key="item.name"
  72. :value="item.lang"
  73. :active="localeStore.currentLocale.lang === item.lang"
  74. @click="handleChangeLocale(item)"
  75. >
  76. <v-list-item-title>{{ item.name }}</v-list-item-title>
  77. </v-list-item>
  78. </v-list>
  79. </v-menu> -->
  80. <div class="d-flex align-center" v-if="showBall">
  81. <!-- <span class="cursor-pointer mx-5" @click="router.push({ path: '/recruit/personal/TaskCenter' })">{{ $t('sys.signIn') }}</span> -->
  82. <!-- <span class="cursor-pointer" @click="router.push({ path: '/recruit/personal/message' })">{{ $t('sys.news') }}</span> -->
  83. <!-- <v-badge
  84. color="error"
  85. dot
  86. :model-value="useIM.unreadCount > 0"
  87. >
  88. <v-btn class="ml-1" size="small" icon="mdi-bell-outline" @click="router.push({ path: '/recruit/personal/message' })"></v-btn>
  89. </v-badge> -->
  90. <message-notification v-if="showBall" path="/recruit/personal/message"></message-notification>
  91. </div>
  92. </div>
  93. </div>
  94. </v-toolbar>
  95. <CtDialog :visible="show" title="请选择要切换的公司账号" :footer="true" widthType="2" @close="show = false" @submit="handleSubmit">
  96. <v-radio-group v-model="radios">
  97. <v-radio v-for="item in enterpriseList" :key="item.enterpriseId" color="primary" :label="item.enterpriseName" :value="item.enterpriseId"></v-radio>
  98. </v-radio-group>
  99. </CtDialog>
  100. </div>
  101. </template>
  102. <script setup>
  103. import { onMounted, ref } from 'vue'
  104. import { getToken } from '@/utils/auth'
  105. import { useUserStore } from '@/store/user'
  106. // import { useLocaleStore } from '@/store/locale'
  107. import { useI18n } from '@/hooks/web/useI18n'
  108. import CtDialog from '@/components/CtDialog'
  109. import { useRouter } from 'vue-router'; const router = useRouter()
  110. import { getUserBindEnterpriseList, getUserRegisterEnterpriseApply } from '@/api/personal/user'
  111. import MessageNotification from '../message.vue'
  112. // import { useIMStore } from '@/store/im'
  113. defineOptions({ name: 'personal-navbar' })
  114. defineProps({
  115. sticky: {
  116. type: Boolean,
  117. default: true
  118. }
  119. })
  120. const showBall = ref(false)
  121. onMounted(() => {
  122. if (getToken()) {
  123. showBall.value = true
  124. }
  125. })
  126. // const useIM = useIMStore()
  127. const { t } = useI18n()
  128. // const localeStore = useLocaleStore()
  129. const userStore = useUserStore()
  130. const list = ref([
  131. { text: t('common.home'), path: '/recruitHome' },
  132. { text: t('common.position'), path: '/recruit/personal/position' },
  133. { text: t('common.company'), path: '/recruit/personal/company' }
  134. ])
  135. const handleLogoClick = () => { window.open('/') } // 点击logo
  136. const handleSubmit = () => { toEnterprise(radios.value) }
  137. // 查看用户是否有企业
  138. const show = ref(false)
  139. const radios = ref(null)
  140. const enterpriseList = ref([])
  141. const changeLoginType = async () => {
  142. const data = await getUserBindEnterpriseList() // 申请通过才有数据,否则空数组
  143. enterpriseList.value = data || []
  144. if (data?.length) {
  145. if (data.length > 1) {
  146. show.value = true
  147. radios.value = data[0].enterpriseId
  148. } else {
  149. //只有一个企业直接切换
  150. toEnterprise(data[0].enterpriseId)
  151. }
  152. }
  153. else getApplyInfo()
  154. }
  155. // 切换为招聘者
  156. const toEnterprise = async (enterpriseId) => {
  157. await getUserBindEnterpriseList({ enterpriseId })
  158. // 获取企业账号令牌以及企业用户个人信息
  159. await userStore.changeRole(enterpriseId)
  160. router.push({ path: '/recruit/enterprise' })
  161. }
  162. // 查看用户是否有在申请中的数据
  163. const getApplyInfo = async () => {
  164. const data = await getUserRegisterEnterpriseApply()
  165. const bool = data && Object.keys(data).length // 已经有数据说明已经申请过了
  166. const path = bool ? '/recruit/enterprise/register/inReview' : '/recruit/enterprise/register'
  167. router.replace({ path })
  168. }
  169. const handleToPersonalCenter = () => {
  170. router.push({ path: '/recruit/personal/personalCenter' })
  171. }
  172. // 退出登录
  173. const handleLogout = async () => {
  174. await userStore.userLogout(1)
  175. router.push({ path: '/login' })
  176. }
  177. const items = ref([
  178. { title: t('vipPackage.purchasePackage'), icon: 'mdi-gift-outline', change: () => router.push({ path: '/recruit/personal/purchasePackage' }) },
  179. { title: t('resume.onlineResume'), icon: 'mdi-list-box-outline', change: () => router.push({ path: '/recruit/personal/resume' }) },
  180. { title: t('setting.accountSettings'), icon: 'mdi-cog-outline', change: () => router.push({ path: '/recruit/personal/accountSettings/accountBinding' }) },
  181. // { title: t('setting.switchToRecruit'), icon: 'mdi-swap-horizontal', change: changeLoginType },
  182. { title: t('publicRecruitment.bountyRewards'), icon: 'mdi-google-circles-extended', change: () => router.push({ path: '/publicRecruitment' }) },
  183. { title: t('points.wallet'), icon: ' mdi-database-outline', change: () => router.push({ path: '/recruit/personal/myWallet' }) },
  184. { title: t('taskCenter.taskCenter'), icon: 'mdi-calendar-check-outline', change: () => router.push({ path: '/recruit/personal/TaskCenter' }) },
  185. { title: t('setting.logOut'), icon: 'mdi-logout', change: handleLogout }
  186. ])
  187. let baseInfo = ref(JSON.parse(localStorage.getItem('baseInfo')) || {}) // 人才信息
  188. let userAccount = ref(JSON.parse(localStorage.getItem('userAccount')) || {}) // 账户信息
  189. userStore.$subscribe((mutation, state) => {
  190. if (Object.keys(state.baseInfo).length) baseInfo.value = state.baseInfo
  191. if (Object.keys(state.userAccount).length) userAccount.value = state.userAccount
  192. })
  193. const handleLogin = () => {
  194. router.push({ path: '/login' })
  195. }
  196. // 语言切换
  197. // const handleChangeLocale = (item) => {
  198. // localeStore.setCurrentLocale(item)
  199. // location.reload()
  200. // }
  201. </script>
  202. <style lang="scss" scoped>
  203. @import '@/styles/personal/navBar.scss'
  204. </style>