Browse Source

职位编辑

Xiao_123 11 months ago
parent
commit
2fc00bff6f

+ 8 - 0
src/api/position.js

@@ -142,4 +142,12 @@ export const getJobAdvertisedList = async (params) => {
     url: '/app-admin-api/menduner/system/job-advertised/page',
     params
   })
+}
+
+// 招聘端-发布职位详情
+export const getJobDetails = async (params) => {
+  return await request.get({
+    url: '/app-admin-api/menduner/system/job-advertised/detail',
+    params
+  })
 }

+ 1 - 2
src/components/DatePicker/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div style="width: 100%">
     <VueDatePicker
-      :locale="getCurrentLocaleLang() || 'zh-CN'"
+      locale="zh-CN"
       :disabled="options?.disabled || false"
       :range="options?.range || false"
       :model-type="options?.format || 'yyyy.MM.dd'"
@@ -24,7 +24,6 @@
 <script setup>
 defineOptions({ name: 'date-picker'})
 import { computed } from 'vue';
-import { getCurrentLocaleLang } from '@/utils/lang'
 
 const props = defineProps({
   width: {

+ 1 - 1
src/components/FormUI/autocomplete/index.vue

@@ -30,7 +30,7 @@ import { debounce } from 'lodash'
 import { ref, defineEmits, watch } from 'vue';
 defineOptions({ name:'FormUI-v-autocomplete'})
 
-const props = defineProps({item: Object, modelValue: [String, Number]})
+const props = defineProps({item: Object, modelValue: [String, Number, Boolean]})
 
 const value = ref()
 watch(

+ 9 - 1
src/router/modules/enterprise.js

@@ -5,7 +5,7 @@ const enterprise = [
   {
     path: '/enterprise',
     show: true,
-    redirect: '/enterprise/talentPool',
+    redirect: '/enterprise/position',
   },
   {
     path: '/enterprise/talentPool',
@@ -75,6 +75,14 @@ const enterprise = [
           title: '职位编辑'
         },
         component: () => import('@/views/enterprise/positionManagement/components/add.vue')
+      },
+      {
+        path: '/enterprise/position/details/:id',
+        show: true,
+        meta: {
+          title: '职位详情'
+        },
+        component: () => import('@/views/enterprise/positionManagement/components/details.vue')
       }
     ]
   },

+ 5 - 0
src/styles/index.css

@@ -27,6 +27,11 @@
   margin: 0 auto;
 }
 
+.defaultLink {
+  color: #008978;
+  cursor: pointer;
+}
+
 .default-active {
   color: var(--v-primary-base) !important;
 }

+ 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}.vline{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:#666;font-size:14px}
+: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}.defaultLink{color:#008978;cursor:pointer}.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}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:#666;font-size:14px}

+ 12 - 2
src/styles/index.scss

@@ -9,40 +9,47 @@
   --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;
-  // align-items: center;
 }
+
 .defaultLink {
   // color:#5aabff;
   color:#008978;
   cursor:pointer;
   // text-decoration: underline;
 }
+
 // 高亮
 .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;
@@ -64,12 +71,14 @@
   padding: 20px 30px;
   background-color: #fff;
 }
+
 .resume-header {
   display: flex;
   justify-content: space-between;
   align-items: center;
   height: 36px;
 }
+
 .resume-title {
   font-weight: 700;
   font-size: 18px;
@@ -77,6 +86,7 @@
   padding-left: 12px;
   line-height: 17px;
 }
