990 lines
22 KiB
Vue
990 lines
22 KiB
Vue
<template>
|
||
<view class="vaccine-container page-container-with-bg">
|
||
<!-- 疫苗状态概览卡片 -->
|
||
<view class="status-overview-card">
|
||
<view class="overview-header">
|
||
<text class="pet-name">{{ petName }}的疫苗管理</text>
|
||
<text class="last-update">最后更新:{{ lastUpdateTime }}</text>
|
||
</view>
|
||
|
||
<view class="status-display">
|
||
<view class="completion-circle">
|
||
<view class="circle-progress" :style="{ background: `conic-gradient(#4CAF50 0deg, #4CAF50 ${completionRate * 3.6}deg, #E0E0E0 ${completionRate * 3.6}deg)` }">
|
||
<view class="circle-center">
|
||
<text class="completion-rate">{{ completionRate }}%</text>
|
||
<text class="completion-label">完成度</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="status-stats">
|
||
<view class="stat-item">
|
||
<text class="stat-number" style="color: #4CAF50;">{{ statusSummary.completed }}</text>
|
||
<text class="stat-label">已完成</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-number" style="color: #FF9800;">{{ statusSummary.expiringSoon }}</text>
|
||
<text class="stat-label">即将到期</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-number" style="color: #F44336;">{{ statusSummary.expired }}</text>
|
||
<text class="stat-label">已过期</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-number" style="color: #9E9E9E;">{{ statusSummary.missing }}</text>
|
||
<text class="stat-label">未接种</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 疫苗分类切换 -->
|
||
<view class="category-selector">
|
||
<view class="selector-header">
|
||
<text class="selector-title">💉 疫苗分类</text>
|
||
</view>
|
||
<view class="category-tabs">
|
||
<view
|
||
class="category-tab"
|
||
:class="{ active: activeCategory === 'all' }"
|
||
@click="switchCategory('all')"
|
||
>
|
||
<text class="tab-text">全部</text>
|
||
</view>
|
||
<view
|
||
class="category-tab"
|
||
:class="{ active: activeCategory === 'core' }"
|
||
@click="switchCategory('core')"
|
||
>
|
||
<text class="tab-text">核心疫苗</text>
|
||
</view>
|
||
<view
|
||
class="category-tab"
|
||
:class="{ active: activeCategory === 'nonCore' }"
|
||
@click="switchCategory('nonCore')"
|
||
>
|
||
<text class="tab-text">非核心疫苗</text>
|
||
</view>
|
||
<view
|
||
class="category-tab"
|
||
:class="{ active: activeCategory === 'plan' }"
|
||
@click="switchCategory('plan')"
|
||
>
|
||
<text class="tab-text">接种计划</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 疫苗记录列表 -->
|
||
<view class="vaccine-records" v-if="activeCategory !== 'plan'">
|
||
<view class="records-header">
|
||
<text class="records-title">📋 疫苗记录</text>
|
||
<view class="add-record-btn" @click="addVaccineRecord">
|
||
<text class="add-btn-text">+ 添加</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="records-timeline" v-if="filteredRecords.length > 0">
|
||
<view
|
||
class="timeline-item"
|
||
v-for="record in filteredRecords"
|
||
:key="record.id"
|
||
>
|
||
<view class="timeline-dot" :class="getStatusClass(record)"></view>
|
||
<view class="timeline-content">
|
||
<view class="vaccine-card" :class="getStatusClass(record)">
|
||
<view class="vaccine-header">
|
||
<text class="vaccine-name">{{ record.vaccineName }}</text>
|
||
<view class="vaccine-status" :class="getStatusClass(record)">
|
||
<text class="status-text">{{ getStatusText(record) }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="vaccine-details">
|
||
<view class="detail-row">
|
||
<text class="detail-label">接种日期:</text>
|
||
<text class="detail-value">{{ formatDate(record.vaccineDate) }}</text>
|
||
</view>
|
||
<view class="detail-row">
|
||
<text class="detail-label">有效期至:</text>
|
||
<text class="detail-value">{{ formatDate(record.expiryDate) }}</text>
|
||
</view>
|
||
<view class="detail-row" v-if="record.hospital">
|
||
<text class="detail-label">接种医院:</text>
|
||
<text class="detail-value">{{ record.hospital }}</text>
|
||
</view>
|
||
<view class="detail-row" v-if="record.batchNumber">
|
||
<text class="detail-label">批次号:</text>
|
||
<text class="detail-value">{{ record.batchNumber }}</text>
|
||
</view>
|
||
<view class="detail-row" v-if="record.note">
|
||
<text class="detail-label">备注:</text>
|
||
<text class="detail-value">{{ record.note }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="empty-records" v-else>
|
||
<text class="empty-icon">💉</text>
|
||
<text class="empty-title">暂无{{ getCategoryName() }}记录</text>
|
||
<text class="empty-subtitle">点击添加按钮开始记录疫苗接种信息</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 接种计划 -->
|
||
<view class="vaccine-plan" v-if="activeCategory === 'plan'">
|
||
<view class="plan-header">
|
||
<text class="plan-title">📅 接种计划</text>
|
||
</view>
|
||
|
||
<view class="plan-list" v-if="vaccinePlan.length > 0">
|
||
<view
|
||
class="plan-item"
|
||
v-for="plan in vaccinePlan"
|
||
:key="plan.vaccineType"
|
||
:class="getPriorityClass(plan.priority)"
|
||
>
|
||
<view class="plan-priority" :class="getPriorityClass(plan.priority)">
|
||
<text class="priority-text">{{ getPriorityText(plan.priority) }}</text>
|
||
</view>
|
||
|
||
<view class="plan-content">
|
||
<text class="plan-vaccine-name">{{ plan.vaccineName }}</text>
|
||
<text class="plan-due-date">建议接种时间:{{ formatDate(plan.nextDueDate) }}</text>
|
||
<text class="plan-reason">{{ plan.reason }}</text>
|
||
</view>
|
||
|
||
<view class="plan-action" @click="scheduleVaccine(plan)">
|
||
<text class="action-text">安排接种</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- AI分析卡片 -->
|
||
<view class="ai-analysis-card">
|
||
<view class="analysis-header">
|
||
<text class="analysis-title">🤖 AI疫苗分析</text>
|
||
<view class="analysis-badge">
|
||
<text class="badge-text">智能分析</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="analysis-content">
|
||
<view class="analysis-section">
|
||
<text class="section-title">📊 完整性评估</text>
|
||
<text class="section-content">{{ aiAnalysis.completenessAnalysis }}</text>
|
||
</view>
|
||
|
||
<view class="analysis-section">
|
||
<text class="section-title">⏰ 时效性分析</text>
|
||
<text class="section-content">{{ aiAnalysis.timelinessAnalysis }}</text>
|
||
</view>
|
||
|
||
<view class="analysis-section">
|
||
<text class="section-title">💡 个性化建议</text>
|
||
<text class="section-content">{{ aiAnalysis.recommendations }}</text>
|
||
</view>
|
||
|
||
<view class="analysis-section" v-if="aiAnalysis.riskAssessment">
|
||
<text class="section-title">⚠️ 风险提醒</text>
|
||
<text class="section-content warning">{{ aiAnalysis.riskAssessment }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
// 疫苗管理器 - 从 utils/vaccineManager.js 移入
|
||
const vaccineManager = {
|
||
storageKey: 'pet_vaccine_records',
|
||
|
||
getVaccineRecords(petId) {
|
||
try {
|
||
const allRecords = uni.getStorageSync(this.storageKey) || {}
|
||
return allRecords[petId] || []
|
||
} catch (error) {
|
||
console.error('获取疫苗记录失败:', error)
|
||
return []
|
||
}
|
||
},
|
||
|
||
addVaccineRecord(petId, vaccineData) {
|
||
try {
|
||
const allRecords = uni.getStorageSync(this.storageKey) || {}
|
||
if (!allRecords[petId]) {
|
||
allRecords[petId] = []
|
||
}
|
||
|
||
const newRecord = {
|
||
id: Date.now(),
|
||
petId: petId,
|
||
...vaccineData,
|
||
createTime: new Date().toISOString()
|
||
}
|
||
|
||
allRecords[petId].push(newRecord)
|
||
allRecords[petId].sort((a, b) => new Date(a.date) - new Date(b.date))
|
||
|
||
uni.setStorageSync(this.storageKey, allRecords)
|
||
return true
|
||
} catch (error) {
|
||
console.error('添加疫苗记录失败:', error)
|
||
return false
|
||
}
|
||
},
|
||
|
||
deleteVaccineRecord(petId, recordId) {
|
||
try {
|
||
const allRecords = uni.getStorageSync(this.storageKey) || {}
|
||
if (allRecords[petId]) {
|
||
allRecords[petId] = allRecords[petId].filter(record => record.id !== recordId)
|
||
uni.setStorageSync(this.storageKey, allRecords)
|
||
}
|
||
return true
|
||
} catch (error) {
|
||
console.error('删除疫苗记录失败:', error)
|
||
return false
|
||
}
|
||
},
|
||
|
||
getVaccineTypes() {
|
||
return [
|
||
{ value: 'rabies', label: '狂犬疫苗', required: true },
|
||
{ value: 'dhpp', label: '四联疫苗', required: true },
|
||
{ value: 'feline', label: '猫三联', required: true },
|
||
{ value: 'other', label: '其他疫苗', required: false }
|
||
]
|
||
}
|
||
}
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
petId: '',
|
||
petName: '',
|
||
petInfo: {},
|
||
lastUpdateTime: '',
|
||
|
||
// 状态统计
|
||
statusSummary: {
|
||
completed: 0,
|
||
expiringSoon: 0,
|
||
expired: 0,
|
||
missing: 0,
|
||
total: 0,
|
||
completionRate: 0
|
||
},
|
||
completionRate: 0,
|
||
|
||
// 分类切换
|
||
activeCategory: 'all',
|
||
|
||
// 疫苗记录
|
||
allRecords: [],
|
||
filteredRecords: [],
|
||
|
||
// 接种计划
|
||
vaccinePlan: [],
|
||
|
||
// AI分析
|
||
aiAnalysis: {
|
||
completenessAnalysis: '',
|
||
timelinessAnalysis: '',
|
||
recommendations: '',
|
||
riskAssessment: ''
|
||
}
|
||
}
|
||
},
|
||
|
||
onLoad(options) {
|
||
this.petId = options.petId || ''
|
||
this.petName = options.petName || '宠物'
|
||
this.loadPetInfo()
|
||
this.loadVaccineData()
|
||
},
|
||
|
||
methods: {
|
||
loadPetInfo() {
|
||
try {
|
||
const pets = uni.getStorageSync('pets') || []
|
||
this.petInfo = pets.find(pet => pet.id == this.petId) || {
|
||
id: this.petId,
|
||
name: this.petName,
|
||
breed: '橘猫',
|
||
age: 2,
|
||
gender: '公'
|
||
}
|
||
} catch (error) {
|
||
console.error('加载宠物信息失败:', error)
|
||
}
|
||
},
|
||
|
||
loadVaccineData() {
|
||
// 获取疫苗记录
|
||
this.allRecords = vaccineManager.getVaccineRecords(this.petId)
|
||
this.filterRecords()
|
||
|
||
// 获取状态统计
|
||
this.statusSummary = vaccineManager.getVaccineStatusSummary(this.petId)
|
||
this.completionRate = this.statusSummary.completionRate
|
||
|
||
// 生成接种计划
|
||
this.vaccinePlan = vaccineManager.generateVaccinePlan(this.petId, this.petInfo)
|
||
|
||
// 生成AI分析
|
||
this.aiAnalysis = vaccineManager.generateAIAnalysis(this.petId, this.petInfo)
|
||
|
||
// 更新最后更新时间
|
||
if (this.allRecords.length > 0) {
|
||
const latestRecord = this.allRecords.sort((a, b) => new Date(b.vaccineDate) - new Date(a.vaccineDate))[0]
|
||
const lastDate = new Date(latestRecord.vaccineDate)
|
||
this.lastUpdateTime = `${lastDate.getMonth() + 1}-${lastDate.getDate()} ${lastDate.getHours()}:${lastDate.getMinutes().toString().padStart(2, '0')}`
|
||
} else {
|
||
this.lastUpdateTime = '暂无记录'
|
||
}
|
||
},
|
||
|
||
switchCategory(category) {
|
||
this.activeCategory = category
|
||
this.filterRecords()
|
||
},
|
||
|
||
filterRecords() {
|
||
if (this.activeCategory === 'all') {
|
||
this.filteredRecords = this.allRecords
|
||
} else {
|
||
this.filteredRecords = this.allRecords.filter(record => record.category === this.activeCategory)
|
||
}
|
||
|
||
// 按接种日期倒序排列
|
||
this.filteredRecords.sort((a, b) => new Date(b.vaccineDate) - new Date(a.vaccineDate))
|
||
},
|
||
|
||
getCategoryName() {
|
||
const categoryNames = {
|
||
'all': '疫苗',
|
||
'core': '核心疫苗',
|
||
'nonCore': '非核心疫苗'
|
||
}
|
||
return categoryNames[this.activeCategory] || '疫苗'
|
||
},
|
||
|
||
getStatusClass(record) {
|
||
const status = vaccineManager.getVaccineStatus(record)
|
||
return status // 'valid', 'expiring', 'expired'
|
||
},
|
||
|
||
getStatusText(record) {
|
||
const status = vaccineManager.getVaccineStatus(record)
|
||
const statusTexts = {
|
||
'valid': '有效',
|
||
'expiring': '即将到期',
|
||
'expired': '已过期'
|
||
}
|
||
return statusTexts[status] || '未知'
|
||
},
|
||
|
||
getPriorityClass(priority) {
|
||
return priority // 'high', 'medium', 'low'
|
||
},
|
||
|
||
getPriorityText(priority) {
|
||
const priorityTexts = {
|
||
'high': '紧急',
|
||
'medium': '建议',
|
||
'low': '可选'
|
||
}
|
||
return priorityTexts[priority] || '未知'
|
||
},
|
||
|
||
formatDate(dateStr) {
|
||
if (!dateStr) return ''
|
||
const date = new Date(dateStr)
|
||
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
|
||
},
|
||
|
||
addVaccineRecord() {
|
||
uni.showModal({
|
||
title: '添加疫苗记录',
|
||
content: '跳转到添加疫苗记录页面?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 这里可以跳转到添加疫苗记录的页面
|
||
// 或者显示一个表单弹窗
|
||
this.showAddVaccineForm()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
showAddVaccineForm() {
|
||
// 简化版添加功能,实际项目中可以创建专门的表单页面
|
||
uni.showToast({
|
||
title: '功能开发中',
|
||
icon: 'none'
|
||
})
|
||
},
|
||
|
||
scheduleVaccine(plan) {
|
||
uni.showModal({
|
||
title: '安排接种',
|
||
content: `是否要安排${plan.vaccineName}的接种?`,
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.showToast({
|
||
title: '已添加到日程',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.vaccine-container {
|
||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||
min-height: 100vh;
|
||
padding: 20rpx;
|
||
}
|
||
|
||
/* 疫苗状态概览卡片 */
|
||
.status-overview-card {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 28rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.overview-header {
|
||
text-align: center;
|
||
margin-bottom: 32rpx;
|
||
|
||
.pet-name {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.last-update {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
.status-display {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 32rpx;
|
||
|
||
.completion-circle {
|
||
.circle-progress {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
|
||
.circle-center {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
background: white;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.completion-rate {
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
color: #4CAF50;
|
||
line-height: 1;
|
||
}
|
||
|
||
.completion-label {
|
||
font-size: 18rpx;
|
||
color: #999999;
|
||
margin-top: 4rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.status-stats {
|
||
flex: 1;
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16rpx;
|
||
|
||
.stat-item {
|
||
text-align: center;
|
||
|
||
.stat-number {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
display: block;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
display: block;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 分类选择器 */
|
||
.category-selector {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 28rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.selector-header {
|
||
margin-bottom: 28rpx;
|
||
|
||
.selector-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
}
|
||
|
||
.category-tabs {
|
||
display: flex;
|
||
gap: 12rpx;
|
||
|
||
.category-tab {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding: 16rpx 12rpx;
|
||
border-radius: 16rpx;
|
||
background: rgba(255, 138, 128, 0.1);
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
background: #FF8A80;
|
||
|
||
.tab-text {
|
||
color: white;
|
||
}
|
||
}
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.tab-text {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 疫苗记录列表 */
|
||
.vaccine-records {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 28rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.records-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28rpx;
|
||
|
||
.records-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
|
||
.add-record-btn {
|
||
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
||
border-radius: 20rpx;
|
||
padding: 12rpx 24rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.add-btn-text {
|
||
font-size: 24rpx;
|
||
color: white;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.records-timeline {
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 24rpx;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 2rpx;
|
||
background: #E0E0E0;
|
||
}
|
||
|
||
.timeline-item {
|
||
position: relative;
|
||
margin-bottom: 32rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.timeline-dot {
|
||
position: absolute;
|
||
left: 16rpx;
|
||
top: 24rpx;
|
||
width: 16rpx;
|
||
height: 16rpx;
|
||
border-radius: 50%;
|
||
z-index: 1;
|
||
|
||
&.valid {
|
||
background: #4CAF50;
|
||
}
|
||
|
||
&.expiring {
|
||
background: #FF9800;
|
||
}
|
||
|
||
&.expired {
|
||
background: #F44336;
|
||
}
|
||
}
|
||
|
||
.timeline-content {
|
||
margin-left: 56rpx;
|
||
|
||
.vaccine-card {
|
||
background: white;
|
||
border-radius: 20rpx;
|
||
padding: 24rpx;
|
||
border-left: 4rpx solid #E0E0E0;
|
||
transition: all 0.3s ease;
|
||
|
||
&.valid {
|
||
border-left-color: #4CAF50;
|
||
}
|
||
|
||
&.expiring {
|
||
border-left-color: #FF9800;
|
||
}
|
||
|
||
&.expired {
|
||
border-left-color: #F44336;
|
||
}
|
||
|
||
.vaccine-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
|
||
.vaccine-name {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
|
||
.vaccine-status {
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 20rpx;
|
||
|
||
&.valid {
|
||
background: #E8F5E8;
|
||
color: #4CAF50;
|
||
}
|
||
|
||
&.expiring {
|
||
background: #FFF3E0;
|
||
color: #FF9800;
|
||
}
|
||
|
||
&.expired {
|
||
background: #FFEBEE;
|
||
color: #F44336;
|
||
}
|
||
|
||
.status-text {
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.vaccine-details {
|
||
.detail-row {
|
||
display: flex;
|
||
margin-bottom: 8rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.detail-label {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
min-width: 120rpx;
|
||
}
|
||
|
||
.detail-value {
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.empty-records {
|
||
text-align: center;
|
||
padding: 80rpx 40rpx;
|
||
|
||
.empty-icon {
|
||
font-size: 80rpx;
|
||
margin-bottom: 24rpx;
|
||
display: block;
|
||
}
|
||
|
||
.empty-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
margin-bottom: 12rpx;
|
||
display: block;
|
||
}
|
||
|
||
.empty-subtitle {
|
||
font-size: 26rpx;
|
||
color: #999999;
|
||
display: block;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 接种计划 */
|
||
.vaccine-plan {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 28rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.plan-header {
|
||
margin-bottom: 28rpx;
|
||
|
||
.plan-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
}
|
||
|
||
.plan-list {
|
||
.plan-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
background: white;
|
||
border-radius: 20rpx;
|
||
padding: 20rpx;
|
||
margin-bottom: 16rpx;
|
||
border-left: 4rpx solid #E0E0E0;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
&.high {
|
||
border-left-color: #F44336;
|
||
}
|
||
|
||
&.medium {
|
||
border-left-color: #FF9800;
|
||
}
|
||
|
||
&.low {
|
||
border-left-color: #4CAF50;
|
||
}
|
||
|
||
.plan-priority {
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 20rpx;
|
||
font-weight: 500;
|
||
|
||
&.high {
|
||
background: #FFEBEE;
|
||
color: #F44336;
|
||
}
|
||
|
||
&.medium {
|
||
background: #FFF3E0;
|
||
color: #FF9800;
|
||
}
|
||
|
||
&.low {
|
||
background: #E8F5E8;
|
||
color: #4CAF50;
|
||
}
|
||
|
||
.priority-text {
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
|
||
.plan-content {
|
||
flex: 1;
|
||
|
||
.plan-vaccine-name {
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
display: block;
|
||
margin-bottom: 6rpx;
|
||
}
|
||
|
||
.plan-due-date {
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
display: block;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
|
||
.plan-reason {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
.plan-action {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
border-radius: 16rpx;
|
||
padding: 12rpx 20rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.2);
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.action-text {
|
||
font-size: 22rpx;
|
||
color: #FF8A80;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* AI分析卡片 */
|
||
.ai-analysis-card {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
border-radius: 28rpx;
|
||
padding: 32rpx;
|
||
margin-bottom: 40rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.analysis-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28rpx;
|
||
|
||
.analysis-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
}
|
||
|
||
.analysis-badge {
|
||
background: linear-gradient(135deg, #64B5F6, #81C784);
|
||
border-radius: 20rpx;
|
||
padding: 8rpx 16rpx;
|
||
|
||
.badge-text {
|
||
font-size: 20rpx;
|
||
color: white;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.analysis-content {
|
||
.analysis-section {
|
||
margin-bottom: 24rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 26rpx;
|
||
font-weight: bold;
|
||
color: #333333;
|
||
margin-bottom: 12rpx;
|
||
display: block;
|
||
}
|
||
|
||
.section-content {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
line-height: 1.6;
|
||
display: block;
|
||
|
||
&.warning {
|
||
color: #FF9800;
|
||
background: #FFF3E0;
|
||
padding: 16rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|