1222 lines
26 KiB
Vue
1222 lines
26 KiB
Vue
<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>
|