2026-03-24 11:45:13 +08:00
|
|
|
<template>
|
|
|
|
|
<view class="class-page" :class="{'popupShow':showFilter}">
|
|
|
|
|
<!-- 顶部导航栏 -->
|
|
|
|
|
<custom-navbar title="购买服务" :showBack="true" backgroundColor="#fff"></custom-navbar>
|
|
|
|
|
|
|
|
|
|
<!-- 一级Tab -->
|
|
|
|
|
<scroll-view scroll-x class="main-tab-scroll" :show-scrollbar="false">
|
|
|
|
|
<view class="main-tabs">
|
|
|
|
|
<view v-for="(tab, idx) in mainTabs" :key="tab.id"
|
|
|
|
|
:class="['main-tab', { active: queryData.first_class_id == tab.id }]"
|
|
|
|
|
@click="getFirstlist(tab.id, tab.title, tab.ratio)">
|
|
|
|
|
<text class="tab-text">{{ tab.title }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
<!-- 二级icon分类 -->
|
|
|
|
|
<scroll-view scroll-x class="icon-tab-scroll">
|
|
|
|
|
<view class="icon-tabs">
|
|
|
|
|
<view v-for="(item, idx) in iconTabs" :key="item.id" class="icon-tab"
|
|
|
|
|
:class="{ active: queryData.second_class_id == 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>
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
<view class="filter-bar">
|
|
|
|
|
<view class="filter-bar-cont">
|
|
|
|
|
<view class="filter-item" @click="toggleTimeFilter" :class="{ active: showTimeFilter }">
|
|
|
|
|
<text class="filter-item-text">服务时间</text>
|
|
|
|
|
<image src="/static/images/sq_icon.png" mode="aspectFit" class="sq-icon" v-if="!showTimeFilter">
|
|
|
|
|
</image>
|
|
|
|
|
<image src="/static/images/zk_icon.png" mode="aspectFit" class="sq-icon" v-else></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="filter-item" @click="toggleFilter" :class="{ active: showFilter }">
|
|
|
|
|
<text class="filter-item-text">筛选</text>
|
|
|
|
|
<image src="/static/images/filter_icon.png" mode="aspectFit" class="filter-icon"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 筛选弹框 showFilter-->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 遮罩层 - 更新遮罩层显示逻辑 -->
|
|
|
|
|
<view class="popup-mask" v-if="showTimeFilter" @click="closeAllPopups" @touchmove.prevent.stop>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 服务卡片宫格 -->
|
|
|
|
|
<view class="service-list" v-if="serverlist.length != 0">
|
|
|
|
|
<service-grid :services="serverlist" @service-click="goToDetail" />
|
|
|
|
|
<!-- 加载更多 -->
|
|
|
|
|
<view class="loading-more" v-if="hasMore">加载中...</view>
|
|
|
|
|
<view class="no-more" v-else>没有更多了</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 暂无数据 -->
|
|
|
|
|
<noData v-else></noData>
|
|
|
|
|
|
|
|
|
|
<!-- 筛选弹框 showFilter-->
|
|
|
|
|
<filterPopup ref="filterPopup" @change="filterChange" :filterListSelectLists="filterListSelectLists"
|
|
|
|
|
:filterList="filterList" @reset="resetFilter" @sure="confirmFilter">
|
|
|
|
|
<filterCard :info="filterDetailsLists[0]" @selectDetail="selectDetailPrice" :isSingle="true"
|
|
|
|
|
:infoDetailList="infoDetailLists[0]">
|
|
|
|
|
<view class="price-input">
|
|
|
|
|
<input type="number" v-model="queryData.start_price" placeholder="最低价" class="price-input-field" />
|
|
|
|
|
<text class="price-separator"></text>
|
|
|
|
|
<input type="number" v-model="queryData.end_price" placeholder="最高价" class="price-input-field" />
|
|
|
|
|
</view>
|
|
|
|
|
</filterCard>
|
|
|
|
|
<filterCard :info="filterDetailsLists[1]" @selectDetail="selectDetailSort" :infoDetailList="infoDetailLists[1]" :isSingle="true"> </filterCard
|
|
|
|
|
>
|
|
|
|
|
</filterPopup>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import request from "../../utils/request";
|
|
|
|
|
import filterPopup from "components/filter-popup/filter-popup.vue";
|
|
|
|
|
import filterCard from "components/filterCard/filterCard.vue";
|
|
|
|
|
import customNavbar from "@/components/custom-navbar/custom-navbar.vue";
|
|
|
|
|
import _public from "../../utils/public";
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
customNavbar,
|
|
|
|
|
filterPopup,
|
|
|
|
|
filterCard
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
filterList: [{
|
|
|
|
|
id: 1,
|
|
|
|
|
title: "价格",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
title: "排序",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
mainTabs: [],
|
|
|
|
|
iconTabs: [],
|
|
|
|
|
iconTabIndex: 0,
|
|
|
|
|
dateTabs: ["今日可约", "近两日可约", "近三日可约"],
|
|
|
|
|
dateTabIndex: 0,
|
|
|
|
|
serverlist: [],
|
|
|
|
|
isRefreshing: false,
|
|
|
|
|
hasMore: true,
|
|
|
|
|
infoDetailLists: [], // 筛选列表选择项
|
|
|
|
|
filterListSelectLists: [], // 筛选列表选择状态
|
|
|
|
|
filterDetailsLists: [{
|
|
|
|
|
id: 2,
|
|
|
|
|
title: "价格",
|
|
|
|
|
details: [{
|
|
|
|
|
id: 1,
|
|
|
|
|
name: "0-10元",
|
|
|
|
|
value: "0-10",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
name: "10-30元",
|
|
|
|
|
value: "10-30",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
name: "30-50元",
|
|
|
|
|
value: "30-50",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 4,
|
|
|
|
|
name: "50-100元",
|
|
|
|
|
value: "50-100",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 5,
|
|
|
|
|
name: "100-300元",
|
|
|
|
|
value: "100-300",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 6,
|
|
|
|
|
name: "300+",
|
|
|
|
|
value: "300-",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
title: "排序",
|
|
|
|
|
details: [{
|
|
|
|
|
id: 1,
|
|
|
|
|
name: " 销量最高",
|
|
|
|
|
value: "1",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
name: "价格最高",
|
|
|
|
|
value: "2",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
name: "价格最低",
|
|
|
|
|
value: "3",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
showTimeFilter: false,
|
|
|
|
|
selectedTimeOption: null,
|
|
|
|
|
timeOptions: [{
|
|
|
|
|
text: "今日可约"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "近两日可约",
|
|
|
|
|
discount: "64.31%"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "近三日可约"
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
showFilter: false,
|
|
|
|
|
priceRanges: [{
|
|
|
|
|
id: 0,
|
|
|
|
|
startPrice: 0,
|
|
|
|
|
endPrice: 99,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
startPrice: 100,
|
|
|
|
|
endPrice: 199,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
startPrice: 200,
|
|
|
|
|
endPrice: 299,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
startPrice: 300,
|
|
|
|
|
endPrice: 499,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 4,
|
|
|
|
|
startPrice: 500,
|
|
|
|
|
endPrice: null,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
selectedPricesId: -1,
|
|
|
|
|
sortOptions: ["销量最高", "价格最高", "价格最低"],
|
|
|
|
|
selectedSort: -1,
|
|
|
|
|
typeOptions: ["到家", "到店"],
|
|
|
|
|
selectedType: -1,
|
|
|
|
|
selectedStars: [],
|
|
|
|
|
minPrice: "",
|
|
|
|
|
maxPrice: "",
|
|
|
|
|
queryData: {
|
2026-03-30 14:32:03 +08:00
|
|
|
servers_region: null,
|
2026-03-24 11:45:13 +08:00
|
|
|
page: 1,
|
|
|
|
|
limit: 10,
|
|
|
|
|
},
|
|
|
|
|
ratio: null,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
async onLoad() {
|
|
|
|
|
const beforeShopInfo = await request.post("/user/getuser", {
|
|
|
|
|
type: 3
|
|
|
|
|
});
|
2026-03-30 14:32:03 +08:00
|
|
|
this.queryData.servers_region = beforeShopInfo.data.dependency
|
2026-03-24 11:45:13 +08:00
|
|
|
const nowShopInfo = await request.post("/sj/sjdetail", {
|
|
|
|
|
id: beforeShopInfo.data.id,
|
|
|
|
|
});
|
|
|
|
|
// 加载一级类目
|
|
|
|
|
await request.post("/sj/firstclass").then((res) => {
|
|
|
|
|
this.mainTabs = res.data;
|
|
|
|
|
if (res.data.length != 0) {
|
|
|
|
|
this.ratio = this.mainTabs[0].ratio;
|
|
|
|
|
this.queryData.first_class_id = this.mainTabs[0].id;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 获取商家端服务折扣
|
|
|
|
|
|
|
|
|
|
this.refreshList();
|
|
|
|
|
this.getIconTabs();
|
|
|
|
|
},
|
|
|
|
|
onPullDownRefresh() {
|
|
|
|
|
console.log("触发下拉刷新");
|
|
|
|
|
this.onRefresh();
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
console.log("刷新完毕");
|
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
}, 1000);
|
|
|
|
|
},
|
|
|
|
|
onReachBottom() {
|
|
|
|
|
this.loadMore();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
//处理当前列表
|
|
|
|
|
handleSelectLists(detail, id) {
|
|
|
|
|
if (detail.length > 0) {
|
|
|
|
|
this.$set(this.filterListSelectLists, id, true);
|
|
|
|
|
} else {
|
|
|
|
|
this.$set(this.filterListSelectLists, id, false);
|
|
|
|
|
}
|
|
|
|
|
console.log("当前选择的筛选列表", this.filterListSelectLists);
|
|
|
|
|
// this.filterListId = id;
|
|
|
|
|
},
|
|
|
|
|
selectDetailPrice(detail) {
|
|
|
|
|
if (detail[0]) {
|
|
|
|
|
let priceList = detail[0].split("-");
|
|
|
|
|
this.queryData.start_price = priceList[0];
|
|
|
|
|
this.queryData.end_price = priceList[1] || null;
|
|
|
|
|
} else {
|
|
|
|
|
this.queryData.start_price = null;
|
|
|
|
|
this.queryData.end_price = null;
|
|
|
|
|
}
|
|
|
|
|
this.handleSelectLists(detail, 1);
|
|
|
|
|
this.$set(this.infoDetailLists, 0, detail);
|
|
|
|
|
console.log("选择的价格区间", detail);
|
|
|
|
|
},
|
|
|
|
|
selectDetailSort(detail) {
|
|
|
|
|
this.handleSelectLists(detail, 2);
|
|
|
|
|
//
|
|
|
|
|
this.$set(this.infoDetailLists, 1, detail);
|
|
|
|
|
//赋予排序方式
|
|
|
|
|
this.queryData.ordersort = detail[0];
|
|
|
|
|
console.log("选择的排序方式", detail);
|
|
|
|
|
},
|
|
|
|
|
refreshList() {
|
|
|
|
|
request.post("/sj/getserverlist", this.queryData).then((res) => {
|
|
|
|
|
let data = res.data.map((server) => ({
|
|
|
|
|
...server,
|
|
|
|
|
server_price: _public.roundUpToTwoDecimals(
|
|
|
|
|
Number(server.server_price),
|
|
|
|
|
this.ratio
|
|
|
|
|
),
|
|
|
|
|
}));
|
|
|
|
|
this.serverlist = [...this.serverlist, ...data];
|
|
|
|
|
if (res.count == this.serverlist.length) {
|
|
|
|
|
this.hasMore = false;
|
|
|
|
|
} else {
|
|
|
|
|
this.hasMore = true;
|
|
|
|
|
this.queryData.page = this.queryData.page + 1;
|
|
|
|
|
}
|
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 下拉刷新
|
|
|
|
|
onRefresh() {
|
|
|
|
|
this.isRefreshing = true;
|
|
|
|
|
this.serverlist = [];
|
|
|
|
|
this.queryData.page = 1;
|
|
|
|
|
this.refreshList();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 加载更多
|
|
|
|
|
loadMore() {
|
|
|
|
|
if (!this.hasMore) return;
|
|
|
|
|
// TODO: 加载更多订单数据
|
|
|
|
|
this.refreshList();
|
|
|
|
|
},
|
|
|
|
|
getIconTabs() {
|
|
|
|
|
// 加载二级类目
|
|
|
|
|
request
|
|
|
|
|
.post("/sj/secondclass", {
|
|
|
|
|
id: this.queryData.first_class_id
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
this.iconTabs = res.data;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
getFirstlist(id, title, ratio) {
|
|
|
|
|
this.queryData.first_class_id = id;
|
|
|
|
|
this.ratio = ratio;
|
|
|
|
|
this.title = title;
|
|
|
|
|
delete this.queryData.second_class_id;
|
|
|
|
|
this.serverlist = [];
|
|
|
|
|
this.queryData.page = 1;
|
|
|
|
|
this.refreshList();
|
|
|
|
|
this.getIconTabs();
|
|
|
|
|
},
|
|
|
|
|
getSecondlist(id) {
|
|
|
|
|
this.queryData.second_class_id = id;
|
|
|
|
|
this.serverlist = [];
|
|
|
|
|
this.queryData.page = 1;
|
|
|
|
|
this.refreshList();
|
|
|
|
|
},
|
|
|
|
|
filterChange(e) {
|
|
|
|
|
this.showFilter = e.show
|
|
|
|
|
if (this.showFilter) {
|
|
|
|
|
this.showTimeFilter = false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
toggleFilter() {
|
|
|
|
|
this.$refs.filterPopup.open();
|
|
|
|
|
// this.showFilter = !this.showFilter;
|
|
|
|
|
// if (this.showFilter) {
|
|
|
|
|
// this.showTimeFilter = false;
|
|
|
|
|
// }
|
|
|
|
|
},
|
|
|
|
|
toggleTimeFilter() {
|
|
|
|
|
this.showTimeFilter = !this.showTimeFilter;
|
|
|
|
|
if (this.showTimeFilter) {
|
|
|
|
|
this.showFilter = false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
togglePrice(item) {
|
|
|
|
|
this.selectedPricesId = item.id;
|
|
|
|
|
this.queryData.start_price = item.startPrice;
|
|
|
|
|
this.queryData.end_price = item.endPrice;
|
|
|
|
|
},
|
|
|
|
|
selectSort(index) {
|
|
|
|
|
this.selectedSort = index;
|
|
|
|
|
this.queryData.ordersort = index + 1;
|
|
|
|
|
},
|
|
|
|
|
selectType(index) {
|
|
|
|
|
this.selectedType = index;
|
|
|
|
|
this.queryData.server_kind = index + 1;
|
|
|
|
|
},
|
|
|
|
|
closeTimeFilter() {
|
|
|
|
|
this.showTimeFilter = false;
|
|
|
|
|
},
|
|
|
|
|
getDate(index) {
|
|
|
|
|
this.queryData.date = [];
|
|
|
|
|
|
|
|
|
|
//今天的时间
|
|
|
|
|
var day1 = new Date();
|
|
|
|
|
day1.setTime(day1.getTime());
|
|
|
|
|
var m1 = day1.getMonth() + 1;
|
|
|
|
|
if (m1 <= 9) {
|
|
|
|
|
m1 = "0" + m1;
|
|
|
|
|
}
|
|
|
|
|
var d1 = day1.getDate();
|
|
|
|
|
if (d1 <= 9) {
|
|
|
|
|
d1 = "0" + d1;
|
|
|
|
|
}
|
|
|
|
|
var s1 = day1.getFullYear() + "-" + m1 + "-" + d1;
|
|
|
|
|
|
|
|
|
|
//明天的时间
|
|
|
|
|
var day2 = new Date();
|
|
|
|
|
day2.setTime(day2.getTime() + 24 * 60 * 60 * 1000);
|
|
|
|
|
var m2 = day2.getMonth() + 1;
|
|
|
|
|
if (m2 <= 9) {
|
|
|
|
|
m2 = "0" + m2;
|
|
|
|
|
}
|
|
|
|
|
var d2 = day2.getDate();
|
|
|
|
|
if (d2 <= 9) {
|
|
|
|
|
d2 = "0" + d2;
|
|
|
|
|
}
|
|
|
|
|
var s2 = day2.getFullYear() + "-" + m2 + "-" + d2;
|
|
|
|
|
|
|
|
|
|
//后天的时间
|
|
|
|
|
var day3 = new Date();
|
|
|
|
|
day3.setTime(day3.getTime() + 24 * 60 * 60 * 1000 * 2);
|
|
|
|
|
var m3 = day3.getMonth() + 1;
|
|
|
|
|
if (m3 <= 9) {
|
|
|
|
|
m3 = "0" + m3;
|
|
|
|
|
}
|
|
|
|
|
var d3 = day3.getDate();
|
|
|
|
|
if (d3 <= 9) {
|
|
|
|
|
d3 = "0" + d3;
|
|
|
|
|
}
|
|
|
|
|
var s3 = day3.getFullYear() + "-" + m3 + "-" + d3;
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
return (this.queryData.date = [`${s1}`]);
|
|
|
|
|
} else if (index == 1) {
|
|
|
|
|
return (this.queryData.date = [`${s1}`, `${s2}`]);
|
|
|
|
|
} else if (index == 2) {
|
|
|
|
|
return (this.queryData.date = [`${s1}`, `${s2}`, `${s3}`]);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async selectTimeOption(index) {
|
|
|
|
|
this.selectedTimeOption = index;
|
|
|
|
|
await this.getDate(index);
|
|
|
|
|
this.showTimeFilter = false;
|
|
|
|
|
this.serverlist = [];
|
|
|
|
|
this.queryData.page = 1;
|
|
|
|
|
// 这里可以添加筛选逻辑
|
|
|
|
|
this.refreshList();
|
|
|
|
|
},
|
|
|
|
|
goToDetail(item) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: `/pages/shop/service-detail?id=${item.id}`,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
resetFilter() {
|
|
|
|
|
this.infoDetailLists = [];
|
|
|
|
|
this.filterListSelectLists = [];
|
|
|
|
|
|
|
|
|
|
this.selectedStars = [];
|
|
|
|
|
this.selectedSort = -1;
|
|
|
|
|
this.selectedPricesId = -1;
|
|
|
|
|
this.selectedType = -1;
|
|
|
|
|
// this.queryData.start_price = "";
|
|
|
|
|
// this.queryData.end_price = "";
|
|
|
|
|
|
|
|
|
|
delete this.queryData.start_price;
|
|
|
|
|
delete this.queryData.end_price;
|
|
|
|
|
delete this.queryData.ordersort;
|
|
|
|
|
delete this.queryData.server_kind;
|
|
|
|
|
this.confirmFilter()
|
|
|
|
|
},
|
|
|
|
|
confirmFilter() {
|
|
|
|
|
this.closeFilter();
|
|
|
|
|
this.serverlist = [];
|
|
|
|
|
this.queryData.page = 1;
|
|
|
|
|
console.log(this.queryData);
|
|
|
|
|
this.refreshList();
|
|
|
|
|
},
|
|
|
|
|
closeFilter() {
|
|
|
|
|
this.showFilter = false;
|
|
|
|
|
},
|
|
|
|
|
closeAllPopups() {
|
|
|
|
|
this.showFilter = false;
|
|
|
|
|
this.showTimeFilter = false;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.class-page {
|
|
|
|
|
padding-bottom: 30rpx;
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
}
|
|
|
|
|
.popupShow {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
position: fixed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-tab-scroll {
|
|
|
|
|
position: sticky;
|
|
|
|
|
top: calc(var(--status-bar-height) + 88rpx);
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-tab-scroll {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-tabs {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row nowrap;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
align-items: center;
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
gap: 40rpx;
|
|
|
|
|
padding-bottom: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-tab {
|
|
|
|
|
line-height: 88rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tab-text {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #666;
|
2026-03-30 14:32:03 +08:00
|
|
|
white-space: nowrap;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-tab.active .tab-text {
|
2026-06-02 11:39:23 +08:00
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-tab.active::after {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 50%;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
height: 6rpx;
|
2026-06-02 11:39:23 +08:00
|
|
|
background: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
border-radius: 3rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-tabs {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row wrap;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
align-items: center;
|
|
|
|
|
background: #fff;
|
|
|
|
|
padding: 24rpx 0 0 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-tab {
|
|
|
|
|
width: 110rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-right: 32rpx;
|
|
|
|
|
margin-bottom: 32rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-img {
|
|
|
|
|
width: 96rpx;
|
|
|
|
|
height: 96rpx;
|
|
|
|
|
border-radius: 48rpx;
|
|
|
|
|
margin-bottom: 12rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-text {
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
color: #3d3d3d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-tab.active .icon-text {
|
2026-06-02 11:39:23 +08:00
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-tab.active .icon-img {
|
2026-06-02 11:39:23 +08:00
|
|
|
border: 2rpx solid #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.service-list {
|
|
|
|
|
margin: 32rpx 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 服务时间弹框样式 */
|
|
|
|
|
.time-filter-popup {
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
transform: translateY(-120%);
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
visibility: hidden;
|
|
|
|
|
border-radius: 0 0 20rpx 20rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
z-index: 998;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 66rpx;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-filter-popup.show {
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
visibility: visible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-filter-content {
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-option {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 32rpx;
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-option:not(:last-child)::after {
|
|
|
|
|
content: "";
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 32rpx;
|
|
|
|
|
right: 32rpx;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
height: 1rpx;
|
|
|
|
|
background-color: #eeeeee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-option.active {
|
|
|
|
|
background-color: #fff5f6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-option.active .time-text {
|
2026-06-02 11:39:23 +08:00
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-text {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #333333;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.time-discount {
|
|
|
|
|
font-size: 24rpx;
|
2026-06-02 11:39:23 +08:00
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
padding: 4rpx 12rpx;
|
|
|
|
|
background-color: #fff5f6;
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 筛选栏样式 */
|
|
|
|
|
.filter-bar {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 999;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-bar-cont {
|
|
|
|
|
height: 66rpx;
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row nowrap;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row nowrap;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-right: 40rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-item-text {
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-item.active .filter-item-text {
|
2026-06-02 11:39:23 +08:00
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sq-icon {
|
|
|
|
|
width: 16rpx;
|
|
|
|
|
height: 16rpx;
|
|
|
|
|
margin-left: 8rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-icon {
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
margin-left: 8rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 筛选相关样式 */
|
|
|
|
|
.filter-popup {
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 66rpx;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
z-index: 99;
|
|
|
|
|
padding: 32rpx 24rpx;
|
|
|
|
|
transform: translateY(-100%);
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
visibility: hidden;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-popup.show {
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
visibility: visible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-section {
|
|
|
|
|
margin-bottom: 32rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #333333;
|
|
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-tags,
|
|
|
|
|
.sort-tags,
|
|
|
|
|
.star-tags {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-tag,
|
|
|
|
|
.sort-tag,
|
|
|
|
|
.star-tag {
|
|
|
|
|
width: 220rpx;
|
|
|
|
|
height: 52rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
border-radius: 26rpx;
|
2026-06-02 11:39:23 +08:00
|
|
|
border: 1rpx solid #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
font-size: 24rpx;
|
|
|
|
|
color: #3d3d3d;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-tag.active,
|
|
|
|
|
.sort-tag.active,
|
|
|
|
|
.star-tag.active {
|
2026-06-02 11:39:23 +08:00
|
|
|
background-color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
color: #ffffff;
|
2026-06-02 11:39:23 +08:00
|
|
|
border-color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-input {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-top: 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-input-field {
|
|
|
|
|
width: 220rpx;
|
|
|
|
|
height: 52rpx;
|
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
text-align: center;
|
2026-06-02 11:39:23 +08:00
|
|
|
border: 1rpx solid #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
border-radius: 26rpx;
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
color: #3d3d3d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.price-separator {
|
|
|
|
|
margin: 0 16rpx;
|
|
|
|
|
color: #666666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-buttons {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 34rpx;
|
|
|
|
|
margin-top: 48rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.reset-btn,
|
|
|
|
|
.confirm-btn {
|
|
|
|
|
flex: 1;
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
border-radius: 32rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.reset-btn {
|
|
|
|
|
background-color: #ffffff;
|
2026-06-02 11:39:23 +08:00
|
|
|
border: 1rpx solid #FF4767;
|
|
|
|
|
color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.confirm-btn {
|
2026-06-02 11:39:23 +08:00
|
|
|
background-color: #FF4767;
|
2026-03-24 11:45:13 +08:00
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 加载更多 */
|
|
|
|
|
.loading-more,
|
|
|
|
|
.no-more {
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
color: #999999;
|
|
|
|
|
padding: 24rpx 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 暂无数据 */
|
|
|
|
|
.service-nothings {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row nowrap;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 280rpx 0 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nothings-text {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #999999;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
}
|
|
|
|
|
</style>
|