288 lines
7.1 KiB
Vue
288 lines
7.1 KiB
Vue
|
|
<template>
|
|||
|
|
<view>
|
|||
|
|
<custom-navbar title="服务列表" :leftImg="'/static/images/whiteBack.png'" :showUser="true"
|
|||
|
|
backgroundColor="linear-gradient( 134deg, #F52540 0%, #E8101E 100%)" titleColor="#fff"></custom-navbar>
|
|||
|
|
<serviecFirstTab :tabs="tabs" :activeId="activeId" activeColor="#E8101E" @tab-click="tabClick" bgColor="#fff">
|
|||
|
|
</serviecFirstTab>
|
|||
|
|
|
|||
|
|
<!-- <FilterPanel @filterConfirm="handleFilter"></FilterPanel> -->
|
|||
|
|
<CommonList ref="groupRef" :apiUrl="'/user/getSearchList'" :initialQuery="queryData"
|
|||
|
|
:listScrollHeight="`calc(100vh - ${statusBarHeight * 2 + 250}rpx)`">
|
|||
|
|
<template #headerScroll>
|
|||
|
|
<!-- 二级icon分类 -->
|
|||
|
|
<view class="icon-tabs">
|
|||
|
|
<view v-for="(item, idx) in iconTabs" :key="item.id" class="icon-tab"
|
|||
|
|
:class="{active: queryData.second_class == item.id}" @click="getSecondlist(item.id)">
|
|||
|
|
<image :src="item.photo" class="icon-img" mode="aspectFill"></image>
|
|||
|
|
<text class="icon-text">{{ item.title }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<!-- 添加过滤器组件 -->
|
|||
|
|
<filterVue :key="activeId" @filter-change="handleFilterChange"></filterVue>
|
|||
|
|
</template>
|
|||
|
|
<template #listData="{ list }">
|
|||
|
|
<serviceCardList :list="list" btnText="立即预约"></serviceCardList>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<!-- 空数据状态 -->
|
|||
|
|
<template #empty>
|
|||
|
|
<noData></noData>
|
|||
|
|
</template>
|
|||
|
|
</CommonList>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import serviceCardList from "@/pages/search/components/serviceCardList.vue";
|
|||
|
|
import request from "../../utils/request";
|
|||
|
|
import serviecFirstTab from "@/components/common/service-first-tab.vue";
|
|||
|
|
import searchBox from "./components/search-box.vue";
|
|||
|
|
import FilterPanel from "./components/intmentFilter.vue";
|
|||
|
|
import CommonList from "@/components/common/CommonList.vue";
|
|||
|
|
import filterVue from "./components/filter.vue";
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
components: {
|
|||
|
|
searchBox,
|
|||
|
|
serviecFirstTab,
|
|||
|
|
FilterPanel,
|
|||
|
|
CommonList,
|
|||
|
|
serviceCardList,
|
|||
|
|
filterVue,
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
statusBarHeight: 0,
|
|||
|
|
title: "",
|
|||
|
|
queryData: {
|
|||
|
|
type: 3,
|
|||
|
|
distance: null, // 距离筛选
|
|||
|
|
min_price: null, // 最低价格
|
|||
|
|
max_price: null, // 最高价格
|
|||
|
|
sort: null, // 排序方式
|
|||
|
|
service_type: null // 服务类型
|
|||
|
|
},
|
|||
|
|
activeId: "",
|
|||
|
|
tabs: [],
|
|||
|
|
iconTabs: [],
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
onLoad(options) {
|
|||
|
|
this.getLocation();
|
|||
|
|
const systemInfo = uni.getSystemInfoSync();
|
|||
|
|
this.statusBarHeight = systemInfo.statusBarHeight;
|
|||
|
|
this.queryData.first_class = options.id;
|
|||
|
|
this.activeId = options.id;
|
|||
|
|
this.title = options.title;
|
|||
|
|
this.getFirstClass();
|
|||
|
|
this.getIconTabs()
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
getLocation() {
|
|||
|
|
let addressRes = {};
|
|||
|
|
let userAdrees = uni.getStorageSync("userAdrees");
|
|||
|
|
if (userAdrees) {
|
|||
|
|
addressRes = userAdrees.addressRes;
|
|||
|
|
} else {
|
|||
|
|
addressRes = getApp().globalData.addressRes;
|
|||
|
|
}
|
|||
|
|
this.queryData.userLat = addressRes.latitude;
|
|||
|
|
this.queryData.userLngz = addressRes.longitude;
|
|||
|
|
},
|
|||
|
|
getSecondlist(id) {
|
|||
|
|
this.queryData.second_class = id;
|
|||
|
|
this.search();
|
|||
|
|
},
|
|||
|
|
search() {
|
|||
|
|
this.$refs.groupRef.manualRefresh(this.queryData);
|
|||
|
|
},
|
|||
|
|
searchConfrim(e) {
|
|||
|
|
this.search();
|
|||
|
|
},
|
|||
|
|
tabClick(id) {
|
|||
|
|
this.activeId = id;
|
|||
|
|
this.queryData.first_class = id;
|
|||
|
|
this.queryData.second_class = "";
|
|||
|
|
// 重置筛选条件
|
|||
|
|
this.resetFilterConditions();
|
|||
|
|
this.getIconTabs();
|
|||
|
|
this.search();
|
|||
|
|
},
|
|||
|
|
getFirstClass() {
|
|||
|
|
// 加载一级类目
|
|||
|
|
request.post("/user/firstclass").then((res) => {
|
|||
|
|
this.tabs = res.data;
|
|||
|
|
this.search();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
getIconTabs() {
|
|||
|
|
// 加载二级类目
|
|||
|
|
request.post('/user/secondclass', {
|
|||
|
|
id: this.queryData.first_class
|
|||
|
|
}).then((res) => {
|
|||
|
|
this.iconTabs = res.data;
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
handleFilter(data) {
|
|||
|
|
console.log("筛选结果:", data);
|
|||
|
|
this.queryData.distance = data.selectedDistance;
|
|||
|
|
},
|
|||
|
|
// 处理过滤器变化
|
|||
|
|
handleFilterChange(filterData) {
|
|||
|
|
console.log("收到筛选数据:", filterData);
|
|||
|
|
|
|||
|
|
// 更新查询参数
|
|||
|
|
if (filterData.distance !== undefined && filterData.distance !== null) {
|
|||
|
|
// 注意:接口需要的是km单位,组件里是米,需要转换
|
|||
|
|
this.queryData.distance = filterData.distance / 1000;
|
|||
|
|
} else {
|
|||
|
|
delete this.queryData.distance;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (filterData.minPrice !== undefined && filterData.minPrice !== null) {
|
|||
|
|
this.queryData.min_price = filterData.minPrice;
|
|||
|
|
} else {
|
|||
|
|
delete this.queryData.min_price;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (filterData.maxPrice !== undefined && filterData.maxPrice !== null) {
|
|||
|
|
this.queryData.max_price = filterData.maxPrice;
|
|||
|
|
} else {
|
|||
|
|
delete this.queryData.max_price;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (filterData.sortType !== undefined && filterData.sortType !== null) {
|
|||
|
|
// 根据接口文档映射排序类型
|
|||
|
|
const sortMap = {
|
|||
|
|
'distance': 1, // 离我最近
|
|||
|
|
'sales': 2, // 销量最高
|
|||
|
|
'price_asc': 3, // 价格最低
|
|||
|
|
'price_desc': 4 // 价格最高
|
|||
|
|
};
|
|||
|
|
this.queryData.sort_type = sortMap[filterData.sortType];
|
|||
|
|
} else {
|
|||
|
|
delete this.queryData.sort_type;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (filterData.serviceType !== undefined && filterData.serviceType !== null) {
|
|||
|
|
// 接口文档中服务方式是 server_kind,1=上门,2=到店
|
|||
|
|
this.queryData.server_kind = filterData.serviceType;
|
|||
|
|
} else {
|
|||
|
|
delete this.queryData.server_kind;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log("最终查询参数:", this.queryData);
|
|||
|
|
|
|||
|
|
// 重新搜索
|
|||
|
|
this.search();
|
|||
|
|
},
|
|||
|
|
// 重置筛选条件
|
|||
|
|
resetFilterConditions() {
|
|||
|
|
const resetFields = ['distance', 'server_kind', 'min_price', 'max_price', 'sort_type'];
|
|||
|
|
resetFields.forEach(field => {
|
|||
|
|
delete this.queryData[field];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="less">
|
|||
|
|
::v-deep .navbar-content {
|
|||
|
|
border: none !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//firstTab样式
|
|||
|
|
.service-first-tab {
|
|||
|
|
border-bottom: none;
|
|||
|
|
padding-bottom: 27rpx;
|
|||
|
|
border-bottom: 2rpx solid #f1f1f1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//list样式
|
|||
|
|
.common-list {
|
|||
|
|
// background-color: #fafafa!important; // 这个是莫名其妙多出来一小行的盒子元凶
|
|||
|
|
border-radius: 30rpx 30rpx 0rpx 0rpx;
|
|||
|
|
|
|||
|
|
::v-deep .list-container {
|
|||
|
|
padding: 0rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
::v-deep .list-scroll {
|
|||
|
|
margin-top: 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-tabs {
|
|||
|
|
display: flex;
|
|||
|
|
column-gap: 48rpx;
|
|||
|
|
row-gap: 30rpx;
|
|||
|
|
flex-flow: row wrap;
|
|||
|
|
justify-content: flex-start;
|
|||
|
|
align-items: center;
|
|||
|
|
background: #fff;
|
|||
|
|
padding: 0rpx 0 0 30rpx;
|
|||
|
|
margin-bottom: 17rpx;
|
|||
|
|
// padding-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-tab {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-img {
|
|||
|
|
width: 100rpx;
|
|||
|
|
height: 100rpx;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
border: 2rpx solid transparent;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-text {
|
|||
|
|
margin-top: 10rpx;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
line-height: 33rpx;
|
|||
|
|
text-align: left;
|
|||
|
|
font-style: normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-tab.active .icon-text {
|
|||
|
|
color: #E8101E;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.icon-tab.active .icon-img {
|
|||
|
|
border: 2rpx solid #E8101E;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
::v-deep .list-scroll {
|
|||
|
|
margin-top: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.service-first-tab {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.service-list {
|
|||
|
|
padding-top: 17rpx !important;
|
|||
|
|
background-color: #f5f5f5;
|
|||
|
|
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
::v-deep .service-list {
|
|||
|
|
padding: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
::v-deep .service-item-wrapper {
|
|||
|
|
padding: 5rpx !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ::v-deep .common-list {
|
|||
|
|
// background-color: #f5f5f5;
|
|||
|
|
// }
|
|||
|
|
</style>
|