pet/pages/pets/pets.vue

1222 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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="pets-container page-container-unified">
<!-- 标签切换容器 -->
<view class="tabs-container" v-if="petsList.length > 0">
<view class="tabs-header">
<scroll-view
class="tabs-scroll"
scroll-x
:show-scrollbar="false"
:enable-flex="true"
>
<view class="tabs-content">
<view
class="tab-btn"
:class="{ 'tab-btn--active': currentTabIndex === index }"
v-for="(pet, index) in petsList"
:key="pet.id"
@click="switchTab(index)"
>
<view class="tab-avatar gradient-bg-primary">{{ getPetEmoji(pet.breed) }}</view>
<view class="tab-name">{{ pet.name }}</view>
</view>
</view>
</scroll-view>
<view class="add-tab-fixed" @click="addPet">
<text class="add-tab__icon"></text>
<text class="add-tab__text">添加</text>
</view>
</view>
<!-- 标签内容 -->
<view class="tab-content">
<view
class="tab-panel"
:class="{ 'tab-panel--active': currentTabIndex === index }"
v-for="(pet, index) in petsList"
:key="pet.id"
>
<!-- 宠物详情卡片 -->
<view class="pet-card">
<!-- 宠物基本信息区 -->
<view class="pet-header" @click="viewPetDetail(pet)">
<!-- 左侧头像区域 -->
<view class="pet-avatar-section">
<view class="pet-avatar-wrapper">
<u-avatar
:text="getPetEmoji(pet.breed)"
size="90"
shape="circle"
bg-color="linear-gradient(135deg, #FF8A80, #FFB6C1)"
color="white"
font-size="45"
></u-avatar>
<view class="pet-status-ring" :class="`pet-status-ring--${pet.healthStatus || 'healthy'}`"></view>
</view>
</view>
<!-- 右侧信息区域 -->
<view class="pet-info-section">
<view class="pet-info">
<view class="pet-info-top">
<view class="pet-name-row">
<view class="pet-name">{{ pet.name }}</view>
<u-icon
:name="pet.gender === '公' ? 'man' : 'woman'"
:color="pet.gender === '公' ? '#2196F3' : '#E91E63'"
size="20"
></u-icon>
</view>
<view class="pet-details">
{{ pet.breed }} · {{ pet.age }}岁 ·
<text class="constellation-text">{{ pet.constellation || '水瓶座' }}</text>
<text class="constellation-icon">{{ getConstellationIcon(pet.constellation || '水瓶座') }}</text>
</view>
</view>
<view class="pet-info-bottom">
<text class="companion-text">陪伴 {{ pet.companionDays }} 天</text>
</view>
</view>
</view>
</view>
<!-- 数据统计网格 -->
<view class="pet-stats">
<view class="stat-item">
<text class="stat-icon">⚖️</text>
<view class="stat-value">{{ pet.weight || '未知' }}</view>
<view class="stat-label">当前体重</view>
</view>
<view class="stat-item">
<text class="stat-icon">📝</text>
<view class="stat-value">{{ getPetRecordsCount(pet.id) }}</view>
<view class="stat-label">记录数量</view>
</view>
<view class="stat-item">
<text class="stat-icon">💰</text>
<view class="stat-value">¥{{ getPetMonthlyExpense(pet.id) }}</view>
<view class="stat-label">本月消费</view>
</view>
<view class="stat-item">
<text class="stat-icon">🔔</text>
<view class="stat-value">{{ getPetReminders(pet.id) }}</view>
<view class="stat-label">待办提醒</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 功能区 -->
<!-- <view class="functions-section" v-if="petsList.length > 0">-->
<!-- <scroll-view scroll-x class="functions-scroll" :show-scrollbar="false">-->
<!-- <view class="functions-container">-->
<!-- <view class="function-item btn-gradient radius-medium shadow-medium" v-for="item in mainActionItems" :key="item.id" @click="handleAction(item.action, petsList[currentTabIndex])">-->
<!-- <text class="function-icon">{{ item.icon }}</text>-->
<!-- <text class="function-text">{{ item.text }}</text>-->
<!-- </view>-->
<!-- </view>-->
<!-- </scroll-view>-->
<!-- </view>-->
<!-- 空状态 -->
<view class="empty-state" v-else>
<text class="empty-emoji">🐾</text>
<text class="empty-title">还没有小伙伴呢</text>
<text class="empty-desc">添加你的第一只宠物,开始记录美好时光吧~</text>
<view class="empty-add-btn" @click="addPet">
<text class="empty-add-text">添加第一只宠物</text>
</view>
</view>
<!-- 模块化卡片区域 -->
<view class="cards-section" v-if="petsList.length > 0">
<!-- 家庭概览卡片 -->
<view class="overview-card card-style padding-large">
<view class="card-header">
<text class="card-title text-primary">📊 家庭概览</text>
<text class="card-subtitle text-muted">{{ petsList.length }}位家庭成员</text>
</view>
<view class="overview-stats">
<view class="overview-stat">
<view class="overview-stat-number text-primary">{{ totalRecords }}</view>
<view class="overview-stat-label text-secondary">总记录</view>
</view>
<view class="overview-stat">
<view class="overview-stat-number text-primary">¥{{ totalMonthlyExpense }}</view>
<view class="overview-stat-label text-secondary">本月消费</view>
</view>
<view class="overview-stat">
<view class="overview-stat-number text-primary">{{ totalCompanionDays }}</view>
<view class="overview-stat-label text-secondary">陪伴天数</view>
</view>
</view>
</view>
<!-- 最近互动卡片 -->
<view class="interactions-card card-style padding-large">
<view class="card-header">
<text class="card-title text-primary">💬 最近互动</text>
<text class="card-subtitle text-muted">今日活动</text>
</view>
<view class="interactions-list">
<view class="interaction-item" v-for="interaction in recentInteractions" :key="interaction.id">
<view class="interaction-avatar">{{ interaction.petEmoji }}</view>
<view class="interaction-content">
<view class="interaction-title">{{ interaction.title }}</view>
<view class="interaction-time">{{ interaction.time }}</view>
</view>
<view class="interaction-type">{{ interaction.typeIcon }}</view>
</view>
</view>
<view class="view-more" @click="navigateToRecords">
<text class="view-more-text">查看更多 →</text>
</view>
</view>
<!-- 健康状态卡片 -->
<view class="health-card card-style padding-large">
<view class="card-header">
<text class="card-title text-primary">💚 健康状态</text>
<text class="card-subtitle text-muted">实时监控</text>
</view>
<view class="health-list">
<view class="health-item" v-for="pet in petsList" :key="pet.id">
<view class="health-pet-info">
<text class="health-pet-emoji">{{ getPetEmoji(pet.breed) }}</text>
<text class="health-pet-name">{{ pet.name }}</text>
</view>
<u-tag
:text="getHealthStatusText(pet.healthStatus)"
:type="getHealthTagType(pet.healthStatus)"
shape="circle"
size="mini"
></u-tag>
</view>
</view>
<view class="health-actions">
<view class="health-action" @click="navigateToStats">
<text class="health-action-text">查看详细报告</text>
</view>
</view>
</view>
</view>
<!-- 浮动添加按钮 -->
<view class="floating-add btn-gradient text-white shadow-medium" @click="addRecord(petsList[currentTabIndex])">
<text class="floating-add-icon">📝</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
petsList: [],
totalRecords: 0,
currentTabIndex: 0,
petRecords: [],
petExpenses: [],
mainActionItems: [
{ id: 1, icon: '📝', text: '添加记录', action: 'addRecord' },
{ id: 2, icon: '💬', text: 'AI聊天', action: 'chatWithPet' },
{ id: 3, icon: '📊', text: '健康档案', action: 'viewHealth' },
{ id: 4, icon: '📸', text: '成长时光', action: 'viewTimeline' },
{ id: 5, icon: '📋', text: '所有记录', action: 'viewRecords' },
{ id: 6, icon: '🔔', text: '提醒设置', action: 'showReminder' }
],
recentInteractions: [
{
id: 1,
petEmoji: '🐱',
title: '小橘完成了今日散步',
time: '2小时前',
typeIcon: '🚶'
},
{
id: 2,
petEmoji: '🐶',
title: '小白吃完了晚餐',
time: '4小时前',
typeIcon: '🍽️'
},
{
id: 3,
petEmoji: '🐱',
title: '小橘的体重记录已更新',
time: '1天前',
typeIcon: '⚖️'
}
]
}
},
onShow() {
this.loadPets()
this.loadStatistics()
this.loadPetRecords()
this.loadPetExpenses()
},
computed: {
// 计算总陪伴天数
totalCompanionDays() {
return this.petsList.reduce((total, pet) => total + (pet.companionDays || 0), 0)
},
// 计算总月消费
totalMonthlyExpense() {
return this.petExpenses.reduce((total, expense) => total + (expense.amount || 0), 0)
}
},
methods: {
// 标签切换
switchTab(index) {
this.currentTabIndex = index
},
// 处理功能按钮点击
handleAction(action, pet) {
switch(action) {
case 'addRecord':
this.addRecord(pet)
break
case 'chatWithPet':
this.chatWithPet(pet)
break
case 'viewHealth':
this.viewHealth(pet)
break
case 'viewTimeline':
this.viewTimeline(pet)
break
case 'viewRecords':
this.navigateToRecords()
break
case 'showReminder':
uni.showToast({
title: '提醒功能开发中',
icon: 'none'
})
break
default:
console.log('未知操作:', action)
}
},
// 获取宠物表情符号
getPetEmoji(breed) {
const emojiMap = {
'橘猫': '🐱',
'金毛': '🐶',
'垂耳兔': '🐰',
'哈士奇': '🐕',
'波斯猫': '😸',
'泰迪': '🐩',
'仓鼠': '🐹',
'鹦鹉': '🦜'
}
return emojiMap[breed] || '🐾'
},
loadPets() {
try {
let pets = uni.getStorageSync('pets') || []
// 如果没有宠物数据,添加一些模拟数据
if (pets.length === 0) {
pets = [
{
id: 1,
name: '小橘',
breed: '橘猫',
age: 2,
companionDays: 365,
avatar: '/static/default-pet.png',
gender: '公',
weight: '4.5kg',
birthday: '2022-01-15',
constellation: '摩羯座',
healthStatus: 'healthy',
personality: ['活泼', '粘人', '贪吃'],
lastRecord: '2024-01-15'
},
{
id: 2,
name: '小白',
breed: '金毛',
age: 3,
companionDays: 1095,
avatar: '/static/default-pet.png',
gender: '母',
weight: '25kg',
birthday: '2021-03-20',
constellation: '双鱼座',
healthStatus: 'healthy',
personality: ['温顺', '聪明', '忠诚'],
lastRecord: '2024-01-14'
},
{
id: 3,
name: '小灰',
breed: '垂耳兔',
age: 1,
companionDays: 180,
avatar: '/static/default-pet.png',
gender: '母',
weight: '1.2kg',
birthday: '2023-06-15',
constellation: '双子座',
healthStatus: 'healthy',
personality: ['安静', '可爱', '乖巧'],
lastRecord: '2024-01-13'
},
{
id: 4,
name: '小黑',
breed: '哈士奇',
age: 4,
companionDays: 1460,
avatar: '/static/default-pet.png',
gender: '公',
weight: '28kg',
birthday: '2020-05-10',
constellation: '金牛座',
healthStatus: 'healthy',
personality: ['调皮', '精力充沛', '拆家'],
lastRecord: '2024-01-16'
},
{
id: 5,
name: '咪咪',
breed: '波斯猫',
age: 5,
companionDays: 1825,
avatar: '/static/default-pet.png',
gender: '母',
weight: '3.8kg',
birthday: '2019-08-22',
constellation: '处女座',
healthStatus: 'warning',
personality: ['高贵', '优雅', '挑食'],
lastRecord: '2024-01-12'
},
{
id: 6,
name: '豆豆',
breed: '泰迪',
age: 2,
companionDays: 730,
avatar: '/static/default-pet.png',
gender: '公',
weight: '6.2kg',
birthday: '2022-02-14',
constellation: '水瓶座',
healthStatus: 'healthy',
personality: ['聪明', '活泼', '粘人'],
lastRecord: '2024-01-15'
},
{
id: 7,
name: '花花',
breed: '仓鼠',
age: 1,
companionDays: 120,
avatar: '/static/default-pet.png',
gender: '母',
weight: '0.15kg',
birthday: '2023-09-01',
constellation: '处女座',
healthStatus: 'healthy',
personality: ['可爱', '活跃', '爱囤食'],
lastRecord: '2024-01-16'
},
{
id: 8,
name: '彩彩',
breed: '鹦鹉',
age: 3,
companionDays: 900,
avatar: '/static/default-pet.png',
gender: '公',
weight: '0.8kg',
birthday: '2021-11-30',
constellation: '射手座',
healthStatus: 'healthy',
personality: ['聪明', '话多', '模仿'],
lastRecord: '2024-01-14'
},
{
id: 9,
name: '小雪',
breed: '金毛',
age: 1,
companionDays: 200,
avatar: '/static/default-pet.png',
gender: '母',
weight: '18kg',
birthday: '2023-05-20',
constellation: '金牛座',
healthStatus: 'healthy',
personality: ['温顺', '乖巧', '爱玩'],
lastRecord: '2024-01-15'
},
{
id: 10,
name: '小虎',
breed: '橘猫',
age: 6,
companionDays: 2190,
avatar: '/static/default-pet.png',
gender: '公',
weight: '5.8kg',
birthday: '2018-07-08',
constellation: '巨蟹座',
healthStatus: 'warning',
personality: ['慵懒', '贪吃', '老成'],
lastRecord: '2024-01-11'
}
]
// 保存模拟数据到本地存储
uni.setStorageSync('pets', pets)
}
this.petsList = pets
} catch (error) {
console.error('加载宠物列表失败', error)
this.petsList = []
}
},
loadPetRecords() {
try {
const records = uni.getStorageSync('petRecords') || []
this.petRecords = records
} catch (error) {
console.error('加载宠物记录失败', error)
this.petRecords = []
}
},
loadPetExpenses() {
try {
// 模拟宠物消费数据
const expenses = [
{ petId: 1, amount: 580, month: '2024-01' },
{ petId: 2, amount: 890, month: '2024-01' },
{ petId: 3, amount: 120, month: '2024-01' },
{ petId: 4, amount: 1200, month: '2024-01' },
{ petId: 5, amount: 750, month: '2024-01' },
{ petId: 6, amount: 680, month: '2024-01' },
{ petId: 7, amount: 80, month: '2024-01' },
{ petId: 8, amount: 320, month: '2024-01' },
{ petId: 9, amount: 450, month: '2024-01' },
{ petId: 10, amount: 620, month: '2024-01' }
]
this.petExpenses = expenses
} catch (error) {
console.error('加载宠物消费失败', error)
this.petExpenses = []
}
},
loadStatistics() {
try {
// 加载统计数据
const records = uni.getStorageSync('petRecords') || []
this.totalRecords = records.length || 190
// 计算总陪伴天数
this.totalDays = this.petsList.reduce((total, pet) => total + (pet.companionDays || 0), 0)
// 模拟待办提醒数量
this.upcomingReminders = Math.floor(Math.random() * 5) + 1
} catch (error) {
console.error('加载统计数据失败', error)
}
},
// 获取宠物记录数量
getPetRecordsCount(petId) {
const petRecords = this.petRecords.filter(record => record.petId === petId)
const mockCounts = {
1: 89, 2: 67, 3: 34, 4: 156, 5: 203,
6: 78, 7: 45, 8: 92, 9: 23, 10: 267
}
return petRecords.length || mockCounts[petId] || 0
},
// 获取宠物月消费
getPetMonthlyExpense(petId) {
const expense = this.petExpenses.find(exp => exp.petId === petId)
return expense ? expense.amount : 0
},
// 获取宠物待办提醒数量
getPetReminders(petId) {
// 模拟获取宠物待办提醒数量
const reminders = {
1: 3, 2: 1, 3: 5, 4: 2, 5: 4,
6: 0, 7: 1, 8: 3, 9: 2, 10: 6
};
return reminders[petId] || 0;
},
// 获取星座对应的图标
getConstellationIcon(constellation) {
const constellationIcons = {
'白羊座': '♈',
'金牛座': '♉',
'双子座': '♊',
'巨蟹座': '♋',
'狮子座': '♌',
'处女座': '♍',
'天秤座': '♎',
'天蝎座': '♏',
'射手座': '♐',
'摩羯座': '♑',
'水瓶座': '♒',
'双鱼座': '♓'
};
return constellationIcons[constellation] || '⭐';
},
getHealthStatusText(status) {
const statusMap = {
healthy: '健康',
warning: '注意',
sick: '异常'
}
return statusMap[status] || '健康'
},
getHealthTagType(status) {
const typeMap = {
healthy: 'success',
warning: 'warning',
sick: 'error'
}
return typeMap[status] || 'success'
},
addPet() {
uni.navigateTo({
url: '/pages/pets/add-pet'
})
},
viewPetDetail(pet) {
uni.navigateTo({
url: `/pages/pets/pet-detail?id=${pet.id}`
})
},
chatWithPet(pet) {
uni.navigateTo({
url: `/pages/pets/pet-chat-simple?petId=${pet.id}`
})
},
addRecord(pet) {
uni.navigateTo({
url: `/pages/pets/select-record-type?petId=${pet.id}`
})
},
viewHealth(pet) {
uni.navigateTo({
url: `/pages/pets/health-charts?petId=${pet.id}`
})
},
viewTimeline(pet) {
uni.navigateTo({
url: `/pages/pets/pet-timeline?petId=${pet.id}`
})
},
// 导航方法
navigateToRecords() {
uni.navigateTo({
url: '/pages/pets/pet-records'
})
},
navigateToStats() {
uni.navigateTo({
url: '/pages/pets/health-charts'
})
}
}
}
</script>
<style lang="scss" scoped>
.pets-container {
/* 边距由外层page-container-unified统一管理 */
}
.tabs-container {
background: rgba(255, 255, 255, 0.85);
margin: 0 0 30rpx 0;
border-radius: 40rpx;
backdrop-filter: blur(20rpx);
overflow: visible;
box-shadow: 0 16rpx 64rpx rgba(255, 138, 128, 0.2);
border: 2rpx solid rgba(255, 255, 255, 0.3);
}
.tabs-header {
display: flex;
align-items: center;
background: linear-gradient(135deg, rgba(255, 138, 128, 0.2) 0%, rgba(255, 182, 193, 0.2) 100%);
padding: 10rpx;
border-radius: 40rpx 40rpx 0 0;
position: relative;
width: 100%;
box-sizing: border-box;
}
.tabs-scroll {
flex: 1;
white-space: nowrap;
min-width: 0;
overflow: hidden;
}
.tabs-content {
display: flex;
align-items: center;
width: max-content;
}
.tab-btn {
flex-shrink: 0;
background: none;
border: none;
padding: 24rpx 16rpx;
text-align: center;
border-radius: 30rpx;
transition: all 0.3s ease;
position: relative;
z-index: 2;
min-width: 120rpx;
width: auto;
}
.tab-btn--active {
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 4rpx 16rpx rgba(255, 138, 128, 0.2);
}
.tab-avatar {
width: 48rpx;
height: 48rpx;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
margin: 0 auto 8rpx;
}
.tab-name {
font-size: 24rpx;
font-weight: bold;
color: #333;
}
.add-tab-fixed {
width: 100rpx;
min-width: 100rpx;
flex-shrink: 0;
background: none;
border: none;
padding: 24rpx 8rpx;
text-align: center;
border-radius: 30rpx;
transition: all 0.3s ease;
color: #FF8A80;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 8rpx;
}
.add-tab-fixed:active {
background: rgba(255, 138, 128, 0.15);
}
.add-tab__icon {
font-size: 40rpx;
margin-bottom: 8rpx;
}
.add-tab__text {
font-size: 20rpx;
}
.tab-content {
padding: 0;
}
.tab-panel {
display: none;
}
.tab-panel--active {
display: block;
}
.pet-card {
margin-bottom: 0;
cursor: pointer;
transition: all 0.3s ease;
border-radius: 16rpx;
padding: 16rpx;
}
.pet-card:active {
transform: scale(0.98);
background: rgba(255, 255, 255, 0.1);
}
.pet-header {
display: flex;
align-items: center;
margin-bottom: 8rpx;
text-align: left;
width: 100%;
}
.pet-avatar-section {
width: 35%;
display: flex;
justify-content: center;
align-items: center;
padding: 8rpx;
}
.pet-info-section {
//width: 60%;
padding-left: 80rpx;
padding-right: 8rpx;
}
.pet-info {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100rpx;
width: 100%;
}
.pet-info-top {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
}
.pet-info-bottom {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 6rpx;
width: 100%;
}
.pet-name-row {
display: flex;
align-items: center;
margin-bottom: 6rpx;
height: 40rpx;
}
.pet-name {
font-size: 36rpx;
font-weight: bold;
color: #333;
line-height: 1;
display: inline-block;
margin-right: 24rpx;
}
.pet-details {
font-size: 24rpx;
color: #666;
margin-bottom: 8rpx;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.constellation-text {
color: #666;
}
.constellation-icon {
font-size: 20rpx;
color: #FFD700;
margin-left: 4rpx;
}
.companion-text {
font-size: 22rpx;
color: #999;
flex: 1;
text-align: left;
}
.pet-avatar-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.pet-status-ring {
position: absolute;
top: -8rpx;
left: -8rpx;
right: -8rpx;
bottom: -8rpx;
border: 6rpx solid #4CAF50;
border-radius: 50%;
border-top-color: transparent;
animation: spin 3s linear infinite;
}
.pet-status-ring--healthy {
border-color: #4CAF50;
border-top-color: transparent;
}
.pet-status-ring--warning {
border-color: #FFB74D;
border-top-color: transparent;
}
.pet-status-ring--sick {
border-color: #FF8A80;
border-top-color: transparent;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.pet-stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 4rpx;
margin-bottom: 0;
}
.stat-item {
padding: 14rpx 8rpx;
border-radius: 10rpx;
text-align: center;
}
.stat-icon {
font-size: 28rpx;
margin-bottom: 6rpx;
display: block;
}
.stat-value {
font-size: 22rpx;
font-weight: bold;
color: #333;
margin-bottom: 3rpx;
}
.stat-label {
font-size: 16rpx;
color: #999;
}
.functions-section {
margin: 16rpx 0 20rpx 0;
background: rgba(255, 255, 255, 0.1);
border-radius: 16rpx;
padding: 16rpx 0;
backdrop-filter: blur(10rpx);
}
.functions-scroll {
white-space: nowrap;
width: 100%;
overflow-x: auto;
}
.functions-scroll::-webkit-scrollbar {
display: none;
}
.functions-container {
display: flex;
gap: 14rpx;
width: max-content;
padding: 0 12rpx;
}
.function-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 18rpx 8rpx;
width: 145rpx;
flex-shrink: 0;
transition: all 0.3s ease;
}
.function-item:active {
transform: scale(0.95);
box-shadow: 0 4rpx 16rpx rgba(255, 138, 128, 0.2);
}
.function-icon {
font-size: 32rpx;
margin-bottom: 10rpx;
}
.function-text {
font-size: 22rpx;
color: white;
font-weight: 500;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 60rpx;
text-align: center;
}
.empty-emoji {
font-size: 200rpx;
margin-bottom: 40rpx;
opacity: 0.8;
}
.empty-title {
font-size: 36rpx;
font-weight: bold;
color: white;
margin-bottom: 16rpx;
}
.empty-desc {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
line-height: 1.5;
margin-bottom: 60rpx;
}
.empty-add-btn {
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
padding: 24rpx 48rpx;
border-radius: 50rpx;
box-shadow: 0 16rpx 64rpx rgba(255, 138, 128, 0.4);
display: flex;
align-items: center;
justify-content: center;
}
.empty-add-text {
color: white;
font-size: 32rpx;
font-weight: bold;
}
.cards-section {
padding: 0;
display: flex;
flex-direction: column;
gap: 16rpx;
}
.overview-card,
.interactions-card,
.health-card {
margin-bottom: 16rpx;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.card-title {
font-size: 32rpx;
font-weight: 600;
}
.card-subtitle {
font-size: 24rpx;
}
.overview-stats {
display: flex;
justify-content: space-around;
gap: 20rpx;
}
.overview-stat {
text-align: center;
flex: 1;
}
.overview-stat-number {
font-size: 36rpx;
font-weight: 700;
margin-bottom: 8rpx;
}
.overview-stat-label {
font-size: 22rpx;
}
.floating-add {
position: fixed;
bottom: 60rpx;
right: 40rpx;
width: 112rpx;
height: 112rpx;
border-radius: 56rpx;
border: none;
transition: transform 0.3s;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
}
.floating-add:active {
transform: scale(1.1);
}
.floating-add-icon {
font-size: 48rpx;
}
.interactions-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.interaction-item {
display: flex;
align-items: center;
padding: 16rpx;
border-radius: 12rpx;
background: #f8f9fa;
}
.interaction-avatar {
font-size: 32rpx;
margin-right: 16rpx;
}
.interaction-content {
flex: 1;
}
.interaction-title {
font-size: 26rpx;
color: #333;
margin-bottom: 4rpx;
}
.interaction-time {
font-size: 22rpx;
color: #999;
}
.interaction-type {
font-size: 24rpx;
}
.view-more {
text-align: center;
margin-top: 16rpx;
padding: 12rpx;
}
.view-more-text {
font-size: 24rpx;
color: #FF8A80;
}
.health-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.health-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx;
border-radius: 12rpx;
background: #f8f9fa;
}
.health-pet-info {
display: flex;
align-items: center;
gap: 12rpx;
}
.health-pet-emoji {
font-size: 28rpx;
}
.health-pet-name {
font-size: 26rpx;
color: #333;
}
.health-status {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
}
.health-status--healthy {
background: #e8f5e8;
color: #4caf50;
}
.health-status--warning {
background: #fff3e0;
color: #ff9800;
}
.health-status--sick {
background: #ffebee;
color: #f44336;
}
.health-actions {
text-align: center;
margin-top: 16rpx;
}
.health-action-text {
font-size: 24rpx;
color: #FF8A80;
}
</style>