ソースを参照

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

lifanagju_citu 4 週間 前
コミット
ca5a47da43

+ 3 - 0
components.d.ts

@@ -75,4 +75,7 @@ declare module 'vue' {
     VerifySlide: typeof import('./src/components/Verifition/Verify/VerifySlide.vue')['default']
     WangEditor: typeof import('./src/components/FormUI/wangEditor/index.vue')['default']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

+ 47 - 35
src/layout/company/navBar.vue

@@ -2,40 +2,47 @@
   <div>
     <v-toolbar class="banner font-size-14 pl-0" density="compact" style="height: 50px;">
       <div class="innerBox d-flex justify-space-between">
-        <div class="nav-logo" style="cursor: pointer;" @click="handleLogoClick">
-          <v-img src="../../assets/logo.png"  aspect-ratio="16/9" contain :width="97" style="height: 40px"></v-img>
+        <div class="nav-logo" @click="handleLogoClick">
+          <v-img src="../../assets/logo.png"  aspect-ratio="16/9" contain width="90" height="35"></v-img>
         </div>
         
         <div class="d-flex user-nav align-center">
           <!-- 企业logo、企业名称 -->
-          <div class="d-flex align-center cursor-pointer">
-            <v-img @click="enterpriseClick(2)" rounded contain width="40" height="40" :src="baseInfo?.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'" ></v-img>
-            <span @click="enterpriseClick(1)" class="ml-3 commonHover">{{ formatName(baseInfo?.enterpriseAnotherName || baseInfo?.enterpriseName) }}</span>
+          <div class="d-flex align-center cursor-pointer px-4" :class="{'active-route': route.path.includes('/recruit/enterprise/entInfoSetting')}">
+            <v-img @click="enterpriseClick(2)" rounded contain class="enterprise-logo" width="40" height="40" :src="baseInfo?.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'" ></v-img>
+            <span @click="enterpriseClick(1)" class="ml-3">{{ formatName(baseInfo?.enterpriseAnotherName || baseInfo?.enterpriseName) }}</span>
+            <div v-if="baseInfo?.vipFlag && Date.now() < baseInfo?.vipExpireDate" >
+              <svg-icon name="vip" size="25" class="ml-2"></svg-icon>
+            </div>
           </div>
 
-          <div class="enterprise-septal-line"></div>
-          <div class="cursor-pointer mx-3 commonHover" @click="handleLogout(false)">我要求职</div>
+          <v-chip class="ml-4 mr-8" label color="primary" size="small" variant="flat" @click="handleLogout(false)">我要求职</v-chip>
 
-          <div class="enterprise-septal-line"></div>
-          <div class="d-flex align-center mx-3 cursor-pointer commonHover" @click="router.push('/recruit/enterprise/tradingOrder?key=tab_recharge')">
-            <div>剩余M豆:{{ enterpriseUserAccount?.balance ? enterpriseUserAccount?.balance / 100 : 0 }}个</div>
-          </div>
+          <v-chip
+            color="primary"
+            class="cursor-pointer"
+            label
+            size="small"
+            @click="router.push('/recruit/enterprise/tradingOrder?key=tab_recharge')"
+            >
+            剩余M豆
+            <strong class="ml-3">{{ enterpriseUserAccount?.balance ? enterpriseUserAccount?.balance / 100 : 0 }}个</strong>
+          </v-chip>
 
-          <!-- 企业会员标识 -->
-          <div v-if="baseInfo?.vipFlag && Date.now() < baseInfo?.vipExpireDate" >
-            <div class="enterprise-septal-line"></div>
-            <svg-icon name="vip" size="30" class="ml-3"></svg-icon>
-          </div>
-          
           <!-- 头像用户名 -->
-          <div class="d-flex align-center" v-if="showBall">
+          <div class="d-flex align-center mx-4" v-if="showBall">
             <v-menu open-on-hover>
               <template v-slot:activator="{ props }">
-                <div class="d-flex ml-3 pl-2 align-center cursor-pointer" v-bind="props">
+                <div 
+                  class="d-flex align-center cursor-pointer px-4" 
+                  v-bind="props" 
+                  :class="{'active-route': route.path.includes('/recruit/enterprise/staffInfoSetting')}"
+                  @click="router.push('/recruit/enterprise/staffInfoSetting')"
+                >
                   <v-avatar>
                     <v-img alt="" :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)"></v-img>
                   </v-avatar>
-                  <div class="ml-2 commonHover">{{ formatName(baseInfo?.name ?? baseInfo?.phone) }}</div>
+                  <div class="ml-2">{{ formatName(baseInfo?.name ?? baseInfo?.phone) }}</div>
                 </div>
               </template>
 
