分类渲染数据类型 : 岗位详情 公司详情 岗位收藏 公司收藏 浏览记录 预约列表

This commit is contained in:
xiebin
2025-11-23 18:20:28 +08:00
parent 06fb492cbd
commit abd91e2cb7
22 changed files with 1544 additions and 242 deletions

View File

@@ -0,0 +1,157 @@
<template>
<view v-for="company in listData" :key="company.id">
<view v-if="company.dataType==2" class="cards" @click="nextDetail(company)">
<view class="card-company">
<text class="company line_1">{{ company.name }}</text>
</view>
<view class="card-bottom">
<view class="fl_box fs_14">
<view class="mar_ri10">{{company.industry}}</view>
<view>{{company.scale }}</view>
</view>
<view class="ris">
<text class="fs_14">
在招职位·
<text class="color_256BFA">{{ company.totalRecruitment || '-' }}</text>
</text>
</view>
</view>
<view class="card-tags">
<view class="tag" v-if="company.nature">
{{company.nature}}
</view>
</view>
</view>
<view v-else class="cards" @click="nextDetail(company)">
<view class="card-company">
<text class="company line_1">{{ company.name }}</text>
</view>
<view class="card-bottom">
<view class="fl_box fs_14">
<view class="mar_ri10">{{company.industry}}</view>
<view>{{company.scale }}</view>
</view>
<view class="ris">
<text class="fs_14">
在招职位·
<text class="color_256BFA">{{ company.totalRecruitment || '-' }}</text>
</text>
</view>
</view>
<view class="card-tags">
<view class="tag" v-if="company.nature">
{{company.nature}}
</view>
</view>
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
return props.list;
});
function nextDetail(company) {
if(company.dataType == 2){
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.name}&zphId=${company.zphID}&dataType=2`);
}else{
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.companyId}`);
}
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.salary{
font-weight: 500;
font-size: 28rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 4rpx
margin-bottom: 10rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
.ris{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
}
</style>

View File

@@ -2,18 +2,17 @@
<view v-for="job in listData" :key="job.id"> <view v-for="job in listData" :key="job.id">
<view class="cards" @click="nextDetail(job)"> <view class="cards" @click="nextDetail(job)">
<view class="card-company"> <view class="card-company">
<text class="company line_1">{{ job.gsmc }}</text> <text class="company line_1">{{ job.name }}</text>
</view> </view>
<view class="card-bottom" > <view class="card-bottom">
<view class="fl_box fs_14" > <view class="fl_box fs_14">
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label> <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
<dict-Label dictType="scale" :value="job.scale"></dict-Label> --> <dict-Label dictType="scale" :value="job.scale"></dict-Label>
<view>{{job.gsxy}}</view>
</view> </view>
<view class="ris" > <view class="ris">
<text class="fs_14"> <text class="fs_14">
在招职位· 在招职位·
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text> <text class="color_256BFA">{{ job.totalRecruitment || '-' }}</text>
</text> </text>
</view> </view>
@@ -21,14 +20,10 @@
<view class="card-tags"> <view class="card-tags">
<view class="tag" v-if="job.nature"> <view class="tag" v-if="job.nature">
<dict-Label dictType="nature" :value="job.nature"></dict-Label> <dict-Label dictType="nature" :value="job.nature"></dict-Label>
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
</view> </view>
<view class="tag"> <view class="tag">
{{ vacanciesTo(job.vacancies) }} {{ vacanciesTo(job.vacancies) }}
</view> </view>
<view class="tag" v-if="job.qyxz">
{{job.qyxz}}
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -56,10 +51,6 @@ const props = defineProps({
type: String, type: String,
default: '', default: '',
}, },
zphId: {
type: String,
default: '',
},
}); });
const listData = computed(() => { const listData = computed(() => {
@@ -67,7 +58,7 @@ const listData = computed(() => {
}); });
function nextDetail(company) { function nextDetail(company) {
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}`); navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.companyId}`);
} }
</script> </script>
@@ -128,7 +119,7 @@ function nextDetail(company) {
} }
} }
.card-bottom{ .card-bottom{
margin-top: 15rpx margin-top: 4rpx
margin-bottom: 10rpx margin-bottom: 10rpx
display: flex display: flex
justify-content: space-between justify-content: space-between

View File

@@ -0,0 +1,142 @@
<template>
<view v-for="job in listData" :key="job.id">
<view class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company line_1">{{ job.gsmc }}</text>
</view>
<view class="card-bottom" >
<view class="fl_box fs_14" >
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
<dict-Label dictType="scale" :value="job.scale"></dict-Label> -->
<view>{{job.gsxy}}</view>
</view>
<view class="ris" >
<text class="fs_14">
在招职位·
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text>
</text>
</view>
</view>
<view class="card-tags">
<view class="tag" v-if="job.nature">
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
<view class="tag" v-if="job.qyxz">
{{job.qyxz}}
</view>
</view>
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
zphId: {
type: String,
default: '',
},
});
const listData = computed(() => {
return props.list;
});
function nextDetail(company) {
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}&dataType=2`);
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.salary{
font-weight: 500;
font-size: 28rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 15rpx
margin-bottom: 10rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
.ris{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
}
</style>

View File

@@ -0,0 +1,201 @@
<template>
<view v-for="job in listData" :key="job.id">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<!-- 数据类型2的完整模块 -->
<view v-if="job.dataType == 2">
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
{{job.education == '不限' ? '学历不限' : job.education}}
</view>
<view class="tag">
{{job.experience == '不限' ? '经验不限' : job.experience}}
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
</view>
</view>
</view>
<!-- 数据类型1的完整模块 -->
<view v-else>
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
<dict-Label dictType="education" :value="job.education"></dict-Label>
</view>
<view class="tag">
<dict-Label dictType="experience" :value="job.experience"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ job.postingDate }}</view>
<view>
<convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view>
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
// 解析日期时间用于数据类型2
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
}
function nextDetail(job) {
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}`);
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 30rpx;
color: #333333;
}
.salary{
font-family: DIN-Medium;
font-weight: 500;
font-size: 26rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 32rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
</style>

View File

@@ -0,0 +1,202 @@
<template>
<view v-for="job in listData" :key="job.id">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<!-- 数据类型2的完整模块 -->
<view v-if="job.dataType == 2">
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
{{job.education == '不限' ? '学历不限' : job.education}}
</view>
<view class="tag">
{{job.experience == '不限' ? '经验不限' : job.experience}}
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
</view>
</view>
</view>
<!-- 数据类型1的完整模块 -->
<view v-else>
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
{{job.education == '不限' ? '学历不限' : job.education}}
</view>
<view class="tag">
{{job.experience == '不限' ? '经验不限' : job.experience}}
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ job.postingDate }}</view>
<view>
<convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view>
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
// 解析日期时间用于数据类型2
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
}
function nextDetail(job) {
// 根据数据类型跳转到不同的详情页
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=${job.dataType}`);
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 30rpx;
color: #333333;
}
.salary{
font-family: DIN-Medium;
font-weight: 500;
font-size: 26rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 32rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
</style>

View File

@@ -0,0 +1,201 @@
<template>
<view v-for="job in listData" :key="job.id">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<!-- 数据类型2的完整模块 -->
<view v-if="job.dataType == 2">
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
{{job.education == '不限' ? '学历不限' : job.education}}
</view>
<view class="tag">
{{job.experience == '不限' ? '经验不限' : job.experience}}
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
</view>
</view>
</view>
<!-- 数据类型1的完整模块 -->
<view v-else>
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.companyName }}</view>
<view class="card-tags">
<view class="tag">
{{job.education == '不限' ? '学历不限' : job.education}}
</view>
<view class="tag">
{{job.experience == '不限' ? '经验不限' : job.experience}}
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ job.postingDate }}</view>
<view>
<convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view>
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
// 解析日期时间用于数据类型2
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
}
function nextDetail(job) {
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=${job.dataType}`);
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 30rpx;
color: #333333;
}
.salary{
font-family: DIN-Medium;
font-weight: 500;
font-size: 26rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 32rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
</style>

View File

@@ -2,33 +2,33 @@
<view v-for="job in listData" :key="job.id"> <view v-for="job in listData" :key="job.id">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)"> <view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company"> <view class="card-company">
<text class="company">{{ job.gwmc }}</text> <text class="company">{{ job.jobTitle }}</text>
<view class="salary"> <view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation> <Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view> </view>
</view> </view>
<view class="card-companyName">{{ job.gsmc }}</view> <view class="card-companyName">{{ job.gwmc }}</view>
<view class="card-tags"> <view class="card-tags">
<view class="tag"> <view class="tag">
{{job.xlyq == '不限' ? '学历不限' : job.xlyq}} <dict-Label dictType="education" :value="job.education"></dict-Label>
</view> </view>
<view class="tag"> <view class="tag">
{{job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy}} <dict-Label dictType="experience" :value="job.experience"></dict-Label>
</view> </view>
<view class="tag"> <view class="tag">
{{ vacanciesTo(job.zprs) }} {{ vacanciesTo(job.vacancies) }}
</view> </view>
</view> </view>
<view class="card-bottom"> <view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view> <view>{{ job.postingDate }}</view>
<view> <view>
<!-- <convert-distance <convert-distance
:alat="job.latitude" :alat="job.latitude"
:along="job.longitude" :along="job.longitude"
:blat="latitude" :blat="latitude"
:blong="longitude" :blong="longitude"
></convert-distance> ></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> --> <dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view> </view>
</view> </view>
</view> </view>
@@ -77,25 +77,7 @@ function nextDetail(job) {
const recordData = recommedIndexDb.JobParameter(job); const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData); recommedIndexDb.addRecord(recordData);
} }
navTo(`/packageA/pages/post/post?jobId=${btoa(job.id)}`); navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=1`);
}
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
} }
</script> </script>

View File

@@ -0,0 +1,167 @@
<template>
<view v-for="job in listData" :key="job.id">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company">{{ job.gwmc }}</text>
<view class="salary">
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.gsmc }}</view>
<view class="card-tags">
<view class="tag">
{{job.xlyq == '不限' ? '学历不限' : job.xlyq}}
</view>
<view class="tag">
{{job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy}}
</view>
<view class="tag">
{{ vacanciesTo(job.zprs) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
</template>
<script setup>
import { inject, computed, toRaw } from 'vue';
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
const recommedIndexDb = useRecommedIndexedDBStore();
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
function nextDetail(job) {
// 记录岗位类型,用作数据分析
if (job.jobCategory) {
const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData);
}
navTo(`/packageA/pages/post/post?jobId=${btoa(job.id)}&dataType=2`);
}
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
}
</script>
<style lang="stylus" scoped>
.date-jobTitle{
font-weight: 400;
font-size: 28rpx;
color: #495265;
padding: 28rpx 0 0 20rpx
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
font-weight: 500;
font-size: 30rpx;
color: #333333;
}
.salary{
font-family: DIN-Medium;
font-weight: 500;
font-size: 26rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 32rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
</style>

12
main.js
View File

@@ -12,6 +12,12 @@ import SelectPopup from '@/components/selectPopup/selectPopup.vue'
import SelectPopupPlugin from '@/components/selectPopup/selectPopupPlugin'; import SelectPopupPlugin from '@/components/selectPopup/selectPopupPlugin';
import RenderJobs from '@/components/renderJobs/renderJobs.vue'; import RenderJobs from '@/components/renderJobs/renderJobs.vue';
import RenderCompanys from '@/components/renderCompanys/renderCompanys.vue'; import RenderCompanys from '@/components/renderCompanys/renderCompanys.vue';
import RenderJobsOutData from '@/components/renderJobsOutData/renderJobsOutData.vue';
import RenderCompanysOutData from '@/components/renderCompanysOutData/renderCompanysOutData.vue';
import renderDeliveryRecord from '@/components/renderDeliveryRecord/renderDeliveryRecord.vue';
import renderJobCollectionRecord from '@/components/renderJobCollectionRecord/renderJobCollectionRecord.vue';
import renderCompanyCollectionRecord from '@/components/renderCompanyCollectionRecord/renderCompanyCollectionRecord.vue';
import renderJobViewRecord from '@/components/renderJobViewRecord/renderJobViewRecord.vue';
// import Tabbar from '@/components/tabbar/midell-box.vue' // import Tabbar from '@/components/tabbar/midell-box.vue'
// 自动导入 directives 目录下所有指令 // 自动导入 directives 目录下所有指令
const directives = import.meta.glob('./directives/*.js', { const directives = import.meta.glob('./directives/*.js', {
@@ -36,6 +42,12 @@ export function createApp() {
app.component('SelectPopup', SelectPopup) app.component('SelectPopup', SelectPopup)
app.component('RenderJobs', RenderJobs) app.component('RenderJobs', RenderJobs)
app.component('RenderCompanys', RenderCompanys) app.component('RenderCompanys', RenderCompanys)
app.component('RenderJobsOutData', RenderJobsOutData) //渲染外部岗位数据列表
app.component('RenderCompanysOutData', RenderCompanysOutData) //渲染外部公司数据列表
app.component('renderDeliveryRecord', renderDeliveryRecord) //渲染岗位投递记录
app.component('renderJobCollectionRecord', renderJobCollectionRecord) //渲染岗位收藏记录
app.component('renderCompanyCollectionRecord', renderCompanyCollectionRecord) //渲染公司收藏记录
app.component('renderJobViewRecord', renderJobViewRecord) //渲染岗位浏览记录
// app.component('tabbar-custom', Tabbar) // app.component('tabbar-custom', Tabbar)
for (const path in directives) { for (const path in directives) {

View File

@@ -1,12 +1,12 @@
<template> <template>
<view class="collection-content"> <view class="collection-content">
<renderJobs <renderDeliveryRecord
seeDate="applyTime"
v-if="pageState.list.length" v-if="pageState.list.length"
seeDate="applyTime"
:list="pageState.list" :list="pageState.list"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal">
></renderJobs> </renderDeliveryRecord>
<empty v-else pdTop="200"></empty> <empty v-else pdTop="200"></empty>
</view> </view>
</template> </template>
@@ -41,9 +41,7 @@ onReachBottom(() => {
getJobList(); getJobList();
}); });
function navToPost(jobId) {
navTo(`/packageA/pages/post/post?jobId=${btoa(jobId)}`);
}
function getJobList(type = 'add') { function getJobList(type = 'add') {
if (type === 'refresh') { if (type === 'refresh') {

View File

@@ -21,7 +21,7 @@
<image src="@/static/icon/companyIcon.png" mode=""></image> <image src="@/static/icon/companyIcon.png" mode=""></image>
</view> </view>
<view class="companyinfo-right"> <view class="companyinfo-right">
<view class="row1">{{ companyInfo?.gsmc }}</view> <view class="row1">{{ dataType === 2 ? companyInfo?.gsmc : companyInfo?.name }}</view>
<view class="row2"> <view class="row2">
<dict-tree-Label <dict-tree-Label
v-if="companyInfo?.industry" v-if="companyInfo?.industry"
@@ -30,15 +30,13 @@
></dict-tree-Label> ></dict-tree-Label>
<span v-if="companyInfo?.industry">&nbsp;</span> <span v-if="companyInfo?.industry">&nbsp;</span>
<dict-Label dictType="scale" :value="companyInfo?.scale"></dict-Label> <dict-Label dictType="scale" :value="companyInfo?.scale"></dict-Label>
<span>{{companyInfo.gsxy}}</span> <span v-if="dataType === 2">{{ companyInfo.gsxy }}</span>
</view> </view>
</view> </view>
</view> </view>
<view class="conetent-info" :class="{ expanded: isExpanded }"> <view class="conetent-info" :class="{ expanded: isExpanded }">
<view class="info-title">公司介绍</view> <view class="info-title">公司介绍</view>
<view class="info-desirption">{{ companyInfo.qyxz }}</view> <view class="info-desirption">{{ dataType === 2 ? companyInfo.qyxz : companyInfo.description }}</view>
<!-- <view class="info-title title2">公司地址</view>
<view class="locationCompany"></view> -->
</view> </view>
<view class="expand" @click="expand"> <view class="expand" @click="expand">
<text>{{ isExpanded ? '收起' : '展开' }}</text> <text>{{ isExpanded ? '收起' : '展开' }}</text>
@@ -48,12 +46,18 @@
src="@/static/icon/downs.png" src="@/static/icon/downs.png"
></image> ></image>
</view> </view>
<!-- <scroll-view scroll-y class="Detailscroll-view" @scrolltolower="getJobsList('add')"> --> <scroll-view scroll-y class="Detailscroll-view" @scrolltolower="getJobsList('add')">
<scroll-view scroll-y class="Detailscroll-view">
<view class="views"> <view class="views">
<view class="Detail-title"><text class="title">在招职位</text></view> <view class="Detail-title"><text class="title">在招职位</text></view>
<!-- 根据 dataType 使用不同的职位列表组件 -->
<renderJobsOutData
v-if="dataType === 2 && pageState.list.length"
:list="pageState.list"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderJobsOutData>
<renderJobs <renderJobs
v-if="pageState.list.length" v-else-if="dataType !== 2 && pageState.list.length"
:list="pageState.list" :list="pageState.list"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal"
@@ -77,6 +81,7 @@ const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
const isExpanded = ref(false); const isExpanded = ref(false);
const pageState = reactive({ const pageState = reactive({
current: 0,
page: 0, page: 0,
list: [], list: [],
total: 0, total: 0,
@@ -84,35 +89,108 @@ const pageState = reactive({
pageSize: 10, pageSize: 10,
}); });
const companyInfo = ref({}); const companyInfo = ref({});
const pageOptions = ref({});
const dataType = ref(1); // 1: 原数据, 2: 第三方数据
onLoad((options) => { onLoad((options) => {
console.log(options); console.log(options);
getCompanyInfo(options.companyId,options.companyName,options.zphId); dataType.value = options.dataType ? parseInt(options.dataType) : 1;
pageOptions.value = options;
if (dataType.value === 2) {
// 第三方数据
getCompanyInfo(options.companyId, options.zphId);
getJobsList('refresh');
} else {
// 原数据
getCompanyInfo(options.companyId || options.bussinessId);
}
}); });
function companyCollection() { function companyCollection() {
const companyId = companyInfo.value.gsID; if (dataType.value === 2) {
if (companyInfo.value.isCollection) { // 第三方数据收藏逻辑
$api.createRequest(`/app/company/collection/${companyId}`, {}, 'DELETE').then((resData) => { const id = companyInfo.value.id;
// getCompanyInfo(companyId); const companyId = companyInfo.value.gsID;
$api.msg('取消收藏成功'); const zphId = companyInfo.value.zphID;
if (companyInfo.value.isCollection) {
$api.createRequest(`/app/company/collection/${id}/2`, {}, 'DELETE').then((resData) => {
getCompanyInfo(companyId, zphId);
$api.msg('取消收藏成功');
});
} else {
$api.createRequest(`/app/company/collection/${id}/2`, {}, 'POST').then((resData) => {
getCompanyInfo(companyId, zphId);
$api.msg('收藏成功');
});
}
} else {
// 原数据收藏逻辑
const companyId = companyInfo.value.companyId;
if (companyInfo.value.isCollection) {
$api.createRequest(`/app/company/collection/${companyId}`, {}, 'DELETE').then((resData) => {
getCompanyInfo(companyId);
$api.msg('取消收藏成功');
});
} else {
$api.createRequest(`/app/company/collection/${companyId}`, {}, 'POST').then((resData) => {
getCompanyInfo(companyId);
$api.msg('收藏成功');
});
}
}
}
function getCompanyInfo(...args) {
if (dataType.value === 2) {
// 第三方数据接口
const [companyId, zphId] = args;
$api.createRequest(`/app/internal/companyThirdPart/${companyId}/${zphId}`).then((resData) => {
companyInfo.value = resData.data;
}); });
} else { } else {
$api.createRequest(`/app/company/collection/${companyId}`, {}, 'POST').then((resData) => { // 原数据接口
// getCompanyInfo(companyId); const [companyId] = args;
$api.msg('收藏成功'); $api.createRequest(`/app/company/${companyId}`).then((resData) => {
companyInfo.value = resData.data;
getJobsList();
}); });
} }
} }
function getCompanyInfo(companyId,companyName,zphId) { function getJobsList(type = 'add') {
$api.createRequest(`/app/internal/companyThirdPart/${companyId}/${zphId}`).then((resData) => { if (dataType.value === 2) {
companyInfo.value = resData.data; // 第三方数据职位列表
getJobsList(companyId,companyName,zphId); getThirdPartyJobsList(type);
} else {
// 原数据职位列表
getOriginalJobsList(type);
}
}
function getThirdPartyJobsList(type = 'add') {
const { companyId, companyName, zphId } = pageOptions.value;
if (type === 'refresh') {
pageState.current = 1;
pageState.maxPage = 1;
}
if (type === 'add' && pageState.current < pageState.maxPage) {
pageState.current += 1;
}
let params = {
current: pageState.current,
pageSize: pageState.pageSize,
};
$api.createRequest(`/app/internal/jobThirdPart?gsID=${companyId}&gsmc=${companyName}&zphID=${zphId}`, params).then((resData) => {
const { rows, total } = resData;
handleJobsListResponse(type, rows, total, 'current');
}); });
} }
function getJobsList(companyId,companyName,zphId,type='add') { function getOriginalJobsList(type = 'add') {
if (type === 'refresh') { if (type === 'refresh') {
pageState.page = 1; pageState.page = 1;
pageState.maxPage = 1; pageState.maxPage = 1;
@@ -120,26 +198,31 @@ function getJobsList(companyId,companyName,zphId,type='add') {
if (type === 'add' && pageState.page < pageState.maxPage) { if (type === 'add' && pageState.page < pageState.maxPage) {
pageState.page += 1; pageState.page += 1;
} }
let params = { let params = {
current: pageState.page, current: pageState.page,
pageSize: pageState.pageSize, pageSize: pageState.pageSize,
}; };
$api.createRequest(`/app/internal/jobThirdPart?gsID=${companyId}&gsmc=${companyName}&zphID=${zphId}`, ).then((resData) => {
$api.createRequest(`/app/company/job/${companyInfo.value.companyId}`, params).then((resData) => {
const { rows, total } = resData; const { rows, total } = resData;
if (type === 'add') { handleJobsListResponse(type, rows, total, 'page');
// const str = pageState.pageSize * (pageState.page - 1);
// const end = pageState.list.length;
// const reslist = rows;
// pageState.list.splice(str, end, ...reslist);
pageState.list = rows
} else {
pageState.list = rows;
}
pageState.total = resData.total;
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
}); });
} }
function handleJobsListResponse(type, rows, total, pageKey) {
if (type === 'add') {
const str = pageState.pageSize * (pageState[pageKey] - 1);
const end = pageState.list.length;
const reslist = rows;
pageState.list.splice(str, end, ...reslist);
} else {
pageState.list = rows;
}
pageState.total = total;
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
}
function expand() { function expand() {
isExpanded.value = !isExpanded.value; isExpanded.value = !isExpanded.value;
} }
@@ -177,7 +260,6 @@ image {
margin-right: 24rpx margin-right: 24rpx
} }
.companyinfo-right{ .companyinfo-right{
.row1{ .row1{
font-weight: 500; font-weight: 500;
font-size: 32rpx; font-size: 32rpx;
@@ -213,7 +295,7 @@ image {
} }
} }
.expanded { .expanded {
max-height: 1000rpx; // 足够显示完整内容 max-height: 1000rpx;
} }
.expand{ .expand{
display: flex display: flex
@@ -288,7 +370,7 @@ image {
} }
.card-companyName{ .card-companyName{
font-weight: 400; font-weight: 400;
font-size: 28rpx; font-size: 28rpx;
color: #6C7282; color: #6C7282;
} }
.card-tags{ .card-tags{

View File

@@ -25,12 +25,12 @@
<scroll-view scroll-y class="main-scroll" @scrolltolower="getJobList('add')"> <scroll-view scroll-y class="main-scroll" @scrolltolower="getJobList('add')">
<view class="one-cards"> <view class="one-cards">
<view class="mian"> <view class="mian">
<renderJobs <renderJobViewRecord
:list="pageState.list" :list="pageState.list"
v-if="pageState.list.length" v-if="pageState.list.length"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal"
></renderJobs> ></renderJobViewRecord>
<empty v-else pdTop="200"></empty> <empty v-else pdTop="200"></empty>
<!-- <loadmore ref="loadmoreRef"></loadmore> --> <!-- <loadmore ref="loadmoreRef"></loadmore> -->
</view> </view>
@@ -88,9 +88,7 @@ function toSelectDate() {
}); });
} }
function navToPost(jobId) {
navTo(`/packageA/pages/post/post?jobId=${btoa(jobId)}`);
}
function searchCollection(e) { function searchCollection(e) {
const value = e.detail.value; const value = e.detail.value;

View File

@@ -15,12 +15,12 @@
<swiper-item class="list"> <swiper-item class="list">
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower"> <scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
<view class="mian"> <view class="mian">
<renderJobs <renderJobCollectionRecord
:list="pageState.list"
v-if="pageState.list.length" v-if="pageState.list.length"
:list="pageState.list"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal">
></renderJobs> </renderJobCollectionRecord>
<empty v-else pdTop="200"></empty> <empty v-else pdTop="200"></empty>
</view> </view>
</scroll-view> </scroll-view>
@@ -28,12 +28,12 @@
<swiper-item class="list"> <swiper-item class="list">
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLowerCompany"> <scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLowerCompany">
<view class="mian"> <view class="mian">
<renderCompanys <renderCompanyCollectionRecord
:list="pageCompanyState.list" :list="pageCompanyState.list"
v-if="pageCompanyState.list.length" v-if="pageCompanyState.list.length"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal"
></renderCompanys> ></renderCompanyCollectionRecord>
<empty v-else pdTop="200"></empty> <empty v-else pdTop="200"></empty>
</view> </view>
</scroll-view> </scroll-view>

View File

@@ -69,18 +69,18 @@
src="@/static/icon/downs.png" src="@/static/icon/downs.png"
></image> ></image>
</view> </view>
<scroll-view scroll-y class="Detailscroll-view"> <scroll-view scroll-y class="Detailscroll-view" @scrolltolower="getCompanyList('add')">
<view class="views"> <view class="views">
<view class="Detail-title"> <view class="Detail-title">
<text class="title">参会单位{{ companyList.length }}</text> <text class="title">参会单位{{ pageState.total }}</text>
</view> </view>
<renderCompanys <renderCompanysOutData
v-if="companyList.length" v-if="pageState.list.length"
:zphId="zphId" :zphId="zphId"
:list="companyList" :list="pageState.list"
:longitude="longitudeVal" :longitude="longitudeVal"
:latitude="latitudeVal" :latitude="latitudeVal"
></renderCompanys> ></renderCompanysOutData>
<empty v-else pdTop="200"></empty> <empty v-else pdTop="200"></empty>
</view> </view>
</scroll-view> </scroll-view>
@@ -111,13 +111,24 @@ const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
const isExpanded = ref(false); const isExpanded = ref(false);
const fairInfo = ref({}); const fairInfo = ref({});
const companyList = ref([]);
const pageState = reactive({
current: 0,
list: [],
total: 0,
maxPage: 1,
pageSize: 10,
});
const hasnext = ref(true); const hasnext = ref(true);
const zphId = ref(''); const zphId = ref('');
const pageOptions = ref({})
onLoad((options) => { onLoad((options) => {
zphId.value = options.jobFairId zphId.value = options.jobFairId
pageOptions.value = options
getJobFairInfo(options.jobFairId, options.jobFairName); getJobFairInfo(options.jobFairId, options.jobFairName);
getCompanyInfo(options.jobFairId, options.jobFairName); getCompanyList('refresh');
}); });
function getJobFairInfo(id,name) { function getJobFairInfo(id,name) {
@@ -126,20 +137,43 @@ function getJobFairInfo(id,name) {
hasAppointment(); hasAppointment();
}); });
} }
function getCompanyInfo(id,name) { function getCompanyList(type='add') {
$api.createRequest(`/app/internal/companyThirdPart/?zphID=${id}&zphmc=${name}`).then((resData) => { const { jobFairId,jobFairName} = pageOptions.value
companyList.value = resData.rows; if (type === 'refresh') {
pageState.current = 1;
pageState.maxPage = 1;
}
if (type === 'add' && pageState.current < pageState.maxPage) {
pageState.current += 1;
}
let params = {
current: pageState.current,
pageSize: pageState.pageSize,
};
$api.createRequest(`/app/internal/companyThirdPart/?zphID=${jobFairId}&zphmc=${jobFairName}`,params ).then((resData) => {
const { rows, total } = resData;
if (type === 'add') {
const str = pageState.pageSize * (pageState.current - 1);
const end = pageState.list.length;
const reslist = rows;
pageState.list.splice(str, end, ...reslist);
} else {
pageState.list = rows;
}
pageState.total = resData.total;
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
}); });
} }
const hasAppointment = () => { const hasAppointment = () => {
const isTimePassed = (timeStr) => { const isTimePassed = (timeStr) => {
if(!timeStr) return false
const targetTime = new Date(timeStr.replace(/-/g, '/')).getTime(); // 兼容格式 const targetTime = new Date(timeStr.replace(/-/g, '/')).getTime(); // 兼容格式
const now = Date.now(); const now = Date.now();
return now < targetTime; return now < targetTime;
}; };
hasnext.value = isTimePassed(fairInfo.value.startTime); hasnext.value = isTimePassed(fairInfo.value.zphjbsj);
}; };
function openMap(lat, lng, name = '位置') { function openMap(lat, lng, name = '位置') {
@@ -157,16 +191,16 @@ function expand() {
// 取消/收藏岗位 // 取消/收藏岗位
function applyExhibitors() { function applyExhibitors() {
const fairId = fairInfo.value.jobFairId; const fairId = fairInfo.value.zphID;
if (fairInfo.value.isCollection) { if (fairInfo.value.isCollection) {
// $api.createRequest(`/app/fair/collection/${fairId}`, {}, 'DELETE').then((resData) => { $api.createRequest(`/app/fair/collection/${fairId}`, {}, 'DELETE').then((resData) => {
// getCompanyInfo(fairId); getJobFairInfo(fairId);
// $api.msg('取消预约成功'); $api.msg('取消预约成功');
// }); });
$api.msg('已预约成功'); $api.msg('已预约成功');
} else { } else {
$api.createRequest(`/app/fair/collection/${fairId}`, {}, 'POST').then((resData) => { $api.createRequest(`/app/fair/collection/${fairId}`, {}, 'POST').then((resData) => {
getCompanyInfo(fairId); getJobFairInfo(fairId);
$api.msg('预约成功'); $api.msg('预约成功');
}); });
} }

View File

@@ -5,6 +5,13 @@
<image src="@/static/icon/back-white.png" @click="navBack"></image> <image src="@/static/icon/back-white.png" @click="navBack"></image>
</view> </view>
</template> </template>
<view v-if="userInfo.resumeOcrStatus && showNotice" class="notice-line" :class="userInfo.resumeOcrStatus?.includes('成功')?'green':'blue'">
<image v-if="userInfo.resumeOcrStatus?.includes('成功')" class="icon" src="@/static/icon/notice-green.png" />
<image v-else class="icon" src="@/static/icon/notice-blue.png" />
<view class="text">{{userInfo.resumeOcrStatus}}</view>
<image @click="closeNotice" v-if="userInfo.resumeOcrStatus?.includes('成功')" class="close" src="@/static/icon/close-green.png" />
<image @click="closeNotice" v-else class="close" src="@/static/icon/close-blue.png" />
</view>
<view class="mys-container"> <view class="mys-container">
<!-- 个人信息 --> <!-- 个人信息 -->
<view <view
@@ -164,10 +171,15 @@ const { getUserResume } = useUserStore();
const { getDictData, oneDictData } = useDictStore(); const { getDictData, oneDictData } = useDictStore();
import config from "@/config.js"; import config from "@/config.js";
const showNotice = ref(true)
onLoad(() => { onLoad(() => {
getUserResume(); getUserResume();
}); });
function closeNotice() {
showNotice.value=false
}
function chooseResume() { function chooseResume() {
uni.chooseImage({ uni.chooseImage({
sizeType: ["original", "compressed"], sizeType: ["original", "compressed"],
@@ -254,6 +266,36 @@ function uploadResume(tempFilePath, loading) {
text-align: center; text-align: center;
} }
} }
.notice-line
width 100%;
height:60rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding:0 30rpx
margin-bottom: 20rpx
.icon
width:35rpx;
height:35rpx;
.text
flex: 1;
overflow hidden
padding:0 25rpx
.close
width:25rpx;
height:25rpx;
.notice-line.blue{
background: #E8F1FF
color: #1677ff
}
.notice-line.green{
background: #D4FFF1
color: #38bb8f
}
image{ image{
width: 100%; width: 100%;
height: 100% height: 100%

View File

@@ -6,45 +6,59 @@
</view> </view>
</template> </template>
<template #headerright> <template #headerright>
<!-- <view class="btnshare">
<image src="@/static/icon/share.png" @click="shareJob"></image>
</view> -->
<view class="btn mar_ri10"> <view class="btn mar_ri10">
<image src="@/static/icon/collect3.png" v-if="!jobInfo.isCollection" @click="jobCollection"></image> <image src="@/static/icon/collect3.png" v-if="!jobInfo.isCollection" @click="jobCollection"></image>
<image src="@/static/icon/collect2.png" v-else @click="jobCollection"></image> <image src="@/static/icon/collect2.png" v-else @click="jobCollection"></image>
</view> </view>
</template> </template>
<!-- 根据 dataType 显示不同内容 -->
<view class="content" v-show="!isEmptyObject(jobInfo)"> <view class="content" v-show="!isEmptyObject(jobInfo)">
<!-- 顶部信息区域 -->
<view class="content-top btn-feel"> <view class="content-top btn-feel">
<view class="top-salary"> <view class="top-salary" v-if="jobInfo.maxSalary">
<Salary-Expectation <Salary-Expectation
:max-salary="jobInfo.maxSalary" :max-salary="jobInfo.maxSalary"
:min-salary="jobInfo.minSalary" :min-salary="jobInfo.minSalary"
:is-month="true" :is-month="true"
></Salary-Expectation> ></Salary-Expectation>
</view> </view>
<view class="top-name">{{ jobInfo.gwmc }}</view> <view class="top-salary" v-else>
<Salary-Expectation
:max-salary="jobInfo.maxSalary"
:min-salary="jobInfo.minSalary"
:is-month="true"
></Salary-Expectation>
</view>
<view class="top-name">{{ dataType === 2 ? jobInfo.gwmc : jobInfo.jobTitle }}</view>
<view class="top-info"> <view class="top-info">
<view class="info-img"><image src="/static/icon/post12.png"></image></view> <view class="info-img"><image src="/static/icon/post12.png"></image></view>
<!-- <view class="info-text"> <!-- 第三方数据展示 -->
<dict-Label dictType="experience" :value="jobInfo.experience"></dict-Label> <view class="info-text" v-if="dataType === 2">
</view> -->
<view class="info-text">
{{jobInfo.xlyq == '不限' ? '学历不限' : jobInfo.xlyq}} {{jobInfo.xlyq == '不限' ? '学历不限' : jobInfo.xlyq}}
</view> </view>
<!-- 原数据展示 -->
<view class="info-text" v-else>
<dict-Label dictType="experience" :value="jobInfo.experience"></dict-Label>
</view>
<view class="info-img mar_le20"><image src="/static/icon/post13.png"></image></view> <view class="info-img mar_le20"><image src="/static/icon/post13.png"></image></view>
<!-- <view class="info-text"> <!-- 第三方数据展示 -->
<dict-Label dictType="education" :value="jobInfo.education"></dict-Label> <view class="info-text" v-if="dataType === 2">
</view> -->
<view class="info-text">
{{jobInfo.gwgzjy == '不限' ? '经验不限' : jobInfo.gwgzjy}} {{jobInfo.gwgzjy == '不限' ? '经验不限' : jobInfo.gwgzjy}}
</view> </view>
<!-- 原数据展示 -->
<view class="info-text" v-else>
<dict-Label dictType="education" :value="jobInfo.education"></dict-Label>
</view>
</view> </view>
<view class="position-source"> <view class="position-source">
<text>来源&nbsp;</text> <text>来源&nbsp;</text>
青岛人才网 {{ dataType === 2 ? '青岛人才网' : jobInfo.dataSource }}
</view> </view>
</view> </view>
<!-- AI讲解区域 -->
<view class="ai-explain" v-if="jobInfo.isExplain"> <view class="ai-explain" v-if="jobInfo.isExplain">
<view class="exbg"> <view class="exbg">
<view class="explain-left btn-shaky"> <view class="explain-left btn-shaky">
@@ -54,20 +68,24 @@
<view class="explain-right button-click" @click="seeExplain">点击查看</view> <view class="explain-right button-click" @click="seeExplain">点击查看</view>
</view> </view>
</view> </view>
<!-- 职位描述区域 -->
<view class="content-card"> <view class="content-card">
<view class="card-title"> <view class="card-title">
<text class="title">职位描述</text> <text class="title">职位描述</text>
</view> </view>
<view class="description" :style="{ whiteSpace: 'pre-wrap' }"> <view class="description" :style="{ whiteSpace: 'pre-wrap' }">
{{ jobInfo.gwms }} {{ dataType === 2 ? jobInfo.gwms : jobInfo.description }}
</view> </view>
</view> </view>
<!-- 公司信息区域 -->
<view class="content-card"> <view class="content-card">
<view class="card-title"> <view class="card-title">
<text class="title">公司信息</text> <text class="title">公司信息</text>
<text <text
class="btntext button-click" class="btntext button-click"
@click=" navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${jobInfo.gsID}&companyName=${jobInfo.gsmc}&zphId=${jobInfo.zphID}`);" @click="handleCompanyDetail"
> >
单位详情 单位详情
</text> </text>
@@ -77,16 +95,20 @@
<image src="@/static/icon/companyIcon.png" mode=""></image> <image src="@/static/icon/companyIcon.png" mode=""></image>
</view> </view>
<view class="companyinfo-right"> <view class="companyinfo-right">
<view class="row1">{{ jobInfo.gsmc }}</view> <view class="row1">{{ dataType === 2 ? jobInfo.gsmc : jobInfo.company?.name }}</view>
<view class="row2"> <view class="row2">
<dict-tree-Label <dict-tree-Label
v-if="jobInfo.company?.industry" v-if="dataType !== 2 && jobInfo.company?.industry"
dictType="industry" dictType="industry"
:value="jobInfo.company?.industry" :value="jobInfo.company?.industry"
></dict-tree-Label> ></dict-tree-Label>
<span v-if="jobInfo.company?.industry">&nbsp;</span> <span v-if="dataType !== 2 && jobInfo.company?.industry">&nbsp;</span>
<dict-Label dictType="scale" :value="jobInfo.company?.scale"></dict-Label> <dict-Label
<span>{{jobInfo.qyxz}}</span> v-if="dataType !== 2"
dictType="scale"
:value="jobInfo.company?.scale"
></dict-Label>
<span v-if="dataType === 2">{{jobInfo.qyxz}}</span>
</view> </view>
<view class="row2"> <view class="row2">
<text>在招</text> <text>在招</text>
@@ -104,7 +126,9 @@
></map> ></map>
</view> </view>
</view> </view>
<view class="content-card">
<!-- 竞争力分析区域 -->
<view class="content-card" v-if="dataType !== 2">
<view class="card-title"> <view class="card-title">
<text class="title">竞争力分析</text> <text class="title">竞争力分析</text>
</view> </view>
@@ -132,11 +156,15 @@
</view> </view>
</view> </view>
</view> </view>
<view style="height: 24px"></view> <view style="height: 24px"></view>
</view> </view>
<template #footer> <template #footer>
<view class="footer"> <view class="footer">
<view class="btn-wq button-click" @click="jobApply">立即前往</view> <view class="btn-wq button-click" @click="jobApply">
{{ dataType === 2 ? '立即投递' : '立即前往' }}
</view>
</view> </view>
</template> </template>
<VideoPlayer ref="videoPalyerRef" /> <VideoPlayer ref="videoPalyerRef" />
@@ -150,8 +178,10 @@ import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
import { onLoad, onShow, onHide } from '@dcloudio/uni-app'; import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
import dictLabel from '@/components/dict-Label/dict-Label.vue'; import dictLabel from '@/components/dict-Label/dict-Label.vue';
import RadarMap from './component/radarMap.vue'; import RadarMap from './component/radarMap.vue';
const { $api, navTo, getLenPx, parseQueryParams, navBack, isEmptyObject } = inject('globalFunction'); const { $api, navTo, getLenPx, parseQueryParams, navBack, isEmptyObject } = inject('globalFunction');
import config from '@/config.js'; import config from '@/config.js';
const matchingDegree = ref(['一般', '良好', '优秀', '极好']); const matchingDegree = ref(['一般', '良好', '优秀', '极好']);
const currentStep = ref(1); const currentStep = ref(1);
const companyCount = ref(0); const companyCount = ref(0);
@@ -162,9 +192,11 @@ const jobIdRef = ref();
const raderData = ref({}); const raderData = ref({});
const videoPalyerRef = ref(null); const videoPalyerRef = ref(null);
const explainUrlRef = ref(''); const explainUrlRef = ref('');
const dataType = ref(1); // 1: 原数据, 2: 第三方数据
onLoad((option) => { onLoad((option) => {
if (option.jobId) { if (option.jobId) {
dataType.value = option.dataType ? parseInt(option.dataType) : 1;
initLoad(option); initLoad(option);
} }
}); });
@@ -172,6 +204,7 @@ onLoad((option) => {
onShow(() => { onShow(() => {
const option = parseQueryParams(); // 兼容微信内置浏览器 const option = parseQueryParams(); // 兼容微信内置浏览器
if (option.jobId) { if (option.jobId) {
dataType.value = option.dataType ? parseInt(option.dataType) : 1;
initLoad(option); initLoad(option);
} }
}); });
@@ -187,92 +220,165 @@ function initLoad(option) {
function seeExplain() { function seeExplain() {
if (jobInfo.value.explainUrl) { if (jobInfo.value.explainUrl) {
videoPalyerRef.value?.open(jobInfo.value.explainUrl); videoPalyerRef.value?.open(jobInfo.value.explainUrl);
// console.log(jobInfo.value.explainUrl);
// explainUrlRef.value = jobInfo.value.explainUrl;
} }
} }
function getDetail(jobId) { function getDetail(jobId) {
return new Promise((reslove, reject) => { if (dataType.value === 2) {
$api.createRequest(`/app/internal/jobThirdPart/${jobId}`).then((resData) => { // 第三方数据接口
const { gsID, gsmc, zphID} = resData.data; return new Promise((reslove, reject) => {
$api.createRequest(`/app/internal/jobThirdPart/${jobId}`).then((resData) => {
const { gsID, gsmc, zphID } = resData.data;
jobInfo.value = resData.data;
reslove(resData.data);
getCompanyIsAJobs(gsID, gsmc, zphID);
if (resData.data.latitude && resData.data.longitude) {
initMapCovers(resData.data.latitude, resData.data.longitude, resData.data.gsmc);
}
});
});
} else {
// 原数据接口
$api.createRequest(`/app/job/${jobId}`).then((resData) => {
const { latitude, longitude, companyName, companyId } = resData.data;
jobInfo.value = resData.data; jobInfo.value = resData.data;
reslove(resData.data); getCompanyIsAJobs(companyId);
getCompanyIsAJobs(gsID, gsmc, zphID); getCompetivetuveness(jobId);
// getCompetivetuveness(jobId);
return
if (latitude && longitude) { if (latitude && longitude) {
mapCovers.value = [ initMapCovers(latitude, longitude, companyName);
{
latitude: latitude,
longitude: longitude,
iconPath: point,
label: {
content: companyName,
textAlign: 'center',
padding: 3,
fontSize: 12,
bgColor: '#FFFFFF',
anchorX: getTextWidth(companyName), // X 轴调整,负数向左
borderRadius: 5,
},
width: 34,
},
];
} }
}); });
}); }
} }
function getCompanyIsAJobs(gsID, gsmc, zphID) { function initMapCovers(latitude, longitude, companyName) {
$api.createRequest(`/app/internal/jobThirdPart?gsID=${gsID}&gsmc=${gsmc}&zphID=${zphID}`).then((resData) => { mapCovers.value = [
companyCount.value = resData.total; {
}); latitude: latitude,
longitude: longitude,
iconPath: point,
label: {
content: companyName,
textAlign: 'center',
padding: 3,
fontSize: 12,
bgColor: '#FFFFFF',
anchorX: getTextWidth(companyName),
borderRadius: 5,
},
width: 34,
},
];
}
function getCompanyIsAJobs(...args) {
if (dataType.value === 2) {
// 第三方数据获取公司职位数量
const [gsID, gsmc, zphID] = args;
$api.createRequest(`/app/internal/jobThirdPart?gsID=${gsID}&gsmc=${gsmc}&zphID=${zphID}`).then((resData) => {
companyCount.value = resData.total;
});
} else {
// 原数据获取公司职位数量
const [companyId] = args;
$api.createRequest(`/app/company/count/${companyId}`).then((resData) => {
companyCount.value = resData.data;
});
}
} }
function getTextWidth(text, size = 12) { function getTextWidth(text, size = 12) {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
context.font = `${12}px Arial`; context.font = `${12}px Arial`;
return -(context.measureText(text).width / 2) - 20; // 计算文字中心点 return -(context.measureText(text).width / 2) - 20;
} }
function getCompetivetuveness(jobId) { function getCompetivetuveness(jobId) {
$api.createRequest(`/app/job/competitiveness/${jobId}`, {}, 'GET').then((resData) => { if (dataType.value !== 2) {
raderData.value = resData.data; $api.createRequest(`/app/job/competitiveness/${jobId}`, {}, 'GET').then((resData) => {
currentStep.value = resData.data.matchScore * 0.04; raderData.value = resData.data;
}); currentStep.value = resData.data.matchScore * 0.04;
});
}
} }
// 申请岗位 // 申请岗位
function jobApply() { function jobApply() {
const jobId = jobInfo.value.id; if (dataType.value === 2) {
if (jobInfo.value.isApply) { $api.msg('敬请期待');
const jobUrl = jobInfo.value.jobUrl; return
return window.open(jobUrl); // 第三方数据申请逻辑
} else { const jobId = jobInfo.value.id;
$api.createRequest(`/app/job/apply/${jobId}`, {}, 'GET').then((resData) => { if (jobInfo.value.isApply) {
getDetail(jobId);
$api.msg('申请成功');
const jobUrl = jobInfo.value.jobUrl; const jobUrl = jobInfo.value.jobUrl;
return window.open(jobUrl); return window.open(jobUrl);
}); } else {
$api.createRequest(`/app/job/apply/${jobId}`, {}, 'GET').then((resData) => {
getDetail(jobIdRef.value);
$api.msg('投递成功');
const jobUrl = jobInfo.value.jobUrl;
return window.open(jobUrl);
});
}
} else {
// 原数据申请逻辑
const jobId = jobInfo.value.jobId;
if (jobInfo.value.isApply) {
const jobUrl = jobInfo.value.jobUrl;
return window.open(jobUrl);
} else {
$api.createRequest(`/app/job/apply/${jobId}`, {}, 'GET').then((resData) => {
getDetail(jobId);
$api.msg('申请成功');
const jobUrl = jobInfo.value.jobUrl;
return window.open(jobUrl);
});
}
} }
} }
// 取消/收藏岗位 // 取消/收藏岗位
function jobCollection() { function jobCollection() {
const jobId = jobInfo.value.jobId; if (dataType.value === 2) {
if (jobInfo.value.isCollection) { // 第三方数据收藏逻辑
$api.createRequest(`/app/job/collection/${jobId}`, {}, 'DELETE').then((resData) => { const id = jobInfo.value.id;
getDetail(jobId); if (jobInfo.value.isCollection) {
$api.msg('取消收藏成功'); $api.createRequest(`/app/job/collection/${id}/2`, {}, 'DELETE').then((resData) => {
}); getDetail(jobIdRef.value);
$api.msg('取消收藏成功');
});
} else {
$api.createRequest(`/app/job/collection/${id}/2`, {}, 'POST').then((resData) => {
getDetail(jobIdRef.value);
$api.msg('收藏成功');
});
}
} else { } else {
$api.createRequest(`/app/job/collection/${jobId}`, {}, 'POST').then((resData) => { // 原数据收藏逻辑
getDetail(jobId); const jobId = jobInfo.value.jobId;
$api.msg('收藏成功'); if (jobInfo.value.isCollection) {
}); $api.createRequest(`/app/job/collection/${jobId}`, {}, 'DELETE').then((resData) => {
getDetail(jobId);
$api.msg('取消收藏成功');
});
} else {
$api.createRequest(`/app/job/collection/${jobId}`, {}, 'POST').then((resData) => {
getDetail(jobId);
$api.msg('收藏成功');
});
}
}
}
// 处理公司详情跳转
function handleCompanyDetail() {
if (dataType.value === 2) {
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${jobInfo.value.gsID}&companyName=${jobInfo.value.gsmc}&zphId=${jobInfo.value.zphID}&dataType=2`);
} else {
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${jobInfo.value.company.companyId}`);
} }
} }
@@ -293,6 +399,7 @@ function getClass(index) {
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
/* 样式保持不变与现在的post页面相同 */
.btnback{ .btnback{
width: 64rpx; width: 64rpx;
height: 64rpx; height: 64rpx;
@@ -316,15 +423,14 @@ image {
.progress-container { .progress-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8rpx; /* 间距 */ gap: 8rpx;
margin-top: 24rpx margin-top: 24rpx
} }
.progress-text{ .progress-text{
margin-top: 8rpx margin-top: 8rpx
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8rpx; /* 间距 */ gap: 8rpx;
justify-content: space-around justify-content: space-around
width: 100% width: 100%
font-weight: 400; font-weight: 400;
@@ -343,12 +449,10 @@ image {
transition: background-color 0.3s; transition: background-color 0.3s;
} }
/* 完整激活格子 */
.progress-item.active { .progress-item.active {
background: linear-gradient(to right, #256bfa, #8c68ff); background: linear-gradient(to right, #256bfa, #8c68ff);
} }
/* 当前进度进行中的格子 */
for i in 0..100 for i in 0..100
.progress-item.half{i}::before .progress-item.half{i}::before
content '' content ''
@@ -360,36 +464,12 @@ for i in 0..100
background linear-gradient(to right, #256bfa (i)%, #eaeaea (i)%) background linear-gradient(to right, #256bfa (i)%, #eaeaea (i)%)
border-radius 24rpx border-radius 24rpx
.card-footer{ .card-footer{
.footer-title{ .footer-title{
font-weight: 600; font-weight: 600;
font-size: 28rpx; font-size: 28rpx;
color: #000000; color: #000000;
} }
.footer-content{
.content-line{
display: grid
grid-template-columns: repeat(4, 1fr)
background: linear-gradient( to left, #9E74FD 0%, #256BFA 100%);
border-radius: 10rpx
.line-pargrah{
height: 20rpx;
position: relative
}
.line-pargrah::after{
position: absolute;
content: '';
right: 10
top: 0
width: 6rpx
height: 20rpx
background: #FFFFFF
}
}
}
} }
// ai // ai
.ai-explain{ .ai-explain{
@@ -535,7 +615,6 @@ for i in 0..100
margin-right: 24rpx margin-right: 24rpx
} }
.companyinfo-right{ .companyinfo-right{
.row1{ .row1{
font-weight: 500; font-weight: 500;
font-size: 32rpx; font-size: 32rpx;

View File

@@ -15,24 +15,24 @@
<scroll-view scroll-y> <scroll-view scroll-y>
<view v-if="pageState.list.length"> <view v-if="pageState.list.length">
<view class="card" v-for="(item, index) in pageState.list" :key="index"> <view class="card" v-for="(item, index) in pageState.list" :key="index">
<view @click="navTo('/packageA/pages/exhibitors/exhibitors?jobFairId=' + item.jobFairId)"> <view @click="navTo('/packageA/pages/exhibitors/exhibitors?jobFairId=' + item.zphID + '&jobFairName=' + item.zphmc)">
<view class="card-row"> <view class="card-row">
<Countdown startTime="item.startTime" :endTime="item.endTime" /> <Countdown :startTime="item.zphjbsj" :endTime="item.zphjzsj" />
</view> </view>
<view class="card-Title">{{ item.name }}</view> <view class="card-Title">{{ item.zphmc }}</view>
<view class="card-row"> <view class="card-row">
<view class="rowleft">{{ item.location }}</view> <view class="rowleft">{{ item.zphdz }}</view>
<view class="rowright"> <view class="rowright" style="white-space: nowrap">
<convert-distance <!-- <convert-distance
:alat="item.latitude" :alat="item.latitude"
:along="item.longitude" :along="item.longitude"
:blat="latitudeVal" :blat="latitudeVal"
:blong="longitudeVal" :blong="longitudeVal"
></convert-distance> ></convert-distance> -->
</view> </view>
</view> </view>
</view> </view>
<view class="footer" v-if="isTimePassed(item.startTime)"> <view class="footer" v-if="isTimePassed(item.zphjbsj)">
<view class="card_cancel" @click="updateCancel(item)">取消预约</view> <view class="card_cancel" @click="updateCancel(item)">取消预约</view>
</view> </view>
</view> </view>
@@ -72,6 +72,7 @@ const ranOptions = ref([
]); ]);
function isTimePassed(timeStr) { function isTimePassed(timeStr) {
if(!timeStr) return false
const targetTime = new Date(timeStr.replace(/-/g, '/')).getTime(); // 兼容格式 const targetTime = new Date(timeStr.replace(/-/g, '/')).getTime(); // 兼容格式
const now = Date.now(); const now = Date.now();
return now < targetTime; return now < targetTime;
@@ -88,11 +89,22 @@ function chnageRanOption(item) {
} }
function updateCancel(item) { function updateCancel(item) {
const fairId = item.jobFairId; const fairId = item.zphID;
$api.createRequest(`/app/fair/collection/${fairId}`, {}, 'DELETE').then((resData) => { uni.showModal({
getList('refresh'); title: '提示',
$api.msg('取消预约成功'); content: '确定要取消预约吗?',
}); showCancel: true,
success: ({ confirm, cancel }) => {
if(confirm){
$api.createRequest(`/app/fair/collection/${fairId}`, {}, 'DELETE').then((resData) => {
getList('refresh');
$api.msg('取消预约成功');
});
}
}
})
} }
function getList(type = 'add', loading = true) { function getList(type = 'add', loading = true) {
@@ -166,6 +178,7 @@ function getList(type = 'add', loading = true) {
display: flex display: flex
align-items: center align-items: center
} }
} }
.card-Title{ .card-Title{
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif; font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;

BIN
static/icon/close-blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/icon/close-green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/icon/notice-blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -85,6 +85,7 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
msg msg
} = resData.data } = resData.data
if (code === 200) { if (code === 200) {
console.log(resData.data)
resolve(resData.data) resolve(resData.data)
return return
} }