Files
YwxAppThink/addon/wxchat/YwxMakeFriends/pages/my/profile.uvue
T

1402 lines
32 KiB
Plaintext

<template>
<scroll-view class="user-profile-page" direction="vertical">
<!-- 顶部背景和返回 -->
<view class="header-section">
<view class="header-bg">
<image class="bg-image" :src="userInfo.cover" mode="aspectFill"></image>
<view class="bg-overlay"></view>
</view>
<view class="header-content">
<view class="header-top">
<view class="back-btn" @click="goBack">
<uni-icons type="left" size="24" color="#fff"></uni-icons>
</view>
<view class="header-right">
<view class="header-icon" @click="onShare">
<uni-icons type="redo" size="20" color="#fff"></uni-icons>
</view>
<view class="header-icon" @click="onMore">
<uni-icons type="more" size="20" color="#fff"></uni-icons>
</view>
</view>
</view>
<!-- 用户头像和基本信息 -->
<view class="user-basic">
<view class="avatar-section">
<image class="user-avatar" :src="userInfo.avatar" mode="aspectFill"></image>
<view v-if="userInfo.online" class="online-badge"></view>
<view v-if="userInfo.vip" class="vip-badge">VIP{{ userInfo.vipLevel }}</view>
</view>
<view class="user-info">
<view class="name-section">
<text class="user-name">{{ userInfo.nickname }}</text>
<view class="gender-age">
<view class="gender-badge" :class="userInfo.gender">
<uni-icons :type="userInfo.gender == 'male' ? 'male' : 'female'" size="16"
:color="userInfo.gender == 'male' ? '#007AFF' : '#FF2D55'"></uni-icons>
</view>
<text class="user-age">{{ userInfo.age }}岁</text>
</view>
</view>
<view class="user-tags">
<view v-for="(tag, index) in userInfo.tags.slice(0, 3)" :key="index" class="tag">
<text class="tag-text">{{ tag }}</text>
</view>
<view v-if="userInfo.tags.length > 3" class="tag more" @click="showAllTags">
<text class="tag-text">+{{ userInfo.tags.length - 3 }}</text>
</view>
</view>
<view class="user-meta">
<view class="meta-item">
<uni-icons type="location" size="16" color="#fff"></uni-icons>
<text class="meta-text">{{ userInfo.location }}</text>
</view>
<view class="meta-item">
<uni-icons type="time" size="16" color="#fff"></uni-icons>
<text class="meta-text">{{ formatLastActive(userInfo.lastActive) }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 用户数据统计 -->
<view class="stats-section">
<view class="stats-grid">
<view class="stat-item" @click="navigateTo('followers')">
<text class="stat-value">{{ formatNumber(userInfo.followers) }}</text>
<text class="stat-label">粉丝</text>
</view>
<view class="stat-item" @click="navigateTo('following')">
<text class="stat-value">{{ formatNumber(userInfo.following) }}</text>
<text class="stat-label">关注</text>
</view>
<view class="stat-item" @click="navigateTo('moments')">
<text class="stat-value">{{ formatNumber(userInfo.moments) }}</text>
<text class="stat-label">动态</text>
</view>
<view class="stat-item" @click="navigateTo('gifts')">
<text class="stat-value">{{ formatNumber(userInfo.gifts) }}</text>
<text class="stat-label">礼物</text>
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-section">
<button class="action-btn follow-btn" :class="{ 'followed': isFollowing }" @click="toggleFollow">
<uni-icons :type="isFollowing ? 'checkmark' : 'plus'" size="20"
:color="isFollowing ? '#999' : '#fff'"></uni-icons>
<text>{{ isFollowing ? '已关注' : '关注' }}</text>
</button>
<button class="action-btn chat-btn" @click="startChat">
<uni-icons type="chat" size="20" color="#fff"></uni-icons>
<text>发消息</text>
</button>
<button class="action-btn gift-btn" @click="showGiftPanel">
<uni-icons type="gift" size="20" color="#fff"></uni-icons>
<text>礼物</text>
</button>
</view>
<!-- 内容区域 -->
<scroll-view class="content-section" direction="vertical" :show-scrollbar="false" >
<!-- 个人简介 -->
<view class="content-block" v-if="userInfo.introduction">
<view class="block-header">
<text class="block-title">个人简介</text>
</view>
<view class="block-content">
<text class="intro-text">{{ userInfo.introduction }}</text>
</view>
</view>
<!-- 详细信息 -->
<view class="content-block">
<view class="block-header">
<text class="block-title">详细信息</text>
</view>
<view class="detail-grid">
<view class="detail-item" v-if="userInfo.height">
<text class="detail-label">身高</text>
<text class="detail-value">{{ userInfo.height }}</text>
</view>
<view class="detail-item" v-if="userInfo.weight">
<text class="detail-label">体重</text>
<text class="detail-value">{{ userInfo.weight }}</text>
</view>
<view class="detail-item" v-if="userInfo.profession">
<text class="detail-label">职业</text>
<text class="detail-value">{{ userInfo.profession }}</text>
</view>
<view class="detail-item" v-if="userInfo.income">
<text class="detail-label">月收入</text>
<text class="detail-value">{{ userInfo.income }}</text>
</view>
<view class="detail-item" v-if="userInfo.education">
<text class="detail-label">学历</text>
<text class="detail-value">{{ userInfo.education }}</text>
</view>
<view class="detail-item" v-if="userInfo.constellation">
<text class="detail-label">星座</text>
<text class="detail-value">{{ userInfo.constellation }}</text>
</view>
<view class="detail-item" v-if="userInfo.relationship">
<text class="detail-label">感情状况</text>
<text class="detail-value">{{ userInfo.relationship }}</text>
</view>
</view>
</view>
<!-- 兴趣爱好 -->
<view class="content-block" v-if="userInfo.hobbies !=null && userInfo.hobbies.length > 0">
<view class="block-header">
<text class="block-title">兴趣爱好</text>
</view>
<view class="hobbies-grid">
<view v-for="(hobby, index) in userInfo.hobbies" :key="index" class="hobby-item">
<text class="hobby-text">{{ hobby }}</text>
</view>
</view>
</view>
<!-- 照片墙 -->
<view class="content-block" v-if="userInfo.photos !=null && userInfo.photos.length > 0">
<view class="block-header">
<text class="block-title">照片墙</text>
<text class="block-count">{{ userInfo.photos.length }}张</text>
</view>
<view class="photos-grid">
<view v-for="(photo, index) in userInfo.photos.slice(0, 6)" :key="index" class="photo-item"
@click="previewPhotos(index)">
<image class="photo" :src="photo" mode="aspectFill"></image>
<view v-if="index == 5 && userInfo.photos.length > 6" class="photo-more">
<text>+{{ userInfo.photos.length - 6 }}</text>
</view>
</view>
</view>
</view>
<!-- 最近动态 -->
<view class="content-block" v-if="recentMoments.length > 0">
<view class="block-header">
<text class="block-title">最近动态</text>
<view class="view-all" @click="navigateTo('moments')">
<text class="view-all-text">查看全部</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</view>
<view class="moments-list">
<view v-for="moment in recentMoments" :key="moment.id" class="moment-item"
@click="viewMoment(moment.id)">
<view class="moment-content">
<text class="moment-text">{{ moment.content }}</text>
<view v-if="moment.images !=null && moment.images.length > 0" class="moment-images">
<image v-for="(img, idx) in moment.images.slice(0, 3)" :key="idx" class="moment-image"
:src="img" mode="aspectFill"></image>
</view>
</view>
<view class="moment-footer">
<text class="moment-time">{{ formatTime(moment.time) }}</text>
<view class="moment-stats">
<view class="moment-stat">
<uni-icons type="heart" size="16" color="#999"></uni-icons>
<text class="stat-count">{{ moment.likes }}</text>
</view>
<view class="moment-stat">
<uni-icons type="chat" size="16" color="#999"></uni-icons>
<text class="stat-count">{{ moment.comments }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 相似推荐 -->
<view class="content-block" v-if="similarUsers.length > 0">
<view class="block-header">
<text class="block-title">相似推荐</text>
</view>
<scroll-view class="similar-users" direction="horizontal" :show-scrollbar="false">
<view v-for="user in similarUsers" :key="user.id" class="similar-user" @click="viewUser(user.id)">
<view class="similar-avatar">
<image class="avatar" :src="user.avatar" mode="aspectFill"></image>
<view v-if="user.online" class="online-dot"></view>
</view>
<text class="similar-name">{{ user.nickname }}</text>
<text class="similar-age">{{ user.age }}岁</text>
</view>
</scroll-view>
</view>
<!-- 底部空白 -->
<view class="bottom-space"></view>
</scroll-view>
<!-- 礼物面板 -->
<view v-if="giftPanelVisible" class="gift-panel" @click="hideGiftPanel">
<view class="panel-content" @click.stop>
<view class="panel-header">
<text class="panel-title">选择礼物</text>
<uni-icons type="close" size="20" color="#999" @click="hideGiftPanel"></uni-icons>
</view>
<scroll-view class="gift-list" scroll-y>
<view v-for="gift in gifts" :key="gift.id" class="gift-item"
:class="{ selected: selectedGiftId == gift.id }" @click="selectGift(gift)">
<image class="gift-image" :src="gift.image" mode="aspectFit"></image>
<text class="gift-name">{{ gift.name }}</text>
<view class="gift-price">
<uni-icons type="wallet" size="12" color="#FF9500"></uni-icons>
<text class="price-text">{{ gift.price }}</text>
</view>
</view>
</scroll-view>
<view class="panel-footer">
<view class="balance-info">
<text>余额: </text>
<text class="balance-amount">{{ userBalance }}</text>
<uni-icons type="wallet" size="16" color="#FF9500"></uni-icons>
</view>
<button class="send-gift-btn" :disabled="selectedGiftId !=null" @click="sendGift">
赠送
</button>
</view>
</view>
</view>
<!-- 标签弹窗 -->
<view v-if="showTagsModal" class="tags-modal" @click="hideTagsModal">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">所有标签</text>
<uni-icons type="close" size="20" color="#999" @click="hideTagsModal"></uni-icons>
</view>
<view class="tags-list">
<view v-for="(tag, index) in userInfo.tags" :key="index" class="modal-tag">
<text class="tag-text">{{ tag }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</template>
<script setup lang="uts">
import { ref, reactive, computed, onMounted } from 'vue'
// 用户信息接口
type UserInfo = {
id : number
nickname : string
avatar : string
cover : string
gender : 'male' | 'female'
age : number
vip : boolean
vipLevel : number
online : boolean
tags : string[]
location : string
lastActive : number
introduction : string
followers : number
following : number
moments : number
gifts : number
height ?: string
weight ?: string
profession ?: string
income ?: string
education ?: string
relationship ?: string
constellation ?: string
hobbies : string[]
photos : string[]
}
// 动态接口
type Moment = {
id : number
content : string
images : string[]
time : number
likes : number
comments : number
}
// 相似用户接口
type SimilarUser = {
id : number
nickname : string
avatar : string
age : number
online : boolean
}
// 礼物接口
type Gift = {
id : number
name : string
image : string
price : number
}
// 响应式数据
const isFollowing = ref(false)
const giftPanelVisible = ref(false)
const showTagsModal = ref(false)
const selectedGiftId = ref<number | null>(null)
const userBalance = ref(8888)
// 用户信息
const userInfo = reactive<UserInfo>({
id: 1001,
nickname: '小雨',
avatar: 'https://randomuser.me/api/portraits/women/44.jpg',
cover: 'https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80',
gender: 'female',
age: 25,
vip: true,
vipLevel: 3,
online: true,
tags: ['旅行', '美食', '摄影', '健身', '读书', '电影', '音乐', '舞蹈'],
location: '上海 · 浦东新区',
lastActive: Date.now() - 1000 * 60 * 30, // 30分钟前
introduction: '热爱生活的90后女生,喜欢旅行、摄影和美食。性格开朗,喜欢交朋友,希望在这里遇到有缘的你。',
followers: 1284,
following: 234,
moments: 56,
gifts: 128,
height: '165cm',
weight: '50kg',
profession: 'UI设计师',
income: '15-20k',
education: '本科',
relationship: '单身',
constellation: '白羊座',
hobbies: ['旅行', '摄影', '美食探店', '健身', '看电影', '听音乐', '阅读'],
photos: [
'https://images.unsplash.com/photo-1494790108755-2616c113a1c0?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1488426862026-3ee34a7d66df?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1529626455594-4ff0802cfb7e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
'https://images.unsplash.com/photo-1494790108755-2616c113a1c0?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80'
]
})
// 最近动态
const recentMoments = reactive<Moment[]>([
{
id: 1,
content: '今天天气真好,和朋友一起去了公园散步,心情美美哒~',
images: [
'https://images.unsplash.com/photo-1501854140801-50d01698950b?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80'
],
time: Date.now() - 1000 * 60 * 60 * 2, // 2小时前
likes: 24,
comments: 5
},
{
id: 2,
content: '分享一首最近很喜欢的歌,希望大家喜欢~',
images: [],
time: Date.now() - 1000 * 60 * 60 * 24, // 1天前
likes: 36,
comments: 8
}
])
// 相似用户
const similarUsers = reactive<SimilarUser[]>([
{ id: 1002, nickname: '小美', avatar: 'https://randomuser.me/api/portraits/women/68.jpg', age: 24, online: true },
{ id: 1003, nickname: '莉莉', avatar: 'https://randomuser.me/api/portraits/women/23.jpg', age: 26, online: false },
{ id: 1004, nickname: '静静', avatar: 'https://randomuser.me/api/portraits/women/65.jpg', age: 23, online: true },
{ id: 1005, nickname: '娜娜', avatar: 'https://randomuser.me/api/portraits/women/50.jpg', age: 27, online: true },
{ id: 1006, nickname: '小雅', avatar: 'https://randomuser.me/api/portraits/women/32.jpg', age: 25, online: false }
])
// 礼物列表
const gifts = reactive<Gift[]>([
{ id: 1, name: '玫瑰花', image: 'https://cdn-icons-png.flaticon.com/512/824/824239.png', price: 10 },
{ id: 2, name: '棒棒糖', image: 'https://cdn-icons-png.flaticon.com/512/3235/3235060.png', price: 20 },
{ id: 3, name: '爱心', image: 'https://cdn-icons-png.flaticon.com/512/535/535285.png', price: 50 },
{ id: 4, name: '跑车', image: 'https://cdn-icons-png.flaticon.com/512/744/744465.png', price: 100 },
{ id: 5, name: '钻戒', image: 'https://cdn-icons-png.flaticon.com/512/3135/3135715.png', price: 520 },
{ id: 6, name: '皇冠', image: 'https://cdn-icons-png.flaticon.com/512/201/201623.png', price: 1314 }
])
// 页面加载
onMounted(() => {
console.log('用户信息页面加载完成')
//checkFollowStatus()
})
// 返回上一页
const goBack = () => {
uni.navigateBack()
}
// 分享用户
const onShare = () => {
// uni.showShareMenu({
// withShareTicket: true,
// success: () => {
// console.log('分享用户:', userInfo.nickname)
// }
// })
}
// 更多操作
const onMore = () => {
uni.showActionSheet({
itemList: ['举报用户', '拉黑用户', '分享动态'],
success: (res) => {
switch (res.tapIndex) {
case 0:
// reportUser()
break
case 1:
//blockUser()
break
case 2:
onShare()
break
}
}
})
}
// 格式化最后活跃时间
const formatLastActive = (timestamp : number) : string => {
const now = Date.now()
const diff = now - timestamp
if (diff < 60000) { // 1分钟内
return '刚刚在线'
} else if (diff < 3600000) { // 1小时内
return Math.floor(diff / 60000) + '分钟前在线'
} else if (diff < 86400000) { // 1天内
return Math.floor(diff / 3600000) + '小时前在线'
} else if (diff < 7 * 86400000) { // 1周内
return Math.floor(diff / 86400000) + '天前在线'
} else {
return '一周前在线'
}
}
// 格式化数字
const formatNumber = (num : number) : string => {
if (num >= 10000) {
return (num / 10000).toFixed(1) + 'w'
} else if (num >= 1000) {
return (num / 1000).toFixed(1) + 'k'
}
return num.toString()
}
// 格式化时间
const formatTime = (timestamp : number) : string => {
const now = Date.now()
const diff = now - timestamp
if (diff < 60000) { // 1分钟内
return '刚刚'
} else if (diff < 3600000) { // 1小时内
return Math.floor(diff / 60000) + '分钟前'
} else if (diff < 86400000) { // 1天内
return Math.floor(diff / 3600000) + '小时前'
} else if (diff < 7 * 86400000) { // 1周内
return Math.floor(diff / 86400000) + '天前'
} else {
const date = new Date(timestamp)
return `${date.getMonth() + 1}月${date.getDate()}日`
}
}
// 检查关注状态
const checkFollowStatus = () => {
const followed = uni.getStorageSync(`follow_${userInfo.id}`)
isFollowing.value = followed != null
}
// 切换关注状态
const toggleFollow = () => {
isFollowing.value = !isFollowing.value
if (isFollowing.value) {
uni.setStorageSync(`follow_${userInfo.id}`, '1')
userInfo.followers++
uni.showToast({
title: '关注成功',
icon: 'success',
duration: 1500
})
} else {
uni.removeStorageSync(`follow_${userInfo.id}`)
userInfo.followers--
uni.showToast({
title: '已取消关注',
icon: 'none',
duration: 1500
})
}
}
// 开始聊天
const startChat = () => {
uni.navigateTo({
url: `/pages/chat/chat?userId=${userInfo.id}&userName=${userInfo.nickname}`
})
}
// 显示礼物面板
const showGiftPanel = () => {
giftPanelVisible.value = !giftPanelVisible.value
}
// 隐藏礼物面板
const hideGiftPanel = () => {
giftPanelVisible.value = !giftPanelVisible.value
selectedGiftId.value = null
}
// 选择礼物
const selectGift = (gift : Gift) => {
selectedGiftId.value = gift.id
}
// 发送礼物
const sendGift = () => {
if (selectedGiftId.value == null) return
const gift = gifts.find(g => g.id == selectedGiftId.value)
if (gift == null) return
if (userBalance.value < gift.price) {
uni.showModal({
title: '余额不足',
content: '您的余额不足,请先充值',
confirmText: '去充值',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/recharge/recharge'
})
}
}
})
return
}
// 扣款
userBalance.value -= gift.price
userInfo.gifts++
uni.showToast({
title: `赠送${gift.name}成功`,
icon: 'success',
duration: 1500
})
hideGiftPanel()
}
// 显示所有标签
const showAllTags = () => {
showTagsModal.value = true
}
// 隐藏标签弹窗
const hideTagsModal = () => {
showTagsModal.value = false
}
// 预览照片
const previewPhotos = (index : number) => {
uni.previewImage({
current: index,
urls: userInfo.photos
})
}
// 查看动态
const viewMoment = (momentId : number) => {
uni.navigateTo({
url: `/pages/moment-detail/moment-detail?id=${momentId}`
})
}
// 查看用户
const viewUser = (userId : number) => {
uni.navigateTo({
url: `/pages/user-profile/user-profile?id=${userId}`
})
}
// 页面跳转
const navigateTo = (page : string) => {
let path : string | null = null
switch (page) {
case 'followers':
path = `/pages/followers/followers?userId=${userInfo.id}`
break;
case 'following':
path = `/pages/followers/following?userId=${userInfo.id}`
break;
case 'moments':
path = `/pages/moments/moments?userId=${userInfo.id}`
break;
case 'gifts':
path = `/pages/gifts/gifts?userId=${userInfo.id}`
break;
}
if (path != null) {
uni.navigateTo({
url: path
})
}
}
// 举报用户
const reportUser = () => {
uni.navigateTo({
url: `/pages/report/report?userId=${userInfo.id}&type=user`
})
}
// 拉黑用户
const blockUser = () => {
uni.showModal({
title: '拉黑用户',
content: '拉黑后将不再接收该用户的消息,是否确认?',
confirmText: '确认拉黑',
cancelText: '取消',
confirmColor: '#FF3B30',
success: (res) => {
if (res.confirm) {
uni.showToast({
title: '已拉黑用户',
icon: 'success',
duration: 1500
})
}
}
})
}
</script>
<style>
.user-profile-page {
display: flex;
flex-direction: column;
height: 100%;
background-color: #f5f5f5;
position: relative;
overflow: hidden;
}
/* 头部区域 */
.header-section {
position: relative;
height: 400rpx;
overflow: hidden;
}
.header-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.bg-image {
width: 100%;
height: 100%;
background-color: #e0e0e0;
}
.bg-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.5));
}
.header-content {
position: relative;
z-index: 1;
height: 100%;
display: flex;
flex-direction: column;
padding: 40rpx 30rpx 0;
}
.header-top {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.back-btn {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
}
.header-right {
display: flex;
}
.header-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
}
/* 用户基本信息 */
.user-basic {
display: flex;
align-items: flex-start;
margin-top: auto;
margin-bottom: 30rpx;
}
.avatar-section {
position: relative;
margin-right: 30rpx;
}
.user-avatar {
width: 140rpx;
height: 140rpx;
border-radius: 50%;
border: 6rpx solid rgba(255, 255, 255, 0.3);
background-color: #f0f0f0;
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.2);
}
.online-badge {
position: absolute;
top: 10rpx;
right: 10rpx;
width: 24rpx;
height: 24rpx;
background-color: #4CD964;
border-radius: 50%;
border: 4rpx solid #fff;
}
.vip-badge {
position: absolute;
bottom: 0;
right: 0;
padding: 6rpx 15rpx;
background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
color: #fff;
font-size: 20rpx;
font-weight: bold;
border-radius: 20rpx;
border: 4rpx solid #fff;
}
.user-info {
flex: 1;
display: flex;
}
.name-section {
display: flex;
align-items: center;
flex-flow: row nowrap;
margin-bottom: 15rpx;
flex-wrap: wrap;
}
.user-name {
font-size: 40rpx;
font-weight: bold;
color: #fff;
margin-right: 20rpx;
text-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.3);
}
.gender-age {
display: flex;
align-items: center;
flex-flow: row nowrap;
}
.gender-badge {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
background-color: rgba(255, 255, 255, 0.2);
}
.user-age {
font-size: 28rpx;
color: #fff;
text-shadow: 0 2rpx 5rpx rgba(0, 0, 0, 0.3);
}
.user-tags {
display: flex;
flex-flow: row wrap;
margin-bottom: 20rpx;
}
.tag {
padding: 8rpx 20rpx;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 20rpx;
}
.tag.more {
background-color: rgba(255, 255, 255, 0.1);
}
.tag-text {
font-size: 24rpx;
color: #fff;
font-weight: 500;
}
.user-meta {
display: flex;
flex-flow: row nowrap;
}
.meta-item {
display: flex;
flex-flow: row nowrap;
align-items: center;
}
.meta-text {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.9);
text-shadow: 0 2rpx 5rpx rgba(0, 0, 0, 0.3);
}
/* 统计数据 */
.stats-section {
background-color: #fff;
padding: 30rpx 0;
box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.05);
}
.stats-grid {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: center;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.stat-value {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.stat-label {
font-size: 24rpx;
color: #999;
}
/* 操作按钮 */
.action-section {
position: fixed;
bottom: 0;
width:100%;
display: flex;
padding: 5rpx;
flex-flow: row nowrap;
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.action-btn {
flex: 1;
display: flex;
align-items: center;
flex-flow: row nowrap;
justify-content: center;
padding: 3rpx 0;
border-radius: 40rpx;
font-size: 24rpx;
font-weight: 500;
border: none;
transition: all 0.3s ease;
}
.action-btn:active {
transform: scale(0.95);
}
.follow-btn {
background-color: #f8f8f8;
color: #333;
}
.follow-btn.followed {
background-color: #f0f0f0;
color: #999;
}
.chat-btn {
background: linear-gradient(135deg, #FF6B6B 0%, #FF8E53 100%);
color: #fff;
}
.gift-btn {
background: linear-gradient(135deg, #FF9500 0%, #FFCC00 100%);
color: #fff;
}
/* 内容区域 */
.content-section {
flex: 1;
padding: 0 30rpx 30rpx;
}
.content-block {
background-color: #fff;
border-radius: 20rpx;
padding: 30rpx;
margin-top: 20rpx;
box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.05);
}
.block-header {
display: flex;
justify-content: space-between;
flex-flow: row;
align-items: center;
margin-bottom: 20rpx;
}
.block-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.block-count {
font-size: 24rpx;
color: #999;
}
.view-all {
display: flex;
flex-flow: row;
align-items: center;
}
.view-all-text {
font-size: 24rpx;
color: #999;
}
.block-content {
padding: 10rpx 0;
}
.intro-text {
font-size: 28rpx;
color: #333;
line-height: 1.6;
}
/* 详细信息网格 */
.detail-grid {
display: flex;
flex-flow: row wrap;
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
/* .detail-item:nth-last-child(-n+2) {
border-bottom: none;
} */
.detail-label {
font-size: 28rpx;
color: #666;
}
.detail-value {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
/* 兴趣爱好 */
.hobbies-grid {
display: flex;
flex-flow:row wrap;
}
.hobby-item {
padding: 12rpx 25rpx;
background-color: #f8f8f8;
border-radius: 30rpx;
}
.hobby-text {
font-size: 26rpx;
color: #333;
}
/* 照片墙 */
.photos-grid {
}
.photo-item {
position: relative;
border-radius: 10rpx;
overflow: hidden;
background-color: #f0f0f0;
}
.photo {
width: 100%;
height: 100%;
}
.photo-more {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.photo-more-text {
font-size: 32rpx;
color: #fff;
font-weight: bold;
}
/* 动态列表 */
.moments-list {
display: flex;
flex-direction: column;
}
.moment-item {
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.moment-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.moment-content {
margin-bottom: 20rpx;
}
.moment-text {
font-size: 28rpx;
color: #333;
line-height: 1.5;
margin-bottom: 15rpx;
overflow: hidden;
}
.moment-images {
display: flex;
}
.moment-image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
background-color: #f0f0f0;
}
.moment-footer {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.moment-time {
font-size: 24rpx;
color: #999;
}
.moment-stats {
display: flex;
flex-flow: row nowrap;
}
.moment-stat {
display: flex;
flex-flow: row nowrap;
align-items: center;
}
.stat-count {
font-size: 24rpx;
color: #999;
}
/* 相似用户 */
.similar-users {
display: flex;
flex-flow: row nowrap;
padding: 10rpx 0;
}
.similar-user {
display: flex;
flex-direction: column;
align-items: center;
width: 150rpx;
flex-shrink: 0;
}
.similar-avatar {
position: relative;
margin-bottom: 15rpx;
}
.similar-avatar .avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background-color: #f0f0f0;
border: 4rpx solid #fff;
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.1);
}
.online-dot {
position: absolute;
top: 0;
right: 0;
width: 20rpx;
height: 20rpx;
background-color: #4CD964;
border-radius: 50%;
border: 3rpx solid #fff;
}
.similar-name {
font-size: 24rpx;
color: #333;
font-weight: 500;
margin-bottom: 5rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.similar-age {
font-size: 22rpx;
color: #999;
}
/* 底部空白 */
.bottom-space {
height: 100rpx;
}
/* 礼物面板 */
.gift-panel,
.tags-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 1000;
}
.panel-content {
width: 100%;
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
display: flex;
flex-direction: column;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 40rpx 30rpx 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.panel-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.gift-list {
flex: 1;
padding: 30rpx;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
.gift-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx 0;
border-radius: 20rpx;
border: 2rpx solid #f0f0f0;
transition: all 0.3s ease;
}
.gift-item.selected {
border-color: #FF6B6B;
background-color: #fff5f5;
}
.gift-image {
width: 80rpx;
height: 80rpx;
margin-bottom: 15rpx;
}
.gift-name {
font-size: 24rpx;
color: #333;
margin-bottom: 10rpx;
text-align: center;
}
.gift-price {
display: flex;
align-items: center;
}
.price-text {
font-size: 20rpx;
color: #FF9500;
font-weight: bold;
}
.panel-footer {
height: 120rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
border-top: 1rpx solid #eee;
}
.balance-info {
display: flex;
align-items: center;
font-size: 28rpx;
color: #333;
}
.balance-amount {
font-weight: bold;
color: #FF9500;
}
.send-gift-btn {
background: linear-gradient(135deg, #FF6B6B 0%, #FF8E53 100%);
color: #fff;
padding: 20rpx 50rpx;
border-radius: 40rpx;
font-size: 28rpx;
font-weight: bold;
border: none;
}
.send-gift-btn:disabled {
background: #ccc;
color: #999;
}
/* 标签弹窗 */
.tags-modal .modal-content {
width: 100%;
max-width: 600rpx;
background-color: #fff;
border-radius: 30rpx;
overflow: hidden;
margin: 0 30rpx 100rpx;
}
.tags-list {
padding: 30rpx;
display: flex;
flex-wrap: wrap;
max-height: 400rpx;
}
.modal-tag {
padding: 12rpx 25rpx;
background-color: #f8f8f8;
border-radius: 30rpx;
}
.modal-tag .tag-text {
font-size: 26rpx;
color: #333;
}
</style>