Files
ks-app-employment-service/packageA/pages/browseJob/browseJob.vue
史典卓 0216f6053a flat:AI+
2025-03-28 15:19:42 +08:00

435 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="collection-content">
<view class="collection-search">
<view class="search-content">
<input class="uni-input collInput" type="text" @confirm="searchCollection" >
<uni-icons class="iconsearch" color="#616161" type="search" size="20"></uni-icons>
</input>
</view>
<view class="search-date">
<view class="date-7days AllDay" v-if="state.isAll">
<view class="day" v-for="item in weekday" :key="item.weekday">
{{item.weekday}}
</view>
<!-- 日期 -->
<view class="day" v-for="(item, index) in monthDay" :key="index" :class="{active: item.fullDate === currentDay, nothemonth: !item.isCurrent, optional: findBrowseData(item.fullDate)}" @click="selectDay(item)">
{{item.day}}
</view>
<view class="monthSelect">
<uni-icons size="14" class="monthIcon"
:color="state.lastDisable ? '#e8e8e8' : '#333333'" type="left"
@click="changeMonth('lastmonth')"></uni-icons>
{{state.currentMonth}}
<uni-icons size="14" class="monthIcon"
:color="state.nextDisable ? '#e8e8e8' : '#333333'" type="right"
@click="changeMonth('nextmonth')"></uni-icons>
</view>
</view>
<view class="date-7days" v-else>
<view class="day" v-for="item in weekday" :key="item.weekday">
{{item.weekday}}
</view>
<!-- 日期 -->
<view class="day" v-for="(item, index) in weekday" :key="index" :class="{active: item.fullDate === currentDay, optional: findBrowseData(item.fullDate)}" @click="selectDay(item)">
{{item.day}}
</view>
</view>
<view class="downDate">
<uni-icons class="downIcon" v-if="state.isAll" type="up" color="#FFFFFF" size="17" @click="upDateList"></uni-icons>
<uni-icons class="downIcon" v-else type="down" color="#FFFFFF" size="18" @click="downDateList"></uni-icons>
</view>
</view>
</view>
<view class="one-cards">
<view
class="card-box "
v-for="(item, index) in pageState.list"
:key="index"
:class="{'card-transprent': item.isTitle}"
@click="navToPost(item.jobId)"
>
<view class="card-title" v-if="item.isTitle">{{item.title}}</view>
<view v-else>
<view class="box-row mar_top0">
<view class="row-left">{{ item.jobTitle }}</view>
<view class="row-right"><Salary-Expectation
:max-salary="item.maxSalary"
:min-salary="item.minSalary"
></Salary-Expectation></view>
</view>
<view class="box-row">
<view class="row-left">
<view class="row-tag" v-if="item.educatio">
<dict-Label dictType="education" :value="item.education"></dict-Label>
</view>
<view class="row-tag" v-if="item.experience">
<dict-Label dictType="experience" :value="item.experience"></dict-Label>
</view>
</view>
</view>
<view class="box-row mar_top0">
<view class="row-item mineText">{{ item.postingDate || '发布日期' }}</view>
<view class="row-item mineText">{{ vacanciesTo(item.vacancies) }}</view>
<view class="row-item mineText textblue"><matchingDegree :job="item"></matchingDegree></view>
<view class="row-item">
<!-- <uni-icons type="star" size="28"></uni-icons> -->
<!-- <uni-icons type="star-filled" color="#FFCB47" size="30"></uni-icons> -->
</view>
</view>
<view class="box-row">
<view class="row-left mineText">{{ item.companyName }}</view>
<view class="row-right mineText">
青岛
<dict-Label dictType="area" :value="item.jobLocationAreaCode"></dict-Label>
<!-- 550m -->
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import dictLabel from '@/components/dict-Label/dict-Label.vue';
import { reactive, inject, watch, ref, onMounted } from 'vue';
import { onLoad, onShow, onReachBottom } from '@dcloudio/uni-app';
import useUserStore from '@/stores/useUserStore';
const { $api, navTo, vacanciesTo, getWeeksOfMonth, isFutureDate } = inject('globalFunction');
const userStore = useUserStore();
const state = reactive({
isAll: false,
fiveMonth: [],
currentMonth: '',
currentMonthNumber: 0,
lastDisable: false,
nextDisable: true,
});
const browseDate = ref('')
const weekday = ref([])
const monthDay = ref([])
const currentDay = ref('')
const pageState = reactive({
page: 0,
list: [],
total: 0,
maxPage: 1,
pageSize: 10,
search: {},
lastDate: ''
});
onLoad(() => {
getBrowseDate()
const five = getLastFiveMonths()
state.fiveMonth = five
state.currentMonth = five[0]
state.nextDisable = true
const today = new Date().toISOString().split('T')[0]
// currentDay.value = new Date().toISOString().split('T')[0]
state.currentMonthNumber = new Date().getMonth() + 1
weekday.value = getWeekFromDate(today)
getJobList('refresh');
});
onReachBottom(() => {
getJobList();
});
function navToPost(jobId) {
navTo(`/packageA/pages/post/post?jobId=${btoa(jobId)}`);
}
function findBrowseData(date) {
const reg = new RegExp(date, 'g')
return reg.test(browseDate.value)
}
function searchCollection(e) {
const value = e.detail.value
pageState.search.jobTitle = value
getJobList('refresh')
}
function selectDay(item) {
if(isFutureDate(item.fullDate) || !findBrowseData(item.fullDate)) {
$api.msg("这一天没有浏览记录")
} else {
pageState.search.startDate = getPreviousDay(item.fullDate)
pageState.search.endDate = item.fullDate
currentDay.value = item.fullDate
getJobList('refresh')
if(item.month !== state.currentMonthNumber) {
const today = new Date(item.fullDate);
monthDay.value = getWeeksOfMonth(today.getFullYear(), today.getMonth() + 1).flat(1);
if(item.month > state.currentMonthNumber) {
changeMonth('nextmonth')
} else {
changeMonth('lastmonth')
}
state.currentMonthNumber = item.month
}
}
}
function changeMonth(type) {
const currentIndex = state.fiveMonth.findIndex((item) => item === state.currentMonth)
switch(type) {
case 'lastmonth':
if(currentIndex === state.fiveMonth.length - 2) state.lastDisable = true
if(currentIndex === state.fiveMonth.length - 1) return
state.currentMonth = state.fiveMonth[currentIndex + 1]
state.nextDisable = false
$api.msg("上一月")
break
case 'nextmonth':
if(currentIndex === 1) state.nextDisable = true
if(currentIndex === 0) return
state.currentMonth = state.fiveMonth[currentIndex - 1]
state.lastDisable = false
$api.msg("下一月")
break
}
const today = new Date(state.currentMonth);
monthDay.value = getWeeksOfMonth(today.getFullYear(), today.getMonth() + 1).flat(1);
}
function downDateList(str) {
const today = new Date();
monthDay.value = getWeeksOfMonth(today.getFullYear(), today.getMonth() + 1).flat(1);
state.isAll = true
}
function getBrowseDate() {
$api.createRequest('/app/user/review/array').then((res) => {
browseDate.value = res.data.join(',')
})
}
function upDateList() {
if(currentDay.value) {
weekday.value = getWeekFromDate(currentDay.value)
}
state.isAll = false
}
function getJobList(type = 'add', loading = true) {
if (type === 'refresh') {
pageState.page = 1;
pageState.maxPage = 1;
}
if (type === 'add' && pageState.page < pageState.maxPage) {
pageState.page += 1;
}
let params = {
current: pageState.page,
pageSize: pageState.pageSize,
...pageState.search
};
$api.createRequest('/app/user/review', params, 'GET', loading).then((resData) => {
const { rows, total } = resData;
if (type === 'add') {
const str = pageState.pageSize * (pageState.page - 1);
const end = pageState.list.length;
const [reslist, lastDate] = $api.insertSortData(rows, 'reviewDate')
if(reslist.length) { // 日期监测是否一致
if (reslist[0].title === pageState.lastDate) {
reslist.shift()
}
}
pageState.list.splice(str, end, ...reslist);
pageState.lastDate = lastDate
} else {
const [reslist, lastDate] = $api.insertSortData(rows, 'reviewDate')
pageState.list = reslist
pageState.lastDate = lastDate
}
// pageState.list = resData.rows;
pageState.total = resData.total;
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
});
}
function getWeekFromDate(dateStr) {
const days = [];
const targetDate = new Date(dateStr);
const currentDay = targetDate.getDay(); // 获取星期几0 表示星期日)
const sundayIndex = currentDay === 0 ? 7 : currentDay; // 让星期日变为 7
// 计算本周的起始和结束日期
for (let i = 1; i <= 7; i++) {
const date = new Date(targetDate);
date.setDate(targetDate.getDate() - (sundayIndex - i)); // 计算日期
days.push({
weekday: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'][i - 1],
fullDate: date.toISOString().split('T')[0], // YYYY-MM-DD 格式
day: date.getDate(),
month: date.getMonth() + 1,
year: date.getFullYear(),
});
}
return days;
}
function getPreviousDay(dateStr) {
const date = new Date(dateStr);
date.setDate(date.getDate() - 1); // 减去一天
// 格式化成 YYYY-MM-DD
return date.toISOString().split('T')[0];
}
function getLastFiveMonths() {
const result = [];
const today = new Date();
for (let i = 0; i < 5; i++) {
const date = new Date(today);
date.setMonth(today.getMonth() - i); // 往前推 i 个月
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 补零
result.push(`${year}-${month}`);
}
return result;
}
</script>
<style lang="stylus">
.card-title
color: #5d5d5d;
font-weight: bold;
font-size: 24rpx
.nothemonth
color: #bfbfbf
.downDate
display: flex
align-items: center
justify-content: center
width: 100%
margin-top: 20rpx
.downIcon
background: #e8e8e8
border-radius: 50%
width: 40rpx
height: 40rpx
.AllDay
position: relative
padding-top: 70rpx
.monthSelect
position: absolute;
top: 0
left: 50%
transform: translate(-50%, 0)
text-align: center;
line-height: 50rpx
display: flex
align-items: center
justify-content: center
font-size: 28rpx
.monthIcon
padding: 0 10rpx
.date-7days
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center
margin-top: 10rpx
font-size: 24rpx
grid-gap: 26rpx
.day
position: relative
z-index: 2
.active
color: #FFFFFF
.active::before
position: absolute
content: ''
top: 50%
left: 50%
transform: translate(-50%, -50%)
width: 40rpx
height: 40rpx
background: #4679ef
border-radius: 7rpx
z-index: -1
.optional::after
border 2rpx solid #4679ef
position: absolute
content: ''
top: 50%
left: 50%
border-radius: 10rpx
transform: translate(-50%, -50%)
width: 40rpx
height: 40rpx
z-index: -1
.collection-content
padding: 0 0 20rpx 0;
.collection-search
padding: 10rpx 20rpx;
.search-content
position: relative
.collInput
padding: 6rpx 10rpx 6rpx 50rpx;
background: #e8e8e8
border-radius: 10rpx
.iconsearch
position: absolute
left: 10rpx
top: 50%
transform: translate(0, -50%)
.one-cards
display: flex;
flex-direction: column;
padding: 0 20rpx;
.card-box
width: calc(100% - 36rpx - 36rpx);
border-radius: 0rpx 0rpx 0rpx 0rpx;
background: #FFFFFF;
border-radius: 17rpx;
padding: 15rpx 36rpx;
margin-top: 24rpx;
.box-row
display: flex;
justify-content: space-between;
margin-top: 8rpx;
align-items: center;
.mineText
font-weight: 400;
font-size: 21rpx;
color: #606060;
.textblue
color: #4778EC;
.row-left
display: flex;
justify-content: space-between;
.row-tag
background: #13C57C;
border-radius: 17rpx 17rpx 17rpx 17rpx;
font-size: 21rpx;
color: #FFFFFF;
line-height: 25rpx;
text-align: center;
padding: 4rpx 8rpx;
margin-right: 23rpx;
.card-box:first-child
margin-top: 6rpx;
.card-transprent
background: transparent !important;
.card-transprent:first-child
margin: 0 !important;
padding: 0 !important
</style>