+
 .resumeNoDataText {
   color: #666;
   font-size: 14px;

+ 12 - 3
src/styles/recruit/company.css

@@ -62,8 +62,10 @@
 
 .company-info-top {
   display: flex;
-  height: 76px;
-  padding: 16px 20px;
+  height: 90px;
+  line-height: 90px;
+  padding: 0 20px;
+  align-items: center;
   overflow: hidden;
 }
 
@@ -91,8 +93,15 @@
 
 .company-info-bottom {
   width: 100%;
+  height: 41px;
   overflow: hidden;
   white-space: nowrap;
-  padding: 16px 20px;
+  padding: 10px 20px;
   background-color: #f8fcfb;
+  font-size: 14px;
+  color: #666;
+}
+
+.company-info-bottom .bottom-tag {
+  width: 243px;
 }

+ 1 - 1
src/styles/recruit/company.min.css

@@ -1 +1 @@
-.label-title{width:64px;font-weight:500;margin-right:24px;color:#222}.label-content{flex:1}.label-color{color:#222;font-size:14px;margin-right:24px;display:inline-block;cursor:pointer}.label-color:hover{color:var(--v-primary-base)}.actives{color:var(--v-primary-base);font-weight:600}.company-box{display:flex;flex-wrap:wrap}.sub-li{position:relative;width:calc((100% - 36px) / 4);min-width:calc((100% - 36px) / 4);max-width:calc((100% - 36px) / 4);margin:0 12px 12px 0;height:130px;border-radius:12px;padding:0;overflow:hidden;transition:all .2s linear;background-color:#fff;cursor:pointer}.sub-li:nth-child(4n){margin-right:0}.sub-li:hover{box-shadow:0 16px 40px 0 rgba(153,153,153,0.3)}.company-info{float:left;margin-left:16px;width:282px}.company-info-top{display:flex;height:76px;padding:16px 20px;overflow:hidden}.company-info h3{height:22px;font-size:16px;font-weight:400;color:#222;line-height:22px;margin:0 0 4px 0;padding:0;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.company-info p{height:18px;font-size:13px;font-weight:400;color:#999;line-height:18px}.company-info-bottom{width:100%;overflow:hidden;white-space:nowrap;padding:16px 20px;background-color:#f8fcfb}
+.label-title{width:64px;font-weight:500;margin-right:24px;color:#222}.label-content{flex:1}.label-color{color:#222;font-size:14px;margin-right:24px;display:inline-block;cursor:pointer}.label-color:hover{color:var(--v-primary-base)}.actives{color:var(--v-primary-base);font-weight:600}.company-box{display:flex;flex-wrap:wrap}.sub-li{position:relative;width:calc((100% - 36px) / 4);min-width:calc((100% - 36px) / 4);max-width:calc((100% - 36px) / 4);margin:0 12px 12px 0;height:130px;border-radius:12px;padding:0;overflow:hidden;transition:all .2s linear;background-color:#fff;cursor:pointer}.sub-li:nth-child(4n){margin-right:0}.sub-li:hover{box-shadow:0 16px 40px 0 rgba(153,153,153,0.3)}.company-info{float:left;margin-left:16px;width:282px}.company-info-top{display:flex;height:90px;line-height:90px;padding:0 20px;align-items:center;overflow:hidden}.company-info h3{height:22px;font-size:16px;font-weight:400;color:#222;line-height:22px;margin:0 0 4px 0;padding:0;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.company-info p{height:18px;font-size:13px;font-weight:400;color:#999;line-height:18px}.company-info-bottom{width:100%;height:41px;overflow:hidden;white-space:nowrap;padding:10px 20px;background-color:#f8fcfb;font-size:14px;color:#666}.company-info-bottom .bottom-tag{width:243px}

+ 11 - 3
src/styles/recruit/company.scss

@@ -57,8 +57,10 @@
 }
 .company-info-top {
   display: flex;
-  height: 76px;
-  padding: 16px 20px;
+  height: 90px;
+  line-height: 90px;
+  padding: 0 20px;
+  align-items: center;
   overflow: hidden;
 }
 .company-info h3 {
@@ -83,8 +85,14 @@
 }
 .company-info-bottom {
   width: 100%;
+  height: 41px;
   overflow: hidden;
   white-space: nowrap;
-  padding: 16px 20px;
+  padding: 10px 20px;
   background-color: #f8fcfb;
+  font-size: 14px;
+  color: #666;
+  .bottom-tag {
+    width: 243px;
+  }
 }

+ 5 - 6
src/views/enterprise/positionManagement/components/add.vue

@@ -27,8 +27,8 @@
 defineOptions({ name: 'enterprise-position-add'})
 import { ref } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
-import { dealDictArrayData } from '@/views/recruit/position/components/dict'
-import { saveJobAdvertised, getJobAdvertisedList } from '@/api/position'
+import { dealDictObjData } from '@/views/recruit/position/components/dict'
+import { saveJobAdvertised, getJobDetails } from '@/api/position'
 import baseInfo from './baseInfo.vue'
 import jobRequirements from './jobRequirements.vue'
 import Snackbar from '@/plugins/snackbar'
@@ -80,10 +80,9 @@ const handleSave = async () => {
 
 // 获取编辑的职位详情
 const getPositionDetail = async (id) => {
-  const { list } = await getJobAdvertisedList({ pageSize: 1, pageNo: 1, id })
-  if (!list.length) return
-  const arr = dealDictArrayData([], list)
-  itemData.value = arr[0]
+  const data = await getJobDetails({ id })
+  if (!data && !Object.keys(data).length) return
+  itemData.value = {...data, ...dealDictObjData({}, data)}
 }
 
 // 有id为编辑

+ 26 - 0
src/views/enterprise/positionManagement/components/baseInfo.vue

@@ -55,6 +55,30 @@ const items = ref({
       noParam: true,
       rules: [v => !!v || '请选择职位类型']
     },
+    {
+      type: 'autocomplete',
+      key: 'top',
+      value: null,
+      label: '是否置顶展示 *',
+      itemText: 'label',
+      itemValue: 'value',
+      rules: [v => !!v || '请选择是否置顶展示'],
+      items: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ]
+    },
+    {
+      type: 'datePicker',
+      key: 'expireTime',
+      value: null,
+      class: 'mb-3',
+      options: {
+        format: 'timestamp',
+        placeholder: '过期时间 *',
+      },
+      rules: [v => !!v || '请选择过期时间']
+    },
     {
       type: 'textarea',
       key: 'content',
@@ -106,6 +130,7 @@ watch(
   (val) => {
     if (!Object.keys(val).length) return
     items.value.options.forEach(e => {
+      if (e.key === 'top') return e.value = props.itemData[e.key] === true ? '1' : '0'
       if (e.labelKey) {
         query[e.key] = val[e.key]
         e.value = val[e.labelKey]
@@ -136,6 +161,7 @@ const getQuery = async () => {
   const obj = {}
   items.value.options.forEach(e => {
     if (e.noParam) return
+    if (e.key === 'top') return obj[e.key] = e.value === '1' ? true : false
     obj[e.key] = e.value
   })
   query = Object.assign(query, obj)

+ 192 - 0
src/views/enterprise/positionManagement/components/details.vue

@@ -0,0 +1,192 @@
+<template>
+  <div>
+    <div class="banner px-6">
+      <div class="banner-title">
+        <h1 class="ellipsis">{{ info.name }}</h1>
+        <span class="salary">{{ info.payFrom }}-{{ info.payTo }}/{{ positionInfo.payName }}</span>
+        <span class="refresh-time">{{ timesTampChange(info.updateTime) }} {{ $t('common.refresh') }} <v-icon color="warning" size="20">mdi-alert-outline</v-icon></span>
+      </div>
+      <div class="banner-tags mt-4">
+        <span v-for="k in desc" :key="k.mdi" class="mr-10">
+          <v-icon color="#666" size="20">{{ k.mdi }}</v-icon>
+          <span class="ml-1">{{ positionInfo[k.value] }}</span>
+        </span>
+      </div>
+      <div class="banner-tools my-4">
+        <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="d-flex justify-end mb-5">
+        <div class="banner-tools-btns">
+          <v-btn class="button-item radius" color="primary" variant="outlined">{{ $t('common.edit') }}</v-btn>
+        </div>
+      </div>
+      <v-divider></v-divider>
+      <div class="d-flex">
+          <div class="content-left">
+            <div v-if="Object.keys(info).length">
+              <div>{{ $t('position.jobResponsibilities') }}:</div>
+              <div class="requirement" v-html="info.content.replace(/\n/g, '</br>')"></div>
+              <div class="mt-3">{{ $t('position.jobRequirements') }}:</div>
+              <div class="requirement" v-html="info.requirement.replace(/\n/g, '</br>')"></div>
+            </div>
+            <v-divider class="my-3"></v-divider>
+            <div class="contact" v-if="Object.keys(info).length">
+              <div class="float-left d-flex align-center">
+                <v-img :src="info.contact.avatar || 'https://minio.citupro.com/dev/menduner/7.png'" :width="45" style="height: 45px;"></v-img>
+                <div class="ml-2">
+                  <div class="contact-name">{{ info.contact.name }}</div>
+                  <div class="contact-info">{{ info.enterprise.name }} · {{ info.contact.postNameCn }}</div>
+                </div>
+              </div>
+              <div class="float-right">
+                <v-chip color="primary" label>{{ $t('position.currentOnline') }}</v-chip>
+              </div>
+            </div>
+            <v-divider class="my-3"></v-divider>
+            <div>
+              <h4>{{ $t('position.address') }}</h4>
+              <div class="mt-2">
+                <v-icon size="25" color="primary">mdi-map-marker</v-icon>
+                <span style="color: #666;font-size: 15px;">{{ info.address }}</span>
+              </div>
+            </div>
+            <v-divider class="my-3"></v-divider>
+            <div v-if="info && info.enterprise && Object.keys(info.enterprise).length">
+              <h4>企业信息</h4>
+              <div class="mt-3">
+                <v-img class="float-left mr-5" :src="info.enterprise.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'" :width="60" height="60"></v-img>
+                <div class="">
+                  <div class="contact-name">{{ info.enterprise.name }}</div>
+                  <div class="contact-info">未上市 | 互联网AI | 0-20人</div>
+                </div>
+              </div>
+            </div>
+          </div>
+      </div>
+    </div>
+  </div>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
+</template>
+
+<script setup>
+defineOptions({ name: 'position-details' })
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+import { timesTampChange } from '@/utils/date'
+import { getJobDetails } from '@/api/position'
+import { dealDictObjData } from '@/views/recruit/position/components/dict'
+
+const router = useRouter()
+const { id } = router.currentRoute.value.params
+
+// 职位详情
+const info = ref({})
+const positionInfo = ref({})
+const getPositionDetail = async () => {
+  const data = await getJobDetails({ id })
+  info.value = data
+  positionInfo.value = { 
+    ...info.value,
+    ...dealDictObjData({}, info.value), 
+    enterprise: { 
+      ...dealDictObjData({}, info.value.enterprise),
+      ...info.value.enterprise
+    } 
+  }
+  // console.log(positionInfo.value, 'info')
+}
+getPositionDetail()
+
+const desc = [
+  { mdi: 'mdi-map-marker-outline', value: 'areaName' },
+  { mdi: 'mdi-school-outline', value: 'eduName' },
+  { mdi: 'mdi-clock-time-ten-outline', value: 'expName' },
+  { mdi: 'mdi-file-tree-outline', value: 'positionName' }
+]
+</script>
+
+<style lang="scss" scoped>
+.banner {
+  background-color: #fff;
+  padding: 18px 0 20px;
+}
+.banner-title {
+  line-height: 40px;
+  font-size: 28px;
+  font-weight: 600;
+}
+.banner-title h1 {
+  display: inline-block;
+  color: #37576c;
+  font-size: 28px;
+  margin-right: 30px;
+  margin-top: 1px;
+  max-width: 360px;
+  vertical-align: middle;
+}
+.button-item {
+  min-width: 110px;
+  height: 36px
+}
+.salary {
+  color: var(--v-error-base);
+  line-height: 41px;
+  font-weight: 600;
+  height: auto;
+  display: inline-block;
+  vertical-align: sub;
+}
+.refresh-time {
+  float: right;
+  color: #666;
+  font-size: 14px;
+  line-height: 66px;
+  vertical-align: sub;
+}
+.banner-tags span {
+  font-weight: 600;
+}
+.radius {
+  border-radius: 8px;
+}
+.content-left {
+  width: 100%;
+  padding: 20px 20px;
+}
+.content-right {
+  flex: 1;
+  padding: 20px 20px 20px 0;
+}
+.label-text {
+  color: #7f7a7a;
+  font-weight: 600;
+}
+.value-text {
+  color: #000;
+  font-weight: 400;
+}
+.requirement {
+  white-space: pre-wrap;
+  word-break: break-all;
+  line-height: 28px;
+  color: #333;
+  font-size: 15px;
+  text-align: justify;
+  letter-spacing: 0;
+}
+.contact {
+  height: 60px;
+  line-height: 60px;
+}
+.contact-name {
+  font-size: 20px;
+  font-weight: 500;
+  color: #222;
+  line-height: 28px;
+}
+.contact-info {
+  font-size: 15px;
+  color: #666;
+  line-height: 21px;
+  margin-top: 8px;
+}
+</style>

+ 16 - 13
src/views/enterprise/positionManagement/components/item.vue

@@ -4,7 +4,8 @@
       <div class="d-flex justify-space-between pa-5">
         <div class="position">
           <div>
-            <span class="position-name">{{ val.name }}</span>
+            <span v-if="val.name.indexOf('style')" v-html="val.name" class="position-name" @click="handleDetails(val)"></span>
+            <span v-else class="position-name" @click="handleDetails(val)">{{ val.name }}</span>
           </div>
           <div class="mt-3 other-info ellipsis">
             <span>{{ val.areaName }}</span>
@@ -19,14 +20,13 @@
           </div>
         </div>
         <div class="d-flex align-center">
-          <div class="resume">
-            <div class="resume-number">6</div>
+          <div class="resume" v-if="val.count && val.count > '0'">
+            <div class="resume-number">{{ val.count }}</div>
             <div>待筛选简历</div>
           </div>
           <div v-if="tab === 1">
             <v-btn color="primary" variant="tonal">人才搜索</v-btn>
-            <v-btn class="mx-3" color="primary">刷新职位</v-btn>
-            <v-btn color="primary">置顶职位</v-btn>
+            <v-btn class="ml-3" color="primary">刷新职位</v-btn>
           </div>
           <div v-if="tab === 2">
             <v-btn color="primary">激活职位</v-btn>
@@ -34,17 +34,14 @@
         </div>
       </div>
       <div class="bottom pa-5 d-flex justify-space-between align-center">
-        <div>刷新时间:2024.5.30(90天后到期)</div>
+        <div>刷新时间:{{ timesTampChange(val.updateTime).slice(0, 10) }} {{ val.expireDay && Number(val.expireDay) >= 1 ? `(${ val.expireDay }天后到期)` : '' }}</div>
         <div class="d-flex">
-          <div v-if="tab === 1">
-            <span class="cursor-pointer">{{ $t('common.close') }}</span>
-            <span class="lines"></span>
-            <span class="cursor-pointer">{{ $t('common.suspend') }}</span>
-          </div>
           <div class="ml-10">
+            <span class="cursor-pointer" v-if="tab === 1">{{ $t('common.close') }}</span>
+            <span class="lines" v-if="tab === 1"></span>
             <span class="cursor-pointer">{{ $t('position.recruitmentStatistics') }}</span>
-            <span class="lines"></span>
-            <span class="cursor-pointer" @click="handleEdit(val)">{{ $t('common.edit') }}</span>
+            <span v-if="tab !== 3" class="lines"></span>
+            <span v-if="tab !== 3" class="cursor-pointer" @click="handleEdit(val)">{{ $t('common.edit') }}</span>
           </div>
         </div>
       </div>
@@ -55,6 +52,7 @@
 <script setup>
 defineOptions({ name: 'enterprise-position-item'})
 import { useRouter } from 'vue-router'
+import { timesTampChange } from '@/utils/date'
 
 defineProps({
   tab: {
@@ -69,6 +67,11 @@ const router = useRouter()
 const handleEdit = (val) => {
   router.push(`/enterprise/position/edit?id=${val.id}`)
 }
+
+// 职位详情
+const handleDetails = (val) => {
+  window.open(`/enterprise/position/details/${val.id}`)
+}
 </script>
 
 <style scoped lang="scss">

+ 12 - 9
src/views/enterprise/positionManagement/index.vue

@@ -9,30 +9,26 @@
         <v-btn class="btn" prepend-icon="mdi-plus" color="primary" @click="handleAdd">{{ $t('position.newPositionsAdded') }}</v-btn>
       </div>
       
-      <div>
-        <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#fff">
+      <div class="mt-3">
+        <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#eeeeee" @update:model-value="handleChangeTab">
           <v-tab :value="1"> {{ $t('position.recruitmentInProgress') }}</v-tab>
           <v-tab :value="2"> {{ $t('position.closed') }}</v-tab>
           <v-tab :value="3"> {{ $t('position.expiredPosition') }}</v-tab>
-          <v-tab :value="4"> {{ $t('position.drafts') }}</v-tab>
         </v-tabs>
         <v-window v-model="tab" class="mt-3">
           <v-window-item :value="1">
             <PositionItem v-if="items.length" :tab="tab" :items="items"></PositionItem>
           </v-window-item>
           <v-window-item :value="2">
-            <PositionItem :tab="tab"></PositionItem>
+            <PositionItem v-if="items.length" :tab="tab" :items="[]"></PositionItem>
           </v-window-item>
           <v-window-item :value="3">
-            <PositionItem :tab="tab"></PositionItem>
-          </v-window-item>
-          <v-window-item :value="4">
-            <PositionItem :tab="tab"></PositionItem>
+            <PositionItem v-if="items.length" :tab="tab" :items="items"></PositionItem>
           </v-window-item>
         </v-window>
         <Empty v-if="!items.length" :message="tipsText" :elevation="false"></Empty>
         <CtPagination
-          v-if="items.length"
+          v-else
           :total="total"
           :page="query.pageNo"
           :limit="query.pageSize"
@@ -77,6 +73,8 @@ const handleAdd = () => {
 
 // 获取职位列表
 const getPositionList = async () => {
+  query.value.hasExpiredData = tab.value === 3 ? true : false
+  // status: 1 已关闭
   const { list, total: number } = await getJobAdvertisedList(query.value)
   if (!list.length) {
     if (query.value.name) tipsText.value = '暂无数据,请更换关键词后再试'
@@ -86,6 +84,11 @@ const getPositionList = async () => {
 }
 getPositionList()
 
+const handleChangeTab = () => {
+  query.value.pageNo = 1
+  getPositionList()
+}
+
 const handleChangePage = (index) => {
   query.value.pageNo = index
   getPositionList()

+ 3 - 3
src/views/recruit/company/components/companyItem.vue

@@ -11,7 +11,9 @@
         </div>
       </div>
       <div class="company-info-bottom">
-        <v-chip class="mr-2" color="primary" size="x-small" label v-for="(k, i) in welfareList" :key="i">{{ k }}</v-chip>
+        <div class="bottom-tag ellipsis">
+          <span class="mr-2" v-for="(k, i) in item.welfareList" :key="i">{{ k }}</span>
+        </div>
       </div>
     </div>
   </div>
@@ -23,8 +25,6 @@ defineProps({
   list: Array
 })
 
-const welfareList = ['双休', '五险一金', '零食下午茶', '年终奖']
-
 const handleClickEnterprise = (item) => {
   window.open(`/company/details/${item.id}?key=briefIntroduction`)
 }