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>
|