Переглянути джерело

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

lifanagju_citu 1 рік тому
батько
коміт
82bbaac4fd

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

@@ -55,4 +55,20 @@ export const getDictData = async (params) => {
     url: '/app-api/system/dict-data/type',
     params
   })
+}
+
+// 获取行业树形
+export const getIndustryTreeData = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/industry/get/tree',
+    params
+  })
+}
+
+// 获取行业列表
+export const getIndustryListData = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/industry/list',
+    params
+  })
 }

+ 0 - 9
src/api/personal/position.js

@@ -1,9 +0,0 @@
-import request from '@/config/axios'
-
-// 获取推荐职位
-export const getPromotedPosition = async (params) => {
-  return await request.get({
-    url: '/app-api/menduner/system/job/advertised/get/recommended',
-    params
-  })
-}

+ 25 - 0
src/api/position.js

@@ -0,0 +1,25 @@
+import request from '@/config/axios'
+
+// 获取推荐职位
+export const getPromotedPosition = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/job/advertised/get/recommended',
+    params
+  })
+}
+
+// 获取最新发布的职位
+export const getLatestPosition = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/job/advertised/get/latest',
+    params
+  })
+}
+
+// 获取急聘的职位
+export const getUrgentPosition = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/job/advertised/get/urgent',
+    params
+  })
+}

+ 29 - 53
src/components/Position/item.vue

@@ -1,27 +1,29 @@
 <template>
   <div class="position-box">
-    <div class="sub-li" v-for="(item, index) in list" :key="index">
+    <div class="sub-li" v-for="(item, index) in list" :key="index" @mouseenter="item.active = true" @mouseleave="item.active = false">
       <div class="job-info">
         <div class="sub-li-top">
           <div class="sub-li-info">
-            <p class="name">{{ item.recruitName }}</p>
+            <p :class="['name', {'name-active': item.active }]">{{ item.name }}</p>
             <v-chip size="x-small" color="error" label variant="outlined" class="mr-1">急聘</v-chip>
             <v-chip size="x-small" color="warning" label variant="outlined">NEW</v-chip>
           </div>
-          <p class="salary">{{ item.salary }}</p>
+          <p class="salary">{{ item.payFrom }}-{{ item.payTo }}/{{ item.payName }}</p>
+        </div>
+        <div style="height: 24px;">
+          <v-chip size="x-small" label v-for="(k, i) in tagList" :key="i" class="mr-1" color="#666">{{ k }}</v-chip>
         </div>
-        <v-chip size="x-small" label v-for="(k, i) in item.welfareList" :key="i" class="mr-1" color="#666">{{ k }}</v-chip>
       </div>
       <div class="sub-li-bottom">
         <div class="user-info">
           <div class="d-flex align-center">
-            <v-img :src="item.company.headImg" width="40" style="height: 40px;" />
-            <span class="names ml-2" style="font-size: 14px">{{ item.company.enterpriseName }}</span>
+            <v-img src="../../assets/logo.png" width="40" style="height: 40px;" />
+            <span class="names ml-2" style="font-size: 14px">{{ item.anotherName }}</span>
           </div>
           <p class="names float-right">
-            <span>{{ item.company.industry }}</span>
+            <span>{{ item.industryName }}</span>
             <span class="vline"></span>
-            <span>{{ item.company.scale }}</span>
+            <span>{{ item.scaleName }}</span>
           </p>
         </div>
       </div>
@@ -31,52 +33,23 @@
 
 <script setup>
 defineOptions({ name: 'position-card-item' })
