909 lines
19 KiB
Vue
909 lines
19 KiB
Vue
<template>
|
||
<view class="family-container page-container-with-bg">
|
||
<!-- 家庭概览卡片 -->
|
||
<view class="family-overview-card">
|
||
<view class="overview-header">
|
||
<view class="family-info">
|
||
<text class="family-name">{{ familyData.name || '我的家庭' }}</text>
|
||
<text class="family-desc">{{ familyData.members.length }}位成员 · 共同照顾{{ petCount }}只宠物</text>
|
||
</view>
|
||
<view class="family-avatar">
|
||
<text class="avatar-icon">👨👩👧👦</text>
|
||
</view>
|
||
</view>
|
||
<view class="overview-stats">
|
||
<view class="stat-item">
|
||
<view class="stat-number">{{ familyData.members.length }}</view>
|
||
<view class="stat-label">家庭成员</view>
|
||
</view>
|
||
<view class="stat-item">
|
||
<view class="stat-number">{{ sharedPets }}</view>
|
||
<view class="stat-label">共享宠物</view>
|
||
</view>
|
||
<view class="stat-item">
|
||
<view class="stat-number">{{ todayRecords }}</view>
|
||
<view class="stat-label">今日记录</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 家庭成员卡片 -->
|
||
<view class="members-card">
|
||
<view class="card-header">
|
||
<text class="card-title">家庭成员</text>
|
||
<view class="header-action" @click="inviteMember">
|
||
<text class="action-icon">➕</text>
|
||
<text class="action-text">邀请</text>
|
||
</view>
|
||
</view>
|
||
<view class="members-list">
|
||
<view
|
||
class="member-item"
|
||
v-for="member in familyData.members"
|
||
:key="member.id"
|
||
@click="viewMemberDetail(member)"
|
||
>
|
||
<view class="member-avatar">
|
||
<u-avatar
|
||
:src="member.avatarUrl || ''"
|
||
:text="member.nickName ? member.nickName.charAt(0) : '👤'"
|
||
size="80"
|
||
shape="circle"
|
||
bg-color="linear-gradient(135deg, #FF8A80, #FFB6C1)"
|
||
color="white"
|
||
font-size="32"
|
||
></u-avatar>
|
||
<view class="member-role-badge" :class="member.role">
|
||
<text class="role-text">{{ getRoleText(member.role) }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="member-info">
|
||
<view class="member-name">{{ member.nickName }}</view>
|
||
<view class="member-status">
|
||
<view class="status-dot" :class="{ online: member.isOnline }"></view>
|
||
<text class="status-text">{{ member.isOnline ? '在线' : '离线' }}</text>
|
||
</view>
|
||
<view class="member-stats">
|
||
<text class="stats-text">本月记录 {{ member.monthlyRecords || 0 }} 条</text>
|
||
</view>
|
||
</view>
|
||
<view class="member-action">
|
||
<text class="action-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 权限设置卡片 -->
|
||
<view class="permissions-card">
|
||
<view class="card-header">
|
||
<text class="card-title">权限设置</text>
|
||
</view>
|
||
<view class="permissions-list">
|
||
<view class="permission-item">
|
||
<view class="permission-info">
|
||
<text class="permission-title">宠物管理权限</text>
|
||
<text class="permission-desc">允许成员添加、编辑宠物信息</text>
|
||
</view>
|
||
<view class="permission-switch">
|
||
<u-switch
|
||
v-model="permissions.petManagement"
|
||
@change="onPermissionChange('petManagement', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="permission-item">
|
||
<view class="permission-info">
|
||
<text class="permission-title">记录管理权限</text>
|
||
<text class="permission-desc">允许成员添加、编辑宠物记录</text>
|
||
</view>
|
||
<view class="permission-switch">
|
||
<u-switch
|
||
v-model="permissions.recordManagement"
|
||
@change="onPermissionChange('recordManagement', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="permission-item">
|
||
<view class="permission-info">
|
||
<text class="permission-title">成员管理权限</text>
|
||
<text class="permission-desc">允许成员邀请和管理其他成员</text>
|
||
</view>
|
||
<view class="permission-switch">
|
||
<u-switch
|
||
v-model="permissions.memberManagement"
|
||
@change="onPermissionChange('memberManagement', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 家庭设置卡片 -->
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">家庭设置</text>
|
||
</view>
|
||
<view class="settings-list">
|
||
<view class="setting-item" @click="editFamilyName">
|
||
<view class="setting-left">
|
||
<text class="setting-icon">✏️</text>
|
||
<text class="setting-text">修改家庭名称</text>
|
||
</view>
|
||
<view class="setting-right">
|
||
<text class="setting-value">{{ familyData.name || '我的家庭' }}</text>
|
||
<text class="setting-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
<view class="setting-item" @click="viewInviteCode">
|
||
<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="viewFamilyHistory">
|
||
<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 danger" @click="leaveFamilyConfirm">
|
||
<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>
|
||
|
||
<!-- 邀请成员弹窗 -->
|
||
<u-modal
|
||
:show="showInviteModal"
|
||
title="邀请家庭成员"
|
||
@confirm="confirmInvite"
|
||
@cancel="showInviteModal = false"
|
||
>
|
||
<view class="invite-content">
|
||
<view class="invite-method">
|
||
<text class="method-title">邀请方式</text>
|
||
<view class="method-options">
|
||
<view class="method-option" @click="shareInviteCode">
|
||
<text class="option-icon">📱</text>
|
||
<text class="option-text">分享邀请码</text>
|
||
</view>
|
||
<view class="method-option" @click="shareQRCode">
|
||
<text class="option-icon">📷</text>
|
||
<text class="option-text">分享二维码</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="invite-code">
|
||
<text class="code-title">邀请码</text>
|
||
<view class="code-display">
|
||
<text class="code-text">{{ inviteCode }}</text>
|
||
<view class="code-copy" @click="copyInviteCode">
|
||
<text class="copy-text">复制</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</u-modal>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { reactive, ref, onMounted, computed } from 'vue'
|
||
|
||
export default {
|
||
name: 'FamilyPage',
|
||
setup() {
|
||
// 响应式数据
|
||
const familyData = reactive({
|
||
id: '',
|
||
name: '我的家庭',
|
||
members: []
|
||
})
|
||
|
||
const permissions = reactive({
|
||
petManagement: true,
|
||
recordManagement: true,
|
||
memberManagement: false
|
||
})
|
||
|
||
const showInviteModal = ref(false)
|
||
const inviteCode = ref('')
|
||
const petCount = ref(0)
|
||
const sharedPets = ref(0)
|
||
const todayRecords = ref(0)
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
loadFamilyData()
|
||
generateInviteCode()
|
||
})
|
||
|
||
// 方法定义
|
||
const loadFamilyData = () => {
|
||
try {
|
||
// 加载家庭数据
|
||
const savedFamilyData = uni.getStorageSync('familyData') || {
|
||
id: 'family_' + Date.now(),
|
||
name: '我的家庭',
|
||
members: []
|
||
}
|
||
|
||
// 如果没有成员,添加当前用户作为家庭主人
|
||
if (savedFamilyData.members.length === 0) {
|
||
const userInfo = uni.getStorageSync('userInfo') || {}
|
||
savedFamilyData.members.push({
|
||
id: 'user_' + Date.now(),
|
||
nickName: userInfo.nickName || '我',
|
||
avatarUrl: userInfo.avatarUrl || '',
|
||
role: 'owner',
|
||
isOnline: true,
|
||
joinTime: new Date().toISOString(),
|
||
monthlyRecords: 15
|
||
})
|
||
}
|
||
|
||
Object.assign(familyData, savedFamilyData)
|
||
|
||
// 加载权限设置
|
||
const savedPermissions = uni.getStorageSync('familyPermissions') || permissions
|
||
Object.assign(permissions, savedPermissions)
|
||
|
||
// 加载统计数据
|
||
loadFamilyStats()
|
||
|
||
} catch (error) {
|
||
console.error('加载家庭数据失败:', error)
|
||
}
|
||
}
|
||
|
||
const loadFamilyStats = () => {
|
||
// 加载宠物数量
|
||
const pets = uni.getStorageSync('pets') || []
|
||
petCount.value = pets.length
|
||
sharedPets.value = pets.filter(pet => pet.shared).length || pets.length
|
||
|
||
// 计算今日记录数
|
||
const today = new Date().toDateString()
|
||
let todayCount = 0
|
||
pets.forEach(pet => {
|
||
const records = uni.getStorageSync(`petRecords_${pet.id}`) || []
|
||
todayCount += records.filter(record =>
|
||
new Date(record.date).toDateString() === today
|
||
).length
|
||
})
|
||
todayRecords.value = todayCount
|
||
}
|
||
|
||
const generateInviteCode = () => {
|
||
// 生成6位邀请码
|
||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||
let code = ''
|
||
for (let i = 0; i < 6; i++) {
|
||
code += chars.charAt(Math.floor(Math.random() * chars.length))
|
||
}
|
||
inviteCode.value = code
|
||
}
|
||
|
||
const getRoleText = (role) => {
|
||
const roleMap = {
|
||
'owner': '主人',
|
||
'admin': '管理员',
|
||
'member': '成员',
|
||
'viewer': '观察者'
|
||
}
|
||
return roleMap[role] || '成员'
|
||
}
|
||
|
||
const inviteMember = () => {
|
||
showInviteModal.value = true
|
||
}
|
||
|
||
const confirmInvite = () => {
|
||
shareInviteCode()
|
||
showInviteModal.value = false
|
||
}
|
||
|
||
const shareInviteCode = () => {
|
||
const shareText = `邀请您加入我的宠物家庭!\n邀请码:${inviteCode.value}\n快来一起记录我们的宠物生活吧~`
|
||
|
||
// 复制到剪贴板
|
||
uni.setClipboardData({
|
||
data: shareText,
|
||
success: () => {
|
||
uni.showToast({
|
||
title: '邀请信息已复制',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
const shareQRCode = () => {
|
||
uni.showToast({
|
||
title: '二维码功能开发中',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
const copyInviteCode = () => {
|
||
uni.setClipboardData({
|
||
data: inviteCode.value,
|
||
success: () => {
|
||
uni.showToast({
|
||
title: '邀请码已复制',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
const viewMemberDetail = (member) => {
|
||
uni.showModal({
|
||
title: member.nickName,
|
||
content: `角色:${getRoleText(member.role)}\n加入时间:${new Date(member.joinTime).toLocaleDateString()}\n本月记录:${member.monthlyRecords || 0}条`,
|
||
showCancel: false
|
||
})
|
||
}
|
||
|
||
const onPermissionChange = (key, value) => {
|
||
permissions[key] = value
|
||
uni.setStorageSync('familyPermissions', permissions)
|
||
|
||
uni.showToast({
|
||
title: '权限设置已更新',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
const editFamilyName = () => {
|
||
uni.showModal({
|
||
title: '修改家庭名称',
|
||
editable: true,
|
||
placeholderText: '请输入家庭名称',
|
||
success: (res) => {
|
||
if (res.confirm && res.content.trim()) {
|
||
familyData.name = res.content.trim()
|
||
saveFamilyData()
|
||
uni.showToast({
|
||
title: '家庭名称已更新',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const viewInviteCode = () => {
|
||
showInviteModal.value = true
|
||
}
|
||
|
||
const viewFamilyHistory = () => {
|
||
uni.showToast({
|
||
title: '家庭统计功能开发中',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
const leaveFamilyConfirm = () => {
|
||
uni.showModal({
|
||
title: '确认退出',
|
||
content: '退出后将无法查看家庭共享的宠物信息,确定要退出吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
leaveFamily()
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const leaveFamily = () => {
|
||
// 清除家庭数据
|
||
uni.removeStorageSync('familyData')
|
||
uni.removeStorageSync('familyPermissions')
|
||
|
||
uni.showToast({
|
||
title: '已退出家庭',
|
||
icon: 'success'
|
||
})
|
||
|
||
// 返回上一页
|
||
setTimeout(() => {
|
||
uni.navigateBack()
|
||
}, 1500)
|
||
}
|
||
|
||
const saveFamilyData = () => {
|
||
uni.setStorageSync('familyData', familyData)
|
||
}
|
||
|
||
return {
|
||
familyData,
|
||
permissions,
|
||
showInviteModal,
|
||
inviteCode,
|
||
petCount,
|
||
sharedPets,
|
||
todayRecords,
|
||
getRoleText,
|
||
inviteMember,
|
||
confirmInvite,
|
||
shareInviteCode,
|
||
shareQRCode,
|
||
copyInviteCode,
|
||
viewMemberDetail,
|
||
onPermissionChange,
|
||
editFamilyName,
|
||
viewInviteCode,
|
||
viewFamilyHistory,
|
||
leaveFamilyConfirm
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.family-container {
|
||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||
min-height: 100vh;
|
||
padding-bottom: 40rpx;
|
||
}
|
||
|
||
/* 通用卡片样式 */
|
||
.family-overview-card,
|
||
.members-card,
|
||
.permissions-card,
|
||
.settings-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;
|
||
|
||
.card-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
}
|
||
|
||
.header-action {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 12rpx 20rpx;
|
||
background: rgba(255, 138, 128, 0.1);
|
||
border-radius: 20rpx;
|
||
|
||
.action-icon {
|
||
font-size: 24rpx;
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
.action-text {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 家庭概览卡片 */
|
||
.family-overview-card {
|
||
.overview-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 32rpx;
|
||
|
||
.family-info {
|
||
flex: 1;
|
||
|
||
.family-name {
|
||
display: block;
|
||
font-size: 36rpx;
|
||
font-weight: 700;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.family-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.family-avatar {
|
||
.avatar-icon {
|
||
font-size: 60rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.overview-stats {
|
||
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);
|
||
|
||
.stat-number {
|
||
font-size: 40rpx;
|
||
font-weight: 700;
|
||
color: #FF8A80;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 家庭成员卡片 */
|
||
.members-list {
|
||
.member-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 24rpx 0;
|
||
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);
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.member-avatar {
|
||
position: relative;
|
||
margin-right: 24rpx;
|
||
|
||
.member-role-badge {
|
||
position: absolute;
|
||
bottom: -4rpx;
|
||
right: -4rpx;
|
||
padding: 4rpx 8rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 18rpx;
|
||
|
||
&.owner {
|
||
background: #FFD700;
|
||
color: #333333;
|
||
}
|
||
|
||
&.admin {
|
||
background: #FF8A80;
|
||
color: white;
|
||
}
|
||
|
||
&.member {
|
||
background: #81C784;
|
||
color: white;
|
||
}
|
||
|
||
&.viewer {
|
||
background: #CCCCCC;
|
||
color: #666666;
|
||
}
|
||
|
||
.role-text {
|
||
font-size: 18rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.member-info {
|
||
flex: 1;
|
||
|
||
.member-name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.member-status {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 4rpx;
|
||
|
||
.status-dot {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
background: #CCCCCC;
|
||
margin-right: 8rpx;
|
||
|
||
&.online {
|
||
background: #4CAF50;
|
||
}
|
||
}
|
||
|
||
.status-text {
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.member-stats {
|
||
.stats-text {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
}
|
||
|
||
.member-action {
|
||
.action-arrow {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 权限设置卡片 */
|
||
.permissions-list {
|
||
.permission-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 24rpx 0;
|
||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.permission-info {
|
||
flex: 1;
|
||
|
||
.permission-title {
|
||
display: block;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.permission-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
.permission-switch {
|
||
margin-left: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 家庭设置卡片 */
|
||
.settings-list {
|
||
.setting-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 32rpx 0;
|
||
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);
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
&.danger {
|
||
.setting-text {
|
||
color: #FF5722;
|
||
}
|
||
|
||
.setting-arrow {
|
||
color: #FF5722;
|
||
}
|
||
}
|
||
|
||
.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-value {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
margin-right: 12rpx;
|
||
}
|
||
|
||
.setting-arrow {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 邀请弹窗样式 */
|
||
.invite-content {
|
||
padding: 20rpx 0;
|
||
|
||
.invite-method {
|
||
margin-bottom: 32rpx;
|
||
|
||
.method-title {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.method-options {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16rpx;
|
||
|
||
.method-option {
|
||
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 {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.option-icon {
|
||
font-size: 32rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.option-text {
|
||
font-size: 24rpx;
|
||
color: #333333;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.invite-code {
|
||
.code-title {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.code-display {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 20rpx;
|
||
background: rgba(255, 138, 128, 0.05);
|
||
border-radius: 16rpx;
|
||
border: 2rpx dashed #FF8A80;
|
||
|
||
.code-text {
|
||
flex: 1;
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #FF8A80;
|
||
text-align: center;
|
||
letter-spacing: 4rpx;
|
||
}
|
||
|
||
.code-copy {
|
||
padding: 8rpx 16rpx;
|
||
background: #FF8A80;
|
||
border-radius: 12rpx;
|
||
|
||
.copy-text {
|
||
font-size: 22rpx;
|
||
color: white;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 375px) {
|
||
.family-container {
|
||
.family-overview-card,
|
||
.members-card,
|
||
.permissions-card,
|
||
.settings-card {
|
||
margin: 0 20rpx 20rpx 20rpx;
|
||
padding: 24rpx;
|
||
}
|
||
|
||
.overview-stats {
|
||
gap: 16rpx;
|
||
|
||
.stat-item {
|
||
padding: 20rpx 12rpx;
|
||
|
||
.stat-number {
|
||
font-size: 36rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 动画效果 */
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.family-container > view {
|
||
animation: fadeIn 0.5s ease-out;
|
||
}
|
||
|
||
.family-container > view:nth-child(1) { animation-delay: 0.1s; }
|
||
.family-container > view:nth-child(2) { animation-delay: 0.2s; }
|
||
.family-container > view:nth-child(3) { animation-delay: 0.3s; }
|
||
.family-container > view:nth-child(4) { animation-delay: 0.4s; }
|
||
</style>
|