lifanagju_citu 3 bulan lalu
induk
melakukan
d84c6e7c6b

+ 4 - 0
components.d.ts

@@ -32,6 +32,7 @@ declare module 'vue' {
     DatePicker: typeof import('./src/components/DatePicker/index.vue')['default']
     Echarts: typeof import('./src/components/Echarts/index.vue')['default']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
+    ElTree: typeof import('element-plus/es')['ElTree']
     Empty: typeof import('./src/components/Empty/index.vue')['default']
     File: typeof import('./src/components/Upload/file.vue')['default']
     HeadSearch: typeof import('./src/components/headSearch/index.vue')['default']
@@ -75,4 +76,7 @@ declare module 'vue' {
     VerifySlide: typeof import('./src/components/Verifition/Verify/VerifySlide.vue')['default']
     WangEditor: typeof import('./src/components/FormUI/wangEditor/index.vue')['default']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

+ 21 - 0
src/utils/index.js

@@ -1,3 +1,5 @@
+import router from '@/router'
+
 export const blobToJson = (blob) => {
   return new Promise((resolve, reject) => {
     const reader = new FileReader()
@@ -140,3 +142,22 @@ export const removeEmptyProperties = (obj) => {
     Object.entries(obj).filter(([key, value]) => value !== null && value !== undefined && value !== '' && (Array.isArray(value) ? value.length > 0 : true))
   )
 }
+
+// 招聘会面包屑数据
+export const getJobFairBreadcrumbs = () => {
+  return localStorage.getItem('jobFairBreadcrumbs') && JSON.parse(localStorage.getItem('jobFairBreadcrumbs')) || []
+}
+
+// 招聘会面包屑点击
+export const breadcrumbsClickDeal = (item, index) => {
+  const { disabled, path } = item
+  if (disabled) {
+    // event.preventDefault()
+    return
+  }
+  const breadcrumbs = getJobFairBreadcrumbs()
+	if (index === breadcrumbs?.length-1) return // 当前页面不可点击
+  // 
+  // if (breadcrumbs)
+  if (path) router.push(path)
+}

+ 3 - 3
src/views/recruit/personal/companyDetail/index.vue

@@ -28,8 +28,8 @@
       <v-divider></v-divider>
       <div class="mt-3">
         <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f3f3f3" @update:model-value="handleTabClick">
-          <v-tab :value="1">公司简介</v-tab>
           <v-tab :value="2">在招职位</v-tab>
+          <v-tab :value="1">公司简介</v-tab>
         </v-tabs>
         <div class="d-flex" v-if="Object.keys(info).length">
           <div class="content-left">
@@ -82,9 +82,9 @@ import { formatName } from '@/utils/getText'
 const route = useRoute()
 const router = useRouter()
 const { id } = router.currentRoute.value.params
-const tab = ref(1)
+const tab = ref(2)
 const savedTab = new URLSearchParams(window.location.search).get('key')
-tab.value = savedTab ? (savedTab === 'briefIntroduction' ? 1 : 2) : 1
+tab.value = savedTab ? (savedTab === 'briefIntroduction' ? 1 : 2) : 2
 
 const handleTabClick = () => {
   router.push(`${route.path}?key=${tab.value === 1 ? 'briefIntroduction' : 'recruitmentPositions'}`)

+ 24 - 7
src/views/recruit/personal/jobFair/details.vue

@@ -4,9 +4,9 @@
 		<div class="px-4">
 			<!-- 搜索框 -->
 			<div class="white-bgc py-5">
-				<v-breadcrumbs :items="breadcrumbs" elevation="3">
-          <template v-slot:item="{ item }">
-            <span class="text" :class="{ active: !item.disabled }" >{{ item.text }}</span>
+				<v-breadcrumbs v-if="breadcrumbs?.length" :items="breadcrumbs" elevation="3">
+          <template v-slot:item="{ item, index }">
+            <span class="breadcrumbsText" :class="{ active: !item.disabled && index !== breadcrumbs.length-1 }" @click="breadcrumbsClickDeal({ item, index })">{{ item.text }}</span>
           </template>
         </v-breadcrumbs>
 				<headSearch v-model="content" placeholder="搜索公司关键字" @handleSearch="handleSearch"></headSearch>
@@ -41,13 +41,13 @@
 defineOptions({ name: 'jobFairDetails' })
 import { ref } from 'vue'
 import { formatName } from '@/utils/getText'
+import { breadcrumbsClickDeal } from '@/utils/index'
 import buttons from '@/views/recruit/personal/components/buttons.vue'
 import { useRouter } from 'vue-router'; const router = useRouter()
 
 const content = ref('')
-const breadcrumbs = ref([
-	{ text: '招聘会', href: '' }
-])
+const breadcrumbs = ref(localStorage.getItem('jobFairBreadcrumbs') && JSON.parse(localStorage.getItem('jobFairBreadcrumbs')) || [])
+
 const list = ref([
 	{
 		name: '厦门嘉逸希尔顿格芮精选酒店厦门嘉逸希尔顿格芮精选酒店',
@@ -92,7 +92,15 @@ const handleSearch = (val) => {
 }
 
 const handleClickEnterprise = (val) => {
-  router.push(`/recruit/personal/jobFair/enterprise/${val.id}`)
+	if (!val?.id) return
+	const path = '/recruit/personal/jobFair/enterprise/' + val.id
+	// 面包屑储存
+	localStorage.setItem('jobFairBreadcrumbs', JSON.stringify([
+		...JSON.parse(localStorage.getItem('jobFairBreadcrumbs')),
+		{ text: val.name || '', path }
+	]))
+	// 跳转
+  router.push(path)
 }
 </script>
 
@@ -118,4 +126,13 @@ const handleClickEnterprise = (val) => {
 .enterprise-name:hover {
 	color: var(--v-primary-base);
 }
+
+.breadcrumbsText {
+  color: var(--color-999);
+  font-size: 14px;
+  &.active {
+    color: var(--v-primary-base);
+    cursor: pointer;
+  }
+}
 </style>

+ 61 - 32
src/views/recruit/personal/jobFair/enterprise/index.vue

@@ -1,5 +1,13 @@
 <template>
   <div class="default-width banner px-6">
+    <!-- 面包屑 -->
+    <div class="py-5">
+      <v-breadcrumbs v-if="breadcrumbs?.length" :items="breadcrumbs" elevation="3">
+        <template v-slot:item="{ item, index }">
+          <span class="breadcrumbsText" :class="{ active: !item.disabled && index !== breadcrumbs.length-1 }" @click="breadcrumbsClickDeal({ item, index })">{{ item.text }}</span>
+        </template>
+      </v-breadcrumbs>
+    </div>
     <div v-if="Object.keys(info).length">
       <div class="banner-title pt-3" v-if="Object.keys(info).length">
         <div class="float-left d-flex align-center">
@@ -13,11 +21,11 @@
             </div>
           </div>
         </div>
-        <div class="float-right d-flex">
+        <!-- <div class="float-right d-flex">
           <v-btn color="primary" variant="text" size="large" @click.stop="handleReturn" prepend-icon="mdi-chevron-triple-left">返回上一页</v-btn>
-        </div>
+        </div> -->
       </div>
-      <div class="text-end mb-3">
+      <!-- <div class="text-end mb-3">
         <v-tooltip location="bottom">
           <template v-slot:activator="{ props }">
             <v-icon v-bind="props" class="ml-5 mr-2" size="25" :color="isCollection ? 'error' : ''" @click.stop="handleFollow">{{ isCollection ? 'mdi-heart' : 'mdi-heart-outline' }}</v-icon>
@@ -25,11 +33,16 @@
           <span>关注该企业</span>
         </v-tooltip>
       </div>
-      <v-divider></v-divider>
+      <v-divider></v-divider> -->
       <div class="mt-3">
+        <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f3f3f3" @update:model-value="handleTabClick">
+          <v-tab :value="1">公司简介</v-tab>
+          <v-tab :value="2">在招职位</v-tab>
+        </v-tabs>
         <div class="d-flex" v-if="Object.keys(info).length">
           <div class="content-left">
-            <recruitmentPositions :info="info"/>
+            <EnterpriseIntroduction v-if="tab === 1" :info="info" />
+            <recruitmentPositions v-else :info="info"/>
           </div>
           <div class="content-right">
             <div class="welfare mb-3">
@@ -54,7 +67,7 @@
         </div>
       </div>
     </div>
-    
+
     <!-- 快速登录 -->
     <loginPage v-if="showLogin" @loginSuccess="loginSuccess" @close="loginClose"></loginPage>
   </div>
@@ -63,30 +76,42 @@
 <script setup>
 defineOptions({name: 'jobFair-enterprise'})
 import { ref } from 'vue'
-import {
-  getEnterpriseDetails,
-  getEnterpriseSubscribeCheck,
-  getEnterpriseSubscribe,
-  getEnterpriseUnsubscribe
-} from '@/api/enterprise'
-import { dealDictObjData } from '@/utils/position'
+import EnterpriseIntroduction from './introduction.vue'
+import recruitmentPositions from './positions.vue'
+import { getEnterpriseDetails, getEnterpriseSubscribeCheck, getEnterpriseSubscribe, getEnterpriseUnsubscribe, enterpriseClick } from '@/api/enterprise'
 import { timesTampChange } from '@/utils/date'
-import { useRouter } from 'vue-router'; const router = useRouter()
-import { formatName } from '@/utils/getText'
+import { dealDictObjData } from '@/utils/position'
+import { useRoute, useRouter } from 'vue-router'
 import { getToken } from '@/utils/auth'
-import loginPage from '@/views/common/loginDialog.vue'
 import Snackbar from '@/plugins/snackbar'
-import recruitmentPositions from './positions.vue'
+import loginPage from '@/views/common/loginDialog.vue'
+import { formatName } from '@/utils/getText'
+import { breadcrumbsClickDeal } from '@/utils/index'
 
+const route = useRoute()
+const router = useRouter()
 const { id } = router.currentRoute.value.params
+const tab = ref(1)
+const savedTab = new URLSearchParams(window.location.search).get('key')
+tab.value = savedTab ? (savedTab === 'briefIntroduction' ? 1 : 2) : 1
 
-// 工商信息
-const businessList = [
-  { label: '企业类型:', value: 'type' },
-  { label: '统一社会信用代码:', value: 'code' },
-  { label: '成立日期:', value: 'establishmentTime' },
-  { label: '注册资本:', value: 'registeredCapital' }
-]
+const handleTabClick = () => {
+  router.push(`${route.path}?key=${tab.value === 1 ? 'briefIntroduction' : 'recruitmentPositions'}`)
+}
+
+// 返回上一页
+const handleReturn = () => {
+  if (window.history.state.back) {
+    router.back()
+  } else router.push('/recruitHome')
+}
+
+// 企业埋点
+const handleEnterpriseClick = async () => {
+  if (id) return
+  await enterpriseClick({ id })
+}
+handleEnterpriseClick()
 
 // 企业详情
 const info = ref({})
@@ -103,13 +128,6 @@ const getDetails = async () => {
 }
 getDetails()
 
-// 返回上一页
-const handleReturn = () => {
-  if (window.history.state.back) {
-    router.back()
-  } else router.push('/recruit/personal/jobFair')
-}
-
 // 效验求职者是否关注该企业
 const isCollection = ref(false)
 const getCollectionStatus = async (id) => {
@@ -132,6 +150,14 @@ const handleFollow = async () => {
   getCollectionStatus(id)
 }
 
+// 工商信息
+const businessList = [
+  { label: '企业类型:', value: 'type' },
+  { label: '统一社会信用代码:', value: 'code' },
+  { label: '成立日期:', value: 'establishmentTime' },
+  { label: '注册资本:', value: 'registeredCapital' }
+]
+
 const showLogin = ref(false)
 const nextFunc = ref(null)
 let loginCloseWarningWord = ''
@@ -147,8 +173,11 @@ const loginClose = () => {
   Snackbar.warning(loginCloseWarningWord)
 }
 
+const breadcrumbs = ref(localStorage.getItem('jobFairBreadcrumbs') && JSON.parse(localStorage.getItem('jobFairBreadcrumbs')) || [])
+
 </script>
-<style lang="scss" scoped>
+
+<style scoped lang="scss">
 .banner {
   background-color: #fff;
   padding: 0 0 20px;

+ 66 - 0
src/views/recruit/personal/jobFair/enterprise/introduction.vue

@@ -0,0 +1,66 @@
+<template>
+  <div>
+    <h4>公司简介</h4>
+    <div v-if="props.info.enterprise.introduce" class="requirement" v-html="props.info.enterprise.introduce.replace(/\n/g, '</br>')"></div>
+    <div v-else>暂无</div>
+    <v-divider class="my-3"></v-divider>
+    <div>
+      <h4>公司地址</h4>
+      <div v-if="props.info?.business?.address" class="mt-1">
+        <v-icon size="25" color="primary">mdi-map-marker</v-icon>
+        <span style="color: var(--color-666);font-size: 15px;">{{ props.info.business.address }}</span>
+      </div>
+      <div v-else class="mt-1">暂无</div>
+    </div>
+    <v-divider class="my-3"></v-divider>
+    <div>
+      <h4>公司相册</h4>
+      <v-slide-group v-if="props.info.enterprise.albumList" :show-arrows="true" class="mt-3 img-box cursor-pointer">
+        <v-slide-group-item v-for="(val, i) in props.info.enterprise.albumList" :key="i">
+          <div>
+            <v-img v-if="checkIsImage(val)" class="mr-3" width="200" height="115" :src="val" cover rounded @click.stop="handleClick(i)"></v-img>
+            <video v-else class="videos-radius mr-3" :src="val" controls height="118" width="200" preload="preload" @click.stop="handleClick(i)"></video>
+          </div>
+        </v-slide-group-item>
+      </v-slide-group>
+      <div v-else>暂无</div>
+    </div>
+    <PreviewImage v-if="showPreview" :initialIndex="current" :urlList="props.info.enterprise.albumList" @close="showPreview = !showPreview" />
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'enterprise-introduction'})
+import { checkIsImage } from '@/utils'
+import { ref } from 'vue'
+
+const props = defineProps({
+  info: {
+    type: Object,
+    default: () => {}
+  }
+})
+
+// 预览
+const showPreview = ref(false)
+const current = ref(0)
+const handleClick = (index) => {
+  showPreview.value = !showPreview.value
+  current.value = index
+}
+</script>
+
+<style scoped lang="scss">
+.requirement {
+  white-space: pre-wrap;
+  word-break: break-all;
+  line-height: 28px;
+  color: var(--color-333);
+  font-size: 15px;
+  text-align: justify;
+  letter-spacing: 0;
+}
+.videos-radius {
+  border-radius: 8px;
+}
+</style>

+ 14 - 4
src/views/recruit/personal/jobFair/index.vue

@@ -7,7 +7,7 @@
 				<div class="pa-3">
 					<div class="color-666">活动时间:{{ timesTampChange(val.startTime, 'Y-M-D') }}至{{ timesTampChange(val.endTime, 'Y-M-D') }}</div>
 					<div class="text-end">
-						<v-btn color="primary" variant="outlined" @click.stop="handleJoin(val.id)">查看详情</v-btn>
+						<v-btn color="primary" variant="outlined" @click.stop="handleJoin(val)">查看详情</v-btn>
 					</div>
 				</div>
 			</v-card>
@@ -20,6 +20,7 @@ defineOptions({ name: 'jobFair' })
 import { ref } from 'vue'
 import { timesTampChange } from '@/utils/date'
 import buttons from '@/views/recruit/personal/components/buttons.vue'
+import { useRouter } from 'vue-router'; const router = useRouter()
 
 const list = ref([
 	{
@@ -66,9 +67,18 @@ const list = ref([
 	}
 ])
 
-const handleJoin = (id) => {
-  console.log(id)
-	window.open('/recruit/personal/jobFair/details/' + id)
+const handleJoin = (val) => {
+	if (!val?.id) return
+	const path = '/recruit/personal/jobFair/details/' + val.id
+	// 面包屑储存
+	let text = val.title ? val.title.replace(/<[^>]+>/g, ' ') : '' // 去掉所有 HTML 标签
+	text = text ? text.replace(/\s+/g, ' ').trim() : '' // 去掉多余的空格
+	localStorage.setItem('jobFairBreadcrumbs', JSON.stringify([
+		{ text: '招聘会' , path: '/recruit/personal/jobFair' },
+		{ text, path }
+	]))
+	// 跳转
+  router.push(path)
 }
 </script>