<template>
|
<PageLayoutWithBg class="index-page-wrapper" :title="''" :need-auth="false">
|
<!-- <template #left>
|
<div class="menu-btn-wrapper menu-logo">
|
<img :src="IconLogo" class="logo" />
|
</div>
|
</template> -->
|
<InfiniteLoading
|
scrollViewClassName="common-infinite-scroll-list home-list"
|
commonMode
|
v-bind="infiniteLoadingProps"
|
>
|
<div class="home-header">
|
<div class="home-searchbar-wrapper">
|
<div class="searchbar-container">
|
<BlSearchbar
|
v-model.trim="searchValue"
|
placeholder="搜索"
|
@search="handleSearch"
|
@change="handleSearch"
|
></BlSearchbar>
|
</div>
|
<div class="city-btn" @click="goCitySelect">
|
<img :src="IconLocaltion" class="city-btn-icon" />
|
<div class="city-btn-text">{{ locationCity }}</div>
|
</div>
|
</div>
|
<div class="home-banner-wrapper">
|
<nut-swiper :auto-play="3000">
|
<nut-swiper-item v-for="(item, index) in advertisements" :key="item.id">
|
<img :src="item.file" class="banner-img" draggable="false" />
|
</nut-swiper-item>
|
</nut-swiper>
|
</div>
|
<!-- <div class="home-recommend-wrapper">
|
<div class="home-recommend-item">推荐</div>
|
<div class="home-recommend-item">推荐</div>
|
<div class="home-recommend-item">推荐</div>
|
</div> -->
|
<!-- <nut-swiper :loop="false">
|
<nut-swiper-item
|
v-for="(chunk, index) in positionListChunk"
|
:key="index"
|
style="height: 160px"
|
> -->
|
<nut-grid class="home-gird" :column-num="5">
|
<nut-grid-item v-for="item in positionGrid" :key="item.value" :text="item.label">
|
<img :src="setOSSLink(item.data.field2)" class="home-grid-item-icon" />
|
<!-- <Dongdong /> -->
|
</nut-grid-item>
|
</nut-grid>
|
<!-- </nut-swiper-item>
|
</nut-swiper> -->
|
</div>
|
<div class="home-good-list">
|
<StandardServiceCard
|
v-for="item in infiniteLoadingProps.flattenListData"
|
:key="item.id"
|
@click="goSerciceDetail(item)"
|
v-bind="item"
|
style="min-width: 0"
|
/>
|
</div>
|
</InfiniteLoading>
|
|
<!-- <InfiniteLoading
|
scrollViewClassName="common-infinite-scroll-list home-list"
|
v-bind="infiniteLoadingProps"
|
:key="queryState.orderType"
|
>
|
<template #renderItem="{ item }">
|
<TaskCard @click="goTaskDetail(item)" v-bind="item" />
|
</template>
|
</InfiniteLoading>-->
|
</PageLayoutWithBg>
|
</template>
|
|
<script setup lang="ts">
|
import { useUser } from '@/hooks';
|
import Taro from '@tarojs/taro';
|
import { setLocationCity } from '@/utils';
|
import _ from 'lodash';
|
import IconLogo from '@/assets/home/icon-logo.png';
|
import { TaskCard } from '@12333/components';
|
import IconLocaltion from '@/assets/task/icon-localtion.png';
|
import { useAllAreaList, useInfiniteLoading, useTaskList } from '@12333/hooks';
|
import { useAccessLogin } from '@/hooks';
|
import { usePositionGrid, useShowAdvertisements } from './hooks';
|
import { setOSSLink, trim } from '@12333/utils';
|
import * as standardServiceServices from '@12333/services/apiV2/standardService';
|
import { EnumPagedListOrder, EnumStandardServiceReleaseStatus } from '@12333/constants';
|
import StandardServiceCard from './StandardServiceCard.vue';
|
|
const { locationCity } = useUser();
|
|
const searchValue = ref('');
|
const queryState = reactive({
|
keywords: '',
|
});
|
|
const handleSearch = _.debounce(function () {
|
queryState.keywords = trim(searchValue.value);
|
}, 300);
|
|
const { infiniteLoadingProps, invalidateQueries } = useInfiniteLoading(
|
({ pageParam }) => {
|
let params: API.GetStandardServicesQuery = {
|
pageModel: {
|
rows: 20,
|
page: pageParam,
|
orderInput: [
|
{ property: 'createdTime', order: EnumPagedListOrder.Desc },
|
{ property: 'recommendStatus', order: EnumPagedListOrder.Desc },
|
],
|
},
|
releaseStatus: EnumStandardServiceReleaseStatus.InProcess,
|
keywords: queryState.keywords,
|
};
|
|
return standardServiceServices.getStandardServices(params, {
|
showLoading: false,
|
});
|
},
|
{
|
queryKey: ['standardServiceServices/getStandardServices', queryState],
|
}
|
);
|
|
const { advertisementRefetch, advertisements } = useShowAdvertisements();
|
|
const { positionListChunk, positionGrid } = usePositionGrid();
|
|
onMounted(async () => {
|
try {
|
await setLocationCity();
|
} catch (error) {}
|
});
|
|
function goCitySelect() {
|
Taro.navigateTo({
|
url: RouterPath.citySelect,
|
});
|
}
|
|
const selectItem = ref();
|
|
function handleMenuSelectClose() {
|
selectItem.value?.toggle?.();
|
}
|
|
function goSerciceDetail(item: API.GetStandardServicesQueryResultItem) {
|
Taro.navigateTo({
|
url: `${RouterPath.serciceDetail}?id=${item.id}`,
|
});
|
}
|
</script>
|
|
<style lang="scss">
|
@import '@/styles/common.scss';
|
|
.index-page-wrapper {
|
.menu-logo {
|
padding: 0;
|
|
.logo {
|
width: 96px;
|
height: 64px;
|
}
|
}
|
|
.home-searchbar-wrapper {
|
padding: 32px 0;
|
display: flex;
|
|
.searchbar-container {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.city-btn {
|
display: flex;
|
align-items: center;
|
padding-left: 36px;
|
color: boleGetCssVar('text-color', 'primary');
|
|
.city-btn-icon {
|
width: 40px;
|
height: 40px;
|
}
|
|
.city-btn-text {
|
max-width: 200px;
|
@include ellipsis;
|
margin-left: 12px;
|
font-size: 30px;
|
}
|
}
|
}
|
|
.home-banner-wrapper {
|
margin-bottom: 20px;
|
|
.banner-img {
|
width: 100%;
|
height: 260px;
|
object-fit: cover;
|
}
|
}
|
|
.home-gird {
|
margin-bottom: 20px;
|
|
.home-grid-item-icon {
|
width: 64px;
|
height: 64px;
|
object-fit: cover;
|
}
|
}
|
|
.home-header {
|
// padding: 0 boleGetCssVar('size', 'body-padding-h');
|
}
|
|
.home-good-list {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
grid-gap: 20px;
|
}
|
|
.home-recommend-wrapper {
|
margin-bottom: 20px;
|
display: flex;
|
gap: 20px;
|
|
.home-recommend-item {
|
flex: 1;
|
min-width: 0;
|
height: 200px;
|
background-color: #fff;
|
border-radius: 12px;
|
padding: 24px 32px;
|
}
|
}
|
}
|
|
.home-list {
|
@include infiniteLoadingInTabBarPage;
|
}
|
</style>
|