You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

464 lines
9.5 KiB

<template>
<view class="service-center-page">
<!-- 顶部区域 -->
<view class="header-section">
<!-- 位置和搜索 -->
<view class="top-bar">
<u-search v-model="keyword" shape="round"/>
</view>
<!-- 标题和城市背景 -->
</view>
<u-image src="https://img.ggsxiangan.com/v2_sxaf4p.png" width="100%"/>
<!-- 服务图标网格 -->
<view class="service-grid-section">
<view class="service-grid">
<view
class="service-item"
v-for="(item, index) in serviceList.filter(i => i.parentId === 0)"
:key="index"
@click="handleServiceClick(item)"
>
<view class="service-icon-box">
<u-icon :name="item.image" width="80rpx" height="80rpx"/>
</view>
<text class="service-name">{{ item.title }}</text>
</view>
</view>
</view>
<!-- 分类标签 -->
<view class="category-tabs">
<view
class="tab-item"
:class="{ active: currentTab === index }"
v-for="(tab, index) in tabs"
:key="index"
@click="changeTab(index)"
>
<text class="tab-text">{{ tab.title }}</text>
<view class="tab-underline" v-if="currentTab === index"></view>
</view>
</view>
<!-- 商品列表 -->
<view class="goods-list">
<view
class="goods-item"
v-for="(item, index) in goodsList"
:key="index"
@click="handleGoodsClick(item)"
>
<image class="goods-image" :src="item.image" mode="aspectFill"></image>
<view class="goods-info">
<text class="goods-name">{{ item.name }}</text>
<text class="goods-desc">{{ item.comments }}</text>
<view class="goods-price-box">
<text class="price-symbol">¥</text>
<text class="price-value">{{ item.amount }}</text>
<text class="price-original" v-if="item.originAmount">¥{{ item.originAmount }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {getServiceListReq} from "@/api/service";
export default {
name: "ServiceIndex",
data() {
return {
currentTab: 0,
keyword: '',
tabs: [],
serviceList: [],
goodsList: [],
}
},
methods: {
changeTab(index) {
this.currentTab = index
},
handleServiceClick(item) {
if (item.path) {
uni.navigateTo({url: item.path})
} else {
uni.showToast({
title: '功能开发中',
icon: 'none'
})
}
},
handleGoodsClick(item) {
// 跳转到服务详情页
uni.navigateTo({
url: `/servicePages/pages/detail?id=${item.categoryId}`
})
},
async getCateList(){
const {data} = await getServiceListReq()
this.serviceList = data
this.tabs = data.filter(i => i.parentId === 0)
this.goodsList = data.filter(i => i.parentId === this.tabs[0].categoryId)
}
},
onLoad() {
// 加载初始数据
this.getCateList()
}
}
</script>
<style lang="scss" scoped>
.service-center-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.header-section {
background: linear-gradient(180deg, #87CEEB 0%, #B0E0E6 100%);
padding-bottom: 20rpx;
position: relative;
overflow: hidden;
}
.top-bar {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
padding-top: 40rpx;
.location {
display: flex;
align-items: center;
margin-right: 20rpx;
.location-text {
color: #fff;
font-size: 28rpx;
margin-left: 8rpx;
}
}
.search-box {
flex: 1;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 40rpx;
padding: 12rpx 24rpx;
display: flex;
align-items: center;
margin: 0 20rpx;
.search-text {
color: #999;
font-size: 26rpx;
margin-left: 12rpx;
}
}
.menu-icon, .scan-icon {
margin-left: 20rpx;
}
}
.title-section {
padding: 40rpx 30rpx 20rpx;
position: relative;
.title-text {
font-size: 60rpx;
font-weight: bold;
color: #2E8B57;
text-align: center;
letter-spacing: 4rpx;
text-shadow: 2rpx 2rpx 4rpx rgba(0, 0, 0, 0.1);
}
.subtitle-text {
font-size: 36rpx;
color: #4682B4;
text-align: center;
margin-top: 10rpx;
letter-spacing: 2rpx;
}
.city-bg {
width: 100%;
height: 200rpx;
margin-top: 30rpx;
position: relative;
display: flex;
align-items: flex-end;
justify-content: space-around;
padding: 0 20rpx;
.building {
background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.5) 100%);
border-radius: 8rpx 8rpx 0 0;
position: relative;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
&::before {
content: '';
position: absolute;
top: 10rpx;
left: 50%;
transform: translateX(-50%);
width: 60%;
height: 20rpx;
background: rgba(255, 255, 255, 0.4);
border-radius: 4rpx;
}
}
.building-1 {
width: 60rpx;
height: 120rpx;
background: linear-gradient(180deg, #FF6B6B 0%, #FF8E53 100%);
}
.building-2 {
width: 50rpx;
height: 90rpx;
background: linear-gradient(180deg, #4ECDC4 0%, #44A08D 100%);
}
.building-3 {
width: 70rpx;
height: 140rpx;
background: linear-gradient(180deg, #FFD93D 0%, #FFA500 100%);
}
.building-4 {
width: 55rpx;
height: 100rpx;
background: linear-gradient(180deg, #6C5CE7 0%, #A29BFE 100%);
}
.building-5 {
width: 65rpx;
height: 130rpx;
background: linear-gradient(180deg, #00B894 0%, #55EFC4 100%);
}
.building-6 {
width: 50rpx;
height: 85rpx;
background: linear-gradient(180deg, #FD79A8 0%, #FDCB6E 100%);
}
.building-7 {
width: 60rpx;
height: 110rpx;
background: linear-gradient(180deg, #74B9FF 0%, #0984E3 100%);
}
.building-8 {
width: 55rpx;
height: 95rpx;
background: linear-gradient(180deg, #A29BFE 0%, #6C5CE7 100%);
}
.building-9 {
width: 70rpx;
height: 125rpx;
background: linear-gradient(180deg, #FFEAA7 0%, #FDCB6E 100%);
}
.building-10 {
width: 50rpx;
height: 80rpx;
background: linear-gradient(180deg, #55EFC4 0%, #00B894 100%);
}
.decoration {
position: absolute;
font-size: 40rpx;
animation: float 3s ease-in-out infinite;
}
.tree-1 {
left: 40rpx;
bottom: 0;
}
.tree-2 {
right: 40rpx;
bottom: 0;
}
.balloon {
top: 20rpx;
right: 80rpx;
animation: float 2s ease-in-out infinite;
}
.leaf-1 {
top: 40rpx;
left: 100rpx;
font-size: 30rpx;
animation: float 2.5s ease-in-out infinite;
}
.leaf-2 {
top: 60rpx;
right: 150rpx;
font-size: 25rpx;
animation: float 3.5s ease-in-out infinite;
}
}
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10rpx);
}
}
.service-grid-section {
background-color: #fff;
margin: -20rpx 30rpx 20rpx;
border-radius: 20rpx;
padding: 40rpx 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
}
.service-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30rpx 20rpx;
.service-item {
display: flex;
flex-direction: column;
align-items: center;
.service-icon-box {
width: 100rpx;
height: 100rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
.service-emoji {
font-size: 48rpx;
}
}
.service-name {
font-size: 24rpx;
color: #333;
text-align: center;
}
}
}
.category-tabs {
display: flex;
background-color: #fff;
padding: 0 30rpx;
margin-bottom: 20rpx;
.tab-item {
flex: 1;
padding: 30rpx 0;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
.tab-text {
font-size: 28rpx;
color: #666;
}
.tab-underline {
width: 60rpx;
height: 6rpx;
background: linear-gradient(90deg, #FF6B6B 0%, #FF8E53 100%);
border-radius: 3rpx;
margin-top: 12rpx;
}
&.active .tab-text {
color: #FF6B6B;
font-weight: bold;
}
}
}
.goods-list {
padding: 0 30rpx 30rpx;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
.goods-item {
background-color: #fff;
border-radius: 16rpx;
overflow: hidden;
.goods-image {
width: 100%;
height: 320rpx;
}
.goods-info {
padding: 20rpx;
.goods-name {
font-size: 28rpx;
color: #333;
font-weight: 500;
display: block;
margin-bottom: 8rpx;
}
.goods-desc {
font-size: 24rpx;
color: #999;
display: block;
margin-bottom: 16rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.goods-price-box {
display: flex;
align-items: baseline;
.price-symbol {
font-size: 24rpx;
color: #FF6B6B;
font-weight: bold;
}
.price-value {
font-size: 36rpx;
color: #FF6B6B;
font-weight: bold;
margin-left: 4rpx;
}
.price-original {
font-size: 24rpx;
color: #999;
text-decoration: line-through;
margin-left: 12rpx;
}
}
}
}
}
</style>