feat: redesign user center page

This commit is contained in:
hajimi
2026-08-03 02:57:00 +08:00
parent b92ff6f2dc
commit 2ca5f13b46
+448 -402
View File
@@ -1,115 +1,133 @@
<template>
<view class="user-page">
<view class="user-header" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="user-header__top">
<view class="user-header__title">我的</view>
<view class="user-header__actions">
<view class="user-header__setting" @tap="goPage('/pages/user_set/user_set')">
<u-icon name="setting" color="#fff" size="32" />
<view class="user-toolbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<text class="user-toolbar__title">我的</text>
<view class="user-toolbar__setting" @tap="goPage('/pages/user_set/user_set')">
<u-icon name="setting" color="#111827" size="34" />
</view>
</view>
<view class="user-profile" @tap="openProfile">
<image class="user-profile__avatar" :src="isLogin ? (userInfo.avatar || defaultAvatar) : defaultAvatar"
mode="aspectFill" />
<view class="user-profile__body">
<view class="user-profile__name-row">
<text class="user-profile__name">{{ isLogin ? (userInfo.nickname || '用户') : '点击登录' }}</text>
<view v-if="isLogin" class="user-profile__level">{{ userLevelText }}</view>
</view>
<view class="user-profile__meta">
<text v-if="isLogin">{{ userLevelName }}</text>
<text v-else>登录后享受更多服务</text>
<view v-if="isLogin && !userInfo.is_bind_mobile" class="user-profile__verify"
@tap.stop="goPage(`/pages/bind_mobile/bind_mobile?from=verify&mobile=${userInfo.mobile}`)">
未验证号码
</view>
</view>
</view>
<view class="user-profile__edit">
<text v-if="isLogin">编辑资料</text>
<u-icon name="arrow-right" color="#6b7280" size="28" />
</view>
</view>
<view class="user-stats">
<view class="user-stats__item" @tap="goPage('/pages/my_follow/my_follow?type=follow')">
<text class="user-stats__num">{{ stats.follow_count }}</text>
<text class="user-stats__label">关注</text>
</view>
<view class="user-stats__item" @tap="goPage('/pages/my_follow/my_follow?type=fans')">
<text class="user-stats__num">{{ stats.fans_count }}</text>
<text class="user-stats__label">粉丝</text>
</view>
<view class="user-stats__item" @tap="goPage('/pages/collection/collection')">
<text class="user-stats__num">{{ stats.collect_count }}</text>
<text class="user-stats__label">收藏</text>
</view>
<view class="user-stats__item" @tap="openPointsBuy">
<text class="user-stats__num user-stats__num--points">{{ stats.user_points }}</text>
<text class="user-stats__label">积分</text>
</view>
</view>
<view class="user-content">
<view class="user-section user-benefits">
<text class="user-section__title">我的权益</text>
<view class="user-benefits__grid">
<view class="benefit-card benefit-card--points" @tap="openPointsBuy">
<view class="benefit-card__icon">
<u-icon name="coupon" color="#1468f5" size="42" />
</view>
<view class="benefit-card__body">
<text class="benefit-card__title">积分中心</text>
<view class="benefit-card__value-row">
<text class="benefit-card__value">{{ stats.user_points }}</text>
<text class="benefit-card__unit">积分</text>
</view>
<text class="benefit-card__desc">明细 · 已解锁内容</text>
</view>
<u-icon name="arrow-right" color="#8b929c" size="26" />
</view>
<view class="benefit-card benefit-card--vip" @tap="goVip">
<view class="benefit-card__icon benefit-card__icon--vip">
<u-icon name="level" color="#fff" size="42" />
</view>
<view class="benefit-card__body">
<text class="benefit-card__title">会员权益</text>
<text class="benefit-card__desc benefit-card__desc--vip">{{ memberStatusText }}</text>
<text class="benefit-card__button">查看权益</text>
</view>
<u-icon name="arrow-right" color="#8b929c" size="26" />
</view>
</view>
</view>
<view v-if="isLogin" class="user-info" @tap="goPage('/pages/user_data/user_data')">
<image class="user-info__avatar" :src="userInfo.avatar || defaultAvatar" mode="aspectFill" />
<view class="user-info__detail">
<view class="user-info__name-row">
<text class="user-info__name">{{ userInfo.nickname || '用户' }}</text>
<view v-if="userInfo.vip_info?.is_vip" class="user-info__badge user-info__badge--vip">{{
userInfo.vip_info.vip_level_name }}</view>
<view v-if="!userInfo.is_bind_mobile" class="user-info__badge user-info__badge--unverified"
@tap.stop="goPage(`/pages/bind_mobile/bind_mobile?from=verify&mobile=${userInfo.mobile}`)">
未验证号码</view>
<view class="user-section user-list-section">
<text class="user-section__title">内容与服务</text>
<view class="user-list">
<view v-for="item in contentMenus" :key="item.key" class="user-list__item"
@tap="handleMenuTap(item)">
<view class="user-list__icon"><u-icon :name="item.icon" color="#1468f5" size="34" /></view>
<text class="user-list__label">{{ item.label }}</text>
<view v-if="item.key === 'chat' && stats.chat_unread_count > 0" class="user-list__badge">
{{ stats.chat_unread_count > 99 ? '99+' : stats.chat_unread_count }}
</view>
<u-icon name="arrow-right" color="#9aa0a8" size="26" />
</view>
<text class="user-info__id">ID: {{ userInfo.sn || '' }}</text>
</view>
<view class="user-info__arrow">
<u-icon name="arrow-right" color="rgba(255,255,255,0.6)" size="28" />
</view>
</view>
<view v-else class="user-info" @tap="goPage('/pages/login/login')">
<image class="user-info__avatar" :src="defaultAvatar" mode="aspectFill" />
<view class="user-info__detail">
<text class="user-info__name">点击登录</text>
<text class="user-info__id user-info__id--guest">登录后享受更多服务</text>
</view>
<view class="user-info__arrow">
<u-icon name="arrow-right" color="rgba(255,255,255,0.6)" size="28" />
<view class="user-section user-list-section">
<text class="user-section__title">账户与支持</text>
<view class="user-list">
<view v-for="item in accountMenus" :key="item.key" class="user-list__item"
@tap="handleMenuTap(item)">
<view class="user-list__icon"><u-icon :name="item.icon" color="#1468f5" size="34" /></view>
<text class="user-list__label">{{ item.label }}</text>
<u-icon name="arrow-right" color="#9aa0a8" size="26" />
</view>
</view>
</view>
<view class="user-stats">
<view class="user-stats__item" @tap="goPage('/pages/my_follow/my_follow?type=follow')">
<text class="user-stats__num">{{ stats.follow_count }}</text>
<text class="user-stats__label">关注</text>
</view>
<view class="user-stats__item" @tap="goPage('/pages/my_follow/my_follow?type=fans')">
<text class="user-stats__num">{{ stats.fans_count }}</text>
<text class="user-stats__label">粉丝</text>
</view>
<view class="user-stats__item" @tap="goPage('/pages/collection/collection')">
<text class="user-stats__num">{{ stats.collect_count }}</text>
<text class="user-stats__label">收藏</text>
</view>
<view class="user-stats__item" @tap="openPointsBuy">
<text class="user-stats__num user-stats__num--points">{{ stats.user_points }}</text>
<text class="user-stats__label">积分</text>
<text v-if="isLogin" class="user-stats__buy">购买</text>
</view>
</view>
</view>
<view class="user-vip-wrap">
<vip-card :vip-info="userInfo.vip_info" />
</view>
<view class="assistant-entry" @tap="goPage('/pages/ai_assistant/ai_assistant')">
<view class="assistant-entry__icon">AI</view>
<view class="assistant-entry__body">
<text class="assistant-entry__title">世博头条 AI 助手</text>
<text class="assistant-entry__desc">免费咨询站内资讯赛事社区彩票和行情</text>
</view>
<u-icon name="arrow-right" size="28" color="#185dff" />
</view>
<view class="assistant-entry chat-entry" @tap="openChatList">
<view class="assistant-entry__icon chat-entry__icon"></view>
<view class="assistant-entry__body">
<text class="assistant-entry__title">私聊消息</text>
<text class="assistant-entry__desc">查看好友和关注用户的私聊</text>
</view>
<view v-if="stats.chat_unread_count > 0" class="chat-entry__badge">
<text>{{ stats.chat_unread_count > 99 ? '99+' : stats.chat_unread_count }}</text>
</view>
<u-icon name="arrow-right" size="28" color="#185dff" />
</view>
<view class="user-menu">
<!-- 我的服务从后台装修配置读取 -->
<view v-if="serviceMenu.enabled && serviceMenu.data.length" class="user-menu__group">
<!-- 横排样式 -->
<view v-if="serviceMenu.style === 1" class="user-menu__grid">
<view v-for="(item, idx) in serviceMenuList" :key="idx" class="user-menu__grid-item"
<view v-if="serviceMenu.enabled && serviceMenu.data.length" class="user-service-section">
<text class="user-section__title">{{ serviceMenu.title }}</text>
<view v-if="serviceMenu.style === 1" class="user-service-grid">
<view v-for="(item, idx) in serviceMenuList" :key="idx" class="user-service-grid__item"
@tap="goLink(item.link)">
<image v-if="item.image" :src="getImageUrl(item.image)" class="user-menu__grid-icon"
<image v-if="item.image" :src="getImageUrl(item.image)" class="user-service-grid__icon"
mode="aspectFit" />
<text class="user-menu__grid-text">{{ item.name }}</text>
<text class="user-service-grid__text">{{ item.name }}</text>
</view>
</view>
<!-- 竖排样式 -->
<template v-else>
<view v-for="(item, idx) in serviceMenuList" :key="idx" class="user-menu__item"
<view v-else class="user-list">
<view v-for="(item, idx) in serviceMenuList" :key="idx" class="user-list__item"
@tap="goLink(item.link)">
<image v-if="item.image" :src="getImageUrl(item.image)" class="user-menu__item-icon"
mode="aspectFit" />
<text class="user-menu__text">{{ item.name }}</text>
<u-icon name="arrow-right" size="24" color="#ccc" />
<image v-if="item.image" :src="getImageUrl(item.image)" class="user-list__image" mode="aspectFit" />
<text class="user-list__label">{{ item.name }}</text>
<u-icon name="arrow-right" color="#9aa0a8" size="26" />
</view>
</template>
</view>
</view>
<!-- 个人中心广告图从后台装修配置读取 -->
<view v-if="bannerData.enabled && bannerList.length" class="user-banner">
<swiper class="user-banner__swiper" :autoplay="true" :interval="4000" :circular="true" indicator-dots
indicator-color="rgba(255,255,255,0.4)" indicator-active-color="#fff">
@@ -118,7 +136,6 @@
</swiper-item>
</swiper>
</view>
</view>
</view>
</template>
@@ -132,7 +149,6 @@ import { getToken } from '@/utils/auth'
import { getDecorate } from '@/api/shop'
import request from '@/utils/request'
import { useAppStore } from '@/stores/app'
import VipCard from '@/components/vip-card/vip-card.vue'
const userStore = useUserStore()
const appStore = useAppStore()
@@ -154,6 +170,34 @@ const stats = reactive({
chat_unread_count: 0
})
const contentMenus = [
{ key: 'posts', label: '我的帖子', icon: 'file-text', url: '/pages/my_posts/my_posts' },
{ key: 'comments', label: '我的评论', icon: 'chat', toast: '我的评论功能即将上线' },
{ key: 'collection', label: '我的收藏', icon: 'star', url: '/pages/collection/collection' },
{ key: 'notice', label: '消息通知', icon: 'bell', toast: '消息通知功能即将上线' },
{ key: 'assistant', label: '世博头条 AI 助手', icon: 'robot', url: '/pages/ai_assistant/ai_assistant' },
{ key: 'chat', label: '私聊消息', icon: 'chat' }
]
const accountMenus = [
{ key: 'wallet', label: '钱包与订单', icon: 'wallet', url: '/packages/pages/user_wallet/user_wallet' },
{ key: 'invite', label: '邀请记录', icon: 'account', url: '/pages/distribution/distribution' },
{ key: 'lottery', label: 'AI 彩票分析', icon: 'file-text', url: '/pages/lottery_analysis/lottery_analysis' },
{ key: 'customer', label: '帮助与客服', icon: 'kefu-ermai', url: '/pages/customer_service/customer_service' },
{ key: 'about', label: '关于我们', icon: 'info-circle', toast: '关于我们页面即将上线' },
{ key: 'setting', label: '设置', icon: 'setting', url: '/pages/user_set/user_set' }
]
const userLevelText = computed(() => {
const level = userInfo.value?.user_level || userInfo.value?.level || userInfo.value?.vip_info?.vip_level || 1
return `Lv.${level}`
})
const userLevelName = computed(() => userInfo.value?.level_name || userInfo.value?.user_level_name || '资深球迷')
const memberStatusText = computed(() => userInfo.value?.vip_info?.is_vip
? (userInfo.value.vip_info.vip_level_name || '尊享会员')
: '普通会员')
const serviceMenu = reactive({
enabled: false,
style: 1,
@@ -268,6 +312,14 @@ const openPointsBuy = () => {
uni.navigateTo({ url: '/packages/pages/points_center/points_center' })
}
const goVip = () => {
if (!isLogin.value) {
uni.navigateTo({ url: '/pages/login/login' })
return
}
uni.navigateTo({ url: '/pages/vip/vip' })
}
const openChatList = () => {
if (!isLogin.value) {
uni.navigateTo({ url: '/pages/login/login' })
@@ -280,6 +332,24 @@ const goPage = (url: string) => {
uni.navigateTo({ url })
}
const openProfile = () => {
goPage(isLogin.value ? '/pages/user_data/user_data' : '/pages/login/login')
}
const handleMenuTap = (item: any) => {
if (item.key === 'chat') {
openChatList()
return
}
if (item.url) {
goPage(item.url)
return
}
if (item.toast) {
uni.showToast({ title: item.toast, icon: 'none' })
}
}
const goLink = (link: any) => {
if (!link?.path) return
uni.navigateTo({ url: link.path })
@@ -289,386 +359,362 @@ const goLink = (link: any) => {
<style lang="scss" scoped>
.user-page {
min-height: 100vh;
background: #f5f5f5;
background: #f7f8fa;
color: #111827;
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.user-header {
background: linear-gradient(170deg, #185dff, #4d82ff);
padding-bottom: 60rpx;
&__top {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 32rpx;
}
.user-toolbar {
position: relative;
min-height: 88rpx;
padding-left: 36rpx;
padding-right: 36rpx;
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
&__title {
font-size: 36rpx;
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 40rpx;
line-height: 1;
font-weight: 700;
color: #fff;
color: #111827;
}
&__setting {
margin-left: auto;
width: 64rpx;
height: 64rpx;
background: rgba(255, 255, 255, 0.24);
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.user-info {
.user-profile {
display: flex;
flex-wrap: nowrap;
align-items: center;
padding: 24rpx 32rpx;
padding: 36rpx 48rpx 34rpx;
background: #fff;
&__avatar {
width: 128rpx;
height: 128rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
&__detail {
flex: 1;
margin-left: 24rpx;
min-width: 0;
}
&__arrow {
flex-shrink: 0;
margin-left: 12rpx;
}
&__name-row {
display: flex;
align-items: center;
gap: 12rpx;
}
&__name {
font-size: 36rpx;
font-weight: 600;
color: #fff;
}
&__badge {
font-size: 20rpx;
padding: 2rpx 12rpx;
border-radius: 16rpx;
&--level {
background: rgba(255, 255, 255, 0.25);
color: #fff;
}
&--vip {
background: #f0ad4e;
color: #fff;
}
&--unverified {
background: rgba(255, 80, 80, 0.8);
color: #fff;
}
}
&__id {
font-size: 24rpx;
color: #e6e6e6;
margin-top: 8rpx;
&--guest {
margin-left: 4rpx;
}
}
}
.user-stats {
display: flex;
justify-content: space-around;
margin: 16rpx 18rpx 0;
background: rgba(255, 255, 255, 0.32);
border-radius: 12rpx;
padding: 32rpx 16rpx;
&__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
&__num {
font-size: 36rpx;
font-weight: 700;
color: #fff;
&--points {
color: #ffd700;
}
}
&__label {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.8);
margin-top: 4rpx;
}
&__buy {
margin-top: 8rpx;
padding: 2rpx 14rpx;
border-radius: 18rpx;
font-size: 20rpx;
color: #185dff;
background: #fff;
}
}
.points-buy {
padding: 36rpx 32rpx 48rpx;
background: #fff;
&__title {
font-size: 34rpx;
font-weight: 700;
color: #222;
text-align: center;
}
&__desc {
margin-top: 14rpx;
font-size: 24rpx;
color: #999;
text-align: center;
}
&__packages {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
margin-top: 36rpx;
}
&__package {
height: 148rpx;
border: 2rpx solid #edf0f5;
border-radius: 18rpx;
background: #f8faff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
&__package--active {
border-color: #185dff;
background: #edf3ff;
}
&__points {
font-size: 32rpx;
font-weight: 700;
color: #222;
}
&__money {
margin-top: 8rpx;
font-size: 26rpx;
color: #185dff;
font-weight: 600;
}
&__custom {
margin: 28rpx 0 36rpx;
padding: 22rpx 24rpx;
border-radius: 16rpx;
background: #f7f8fa;
display: flex;
align-items: center;
}
&__custom-label {
font-size: 26rpx;
color: #333;
margin-right: 24rpx;
}
&__input {
flex: 1;
height: 52rpx;
font-size: 28rpx;
text-align: right;
}
}
.user-vip-wrap {
width: 88%;
margin: -40rpx auto 0;
position: relative;
z-index: 10;
}
.assistant-entry {
width: 88%;
margin: 20rpx auto 0;
padding: 24rpx;
box-sizing: border-box;
border-radius: 8rpx;
background: #fff;
border: 1rpx solid #dbe6f5;
display: flex;
align-items: center;
gap: 18rpx;
position: relative;
z-index: 9;
&__icon {
width: 60rpx;
height: 60rpx;
border-radius: 8rpx;
background: #185dff;
color: #fff;
font-size: 24rpx;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
width: 132rpx;
height: 132rpx;
border-radius: 50%;
border: 2rpx solid #dbe5f6;
flex-shrink: 0;
}
&__body {
flex: 1;
min-width: 0;
margin-left: 28rpx;
}
&__title {
display: block;
font-size: 30rpx;
&__name-row,
&__meta {
display: flex;
align-items: center;
}
&__name-row {
gap: 14rpx;
}
&__name {
max-width: 360rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 38rpx;
font-weight: 700;
color: #111827;
}
&__desc {
display: block;
margin-top: 6rpx;
font-size: 23rpx;
&__level {
padding: 4rpx 14rpx;
border-radius: 20rpx;
color: #1468f5;
background: #edf4ff;
font-size: 24rpx;
line-height: 1.2;
}
&__meta {
gap: 14rpx;
margin-top: 10rpx;
color: #6b7280;
line-height: 1.4;
}
}
.chat-entry {
margin-top: 16rpx;
&__icon {
background: #111827;
font-size: 26rpx;
}
&__badge {
min-width: 34rpx;
height: 34rpx;
padding: 0 8rpx;
border-radius: 17rpx;
background: #ef4444;
&__verify {
color: #e67e22;
font-size: 22rpx;
}
&__edit {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
text {
color: #fff;
font-size: 20rpx;
line-height: 1;
}
gap: 6rpx;
margin-left: 18rpx;
color: #6b7280;
font-size: 26rpx;
white-space: nowrap;
}
}
.user-menu {
padding: 20rpx 24rpx 20rpx;
margin-top: 0;
padding-top: 20rpx;
&__group {
background: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
overflow: hidden;
}
.user-stats {
display: flex;
margin: 0 36rpx 24rpx;
padding: 28rpx 10rpx;
border-radius: 22rpx;
background: #fff;
box-shadow: 0 8rpx 28rpx rgba(23, 40, 75, 0.05);
&__item {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 28rpx 28rpx;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
&:not(:last-child)::after {
content: '';
position: absolute;
right: 0;
top: 12rpx;
width: 1rpx;
height: 62rpx;
background: #e5e7eb;
}
}
&__text {
flex: 1;
margin-left: 20rpx;
font-size: 28rpx;
color: #333;
&__num {
color: #111827;
font-size: 34rpx;
line-height: 1.2;
font-weight: 700;
&--points {
color: #1468f5;
}
}
&__tag {
font-size: 20rpx;
color: #f0ad4e;
background: #fff8ed;
padding: 4rpx 12rpx;
border-radius: 6rpx;
margin-right: 12rpx;
&__label {
margin-top: 8rpx;
color: #6b7280;
font-size: 24rpx;
}
}
.user-content {
padding: 0 36rpx;
}
.user-section,
.user-service-section {
margin-bottom: 24rpx;
padding: 24rpx 16rpx 18rpx;
border-radius: 22rpx;
background: #fff;
box-shadow: 0 8rpx 28rpx rgba(23, 40, 75, 0.04);
&__title {
padding: 24rpx 28rpx 16rpx;
font-size: 28rpx;
font-weight: 600;
color: #333;
border-bottom: 1rpx solid #f5f5f5;
display: block;
margin: 0 8rpx 20rpx;
color: #111827;
font-size: 32rpx;
line-height: 1.2;
font-weight: 700;
}
}
.user-benefits {
padding-bottom: 28rpx;
&__grid {
display: flex;
flex-wrap: wrap;
padding: 24rpx 0 8rpx;
gap: 18rpx;
}
}
.benefit-card {
flex: 1;
min-width: 0;
min-height: 178rpx;
display: flex;
align-items: center;
padding: 22rpx 18rpx;
border: 1rpx solid #c8dcff;
border-radius: 18rpx;
box-sizing: border-box;
&--points {
background: linear-gradient(135deg, #fafdff 0%, #f1f6ff 100%);
}
&__grid-item {
&--vip {
border-color: #f6d69f;
background: linear-gradient(135deg, #fffdf8 0%, #fff8eb 100%);
}
&__icon {
width: 72rpx;
height: 72rpx;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #dceaff;
&--vip {
background: linear-gradient(145deg, #ffc85a, #f0a62c);
}
}
&__body {
flex: 1;
min-width: 0;
margin-left: 16rpx;
}
&__title {
display: block;
color: #111827;
font-size: 30rpx;
font-weight: 600;
white-space: nowrap;
}
&__value-row {
display: flex;
align-items: baseline;
margin-top: 4rpx;
}
&__value {
color: #1468f5;
font-size: 34rpx;
font-weight: 700;
}
&__unit,
&__desc {
color: #6b7280;
font-size: 22rpx;
}
&__unit {
margin-left: 8rpx;
}
&__desc {
display: block;
margin-top: 7rpx;
white-space: nowrap;
}
&__desc--vip {
margin-top: 8rpx;
font-size: 24rpx;
color: #6b6257;
}
&__button {
display: inline-block;
margin-top: 10rpx;
padding: 6rpx 20rpx;
border-radius: 22rpx;
color: #fff;
background: #1468f5;
font-size: 22rpx;
}
}
.user-list {
overflow: hidden;
&__item {
min-height: 86rpx;
display: flex;
align-items: center;
padding: 0 8rpx;
border-bottom: 1rpx solid #edf0f3;
&:last-child {
border-bottom: 0;
}
}
&__icon {
width: 46rpx;
display: flex;
justify-content: center;
flex-shrink: 0;
}
&__image {
width: 42rpx;
height: 42rpx;
flex-shrink: 0;
}
&__label {
flex: 1;
min-width: 0;
margin-left: 18rpx;
color: #1f2937;
font-size: 28rpx;
}
&__badge {
min-width: 30rpx;
height: 30rpx;
margin-right: 14rpx;
padding: 0 8rpx;
border-radius: 15rpx;
color: #fff;
background: #f04444;
font-size: 18rpx;
line-height: 30rpx;
text-align: center;
}
}
.user-service-section {
padding-bottom: 24rpx;
}
.user-service-grid {
display: flex;
flex-wrap: wrap;
&__item {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 24rpx;
margin-bottom: 16rpx;
}
&__grid-icon {
width: 52rpx;
height: 52rpx;
&__icon {
width: 50rpx;
height: 50rpx;
}
&__grid-text {
font-size: 24rpx;
color: #333;
margin-top: 12rpx;
}
&__item-icon {
width: 48rpx;
height: 48rpx;
flex-shrink: 0;
&__text {
margin-top: 10rpx;
color: #374151;
font-size: 22rpx;
}
}
.user-banner {
margin: 0 24rpx 20rpx;
margin: 0 0 24rpx;
border-radius: 16rpx;
overflow: hidden;