627 lines
22 KiB
HTML
627 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>宠物详情 - 卡片仪表盘式 V2</title>
|
||
<link rel="stylesheet" href="assets/css/common.css">
|
||
<style>
|
||
/* 卡片仪表盘式 V2 特有样式 - 侧重数据可视化 */
|
||
.dashboard-v2-container {
|
||
background: #F8FAFC;
|
||
}
|
||
|
||
.hero-card {
|
||
background: linear-gradient(135deg, var(--pet-primary), var(--pet-accent));
|
||
color: white;
|
||
border-radius: var(--radius-xl);
|
||
padding: var(--spacing-xl);
|
||
margin: var(--spacing-md);
|
||
box-shadow: 0 20px 40px rgba(255, 138, 128, 0.3);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.hero-card::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -50%;
|
||
right: -50%;
|
||
width: 200%;
|
||
height: 200%;
|
||
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="2" fill="rgba(255,255,255,0.1)"/></svg>') repeat;
|
||
animation: float 20s infinite linear;
|
||
}
|
||
|
||
.hero-content {
|
||
position: relative;
|
||
z-index: 2;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--spacing-lg);
|
||
}
|
||
|
||
.hero-avatar {
|
||
width: 90px;
|
||
height: 90px;
|
||
border-radius: var(--radius-round);
|
||
border: 4px solid rgba(255,255,255,0.8);
|
||
box-shadow: 0 8px 24px rgba(0,0,0,0.2);
|
||
}
|
||
|
||
.hero-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.hero-name {
|
||
font-size: 28px;
|
||
font-weight: bold;
|
||
margin-bottom: var(--spacing-xs);
|
||
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||
}
|
||
|
||
.hero-details {
|
||
opacity: 0.9;
|
||
margin-bottom: var(--spacing-md);
|
||
}
|
||
|
||
.hero-stats {
|
||
display: flex;
|
||
gap: var(--spacing-lg);
|
||
}
|
||
|
||
.hero-stat {
|
||
text-align: center;
|
||
}
|
||
|
||
.hero-stat-value {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.hero-stat-label {
|
||
font-size: 12px;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.dashboard-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: var(--spacing-md);
|
||
margin: var(--spacing-md);
|
||
}
|
||
|
||
.dashboard-card {
|
||
background: white;
|
||
border-radius: var(--radius-lg);
|
||
padding: var(--spacing-lg);
|
||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||
border: 1px solid #E2E8F0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.dashboard-card:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 30px rgba(0,0,0,0.12);
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: var(--spacing-lg);
|
||
}
|
||
|
||
.card-title {
|
||
font-weight: bold;
|
||
color: var(--text-primary);
|
||
font-size: 16px;
|
||
}
|
||
|
||
.card-icon {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: var(--radius-md);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20px;
|
||
}
|
||
|
||
.icon-weight {
|
||
background: linear-gradient(135deg, #FF6B6B, #FF8E8E);
|
||
color: white;
|
||
}
|
||
|
||
.icon-activity {
|
||
background: linear-gradient(135deg, #4ECDC4, #44A08D);
|
||
color: white;
|
||
}
|
||
|
||
.icon-food {
|
||
background: linear-gradient(135deg, #45B7D1, #96CEB4);
|
||
color: white;
|
||
}
|
||
|
||
.icon-sleep {
|
||
background: linear-gradient(135deg, #A8E6CF, #DCEDC1);
|
||
color: white;
|
||
}
|
||
|
||
.metric-display {
|
||
text-align: center;
|
||
}
|
||
|
||
.metric-value-large {
|
||
font-size: 36px;
|
||
font-weight: bold;
|
||
color: var(--text-primary);
|
||
margin-bottom: var(--spacing-sm);
|
||
}
|
||
|
||
.metric-unit {
|
||
font-size: 14px;
|
||
color: var(--text-light);
|
||
margin-left: var(--spacing-xs);
|
||
}
|
||
|
||
.metric-change {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--spacing-xs);
|
||
font-size: 14px;
|
||
margin-bottom: var(--spacing-md);
|
||
}
|
||
|
||
.change-positive {
|
||
color: #10B981;
|
||
}
|
||
|
||
.change-negative {
|
||
color: #EF4444;
|
||
}
|
||
|
||
.change-neutral {
|
||
color: #6B7280;
|
||
}
|
||
|
||
.mini-chart {
|
||
height: 40px;
|
||
background: linear-gradient(90deg, #E5E7EB, #F3F4F6);
|
||
border-radius: var(--radius-md);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.chart-line {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 60%;
|
||
background: linear-gradient(90deg, var(--pet-primary), var(--pet-accent));
|
||
border-radius: var(--radius-md) var(--radius-md) 0 0;
|
||
clip-path: polygon(0 80%, 25% 60%, 50% 40%, 75% 30%, 100% 20%, 100% 100%, 0 100%);
|
||
}
|
||
|
||
.full-width-card {
|
||
grid-column: 1 / -1;
|
||
background: white;
|
||
border-radius: var(--radius-lg);
|
||
padding: var(--spacing-lg);
|
||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||
border: 1px solid #E2E8F0;
|
||
}
|
||
|
||
.health-overview {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: var(--spacing-lg);
|
||
margin-top: var(--spacing-lg);
|
||
}
|
||
|
||
.health-metric {
|
||
text-align: center;
|
||
}
|
||
|
||
.health-circle-v2 {
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: var(--radius-round);
|
||
margin: 0 auto var(--spacing-sm);
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.circle-85 {
|
||
background: conic-gradient(var(--pet-secondary) 0deg, var(--pet-secondary) 306deg, #E5E7EB 306deg);
|
||
}
|
||
|
||
.circle-90 {
|
||
background: conic-gradient(var(--pet-primary) 0deg, var(--pet-primary) 324deg, #E5E7EB 324deg);
|
||
}
|
||
|
||
.circle-70 {
|
||
background: conic-gradient(var(--pet-warning) 0deg, var(--pet-warning) 252deg, #E5E7EB 252deg);
|
||
}
|
||
|
||
.circle-92 {
|
||
background: conic-gradient(var(--pet-accent) 0deg, var(--pet-accent) 331deg, #E5E7EB 331deg);
|
||
}
|
||
|
||
.health-circle-v2::before {
|
||
content: '';
|
||
width: 40px;
|
||
height: 40px;
|
||
background: white;
|
||
border-radius: var(--radius-round);
|
||
position: absolute;
|
||
}
|
||
|
||
.health-value {
|
||
position: relative;
|
||
z-index: 2;
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.health-name {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.recent-activities {
|
||
margin-top: var(--spacing-lg);
|
||
}
|
||
|
||
.activity-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--spacing-md);
|
||
}
|
||
|
||
.activity-item-v2 {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--spacing-md);
|
||
padding: var(--spacing-md);
|
||
background: #F8FAFC;
|
||
border-radius: var(--radius-md);
|
||
border-left: 4px solid var(--pet-accent);
|
||
}
|
||
|
||
.activity-icon-v2 {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: var(--radius-md);
|
||
background: var(--pet-accent);
|
||
color: white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 18px;
|
||
}
|
||
|
||
.activity-details {
|
||
flex: 1;
|
||
}
|
||
|
||
.activity-name {
|
||
font-weight: bold;
|
||
color: var(--text-primary);
|
||
margin-bottom: var(--spacing-xs);
|
||
}
|
||
|
||
.activity-desc {
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.activity-timestamp {
|
||
font-size: 12px;
|
||
color: var(--text-light);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.action-buttons-v2 {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: var(--spacing-md);
|
||
margin: var(--spacing-md);
|
||
}
|
||
|
||
.action-btn-v2 {
|
||
background: white;
|
||
border: 2px solid var(--pet-primary);
|
||
color: var(--pet-primary);
|
||
padding: var(--spacing-lg);
|
||
border-radius: var(--radius-lg);
|
||
text-align: center;
|
||
font-weight: bold;
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.action-btn-v2:hover {
|
||
background: var(--pet-primary);
|
||
color: white;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 25px rgba(255, 138, 128, 0.3);
|
||
}
|
||
|
||
.btn-icon {
|
||
font-size: 24px;
|
||
margin-bottom: var(--spacing-sm);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container dashboard-v2-container">
|
||
<!-- 英雄卡片 -->
|
||
<div class="hero-card">
|
||
<div class="hero-content">
|
||
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiByeD0iNTAiIGZpbGw9IiNGRjhBODAiLz4KPHRleHQgeD0iNTAiIHk9IjU1IiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMzAiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj7wn5GBPC90ZXh0Pgo8L3N2Zz4K"
|
||
alt="小橘" class="hero-avatar">
|
||
<div class="hero-info">
|
||
<h1 class="hero-name">小橘</h1>
|
||
<p class="hero-details">橘猫 · 公 · 2岁3个月</p>
|
||
<div class="hero-stats">
|
||
<div class="hero-stat">
|
||
<div class="hero-stat-value">645</div>
|
||
<div class="hero-stat-label">陪伴天数</div>
|
||
</div>
|
||
<div class="hero-stat">
|
||
<div class="hero-stat-value">85</div>
|
||
<div class="hero-stat-label">健康评分</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 仪表盘网格 -->
|
||
<div class="dashboard-grid">
|
||
<!-- 体重卡片 -->
|
||
<div class="dashboard-card">
|
||
<div class="card-header">
|
||
<span class="card-title">体重</span>
|
||
<div class="card-icon icon-weight">⚖️</div>
|
||
</div>
|
||
<div class="metric-display">
|
||
<div class="metric-value-large">
|
||
4.2<span class="metric-unit">kg</span>
|
||
</div>
|
||
<div class="metric-change change-positive">
|
||
<span>↗</span>
|
||
<span>+0.1kg 本周</span>
|
||
</div>
|
||
<div class="mini-chart">
|
||
<div class="chart-line"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 活动卡片 -->
|
||
<div class="dashboard-card">
|
||
<div class="card-header">
|
||
<span class="card-title">活动量</span>
|
||
<div class="card-icon icon-activity">🏃</div>
|
||
</div>
|
||
<div class="metric-display">
|
||
<div class="metric-value-large">
|
||
78<span class="metric-unit">%</span>
|
||
</div>
|
||
<div class="metric-change change-positive">
|
||
<span>↗</span>
|
||
<span>+5% 昨日</span>
|
||
</div>
|
||
<div class="mini-chart">
|
||
<div class="chart-line" style="clip-path: polygon(0 60%, 25% 40%, 50% 50%, 75% 30%, 100% 25%, 100% 100%, 0 100%);"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 食欲卡片 -->
|
||
<div class="dashboard-card">
|
||
<div class="card-header">
|
||
<span class="card-title">食欲</span>
|
||
<div class="card-icon icon-food">🍽️</div>
|
||
</div>
|
||
<div class="metric-display">
|
||
<div class="metric-value-large">
|
||
92<span class="metric-unit">%</span>
|
||
</div>
|
||
<div class="metric-change change-negative">
|
||
<span>↘</span>
|
||
<span>-3% 本周</span>
|
||
</div>
|
||
<div class="mini-chart">
|
||
<div class="chart-line" style="clip-path: polygon(0 40%, 25% 30%, 50% 35%, 75% 45%, 100% 50%, 100% 100%, 0 100%);"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 睡眠卡片 -->
|
||
<div class="dashboard-card">
|
||
<div class="card-header">
|
||
<span class="card-title">睡眠</span>
|
||
<div class="card-icon icon-sleep">😴</div>
|
||
</div>
|
||
<div class="metric-display">
|
||
<div class="metric-value-large">
|
||
14<span class="metric-unit">h</span>
|
||
</div>
|
||
<div class="metric-change change-neutral">
|
||
<span>→</span>
|
||
<span>正常范围</span>
|
||
</div>
|
||
<div class="mini-chart">
|
||
<div class="chart-line" style="clip-path: polygon(0 50%, 25% 45%, 50% 50%, 75% 48%, 100% 52%, 100% 100%, 0 100%);"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 健康概览卡片 -->
|
||
<div class="dashboard-grid">
|
||
<div class="full-width-card">
|
||
<div class="card-header">
|
||
<span class="card-title">健康状态概览</span>
|
||
<div class="card-icon" style="background: linear-gradient(135deg, var(--pet-secondary), var(--pet-accent)); color: white;">📊</div>
|
||
</div>
|
||
|
||
<div class="health-overview">
|
||
<div class="health-metric">
|
||
<div class="health-circle-v2 circle-85">
|
||
<div class="health-value">85</div>
|
||
</div>
|
||
<div class="health-name">综合健康</div>
|
||
</div>
|
||
<div class="health-metric">
|
||
<div class="health-circle-v2 circle-90">
|
||
<div class="health-value">90</div>
|
||
</div>
|
||
<div class="health-name">疫苗状态</div>
|
||
</div>
|
||
<div class="health-metric">
|
||
<div class="health-circle-v2 circle-70">
|
||
<div class="health-value">70</div>
|
||
</div>
|
||
<div class="health-name">驱虫状态</div>
|
||
</div>
|
||
<div class="health-metric">
|
||
<div class="health-circle-v2 circle-92">
|
||
<div class="health-value">92</div>
|
||
</div>
|
||
<div class="health-name">营养状态</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="recent-activities">
|
||
<h3 style="margin-bottom: var(--spacing-md); color: var(--text-primary); font-weight: bold;">最近活动</h3>
|
||
<div class="activity-list">
|
||
<div class="activity-item-v2">
|
||
<div class="activity-icon-v2">⚖️</div>
|
||
<div class="activity-details">
|
||
<div class="activity-name">体重记录</div>
|
||
<div class="activity-desc">今天体重4.2kg,比上周增加了0.1kg</div>
|
||
</div>
|
||
<div class="activity-timestamp">2小时前</div>
|
||
</div>
|
||
|
||
<div class="activity-item-v2">
|
||
<div class="activity-icon-v2" style="background: var(--pet-secondary);">💉</div>
|
||
<div class="activity-details">
|
||
<div class="activity-name">疫苗接种</div>
|
||
<div class="activity-desc">完成了狂犬疫苗第二针接种</div>
|
||
</div>
|
||
<div class="activity-timestamp">1天前</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 操作按钮 -->
|
||
<div class="action-buttons-v2">
|
||
<div class="action-btn-v2" onclick="interactions.handleButtonClick('addRecord')">
|
||
<div class="btn-icon">📝</div>
|
||
<div>添加记录</div>
|
||
</div>
|
||
<div class="action-btn-v2" onclick="interactions.handleButtonClick('aiChat')">
|
||
<div class="btn-icon">💬</div>
|
||
<div>AI助手</div>
|
||
</div>
|
||
<div class="action-btn-v2" onclick="interactions.handleButtonClick('healthChart')">
|
||
<div class="btn-icon">📊</div>
|
||
<div>健康报告</div>
|
||
</div>
|
||
<div class="action-btn-v2" onclick="interactions.handleButtonClick('timeline')">
|
||
<div class="btn-icon">⏰</div>
|
||
<div>成长时光</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="assets/js/common.js"></script>
|
||
<script>
|
||
// 卡片仪表盘式 V2 特有交互
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 卡片入场动画
|
||
const cards = document.querySelectorAll('.dashboard-card, .full-width-card');
|
||
cards.forEach((card, index) => {
|
||
card.style.opacity = '0';
|
||
card.style.transform = 'translateY(30px)';
|
||
|
||
setTimeout(() => {
|
||
card.style.transition = 'all 0.6s ease';
|
||
card.style.opacity = '1';
|
||
card.style.transform = 'translateY(0)';
|
||
}, index * 150);
|
||
});
|
||
|
||
// 数值动画
|
||
const metricValues = document.querySelectorAll('.metric-value-large');
|
||
metricValues.forEach(value => {
|
||
const text = value.textContent;
|
||
const number = parseFloat(text);
|
||
const unit = text.replace(number.toString(), '');
|
||
|
||
let current = 0;
|
||
const increment = number / 30;
|
||
|
||
const timer = setInterval(() => {
|
||
current += increment;
|
||
if (current >= number) {
|
||
current = number;
|
||
clearInterval(timer);
|
||
}
|
||
|
||
if (unit.includes('%') || unit.includes('h')) {
|
||
value.innerHTML = Math.round(current) + `<span class="metric-unit">${unit}</span>`;
|
||
} else {
|
||
value.innerHTML = current.toFixed(1) + `<span class="metric-unit">${unit}</span>`;
|
||
}
|
||
}, 50);
|
||
});
|
||
|
||
// 健康圆环动画
|
||
const healthCircles = document.querySelectorAll('.health-circle-v2');
|
||
healthCircles.forEach((circle, index) => {
|
||
setTimeout(() => {
|
||
circle.style.animation = 'scaleIn 0.8s ease forwards';
|
||
}, index * 100);
|
||
});
|
||
|
||
console.log('卡片仪表盘式 V2 原型已加载');
|
||
});
|
||
|
||
// 添加缩放动画
|
||
const style = document.createElement('style');
|
||
style.textContent = `
|
||
@keyframes scaleIn {
|
||
from {
|
||
transform: scale(0);
|
||
opacity: 0;
|
||
}
|
||
to {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes float {
|
||
0%, 100% { transform: translateX(0) translateY(0); }
|
||
50% { transform: translateX(-10px) translateY(-10px); }
|
||
}
|
||
`;
|
||
document.head.appendChild(style);
|
||
</script>
|
||
</body>
|
||
</html>
|