343 lines
8.4 KiB
Vue
343 lines
8.4 KiB
Vue
<template>
|
|
<view class="employ_page">
|
|
<view class="banner">
|
|
<TnSwiper
|
|
v-model="currentSwiperIndex"
|
|
:data="swiperList"
|
|
width="100%"
|
|
height="100%"
|
|
autoplay
|
|
loop
|
|
indicator
|
|
indicator-type="number"
|
|
indicator-position="left-top"
|
|
>
|
|
<template #default="{ data }">
|
|
<view class="swiper-data tn-w-full" @click="toDetail(data)">
|
|
<image class="image" :src="data.pic" mode="aspectFill" style="width: 100%;height: 100%;"/>
|
|
<view class="title tn-pl tn-pr tn-text-lg tn-gray-light_text tn-text-ellipsis-1">
|
|
{{data.title}}
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</TnSwiper>
|
|
<view class="search tn-pl-sm tn-pr-sm tn-pt-xs tn-pb-xs" @click="showSearch">
|
|
<TnIcon name="search"></TnIcon>
|
|
<span class="tn-pl-xs">搜 索</span>
|
|
</view>
|
|
</view>
|
|
<view class="main tn-pt-sm">
|
|
<view class="options tn-flex tn-flex-center-around">
|
|
<view class="btn tn-gradient-bg__cool-16 tn-text-center tn-text-xl tn-radius" @click="check('list')">
|
|
招聘信息
|
|
</view>
|
|
<view class="btn tn-gradient-bg__cool-13 tn-text-center tn-text-xl tn-radius" @click="check('position')">
|
|
选职位
|
|
</view>
|
|
<view class="btn tn-gradient-bg__cool-6 tn-text-center tn-text-xl tn-radius" @click="check('company')">
|
|
选公司
|
|
</view>
|
|
</view>
|
|
<view class="jobList tn-m-sm">
|
|
<view class="item tn-mb-sm tn-radius tn-p tn-shadow" v-for="(item,index) in jobList" :key="index" @click="toJob(item.jobId)">
|
|
<view class="title tn-text-2xl tn-text-bold">
|
|
{{item.title}}
|
|
</view>
|
|
<view class="tn-flex tn-flex-center-between tn-pt-sm tn-text">
|
|
<view class="needs">
|
|
招聘人数:<span class="count">{{item.needs}}</span>
|
|
</view>
|
|
<view class="salary tn-text-lg tn-cyan-dark_text tn-text-bold">
|
|
{{item.salary}}
|
|
</view>
|
|
</view>
|
|
<view class="tags tn-flex tn-flex-wrap">
|
|
<view class="tag-item tn-m-xs tn-ml-0" v-for="(tag,idx) in item.tags" :key="idx">
|
|
<TnTag font-size="24rpx" text-color="#fff" bg-color="#24ba97">{{tag.name}}</TnTag>
|
|
</view>
|
|
</view>
|
|
<view class="companyTime tn-flex tn-flex-center-between tn-text">
|
|
<view class="company" v-if="item.company">
|
|
{{item.company.name}}
|
|
</view>
|
|
<view class="time">
|
|
{{dayjs(Date.parse(item.createTime)).locale('zh-cn').fromNow()}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="loadmore tn-pt tn-pb">
|
|
<TnLoadmore :status="loadmoreStatus" color="#666" loading-icon-mode="flower" />
|
|
</view>
|
|
<TnPopup v-model="showPopup" open-direction="top" :radius="0">
|
|
<view class="tn-pt-xs tn-pb-xs tn-pl-lg tn-pr-lg">
|
|
<TnSearchBox
|
|
v-model="searchValue"
|
|
shape="round"
|
|
placeholder="请输入搜索职位"
|
|
@search="searchBtnClickEvent"
|
|
@clear="clearEvent"
|
|
/>
|
|
</view>
|
|
</TnPopup>
|
|
<TnPopup class="checkPop" v-model="checkPopup" close-btn open-direction="bottom">
|
|
<view class="list tn-flex tn-flex-wrap tn-flex-center-between tn-ml tn-mr tn-mt-xl">
|
|
<view class="item tn-mb" v-for="(item,index) in popList" :key="index" >
|
|
<TnTag @click="toList(item)"><view class="tn-p-sm">{{item.name}}</view></TnTag>
|
|
</view>
|
|
</view>
|
|
</TnPopup>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { onMounted, reactive, ref } from 'vue';
|
|
import { onLoad, onReachBottom } from "@dcloudio/uni-app";
|
|
import dayjs from "dayjs";
|
|
import 'dayjs/locale/zh-cn'
|
|
import relativeTime from "dayjs/plugin/relativeTime";
|
|
import type { LoadmoreStatus } from '@tuniao/tnui-vue3-uniapp'
|
|
import TnSwiper from '@/uni_modules/tuniaoui-vue3/components/swiper/src/swiper.vue'
|
|
import TnLoadmore from '@/uni_modules/tuniaoui-vue3/components/loadmore/src/loadmore.vue'
|
|
import TnPopup from '@/uni_modules/tuniaoui-vue3/components/popup/src/popup.vue'
|
|
import TnSearchBox from '@/uni_modules/tuniaoui-vue3/components/search-box/src/search-box.vue'
|
|
import TnTag from '@/uni_modules/tuniaoui-vue3/components/tag/src/tag.vue'
|
|
import request from '@/utils/request';
|
|
dayjs.extend(relativeTime)
|
|
|
|
const defaultPic = ref('')
|
|
const showPopup = ref(false)
|
|
const checkPopup = ref(false)
|
|
const cateId = ref()
|
|
const searchValue = ref('')
|
|
const currentSwiperIndex = ref(0)
|
|
const swiperList = ref([])
|
|
const hasMore = ref(true)
|
|
const loadmoreStatus = ref<LoadmoreStatus>('loadmore')
|
|
|
|
const params = reactive<{
|
|
page?:number,
|
|
limit?:number,
|
|
keyword?:string,
|
|
companyId?:number,
|
|
cate?:number
|
|
}>({
|
|
page:1,
|
|
limit:10
|
|
})
|
|
|
|
const jobList = ref([])
|
|
|
|
const popList = ref([])
|
|
|
|
const getSwiper = () =>{
|
|
request({
|
|
url:'/front/content/list',
|
|
method:'GET',
|
|
data: {'cateId':cateId.value,'limit':3}
|
|
}).then(res => {
|
|
res.data.data.list.map((d:any)=>{
|
|
if(d.image){
|
|
d.pic = JSON.parse(d.image)[0]
|
|
}else{
|
|
d.pic = defaultPic.value
|
|
}
|
|
})
|
|
swiperList.value = res.data.data.list
|
|
})
|
|
};
|
|
|
|
const showSearch = () => {
|
|
showPopup.value = true
|
|
}
|
|
|
|
const clearEvent = () => {
|
|
params.page = 1;
|
|
jobList.value = []
|
|
getJobList(params)
|
|
}
|
|
|
|
const searchBtnClickEvent = (value: string) => {
|
|
params.page = 1;
|
|
jobList.value = [];
|
|
showPopup.value = false;
|
|
params.keyword = value
|
|
getJobList(params)
|
|
}
|
|
|
|
const check = (field:string) => {
|
|
if(field == 'position'){
|
|
getCateList()
|
|
}else if(field == 'company'){
|
|
getCompanyList()
|
|
}else{
|
|
uni.redirectTo({
|
|
url:'/pages/category/index?cateId=' + cateId.value
|
|
})
|
|
}
|
|
if(popList.value){
|
|
checkPopup.value = true
|
|
}
|
|
}
|
|
|
|
const getJobList = (params:any) =>{
|
|
loadmoreStatus.value = 'loading'
|
|
request({
|
|
url:'/employ/job/page',
|
|
method:'GET',
|
|
data:params
|
|
}).then((res)=>{
|
|
jobList.value = jobList.value.concat(res.data.data.list)
|
|
if(res.data.data.list.length = params.limit){
|
|
loadmoreStatus.value = 'loadmore'
|
|
}else if(res.data.data.list.length = 0){
|
|
loadmoreStatus.value = 'empty'
|
|
}else if(res.data.data.list.length < params.limit){
|
|
hasMore.value = false
|
|
loadmoreStatus.value = 'nomore'
|
|
}
|
|
})
|
|
}
|
|
const getCateList = () => {
|
|
request({
|
|
url:'/employ/cate',
|
|
method:'GET'
|
|
}).then((res)=>{
|
|
popList.value = []
|
|
popList.value = res.data.data
|
|
})
|
|
}
|
|
const getCompanyList = () => {
|
|
request({
|
|
url:'/employ/company',
|
|
method:'GET'
|
|
}).then((res)=>{
|
|
popList.value = []
|
|
popList.value = res.data.data
|
|
})
|
|
}
|
|
|
|
const toList = (item:any) => {
|
|
jobList.value = []
|
|
if(item.companyId){
|
|
params.page = 1
|
|
params.limit = 10
|
|
params.cate = undefined
|
|
params.companyId = item.companyId
|
|
getJobList(params)
|
|
checkPopup.value = false
|
|
}else{
|
|
params.page = 1
|
|
params.limit = 10
|
|
params.cate = item.categoryId
|
|
params.companyId = undefined
|
|
getJobList(params)
|
|
checkPopup.value = false
|
|
}
|
|
}
|
|
|
|
const toJob = (id:number) => {
|
|
uni.navigateTo({
|
|
url:'/pages/employ/jobs/index?jobId='+id
|
|
})
|
|
}
|
|
|
|
const toDetail = (item:any) => {
|
|
if(item.type === 0){
|
|
let routeUrl = '/pages/detail/index'
|
|
if(item.template){
|
|
routeUrl = item.template //定义模板后
|
|
}
|
|
uni.navigateTo({
|
|
url:routeUrl + '?cateId=' + item.cateId + '&id=' + item.id
|
|
})
|
|
}else if(item.type === 1){
|
|
//外链
|
|
if(item.link && item.link.slice(0,25) !== 'https://mp.weixin.qq.com/'){
|
|
uni.navigateTo({
|
|
url:'/pages/webview/index?url=' + item.link
|
|
})
|
|
}else{
|
|
window.location.href = item.link
|
|
}
|
|
}else{
|
|
uni.navigateTo({
|
|
url:'/pages/detail/album?id=' + item.id
|
|
})
|
|
}
|
|
}
|
|
|
|
onReachBottom(() => {
|
|
if(hasMore.value){
|
|
params.page += 1
|
|
getJobList(params)
|
|
}else{
|
|
loadmoreStatus.value = 'nomore'
|
|
}
|
|
})
|
|
|
|
onLoad((option)=>{
|
|
cateId.value = option.cateId
|
|
})
|
|
|
|
onMounted(() =>{
|
|
getSwiper()
|
|
getJobList(params)
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.employ_page{
|
|
background-color: #f5f5f5;
|
|
.banner{
|
|
position: relative;
|
|
height: 450rpx;
|
|
.swiper-data{
|
|
height: 100%;
|
|
position: relative;
|
|
.title{
|
|
position: absolute;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
line-height: 1.8rem;
|
|
}
|
|
}
|
|
.search{
|
|
position: absolute;
|
|
color: #fff;
|
|
right: 20rpx;
|
|
top: 10rpx;
|
|
border-radius: 30rpx;
|
|
background-color: rgba(0, 0, 0, 0.3);
|
|
}
|
|
}
|
|
|
|
.main{
|
|
background-color: #fff;
|
|
.options{
|
|
.btn{
|
|
width: 28%;
|
|
height: 100rpx;
|
|
line-height: 100rpx;
|
|
color: #fff;
|
|
}
|
|
}
|
|
.jobList{
|
|
background-color: #fff;
|
|
.item{
|
|
color: #444;
|
|
background-color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.checkPop{
|
|
.list{
|
|
max-height: 90vh;
|
|
overflow-y: scroll;
|
|
}
|
|
}
|
|
}
|
|
</style> |