435 lines
14 KiB
Vue
435 lines
14 KiB
Vue
![]() |
<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>
|