2026-06-12 11:02:01 +08:00

125 lines
4.6 KiB
Vue

<template>
<view class="hs-page">
<!-- 到家/家政 Tab -->
<view class="hs-tabs">
<view class="hs-tab" :class="{ active: serviceType === 1 }" @tap="switchType(1)">到家服务</view>
<view class="hs-tab" :class="{ active: serviceType === 2 }" @tap="switchType(2)">家政服务</view>
</view>
<view class="hs-body">
<!-- 左侧分类 -->
<scroll-view class="hs-cate" scroll-y>
<view class="hs-cate-item" :class="{ active: currentCate === 0 }" @tap="selectCate(0)">全部</view>
<view class="hs-cate-item" :class="{ active: currentCate === item.id }"
v-for="item in categoryList" :key="item.id" @tap="selectCate(item.id)">
{{ item.category_name }}
</view>
</scroll-view>
<!-- 右侧服务列表 -->
<scroll-view class="hs-list" scroll-y @scrolltolower="loadMore">
<view class="hs-card" v-for="item in serviceList" :key="item.id" @tap="toDetail(item)">
<image class="hs-card-pic" :src="picUrl + item.cover_pic" mode="aspectFill" />
<view class="hs-card-info">
<view class="hs-card-name">{{ item.service_name }}</view>
<view class="hs-card-desc">{{ item.price_desc }}</view>
<view class="hs-card-foot">
<text class="hs-card-tag">{{ serviceType === 1 ? '到家' : '家政' }}</text>
<text class="hs-card-btn">查看</text>
</view>
</view>
</view>
<view v-if="serviceList.length === 0" class="hs-empty">暂无服务</view>
</scroll-view>
</view>
</view>
</template>
<script>
import { request, picUrl, NavgateTo } from '@/utils'
import { apiArr } from '@/api/homeService'
export default {
data() {
return {
picUrl,
serviceType: 1,
categoryList: [],
currentCate: 0,
serviceList: [],
pageNum: 1,
pageSize: 10,
hasMore: true
}
},
onLoad() {
this.loadCategory()
this.loadList(true)
},
methods: {
switchType(t) {
if (this.serviceType === t) return
this.serviceType = t
this.currentCate = 0
this.loadCategory()
this.loadList(true)
},
selectCate(id) {
this.currentCate = id
this.loadList(true)
},
loadCategory() {
request(apiArr.categoryList, 'POST', { service_type: this.serviceType }, {}, false).then(res => {
this.categoryList = res.rows || []
})
},
loadList(reset) {
if (reset) {
this.pageNum = 1
this.hasMore = true
this.serviceList = []
}
if (!this.hasMore) return
request(apiArr.serviceList, 'POST', {
service_type: this.serviceType,
category_id: this.currentCate,
page_num: this.pageNum,
page_size: this.pageSize
}, {}, false).then(res => {
const rows = res.rows || []
this.serviceList = this.serviceList.concat(rows)
this.hasMore = rows.length === this.pageSize
this.pageNum++
})
},
loadMore() {
this.loadList(false)
},
toDetail(item) {
NavgateTo('/packages/homeService/detail/index?id=' + item.id)
}
}
}
</script>
<style scoped>
.hs-page { display: flex; flex-direction: column; height: 100vh; background: #f5f5f5; }
.hs-tabs { display: flex; background: #fff; }
.hs-tab { flex: 1; text-align: center; padding: 26rpx 0; font-size: 28rpx; color: #666; }
.hs-tab.active { color: #FF370B; font-weight: 600; border-bottom: 4rpx solid #FF370B; }
.hs-body { flex: 1; display: flex; overflow: hidden; }
.hs-cate { width: 180rpx; background: #fafafa; height: 100%; }
.hs-cate-item { padding: 28rpx 16rpx; font-size: 26rpx; color: #555; text-align: center; }
.hs-cate-item.active { background: #fff; color: #FF370B; font-weight: 600; }
.hs-list { flex: 1; padding: 20rpx; box-sizing: border-box; }
.hs-card { display: flex; background: #fff; border-radius: 12rpx; padding: 16rpx; margin-bottom: 16rpx; }
.hs-card-pic { width: 200rpx; height: 200rpx; border-radius: 8rpx; flex-shrink: 0; background: #f0f0f0; }
.hs-card-info { flex: 1; margin-left: 18rpx; display: flex; flex-direction: column; min-width: 0; }
.hs-card-name { font-size: 30rpx; color: #222; font-weight: 600; }
.hs-card-desc { font-size: 24rpx; color: #999; margin-top: 12rpx; flex: 1; }
.hs-card-foot { display: flex; align-items: center; justify-content: space-between; }
.hs-card-tag { font-size: 20rpx; color: #FF370B; border: 1rpx solid #FFD9CD; border-radius: 6rpx; padding: 2rpx 10rpx; }
.hs-card-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 24rpx; padding: 8rpx 28rpx; border-radius: 30rpx; }
.hs-empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
</style>