feat : 到家服务 搜索部分页面

This commit is contained in:
赵毅 2025-07-11 15:34:22 +08:00
parent 142e1ad8fe
commit add52699ad
4 changed files with 547 additions and 37 deletions

View File

@ -2,7 +2,6 @@
margin-top: 87rpx; margin-top: 87rpx;
padding: 0 15rpx; padding: 0 15rpx;
background-color: whte; background-color: whte;
min-height: 100vh;
} }
/* 头部样式 */ /* 头部样式 */
@ -265,6 +264,7 @@
/* 热门服务样式 */ /* 热门服务样式 */
.hot-services { .hot-services {
padding: 20rpx; padding: 20rpx;
border: 1rpx solid #e8e8e8;
} }
.section-header { .section-header {
@ -346,7 +346,6 @@
.service-tag { .service-tag {
display: inline-block; display: inline-block;
/* background-color: #f5f5f5; */
color: #e1ca9b; color: #e1ca9b;
font-size: 22rpx; font-size: 22rpx;
padding: 2rpx 16rpx; padding: 2rpx 16rpx;
@ -361,12 +360,6 @@
line-height: 1.5; line-height: 1.5;
} }
.service-footer {
/* display: flex;
justify-content: space-between;
align-items: center; */
}
.service-count { .service-count {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
@ -380,3 +373,18 @@
padding: 12rpx 36rpx; padding: 12rpx 36rpx;
border-radius: 60rpx; border-radius: 60rpx;
} }
/* 回到顶部 */
.toUp {
width: 100rpx;
height: 100rpx;
position: fixed;
right: 33rpx;
bottom: 250rpx;
z-index: 10;
}
.toUp image {
width: 100%;
height: 100%;
}

View File

@ -9,7 +9,8 @@
<view class="location-search"> <view class="location-search">
<view class="location" @click="chooseLocation"> <view class="location" @click="chooseLocation">
<text class="location-text">{{ currentLocation }}</text> <text class="location-text">{{ currentLocation }}</text>
<image src="" class="arrow-down"></image> <!-- <image src="" class="arrow-down"></image> -->
<u-icon name="arrow-down" color="#999999" size="28"></u-icon>
</view> </view>
<view class="search-box" @click="searchService"> <view class="search-box" @click="searchService">
<image <image
@ -117,6 +118,19 @@
</view> </view>
<nav-footer :current="3" /> <nav-footer :current="3" />
<!-- 回到顶部 -->
<div class="toUp" @click="scrollToTop">
<u-badge
numberType="limit"
type="error"
max="99"
:value="value"
></u-badge>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"
></image>
</div>
</view> </view>
</template> </template>
@ -186,8 +200,7 @@ export default {
{ {
id: 1, id: 1,
name: "空调清洗", name: "空调清洗",
image: image: "",
"",
badge: "推荐", badge: "推荐",
tag: "平台保障", tag: "平台保障",
description: "专业保洁团队,全屋深度清洁,去除顽固污渍,还您清新居所", description: "专业保洁团队,全屋深度清洁,去除顽固污渍,还您清新居所",
@ -234,6 +247,14 @@ export default {
// API // API
console.log("获取当前位置信息"); console.log("获取当前位置信息");
}, },
//
scrollToTop() {
uni.pageScrollTo({
scrollTop: 0,
duration: 300,
});
},
}, },
onLoad() { onLoad() {
this.getCurrentLocation(); this.getCurrentLocation();

View File

@ -0,0 +1,276 @@
.container {
margin-top: 81rpx;
padding: 0 15rpx;
background-color: whte;
}
/* 搜索栏样式 */
.search-bar {
width: 520rpx;
display: flex;
align-items: center;
padding: 16rpx 20rpx;
background-color: #fff;
border-bottom: 1rpx solid #f5f5f5;
}
.search-input-container {
flex: 1;
display: flex;
align-items: center;
background-color: #f5f7fb;
border-radius: 60rpx;
padding: 14rpx 24rpx;
}
.search-icon {
width: 28rpx;
height: 28rpx;
margin-right: 16rpx;
}
.search-input {
flex: 1;
font-size: 26rpx;
font-weight: 300;
background: transparent;
}
.cancel-btn {
font-size: 28rpx;
color: #333;
margin-left: 20rpx;
}
/* 加载状态样式 */
.loading-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 999;
}
.loading-spinner {
width: 80rpx;
height: 80rpx;
border: 8rpx solid #949494;
border-radius: 50%;
border-top-color: #333;
animation: spin 1s ease-in-out infinite;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 32rpx;
color: #949494;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* 搜索指定内容 */
.specifiedContent {
min-height: 30rpx;
margin: 20rpx 10rpx 40rpx 10rpx;
}
.specifiedContent-title {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.specifiedContent-list {
display: flex;
gap: 20rpx;
flex-wrap: wrap;
}
.specifiedContent-item {
display: flex;
align-items: center;
font-size: 23rpx;
font-weight: 500;
background-color: #f5f7fb;
padding: 10rpx 20rpx;
border-radius: 8rpx;
}
.specifiedContent-img {
width: 26rpx;
height: 26rpx;
margin-right: 10rpx;
}
.search-history {
min-height: 30rpx;
margin: 20rpx 10rpx;
}
.history-header {
display: flex;
justify-content: space-between;
align-items: center;
/* margin-bottom: 10rpx; */
}
/* 搜索历史 */
.history-title {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.history-list {
display: flex;
gap: 20rpx;
flex-wrap: wrap;
}
.history-item {
display: flex;
align-items: center;
font-size: 23rpx;
font-weight: 500;
background-color: #f5f7fb;
padding: 10rpx 20rpx;
border-radius: 8rpx;
}
/* 有数据 */
.hot-services {
margin: 20rpx;
border: 1rpx solid #e8e8e8;
}
.section-header {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.section-arrow {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
.service-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.service-card {
background-color: #fff;
border-radius: 16rpx;
overflow: hidden;
}
.service-info {
display: flex;
align-items: flex-end;
width: 100%;
padding: 20rpx;
}
.service-info-left {
width: 60%;
}
.service-info-right {
width: 35%;
display: flex;
justify-content: flex-end;
}
.service-footer {
align-items: center;
gap: 15rpx;
}
.service-image {
width: 100%;
height: 240rpx;
}
.service-badge {
position: absolute;
top: 20rpx;
left: 20rpx;
background-color: #FF512A;
color: #fff;
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 20rpx;
}
.service-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.service-tag {
display: inline-block;
color: #e1ca9b;
font-size: 22rpx;
padding: 2rpx 16rpx;
border-radius: 20rpx;
margin-bottom: 16rpx;
}
.service-desc {
font-size: 24rpx;
color: #666;
margin-bottom: 20rpx;
line-height: 1.5;
}
.service-count {
font-size: 24rpx;
color: #999;
margin-left: 15rpx;
}
.service-button {
background-color: #FF512A;
color: #fff;
font-size: 26rpx;
padding: 12rpx 36rpx;
border-radius: 60rpx;
}
/* 回到顶部 */
.toUp {
width: 100rpx;
height: 100rpx;
position: fixed;
right: 33rpx;
bottom: 250rpx;
z-index: 10;
}
.toUp image {
width: 100%;
height: 100%;
}

View File

@ -1,44 +1,249 @@
<template> <template>
<view class="container"> <view class="container">
<!-- 搜索栏 -->
<view class="search-bar">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
class="search-icon"
@click="upView"
></image>
<view class="search-input-container">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
class="search-icon"
></image>
<input
type="text"
class="search-input"
placeholder="请选择搜索指定内容"
v-model="searchText"
@confirm="handleSearch"
/>
</view>
</view> </view>
<!-- 搜索指定内容 -->
<view
class="specifiedContent"
v-if="!isLoading && specifiedContent.length > 0 && !hasResult"
>
<view class="specifiedContent-title">搜索指定内容</view>
<view class="specifiedContent-list">
<view
class="specifiedContent-item"
v-for="(item, index) in specifiedContent"
:key="index"
@click="handleHistoryClick(item.name)"
>
<image class="specifiedContent-img" :src="item.icon"></image>
<view>{{ item.name }}</view>
</view>
</view>
</view>
<!-- 搜索历史 -->
<view
class="search-history"
v-if="!isLoading && searchHistory.length > 0 && !hasResult"
>
<view class="history-header">
<view class="history-title">搜索历史</view>
<u-icon
name="trash"
color="#999999"
size="28"
class="history-trash"
@click="deleteHistory"
></u-icon>
</view>
<view class="history-list">
<view
class="history-item"
v-for="(item, index) in searchHistory"
:key="index"
@click="handleHistoryClick(item)"
>
{{ item }}
</view>
</view>
</view>
<!-- 搜索结果 -->
<view class="search-result" v-if="!isLoading && hasResult">
<view class="hot-services">
<view class="service-list">
<view
class="service-card"
v-for="(service, index) in hotServiceList"
:key="index"
>
<image :src="service.image" class="service-image"></image>
<view class="service-info">
<view class="service-info-left">
<text class="service-name">{{ service.name }}</text>
<text class="service-tag">{{ service.tag }}</text>
<br />
<text class="service-desc">{{ service.description }}</text>
</view>
<view class="service-info-right">
<view class="service-footer">
<view
class="service-button"
@click="navigateToReservation(service)"
>
<text class="button-text" @click="goSubscribe">去预约</text>
</view>
<text class="service-count">{{ service.count }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="loading-container" v-if="isLoading">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 回到顶部 -->
<div class="toUp" v-show="searchHistory.length > 0 && isShowToTop" @click="scrollToTop">
<u-badge
numberType="limit"
type="error"
max="99"
:value="value"
></u-badge>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"
></image>
</div>
</view>
</template> </template>
<script> <script>
import { request, picUrl, NavgateTo, menuButtonInfo } from '../../../utils/index'; import { request, NavgateTo } from "../../../utils/index";
import { apiArr } from '../../../api/reservation';
export default { export default {
data() { data() {
return { return {
top: "", isShowToTop: false,
localHeight: "" searchText: "",
} isLoading: false,
}, specifiedContent: [
methods: { {
name: "服务",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png",
},
{
name: "阿石",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png",
},
{
name: "阿榴",
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png",
},
],
searchHistory: [],
hasResult: false,
hotServiceList: [
{
id: 1,
name: "空调清洗",
image: "",
badge: "推荐",
tag: "平台保障",
description: "专业保洁团队,全屋深度清洁,去除顽固污渍,还您清新居所",
count: "已预约100+",
},
],
};
},
}, created() {
onReady() { const history = uni.getStorageSync("searchHistory") || [];
this.searchHistory = history;
window.addEventListener('scroll', this.handleScroll);
},
beforeUnmount() {
window.removeEventListener('scroll', this.handleScroll);
},
methods: {
handleScroll() {
this.isShowToTop = window.pageYOffset > 200;
},
scrollToTop() {
uni.pageScrollTo({
scrollTop: 0,
duration: 300
});
},
upView() {
NavgateTo("/packages/homeServer/index/index");
},
//
handleSearch() {
const keyword = this.searchText.trim();
if (!keyword) return;
//
if (!this.searchHistory.includes(keyword)) {
this.searchHistory.unshift(keyword);
uni.setStorageSync("searchHistory", this.searchHistory);
}
//
this.isLoading = true;
this.hasResult = false;
//
setTimeout(() => {
this.isLoading = false;
this.hasResult = true; //
}, 1500);
}, },
onload(options) { //
const meun = menuButtonInfo(); handleHistoryClick(keyword) {
this.top = meun.top; this.searchText = keyword;
this.localHeight = meun.height; this.handleSearch();
},
onShow() {
}, },
/** //
* 页面上拉触底事件的处理函数 handleCancel() {
*/ uni.navigateBack();
onReachBottom() {
}, },
} //
deleteHistory() {
uni.showModal({
// title: "",
content: "删除所有搜素历史?",
success: (res) => {
if (res.confirm) {
console.log("用户点击确定");
uni.removeStorageSync("searchHistory");
this.getSearchHistory();
} else if (res.cancel) {
console.log("用户点击取消");
}
},
});
},
//
getSearchHistory() {
this.searchHistory = uni.getStorageSync("searchHistory") || [];
},
//
goSubscribe(){
NavgateTo("/packages/homeServer/serverInfo/index")
}
},
};
</script> </script>
<style> <style>