910 lines
21 KiB
Plaintext
910 lines
21 KiB
Plaintext
<!-- 消费者端 - 个人中心 -->
|
|
<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>
|
|
</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')">
|
|
<text class="tab-icon">📋</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')">
|
|
<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')">
|
|
<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')">
|
|
<text class="tab-icon">⭐</text>
|
|
<text class="tab-text">待评价</text>
|
|
<text v-if="orderCounts.review > 0" class="tab-badge">{{ orderCounts.review }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 最近订单 -->
|
|
<view class="recent-orders">
|
|
<view class="section-header">
|
|
<text class="section-title">最近订单</text>
|
|
<text class="view-all" @click="goToOrders('all')">查看全部 ></text>
|
|
</view>
|
|
|
|
<view v-if="recentOrders.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 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" />
|
|
<view class="order-info">
|
|
<text class="order-title">{{ getOrderTitle(order) }}</text>
|
|
<text class="order-amount">¥{{ order.actual_amount }}</text>
|
|
<text class="order-time">{{ formatTime(order.created_at) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="order-actions">
|
|
<button v-if="order.status === 1" class="action-btn pay" @click.stop="payOrder(order)">立即支付</button>
|
|
<button v-if="order.status === 3" class="action-btn confirm" @click.stop="confirmReceive(order)">确认收货</button>
|
|
<button v-if="order.status === 4" class="action-btn review" @click.stop="reviewOrder(order)">评价</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 我的服务 -->
|
|
<view class="my-services">
|
|
<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>
|
|
|
|
<!-- 消费统计 -->
|
|
<view class="consumption-stats">
|
|
<view class="section-title">消费统计</view>
|
|
<view class="stats-period">
|
|
<text v-for="period in statsPeriods" :key="period.key"
|
|
class="period-tab"
|
|
:class="{ active: activeStatsPeriod === period.key }"
|
|
@click="switchStatsPeriod(period.key)">{{ period.label }}</text>
|
|
</view>
|
|
|
|
<view class="stats-content">
|
|
<view class="stat-card">
|
|
<text class="stat-value">¥{{ currentStats.total_amount }}</text>
|
|
<text class="stat-label">总消费</text>
|
|
</view>
|
|
<view class="stat-card">
|
|
<text class="stat-value">{{ currentStats.order_count }}</text>
|
|
<text class="stat-label">订单数</text>
|
|
</view>
|
|
<view class="stat-card">
|
|
<text class="stat-value">¥{{ currentStats.avg_amount }}</text>
|
|
<text class="stat-label">平均消费</text>
|
|
</view>
|
|
<view class="stat-card">
|
|
<text class="stat-value">{{ currentStats.save_amount }}</text>
|
|
<text class="stat-label">节省金额</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 账户安全 -->
|
|
<view class="account-security">
|
|
<view class="section-title">账户安全</view>
|
|
<view class="security-items">
|
|
<view class="security-item" @click="changePassword">
|
|
<text class="security-icon">🔒</text>
|
|
<text class="security-text">修改密码</text>
|
|
<text class="security-arrow">></text>
|
|
</view>
|
|
<view class="security-item" @click="bindPhone">
|
|
<text class="security-icon">📱</text>
|
|
<text class="security-text">手机绑定</text>
|
|
<view class="security-status">
|
|
<text class="status-text" :class="{ bound: userInfo.phone }">{{ userInfo.phone ? '已绑定' : '未绑定' }}</text>
|
|
<text class="security-arrow">></text>
|
|
</view>
|
|
</view>
|
|
<view class="security-item" @click="bindEmail">
|
|
<text class="security-icon">📧</text>
|
|
<text class="security-text">邮箱绑定</text>
|
|
<view class="security-status">
|
|
<text class="status-text" :class="{ bound: userInfo.email }">{{ userInfo.email ? '已绑定' : '未绑定' }}</text>
|
|
<text class="security-arrow">></text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { UserType, OrderType } from '@/types/mall-types.uts'
|
|
|
|
type UserStatsType = {
|
|
points: number
|
|
balance: number
|
|
level: number
|
|
}
|
|
|
|
type OrderCountsType = {
|
|
total: number
|
|
pending: number
|
|
shipped: number
|
|
review: number
|
|
}
|
|
|
|
type ServiceCountsType = {
|
|
coupons: number
|
|
favorites: number
|
|
}
|
|
|
|
type ConsumptionStatsType = {
|
|
total_amount: number
|
|
order_count: number
|
|
avg_amount: number
|
|
save_amount: number
|
|
}
|
|
|
|
type StatsPeriodType = {
|
|
key: string
|
|
label: string
|
|
}
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
userInfo: {
|
|
id: '',
|
|
phone: '',
|
|
email: '',
|
|
nickname: '',
|
|
avatar_url: '',
|
|
gender: 0,
|
|
user_type: 0,
|
|
status: 0,
|
|
created_at: ''
|
|
} as UserType,
|
|
userStats: {
|
|
points: 0,
|
|
balance: 0,
|
|
level: 1
|
|
} as UserStatsType,
|
|
orderCounts: {
|
|
total: 0,
|
|
pending: 0,
|
|
shipped: 0,
|
|
review: 0
|
|
} as OrderCountsType,
|
|
serviceCounts: {
|
|
coupons: 0,
|
|
favorites: 0
|
|
} as ServiceCountsType,
|
|
recentOrders: [] as Array<OrderType>,
|
|
statsPeriods: [
|
|
{ key: 'month', label: '本月' },
|
|
{ key: 'quarter', label: '本季度' },
|
|
{ key: 'year', label: '本年' },
|
|
{ key: 'all', label: '全部' }
|
|
] as Array<StatsPeriodType>,
|
|
activeStatsPeriod: 'month',
|
|
currentStats: {
|
|
total_amount: 0,
|
|
order_count: 0,
|
|
avg_amount: 0,
|
|
save_amount: 0
|
|
} as ConsumptionStatsType
|
|
}
|
|
},
|
|
onLoad() {
|
|
this.loadUserProfile()
|
|
},
|
|
onShow() {
|
|
this.refreshData()
|
|
},
|
|
methods: {
|
|
loadUserProfile() {
|
|
// 模拟加载用户信息
|
|
this.userInfo = {
|
|
id: 'user_001',
|
|
phone: '13800138000',
|
|
email: 'user@example.com',
|
|
nickname: '张三',
|
|
avatar_url: '/static/avatar1.jpg',
|
|
gender: 1,
|
|
user_type: 1,
|
|
status: 1,
|
|
created_at: '2023-06-15T10:30:00'
|
|
}
|
|
|
|
this.userStats = {
|
|
points: 1580,
|
|
balance: 268.50,
|
|
level: 3
|
|
}
|
|
|
|
this.orderCounts = {
|
|
total: 23,
|
|
pending: 2,
|
|
shipped: 1,
|
|
review: 3
|
|
}
|
|
|
|
this.serviceCounts = {
|
|
coupons: 5,
|
|
favorites: 12
|
|
}
|
|
|
|
this.recentOrders = [
|
|
{
|
|
id: 'order_001',
|
|
order_no: 'ORD202401150001',
|
|
user_id: 'user_001',
|
|
merchant_id: 'merchant_001',
|
|
status: 3,
|
|
total_amount: 299.98,
|
|
discount_amount: 30.00,
|
|
delivery_fee: 8.00,
|
|
actual_amount: 277.98,
|
|
payment_method: 1,
|
|
payment_status: 1,
|
|
delivery_address: {},
|
|
created_at: '2024-01-15T14:30:00'
|
|
},
|
|
{
|
|
id: 'order_002',
|
|
order_no: 'ORD202401140002',
|
|
user_id: 'user_001',
|
|
merchant_id: 'merchant_002',
|
|
status: 4,
|
|
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-14T09:20:00'
|
|
}
|
|
]
|
|
|
|
this.loadConsumptionStats()
|
|
},
|
|
|
|
loadConsumptionStats() {
|
|
// 模拟加载消费统计数据
|
|
const statsData: Record<string, ConsumptionStatsType> = {
|
|
month: {
|
|
total_amount: 1280.50,
|
|
order_count: 8,
|
|
avg_amount: 160.06,
|
|
save_amount: 85.20
|
|
},
|
|
quarter: {
|
|
total_amount: 3680.80,
|
|
order_count: 18,
|
|
avg_amount: 204.49,
|
|
save_amount: 256.30
|
|
},
|
|
year: {
|
|
total_amount: 15680.90,
|
|
order_count: 56,
|
|
avg_amount: 280.02,
|
|
save_amount: 986.50
|
|
},
|
|
all: {
|
|
total_amount: 25680.50,
|
|
order_count: 89,
|
|
avg_amount: 288.55,
|
|
save_amount: 1580.20
|
|
}
|
|
}
|
|
|
|
this.currentStats = statsData[this.activeStatsPeriod]
|
|
},
|
|
|
|
refreshData() {
|
|
// 刷新页面数据
|
|
this.loadUserProfile()
|
|
},
|
|
|
|
getUserLevel(): string {
|
|
const levels = ['新手', '铜牌会员', '银牌会员', '金牌会员', '钻石会员']
|
|
return levels[this.userStats.level] || '新手'
|
|
},
|
|
|
|
getOrderStatusText(status: number): string {
|
|
const statusTexts = ['异常', '待支付', '待发货', '待收货', '已完成', '已取消']
|
|
return statusTexts[status] || '未知'
|
|
},
|
|
|
|
getOrderStatusClass(status: number): string {
|
|
const statusClasses = ['error', 'pending', 'processing', 'shipping', 'completed', 'cancelled']
|
|
return statusClasses[status] || 'error'
|
|
},
|
|
|
|
getOrderMainImage(order: OrderType): string {
|
|
// 模拟获取订单主图
|
|
return '/static/product1.jpg'
|
|
},
|
|
|
|
getOrderTitle(order: OrderType): string {
|
|
// 模拟获取订单标题
|
|
return '精选商品等多件商品'
|
|
},
|
|
|
|
formatTime(timeStr: string): string {
|
|
const date = new Date(timeStr)
|
|
const now = new Date()
|
|
const diff = now.getTime() - date.getTime()
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
|
|
|
if (days === 0) {
|
|
return '今天'
|
|
} else if (days === 1) {
|
|
return '昨天'
|
|
} else {
|
|
return `${days}天前`
|
|
}
|
|
},
|
|
|
|
switchStatsPeriod(period: string) {
|
|
this.activeStatsPeriod = period
|
|
this.loadConsumptionStats()
|
|
},
|
|
|
|
editProfile() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/edit-profile'
|
|
})
|
|
},
|
|
|
|
goToSettings() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/settings'
|
|
})
|
|
},
|
|
|
|
goToOrders(type: string) {
|
|
uni.navigateTo({
|
|
url: `/pages/mall/consumer/orders?type=${type}`
|
|
})
|
|
},
|
|
|
|
goShopping() {
|
|
uni.switchTab({
|
|
url: '/pages/mall/consumer/index'
|
|
})
|
|
},
|
|
|
|
viewOrderDetail(order: OrderType) {
|
|
uni.navigateTo({
|
|
url: `/pages/mall/consumer/order-detail?orderId=${order.id}`
|
|
})
|
|
},
|
|
|
|
payOrder(order: OrderType) {
|
|
uni.navigateTo({
|
|
url: `/pages/mall/consumer/payment?orderId=${order.id}`
|
|
})
|
|
},
|
|
|
|
confirmReceive(order: OrderType) {
|
|
uni.showModal({
|
|
title: '确认收货',
|
|
content: '确认已收到商品吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.showToast({
|
|
title: '确认收货成功',
|
|
icon: 'success'
|
|
})
|
|
this.refreshData()
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
reviewOrder(order: OrderType) {
|
|
uni.navigateTo({
|
|
url: `/pages/mall/consumer/review?orderId=${order.id}`
|
|
})
|
|
},
|
|
|
|
goToCoupons() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/coupons'
|
|
})
|
|
},
|
|
|
|
goToAddress() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/address'
|
|
})
|
|
},
|
|
|
|
goToFavorites() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/favorites'
|
|
})
|
|
},
|
|
|
|
goToFootprint() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/footprint'
|
|
})
|
|
},
|
|
|
|
goToRefund() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/refund'
|
|
})
|
|
},
|
|
|
|
contactService() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/service/chat'
|
|
})
|
|
},
|
|
goToMySubscriptions() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/subscription/my-subscriptions'
|
|
})
|
|
},
|
|
goToSubscriptions() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/subscription/plan-list'
|
|
})
|
|
},
|
|
|
|
changePassword() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/change-password'
|
|
})
|
|
},
|
|
|
|
bindPhone() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/bind-phone'
|
|
})
|
|
},
|
|
|
|
bindEmail() {
|
|
uni.navigateTo({
|
|
url: '/pages/mall/consumer/bind-email'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.consumer-profile {
|
|
background-color: #f5f5f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.profile-header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
padding: 60rpx 30rpx 40rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
color: #fff;
|
|
}
|
|
|
|
.user-avatar {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
border-radius: 60rpx;
|
|
margin-right: 30rpx;
|
|
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.order-shortcuts, .recent-orders, .my-services, .consumption-stats, .account-security {
|
|
background-color: #fff;
|
|
margin-bottom: 20rpx;
|
|
padding: 30rpx;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
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;
|
|
}
|
|
|
|
.order-tabs {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.order-tab {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
position: relative;
|
|
}
|
|
|
|
.tab-icon {
|
|
font-size: 40rpx;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.tab-text {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.tab-badge {
|
|
position: absolute;
|
|
top: -8rpx;
|
|
right: 20rpx;
|
|
background-color: #ff4444;
|
|
color: #fff;
|
|
font-size: 20rpx;
|
|
padding: 4rpx 8rpx;
|
|
border-radius: 10rpx;
|
|
min-width: 32rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.empty-orders {
|
|
text-align: center;
|
|
padding: 80rpx 0;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-bottom: 30rpx;
|
|
}
|
|
|
|
.start-shopping {
|
|
background-color: #007aff;
|
|
color: #fff;
|
|
padding: 20rpx 40rpx;
|
|
border-radius: 25rpx;
|
|
font-size: 26rpx;
|
|
border: none;
|
|
}
|
|
|
|
.order-item {
|
|
padding: 25rpx 0;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
}
|
|
|
|
.order-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.order-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 15rpx;
|
|
}
|
|
|
|
.order-no {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.order-status {
|
|
font-size: 24rpx;
|
|
padding: 6rpx 12rpx;
|
|
border-radius: 10rpx;
|
|
color: #fff;
|
|
}
|
|
|
|
.order-status.pending {
|
|
background-color: #ffa726;
|
|
}
|
|
|
|
.order-status.processing {
|
|
background-color: #2196f3;
|
|
}
|
|
|
|
.order-status.shipping {
|
|
background-color: #9c27b0;
|
|
}
|
|
|
|
.order-status.completed {
|
|
background-color: #4caf50;
|
|
}
|
|
|
|
.order-content {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 15rpx;
|
|
}
|
|
|
|
.order-image {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 8rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.order-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.order-title {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.order-amount {
|
|
font-size: 28rpx;
|
|
color: #ff4444;
|
|
font-weight: bold;
|
|
margin-bottom: 5rpx;
|
|
}
|
|
|
|
.order-time {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.order-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 15rpx;
|
|
}
|
|
|
|
.action-btn {
|
|
padding: 12rpx 25rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
border: none;
|
|
}
|
|
|
|
.action-btn.pay {
|
|
background-color: #ff4444;
|
|
color: #fff;
|
|
}
|
|
|
|
.action-btn.confirm {
|
|
background-color: #4caf50;
|
|
color: #fff;
|
|
}
|
|
|
|
.action-btn.review {
|
|
background-color: #ffa726;
|
|
color: #fff;
|
|
}
|
|
|
|
.service-grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 30rpx;
|
|
}
|
|
|
|
.service-item {
|
|
width: 30%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
position: relative;
|
|
}
|
|
|
|
.service-icon {
|
|
font-size: 48rpx;
|
|
margin-bottom: 15rpx;
|
|
}
|
|
|
|
.service-text {
|
|
font-size: 24rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.service-badge {
|
|
position: absolute;
|
|
top: -5rpx;
|
|
right: 10rpx;
|
|
background-color: #ff4444;
|
|
color: #fff;
|
|
font-size: 18rpx;
|
|
padding: 4rpx 6rpx;
|
|
border-radius: 8rpx;
|
|
min-width: 24rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.stats-period {
|
|
display: flex;
|
|
gap: 30rpx;
|
|
margin-bottom: 30rpx;
|
|
}
|
|
|
|
.period-tab {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
padding: 12rpx 24rpx;
|
|
border-radius: 20rpx;
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
.period-tab.active {
|
|
background-color: #007aff;
|
|
color: #fff;
|
|
}
|
|
|
|
.stats-content {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
}
|
|
|
|
.stat-card {
|
|
flex: 1;
|
|
text-align: center;
|
|
padding: 30rpx 0;
|
|
background-color: #f8f9fa;
|
|
border-radius: 10rpx;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.security-items {
|
|
margin-top: 25rpx;
|
|
}
|
|
|
|
.security-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 25rpx 0;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
}
|
|
|
|
.security-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.security-icon {
|
|
font-size: 32rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.security-text {
|
|
flex: 1;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.security-status {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.status-text {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.status-text.bound {
|
|
color: #4caf50;
|
|
}
|
|
|
|
.security-arrow {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
</style>
|