Browse Source

职位推荐

lifanagju_citu 9 months ago
parent
commit
6f3616196c

+ 18 - 4
src/views/recruit/personal/position/components/details.vue

@@ -1,6 +1,6 @@
 <template>
   <div style="position: relative;">
-    <div class="default-width banner px-6" id="share">
+    <div class="banner px-6" id="share" :class="{'default-width': defaultWidth}">
       <div class="banner-title d-flex justify-space-between">
         <div class="d-flex align-center">
           <h1 class="ellipsis">{{ info.name }}</h1>
@@ -89,7 +89,7 @@
               <v-btn class="radius button-item" :disabled="delivery" color="primary" @click="handleDelivery">{{ delivery ? $t('position.delivered') : $t('position.submitResume') }}</v-btn>
             </div>
           </div>
-          <div class="content-right" v-if="Object.keys(info).length">
+          <div class="content-right" v-if="Object.keys(info).length && props.showContentRight">
             <!-- 公司信息 -->
             <EnterpriseInfo :info="{ ...info, position: { ...positionInfo } }"></EnterpriseInfo>
             <!-- 相似职位 -->
@@ -177,10 +177,24 @@ import PosterPage from './poster.vue'
 import html2canvas from 'html2canvas'
 import { downloadBase64, DPR } from '@/utils'
 import loginPage from '@/views/common/loginDialog.vue'
+const props = defineProps({
+  defaultWidth: {
+    type: Boolean,
+    default: true
+  },
+  showContentRight: {
+    type: Boolean,
+    default: true
+  },
+  propJobId: {
+    type: String,
+    default: ''
+  },
+})
 
 const { t } = useI18n()
 const router = useRouter()
-const { id } = router.currentRoute.value.params
+const { id } = props.propJobId ? { id: props.propJobId } : router.currentRoute.value.params
 const delivery = ref(false) // 是否已投递简历
 const loading = ref(false)
 const showLogin = ref(false)
@@ -267,7 +281,7 @@ const getPositionDetail = async () => {
   const data = await getPositionDetails({ id })
   info.value = data
   positionInfo.value = { ...dealDictObjData({}, info.value), ...info.value }
-  getSimilarPositionList()
+  if (props.type !=='recommendShow') getSimilarPositionList()
 }
 getPositionDetail()
 

+ 0 - 11
src/views/recruit/personal/recommend/components/details.vue

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

+ 26 - 12
src/views/recruit/personal/recommend/components/item.vue

@@ -1,8 +1,14 @@
 <template>
   <div class="d-flex">
     <div class="position-box">
-      <div class="sub-li" v-for="(item, index) in list" :key="index">
-        <div class="job-info" @click="handlePosition(item)" @mouseenter="item.active = true" @mouseleave="item.active = false">
+      <div class="sub-li"
+        v-for="(item, index) in list" :key="index"
+        :class="{'chosen': chosenIndex === index}"
+        :style="`margin-top: ${index ? '12px' : '0'}`"
+        @mouseenter="item.active = true" @mouseleave="item.active = false"
+        @click="handleClick(item, index)"
+      >
+        <div class="job-info">
           <div class="sub-li-top">
             <div class="sub-li-info">
               <p :class="['name', {'default-active': item.active }]">{{ item.job.name }}</p>
@@ -23,7 +29,7 @@
             <span v-for="(j, i) in item.job.tagList" :key="i" class="mr-3 tags" style="color: #345768;">{{ j }}</span>
           </div>
         </div>
-        <div class="sub-li-bottom" @click="handleEnterprise(item)">
+        <div class="sub-li-bottom">
           <div class="user-info">
             <div class="d-flex align-center">
               <v-avatar size="35">
@@ -49,12 +55,14 @@
 defineOptions({ name: 'position-card-item' })
 import { ref, watch } from 'vue'
 
+const emit = defineEmits([''])
 const props = defineProps({
   items: {
     type: Array,
     default: () => []
   }
 })