@@ -76,7 +83,7 @@
           </v-menu> -->
 
           <!-- 消息通知 -->
-          <MessageNotification class="commonHover2" path="/recruit/enterprise/chatTools"></MessageNotification>
+          <MessageNotification path="/recruit/enterprise/chatTools"></MessageNotification>
         </div>
       </div>
     </v-toolbar>
@@ -89,7 +96,7 @@ import { ref, onMounted, computed } from 'vue'
 import { getToken } from '@/utils/auth'
 import { useUserStore } from '@/store/user'; const userStore = useUserStore()
 // import { useLocaleStore } from '@/store/locale'; const localeStore = useLocaleStore()
-import { useRouter } from 'vue-router'; const router = useRouter()
+import { useRouter, useRoute } from 'vue-router'; const router = useRouter(); const route = useRoute()
 import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
 import MessageNotification from '../message.vue'
 import { getUserAvatar } from '@/utils/avatar'
@@ -178,15 +185,12 @@ userStore.$subscribe((mutation, state) => {
   width: 100%;
   height: 50px;
   z-index: var(--zIndex-nav) !important;
-  color: #fff;
-  background-color: var(--color-d5e6e8);
+  color: #0E100F;
+  background-color: #fff;
   padding-left: 0px;
   height: 50px;
   font-size: 15px;
-}
-.hover:hover {
-  cursor: pointer;
-  background: rgba(0, 0, 0, 0.03);
+  border-bottom: 1px solid #e8e6e6;
 }
 .innerBox {
   position: relative;
@@ -196,6 +200,8 @@ userStore.$subscribe((mutation, state) => {
 }
 .nav-logo {
   float: left;
+  cursor: pointer;
+  margin-bottom: 1px;
 }
 .nav {
   font-size: 0;
@@ -208,12 +214,18 @@ userStore.$subscribe((mutation, state) => {
   color: var(--color-333);
   font-size: 15px;
 }
-.enterprise-septal-line {
-  width: 1px;
-  display: inline-block;
-  height: 20px;
-  vertical-align: middle;
-  background-color: #fff;
-  margin: 0 10px;
+.enterprise-logo {
+  border: 1px solid #E1E4E9;
+  border-radius: 4px;
+}
+.active-route {
+  color: #00B760;
+  font-weight: 700;
+  border-bottom: 4px solid #00B760;
+  background-color: #e5f8ef;
+  height: 50px;
+}
+:deep(.v-toolbar__content) {
+  height: 50px !important;
 }
 </style>

+ 219 - 0
src/layout/company/navBarCopy.vue

@@ -0,0 +1,219 @@
+<template>
+  <div>
+    <v-toolbar class="banner font-size-14 pl-0" density="compact" style="height: 50px;">
+      <div class="innerBox d-flex justify-space-between">
+        <div class="nav-logo" style="cursor: pointer;" @click="handleLogoClick">
+          <v-img src="../../assets/logo.png"  aspect-ratio="16/9" contain :width="97" style="height: 40px"></v-img>
+        </div>
+        
+        <div class="d-flex user-nav align-center">
+          <!-- 企业logo、企业名称 -->
+          <div class="d-flex align-center cursor-pointer">
+            <v-img @click="enterpriseClick(2)" rounded contain width="40" height="40" :src="baseInfo?.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'" ></v-img>
+            <span @click="enterpriseClick(1)" class="ml-3 commonHover">{{ formatName(baseInfo?.enterpriseAnotherName || baseInfo?.enterpriseName) }}</span>
+          </div>
+
+          <div class="enterprise-septal-line"></div>
+          <div class="cursor-pointer mx-3 commonHover" @click="handleLogout(false)">我要求职</div>
+
+          <div class="enterprise-septal-line"></div>
+          <div class="d-flex align-center mx-3 cursor-pointer commonHover" @click="router.push('/recruit/enterprise/tradingOrder?key=tab_recharge')">
+            <div>剩余M豆:{{ enterpriseUserAccount?.balance ? enterpriseUserAccount?.balance / 100 : 0 }}个</div>
+          </div>
+
+          <!-- 企业会员标识 -->
+          <div v-if="baseInfo?.vipFlag && Date.now() < baseInfo?.vipExpireDate" >
+            <div class="enterprise-septal-line"></div>
+            <svg-icon name="vip" size="30" class="ml-3"></svg-icon>
+          </div>
+          
+          <!-- 头像用户名 -->
+          <div class="d-flex align-center" v-if="showBall">
+            <v-menu open-on-hover>
+              <template v-slot:activator="{ props }">
+                <div class="d-flex ml-3 pl-2 align-center cursor-pointer" v-bind="props">
+                  <v-avatar>
+                    <v-img alt="" :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)"></v-img>
+                  </v-avatar>
+                  <div class="ml-2 commonHover">{{ formatName(baseInfo?.name ?? baseInfo?.phone) }}</div>
+                </div>
+              </template>
+
+              <v-list>
+                <v-list-item v-for="(item, index) in items" :key="index" @click="item.change">
+                  <template v-slot:prepend>
+                    <v-icon :icon="item.icon"></v-icon>
+                  </template>
+                  <v-list-item-title>{{ item.title }}</v-list-item-title>
+                </v-list-item>
+              </v-list>
+            </v-menu>
+          </div>
+
+          <!-- 语言切换 -->
+          <!-- <v-menu>
+            <template v-slot:activator="{ props }">
+              <v-btn
+                class="ml-3"
+                color="primary"
+                size="small"
+                icon="mdi-translate"
+                v-bind="props"
+              >
+              </v-btn>
+            </template>
+            <v-list density="compact">
+              <v-list-item
+                v-for="item in localeStore.localeMap"
+                :key="item.name"
+                :value="item.lang"
+                :active="localeStore.currentLocale.lang === item.lang"
+                @click="handleChangeLocale(item)"
+              >
+                <v-list-item-title>{{ item.name }}</v-list-item-title>
+              </v-list-item>
+            </v-list>
+          </v-menu> -->
+
+          <!-- 消息通知 -->
+          <MessageNotification class="commonHover2" path="/recruit/enterprise/chatTools"></MessageNotification>
+        </div>
+      </div>
+    </v-toolbar>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'personal-navbar' })
+import { ref, onMounted, computed } from 'vue'
+import { getToken } from '@/utils/auth'
+import { useUserStore } from '@/store/user'; const userStore = useUserStore()
+// import { useLocaleStore } from '@/store/locale'; const localeStore = useLocaleStore()
+import { useRouter } from 'vue-router'; const router = useRouter()
+import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
+import MessageNotification from '../message.vue'
+import { getUserAvatar } from '@/utils/avatar'
+import { formatName } from '@/utils/getText'
+// import { logoutToken } from '@/api/common'
+
+defineProps({
+  sticky: {
+    type: Boolean,
+    default: true
+  }
+})
+
+const showBall = ref(false)
+
+const handleLogoClick = () => { window.open('/recruitHome') } // 点击logo
+
+const enterpriseClick = (tabKey = 1) => {
+  const path = '/recruit/enterprise/entInfoSetting'
+  router.push({ path, query: { tabKey } })
+}
+
+// 退出登录、切换求职者
+const handleLogout = async (exit = true) => {
+  if (exit) await userStore.userLogout(2)
+  router.push({ path: '/recruitHome' })
+}
+
+// 我要求职
+// const handleRecruit = async () => {
+//   // 没有登录个人的则直接清除企业缓存后跳转登录页
+//   if (!getToken()) {
+//     await userStore.userLogout(2)
+//     router.push({ path: '/login' })
+//     return
+//   }
+
+//   // 有登录个人账号时则清除企业登录缓存后跳转到求职者首页
+// 	await logoutToken(getToken(1))
+// 	const isChangeRole = localStorage.getItem('enterpriseId')
+// 	if (isChangeRole) {
+// 		const perAccountData = JSON.parse(localStorage.getItem('perAccountInfo'))
+// 		localStorage.setItem('accountInfo', JSON.stringify(perAccountData))
+// 	} else localStorage.removeItem('accountInfo')
+	
+// 	// 清除企业相关缓存信息
+// 	const enterpriseLocalStorage = ['ENT_REFRESH_TOKEN', 'ENT_ACCESS_TOKEN', 'entBaseInfo', 'isAdmin', 'enterpriseUserAccount', 'entUpdatePassword', 'emailLoginInfo', 'enterpriseStore', 'enterpriseId']
+// 	enterpriseLocalStorage.forEach(e => localStorage.removeItem(e))
+
+// 	router.push('/')
+// }
+
+const menuList = ref([
+  { title: t('setting.editPassword'), icon: 'mdi-shield-lock-open-outline', key: 'editPassword', change: () => router.push({ path: '/recruit/enterprise/staffChangePassword' }) },
+  { title: t('setting.logOut'), icon: 'mdi-logout', change: handleLogout }
+])
+const items = computed(() => {
+  return menuList.value.filter(item => !item.hidden)
+})
+
+onMounted(() => {
+  if (getToken(1)) {
+    showBall.value = true
+  }
+})
+
+// 企业logo、用户基本信息
+let baseInfo = ref(JSON.parse(localStorage.getItem('entBaseInfo')) || {})
+let enterpriseUserAccount = ref(JSON.parse(localStorage.getItem('enterpriseUserAccount')) || {}) // 账户信息
+
+userStore.$subscribe((mutation, state) => {
+  if (Object.keys(state.entBaseInfo).length) baseInfo.value = state.entBaseInfo
+  if (Object.keys(state.enterpriseUserAccount).length) enterpriseUserAccount.value = state.enterpriseUserAccount
+})
+
+// 语言切换
+// const handleChangeLocale = (item) => {
+//   localeStore.setCurrentLocale(item)
+//   location.reload()
+// }
+
+</script>
+
+<style lang="scss" scoped>
+.banner {
+  width: 100%;
+  height: 50px;
+  z-index: var(--zIndex-nav) !important;
+  color: #fff;
+  background-color: var(--color-d5e6e8);
+  padding-left: 0px;
+  height: 50px;
+  font-size: 15px;
+}
+.hover:hover {
+  cursor: pointer;
+  background: rgba(0, 0, 0, 0.03);
+}
+.innerBox {
+  position: relative;
+  width: 100%;
+  align-items: center;
+  padding: 0 30px;
+}
+.nav-logo {
+  float: left;
+}
+.nav {
+  font-size: 0;
+  float: left;
+  margin-left: 50px;
+  height: 49px;
+  line-height: 49px;
+}
+.user-nav {
+  color: var(--color-333);
+  font-size: 15px;
+}
+.enterprise-septal-line {
+  width: 1px;
+  display: inline-block;
+  height: 20px;
+  vertical-align: middle;
+  background-color: #fff;
+  margin: 0 10px;
+}
+</style>

+ 1 - 1
src/layout/enterprise.vue

@@ -6,7 +6,7 @@
       <div class="content-box d-flex flex-column" :style="`width: ${ !isInWhiteList(route.path) ? 'calc(100% - 230px)' : '100%'}`">
         <div v-if="!isInWhiteList(route.path)" class="breadcrumbs_sticky">
           <div class=" d-flex align-center justify-space-between">
-            <v-breadcrumbs :items="system.breadcrumbs" elevation="3">
+            <v-breadcrumbs :items="system.breadcrumbs" elevation="3" density="compact">
               <template v-slot:item="{ item }">
                 <span class="text" :class="{active: !item.disabled}" @click="toPath(item)">{{ item.text }}</span>
               </template>

+ 39 - 19
src/layout/message.vue

@@ -1,12 +1,18 @@
 <template>
-  <v-badge
-    color="error"
-    :content="IM.unreadCount"
-    :model-value="IM.unreadCount > 0"
-    offset-y="10"
-  >
-    <v-btn @click="router.push(path)" append-icon="mdi-bell-outline">通知</v-btn>
-  </v-badge>
+  <div @click.stop="router.push(path)">
+    <v-badge
+      class="cursor-pointer"
+      color="error"
+      :content="IM.unreadCount > 99 ? '99+' : IM.unreadCount"
+      :model-value="IM.unreadCount > 0"
+      offset-y="1"
+      offset-x="4"
+    >
+      <div class="customIcon" :class="{'noUnReadWidth': !IM.unreadCount || IM.unreadCount <= 0}" >
+        <v-icon color="primary" size="16">mdi-bell</v-icon>
+      </div>
+    </v-badge>
+  </div>
 </template>
 
 <script setup>
@@ -15,29 +21,43 @@ import { useIM } from '@/hooks/web/useIM'
 import { useIMStore } from '@/store/im'
 import { useRouter } from 'vue-router'
 
-defineProps({
+const props = defineProps({
   path: {
     type: String,
     default: '/recruit/personal/message'
   }
 })
-
 const router = useRouter()
 
 const IM = useIMStore()
-// useDataSource()
-
-// const { resetConfig } = useIM()
 useIM()
 </script>
 
 <style lang="scss" scoped>
-:deep(.v-btn__content) {
-  font-size: 15px;
-}
-@media (max-width: 1425px) {
-  :deep(.v-btn__content) {
-    font-size: 13px;
+.customIcon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 26px;
+  line-height: 23px;
+  color: #00B760;
+  padding: 0 10px;
+  background-color: #e0f6ec;
+  border-radius: 4px;
+  font-weight: bold;
+  font-size: 12px;
+  cursor: pointer;
+  &:hover {
+    background-color: #d7f3e7;
   }
 }
+.noUnReadWidth {
+  width: 26px;
+}
+:deep(.v-badge__badge) {
+  width: 25px;
+  height: 17px;
+  min-width: 25px;
+  font-size: 10px;
+}
 </style>

+ 49 - 50
src/layout/personal/navBar.vue

@@ -3,68 +3,46 @@
     <v-toolbar
       class="banner"
       density="compact"
-      style="padding-left: 0px;height: 50px;font-size: 15px;"
     >
-      <div class="innerBox d-flex justify-space-between" style="min-width: 1240px;">
-        <div>
-          <div class="nav-logo mr-3 mt-1 cursor-pointer d-flex align-center" @click="router.push('/recruitHome')">
-            <v-img src="../../assets/logo.png"  aspect-ratio="16/9" contain :width="97" style="height: 40px"></v-img>
-            <span class="ml-2" style="margin-top: 6px;" :class="{'active-route' : route.path === '/recruitHome'}">首页</span>
-          </div>
-          <!-- <div class="nav-city">
-            <p class="nav-city-box">
-              <v-icon color="primary">mdi-map-marker</v-icon>
-              <span class="nav-city-selected">广州</span>
-              <span class="switchover-city nav-city-selected">[{{ $t('sys.switchCities') }}]</span>
-            </p>
-          </div> -->
+      <div class="innerBox d-flex align-center">
+        <div class="nav-logo" @click="router.push('/recruitHome')">
+          <v-img src="../../assets/logo.png"  aspect-ratio="16/9" contain width="90" height="35"></v-img>
+        </div>
           
-          <div class="menuList">
-            <div v-for="val in navList" :key="val.name" class="mr-3">
-              <template v-if="val.children">
-                <defineListPage v-bind="$attrs" :title="val.title" :list="val.children" @emitClick="handleClick" :closeOnContentClick="true"></defineListPage>
-              </template>
-              <template v-else>
-                <span 
-                  class="cursor-pointer menuList-first-title"
-                  :class="{'active-route': menuActive(val)}"
-                  @click.stop="handleClick(val, true)">
-                  {{ val.title }}
-                </span>
-              </template>
-            </div>
+        <div class="menuList default-width">
+          <div v-for="val in navList" :key="val.name" :class="{'active-route': menuActive(val)}">
+            <template v-if="val.children">
+              <defineListPage v-bind="$attrs" :title="val.title" :list="val.children" @emitClick="handleClick" :closeOnContentClick="true"></defineListPage>
+            </template>
+            <template v-else>
+              <span 
+                class="cursor-pointer menuList-first-title"
+                @click.stop="handleClick(val, val.title === '首页' ? false : true)">
+                {{ val.title }}
+              </span>
+            </template>
           </div>
         </div>
         
-        <div class="d-flex" style="height: 50px;">
+        <div class="d-flex align-center position-absolute" style="right: 30px;">
           <div class="btns d-flex align-center" v-if="!isLogin && showLoginBtn">
             <v-btn color="primary" style="color: #fff !important; background-color: #00B760;" to="/login">{{ t('login.loginOrRegister') }}</v-btn>
           </div>
           
           <!-- 头像用户名 -->
           <div class="d-flex align-center color-333" v-if="isLogin">
-            <span class="cursor-pointer mr-5 commonHover" v-if="showTeacherLogin" @click="handleSwitchTeacher">切换为老师</span>
-            <span class="cursor-pointer mr-5 commonHover" v-else @click="handleSwitchEnterprise">我要招聘</span>
-            <span class="cursor-pointer commonHover" @click="router.push({ path: paths[6] })">
-              <span>
-                现金:{{ userAccount?.balance && userAccount?.balance > 0 ? (userAccount?.balance / 100.0).toFixed(2) : 0 }}
-                <span style="color: #00000000;">1</span>
-                积分:{{ userAccount?.point || 0 }}
-              </span>
-            </span>
-
             <v-menu open-on-hover>
               <template v-slot:activator="{ props }">
-                <div class="d-flex ml-8 align-center cursor-pointer" :class="{'active-route': route.path.includes('/recruit/personal/personalCenter'), 'vipBox': vip}" v-bind="props" @click="handleToPersonalCenter">
-                  <div style="position: relative;">
+                <div class="d-flex align-center cursor-pointer px-4" :class="{'active-route': route.path.includes('/recruit/personal/personalCenter'), 'vipBox': vip}" v-bind="props" @click="handleToPersonalCenter">
+                  <div class="position-relative d-flex align-center">
                     <v-avatar class="avatar">
                       <v-img alt="" :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)" ></v-img>
                     </v-avatar>
-                    <div v-if="vip" style="position: absolute; left: -9px; bottom: -3px;" @click.stop="router.push('/recruit/personal/personalCenter/memberBenefits/membershipPackage')">
+                    <div v-if="vip" style="position: absolute; right: -9px; bottom: -13px;" @click.stop="router.push('/recruit/personal/personalCenter/memberBenefits/membershipPackage')">
                       <svg-icon name="huangguan1" size="25"></svg-icon>
                     </div>
                   </div>
-                  <div class="ml-3 userName">
+                  <div class="ml-3 font-size-15 userName">
                     {{ baseInfo?.name || userInfo.phone }}
                   </div>
                 </div>
@@ -79,6 +57,27 @@
                 </v-list-item>
               </v-list>
             </v-menu>
+
+            <v-chip
+              class="mx-4 cursor-pointer"
+              color="#008bb7"
+              label
+              size="small"
+              @click="router.push({ path: paths[6] })"
+              >
+              积分
+              <strong class="ml-3">{{ userAccount?.point || 0 }}</strong>
+            </v-chip>
+            <v-chip
+              color="primary"
+              class="cursor-pointer"
+              label
+              size="small"
+              @click="router.push({ path: paths[6] })"
+              >
+              现金
+              <strong class="ml-3">{{ userAccount?.balance && userAccount?.balance > 0 ? (userAccount?.balance / 100.0).toFixed(2) : 0 }}</strong>
+            </v-chip>
           </div>
 
           <!-- 语言切换 -->
@@ -105,8 +104,12 @@
               </v-list-item>
             </v-list>
           </v-menu> -->
-          <div class="d-flex align-center ml-3" v-if="showBall">
-            <message-notification v-if="showBall" :path="paths[3]" class="commonHover2" :class="{'active-route': routeActive === 3}"></message-notification>
+          <div class="d-flex align-center ml-4" v-if="showBall">
+            <message-notification v-if="showBall" :path="paths[3]"></message-notification>
+          </div>
+          <div v-if="isLogin" class="d-flex align-center ml-6 cursor-pointer">
+            <v-chip v-if="showTeacherLogin" label size="small" color="primary" variant="flat" @click="handleSwitchTeacher">切换为老师</v-chip>
+            <v-chip v-else label color="primary" size="small" variant="flat" @click="handleSwitchEnterprise">我要招聘</v-chip>
           </div>
         </div>
       </div>
@@ -189,6 +192,7 @@ const paths = [ // 有选中样式-路由列表
 ]
 
 const navList = ref([
+  { title: '首页', path: '/recruitHome' },
   { title: '门墩儿招聘', path: '/recruit/personal/recommend', dealActive: true },
   { title: '门墩儿猎头', path: '/headhunting' },
   { title: '门墩儿商城', path: '/pointsExchange', isEdit: true },
@@ -209,11 +213,6 @@ const handleClick = (e, status) => {
   else router.push(e.path)
 }
 
-const routeActive = computed(() => {
-  const index = paths.findIndex(item => item === route.path)
-  return index
-})
-
 // 左侧菜单选中状态
 const position = [
   '/recruit/personal/recommend',

+ 4 - 0
src/styles/index.css

@@ -271,6 +271,10 @@ body {
   margin: 0 10px;
 }
 
+.default-text-color {
+  color: #0E100F;
+}
+
 .absolute-center {
   position: absolute;
   top: 50%;

ファイルの差分が大きいため隠しています
+ 0 - 0
src/styles/index.min.css


+ 4 - 0
src/styles/index.scss

@@ -211,6 +211,10 @@
   margin: 0 10px;
 }
 
+.default-text-color {
+  color: #0E100F;
+}
+
 .absolute-center {
   position: absolute;
   top: 50%;

+ 27 - 101
src/styles/personal/navBar.css

@@ -2,8 +2,14 @@
   .menuList {
     font-size: 13px;
   }
-  .user-nav {
-    font-size: 13px;
+  .menuList > div {
+    width: 85px !important;
+  }
+}
+
+@media (max-width: 1480px) {
+  .menuList {
+    margin-left: 120px;
   }
 }
 
@@ -24,137 +30,57 @@
   -webkit-text-fill-color: transparent;
 }
 
-.user-nav .nav-resume-tools {
-  display: inline-block;
-  vertical-align: middle;
-}
-
-.user-nav .nav-resume-tools > a {
-  display: inline-block;
-  font-weight: 500;
-  color: var(--v-primary-base);
-  line-height: 20px;
-  height: auto;
-  padding: 3px 7px;
-  vertical-align: middle;
-  border-radius: 4px;
-  margin-right: 8px;
-  border: 1px solid transparent;
-}
-
 .banner {
   width: 100%;
   height: 50px;
   z-index: var(--zIndex-nav) !important;
   color: #333;
-  background-color: #d6e5e8;
+  background-color: #fff;
+  border-bottom: 1px solid #e8e6e6;
   padding-left: 0px;
-  height: 50px;
-}
-
-.banner .left {
-  height: 100%;
-  display: flex;
-  align-items: center;
-  cursor: pointer;
-}
-
-.hover:hover {
-  cursor: pointer;
-  background: rgba(0, 0, 0, 0.03);
+  font-size: 15px;
 }
 
 .innerBox {
   position: relative;
   width: 100vw;
+  min-width: 1180px;
   margin: 0 auto;
   align-items: center;
-  padding: 0 30px;
+  height: 50px;
+  line-height: 50px;
 }
 
 .nav-logo {
-  float: left;
-}
-
-.nav-city {
-  float: left;
-  position: relative;
-  cursor: pointer;
-  height: 49px;
-  line-height: 49px;
-  color: var(--v-primary-base);
-  margin-left: 50px;
-}
-
-.nav-city-selected {
-  display: inline-block;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  max-width: 95px;
-  vertical-align: middle;
-}
-
-.switchover-city {
-  color: var(--v-primary-base);
-  margin-left: 10px;
-}
-
-.nav {
-  float: left;
-  margin-left: 50px;
-  height: 49px;
-  line-height: 49px;
-}
-
-.nav ul {
-  display: flex;
-  white-space: nowrap;
-  vertical-align: top;
-}
-
-.nav ul li {
-  text-align: center;
-  margin: 0 5px;
-  list-style: none;
-}
-
-.nav li a {
-  display: block;
-  padding: 0 5px;
-  position: relative;
-  text-decoration: none;
-  color: #333;
-}
-
-.routeActive {
-  color: var(--color-333) !important;
-}
-
-.routeActive .aLink {
-  color: #00B760 !important;
-  font-weight: 700;
-  text-decoration: underline !important;
+  position: absolute;
+  left: 20px;
+  margin-bottom: 1px;
 }
 
 .active-route {
   color: #00B760;
   font-weight: 700;
-  border-bottom: 2px solid #00B760;
+  border-bottom: 4px solid #00B760;
+  background-color: #e5f8ef;
+  height: 50px;
 }
 
 .menuList {
   display: flex;
+  align-items: center;
   height: 50px;
-  line-height: 55px;
 }
 
 .menuList div {
-  margin-left: 10px;
+  width: 110px;
+  text-align: center;
 }
 
 .menuList-first-title:hover {
   color: #00B760;
   font-weight: 700;
-  border-bottom: 2px solid #00B760;
+}
+
+:deep(.v-toolbar__content) {
+  height: 50px !important;
 }

ファイルの差分が大きいため隠しています
+ 0 - 0
src/styles/personal/navBar.min.css


+ 26 - 92
src/styles/personal/navBar.scss

@@ -2,8 +2,14 @@
   .menuList {
     font-size: 13px;
   }
-  .user-nav {
-    font-size: 13px;
+  .menuList>div {
+    width: 85px !important;
+  }
+}
+
+@media (max-width: 1480px) {
+  .menuList {
+    margin-left: 120px;
   }
 }
 
@@ -25,123 +31,51 @@
   }
 }
 
-.user-nav .nav-resume-tools {
-  display: inline-block;
-  vertical-align: middle;
-}
-.user-nav .nav-resume-tools > a {
-  display: inline-block;
-  font-weight: 500;
-  color: var(--v-primary-base);
-  line-height: 20px;
-  height: auto;
-  padding: 3px 7px;
-  vertical-align: middle;
-  border-radius: 4px;
-  margin-right: 8px;
-  border: 1px solid transparent;
-}
 .banner {
   width: 100%;
   height: 50px;
   z-index: var(--zIndex-nav) !important;
   color: #333;
-  background-color: #d6e5e8;
+  background-color: #fff;
+  border-bottom: 1px solid #e8e6e6;
   padding-left: 0px;
-  height: 50px;
-  .left {
-    height: 100%;
-    display: flex;
-    align-items: center;
-    cursor: pointer;
-  }
-}
-.hover:hover {
-  cursor: pointer;
-  background: rgba(0, 0, 0, 0.03);
+  font-size: 15px; 
 }
 .innerBox {
   position: relative;
   width: 100vw;
-  // width: 1184px;
-  // max-width: 1184px;
+  min-width: 1180px;
   margin: 0 auto;
   align-items: center;
-  padding: 0 30px;
+  height: 50px;
+  line-height: 50px;
 }
 .nav-logo {
-  float: left;
-}
-.nav-city {
-  float: left;
-  position: relative;
-  cursor: pointer;
-  height: 49px;
-  line-height: 49px;
-  color: var(--v-primary-base);
-  margin-left: 50px;
-}
-.nav-city-selected {
-  display: inline-block;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  max-width: 95px;
-  vertical-align: middle;
-}
-.switchover-city {
-  // font-size: 12px;
-  color: var(--v-primary-base);
-  margin-left: 10px;
-}
-.nav {
-  // font-size: 0;
-  float: left;
-  margin-left: 50px;
-  height: 49px;
-  line-height: 49px;
-}
-.nav ul {
-  display: flex;
-  white-space: nowrap;
-  vertical-align: top;
-}
-.nav ul li {
-  text-align: center;
-  margin: 0 5px;
-  list-style: none;
-}
-.nav li a {
-  display: block;
-  padding: 0 5px;
-  position: relative;
-  text-decoration: none;
-  color: #333;
-}
-.routeActive { // 选中样式
-  color: var(--color-333) !important;
-  .aLink {
-    color: #00B760 !important;
-    font-weight: 700;
-    text-decoration: underline !important; // 多个下划线
-  }
+  position: absolute;
+  left: 20px;
+  margin-bottom: 1px;
 }
 .active-route {
   color: #00B760;
   font-weight: 700;
-  border-bottom: 2px solid #00B760;
+  border-bottom: 4px solid #00B760;
+  background-color: #e5f8ef;
+  height: 50px;
 }
 
 .menuList {
   display: flex;
+  align-items: center;
   height: 50px;
-  line-height: 55px;
   div {
-    margin-left: 10px;
+    width: 110px;
+    text-align: center;
   }
 }
 .menuList-first-title:hover {
   color: #00B760;
   font-weight: 700;
-  border-bottom: 2px solid #00B760;
 }
+:deep(.v-toolbar__content) {
+  height: 50px !important;
+}

+ 1 - 1
src/views/recruit/components/message/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="message" :class="{'default-width': !isEnterprise}" :style="`height: calc(100vh - ${isEnterprise ? '130px' : '50px'});`">
+  <div class="message" :class="{'default-width': !isEnterprise, 'py-3': !isEnterprise}" :style="`height: calc(100vh - ${isEnterprise ? '130px' : '50px'});`">
     <div class="message-left d-flex flex-column">
       <div class="message-left-search d-flex align-center px-3 justify-space-between" >
         <div>

+ 1 - 0
src/views/recruit/personal/companyDetail/index.vue

@@ -173,6 +173,7 @@ const loginClose = () => {
   background-color: #fff;
   padding: 0 0 20px;
   min-height: 60vh;
+  margin-top: 62px;
 }
 .sticky {
   position: sticky;

+ 1 - 1
src/views/recruit/personal/home/components/homeJobTypeCard/index.vue

@@ -188,7 +188,7 @@ const handleClick = (item) => {
   border-radius: 12px;
   top: 10px;
   left: 390px;
-  background-color: rgba(255, 255, 255 , .8);
+  background-color: rgba(255, 255, 255 , .9);
 }
 .hasPageCard {
   width: 100%;

+ 10 - 3
src/views/recruit/personal/position/components/details.vue

@@ -1,6 +1,6 @@
 <template>
   <div style="position: relative;">
-    <div class="banner px-6" id="share" :class="{'default-width': defaultWidth}">
+    <div class="banner px-6" id="share" :class="{'default-width': defaultWidth}" :style="{'margin-top': isRecommend || isEnterprise ? '0' : '62px'}">
       <div class="sticky" :style="{'top': isRecommend || isEnterprise ? '0' : '50px'}">
         <div class="banner-title d-flex justify-space-between align-center pt-5">
           <div class="d-flex align-center justify-between">
@@ -295,7 +295,6 @@ const share = ref()
 // 生成图片
 const generateAndDownloadImage = async () => {
   if (!share.value) return
-  loading.value = true
   try {  
     const canvas = await html2canvas(share.value.$el, { scale: DPR(), useCORS: true })
     const image = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '')
@@ -307,6 +306,7 @@ const generateAndDownloadImage = async () => {
     }
     showPreview.value = true
   } catch (error) {
+    loading.value = false
     console.error('Error generating image:', error)
     Snackbar.error('图片生成失败')
   }
@@ -375,7 +375,14 @@ const handleShare = async () => {
     })
     return
   }
-  generateAndDownloadImage() // 生成海报
+  
+  loading.value = true
+  try {
+    await share.value.getQrCode()
+    generateAndDownloadImage() // 生成海报
+  } catch {
+    loading.value = false
+  }
 }
 
 // 收藏&取消收藏职位

+ 5 - 1
src/views/recruit/personal/position/components/poster.vue

@@ -121,13 +121,17 @@ const getQrCode = async () => {
   const data = await getJobAdvertisedShareQrcode(query)
   url.value = 'data:image/png;base64,' + data
 }
-getQrCode()
+// getQrCode()
 
 const desc = [
   { value: 'areaName' },
   { value: 'expName' },
   { value: 'eduName' }
 ]
+
+defineExpose({
+  getQrCode
+})
 </script>
 
 <style lang="scss" scoped>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません