Explorar o código

招聘会职位列表

Xiao_123 hai 1 mes
pai
achega
d58c76cb8a

+ 37 - 12
api/jobFair.js

@@ -1,14 +1,26 @@
 import request from "@/utils/request"
 
 // 获得招聘会列表
-export const getJobFairList = (params) => {
+export const getJobFairList = () => {
   return request({
-    url: '/app-api/menduner/system/job-fair/list',
+    url: '/app-api/menduner/system/recruit/job-fair/list',
     method: 'GET',
-    params,
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
+    }
+  })
+}
+
+// 效验是否有权限参加招聘会
+export const checkJobFairPermission = (jobFairId) => {
+  return request({
+    url: '/app-api/menduner/system/recruit/job-fair/check/permission',
+    method: 'GET',
+    params: { jobFairId },
+    custom: {
+      showLoading: false,
+      auth: true
     }
   })
 }
@@ -16,12 +28,12 @@ export const getJobFairList = (params) => {
 // 获得招聘会-招聘会详情
 export const getJobFair = (id) => {
   return request({
-    url: '/app-api/menduner/system/job-fair/get',
+    url: '/app-api/menduner/system/recruit/job-fair/get',
     method: 'GET',
     params: { id },
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
@@ -34,20 +46,33 @@ export const getJobFairEnterprisePage = (params) => {
     params,
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
 
-// 根据企业id查询招聘会职位列表
-export const getJobFairEntJobPage = (params) => {
+// 查询企业招聘会职位列表
+export const getJobFairPosition = (id) => {
   return request({
-    url: '/app-api/menduner/system/job-fair/detail/page',
+    url: '/app-api/menduner/system/recruit/job-fair/get/by/job-fair',
     method: 'GET',
-    params,
+    params: { id },
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
+    }
+  })
+}
+
+// 企业将职位移除招聘会
+export const quitJobFairPosition = (data) => {
+  return request({
+    url: '/app-api/menduner/system/recruit/job-fair/quit',
+    method: 'POST',
+    data,
+    custom: {
+      showLoading: false,
+      auth: true
     }
   })
 }

+ 1 - 185
api/position.js

@@ -1,141 +1,9 @@
 import request from "@/utils/request"
 
-// 根据条件搜索招聘职位
-export const getJobAdvertisedSearch = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job/advertised/search',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: false
-    }
-  })
-}
-
-// 推荐职位列表
-export const getPromotedPosition = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job/advertised/get/recommended',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: false
-    }
-  })
-}
-
 // 职位详情
 export const getPositionDetails = (params) => {
   return request({
-    url: '/app-api/menduner/system/job/advertised/get/detail',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: false
-    }
-  })
-}
-
-// 效验招聘职位是否投递
-export const jobCvRelCheckSend = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/send/check',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
-// 效验“招聘会”职位是否投递
-export const jobFairCvRelCheckSend = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/job-fair/send/check',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
-// 效验求职者是否收藏该职位
-export const getJobFavoriteCheck = (params) => {
-  return request({
-    url: '/app-api/menduner/system/person/job/favorite/check',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
-// 求职者收藏职位
-export const getPersonJobFavorite = (data) => {
-  return request({
-    url: '/app-api/menduner/system/person/job/favorite',
-    method: 'POST',
-    data,
-    custom: {
-      auth: true,
-      showLoading: false
-    }
-  })
-}
-
-// 求职者取消收藏职位
-export const getPersonJobUnfavorite = (jobId) => {
-  return request({
-    url: `/app-api/menduner/system/person/job/unfavorite?jobId=` + jobId,
-    method: 'DELETE',
-    // params: {
-    //   jobId
-    // },
-    custom: {
-      auth: true,
-      showLoading: false
-    }
-  })
-}
-
-// 投递简历
-export const jobCvRelSend = (data) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/send',
-    method: 'POST',
-    data,
-    custom: {
-      auth: true,
-      showLoading: false
-    }
-  })
-}
-
-// 众聘分享-投递简历
-export const jobCvRelHireSend = (data) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/hire/recommend/send',
-    method: 'POST',
-    data,
-    custom: {
-      auth: true,
-      showLoading: false
-    }
-  })
-}
-
-// 获取众聘职位分页
-export const getJobAdvertisedHire = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job/advertised/get/hire',
+    url: '/app-api/menduner/system/recruit/job-advertised/detail',
     method: 'GET',
     params,
     custom: {
@@ -145,45 +13,6 @@ export const getJobAdvertisedHire = (params) => {
   })
 }
 
-// 获取统计信息
-export const getRecommendCount = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/hire/get/recommend/count',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
-// 二维码拉新记录
-export const getInviteRecord = (params) => {
-  return request({
-    url: '/app-api/menduner/system/person/get/invite/person/page',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
-// 获取统计信息
-export const getRecommendationList = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job-cv-rel/hire/page',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: true
-    }
-  })
-}
-
 // 根据id查询分享的职位id与推荐人id
 export const getShareDetail = (params) => {
   return request({
@@ -196,16 +25,3 @@ export const getShareDetail = (params) => {
     }
   })
 }
-
-// 职位详情-获取相似职位
-export const getSimilarPosition = (params) => {
-  return request({
-    url: '/app-api/menduner/system/job/advertised/get/acquainted',
-    method: 'GET',
-    params,
-    custom: {
-      showLoading: false,
-      auth: false
-    }
-  })
-}

+ 1 - 80
api/resume.js

@@ -14,14 +14,6 @@ export const saveResumeBasicInfo = async (data) => {
   })
 }
 
-// // 保存个人优势
-// export const saveResumeAdvantage = async (data) => {
-//   return await request.post({
-//     url: '/app-api/menduner/system/person/resume/advantage/save',
-//     data
-//   })
-// }
-
 // 保存培训经历
 export const saveResumeTrainExp = async (data) => {
   return request({
@@ -133,33 +125,6 @@ export const saveResumeWorkExp = async (data) => {
   })
 }
 
-// // 保存项目经历
-// export const saveResumeProjectExp = async (data) => {
-//   return await request.post({
-//     url: '/app-api/menduner/system/person/resume/project/exp/save',
-//     data
-//   })
-// }
-
-// // 删除项目经历
-// export const deleteResumeProjectExp = async (id) => {
-//   return await request.delete({
-//     url: '/app-api/menduner/system/person/resume/project/exp/remove?id=' + id
-//   })
-// }
-
-// 获取项目经历
-// export const getResumeProjectExp = async () => {
-//   return request({
-//     url: '/app-api/menduner/system/person/resume/get/project/exp',
-//     method: 'GET',
-//     custom: {
-//       showLoading: false,
-//       auth: true
-//     }
-//   })
-// }
-
 // 获取-技能树形
 export const getSkillTree = async () => {
   return request({
@@ -283,48 +248,4 @@ export const enterpriseSearchByName = async (params) => {
       auth: true
     }
   })
-}
-
-// // 保存附件
-// export const savePersonResumeCv = async (data) => {
-//   return await request.post({
-//     url: '/app-api/menduner/system/person/resume/person/cv/save',
-//     data
-//   })
-// }
-
-// // 删除附件
-// export const deletePersonResumeCv = async (id) => {
-//   return await request.delete({
-//     url: '/app-api/menduner/system/person/resume/person/cv/remove?id=' + id
-//   })
-// }
-
-// // 获取附件列表
-// export const getPersonResumeCv = async () => {
-//   return await request.get({
-//     url: '/app-api/menduner/system/person/resume/get/person/cv'
-//   })
-// }
-
-// // 修改求职类型
-// export const updateJobStatus = async (data) => {
-//   return await request.post({
-//     url: '/app-api/menduner/system/person/resume/job/status/update?status=' + data,
-//   })
-// }
-
-// // 修改人才头像
-// export const updatePersonAvatar = async (url) => {
-//   return await request.post({
-//     url: `/app-api/menduner/system/person/resume/avatar/update?avatar=${url}`
-//   })
-// }
-
-// // 修改个人画像
-// export const savePersonPortrait = async (data) => {
-//   return await request.post({
-//     url: '/app-api/menduner/system/person/resume/tag/update',
-//     data
-//   })
-// }
+}

+ 0 - 94
components/ResumeStatus/index.vue

@@ -1,94 +0,0 @@
-<template>
-	<slot name="header"></slot>
-	<view class="content">
-		<view v-for="(item,index) in items" :key="item.label" class="content-box" @tap="handleTo(item)">
-			<view class="content-box-value">
-				{{ item.count }}
-			</view>
-			<view class="content-box-title">
-				{{ item.label }}
-			</view>
-		</view>
-	</view>
-	
-</template>
-
-<script setup>
-import { ref, watch } from 'vue';
-import { getRecommendCount } from '@/api/position.js'
-import { getDict } from '@/hooks/useDictionaries.js'
-import { onShow } from '@dcloudio/uni-app'
-// const props = defineProps({
-// 	type: {
-// 		type: String,
-// 		default: 'menduner_hire_job_cv_status'
-// 	}
-// })
-
-import { userStore } from '@/store/user'
-const useUserStore = userStore()
-
-// 监听登录状态
-watch(() => useUserStore.refreshToken, (newVal, oldVal) => {
-	const reset = Boolean(!newVal)
-	recommendCount(reset)
-})
-
-onShow(() => {
-	recommendCount()
-})
-
-const items = ref([])
-
-const handleTo = (item) => {
-	uni.navigateTo({
-		url: `/pagesA/recommendation/index?id=${item.value}`
-	})
-}
-
-async function recommendCount (reset = false) {
-	try {
-		const { data: dict } = await getDict('menduner_hire_job_cv_status')
-		if (!dict?.data) {
-			return
-		}
-		items.value = dict.data.map(e => {
-			return {
-				...e,
-				count: 0
-			}
-		})
-		// console.log(items)
-		if (reset) {
-			return
-		}
-		const { data } = await getRecommendCount()
-		if (!data) {
-			return
-		}
-		items.value.forEach(e => {
-			e.count = data.find(_e => _e.key === e.value)?.value || 0
-		})
-	} catch (error) {
-		// console.log(error)
-	}
-}
-
-</script>
-
-<style scoped lang="scss">
-.content {
-	display: flex;
-	justify-content: space-around;
-	padding: 36rpx 12rpx;
-	&-box {
-		font-size: 24rpx;
-		color: #999;
-		text-align: center;
-		&-value {
-			font-size: 1.8em;
-			color: #000;
-		}
-	}
-}
-</style>