+const chosenIndex = ref(0)
 const list = ref([])
 watch(
   () => props.items, 
@@ -70,12 +78,14 @@ const desc = [
   { mdi: 'mdi-clock-time-ten-outline', value: 'expName' }
 ]
 
-const handlePosition = (item) => {
-  console.log(item, 'iiiiiiii')
-}
-const handleEnterprise = (item) => {
-  window.open(`/recruit/personal/company/details/${item.enterprise.id}?key=briefIntroduction`)
+const handleClick = (item, index) => {
+  chosenIndex.value = index
+  list.value.forEach((e, i) => e.active = i === index )
+  emit('selectChange', item)
 }
+// const handleEnterprise = (item) => {
+//   window.open(`/recruit/personal/company/details/${item.enterprise.id}?key=briefIntroduction`)
+// }
 </script>
 
 <style lang="scss" scoped>
@@ -83,19 +93,23 @@ const handleEnterprise = (item) => {
   width: 100%;
   height: 100%;
 }
+.chosen { border: 1px solid var(--v-primary-lighten2) !important; }
 .sub-li {
   position: relative;
   width: 384px;
   height: 149px;
-  margin-bottom: 12px;
+  margin-right: 8px;
+  margin-top: 12px;
   border-radius: 12px;
   padding: 0;
   overflow: hidden;
   cursor: pointer;
-  transition: all .2s linear;
+  // transition: all .2s linear;
   background-color: #fff;
+  border: 1px solid #fff;
   &:hover {
     box-shadow: 0 16px 40px 0 rgba(153, 153, 153, .3);
+    .salary { color: var(--v-primary-base) !important; }
   }
 }
 .job-info {
@@ -170,9 +184,9 @@ const handleEnterprise = (item) => {
 }
 .names {
   font-weight: 500;
-  color: #404040;
   &:hover {
-    color: var(--v-primary-base);
+    // color: var(--v-primary-base);
+    color: #404040;
   }
 }
 </style>

+ 61 - 17
src/views/recruit/personal/recommend/index.vue

@@ -3,51 +3,95 @@
     <div style="background-color: #fff; position: sticky;">
       <buttons :current="0"></buttons>
     </div>
-    <div class="d-flex recommend-content">
-      <div class="mt-3">
-        <PositionList v-if="items.length" :items="items"></PositionList>
+    <Empty v-if="!items.length" message="暂无职位推荐,请前往职位查看其他职位~" class="mt-3 py-15"></Empty>
+    <template v-else>
+      <div class="d-flex">
+        <div class="mt-3">
+          <PositionList v-if="items.length" :items="items" @selectChange="selectChange"></PositionList>
+        </div>
+        <div class="position-details ml-1" style="flex: 1; overflow: hidden;">
+          <div class="position-content">
+            <recommendDetails 
+              v-if="showRecommendDetails && jobId"
+              :defaultWidth="false"
+              :showContentRight="false"
+              :propJobId="jobId"
+            ></recommendDetails>
+          </div>
+        </div>
       </div>
-      <div style="flex: 1;" class="ml-3">right-details</div>
-    </div>
+    </template>
   </div>
 </template>
 
 <script setup>
 defineOptions({ name: 'personalPositionRecommend'})
 import buttons from '@/views/recruit/personal/components/buttons.vue'
-import { ref, reactive } from 'vue'
+import { ref, reactive, nextTick } from 'vue'
 import { getJobAdvertisedSearch } from '@/api/position'
 import { dealDictObjData } from '@/utils/position'
 import PositionList from './components/item'
+import recommendDetails from '@/views/recruit/personal/position/components/details.vue'
+
+const jobId = ref('')
+const showRecommendDetails = ref(false)
+const selectChange = (item) => {
+  jobId.value = item.job.id
+  showRecommendDetails.value = false
+  nextTick(() => showRecommendDetails.value = true)
+}
 
 const query = reactive({
   pageNum: 1,
   pageSize: 10
 })
 const items = ref([])
-
 const getData = async () => {
   const { list } = await getJobAdvertisedSearch(query)
   if (!list.length) return
-  items.value = list.map(e => {
+  items.value = list.map((e, index) => {
+    const id = e?.job?.id || ''
+    if (!id) return ''
+    jobId.value = id
+    showRecommendDetails.value = true
     e.job = { ...e.job, ...dealDictObjData({}, e.job) }
     e.enterprise = { ...e.enterprise, ...dealDictObjData({}, e.enterprise) }
+    e.active = index ? false : true
     return e
-  })
-  if (items.value.length) {
-    items.value[0].active = true
-  }
+  }).filter(Boolean)
+  console.log('personalPositionRecommend-data', items.value)
 }
 getData()
+
 </script>
 
 <style scoped lang="scss">
-.recommend-content {
-  height: calc(100vh - 100px);
-  overflow-y: auto;
+.position-details {
+  position: sticky;
+  top: 62px;
+  border-radius: 12px;
+  background-color: #fff;
+  margin-top: 12px;
+  height: calc(100vh - 127px);
+  widows: 100%;
+  overflow: hidden;
+  .position-content {
+    height: 100%;
+    width: 100%;
+    padding-right: 4px;
+    overflow-y: auto;
+  }
 }
 ::-webkit-scrollbar {
-  width: 0;
-  height: 0;
+  width: 4px;
+  height: 10px;
+}
+::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
+  // 滚动条-颜色
+  background: #c3c3c379;
+}
+::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
+  // 滚动条-底色
+  background: #e5e5e58f;
 }
 </style>