Bläddra i källkod

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

lifanagju_citu 1 år sedan
förälder
incheckning
e96915fa11

+ 0 - 2
components.d.ts

@@ -7,7 +7,6 @@ export {}
 
 declare module 'vue' {
   export interface GlobalComponents {
-    AreaTree: typeof import('./src/components/areaTree/index.vue')['default']
     Autocomplete: typeof import('./src/components/FormUI/autocomplete/index.vue')['default']
     copy: typeof import('./src/components/CtForm/index copy.vue')['default']
     CtBtn: typeof import('./src/components/CtVuetify/CtBtn/index.vue')['default']
@@ -28,7 +27,6 @@ declare module 'vue' {
     Item: typeof import('./src/components/Position/item.vue')['default']
     JobTypeCard: typeof import('./src/components/jobTypeCard/index.vue')['default']
     Positions: typeof import('./src/components/Enterprise/components/positions.vue')['default']
-    Recursive: typeof import('./src/components/areaTree/recursive.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     SimilarPositions: typeof import('./src/components/Position/similarPositions.vue')['default']

+ 8 - 0
src/api/enterprise.js

@@ -24,6 +24,14 @@ export const getEnterpriseSubscribeCheck = async (params) => {
   })
 }
 
+// 求职者关注、取消关注企业
+export const getEnterpriseSubscribe = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/person/enterprise/subscribe',
+    params
+  })
+}
+
 // 企业检索
 export const getEnterpriseSearch = async (params) => {
   return await request.get({

+ 8 - 0
src/api/position.js

@@ -59,6 +59,14 @@ export const getJobFavoriteCheck = async (params) => {
   })
 }
 
+// 求职者是否收藏/取消收藏职位
+export const getJobFavorite = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/person/job/favorite',
+    params
+  })
+}
+
 // 根据企业id统计职位类型的数量
 export const getJobAdvertisedPositionCount = async (params) => {
   return await request.get({

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

@@ -128,14 +128,6 @@ const handleMoreEnterprise = (item) => {
   color: #999;
   line-height: 18px;
 }
-.vline {
-  display: inline-block;
-  width: 1px;
-  height: 10px;
-  vertical-align: middle;
-  background-color: #e0e0e0;
-  margin: 0 10px;
-}
 .company-job-list {
   display: block;
   padding: 4px 20px 12px;

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

@@ -158,12 +158,4 @@ const handleEnterprise = (item) => {
   color: #666;
   font-size: 13px;
 }
-.vline {
-  display: inline-block;
-  width: 1px;
-  height: 10px;
-  vertical-align: middle;
-  background-color: #e0e0e0;
-  margin: 0 10px;
-}
 </style>

+ 1 - 0
src/config/axios/service.js

@@ -42,6 +42,7 @@ const service = axios.create({
 // request拦截器
 service.interceptors.request.use(
   (config) => {
+    config.headers['Accept-Language'] = 'en_EN'
     // 是否需要设置 token
     let isToken = (config.headers || {}).isToken === false
     whiteList.some((v) => {

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

@@ -34,11 +34,13 @@
             </span>
             <v-btn class="half-button" border color="primary" size="small" @click="handleLogin">登录/注册</v-btn>
           </div>
+          
+          <!-- 头像用户名 -->
           <div class="d-flex align-center" v-if="getToken()">
             <span style="cursor: pointer;">消息</span>
             <v-menu open-on-hover>
               <template v-slot:activator="{ props }">
-                <div class="d-flex ml-5 align-center" v-bind="props">
+                <div class="d-flex ml-5 align-center cursor-pointer" v-bind="props" @click="handleToPersonalCenter">
                   <v-avatar>
                     <v-img alt="John" src="https://cdn.vuetifyjs.com/images/john.jpg"></v-img>
                   </v-avatar>
@@ -56,6 +58,8 @@
               </v-list>
             </v-menu>
           </div>
+
+          <!-- 语言切换 -->
           <v-menu>
             <template v-slot:activator="{ props }">
               <v-btn
@@ -127,6 +131,10 @@ const changeRole = () => {
   }
 }
 
+const handleToPersonalCenter = () => {
+  router.push({ path: '/personalCenter' })
+}
+
 // 退出登录
 const userStore = useUserStore()
 const handleLogout = async () => {

+ 7 - 1
src/locales/en.js

@@ -43,7 +43,13 @@ export default {
     recommend: 'Recommended Positions',
     latest: 'Latest Position',
     urgent: 'Urgent Position',
-    allBtn: 'View All Positions'
+    allBtn: 'View All Positions',
+    throughCommunication: 'Through Communication',
+    delivered: 'Delivered',
+    interview: 'Interview',
+    interested: 'Interested',
+    interestedInMe: 'Interested In Me',
+    haveSeenMe: 'Have Seen Me'
   },
   enterprise: {
     moreBtn: 'View More Enterprises'

+ 7 - 1
src/locales/zh-CN.js

@@ -43,7 +43,13 @@ export default {
     recommend: '推荐职位',
     latest: '最新职位',
     urgent: '急聘职位',
-    allBtn: '查看全部职位'
+    allBtn: '查看全部职位',
+    throughCommunication: '沟通过',
+    delivered: '已投递',
+    interview: '面试',
+    interested: '感兴趣',
+    interestedInMe: '对我感兴趣',
+    haveSeenMe: '看过我'
   },
   enterprise: {
     moreBtn: '查看更多企业'

+ 14 - 0
src/router/modules/personal.js

@@ -59,6 +59,20 @@ const personal = [
         component: () => import('@/views/resume/index')
       }
     ]
+  },
+  {
+    path: '/personalCenter',
+    component: Layout,
+    name: 'resume',
+    meta: {
+      title: '个人中心'
+    },
+    children: [
+      {
+        path: '/personalCenter',
+        component: () => import('@/views/PersonalCenter/index')
+      }
+    ]
   }
 ]
 export default personal

+ 9 - 0
src/styles/index.css

@@ -44,3 +44,12 @@
   text-overflow: ellipsis;
   overflow: hidden;
 }
+
+.vline {
+  display: inline-block;
+  width: 1px;
+  height: 10px;
+  vertical-align: middle;
+  background-color: #e0e0e0;
+  margin: 0 10px;
+}

+ 1 - 1
src/styles/index.min.css

@@ -1 +1 @@
-:root{--zIndex-dialog:9999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--default-text:#666}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed #ccc}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
+:root{--zIndex-dialog:9999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--default-text:#666}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed #ccc}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.vline{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}

+ 9 - 0
src/styles/index.scss

@@ -41,4 +41,13 @@
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
+}
+
+.vline {
+  display: inline-block;
+  width: 1px;
+  height: 10px;
+  vertical-align: middle;
+  background-color: #e0e0e0;
+  margin: 0 10px;
 }

+ 129 - 0
src/views/PersonalCenter/dynamic/left.vue

@@ -0,0 +1,129 @@
+<template>
+  <div>
+    <div class="left-top">
+      <v-badge bordered offset-x="10" offset-y="50" color="error" icon="mdi-gender-female">
+        <v-avatar size="x-large" image="https://img.bosszhipin.com/beijin/upload/avatar/20240511/607f1f3d68754fd0a4bb289192623958d852808aec65360d0b597e499d40ff1a18e9c7db720a8820_s.jpg.webp"></v-avatar>
+      </v-badge>
+      <div class="ml-5 content">
+        <div class="username">
+          <span class="mr-2">花城</span>
+          <v-icon class="cursor-pointer" style="width: 80px; height: 22px;">
+            <v-img width="80" height="22" src="https://minio.citupro.com/dev/menduner/upgrade.png"></v-img>
+          </v-icon>
+        </div>
+        <div class="userInfo">
+          44岁<span class="vline"></span>10年以上经验<span class="vline"></span>本科
+        </div>
+        <div class="mt-3">
+          <v-select v-model="selectVal" :items="items" density="compact" variant="outlined" item-title="label" item-value="value" hide-details color="primary"></v-select>
+        </div>
+      </div>
+      <div class="otherInfo">
+        <div class="expect">
+          <span>期望:前端开发工程师</span>
+          <span class="salary">12-13k</span>
+        </div>
+        <div class="edu">
+          <span>北京理工大学·计算机应用与管理</span>
+          <span class="edu-time">2024-2028</span>
+        </div>
+        <div class="work-exp">
+          <span>广州辞图科技有限公司·前端开发工程师</span>
+          <span class="edu-time">1990.01-2024.02</span>
+        </div>
+      </div>
+      <div class="slider-btn">
+        <v-btn class="slider-btn-item" rounded variant="outlined" color="primary" append-icon="mdi-menu-right">在线简历</v-btn>
+      </div>
+    </div>
+    <div class="left-tabs my-3">
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#fff" @click="getPositionList">
+        <v-tab :value="1">{{ $t('position.throughCommunication') }}</v-tab>
+        <v-tab :value="2">{{ $t('position.delivered') }}</v-tab>
+        <v-tab :value="3">{{ $t('position.interview') }}</v-tab>
+        <v-tab :value="4">{{ $t('position.interested') }}</v-tab>
+        <v-tab :value="5">{{ $t('position.interestedInMe') }}</v-tab>
+        <v-tab :value="6">{{ $t('position.haveSeenMe') }}</v-tab>
+      </v-tabs>
+    </div>
+    <div class="left-bottom">岗位</div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'personal-center-left'})
+import { ref } from 'vue'
+
+const tab = ref(1)
+const selectVal = ref(0)
+const items = [
+  { label: '离职-随时到岗', value: 0 },
+  { label: '在职-暂不考虑', value: 1 },
+  { label: '在职-考虑机会', value: 2 },
+  { label: '在职-月内到岗', value: 3 }
+]
+
+const getPositionList = () => {}
+</script>
+
+<style scoped lang="scss">
+.left-top {
+  display: flex;
+  align-items: center;
+  padding: 12px 0 12px 12px;
+  height: 135px;
+  border-radius: 12px;
+  background-color: #fff;
+  .content {
+    height: 100%;
+    .username {
+      font-weight: 500;
+      font-size: 20px;
+      color: #222;
+      height: 24px;
+      line-height: 24px;
+    }
+    .userInfo {
+      height: 21px;
+      margin-top: 8px;
+      color: #666;
+      font-size: 14px;
+    }
+  }
+  .otherInfo {
+    flex: 1;
+    height: 100%;
+    margin-left: 50px;
+    font-size: 14px;
+    font-weight: 500;
+    color: #333;
+    text-align: left;
+    .salary {
+      font-size: 16px;
+      font-family: 'kanzhun-Regular';
+      font-weight: 500;
+      color: var(--v-error-base);
+      margin: -1px 0 0 16px;
+    }
+    .edu-time {
+      color: #999;
+      font-weight: 400;
+      margin-left: 20px;
+    }
+    .edu {
+      margin: 12px 0;
+    }
+  }
+  .slider-btn {
+    position: relative;
+    width: 146px;
+    height: 100%;
+    overflow: hidden;
+    .slider-btn-item {
+      position: absolute;
+      top: 4px;
+      right: -15px;
+    }
+  }
+}
+</style>

+ 11 - 0
src/views/PersonalCenter/dynamic/right.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>right</div>
+</template>
+
+<script setup>
+defineOptions({ name: 'personal-center-right'})
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 27 - 0
src/views/PersonalCenter/index.vue

@@ -0,0 +1,27 @@
+<template>
+  <div class="default-width d-flex pt-3">
+    <div class="left mr-3">
+      <LeftPage></LeftPage>
+    </div>
+    <div class="right">
+      <RightPage></RightPage>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'personal-center'})
+
+import LeftPage from './dynamic/left.vue'
+import RightPage from './dynamic/right.vue'
+</script>
+
+<style scoped lang="scss">
+.left {
+  width: 884px;
+}
+.right {
+  flex: 1;
+  background-color: #fff;
+}
+</style>

+ 14 - 2
src/views/recruit/position/components/details.vue

@@ -17,7 +17,13 @@
             <v-chip size="small" label v-for="(k, i) in info.tagList" :key="i" class="mr-1" color="primary">{{ k }}</v-chip>
           </div>
           <div class="banner-tools-btns float-right">
-            <v-btn class="button-item radius" color="warning" variant="outlined" :prepend-icon="isCollection ? 'mdi-heart' : 'mdi-heart-outline'">{{ isCollection ? '取消收藏': '收藏' }}</v-btn>
+            <v-btn
+              class="button-item radius"
+              color="warning" 
+              variant="outlined" 
+              :prepend-icon="isCollection ? 'mdi-heart' : 'mdi-heart-outline'"
+              @click="handleCollection"
+            >{{ isCollection ? '取消收藏': '收藏' }}</v-btn>
             <v-btn class="button-item mx-2 radius" color="success" variant="outlined">立即沟通</v-btn>
             <v-btn class="button-item radius" color="primary" variant="outlined">投递简历</v-btn>
           </div>
@@ -73,7 +79,7 @@ defineOptions({ name: 'position-details' })
 import { ref } from 'vue'
 import { useRouter } from 'vue-router'
 import { timesTampChange } from '@/utils/date'
-import { getPositionDetails, getSimilarPosition, getJobFavoriteCheck } from '@/api/position'
+import { getPositionDetails, getSimilarPosition, getJobFavoriteCheck, getJobFavorite } from '@/api/position'
 import { dealDictData } from '@/views/recruit/position/components/dict'
 import similarPositions from '@/components/Position/similarPositions.vue'
 import EnterpriseInfo from '@/components/Enterprise/info.vue'
@@ -115,6 +121,12 @@ const getCollectionStatus = async () => {
   isCollection.value = data
 }
 getCollectionStatus()
+
+// 收藏/取消收藏职位
+const handleCollection = async () => {
+  await getJobFavorite({ jobId: id })
+  getCollectionStatus()
+}
 </script>
 
 <style lang="scss" scoped>