pet/pages/profile/profile.vue

1346 lines
32 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="profile-container page-container-with-bg">
<!-- 用户信息卡片 -->
<view class="user-info-card" @click="handleWxLogin">
<view class="user-avatar-section">
<view class="avatar-wrapper">
<u-avatar
:src="userInfo.avatarUrl || ''"
:text="userInfo.nickName ? userInfo.nickName.charAt(0) : '👤'"
size="100"
shape="circle"
bg-color="linear-gradient(135deg, #FF8A80, #FFB6C1)"
color="white"
font-size="40"
></u-avatar>
<view class="online-status" v-if="userInfo.nickName">
<view class="status-dot"></view>
</view>
</view>
</view>
<view class="user-info-section">
<view class="user-name">{{ userInfo.nickName || '点击登录' }}</view>
<view class="user-status">{{ userInfo.nickName ? '已登录' : '未登录' }}</view>
<view class="login-days" v-if="userInfo.nickName">已使用 {{ loginDays }} </view>
</view>
<view class="user-action">
<!-- 登录按钮 -->
<button
v-if="!userInfo.nickName"
class="login-btn"
>
<text class="action-icon">👋</text>
</button>
<!-- 已登录状态 -->
<view v-else @click="handleUserAction" class="logged-in-action">
<text class="action-icon">⚙️</text>
</view>
</view>
</view>
<!-- 宠物概览统计卡片 -->
<view class="stats-card">
<view class="stats-header">
<text class="stats-title">我的宠物</text>
<view class="stats-action" @click="navigateTo('/pages/pets/pets')">
<text class="action-text">管理</text>
<text class="action-arrow">→</text>
</view>
</view>
<view class="stats-grid">
<view class="stat-item" @click="navigateTo('/pages/pets/pets')">
<view class="stat-number">{{ petStats.petCount }}</view>
<view class="stat-label">宠物</view>
<view class="stat-icon">🐱</view>
</view>
<view class="stat-item" @click="navigateTo('/pages/pets/pet-records')">
<view class="stat-number">{{ petStats.recordCount }}</view>
<view class="stat-label">记录</view>
<view class="stat-icon">📝</view>
</view>
<view class="stat-item" @click="showReminders">
<view class="stat-number">{{ petStats.reminderCount }}</view>
<view class="stat-label">提醒</view>
<view class="stat-icon">⏰</view>
</view>
</view>
</view>
<!-- 家庭管理卡片 -->
<view class="family-card">
<view class="card-header">
<view class="header-left">
<text class="card-icon">👨‍👩‍👧‍👦</text>
<text class="card-title">我的家庭</text>
</view>
<view class="header-right" @click="navigateToFamily">
<text class="member-count">{{ familyStats.memberCount }}人</text>
<text class="action-arrow">→</text>
</view>
</view>
<view class="family-actions">
<view class="action-btn" @click="inviteFamily">
<text class="btn-icon"></text>
<text class="btn-text">邀请成员</text>
</view>
<view class="action-btn" @click="navigateToFamily">
<text class="btn-icon">👥</text>
<text class="btn-text">家庭设置</text>
</view>
</view>
</view>
<!-- 领养管理卡片 -->
<view class="adoption-card">
<view class="card-header">
<view class="header-left">
<text class="card-icon">🏠</text>
<text class="card-title">领养管理</text>
</view>
<view class="header-right" @click="navigateTo('/pages/adoption/my-adoption')">
<text class="action-arrow">→</text>
</view>
</view>
<view class="adoption-stats">
<view class="adoption-item" @click="navigateTo('/pages/adoption/my-published')">
<view class="adoption-number">{{ adoptionStats.publishedCount }}</view>
<view class="adoption-label">已发布</view>
</view>
<view class="adoption-item" @click="navigateTo('/pages/adoption/my-applications')">
<view class="adoption-number">{{ adoptionStats.applicationCount }}</view>
<view class="adoption-label">已申请</view>
</view>
</view>
<view class="publish-btn" @click="navigateTo('/pages/adoption/publish')">
<text class="publish-icon">📝</text>
<text class="publish-text">发布领养信息</text>
</view>
</view>
<!-- 设置功能卡片 -->
<view class="settings-card">
<view class="settings-list">
<view class="setting-item" @click="navigateTo('/pages/profile/notifications')">
<view class="setting-left">
<text class="setting-icon">🔔</text>
<text class="setting-text">消息通知</text>
</view>
<view class="setting-right">
<text class="setting-badge" v-if="notificationCount > 0">{{ notificationCount }}</text>
<text class="setting-arrow">→</text>
</view>
</view>
<view class="setting-item" @click="navigateTo('/pages/profile/privacy')">
<view class="setting-left">
<text class="setting-icon">🔒</text>
<text class="setting-text">隐私设置</text>
</view>
<view class="setting-right">
<text class="setting-arrow">→</text>
</view>
</view>
<view class="setting-item" @click="navigateTo('/pages/profile/feedback')">
<view class="setting-left">
<text class="setting-icon">💬</text>
<text class="setting-text">意见反馈</text>
</view>
<view class="setting-right">
<text class="setting-arrow">→</text>
</view>
</view>
<view class="setting-item" @click="navigateTo('/pages/profile/about')">
<view class="setting-left">
<text class="setting-icon"></text>
<text class="setting-text">关于我们</text>
</view>
<view class="setting-right">
<text class="setting-arrow">→</text>
</view>
</view>
</view>
</view>
<!-- 手机号授权按钮 -->
<view v-if="showPhoneAuthBtn" class="phone-auth-modal">
<view class="auth-overlay" @click="cancelPhoneAuth"></view>
<view class="auth-content">
<view class="auth-title">手机号授权</view>
<view class="auth-desc">为了更好的服务体验,需要获取您的手机号</view>
<view class="auth-buttons">
<button
class="auth-btn primary"
open-type="getPhoneNumber"
@getphonenumber="handlePhoneAuth"
>
授权手机号
</button>
<button
class="auth-btn secondary"
@click="cancelPhoneAuth"
>
跳过
</button>
</view>
</view>
</view>
</view>
</template>
<script>
import {reactive, ref, onMounted, computed} from 'vue'
import WechatAuth from '@/utils/wechat-auth.js'
import {wxLogin, wxLoginWithPhone, bindPhone} from '@/http/api/profile.js'
export default {
name: 'ProfilePage',
setup() {
// 响应式数据
const userInfo = ref({
nickName: '',
avatarUrl: ''
})
const loginDays = ref(0)
const notificationCount = ref(3)
const showPhoneAuthBtn = ref(false)
const currentLoginCode = ref('')
// 宠物统计数据
const petStats = reactive({
petCount: 0,
recordCount: 0,
reminderCount: 0
})
// 家庭统计数据
const familyStats = reactive({
memberCount: 1
})
// 领养统计数据
const adoptionStats = reactive({
publishedCount: 0,
applicationCount: 0
})
// 方法定义
const initPage = () => {
checkLogin()
loadUserStats()
}
const checkLogin = () => {
// 检查是否已登录
if (WechatAuth.isLoggedIn()) {
const savedUserInfo = WechatAuth.getUserInfoFromStorage()
if (savedUserInfo) {
userInfo.value = savedUserInfo
calculateLoginDays()
}
}
}
const calculateLoginDays = () => {
const loginDate = uni.getStorageSync('loginDate')
if (loginDate) {
const now = new Date()
const login = new Date(loginDate)
const diffTime = Math.abs(now - login)
loginDays.value = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
}
}
const loadUserStats = () => {
try {
// 加载宠物统计数据
const pets = uni.getStorageSync('pets') || []
petStats.petCount = pets.length
// 加载记录统计数据 - 统计所有宠物的记录
let totalRecords = 0
pets.forEach(pet => {
const petRecords = uni.getStorageSync(`petRecords_${pet.id}`) || []
totalRecords += petRecords.length
})
petStats.recordCount = totalRecords
// 计算待处理提醒数量
const today = new Date()
const reminders = uni.getStorageSync('reminders') || []
const pendingReminders = reminders.filter(reminder => {
const reminderDate = new Date(reminder.date)
return reminderDate <= today && !reminder.completed
})
petStats.reminderCount = pendingReminders.length
// 加载家庭数据
const familyData = uni.getStorageSync('familyData') || {members: []}
familyStats.memberCount = familyData.members.length || 1
// 加载领养数据
const adoptionData = uni.getStorageSync('adoptionData') || {
published: [],
applications: []
}
adoptionStats.publishedCount = adoptionData.published.length
adoptionStats.applicationCount = adoptionData.applications.length
// 加载通知数量
const notifications = uni.getStorageSync('notifications') || []
const unreadNotifications = notifications.filter(n => !n.read)
notificationCount.value = unreadNotifications.length
} catch (error) {
console.error('加载用户统计数据失败:', error)
// 设置默认值
petStats.petCount = 0
petStats.recordCount = 0
petStats.reminderCount = 0
familyStats.memberCount = 1
adoptionStats.publishedCount = 0
adoptionStats.applicationCount = 0
}
}
const handleUserAction = () => {
if (userInfo.value.nickName) {
// 已登录,跳转到个人信息设置
navigateTo('/pages/profile/user-info')
}
}
const handleWxLogin = () => {
wx.login({
success: (loginRes) => {
if (loginRes.code) {
console.log(loginRes)
// 3. 调用后端登录接口
handleWxLoginSuccess(loginRes.code, userInfo.value)
} else {
handleLoginError(new Error('获取微信授权码失败'))
}
},
fail: (error) => {
handleLoginError(new Error('微信登录失败: ' + (error.errMsg || '未知错误')))
}
})
// 微信登录按钮点击事件
// performWxLogin()
}
const handleUserInfo = (e) => {
// 处理用户信息授权回调
console.log('用户信息授权结果:', e.detail)
}
const performWxLogin = async () => {
try {
console.log(999)
// 1. 先获取用户信息
wx.getUserProfile({
desc: "获取用户头像昵称",
success: (res) => {
// 更新用户信息
userInfo.value = {
...res.userInfo,
avatarUrl: res.userInfo.avatarUrl || '',
nickName: res.userInfo.nickName || "未命名用户",
}
console.log("111")
// 2. 获取微信登录码
wx.login({
success: (loginRes) => {
if (loginRes.code) {
// 3. 调用后端登录接口
handleWxLoginSuccess(loginRes.code, userInfo.value)
} else {
handleLoginError(new Error('获取微信授权码失败'))
}
},
fail: (error) => {
handleLoginError(new Error('微信登录失败: ' + (error.errMsg || '未知错误')))
}
})
},
fail: (error) => {
console.log(error)
handleLoginError(new Error('获取用户信息失败: ' + (error.errMsg || '未知错误')))
}
})
} catch (error) {
console.log(error)
handleLoginError(error)
}
}
const handleWxLoginSuccess = async (code, wxUserInfo) => {
try {
uni.showLoading({
title: '正在登录...',
mask: true
})
// 调用后端登录接口
const response = await wxLogin({
code: code,
userInfo: wxUserInfo
})
// 处理登录成功
handleLoginSuccess(response)
} catch (error) {
handleLoginError(error)
}
}
const showPhoneAuthModal = (code) => {
// 保存当前登录码
currentLoginCode.value = code
// 显示手机号授权按钮
showPhoneAuthBtn.value = true
// 提示用户点击授权按钮
uni.showToast({
title: '请点击授权按钮',
icon: 'none',
duration: 2000
})
}
const doBasicLogin = async (code) => {
try {
uni.showLoading({
title: '正在登录...',
mask: true
})
// 调用后端登录接口
const response = await wxLogin({code})
// 处理登录成功
handleLoginSuccess(response)
} catch (error) {
handleLoginError(error)
}
}
const doWxLoginWithPhone = async () => {
try {
uni.showLoading({
title: '正在登录...',
mask: true
})
// 1. 获取微信授权码
const code = await WechatAuth.getWxCode()
// 2. 显示手机号授权提示
uni.hideLoading()
uni.showModal({
title: '手机号授权',
content: '为了更好的服务体验,需要获取您的手机号',
confirmText: '授权',
cancelText: '跳过',
success: (res) => {
if (res.confirm) {
// 用户同意授权,显示手机号授权页面
showPhoneAuthPage(code)
} else {
// 用户跳过,使用基础登录
doWxLoginOnly(code)
}
}
})
} catch (error) {
handleLoginError(error)
}
}
const showPhoneAuthPage = (code) => {
// 跳转到手机号授权页面
uni.navigateTo({
url: `/pages/profile/phone-auth?code=${code}`,
fail: () => {
// 如果页面不存在,使用基础登录
doWxLoginOnly(code)
}
})
}
const doWxLoginOnly = async (code) => {
try {
uni.showLoading({
title: '正在登录...',
mask: true
})
const response = await wxLogin({code})
handleLoginSuccess(response)
} catch (error) {
handleLoginError(error)
}
}
const handleLoginSuccess = (response) => {
if (response && response.token) {
WechatAuth.saveLoginInfo(
response.token,
response.refreshToken,
response.userInfo || userInfo.value
)
// 如果后端返回了用户信息,使用后端的,否则使用本地的
if (response.userInfo) {
userInfo.value = response.userInfo
}
// 保存登录日期
uni.setStorageSync('loginDate', new Date().toISOString())
calculateLoginDays()
// 刷新统计数据
loadUserStats()
uni.hideLoading()
// 询问是否获取手机号
uni.showModal({
title: '完善信息',
content: '是否授权获取手机号,以便为您提供更好的服务?',
confirmText: '授权',
cancelText: '跳过',
success: (res) => {
if (res.confirm) {
// 显示手机号授权
showPhoneAuthBtn.value = true
} else {
// 跳过手机号授权
uni.showToast({
title: '登录成功',
icon: 'success'
})
}
}
})
} else {
throw new Error('登录响应数据异常')
}
}
const handlePhoneAuth = async (e) => {
// 隐藏授权按钮
showPhoneAuthBtn.value = false
try {
uni.showLoading({
title: '正在绑定手机号...',
mask: true
})
// 获取手机号授权结果
const phoneResult = WechatAuth.getPhoneNumber(e)
if (phoneResult.success) {
// 手机号授权成功,调用绑定手机号接口
const response = await bindPhone({
encryptedData: phoneResult.encryptedData,
iv: phoneResult.iv,
cloudID: phoneResult.cloudID
})
uni.hideLoading()
uni.showToast({
title: '手机号绑定成功',
icon: 'success'
})
} else {
// 手机号授权失败
uni.hideLoading()
uni.showToast({
title: '手机号授权失败',
icon: 'none'
})
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: '绑定失败',
icon: 'none'
})
}
}
const cancelPhoneAuth = () => {
// 隐藏授权按钮
showPhoneAuthBtn.value = false
// 使用基础登录
doBasicLogin(currentLoginCode.value)
}
const handleLoginError = (error) => {
uni.hideLoading()
let errorMessage = '登录失败'
if (error.message.includes('用户拒绝授权')) {
errorMessage = '需要授权才能使用完整功能'
} else if (error.message.includes('网络')) {
errorMessage = '网络连接失败,请检查网络'
} else if (error.message.includes('code')) {
errorMessage = '微信授权失败,请重试'
}
uni.showModal({
title: '登录提示',
content: errorMessage,
showCancel: false,
confirmText: '确定'
})
}
const navigateTo = (url) => {
uni.navigateTo({
url,
fail: () => {
uni.showToast({
title: '页面开发中',
icon: 'none'
})
}
})
}
const navigateToFamily = () => {
navigateTo('/pages/profile/family')
}
const inviteFamily = () => {
uni.showModal({
title: '邀请家庭成员',
content: '通过微信分享邀请码邀请家人加入',
confirmText: '分享邀请',
success: (res) => {
if (res.confirm) {
uni.showToast({
title: '功能开发中',
icon: 'none'
})
}
}
})
}
const showReminders = () => {
if (petStats.reminderCount > 0) {
navigateTo('/pages/profile/reminders')
} else {
uni.showToast({
title: '暂无提醒事项',
icon: 'none'
})
}
}
// 刷新页面数据
const refreshData = () => {
loadUserStats()
}
// 页面显示时刷新数据
const onShow = () => {
refreshData()
}
// 下拉刷新
const onPullDownRefresh = () => {
refreshData()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000)
}
// 格式化数字显示
const formatNumber = (num) => {
if (num >= 1000) {
return (num / 1000).toFixed(1) + 'k'
}
return num.toString()
}
// 检查是否有新功能提示
const checkNewFeatures = () => {
const lastVersion = uni.getStorageSync('lastAppVersion') || '1.0.0'
const currentVersion = '1.1.0' // 当前版本
if (lastVersion !== currentVersion) {
// 显示新功能提示
setTimeout(() => {
uni.showModal({
title: '发现新功能',
content: '新增了家庭共享和领养管理功能,快来体验吧!',
confirmText: '去看看',
success: (res) => {
if (res.confirm) {
uni.setStorageSync('lastAppVersion', currentVersion)
}
}
})
}, 2000)
}
}
// 初始化时检查新功能
onMounted(() => {
initPage()
// checkNewFeatures()
})
return {
userInfo,
loginDays,
notificationCount,
petStats,
familyStats,
adoptionStats,
showPhoneAuthBtn,
handleUserAction,
handleWxLogin,
handleUserInfo,
handlePhoneAuth,
cancelPhoneAuth,
navigateTo,
navigateToFamily,
inviteFamily,
showReminders,
refreshData,
formatNumber,
onShow,
onPullDownRefresh
}
},
// 页面生命周期
onShow() {
this.onShow()
},
onPullDownRefresh() {
this.onPullDownRefresh()
}
}
</script>
<style lang="scss" scoped>
.profile-container {
padding-bottom: 40rpx;
}
/* 用户信息卡片 */
.user-info-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
margin: 0 30rpx 24rpx 30rpx;
border-radius: 24rpx;
padding: 32rpx;
display: flex;
align-items: center;
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
border: 1rpx solid rgba(255, 255, 255, 0.3);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
.user-avatar-section {
.avatar-wrapper {
position: relative;
.online-status {
position: absolute;
bottom: 8rpx;
right: 8rpx;
width: 24rpx;
height: 24rpx;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.status-dot {
width: 16rpx;
height: 16rpx;
background: #4CAF50;
border-radius: 50%;
}
}
}
}
.user-info-section {
flex: 1;
margin-left: 24rpx;
.user-name {
font-size: 36rpx;
font-weight: 600;
color: #333333;
margin-bottom: 8rpx;
}
.user-status {
font-size: 24rpx;
color: #FF8A80;
margin-bottom: 4rpx;
}
.login-days {
font-size: 22rpx;
color: #999999;
}
}
.user-action {
.action-icon {
font-size: 32rpx;
}
}
}
/* 宠物概览统计卡片 */
.stats-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
margin: 0 30rpx 24rpx 30rpx;
border-radius: 24rpx;
padding: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
border: 1rpx solid rgba(255, 255, 255, 0.3);
.stats-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.stats-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
.stats-action {
display: flex;
align-items: center;
.action-text {
font-size: 24rpx;
color: #FF8A80;
margin-right: 8rpx;
}
.action-arrow {
font-size: 24rpx;
color: #FF8A80;
}
}
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24rpx;
.stat-item {
text-align: center;
padding: 24rpx 16rpx;
border-radius: 16rpx;
background: rgba(255, 138, 128, 0.05);
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: rgba(255, 138, 128, 0.1);
}
.stat-number {
font-size: 40rpx;
font-weight: 700;
color: #FF8A80;
margin-bottom: 8rpx;
}
.stat-label {
font-size: 22rpx;
color: #666666;
margin-bottom: 8rpx;
}
.stat-icon {
font-size: 28rpx;
}
}
}
}
/* 家庭管理卡片 */
.family-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
margin: 0 30rpx 24rpx 30rpx;
border-radius: 24rpx;
padding: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
border: 1rpx solid rgba(255, 255, 255, 0.3);
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.header-left {
display: flex;
align-items: center;
.card-icon {
font-size: 32rpx;
margin-right: 12rpx;
}
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
}
.header-right {
display: flex;
align-items: center;
.member-count {
font-size: 24rpx;
color: #FF8A80;
margin-right: 8rpx;
}
.action-arrow {
font-size: 24rpx;
color: #FF8A80;
}
}
}
.family-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16rpx;
.action-btn {
display: flex;
flex-direction: column;
align-items: center;
padding: 24rpx 16rpx;
border-radius: 16rpx;
background: rgba(255, 138, 128, 0.05);
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: rgba(255, 138, 128, 0.1);
}
.btn-icon {
font-size: 32rpx;
margin-bottom: 8rpx;
}
.btn-text {
font-size: 22rpx;
color: #666666;
}
}
}
}
/* 领养管理卡片 */
.adoption-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
margin: 0 30rpx 24rpx 30rpx;
border-radius: 24rpx;
padding: 32rpx;
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
border: 1rpx solid rgba(255, 255, 255, 0.3);
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.header-left {
display: flex;
align-items: center;
.card-icon {
font-size: 32rpx;
margin-right: 12rpx;
}
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
}
.header-right {
.action-arrow {
font-size: 24rpx;
color: #FF8A80;
}
}
}
.adoption-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16rpx;
margin-bottom: 24rpx;
.adoption-item {
text-align: center;
padding: 20rpx 16rpx;
border-radius: 16rpx;
background: rgba(255, 138, 128, 0.05);
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: rgba(255, 138, 128, 0.1);
}
.adoption-number {
font-size: 36rpx;
font-weight: 700;
color: #FF8A80;
margin-bottom: 8rpx;
}
.adoption-label {
font-size: 22rpx;
color: #666666;
}
}
}
.publish-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
border-radius: 16rpx;
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
.publish-icon {
font-size: 24rpx;
margin-right: 8rpx;
}
.publish-text {
font-size: 26rpx;
color: white;
font-weight: 500;
}
}
}
/* 设置功能卡片 */
.settings-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
margin: 0 30rpx 24rpx 30rpx;
border-radius: 24rpx;
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
border: 1rpx solid rgba(255, 255, 255, 0.3);
overflow: hidden;
.settings-list {
.setting-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
transition: all 0.3s ease;
&:last-child {
border-bottom: none;
}
&:active {
background: rgba(255, 138, 128, 0.05);
}
.setting-left {
display: flex;
align-items: center;
.setting-icon {
font-size: 32rpx;
margin-right: 16rpx;
}
.setting-text {
font-size: 30rpx;
color: #333333;
font-weight: 500;
}
}
.setting-right {
display: flex;
align-items: center;
.setting-badge {
background: #FF8A80;
color: white;
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 20rpx;
margin-right: 12rpx;
min-width: 32rpx;
text-align: center;
}
.setting-arrow {
font-size: 24rpx;
color: #FF8A80;
}
}
}
}
}
/* 响应式设计 */
@media (max-width: 375px) {
.profile-container {
.user-info-card {
margin: 0 20rpx 20rpx 20rpx;
padding: 24rpx;
}
.stats-card,
.family-card,
.adoption-card,
.settings-card {
margin: 0 20rpx 20rpx 20rpx;
padding: 24rpx;
}
.stats-grid {
gap: 16rpx;
.stat-item {
padding: 20rpx 12rpx;
.stat-number {
font-size: 36rpx;
}
}
}
.family-actions {
gap: 12rpx;
.action-btn {
padding: 20rpx 12rpx;
}
}
}
}
/* 加载状态 */
.loading-state {
display: flex;
justify-content: center;
align-items: center;
padding: 60rpx;
.loading-text {
font-size: 24rpx;
color: #999999;
margin-left: 16rpx;
}
}
/* 空状态 */
.empty-state {
text-align: center;
padding: 60rpx 40rpx;
.empty-icon {
font-size: 80rpx;
margin-bottom: 16rpx;
opacity: 0.5;
}
.empty-text {
font-size: 24rpx;
color: #999999;
line-height: 1.5;
}
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.profile-container > view {
animation: fadeIn 0.5s ease-out;
}
.profile-container > view:nth-child(1) {
animation-delay: 0.1s;
}
.profile-container > view:nth-child(2) {
animation-delay: 0.2s;
}
.profile-container > view:nth-child(3) {
animation-delay: 0.3s;
}
.profile-container > view:nth-child(4) {
animation-delay: 0.4s;
}
.profile-container > view:nth-child(5) {
animation-delay: 0.5s;
}
/* 手机号授权模态框 */
.phone-auth-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
.auth-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
}
.auth-content {
position: relative;
background: white;
margin: 0 60rpx;
border-radius: 24rpx;
padding: 60rpx 40rpx;
text-align: center;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
.auth-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
}
.auth-desc {
font-size: 28rpx;
color: #666;
line-height: 1.5;
margin-bottom: 60rpx;
}
.auth-buttons {
display: flex;
flex-direction: column;
gap: 20rpx;
.auth-btn {
height: 88rpx;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 600;
border: none;
&.primary {
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
color: white;
}
&.secondary {
background: #f5f5f5;
color: #666;
}
}
}
}
}
/* 登录按钮样式 */
.login-btn {
background: transparent;
border: none;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
.action-icon {
font-size: 32rpx;
}
}
.logged-in-action {
display: flex;
align-items: center;
justify-content: center;
.action-icon {
font-size: 32rpx;
}
}
</style>