继续补充功能页面,consumer模块完成度70%
This commit is contained in:
@@ -1,40 +1,110 @@
|
||||
<!-- 消费者端 - 个人中心 -->
|
||||
<template>
|
||||
<view class="consumer-profile">
|
||||
<!-- 用户信息头部 -->
|
||||
<view class="profile-header">
|
||||
<image :src="userInfo.avatar_url || '/static/default-avatar.png'" class="user-avatar" @click="editProfile" />
|
||||
<view class="user-info">
|
||||
<text class="user-name">{{ userInfo.nickname || userInfo.phone }}</text>
|
||||
<text class="user-level">{{ getUserLevel() }}</text>
|
||||
<view class="user-stats">
|
||||
<text class="stat-item">积分: {{ userStats.points }}</text>
|
||||
<text class="stat-item">余额: ¥{{ userStats.balance }}</text>
|
||||
<!-- 智能顶部导航栏 - 与消息页保持一致 -->
|
||||
<view class="smart-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<view class="nav-container">
|
||||
<!-- 头像 -->
|
||||
<image
|
||||
:src="userInfo.avatar_url || '/static/default-avatar.png'"
|
||||
class="nav-avatar"
|
||||
@click="editProfile"
|
||||
/>
|
||||
|
||||
<!-- 用户信息横向排列 (名字、积分、余额、优惠券) -->
|
||||
<view class="nav-user-stats">
|
||||
<text class="nav-user-name">{{ userInfo.nickname || userInfo.phone }}</text>
|
||||
|
||||
<view class="nav-stat-item">
|
||||
<text class="nav-stat-label">积分</text>
|
||||
<text class="nav-stat-value">{{ userStats.points }}</text>
|
||||
</view>
|
||||
|
||||
<view class="nav-stat-item">
|
||||
<text class="nav-stat-label">余额</text>
|
||||
<text class="nav-stat-value">¥{{ userStats.balance }}</text>
|
||||
</view>
|
||||
|
||||
<view class="nav-stat-item" @click="goToCoupons">
|
||||
<text class="nav-stat-label">券</text>
|
||||
<text class="nav-stat-value">{{ serviceCounts.coupons }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设置按钮 (右侧) -->
|
||||
<view class="nav-actions">
|
||||
<view class="action-btn" @click="goToSettings">
|
||||
<text class="action-icon">⚙️</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 导航栏占位符 - 恢复 -->
|
||||
<view :style="{ height: (statusBarHeight + 10) + 'px' }"></view>
|
||||
|
||||
<!-- 我的服务 (移到订单上方) -->
|
||||
<view class="my-services" style="margin-top: 10px;">
|
||||
<view class="section-title">我的服务</view>
|
||||
<view class="service-grid">
|
||||
<view class="service-item" @click="goToCoupons">
|
||||
<text class="service-icon">🎫</text>
|
||||
<text class="service-text">优惠券</text>
|
||||
<text v-if="serviceCounts.coupons > 0" class="service-badge">{{ serviceCounts.coupons }}</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToAddress">
|
||||
<text class="service-icon">📍</text>
|
||||
<text class="service-text">收货地址</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToFavorites">
|
||||
<text class="service-icon">❤️</text>
|
||||
<text class="service-text">我的收藏</text>
|
||||
<text v-if="serviceCounts.favorites > 0" class="service-badge">{{ serviceCounts.favorites }}</text>
|
||||
</view>
|
||||
|
||||
<view class="service-item" @click="goToFootprint">
|
||||
<text class="service-icon">👣</text>
|
||||
<text class="service-text">浏览足迹</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToRefund">
|
||||
<text class="service-icon">🔄</text>
|
||||
<text class="service-text">退款/售后</text>
|
||||
</view>
|
||||
<view class="service-item" @click="contactService">
|
||||
<text class="service-icon">💬</text>
|
||||
<text class="service-text">在线客服</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToMySubscriptions">
|
||||
<text class="service-icon">🧩</text>
|
||||
<text class="service-text">我的订阅</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToSubscriptions">
|
||||
<text class="service-icon">📱</text>
|
||||
<text class="service-text">软件订阅</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="settings-icon" @click="goToSettings">⚙️</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单状态快捷入口 -->
|
||||
<view class="order-shortcuts">
|
||||
<view class="section-title">我的订单</view>
|
||||
<view class="order-tabs">
|
||||
<view class="order-tab" @click="goToOrders('all')">
|
||||
<view class="order-tab" :class="{ active: currentOrderTab === 'all' }" @click="switchOrderTab('all')">
|
||||
<text class="tab-icon">📋</text>
|
||||
<text class="tab-text">全部订单</text>
|
||||
<text class="tab-text">全部</text>
|
||||
<text v-if="orderCounts.total > 0" class="tab-badge">{{ orderCounts.total }}</text>
|
||||
</view>
|
||||
<view class="order-tab" @click="goToOrders('pending')">
|
||||
<view class="order-tab" :class="{ active: currentOrderTab === 'pending' }" @click="switchOrderTab('pending')">
|
||||
<text class="tab-icon">💰</text>
|
||||
<text class="tab-text">待支付</text>
|
||||
<text v-if="orderCounts.pending > 0" class="tab-badge">{{ orderCounts.pending }}</text>
|
||||
</view>
|
||||
<view class="order-tab" @click="goToOrders('shipped')">
|
||||
<view class="order-tab" :class="{ active: currentOrderTab === 'shipped' }" @click="switchOrderTab('shipped')">
|
||||
<text class="tab-icon">🚚</text>
|
||||
<text class="tab-text">待收货</text>
|
||||
<text v-if="orderCounts.shipped > 0" class="tab-badge">{{ orderCounts.shipped }}</text>
|
||||
</view>
|
||||
<view class="order-tab" @click="goToOrders('completed')">
|
||||
<view class="order-tab" :class="{ active: currentOrderTab === 'review' }" @click="switchOrderTab('review')">
|
||||
<text class="tab-icon">⭐</text>
|
||||
<text class="tab-text">待评价</text>
|
||||
<text v-if="orderCounts.review > 0" class="tab-badge">{{ orderCounts.review }}</text>
|
||||
@@ -42,25 +112,25 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 最近订单 -->
|
||||
<!-- 最近订单列表 (根据Tab切换显示) -->
|
||||
<view class="recent-orders">
|
||||
<view class="section-header">
|
||||
<text class="section-title">最近订单</text>
|
||||
<text class="view-all" @click="goToOrders('all')">查看全部 ></text>
|
||||
<text class="section-title">{{ getOrderSectionTitle() }}</text>
|
||||
<text class="view-all" @click="goToOrders(currentOrderTab)">查看更多 ></text>
|
||||
</view>
|
||||
|
||||
<view v-if="recentOrders.length === 0" class="empty-orders">
|
||||
<text class="empty-text">暂无订单记录</text>
|
||||
<view v-if="filteredOrders.length === 0" class="empty-orders">
|
||||
<text class="empty-text">暂无相关订单记录</text>
|
||||
<button class="start-shopping" @click="goShopping">去逛逛</button>
|
||||
</view>
|
||||
|
||||
<view v-for="order in recentOrders" :key="order.id" class="order-item" @click="viewOrderDetail(order)">
|
||||
<view v-for="order in filteredOrders" :key="order.id" class="order-item" @click="viewOrderDetail(order)">
|
||||
<view class="order-header">
|
||||
<text class="order-no">订单号: {{ order.order_no }}</text>
|
||||
<text class="order-status" :class="getOrderStatusClass(order.status)">{{ getOrderStatusText(order.status) }}</text>
|
||||
</view>
|
||||
<view class="order-content">
|
||||
<image :src="getOrderMainImage(order)" class="order-image" />
|
||||
<image :src="getOrderMainImage(order)" class="order-image" mode="aspectFill" />
|
||||
<view class="order-info">
|
||||
<text class="order-title">{{ getOrderTitle(order) }}</text>
|
||||
<text class="order-amount">¥{{ order.actual_amount }}</text>
|
||||
@@ -76,7 +146,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 我的服务 -->
|
||||
<view class="my-services">
|
||||
<!-- <view class="my-services">
|
||||
<view class="section-title">我的服务</view>
|
||||
<view class="service-grid">
|
||||
<view class="service-item" @click="goToCoupons">
|
||||
@@ -114,7 +184,7 @@
|
||||
<text class="service-text">软件订阅</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 消费统计 -->
|
||||
<view class="consumption-stats">
|
||||
@@ -251,16 +321,150 @@ export default {
|
||||
order_count: 0,
|
||||
avg_amount: 0,
|
||||
save_amount: 0
|
||||
} as ConsumptionStatsType
|
||||
} as ConsumptionStatsType,
|
||||
statusBarHeight: 0,
|
||||
currentOrderTab: 'all' as string, // 当前选中的订单Tab
|
||||
allOrders: [] as Array<OrderType> // 存储所有订单数据
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.initPage()
|
||||
this.loadUserProfile()
|
||||
this.loadMockOrders() // 加载Mock订单数据
|
||||
},
|
||||
onShow() {
|
||||
this.refreshData()
|
||||
computed: {
|
||||
// 根据当前Tab筛选订单
|
||||
filteredOrders(): Array<OrderType> {
|
||||
if (this.currentOrderTab === 'all') {
|
||||
return this.allOrders
|
||||
} else if (this.currentOrderTab === 'pending') {
|
||||
return this.allOrders.filter((order: OrderType): boolean => order.status === 1)
|
||||
} else if (this.currentOrderTab === 'shipped') {
|
||||
return this.allOrders.filter((order: OrderType): boolean => order.status === 2 || order.status === 3)
|
||||
} else if (this.currentOrderTab === 'review') {
|
||||
return this.allOrders.filter((order: OrderType): boolean => order.status === 4)
|
||||
}
|
||||
return []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载Mock订单数据
|
||||
loadMockOrders() {
|
||||
// 创建Mock数据
|
||||
const mockData: Array<OrderType> = [
|
||||
// 待支付订单
|
||||
{
|
||||
id: 'order_001',
|
||||
order_no: 'ORD202401250001',
|
||||
user_id: 'user_001',
|
||||
merchant_id: 'merchant_001',
|
||||
status: 1, // 待支付
|
||||
total_amount: 299.00,
|
||||
discount_amount: 30.00,
|
||||
delivery_fee: 0.00,
|
||||
actual_amount: 269.00,
|
||||
payment_method: 1,
|
||||
payment_status: 0,
|
||||
delivery_address: {},
|
||||
created_at: '2024-01-25T14:30:00'
|
||||
},
|
||||
// 待发货
|
||||
{
|
||||
id: 'order_002',
|
||||
order_no: 'ORD202401240002',
|
||||
user_id: 'user_001',
|
||||
merchant_id: 'merchant_002',
|
||||
status: 2, // 待发货
|
||||
total_amount: 158.00,
|
||||
discount_amount: 0,
|
||||
delivery_fee: 6.00,
|
||||
actual_amount: 164.00,
|
||||
payment_method: 1,
|
||||
payment_status: 1,
|
||||
delivery_address: {},
|
||||
created_at: '2024-01-24T09:20:00'
|
||||
},
|
||||
// 待收货
|
||||
{
|
||||
id: 'order_003',
|
||||
order_no: 'ORD202401230003',
|
||||
user_id: 'user_001',
|
||||
merchant_id: 'merchant_001',
|
||||
status: 3, // 待收货
|
||||
total_amount: 89.90,
|
||||
discount_amount: 10.00,
|
||||
delivery_fee: 0.00,
|
||||
actual_amount: 79.90,
|
||||
payment_method: 1,
|
||||
payment_status: 1,
|
||||
delivery_address: {},
|
||||
created_at: '2024-01-23T18:15:00'
|
||||
},
|
||||
// 待评价 (已完成)
|
||||
{
|
||||
id: 'order_004',
|
||||
order_no: 'ORD202401200004',
|
||||
user_id: 'user_001',
|
||||
merchant_id: 'merchant_003',
|
||||
status: 4, // 待评价
|
||||
total_amount: 399.00,
|
||||
discount_amount: 50.00,
|
||||
delivery_fee: 0.00,
|
||||
actual_amount: 349.00,
|
||||
payment_method: 1,
|
||||
payment_status: 1,
|
||||
delivery_address: {},
|
||||
created_at: '2024-01-20T11:30:00'
|
||||
},
|
||||
// 已完成 (已评价)
|
||||
{
|
||||
id: 'order_005',
|
||||
order_no: 'ORD202401180005',
|
||||
user_id: 'user_001',
|
||||
merchant_id: 'merchant_001',
|
||||
status: 5, // 已完成
|
||||
total_amount: 128.00,
|
||||
discount_amount: 0,
|
||||
delivery_fee: 0.00,
|
||||
actual_amount: 128.00,
|
||||
payment_method: 1,
|
||||
payment_status: 1,
|
||||
delivery_address: {},
|
||||
created_at: '2024-01-18T16:45:00'
|
||||
}
|
||||
]
|
||||
this.allOrders = mockData
|
||||
this.recentOrders = mockData // 初始显示全部
|
||||
|
||||
// 更新角标统计
|
||||
this.orderCounts = {
|
||||
total: mockData.length,
|
||||
pending: mockData.filter((o: OrderType): boolean => o.status === 1).length,
|
||||
shipped: mockData.filter((o: OrderType): boolean => o.status === 2 || o.status === 3).length,
|
||||
review: mockData.filter((o: OrderType): boolean => o.status === 4).length
|
||||
}
|
||||
},
|
||||
|
||||
// 切换订单Tab
|
||||
switchOrderTab(tab: string) {
|
||||
this.currentOrderTab = tab
|
||||
},
|
||||
|
||||
// 获取当前订单部分标题
|
||||
getOrderSectionTitle(): string {
|
||||
const titles: Record<string, string> = {
|
||||
'all': '全部订单',
|
||||
'pending': '待支付订单',
|
||||
'shipped': '待收货订单',
|
||||
'review': '待评价订单'
|
||||
}
|
||||
return titles[this.currentOrderTab] || '我的订单'
|
||||
},
|
||||
|
||||
initPage() {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
this.statusBarHeight = systemInfo.statusBarHeight || 0
|
||||
},
|
||||
loadUserProfile() {
|
||||
// 模拟加载用户信息
|
||||
this.userInfo = {
|
||||
@@ -364,6 +568,15 @@ export default {
|
||||
refreshData() {
|
||||
// 刷新页面数据
|
||||
this.loadUserProfile()
|
||||
this.loadMockOrders() // 加载Mock订单数据
|
||||
this.updateCouponCount() // 更新优惠券数量
|
||||
},
|
||||
|
||||
updateCouponCount() {
|
||||
// 从本地存储读取领取的优惠券数量并叠加到基础数量上
|
||||
const baseCoupons = 5
|
||||
const claimedCoupons = uni.getStorageSync('claimedCoupons') || 0
|
||||
this.serviceCounts.coupons = baseCoupons + (claimedCoupons as number)
|
||||
},
|
||||
|
||||
getUserLevel(): string {
|
||||
@@ -476,8 +689,9 @@ export default {
|
||||
},
|
||||
|
||||
goToAddress() {
|
||||
// 暂时跳转到设置页的地址管理
|
||||
uni.navigateTo({
|
||||
url: '/pages/mall/consumer/address'
|
||||
url: '/pages/mall/consumer/address-list'
|
||||
})
|
||||
},
|
||||
|
||||
@@ -542,115 +756,183 @@ export default {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.profile-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 60rpx 30rpx 40rpx;
|
||||
/* 智能顶部导航栏 */
|
||||
.smart-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 12px rgba(76, 175, 80, 0.15);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
/* 导航栏用户信息区域 */
|
||||
.nav-user-stats {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start; /* 靠左对齐,紧跟头像 */
|
||||
margin-right: 12px;
|
||||
overflow: hidden; /* 防止溢出 */
|
||||
}
|
||||
|
||||
.nav-user-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
margin-right: 12px;
|
||||
max-width: 30%; /* 限制名字宽度 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-stat-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 12px;
|
||||
padding: 2px 8px;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0; /* 防止被压缩 */
|
||||
}
|
||||
|
||||
.nav-stat-label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.nav-stat-value {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.8);
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
margin-right: 30rpx;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
.action-icon {
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: 24rpx;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 15rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.user-stats {
|
||||
display: flex;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.settings-icon {
|
||||
font-size: 32rpx;
|
||||
padding: 10rpx;
|
||||
/* 导航栏占位符 */
|
||||
.navbar-placeholder {
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.order-shortcuts, .recent-orders, .my-services, .consumption-stats, .account-security {
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin: 15px 15px; /* 顶部恢复 margin */
|
||||
border-radius: 12px; /* 统一圆角 */
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
.view-all {
|
||||
font-size: 24rpx;
|
||||
color: #007aff;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.order-tabs {
|
||||
display: flex;
|
||||
flex-direction: row; /* 显式横向排列 */
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.order-tab {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row; /* 关键:改为横向排列 */
|
||||
align-items: center;
|
||||
justify-content: center; /* 居中 */
|
||||
position: relative;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 20px;
|
||||
margin-right: 6px; /* 图标和文字间距 */
|
||||
margin-bottom: 0; /* 移除底部间距 */
|
||||
}
|
||||
|
||||
.tab-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 选中状态的Tab */
|
||||
.order-tab.active .tab-icon,
|
||||
.order-tab.active .tab-text {
|
||||
color: #4CAF50;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.order-tab.active {
|
||||
background-color: #f0f9f0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.tab-badge {
|
||||
position: absolute;
|
||||
top: -8rpx;
|
||||
right: 20rpx;
|
||||
top: 0;
|
||||
right: 10%; /* 调整位置 */
|
||||
background-color: #ff4444;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 10rpx;
|
||||
min-width: 32rpx;
|
||||
font-size: 10px;
|
||||
padding: 1px 5px;
|
||||
border-radius: 8px;
|
||||
min-width: 14px;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.empty-orders {
|
||||
@@ -782,16 +1064,19 @@ export default {
|
||||
|
||||
.service-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 30rpx;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap; /* 允许换行 */
|
||||
gap: 16px 0; /* 行间距16px,列间距由 flex 控制 */
|
||||
justify-content: flex-start; /* 从左开始排列 */
|
||||
}
|
||||
|
||||
.service-item {
|
||||
width: 30%;
|
||||
width: 25%; /* 每行4个 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
box-sizing: border-box; /* 确保 padding 不影响宽度 */
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
|
||||
Reference in New Issue
Block a user