-const list = [
-  {
-    recruitName: '产品经理',
-    salary: '6-11k',
-    welfareList: ['广州','本科','1-3年'],
-    company: {
-      headImg: 'https://img.bosszhipin.com/beijin/mcs/banner/06123cabdf75ed08313530ec8a42aef2cfcd208495d565ef66e7dff9f98764da.jpg',
-      enterpriseName: '卓越教育',
-      industry: '互联网行业',
-      scale: '0-20人'
-    }
-  },
-  {
-    recruitName: '产品经理',
-    salary: '6-11k',
-    welfareList: ['广州','本科','1-3年'],
-    company: {
-      headImg: 'https://img.bosszhipin.com/beijin/mcs/banner/06123cabdf75ed08313530ec8a42aef2cfcd208495d565ef66e7dff9f98764da.jpg',
-      enterpriseName: '卓越教育',
-      industry: '互联网行业',
-      scale: '0-20人'
-    }
-  },
-  {
-    recruitName: '产品经理',
-    salary: '6-11k',
-    welfareList: ['广州','本科','1-3年'],
-    company: {
-      headImg: 'https://img.bosszhipin.com/beijin/mcs/banner/06123cabdf75ed08313530ec8a42aef2cfcd208495d565ef66e7dff9f98764da.jpg',
-      enterpriseName: '卓越教育',
-      industry: '互联网行业',
-      scale: '0-20人'
-    }
-  },
-  {
-    recruitName: '产品经理',
-    salary: '6-11k',
-    welfareList: ['广州','本科','1-3年'],
-    company: {
-      headImg: 'https://img.bosszhipin.com/beijin/mcs/banner/06123cabdf75ed08313530ec8a42aef2cfcd208495d565ef66e7dff9f98764da.jpg',
-      enterpriseName: '卓越教育',
-      industry: '互联网行业',
-      scale: '0-20人'
-    }
+import { ref, watch } from 'vue'
+const props = defineProps({
+  items: {
+    type: Array,
+    default: () => []
   }
-]
+})
+const tagList = ['广州','本科','1-3年']
+const list = ref([])
+watch(
+  () => props.items, 
+  (newVal) => {
+    list.value = newVal
+  },
+  { immediate: true },
+  { deep: true }
+)
 </script>
 
 <style lang="scss" scoped>
@@ -173,4 +146,7 @@ const list = [
   background-color: #e0e0e0;
   margin: 0 10px;
 }
+.name-active {
+  color: var(--v-primary-base);
+}
 </style>

+ 11 - 10
src/hooks/web/useDictionaries.js

@@ -1,9 +1,8 @@
-
-import { getDictData } from '@/api/common/index'
+import { getDictData, getIndustryListData } from '@/api/common/index'
 // 定义对应的api
-const DICT_CITY_API = {
-  menduner_exp_type: getDictData
-}
+// const DICT_CITY_API = {
+//   menduner_exp_type: getDictData
+// }
 
 const setDict = (type, val, cacheTime = 7200) => {
   localStorage.setItem(type, JSON.stringify({
@@ -12,18 +11,20 @@ const setDict = (type, val, cacheTime = 7200) => {
   }))
 }
 
-export const getDict = (type) => {
+export const getDict = (type, params, apiType = 'dict') => {
     return new Promise((resolve) => {
       const item = localStorage.getItem(type)
       const catchData = item ? JSON.parse(item) : null
       if (catchData && catchData.expire && (Date.now() <= catchData.expire)) {
-        return resolve(catchData.data)
+        return resolve({ data: catchData.data })
       }
       // 传参按照规范参数传
-      const query = {
-        type
+      const query = params ? params : { type }
+      const apiFn = {
+        dict: getDictData,
+        industryList: getIndustryListData
       }
-      DICT_CITY_API[type](query).then(data => {
+      apiFn[apiType](query).then(data => {
         setDict(type, data, Date.now())
         resolve({ data })
       })

+ 2 - 4
src/hooks/web/useTitle.js

@@ -1,14 +1,12 @@
 import { watch, ref } from 'vue'
 import { isString } from '@/utils/is'
-import { useAppStore } from '@/store/app'
 import { useI18n } from './useI18n'
-
+const mTitle = import.meta.env.VITE_APP_TITLE
 
 export const useTitle = (newTitle) => {
-  const appStore = useAppStore()
   const { t } = useI18n()
   const title = ref(
-    newTitle ? `${appStore.title} - ${t(newTitle)}` : appStore.title
+    newTitle ? `${mTitle} - ${t(newTitle)}` : mTitle
   )
 
   watch(

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

@@ -106,7 +106,7 @@ const localeStore = useLocaleStore()
 
 const list = ref([
   { text: '首页', path: '/home' },
-  { text: '职位', path: '' },
+  { text: '职位', path: '/recruit/position' },
   { text: '公司', path: '' }
 ])
 

+ 6 - 8
src/layout/personal/slider.vue

@@ -3,15 +3,13 @@
     <div v-for="item in list" :key="item.mdi" class="slider-box-item">
       <v-tooltip :text="item.tips" location="start">
         <template v-slot:activator="{ props }">
-          <v-icon size="30" class="icons" v-bind="props">{{ item.mdi }}</v-icon>
-        </template>
-        <template #default>
-          <div v-if="item.showImg" class="ma-3" style="text-align: center">
-            <v-img cover aspect-ratio="1/1" src="https://minio.citupro.com/dev/static/mendunerCode.jpg" :width="170" style="height: 170px;"></v-img>
-            <span class="tips-text">关注门墩儿直聘微信公众号</span>
-          </div>
-          <span v-else>{{ item.tips }}</span>
+          <v-btn size="30" class="icons" variant="text" v-bind="props" :icon="item.mdi"></v-btn>
         </template>
+        <div v-if="item.showImg" class="ma-3" style="text-align: center">
+          <v-img cover aspect-ratio="1/1" src="https://minio.citupro.com/dev/static/mendunerCode.jpg" :width="170" style="height: 170px;"></v-img>
+          <span class="tips-text">关注门墩儿直聘微信公众号</span>
+        </div>
+        <span v-else>{{ item.tips }}</span>
       </v-tooltip>
     </div>
   </div>

+ 21 - 0
src/router/modules/recruit.js

@@ -0,0 +1,21 @@
+
+// 门墩儿招聘
+import Layout from '@/layout'
+const recruit = [
+  {
+    path: '/recruit',
+    component: Layout,
+    name: 'recruit',
+    children: [
+      {
+        path: '/recruit/position',
+        component: () => import('@/views/recruit/position'),
+        name: 'recruitPosition',
+        meta: {
+          title: '职位'
+        }
+      }
+    ]
+  }
+]
+export default recruit

+ 7 - 5
src/router/modules/remaining.js

@@ -1,13 +1,15 @@
 import personal from './personal'
 import enterprise from './enterprise'
+import recruit from './recruit'
 import Layout from '@/layout'
 
-const type  = 0
+// const type  = 0
 const routeArray = [
-  personal,
-  enterprise
+  ...recruit,
+  ...personal,
+  ...enterprise
 ]
-const items = routeArray[type]
+// const items = routeArray[type]
 const remainingRouter = [
   {
     path: '/login',
@@ -65,7 +67,7 @@ const remainingRouter = [
       title: '注册企业'
     }
   },
-  ...items
+  ...routeArray
 ]
 
 export default remainingRouter

+ 0 - 20
src/store/app.js

@@ -1,20 +0,0 @@
-import { defineStore } from 'pinia'
-import { ref } from 'vue' 
-
-
-export const useAppStore = defineStore('app', 
-  () => {
-    const title = ref(import.meta.env.VITE_APP_TITLE) // 标题
-
-    const setTitle = (txt) => {
-      title.value = txt
-    }
-    return {
-      title,
-      setTitle
-    }
-  },
-  {
-    persist: true, // ref() 持久化响应
-  }
-)

+ 40 - 14
src/views/Home/personal/components/hotPromotedPositions.vue

@@ -1,19 +1,19 @@
 <template>
   <div>
-    <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#fff">
+    <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#fff" @click="getPositionList">
       <v-tab :value="1">推荐职位</v-tab>
       <v-tab :value="2">最新职位</v-tab>
       <v-tab :value="3">急聘职位</v-tab>
     </v-tabs>
     <v-window v-model="tab" class="mt-3">
       <v-window-item :value="1">
-        <PositionCard></PositionCard>
+        <PositionCard :items="items"></PositionCard>
       </v-window-item>
       <v-window-item :value="2">
-        <PositionCard></PositionCard>
+        <PositionCard :items="items"></PositionCard>
       </v-window-item>
       <v-window-item :value="3">
-        <PositionCard></PositionCard>
+        <PositionCard :items="items"></PositionCard>
       </v-window-item>
     </v-window>
     <div class="text-center">
@@ -24,19 +24,45 @@
 
 <script setup name="hotPromotedPositions">
 import PositionCard from '@/components/Position/item.vue'
-import { ref } from 'vue'
-// import { getPromotedPosition } from '@/api/personal/position'
+import { ref, reactive } from 'vue'
+import { getPromotedPosition, getLatestPosition, getUrgentPosition } from '@/api/position'
 import { getDict } from '@/hooks/web/useDictionaries'
 
-const tab = ref(0)
+const tab = ref(1)
+const items = ref([])
+const dictObj = reactive({
+  payUnit: [], // 薪资单位
+  scale: [], // 规模
+  industry: [] // 行业
+})
+const dictList = [
+  { type: 'menduner_pay_unit', value: 'payUnit', key: 'payUnit', label: 'payName' },
+  { type: 'menduner_scale', value: 'scale', key: 'scale', label: 'scaleName' },
+  { type: 'menduner_industry_type', value: 'industry', key: 'industryId', label: 'industryName', params: {}, apiType: 'industryList' }
+]
 
 // 推荐职位
-// const getPositionList = async () => {
-//   const { list } = await getPromotedPosition({ pageNo: 1, pageSize: 10 })
-//   console.log(list, 'list')
-// }
-// getPositionList()
+const getPositionList = async () => {
+  const api = tab.value === 1 ? getPromotedPosition : (tab.value === 2 ? getLatestPosition : getUrgentPosition)
+  const { list } = await api({ pageNo: 1, pageSize: 9 })
+  dictList.forEach(item => {
+    items.value = list.map(e => {
+      const valueKey = item.type === 'menduner_industry_type' ? 'nameCn' : 'label'
+      const idKey = item.type === 'menduner_industry_type' ? 'id' : 'value'
+      e[item.label] = dictObj[item.value].find(k => Number(k[idKey]) === e[item.key])[valueKey]
+      e.active = false
+      return e
+    })
+  })
+}
 
-const uuu = getDict('menduner_business_status')
-console.log(uuu, 'gggg')
+// 字典
+const getDictList = async () => {
+  dictList.forEach(async (val) => {
+    const { data } = await getDict(val.type, val.params, val.apiType)
+    dictObj[val.value] = data
+  })
+}
+getDictList()
+getPositionList()
 </script>

+ 10 - 1
src/views/recruit/position/index.vue

@@ -1,5 +1,14 @@
 <template>
-  <div>招聘</div>
+  <div>
+    检索
+  </div>
+  <div>筛选条件</div>
+  <div>
+    <div>
+      左侧列表
+    </div>
+    <div>右侧列表</div>
+  </div>
 </template>
 <script setup>
 defineOptions({name: 'position-page'})