+ 2 - 20
pages.json

@@ -173,15 +173,9 @@
 					}
 				},
 				{
-					"path": "jobFair/index",
+					"path": "jobFair/details",
 					"style": {
-						"navigationBarTitleText": "招聘会"
-					}
-				},
-				{
-					"path": "jobFair/jobFairShare",
-					"style": {
-						"navigationBarTitleText": "分享招聘会"
+						"navigationBarTitleText": "招聘会详情"
 					}
 				},
 				{
@@ -190,18 +184,6 @@
 						"navigationBarTitleText": "分享招聘会企业"
 					}
 				},
-				{
-					"path": "jobFair/enterprisesClassification",
-					"style": {
-						"navigationBarTitleText": "招聘会/企业"
-					}
-				},
-				{
-					"path": "jobFair/positionClassification",
-					"style": {
-						"navigationBarTitleText": "招聘会/职位"
-					}
-				},
 				{
 					"path": "InviteInterview/index",
 					"style": {

+ 66 - 1
pages/index/jobFair.vue

@@ -1,12 +1,43 @@
 <template>
-	<layout-page>招聘会</layout-page>
+	<layout-page>
+    <view style="padding-bottom: 30px; ">
+      <view v-if="items.length">
+        <uni-card v-for="val in items" :key="val.id" @tap="handleToJobFairEnterprises(val)">
+          <image v-if="val?.previewImg" class="ss-m-t-10" :src="val.previewImg" mode="widthFix" style="width: 100%; height: auto; border-radius: 6px;"></image>
+          <view class="ss-m-t-20">活动时间:{{ timesTampChange(val.startTime, 'Y-M-D') }}至{{ timesTampChange(val.endTime, 'Y-M-D') }}</view>
+          <button class="ss-m-t-20 ss-m-b-10" style="background-color: #00B760; color: #fff;" type="primary">立即加入</button>
+        </uni-card>
+      </view>
+      <view v-else class="nodata-img-parent">
+        <image src="https://minio.citupro.com/dev/static/nodata.png" mode="widthFix" style="width: 100vw;height: 100vh;"></image>
+      </view>
+    </view>
+  </layout-page>
 </template>
 
 <script setup>
 import layoutPage from '@/layout'
+import { ref, watch } from 'vue'
 import { onShow } from '@dcloudio/uni-app'
 import { getAccessToken } from '@/utils/request'
 import { showAuthModal } from '@/hooks/useModal'
+import { getJobFairList, checkJobFairPermission } from '@/api/jobFair'
+import { timesTampChange } from '@/utils/date'
+import { userStore } from '@/store/user'
+
+const useUserStore = userStore()
+const items = ref([])
+
+// 获得招聘会列表
+const getList = async () => {
+  const res = await getJobFairList()
+  items.value = res?.data || []
+}
+
+watch(() => useUserStore.refreshToken, () => {
+	if (!useUserStore.refreshToken) return items.value = []
+	getList()
+})
 
 onShow(() => {
 	// 设置自定义tabbar选中值
@@ -17,7 +48,41 @@ onShow(() => {
   currentTabBar?.setData({ selected: 3 })
 
 	if (!getAccessToken()) return showAuthModal()
+
+  getList()
 })
+
+//跳转招聘会详情
+const handleToJobFairEnterprises = async (val) => {
+  if (!val?.id) {
+    uni.showToast({ title: '资源获取失败,请稍后重试', icon: 'none' })
+  }
+
+  try {
+    const { data } = await checkJobFairPermission(val.id)
+    if (data) {
+      uni.navigateTo({
+        url: '/pagesB/jobFair/details?id=' + val.id
+      })
+    }
+  } catch (error) {
+    // 权限被禁用
+    if (error?.code === 1100056008) {
+      uni.showToast({ title: error.msg, icon: 'none', duration: 2000 })
+      return
+    }
+    // 没有权限参加招聘会,购买门票
+    if (error?.code === 1100056005) {
+      // 没有设置门票金额则提示无权限参加
+      if (!val?.admissionPrice || val?.admissionPrice <= 0) {
+        uni.showToast({ title: error.msg, icon: 'none', duration: 2000 })
+        return
+      }
+      // 设置门票金额则提示购买门票
+      uni.showToast({ title: '您暂时无法参加该招聘会,请先购买门票', icon: 'none', duration: 2000 })
+    }
+  }
+}
 </script>
 
 <style scoped lang="scss">

+ 118 - 0
pagesB/jobFair/details.vue

@@ -0,0 +1,118 @@
+<template>
+	<view class="box" :style="`background-color: ${jobFairInfo?.backgroundColour}`">
+		<view class="d-flex" style="padding: 15px 15px 0 15px;">
+			<view class="title-line"></view>
+			<rich-text class="title" :nodes="jobFairInfo?.title?.replace(/<\/?p[^>]*>/gi, '')"></rich-text>
+		</view>
+
+		<scroll-view class="scrollBox" :scroll-y="true" style="position:relative;">
+			<JobItem v-if="jobFairPosition?.length" :list="jobFairPosition" :jobFairId="id" @refresh="getJobFairPositionList" />
+			<uni-load-more v-else status="noMore" />
+		</scroll-view>
+
+		<view class="bottom-sticky">
+			<view class="bottom-content">
+				<button class="btnStyle bgButtons ss-m-l-15" type="primary" plain="true">我的分享海报</button>
+        <button class="buttons btnStyle" type="primary">职位加入</button>
+      </view>
+		</view>
+	</view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { getJobFair, getJobFairPosition } from '@/api/jobFair.js'
+import { dealDictArrayData } from '@/utils/position.js'
+import JobItem from './jobItem.vue'
+
+const id = ref(null)
+
+// 获取招聘会信息
+const jobFairInfo = ref({})
+const getJobFairInfo = async () => {
+  const { data } = await getJobFair(id.value)
+  if (!data) return
+  jobFairInfo.value = data || {}
+}
+
+// 获取招聘会职位
+const jobFairPosition = ref([])
+const getJobFairPositionList = async () => {
+  const { data } = await getJobFairPosition(id.value)
+  if (!data || !data.length) {
+		jobFairPosition.value = []
+		return
+	}
+  jobFairPosition.value = dealDictArrayData([], data)
+}
+
+onLoad((options) => {
+	id.value = options.id
+	if (!id.value) {
+		uni.showToast({
+			title: '缺少招聘会id',
+			icon: 'none'
+		})
+		setTimeout(() => {
+			uni.navigateBack({ delta: 1 })
+		}, 1000)
+		return
+	}
+
+	getJobFairInfo()
+	console.log('onLoad')
+	getJobFairPositionList()
+})
+</script>
+
+<style scoped lang="scss">
+.title {
+	font-size: 18px;
+	color: #fff;
+}
+.title-line {
+	width: 12px;
+	height: 18px;
+	background-color: #fff;
+	margin-right: 10px;
+	border-radius: 6px;
+	margin-top: 3px;
+}
+.bottom-content {
+  display: flex;
+  justify-content: space-evenly;
+  align-items: center;
+  width: 100%;
+  margin: 20rpx 0;
+  .btnStyle {
+    flex: 1;
+    margin-right: 20rpx;
+		border-radius: 50rpx;
+  }
+  .bgButtons {
+    border: 2rpx solid #00B760;
+    color: #00B760;
+  }
+  &-tool {
+    width: 160rpx;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+  }
+}
+.box {
+  height: 100vh;
+  overflow: hidden;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+}
+.scrollBox{
+  flex: 1;
+  height: 0 !important;
+  padding-bottom: 100rpx;
+  box-sizing: border-box;
+}
+</style>

+ 0 - 354
pagesB/jobFair/enterprisesClassification.vue

@@ -1,354 +0,0 @@
-<!-- 招聘会/企业详情 -->
-<template>
-  <view class="box" :style="`background-color: ${backgroundColor}`">
-    <scroll-view class="scrollBox" :scroll-y="true" :scroll-top="scrollTop" @scrolltolower="loadingMore" @scroll="onScroll" style="position:relative;">
-      <view style="position: relative;">
-        <!-- 轮播图 -->
-        <SwiperAd v-if="swiperAdList.length" :list="swiperAdList" margin="0" borderRadius="0" @click="handleToDetails"></SwiperAd>
-        <view class="stick ss-p-y-30" :style="`background-color: ${backgroundColor}`">
-          <view style="position: relative;">
-            <uni-search-bar
-              v-model="query.keyword"
-              placeholder="输入关键字"
-              cancelButton="none"
-              :focus="false"
-              bgColor="#fff"
-              @confirm="onSearch($event.value)"
-              @clear="query.keyword = ''; onSearch()"
-            >
-            </uni-search-bar>
-            <button class="search-btn" @tap.stop="onSearch">搜索</button>
-          </view>
-          <!-- tab页签 -->
-          <scroll-view v-if="tabList?.length" scroll-x="true" class="scroll-container">
-            <view
-              class="scroll-item"
-              :style="`margin-left: ${index ? '24px' : ''};`"
-              v-for="(val, index) in tabList" :key="val.key"
-              @tap="handClickTab(index)"
-            >
-              <view>
-                <view class="text">{{ val.title }}</view>
-                <view v-if="index === tabIndex" class="choose" style="background-color: #fff;"></view>
-                <view v-else class="choose" style="background-color: #ffffff00;"></view>
-              </view>
-            </view>
-          </scroll-view>
-        </view>
-        <view v-if="listData?.length" class="listDataBox">
-          <uni-card v-for="val in listData" :key="val.id" @click="toDetail(val)" :is-shadow="true" :border='false' shadow="0px 0px 3px 1px rgba(0,0,0,0.1)">
-            <view class="d-flex align-center ss-m-30" @click="null">
-              <image class="enterAvatar" :src="val.logoUrl ? val.logoUrl : 'https://minio.citupro.com/dev/menduner/company-avatar.png'"></image>
-              <view class="ss-m-l-20" style="flex: 1;">
-                <view class="font-size-16 enterpriseName">{{ formatName(val.anotherName || val.name) }}</view>
-                <view class="ss-m-t-5">
-                  <span class="color-999">{{ val?.industryName || '' }}</span>
-                  <span class="divider tag-gap1" v-if="val?.industryName && val?.scaleName"> | </span>
-                  <span class="color-999">{{ val?.scaleName || '' }}</span>
-                </view>
-                <view class="ss-m-t-10">
-                  <uni-tag 
-                    v-for="(tag,i) in val?.lastJobTop5 || []"
-                    :key="i"
-                    class="ss-m-r-5"
-                    :text="formatName(tag.name)"
-                    inverted="false"
-                    size="default"
-                    custom-style="background-color: #00B760; color: #fff; border-color: #00B760; display: inline-block;border-radius: 15px; margin: 0 5px 5px 0;"
-                  />
-                </view>
-              </view>
-            </view>
-            <view class="jobCount">{{ val.jobCount }}个在线职位招聘中 >>></view>
-          </uni-card>
-          <uni-load-more :status="more" :color="textColor" />
-        </view>
-        <view v-else class="nodata-img-parent">
-          <uni-load-more class="ss-m-t-50" :color="textColor" status="noMore" :content-text="{'contentnomore': loading ? '加载中. . .' : tabList?.length ? '暂无数据,请切换类型查看~': '暂无数据'}" />
-        </view>
-        <!-- 招聘会分享按钮 -->
-        <view v-if="showShareBtn" class="shareButtonBox" @tap="handleShare">
-          <uni-icons type="redo-filled" size="30" color="#00B760" />
-        </view>
-      </view>
-    </scroll-view>
-  </view>
-</template>
-
-<script setup>
-import { onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import { ref, reactive, computed } from 'vue'
-import { dealDictArrayData } from '@/utils/position'
-import { getJobFairEnterprisePage, getJobFair } from '@/api/jobFair'
-import SwiperAd from '@/components/SwiperAd'
-import { formatName } from '@/utils/getText'
-import { getShareQueryById } from '@/api/jobFair.js'
-
-const loading = ref(true)
-const more = ref('more')
-const listData = ref([])
-const query = reactive({
-  pageSize: 20, 
-  pageNo: 1,
-  keyword: '',
-  jobFairId: undefined,
-})
-
-const showShareBtn = ref(false)
-
-onLoad(async (options) => {
-  // 网站二维码分享
-	if (options.scene) {
-    const scene = decodeURIComponent(options.scene)
-    const key = scene.split('=')[1]
-    if (!key) return
-    const res = await getShareQueryById({key})
-    options.jobFairId = res?.data?.jobFairId
-  }
-  if (options?.jobFairId) {
-    query.jobFairId = options.jobFairId
-    getJobFairDetail()
-	}
-  
-  // 转发朋友
-  onShareAppMessage(() => {
-    if(!jobFairTitle.value){
-      setTimeout(() => {}, 1000)
-    }
-    return {
-      title: jobFairTitle.value,
-      path: `/pagesB/jobFair/enterprisesClassification?jobFairId=${options?.jobFairId}`
-    }
-  })
-  // 转发朋圈
-  onShareTimeline(() => {
-    if(!jobFairTitle.value){
-      setTimeout(() => {}, 1000)
-    }
-    return {
-      title: jobFairTitle.value || '门墩儿 专注顶尖招聘',
-      path: `/pagesB/jobFair/enterprisesClassification?jobFairId=${options?.jobFairId}`
-    }
-  })
-})
-
-// 招聘会详情
-const tabIndex = ref(-1)
-const tabList = ref([])
-const swiperAdList = ref([])
-const backgroundColor = ref('#fff')
-const jobFairTitle = ref('')
-const textColor = computed(() => {
-  return backgroundColor.value === '#fff' ? '#777' : '#fff'
-})
-const getJobFairDetail = async () => {
-  if (!query.jobFairId) return
-  const { data } = await getJobFair(query.jobFairId)
-  // 类型 -1为不传tag参数
-  tabList.value = data?.tag || []
-  handClickTab(tabList.value?.length ? 0 : -1)
-  // 轮播图
-  if (data?.headImg?.length) {
-    swiperAdList.value = data.headImg
-  }
-  // 背景色
-  if (data?.backgroundColour) {
-    backgroundColor.value = data.backgroundColour || '#fff'
-  }
-  if (data?.title) {
-    jobFairTitle.value = data.title
-  }
-  showShareBtn.value = Boolean(data?.shareImg)
-}
-getJobFairDetail()
-
-// 切换类型
-const handClickTab = (index) => {
-  tabIndex.value = index
-  query.pageNo = 1
-  listData.value = []
-  getEnterpriseList()
-}
-
-const onSearch = () => {
-  query.pageNo = 1
-  listData.value = []
-  getEnterpriseList()
-}
-
-const getEnterpriseList = async () => {
-  if (!query.jobFairId) return
-  try {
-    const params = { ...query }
-    // tab对应的职位类型id列表
-    const idList = tabIndex.value !== -1 ? tabList.value[tabIndex.value]?.content : []
-    idList?.length && idList.forEach((value, index) => { params[`enterpriseId[${index}]`] = value.value })
-
-    const res = await getJobFairEnterprisePage(params)
-    const list = res?.data?.list || []
-    listData.value = listData.value.concat(dealDictArrayData([], list))
-    loading.value = false
-    if (listData.value?.length === +res?.data?.total) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-    query.pageNo--
-    more.value = 'more'
-  }
-}
-
-const scrollTop = ref(0)
-const old = ref({
-  scrollTop: 0
-})
-const onScroll = (e) =>{
-  old.value.scrollTop = e.detail.scrollTop
-}
-
-// 加载更多
-const loadingMore = () => {
-  more.value = 'loading'
-  query.pageNo++
-  getEnterpriseList()
-}
-
-const toDetail = (item) =>{
-  if (!item?.id || !(item?.jobFairId ?? query.jobFairId)) return
-  let url = `/pagesB/jobFair/positionClassification?jobFairId=${query.jobFairId || item.jobFairId}&enterpriseId=${item.id}&entName=${item.anotherName}`
-  url = url + `&backgroundColor=${backgroundColor.value}`
-  uni.navigateTo({ url })
-}
-// const goBack = () => {
-// 	uni.navigateTo({
-// 		url: '/pagesB/jobFair/index'
-// 	})
-// }
-
-// 分享招聘会
-const handleShare = () => {
-	uni.navigateTo({
-    url: `/pagesB/jobFair/jobFairShare?jobFairId=${query.jobFairId}`
-	})
-}
-</script>
-
-<style scoped lang="scss">
-.stick {
-  z-index: 1;
-  position: sticky;
-  top: 0;
-}
-.shareButtonBox {
-  z-index: 1;
-  position: absolute;
-  right: 20px;
-  top: 16px;
-  border-radius: 8px;
-  padding: 7px 9px;
-  background-color: #fff;
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  // padding-bottom: 120rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.listDataBox {
-  // padding: 1px 0 120rpx;
-  padding-bottom: 120rpx;
-  margin: 0 5rpx;
-  margin-top: -10px;
-  .enterpriseName {
-    color: #404040;
-    font-weight: 700;
-  }
-  .enterAvatar {
-    width: 60px;
-    height: 60px;
-    // border-radius: 50%;
-    margin: auto;
-  }
-  .jobCount {
-    height: 40px;
-    line-height: 40px;
-    color: #00B760;
-    text-align: center;
-    // padding: 0 50rpx;
-    font-size: 15px;
-    // background: linear-gradient(to right, #12ebb0, #7ec04c);
-    background: #F5F5F5;
-  }
-}
-.scrollBox{
-  flex: 1;
-  height: 0 !important;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-}
-
-// :deep(.uni-load-more__text) {
-//   color: #fff !important;
-// }
-
-:deep(.uni-card) {
-  padding: 0 !important;
-  .uni-card__content {
-    padding: 0 !important;
-  }
-}
-
-.scroll-container {
-  width: calc(100vw - 20px);
-  padding: 0 20rpx;
-  white-space: nowrap; /* 确保子元素在一行内排列 */
-  .scroll-item {
-    display: inline-block; /* 子元素内联块显示 */
-    color: #fff;
-    font-size: 17px;
-    font-weight: 500;
-    .text {
-      padding: 20px 2px 0;
-    }
-    .choose {
-      width: 28px;
-      height: 2px;
-      border-radius: 8px;
-      margin: 8px auto;
-    }
-  }
-}
-
-:deep(.uni-searchbar) {
-  // background-color: #fff !important;
-  padding: 0;
-  margin: 0 10px;
-  border-radius: 5px;
-}
-
-:deep(.uni-searchbar__box) {
-  width: calc(100% - 100px);
-  height: 40px !important;
-  // border: 1px solid #00B760;
-  padding-right: 20px;
-  flex: none;
-  background-color: #fff;
-}
-
-.search-btn {
-  position: absolute;
-  right: 13px;
-  top: 3px;
-  width: 106px;
-  height: 34px;
-  line-height: 34px;
-  font-size: 16px;
-  // margin: 4px 4px 4px 0;
-  background-color: #00B760;
-  color: #fff;
-  border-radius: 5px;
-  z-index: 9;
-}
-</style>

+ 0 - 62
pagesB/jobFair/index.vue

@@ -1,62 +0,0 @@
-<!-- 招聘会 -->
-<template>
-  <view style="padding-bottom: 30px; ">
-    <view v-if="items.length">
-      <uni-card v-for="val in items" :key="val.id" @tap="handleToJobFairEnterprises(val)">
-        <image v-if="val?.previewImg" class="ss-m-t-10" :src="val.previewImg" mode="widthFix" style="width: 100%; height: auto; border-radius: 6px;"></image>
-        <view class="ss-m-t-20">活动时间:{{ timesTampChange(val.startTime, 'Y-M-D') }}至{{ timesTampChange(val.endTime, 'Y-M-D') }}</view>
-        <button class="ss-m-t-20 ss-m-b-10" style="background-color: #00B760; color: #fff;" type="primary">查看详情</button>
-      </uni-card>
-    </view>
-    <view v-else class="nodata-img-parent">
-      <image src="https://minio.citupro.com/dev/static/nodata.png" mode="widthFix" style="width: 100vw;height: 100vh;"></image>
-    </view>
-  </view>
-</template>
-<script setup>
-import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import { ref }  from 'vue'
-import { getJobFairList } from '@/api/jobFair'
-import { timesTampChange } from '@/utils/date'
-
-const items = ref([])
-
-// 获得招聘会列表
-const getList = async () => {
-  const res = await getJobFairList()
-  items.value = res?.data || []
-}
-getList()
-
-//招聘会
-const handleToJobFairEnterprises = (val) => {
-  if (!val?.id) {
-    uni.showToast({ title: '进去招聘会失败!', icon: 'none' })
-  }
-  let url = `/pagesB/jobFair/${Number(val?.category) ? 'positionClassification': 'enterprisesClassification'}?jobFairId=${val.id}`
-	uni.navigateTo({url})
-}
-
-
-const getShareParams = () => {
-  return {
-    title: '门墩儿-招聘会',
-    path: '/pagesB/jobFair/index',
-  }
-}
-
-// 转发朋友
-onShareAppMessage(() => {
-  return getShareParams()
-})
-// 转发朋圈
-onShareTimeline(() => {
-  return getShareParams()
-})
-
-</script>
-<style lang="scss" scoped>
-.line {
-  border-top: 1px solid #ccc;
-}
-</style>

+ 220 - 220
pagesB/jobFair/jobFairEntShare.vue

@@ -1,241 +1,241 @@
 <!-- 招聘会-分享企业 -->
 <template>
   <view style="position: relative;">
-    <view v-if="shareUrl" class="d-flex align-center flex-column justify-center" style="height: 100vh;">
+    <!-- <view v-if="shareUrl" class="d-flex align-center flex-column justify-center" style="height: 100vh;">
       <image v-if="!!shareUrl" :style="imgStyle" @click="handlePreviewSharePoster" :src="shareUrl" :show-menu-by-longpress="true"></image>
       <view class="color-999 ss-m-t-20 font-size-14 ss-m-b-50">点击图片预览,长按图片保存</view>
     </view>
-		<canvas canvas-id="posterCanvas" class="shareCanvas" style="width: 540px; height: 788px;"></canvas>
+		<canvas canvas-id="posterCanvas" class="shareCanvas" style="width: 540px; height: 788px;"></canvas> -->
   </view>
 </template>
 
 <script setup>
-import { ref, computed } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { getJobAdvertisedShareQrcode } from '@/api/user'
-import { getJobFairEntJobPage, getJobFair, saveShareQuery } from '@/api/jobFair'
-import { formatName } from '@/utils/getText'
-
-const shareUrl = ref('')
-const windowWidth = ref(0)
-let jobFairId = '' // 分享会ID
-let enterpriseId = '' // 企业ID
-let entName = '' // 企业名称
-let shareImg = '' // 分享背景图片-底图
-
-onLoad(async (options) => {
-  jobFairId = options.jobFairId
-  enterpriseId = options.enterpriseId
-  await getJobFairDetail()
-  await getEntPositionList()
-  const windowInfo = wx.getWindowInfo()
-  windowWidth.value = windowInfo.windowWidth
-  console.log(windowWidth.value, '当前机型屏幕宽')
-  if (shareImg) createPoster() // 生成海报
-})
-
-const getJobFairDetail = async () => {
-  if (!jobFairId) return
-  const { data } = await getJobFair(jobFairId)
-  shareImg = data?.contentImg || ''
-}
-
-let positionNameList = []
-let entLogoUrl = 'https://minio.citupro.com/dev/menduner/company-avatar.png'
-const getEntPositionList = async () => {
-  if (!jobFairId || !enterpriseId) {
-    uni.showToast({ title: '获取企业岗位失败,请重试!', icon: 'none', duration: 2000 })
-    return
-  }
-  try {
-    const params = {
-      pageSize: 3, 
-      pageNo: 1,
-      jobFairId,
-      enterpriseId,
-    }
-    const res = await getJobFairEntJobPage(params)
-    const list = res?.data?.list?.length ? res.data.list : []
-    positionNameList = list.map(e => { return formatName(e?.name) })
-    entLogoUrl = list[0]?.enterprise?.logoUrl || ''
-    entName = list[0]?.enterprise?.anotherName || ''
-  } catch (error) {}
-}
-
-const imgStyle = computed(() => {
-  if (windowWidth.value <= 320) return `width: 259px; height: 377px;`
-  if (windowWidth.value > 320 && windowWidth.value <= 375) return `width: 313px; height: 455px;`
-  if (windowWidth.value > 375) return `width: 328px; height: 474px;`
-})
-
-// 图片预览
-const handlePreviewSharePoster = () => {
-	uni.previewImage({
-		current: 0,
-		longPressActions: {
-			itemList: ['发送给朋友', '保存图片', '收藏']
-		},
-		urls: [shareUrl.value]
-	})
-}
-
-const getImageTempRatio = (url) => {
-  return new Promise((req, rej)=>{
-    wx.getImageInfo({
-      src:url,
-      success:(res) =>{
-        req(res)
-      }
-    })
-  })
-}
-
-const getToLocal = (base64data) => {
-  const fsm = wx.getFileSystemManager()
-  const FILE_BASE_NAME = `tmp_${new Date().getTime()}` // 自定义文件名
-  const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
-  if (!format) {
-    return (new Error('ERROR_BASE64SRC_PARSE'))
-  }
-  const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`
-  const buffer = wx.base64ToArrayBuffer(bodyData);
-  fsm.writeFile({
-    filePath,
-    data: buffer,
-    encoding: 'binary',
-    success(r) {
-      console.log(filePath,'filePath')
-      qrCode.value = filePath
-    },
-    fail() {
-      return (new Error('ERROR_BASE64SRC_WRITE'))
-    }
-  })
-}
-
-// 生成分享二维码
-const qrCode = ref()
-const handleShareCode = async () => {
-  const result = await saveShareQuery({ jobFairId, enterpriseId, entName })
-	const query = {
-		scene: 'id=' + result.data,
-    path: 'pagesB/jobFair/positionClassification',
-		width: 200,
-		autoColor: false,
-		checkPath: true,
-		hyaline: false // 二维码背景颜色为透明
-	}
-	const res = await getJobAdvertisedShareQrcode(query, { noAuth: true })
-	const data = res?.data ? 'data:image/png;base64,' + res.data : ''
-  getToLocal(data)
-}
-
-
-const createPoster = async () => {
-  uni.showLoading({ title: '生成中...', mask: true })
-  await handleShareCode() // 生产分享二维码
-  var context = uni.createCanvasContext('posterCanvas')
-
-  //清空画布
-  context.clearRect(0, 0, 540, 788)
-
-  //背景图片 
-  const { path: bgUrl } = await getImageTempRatio(shareImg)
-  context.drawImage(bgUrl, 0, 0, 540, 788) // 路径、x、y、宽、高
-
-  // 企业头像
-  context.save()
-  const secondImgWidth = 120
-  const secondImgHeight = 120
-  const x = (540 - secondImgWidth) / 2
-  const y = 788 - secondImgHeight - 460
-  context.beginPath()
-  context.arc(x + secondImgWidth / 2, y + secondImgHeight / 2, secondImgWidth / 2, 0, Math.PI * 2, true)
-  context.clip()
-  const { path: entLogoUrlPath } = await getImageTempRatio(entLogoUrl)
-  context.drawImage(entLogoUrlPath, x, y, secondImgWidth, secondImgHeight)
-  context.restore()
+// import { ref, computed } from 'vue'
+// import { onLoad } from '@dcloudio/uni-app'
+// import { getJobAdvertisedShareQrcode } from '@/api/user'
+// import { getJobFairEntJobPage, getJobFair, saveShareQuery } from '@/api/jobFair'
+// import { formatName } from '@/utils/getText'
+
+// const shareUrl = ref('')
+// const windowWidth = ref(0)
+// let jobFairId = '' // 分享会ID
+// let enterpriseId = '' // 企业ID
+// let entName = '' // 企业名称
+// let shareImg = '' // 分享背景图片-底图
+
+// onLoad(async (options) => {
+//   jobFairId = options.jobFairId
+//   enterpriseId = options.enterpriseId
+//   await getJobFairDetail()
+//   await getEntPositionList()
+//   const windowInfo = wx.getWindowInfo()
+//   windowWidth.value = windowInfo.windowWidth
+//   console.log(windowWidth.value, '当前机型屏幕宽')
+//   if (shareImg) createPoster() // 生成海报
+// })
+
+// const getJobFairDetail = async () => {
+//   if (!jobFairId) return
+//   const { data } = await getJobFair(jobFairId)
+//   shareImg = data?.contentImg || ''
+// }
+
+// let positionNameList = []
+// let entLogoUrl = 'https://minio.citupro.com/dev/menduner/company-avatar.png'
+// const getEntPositionList = async () => {
+//   if (!jobFairId || !enterpriseId) {
+//     uni.showToast({ title: '获取企业岗位失败,请重试!', icon: 'none', duration: 2000 })
+//     return
+//   }
+//   try {
+//     const params = {
+//       pageSize: 3, 
+//       pageNo: 1,
+//       jobFairId,
+//       enterpriseId,
+//     }
+//     const res = await getJobFairEntJobPage(params)
+//     const list = res?.data?.list?.length ? res.data.list : []
+//     positionNameList = list.map(e => { return formatName(e?.name) })
+//     entLogoUrl = list[0]?.enterprise?.logoUrl || ''
+//     entName = list[0]?.enterprise?.anotherName || ''
+//   } catch (error) {}
+// }
+
+// const imgStyle = computed(() => {
+//   if (windowWidth.value <= 320) return `width: 259px; height: 377px;`
+//   if (windowWidth.value > 320 && windowWidth.value <= 375) return `width: 313px; height: 455px;`
+//   if (windowWidth.value > 375) return `width: 328px; height: 474px;`
+// })
+
+// // 图片预览
+// const handlePreviewSharePoster = () => {
+// 	uni.previewImage({
+// 		current: 0,
+// 		longPressActions: {
+// 			itemList: ['发送给朋友', '保存图片', '收藏']
+// 		},
+// 		urls: [shareUrl.value]
+// 	})
+// }
+
+// const getImageTempRatio = (url) => {
+//   return new Promise((req, rej)=>{
+//     wx.getImageInfo({
+//       src:url,
+//       success:(res) =>{
+//         req(res)
+//       }
+//     })
+//   })
+// }
+
+// const getToLocal = (base64data) => {
+//   const fsm = wx.getFileSystemManager()
+//   const FILE_BASE_NAME = `tmp_${new Date().getTime()}` // 自定义文件名
+//   const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
+//   if (!format) {
+//     return (new Error('ERROR_BASE64SRC_PARSE'))
+//   }
+//   const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`
+//   const buffer = wx.base64ToArrayBuffer(bodyData);
+//   fsm.writeFile({
+//     filePath,
+//     data: buffer,
+//     encoding: 'binary',
+//     success(r) {
+//       console.log(filePath,'filePath')
+//       qrCode.value = filePath
+//     },
+//     fail() {
+//       return (new Error('ERROR_BASE64SRC_WRITE'))
+//     }
+//   })
+// }
+
+// // 生成分享二维码
+// const qrCode = ref()
+// const handleShareCode = async () => {
+//   const result = await saveShareQuery({ jobFairId, enterpriseId, entName })
+// 	const query = {
+// 		scene: 'id=' + result.data,
+//     path: 'pagesB/jobFair/positionClassification',
+// 		width: 200,
+// 		autoColor: false,
+// 		checkPath: true,
+// 		hyaline: false // 二维码背景颜色为透明
+// 	}
+// 	const res = await getJobAdvertisedShareQrcode(query, { noAuth: true })
+// 	const data = res?.data ? 'data:image/png;base64,' + res.data : ''
+//   getToLocal(data)
+// }
+
+
+// const createPoster = async () => {
+//   uni.showLoading({ title: '生成中...', mask: true })
+//   await handleShareCode() // 生产分享二维码
+//   var context = uni.createCanvasContext('posterCanvas')
+
+//   //清空画布
+//   context.clearRect(0, 0, 540, 788)
+
+//   //背景图片 
+//   const { path: bgUrl } = await getImageTempRatio(shareImg)
+//   context.drawImage(bgUrl, 0, 0, 540, 788) // 路径、x、y、宽、高
+
+//   // 企业头像
+//   context.save()
+//   const secondImgWidth = 120
+//   const secondImgHeight = 120
+//   const x = (540 - secondImgWidth) / 2
+//   const y = 788 - secondImgHeight - 460
+//   context.beginPath()
+//   context.arc(x + secondImgWidth / 2, y + secondImgHeight / 2, secondImgWidth / 2, 0, Math.PI * 2, true)
+//   context.clip()
+//   const { path: entLogoUrlPath } = await getImageTempRatio(entLogoUrl)
+//   context.drawImage(entLogoUrlPath, x, y, secondImgWidth, secondImgHeight)
+//   context.restore()
   
-  // 企业名称
-  const maxTextWidth = 400
-  const fontStyle = 'bold 24px Arial'
-  context.font = fontStyle
-  let truncatedText = entName
-  while (context.measureText(truncatedText + '...').width > maxTextWidth && truncatedText.length > 0) {
-    truncatedText = truncatedText.slice(0, -1)
-  }
-  if (truncatedText !== entName) truncatedText += '...'
-  const textX = x + (secondImgWidth - context.measureText(truncatedText).width) / 2
-  const textY = y + secondImgHeight + 30
-  context.fillStyle = '#000'
-  context.fillText(truncatedText, textX, textY)
+//   // 企业名称
+//   const maxTextWidth = 400
+//   const fontStyle = 'bold 24px Arial'
+//   context.font = fontStyle
+//   let truncatedText = entName
+//   while (context.measureText(truncatedText + '...').width > maxTextWidth && truncatedText.length > 0) {
+//     truncatedText = truncatedText.slice(0, -1)
+//   }
+//   if (truncatedText !== entName) truncatedText += '...'
+//   const textX = x + (secondImgWidth - context.measureText(truncatedText).width) / 2
+//   const textY = y + secondImgHeight + 30
+//   context.fillStyle = '#000'
+//   context.fillText(truncatedText, textX, textY)
   
-  // 职位标签
-  const tagPaddingLeftRight = 20
-  const tagPaddingTopBottom = 10
-  const tagRadius = 8
-  const tagSpacing = 22
-  let tagY = textY + tagSpacing + 10
-  positionNameList.forEach((tag) => {
-    let truncatedTag = tag
-    context.font = '18px Arial' // 绘制前设置字体,否则tagWidth受前面的font fontStyle影响
-
-    while (context.measureText(truncatedTag + '...').width > maxTextWidth - 2 * tagPaddingLeftRight && truncatedTag.length > 0) {
-      truncatedTag = truncatedTag.slice(0, -1)
-    }
-    if (truncatedTag !== tag) truncatedTag += '...'
-
-    const tagWidth = context.measureText(truncatedTag).width + 2 * tagPaddingLeftRight
-    const tagX = x + (secondImgWidth - tagWidth) / 2
-
-    context.fillStyle = '#00B760'
-    context.beginPath()
-    context.moveTo(tagX + tagRadius, tagY)
-    context.lineTo(tagX + tagWidth - tagRadius, tagY)
-    context.quadraticCurveTo(tagX + tagWidth, tagY, tagX + tagWidth, tagY + tagRadius)
-    context.lineTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2)
-    context.quadraticCurveTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX + tagWidth - tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
-    context.lineTo(tagX + tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
-    context.quadraticCurveTo(tagX, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX, tagY + tagPaddingTopBottom * 2)
-    context.lineTo(tagX, tagY + tagRadius);
-    context.quadraticCurveTo(tagX, tagY, tagX + tagRadius, tagY)
-    context.closePath()
-    context.fill()
-
-    context.fillStyle = '#fff'
-    context.fillText(truncatedTag, tagX + tagPaddingLeftRight, tagY + tagPaddingTopBottom + 10)
-
-    tagY += tagPaddingTopBottom * 2 + tagSpacing
-  })
+//   // 职位标签
+//   const tagPaddingLeftRight = 20
+//   const tagPaddingTopBottom = 10
+//   const tagRadius = 8
+//   const tagSpacing = 22
+//   let tagY = textY + tagSpacing + 10
+//   positionNameList.forEach((tag) => {
+//     let truncatedTag = tag
+//     context.font = '18px Arial' // 绘制前设置字体,否则tagWidth受前面的font fontStyle影响
+
+//     while (context.measureText(truncatedTag + '...').width > maxTextWidth - 2 * tagPaddingLeftRight && truncatedTag.length > 0) {
+//       truncatedTag = truncatedTag.slice(0, -1)
+//     }
+//     if (truncatedTag !== tag) truncatedTag += '...'
+
+//     const tagWidth = context.measureText(truncatedTag).width + 2 * tagPaddingLeftRight
+//     const tagX = x + (secondImgWidth - tagWidth) / 2
+
+//     context.fillStyle = '#00B760'
+//     context.beginPath()
+//     context.moveTo(tagX + tagRadius, tagY)
+//     context.lineTo(tagX + tagWidth - tagRadius, tagY)
+//     context.quadraticCurveTo(tagX + tagWidth, tagY, tagX + tagWidth, tagY + tagRadius)
+//     context.lineTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2)
+//     context.quadraticCurveTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX + tagWidth - tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
+//     context.lineTo(tagX + tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
+//     context.quadraticCurveTo(tagX, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX, tagY + tagPaddingTopBottom * 2)
+//     context.lineTo(tagX, tagY + tagRadius);
+//     context.quadraticCurveTo(tagX, tagY, tagX + tagRadius, tagY)
+//     context.closePath()
+//     context.fill()
+
+//     context.fillStyle = '#fff'
+//     context.fillText(truncatedTag, tagX + tagPaddingLeftRight, tagY + tagPaddingTopBottom + 10)
+
+//     tagY += tagPaddingTopBottom * 2 + tagSpacing
+//   })
 
   
-  //分享二维码
-  context.drawImage(qrCode.value, 80, 550, 110, 110)
+//   //分享二维码
+//   context.drawImage(qrCode.value, 80, 550, 110, 110)
 
-  context.font = 'bold 18px Arial'
-  context.fillStyle = '#000'
-  context.fillText('海量职位火热招聘中', 280, 605)
+//   context.font = 'bold 18px Arial'
+//   context.fillStyle = '#000'
+//   context.fillText('海量职位火热招聘中', 280, 605)
 
-  context.font = '15px Arial'
-  context.fillStyle = '#999'
-  context.fillText('长按图片识别二维码', 290, 625)
+//   context.font = '15px Arial'
+//   context.fillStyle = '#999'
+//   context.fillText('长按图片识别二维码', 290, 625)
   
 
-  context.draw(false, () =>{
-    wx.canvasToTempFilePath({ 
-      canvasId: 'posterCanvas',
-      success:(res)=>{
-        shareUrl.value = res.tempFilePath
-        console.log('canvas-success', shareUrl.value)
-		    uni.hideLoading({})
-      },
-      fail:(err)=>{
-        uni.hideLoading({})
-        console.log('canvas-fail', err)
-      }
-    })
-  })
-}
+//   context.draw(false, () =>{
+//     wx.canvasToTempFilePath({ 
+//       canvasId: 'posterCanvas',
+//       success:(res)=>{
+//         shareUrl.value = res.tempFilePath
+//         console.log('canvas-success', shareUrl.value)
+// 		    uni.hideLoading({})
+//       },
+//       fail:(err)=>{
+//         uni.hideLoading({})
+//         console.log('canvas-fail', err)
+//       }
+//     })
+//   })
+// }
 </script>
 
 <style scoped lang="scss">

+ 0 - 191
pagesB/jobFair/jobFairShare.vue

@@ -1,191 +0,0 @@
-<!-- 分享招聘会 -->
-<template>
-  <view style="position: relative;">
-    <view v-if="shareUrl" class="d-flex align-center flex-column justify-center" style="height: 100vh;">
-      <image v-if="!!shareUrl" :style="imgStyle" @click="handlePreviewSharePoster" :src="shareUrl" :show-menu-by-longpress="true"></image>
-      <view class="color-999 ss-m-t-20 font-size-14 ss-m-b-50">点击图片预览,长按图片保存</view>
-    </view>
-		<canvas canvas-id="posterCanvas" class="shareCanvas" :style="`width: ${canvasWidth}px; height: ${canvasHeight}px;`"></canvas>
-  </view>
-</template>
-
-<script setup>
-import { ref, computed } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { getJobAdvertisedShareQrcode } from '@/api/user'
-import { getJobFair, saveShareQuery } from '@/api/jobFair'
-
-const canvasWidth = 500
-const canvasHeight = 900
-
-const shareUrl = ref('')
-const windowWidth = ref(0)
-let jobFairId = '' // 分享会ID
-let isEnt = false // 招聘会类型
-let shareImg = '' // 分享背景图片-底图
-// let shareImg = 'https://menduner.citupro.com:3443/dev/4dd7dd3c9ef350d62fcbc814b88c1ac1916f484a3ee8d8531ae7a2698a289670.jpg' // 分享背景图片-底图
-
-onLoad(async (options) => {
-  jobFairId = options.jobFairId
-  await getJobFairDetail()
-  const windowInfo = wx.getWindowInfo()
-  windowWidth.value = windowInfo.windowWidth
-  console.log(windowWidth.value, '当前机型屏幕宽')
-})
-
-const getJobFairDetail = async () => {
-  if (!jobFairId) return
-  const { data } = await getJobFair(jobFairId)
-  shareImg = data?.shareImg || ''
-  isEnt = Number(data?.category)
-  if (shareImg) createPoster()
-}
-
-const imgStyle = computed(() => {
-  if (windowWidth.value <= 320) return `width: 259px; height: ${Math.round((canvasHeight*259)/canvasWidth)}px;`
-  if (windowWidth.value > 320 && windowWidth.value <= 375) return `width: 313px; height: ${Math.round((canvasHeight*313)/canvasWidth)}px;`
-  if (windowWidth.value > 375) return `width: 328px; height: ${Math.round((canvasHeight*328)/canvasWidth)}px;`
-})
-
-// 图片预览
-const handlePreviewSharePoster = () => {
-	uni.previewImage({
-		current: 0,
-		longPressActions: {
-			itemList: ['发送给朋友', '保存图片', '收藏']
-		},
-		urls: [shareUrl.value]
-	})
-}
-
-const getImageTempRatio = (url) => {
-  return new Promise((req, rej)=>{
-    wx.getImageInfo({
-      src:url,
-      success:(res) =>{
-        req(res)
-      }
-    })
-  })
-}
-
-// const getToLocal = (base64data) => {
-//   const fsm = wx.getFileSystemManager()
-//   const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
-//   const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
-//   if (!format) {
-//     return (new Error('ERROR_BASE64SRC_PARSE'))
-//   }
-//   const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`
-//   const buffer = wx.base64ToArrayBuffer(bodyData);
-//   fsm.writeFile({
-//     filePath,
-//     data: buffer,
-//     encoding: 'binary',
-//     success(r) {
-//       console.log(filePath,'filePath')
-//       qrCode.value = filePath
-//     },
-//     fail() {
-//       return (new Error('ERROR_BASE64SRC_WRITE'))
-//     }
-//   })
-// }
-const getToLocal = (base64data) => {
-  return new Promise((resolve, reject) => {
-    const fsm = wx.getFileSystemManager()
-    const FILE_BASE_NAME = `tmp_${new Date().getTime()}` // 自定义文件名
-    const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
-    if (!format) {
-      reject(new Error('ERROR_BASE64SRC_PARSE'))
-      return
-    }
-    const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`
-    const buffer = wx.base64ToArrayBuffer(bodyData)
-    fsm.writeFile({
-      filePath,
-      data: buffer,
-      encoding: 'binary',
-      success(r) {
-        resolve(filePath) // 成功时返回 filePath
-      },
-      fail() {
-        reject(new Error('ERROR_BASE64SRC_WRITE'))
-      },
-    })
-  })
-}
-
-// 生成分享二维码
-const qrCode = ref()
-const handleShareCode = async () => {
-  const result = await saveShareQuery({ jobFairId })
-	const query = {
-    scene: 'id=' + result.data,
-    path: `pagesB/jobFair/${!isEnt ? 'enterprisesClassification' : 'positionClassification'}`,
-		width: 200,
-		autoColor: false,
-		checkPath: true,
-		hyaline: false // 二维码背景颜色为透明
-	}
-  console.log(result.data, query.scene, '=========================')
-	const res = await getJobAdvertisedShareQrcode(query, { noAuth: true })
-	const data = res?.data ? 'data:image/png;base64,' + res.data : ''
-  const filePath = await getToLocal(data) // 等待 getToLocal 完成
-  qrCode.value = filePath
-}
-
-const createPoster = async () => {
-  uni.showLoading({ title: '生成中...', mask: true })
-  await handleShareCode() // 生产分享二维码
-
-  var context = uni.createCanvasContext('posterCanvas')
-
-  //清空画布
-  context.clearRect(0, 0, canvasWidth, canvasHeight)
-
-  //背景图片 
-  const { path: bgUrl } = await getImageTempRatio(shareImg)
-  context.drawImage(bgUrl, 0, 0, canvasWidth, canvasHeight) // 路径、x、y、宽、高
-  
-  //分享二维码
-  const qrCodeWidth = 127
-  const qrCodeHeight = 127
-  const qrCodeX = 188
-  const qrCodeY = 585
-  console.log('dddd', qrCode.value)
-  context.drawImage(qrCode.value, qrCodeX, qrCodeY, qrCodeWidth, qrCodeHeight)
-  
-  context.font = 'bold 16px Arial'
-  context.fillStyle = '#10325d'
-  const text = '诚挚邀约 共享机遇'
-  const textWidth = context.measureText(text).width
-  const textX = qrCodeX + (qrCodeWidth - textWidth) / 2
-  const textY = qrCodeY + qrCodeHeight + 30
-  context.fillText(text, textX, textY)
-  
-  context.draw(false, () =>{
-    wx.canvasToTempFilePath({ 
-      canvasId: 'posterCanvas',
-      success:(res)=>{
-        shareUrl.value = res.tempFilePath
-        console.log('canvas-success', shareUrl.value)
-        uni.hideLoading({})
-      },
-      fail:(err)=>{
-        uni.hideLoading({})
-        console.log('canvas-fail', err)
-      }
-    })
-  })
-}
-</script>
-
-<style scoped lang="scss">
-.shareCanvas {
-	position: fixed;
-	top: -99999upx;
-	left: -99999upx;
-	z-index: -99999;
-}
-</style>

+ 162 - 0
pagesB/jobFair/jobItem.vue

@@ -0,0 +1,162 @@
+<template>
+  <view class="ss-m-x-20">
+    <view v-if="list?.length" class="ss-p-b-30 ss-p-t-20">
+      <view v-for="(item, index) in list" :key="index" class="mList">
+        <view class="list-shape" style="border-radius: 12px;">
+          <view class="titleBox" @tap.stop="handleToDetail(item)">
+            <view style="display: flex;align-items: center;">
+							<image src="/static/svg/jobFair.svg" class=" ss-m-r-10" style="width: 20px; height: 20px;"></image>
+              <rich-text v-if="item.name?.indexOf('style') !== -1" class="job-name" :nodes="item.name"></rich-text>
+              <view v-else class="job-name">{{ formatName(item.name) }}</view>
+            </view>
+          </view>
+          <view class="d-flex align-center justify-space-between ss-m-t-20" @tap.stop="handleToDetail(item)">
+            <view class="font-size-13 ellipsis" style="flex: 1;">
+              <span class="tag-gap" style="color: #808080;">
+                <span>{{item.area?.str ?? '全国' }}</span>
+                <span class="divider-mx" v-if="item.eduName">|</span>
+                <span>{{item.eduName }}</span>
+                <span class="divider-mx" v-if="item.expName">|</span>
+                <span>{{item.expName }}</span>
+                <span class="divider-mx">|</span>
+                <span>{{!item.payFrom && !item.payTo ? '面议' : `${item.payFrom}-${item.payTo}${item.payName ? '/' + item.payName : ''}` }}</span>
+              </span>
+            </view>
+          </view>
+          <view class="sub-li-bottom">
+						<view class="sub-li-bottom-item color-primary" @tap.stop="handleToResume(item)">{{ item.count || 0 }} 已投递简历</view>
+						<view class="sub-li-bottom-item color-error" @tap.stop="handleRemove(item)">移出招聘会</view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+		<uni-popup ref="removePopup" type="dialog">
+			<uni-popup-dialog 
+				type="warn" 
+				cancelText="取消" 
+				confirmText="确定" 
+				title="系统提示" 
+				content="是否确认将此职位移出招聘会?" 
+				@confirm="handleRemoveConfirm"
+				@close="handleRemoveClose"
+			></uni-popup-dialog>
+		</uni-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { formatName } from '@/utils/getText'
+import { quitJobFairPosition } from '@/api/jobFair'
+
+const emit = defineEmits(['refresh'])
+const props = defineProps({
+	list: Array,
+	jobFairId: [String, Number]
+})
+
+// 查看职位详情
+const handleToDetail = (val) => {
+	console.log(val, '查看职位详情')
+	uni.navigateTo({
+		url: `pagesB/positionDetail/index?jobId=${val.id}&jobFairId=${props.jobFairId}`
+	})
+}
+
+
+// 查看职位投递简历
+const handleToResume = (val) => {
+	console.log(val, '投递简历数')
+}
+
+// 移出招聘会
+const removePopup = ref()
+const removeParams = ref({})
+const handleRemove = (val) => {
+	removeParams.value = val
+	removePopup.value.open()
+}
+const handleRemoveClose = () => {
+	removeParams.value = {}
+  removePopup.value.close()
+}
+const handleRemoveConfirm = async () => {
+	if (!removeParams.value.id || !props.jobFairId) {
+		uni.showToast({ title: '正在维护中,请稍后再试', icon: 'none', duration: 2000 })
+		return
+	}
+	uni.showLoading({ title: '加载中' })
+	try {
+		await quitJobFairPosition({ jobFairId: props.jobFairId, jobId: removeParams.value.id })
+		uni.hideLoading()
+		uni.showToast({ title: '移出成功', icon: 'none' })
+		removeParams.value = {}
+		emit('refresh')
+	} catch {
+		removeParams.value = {}
+		uni.hideLoading()
+	}
+}
+</script>
+
+<style scoped lang="scss">
+.job-name {
+  font-size: 16px;
+  font-weight: 700;
+  color: #0E100F;
+  max-width: 80vw;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
+.sub-li-bottom {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 10px;
+  padding-top: 10px;
+  font-size: 13px;
+  color: #666;
+	&-item {
+		width: 50%;
+		height: 35px;
+		line-height: 35px;
+		text-align: center;
+		margin-right: 15px;
+		background-color: #f7f8fa;
+		border-radius: 4px;
+		&:nth-child(2) {
+			margin-right: 0;
+		}
+	}
+}
+
+.salary-text {
+	float: right;
+	color: #00B760;
+  font-weight: 700;
+}
+.list-shape {
+	padding: 10px 30rpx 10px;
+  background-color: #fff;
+  border-radius: 12px 12px 0 0;
+  .titleBox {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+}
+.tag-gap{
+	margin: 10rpx 10rpx 10rpx 0;
+}
+.divider-mx{
+	margin: 0 10rpx;
+}
+.divider {
+	color:#e4d4d2;
+}
+.mList {
+  margin-bottom: 20rpx;
+}
+</style>

+ 0 - 390
pagesB/jobFair/positionClassification.vue

@@ -1,390 +0,0 @@
-<!-- 招聘会职位列表 / 招聘会内的企业下-职位列表 -->
-<!-- 没有企业ID的就是招聘会下的职位列表。存在企业ID的就是招聘会企业下的职位列表。 -->
-<template>
-  <view class="box" :style="`background-color: ${backgroundColor}`">
-    <scroll-view class="scrollBox" :scroll-y="true" :scroll-top="scrollTop" @scrolltolower="loadingMore" @scroll="onScroll" style="position:relative;">
-      <view style="position: relative;">
-
-        <!-- 招聘会企业下的职位列表 -->
-        <template v-if="query?.enterpriseId">
-          <view class="enterpriseName" :style="`color: ${entNameColor}`">{{ entName }}</view>
-          <view class="stick ss-p-y-30" :style="`background-color: ${backgroundColor}`">
-            <!-- 搜索条 -->
-            <view style="position: relative;">
-              <uni-search-bar
-                v-model="query.keyword"
-                placeholder="输入关键字"
-                cancelButton="none"
-                :focus="false"
-                bgColor="#fff"
-                @confirm="onSearch($event.value)"
-                @clear="query.keyword = ''; onSearch()"
-              >
-              </uni-search-bar>
-              <button class="search-btn" @tap.stop="onSearch">搜索</button>
-            </view>
-          </view>
-        </template>
-
-        <!-- 招聘会职位列表 -->
-        <template v-else>
-          <SwiperAd v-if="swiperAdList.length && !query.enterpriseId" :list="swiperAdList" margin="0" borderRadius="0"></SwiperAd>
-          <view class="stick ss-p-y-30" :style="`background-color: ${backgroundColor}`">
-            <view style="position: relative;">
-              <uni-search-bar
-                v-model="query.keyword"
-                placeholder="输入关键字"
-                cancelButton="none"
-                :focus="false"
-                bgColor="#fff"
-                @confirm="onSearch($event.value)"
-                @clear="query.keyword = ''; onSearch()"
-              >
-              </uni-search-bar>
-              <button class="search-btn" @tap.stop="onSearch">搜索</button>
-            </view>
-            
-            <!-- 横向分类页签 -->
-            <scroll-view v-if="tabList?.length && !query.enterpriseId" scroll-x="true" class="scroll-container">
-              <view
-                class="scroll-item"
-                :style="`margin-left: ${index ? '24px' : ''};`"
-                v-for="(val, index) in tabList" :key="index+val"
-                @tap="handClickTab(index)"
-              >
-                <view>
-                  <view class="text">{{ val.title }}</view>
-                  <view v-if="index === tabIndex" class="choose" style="background-color: #fff;"></view>
-                  <view v-else class="choose" style="background-color: #ffffff00;"></view>
-                </view>
-              </view>
-            </scroll-view>
-          </view>
-        </template>
-        <view v-if="listData?.length" class="listDataBox">
-          <PositionList
-            :list="listData"
-            :noMore="false"
-            :jobFairId="query.jobFairId"
-            :showUpdateTime="false"
-            :noDataTextColor="textColor"
-            @entClick="entClick"
-          ></PositionList>
-          <uni-load-more :status="more" :color="textColor" />
-        </view>
-        <view v-else class="nodata-img-parent">
-          <uni-load-more class="ss-m-t-50" :color="textColor" status="noMore" :content-text="{'contentnomore': loading ? '加载中. . .' : tabList?.length ? '暂无数据,请切换类型查看~': '暂无数据'}" />
-        </view>
-        <!-- 招聘会分享按钮 -->
-        <view v-if="showShareBtn" class="shareButtonBox" @tap="handleShare">
-          <uni-icons type="redo-filled" size="30" color="#00B760" />
-        </view>
-      </view>
-    </scroll-view>
-  </view>
-</template>
-
-<script setup>
-import { onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import { ref, reactive, computed } from 'vue'
-import { dealDictObjData } from '@/utils/position'
-import { getJobFairEntJobPage, getJobFair } from '@/api/jobFair'
-import PositionList from '@/components/PositionList'
-import SwiperAd from '@/components/SwiperAd'
-import { getShareQueryById } from '@/api/jobFair.js'
-
-const loading = ref(true)
-const more = ref('more')
-const listData = ref([])
-const query = reactive({
-  pageSize: 20, 
-  pageNo: 1,
-  keyword: '',
-  jobFairId: undefined,
-})
-
-const entName = ref('')
-const showShareBtn = ref(false)
-
-onLoad(async (options) => {
-  // 海报二维码分享
-	if (options.scene) {
-    const scene = decodeURIComponent(options.scene)
-    console.log(scene, 'scene')
-    const key = scene.split('=')[1]
-    if (!key) return
-    const res = await getShareQueryById({key})
-    console.log(res, 'result')
-    options.jobFairId = res?.data?.jobFairId
-    options.enterpriseId = res?.data?.enterpriseId
-    options.backgroundColor = res?.data?.backgroundColor
-    options.entName = res?.data?.entName
-  }
-  if (options?.jobFairId) {
-    query.jobFairId = options.jobFairId
-    if (options.enterpriseId) {
-      query.enterpriseId = options.enterpriseId
-      entName.value = options.entName
-      getEntShareImg()
-      getEntPositionList()
-    } else {
-      getJobFairDetail()
-    }
-  }
-  if (options.backgroundColor) backgroundColor.value = options.backgroundColor
-  
-  // 转发朋友
-  onShareAppMessage(() => {
-    if (!options?.enterpriseId && !jobFairTitle.value) setTimeout(() => {}, 1000)
-    let path = `/pagesB/jobFair/positionClassification?jobFairId=${options.jobFairId}`
-    if (options?.enterpriseId) path += `&enterpriseId=${options.enterpriseId}&entName=${options.entName}`
-    return {
-      title: options?.enterpriseId ? options?.entName || '门墩儿 专注顶尖招聘' : jobFairTitle.value,
-      path
-    }
-  })
-  // 转发朋圈
-  onShareTimeline(() => {
-    if (!query.enterpriseId && !jobFairTitle.value) setTimeout(() => {}, 1000)
-    let path = `/pagesB/jobFair/positionClassification?jobFairId=${options.jobFairId}`
-    if (options?.enterpriseId) path += `&enterpriseId=${options.enterpriseId}&entName=${options.entName}`
-    return {
-      title: query.enterpriseId ? entName.value || '门墩儿 专注顶尖招聘' : jobFairTitle.value,
-      path
-    }
-  })
-})
-
-// 招聘会详情
-const tabIndex = ref(-1)
-const tabList = ref([])
-const swiperAdList = ref([])
-const backgroundColor = ref('#fff')
-const jobFairTitle = ref('')
-const textColor = computed(() => {
-  return backgroundColor.value === '#fff' ? '#777' : '#fff'
-})
-const entNameColor = computed(() => {
-  return backgroundColor.value === '#fff' ? '#00B760' : '#fff'
-})
-const getJobFairDetail = async () => {
-  if (!query.jobFairId) return
-  const { data } = await getJobFair(query.jobFairId)
-  // 类型 -1为不传tag参数
-  tabList.value = data?.tag || []
-  handClickTab(tabList.value?.length ? 0 : -1)
-
-  // 轮播图
-  if (data?.headImg?.length) {
-    swiperAdList.value = data.headImg
-  }
-  // 背景色
-  if (data?.backgroundColour) {
-    backgroundColor.value = data.backgroundColour || '#fff'
-  }
-  if (data?.title) {
-    jobFairTitle.value = data.title
-  }
-  showShareBtn.value = Boolean(data?.shareImg)
-}
-
-const getEntShareImg = async () => {
-  if (!query.jobFairId) return
-  const { data } = await getJobFair(query.jobFairId)
-  showShareBtn.value = Boolean(data?.contentImg)
-  backgroundColor.value = data.backgroundColour || '#fff'
-}
-
-// 切换类型
-const handClickTab = (index) => {
-  tabIndex.value = index
-  query.pageNo = 1
-  listData.value = []
-  getEntPositionList()
-}
-
-const onSearch = () => {
-  query.pageNo = 1
-  listData.value = []
-  getEntPositionList()
-}
-
-const getEntPositionList = async () => {
-  if (!query.jobFairId) {
-    uni.showToast({ title: '获取企业岗位失败,请重试!', icon: 'none', duration: 2000 })
-    return
-  }
-  try {
-    const params = { ...query }
-    // tab对应的职位类型id列表
-    const idList = tabIndex.value !== -1 ? tabList.value[tabIndex.value]?.content : []
-    idList?.length && idList.forEach((value, index) => { params[`positionId[${index}]`] = value.value })
-    //
-    const res = await getJobFairEntJobPage(params)
-    const list = res?.data?.list || []
-    list.forEach(e => {
-      e.job = dealDictObjData({}, e)
-      e.enterprise = { ...e.enterprise, ...dealDictObjData({}, e.enterprise)}
-    })
-    listData.value = listData.value.concat(list)
-    loading.value = false
-    if (listData.value?.length === +res?.data?.total) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-    query.pageNo--
-    more.value = 'more'
-  }
-}
-
-const scrollTop = ref(0)
-const old = ref({
-  scrollTop: 0
-})
-const onScroll = (e) =>{
-  old.value.scrollTop = e.detail.scrollTop
-}
-
-// 加载更多
-const loadingMore = () => {
-  more.value = 'loading'
-  query.pageNo++
-  getEntPositionList()
-}
-
-const entClick = (info) => {
-  // 点击企业信息跳转企业职位列表(招聘会内)。如果已经在了则不跳转
-  if (info?.enterpriseId && !query.enterpriseId) {
-    const url = `/pagesB/jobFair/positionClassification?jobFairId=${query.jobFairId }&enterpriseId=${info.enterpriseId}&entName=${info.anotherName}`
-    uni.navigateTo({ url })
-  }
-}
-
-const handleShare = () => {
-  // 分享招聘会
-  let url = `/pagesB/jobFair/${query.enterpriseId ? 'jobFairEntShare' : 'jobFairShare'}?jobFairId=${query.jobFairId}`
-  // 分享招聘会企业
-  if (query.enterpriseId) url = url + `&enterpriseId=${query.enterpriseId}`
-	uni.navigateTo({ url })
-}
-</script>
-
-<style scoped lang="scss">
-.stick {
-  z-index: 1;
-  position: sticky;
-  top: 0;
-}
-.shareButtonBox {
-  z-index: 1;
-  position: absolute;
-  right: 20px;
-  top: 16px;
-  border-radius: 8px;
-  padding: 7px 9px;
-  background-color: #fff;
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  // padding-bottom: 120rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.listDataBox {
-  // padding: 1px 0 120rpx;
-  padding-bottom: 120rpx;
-  margin: 0 5rpx;
-}
-.scrollBox{
-  flex: 1;
-  height: 0 !important;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-}
-
-// :deep(.uni-load-more__text) {
-//   color: #fff !important;
-// }
-
-:deep(.uni-card) {
-  padding: 0 !important;
-  .uni-card__content {
-    padding: 0 !important;
-  }
-}
-
-.scroll-container {
-  width: calc(100vw - 20px);
-  padding: 0 20rpx;
-  white-space: nowrap; /* 确保子元素在一行内排列 */
-  .scroll-item {
-    display: inline-block; /* 子元素内联块显示 */
-    color: #fff;
-    font-size: 17px;
-    font-weight: 500;
-    .text {
-      padding: 20px 2px 0;
-    }
-    .choose {
-      width: 28px;
-      height: 2px;
-      border-radius: 8px;
-      margin: 8px auto;
-    }
-  }
-}
-
-.enterpriseName {
-  color: #fff;
-  font-size: 18px;
-  font-weight: bold;
-  line-height: 28px;
-  padding: 20px 80px 20px 30px;
-  position: relative;
-  &::before {
-    display: block;
-    content: '';
-    width: 6px;
-    height: 30px;
-    background-color: #fff;
-    position: absolute;
-    top: 20px;
-    left: 12px;
-    border-radius: 2px;
-  }
-}
-
-:deep(.uni-searchbar) {
-  // background-color: #fff !important;
-  padding: 0;
-  margin: 0 10px;
-  border-radius: 5px;
-}
-
-:deep(.uni-searchbar__box) {
-  width: calc(100% - 100px);
-  height: 40px !important;
-  // border: 1px solid #00B760;
-  padding-right: 20px;
-  flex: none;
-  background-color: #fff;
-}
-
-.search-btn {
-  position: absolute;
-  right: 13px;
-  top: 3px;
-  width: 106px;
-  height: 34px;
-  line-height: 34px;
-  font-size: 16px;
-  // margin: 4px 4px 4px 0;
-  background-color: #00B760;
-  color: #fff;
-  border-radius: 5px;
-  z-index: 9;
-}
-</style>

+ 9 - 3
pagesB/positionDetail/index.vue

@@ -78,6 +78,12 @@
         </view>
       </view>
     </scroll-view>
+    <view class="bottom-sticky" v-if="!loading && jobId">
+      <view class="bottom-content">
+        <!-- <button class="btnStyle bgButtons" type="primary" plain="true" @tap="handleSend">立即沟通</button> -->
+        <button class="buttons btnStyle" type="primary" @click="handleEdit">编辑职位</button>
+      </view>
+    </view>
   </layout-page>
 </template>
 
@@ -100,7 +106,6 @@ const loadingText = ref('加载中 . . . ')
 const info = ref({})
 const positionInfo = ref({})
 const beenLogin = ref(false)
-const areaName = ref('')
 
 // 监听登录状态
 watch(() => useUserStore.refreshToken, (newVal) => {
@@ -111,8 +116,8 @@ let jobId = ''
 const isJobFair = ref(false) // 是否是通过招聘会进入的岗位
 let obj = {}
 onLoad(async (options) => {
-  areaName.value = options?.area || ''
   jobId = options?.id || options?.jobId || obj?.jobId || ''
+  if (options?.jobFairId) isJobFair.value = true
   if (jobId) {
     loading.value = true
     loadingText.value = '加载中 . . . '
@@ -142,11 +147,12 @@ async function getPositionDetail () {
     info.value = data
     positionInfo.value = { ...dealDictObjData({}, info.value), ...info.value, enterprise: dealDictObjData({}, data.enterprise) }
     loading.value = false
-    areaName.value = positionInfo.value.area?.str ?? '全国'
   } finally {
   }
 }
 
+const handleEdit = () => {}
+
 </script>
 
 <style scoped lang="scss">

+ 0 - 122
pagesB/positionDetail/similar.vue

@@ -1,122 +0,0 @@
-<template>
-  <view>
-    <view class="box defaultBgc">
-      <scroll-view class="scrollBox" :scroll-y="true" :scroll-top="scrollTop" @scrolltolower="loadingMore" @scroll="onScroll" style="position:relative;">
-        <PositionList :list="positionListData" :noMore="false"></PositionList>
-        <uni-load-more :status="more" />
-      </scroll-view>
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue'
-import PositionList from '@/components/PositionList'
-import { dealDictArrayData } from '@/utils/position'
-import { getSimilarPosition } from '@/api/position'
-
-const props = defineProps({
-  id: String
-})
-const more = ref('more')
-
-const positionListData = ref([])
-const query = reactive({
-  pageSize: 10, 
-  pageNo: 1,
-	id: props.id
-})
-console.log(props.id, '==================')
-const getData = async () => {
-  try {
-    const res = await getSimilarPosition(query)
-    const arr = res?.data?.list || []
-    // 推荐接口返回数据需要拼接
-    const list = arr
-    positionListData.value.push(...dealDictArrayData(list))
-    if (positionListData.value.length === +res.data.total) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-    query.pageNo--
-    more.value = 'more'
-  }
-}
-
-const scrollTop = ref(0)
-const old = ref({
-  scrollTop: 0
-})
-const onScroll = (e) =>{
-  old.value.scrollTop = e.detail.scrollTop
-}
-
-// 加载更多
-const loadingMore = () => {
-  more.value = 'loading'
-  query.pageNo++
-  getData()
-}
-
-</script>
-
-<style scoped lang="scss">
-.stick {
-  z-index: 1;
-  position: sticky;
-  top: 0;
-}
-.stickFilter {
-  z-index: 1;
-  position: sticky;
-  box-shadow: 0px 10rpx 12rpx 0px rgba(195, 195, 195, .25);
-  top: 120rpx;
-}
-.px-0 { padding-left: 0 !important; padding-right: 0 !important; }
-.pb-10 {
-  padding-bottom: 10px;
-}
-.pb-20 { padding-bottom: 20px; }
-.px-5 { padding-left: 5px; padding-right: 5px; }
-.px-10 { padding-left: 10px; padding-right: 10px; }
-.mx-10 { margin-left: 10px; margin-right: 10px }
-.mx-20 { margin-left: 20px; margin-right: 20px; }
-.mb-10 { margin-bottom: 10px; }
-.box {
-  height: 100vh;
-  overflow: hidden;
-  padding-bottom: 120rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-  flex: 1;
-  height: 0 !important;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-}
-:deep(.uni-searchbar__box) {
-  width: calc(100% - 105px);
-  height: 40px !important;
-  border: 1px solid #00B760;
-  padding-right: 20px;
-  flex: none;
-}
-.search-btn {
-  position: absolute;
-  right: 11px;
-  top: 10px;
-  width: 110px;
-  height: 40px;
-  font-size: 16px;
-  background-color: #00B760;
-  color: #fff;
-  border-radius: 0 5px 5px 0;
-  z-index: 9;
-}
-:deep(.picker-view) {
-  padding-bottom: 80px !important;
-}
-</style>