zhengnaiwen_citu 6 months ago
parent
commit
5b5edfcd4d

+ 8 - 0
src/api/recruit/personal/resume/index.js

@@ -163,6 +163,14 @@ export const schoolMajorByName = async (params) => {
   })
 }
 
+// 根据专业名称模糊搜索
+export const schoolMajorById = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/major/get',
+    params
+  })
+}
+
 // 根据学校名称模糊搜索
 export const schoolSearchByName = async (params) => {
   return await request.get({

+ 146 - 4
src/views/recruit/enterprise/jobFair/components/job.vue

@@ -4,14 +4,61 @@
       <v-btn color="primary" class="mr-3" @click="handleAdd">新增职位</v-btn>
       <v-btn color="primary" variant="outlined" @click="handleJoin">选择已发布的职位加入招聘会</v-btn>
     </div>
-    <JobItem :items="jobList"></JobItem>
+    <JobItem :items="jobList" @refresh="getJobList"></JobItem>
 
     <v-navigation-drawer v-model="showDrawer" location="right" temporary width="600">
+      <Loading :visible="positionLoading" :contained="true"></Loading>
       <div class="resume-box">
         <div class="resume-header">
-          <div class="resume-title">已发布职位</div>
+          <div class="resume-title mr-5">已发布职位</div>
         </div>
       </div>
+      <div class="px-3">
+        <v-text-field
+          v-model="positionSearch"
+          append-inner-icon="mdi-magnify"
+          density="compact"
+          :label="t('position.positionName')"
+          variant="outlined"
+          hide-details
+          single-line
+          @click:append-inner="getPositionList"
+          @keyup.enter="getPositionList"
+        ></v-text-field>
+      </div>
+      <div class="pa-3">
+        <div v-for="val in positionItems" :key="val.id" class="itemBox mb-3" style="height: 80px;">
+          <div class="d-flex justify-space-between" style="padding: 10px 20px;">
+            <div class="position">
+              <div class="d-flex align-center justify-space-between">
+                <!-- <span v-if="val.name.indexOf('style')" v-html="val.name" class="position-name"></span> -->
+                <span class="position-name">{{ val.name }}</span>
+                <div>
+                  <v-btn size="small" color="primary" @click="handleTo(val)">添加至双选会</v-btn>
+                </div>
+              </div>
+              <div :class="['mt-3', 'other-info', 'ellipsis']">
+                <span>{{ val.areaName }}</span>
+                <span class="lines" v-if="val.areaName && val.eduName"></span>
+                <span>{{ val.eduName }}</span>
+                <span class="lines"></span>
+                <span>{{ val.expName }}</span>
+                <span class="lines"></span>
+                <span v-if="!val.payFrom && !val.payTo">面议</span>
+                <span v-else>{{ val.payFrom ? val.payFrom + '-' : '' }}{{ val.payTo }}{{ val.payName ? '/' + val.payName : '' }}</span>
+                <span class="lines" v-if="val.positionName"></span>
+                <span>{{ val.positionName }}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <CtPagination
+        :total="positionTotal"
+        :page="positionPageInfo.pageNo"
+        :limit="positionPageInfo.pageSize"
+        @handleChange="handleChangePage"
+      ></CtPagination>
     </v-navigation-drawer>
   </div>
 </template>
@@ -23,21 +70,36 @@ import { getJobFairPosition } from '@/api/recruit/enterprise/jobFair'
 import { dealDictArrayData } from '@/utils/position.js'
 import JobItem from '../job/item.vue'
 import { useRouter, useRoute } from 'vue-router'
+import { useI18n } from '@/hooks/web/useI18n'
 import Snackbar from '@/plugins/snackbar'
 import { getEnterprisePubJobTypePermission } from '@/api/recruit/enterprise/position'
 
+import { getJobAdvertisedList } from '@/api/position'
+import Confirm from '@/plugins/confirm'
+
 const props = defineProps({ id: [String, Number]})
 const router = useRouter()
 const route = useRoute()
+const { t } = useI18n()
 
 // 职位列表
 const jobList = ref([])
+
+const positionItems = ref([])
+const positionTotal = ref(0)
+const positionLoading = ref(false)
+const positionPageInfo = ref({
+  pageSize: 10,
+  pageNo: 1,
+})
+const positionSearch = ref('')
+
+
 const getJobList = async () => {
   const data = await getJobFairPosition(props.id)
   if (!data || !data.length) return jobList.value = []
   jobList.value = dealDictArrayData([], data)
 }
-getJobList()
 
 const handleAdd = async () => {
   const data = await getEnterprisePubJobTypePermission()
@@ -46,11 +108,91 @@ const handleAdd = async () => {
 }
 
 const showDrawer = ref(false)
-const handleJoin = () => {
+const handleJoin = async () => {
+  getPositionList()
   showDrawer.value = true
 }
+
+const handleChangePage = (index) => {
+  positionPageInfo.value.pageNo = index
+  getPositionList()
+}
+
+const handleTo = (val) => {
+  router.push(`/recruit/enterprise/jobFair/details/${route.params.id}/edit?id=${val.id}`)
+}
+
+// 获取职位列表
+const getPositionList = async () => {
+  positionLoading.value = true
+  const query = {
+    ...positionPageInfo.value,
+    status: 0,
+    hasExpiredData: false,
+    hire: false
+  }
+  if ( positionSearch.value) {
+    Object.assign(query, {
+      name: positionSearch.value,
+    })
+  }
+  try {
+    const { list, total } = await getJobAdvertisedList(query)
+    positionTotal.value = total
+    positionItems.value = list.length ? dealDictArrayData([], list) : []
+  } finally {
+    positionLoading.value = false
+  }
+}
+
+getJobList()
 </script>
 
 <style scoped lang="scss">
+.resume-box {
+  padding-top: 120px;
+}
 
+.itemBox {
+  position: relative;
+  border: 1px solid #e5e6eb;
+}
+.position-name {
+  color: var(--color-333);
+  font-size: 19px;
+}
+.position {
+  width: 100%;
+  position: relative;
+  .item-select {
+    position: absolute;
+    left: -8px;
+    top: -13px;
+  }
+}
+.lines {
+  display: inline-block;
+  width: 1px;
+  height: 17px;
+  vertical-align: middle;
+  background-color: #e0e0e0;
+  margin: 0 10px;
+}
+.other-info {
+  font-size: 15px;
+  color: var(--color-666);
+}
+.bottom {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 40px;
+  background-color: #f7f8fa;
+  font-size: 14px;
+  color: var(--color-888);
+}
+.actions:hover {
+  color: var(--v-primary-base);
+}
 </style>

+ 12 - 5
src/views/recruit/enterprise/jobFair/editJob.vue

@@ -21,7 +21,7 @@ import {  useRoute, useRouter } from 'vue-router'
 import CtForm from '@/components/CtForm'
 import Add from '@/views/recruit/enterprise/positionManagement/components/add.vue'
 import { useI18n } from '@/hooks/web/useI18n'
-import { schoolMajorByName } from '@/api/recruit/personal/resume'
+import { schoolMajorByName, schoolMajorById } from '@/api/recruit/personal/resume'
 import {
   saveJobAdvertisedExtend,
   joinJobFairPosition,
@@ -92,22 +92,23 @@ const items = ref({
   ]
 })
 
-console.log(route)
+// console.log(route)
 if (route.query.id) {
   // 编辑
   initPosition(route.query.id)
 }
 
 async function initPosition (jobId) {
-  console.log(jobId)
   const res = await getJobAdvertisedExtend(jobId)
-  console.log(res)
   items.value.options.forEach(e => {
-    if (e.key.includes('frequency')) {
+    if (e.key.includes('frequency') && res.frequency) {
       const keys = e.key.split('-')
       e.value = res[keys[0]][keys[1]]
       return
     }
+    if (e.key === 'majorId') {
+      getMajorById(res.majorId)
+    }
     e.value = res[e.key]
   })
 }
@@ -120,6 +121,11 @@ async function getMajorList (name) {
   items.value.options.find(e => e.key === 'majorId').items = res
 }
 
+async function getMajorById (id) {
+  const res = await schoolMajorById({ id })
+  items.value.options.find(e => e.key === 'majorId').items = [res]
+}
+
 const validate = async () => {
   const res = await formPageRef.value.formRef.validate()
   return res
@@ -150,6 +156,7 @@ const afterAdd = async (jobId) => {
     Snackbar.success(t('common.publishSuccessMsg'))
     router.push(`/recruit/enterprise/jobFair/details/${route.params.id}`)
   } catch (error) {
+    console.log(error)
     Snackbar.error(t('sys.api.operationFailed'))
   }
 }

+ 18 - 3
src/views/recruit/enterprise/jobFair/job/item.vue

@@ -24,9 +24,9 @@
       <div class="bottom pa-5 d-flex justify-space-between align-center">
         <div>到期时间:{{ val.expireTime ? timesTampChange(val.expireTime, 'Y-M-D') : '长期有效' }}</div>
         <div class="d-flex">
-          <span class="cursor-pointer actions">编辑</span>
+          <span class="cursor-pointer actions" @click="handleEdit(val)">编辑</span>
           <span class="lines"></span>
-          <span class="cursor-pointer actions">移出双选会</span>
+          <span class="cursor-pointer actions" @click="handleRemove(val)">移出双选会</span>
         </div>
       </div>
     </div>
@@ -42,8 +42,10 @@ import { useRouter, useRoute } from 'vue-router'
 import { timesTampChange } from '@/utils/date'
 import Snackbar from '@/plugins/snackbar'
 import { getEnterprisePubJobTypePermission } from '@/api/recruit/enterprise/position'
+import { quitJobFairPosition } from '@/api/recruit/enterprise/jobFair'
+import Confirm from '@/plugins/confirm'
 
-// const emit = defineEmits(['refresh'])
+const emit = defineEmits(['refresh'])
 defineProps({
   items: Array
 })
@@ -59,6 +61,19 @@ const handleEdit = async (val) => {
   if (!data || !data.length) return Snackbar.warning('没有该操作权限,请联系平台管理员升级后再试')
   router.push(`/recruit/enterprise/jobFair/details/${route.params.id}/edit?id=${val.id}`)
 }
+
+
+const handleRemove = ({ id }) => {
+  Confirm('确定要移出该职位吗?', '提示').then(async () => {
+    await quitJobFairPosition({
+      jobFairId: route.params.id,
+      jobId: id
+    })
+    Snackbar.success('移出成功')
+    emit('refresh')
+  })
+  
+}
 </script>
 
 <style scoped lang="scss">