407 lines
11 KiB
JavaScript
407 lines
11 KiB
JavaScript
/**
|
|
* 宠物疫苗管理工具类
|
|
* 负责疫苗数据的存储、分析和AI建议生成
|
|
*/
|
|
|
|
class VaccineManager {
|
|
constructor() {
|
|
this.storageKey = 'pet_vaccine_records'
|
|
|
|
// 疫苗类型定义
|
|
this.vaccineTypes = {
|
|
core: {
|
|
'rabies': {
|
|
name: '狂犬病疫苗',
|
|
duration: 365, // 有效期天数
|
|
interval: 365, // 接种间隔天数
|
|
required: true,
|
|
description: '预防狂犬病,法律要求必须接种'
|
|
},
|
|
'fvrcp': {
|
|
name: '猫三联疫苗',
|
|
duration: 365,
|
|
interval: 365,
|
|
required: true,
|
|
description: '预防猫瘟热、猫杯状病毒、猫鼻气管炎'
|
|
}
|
|
},
|
|
nonCore: {
|
|
'felv': {
|
|
name: '猫白血病疫苗',
|
|
duration: 365,
|
|
interval: 365,
|
|
required: false,
|
|
description: '预防猫白血病病毒感染'
|
|
},
|
|
'fip': {
|
|
name: '猫传腹疫苗',
|
|
duration: 365,
|
|
interval: 365,
|
|
required: false,
|
|
description: '预防猫传染性腹膜炎'
|
|
},
|
|
'chlamydia': {
|
|
name: '猫衣原体疫苗',
|
|
duration: 365,
|
|
interval: 365,
|
|
required: false,
|
|
description: '预防猫衣原体感染'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取宠物的疫苗记录
|
|
* @param {string} petId 宠物ID
|
|
* @returns {Array} 疫苗记录数组
|
|
*/
|
|
getVaccineRecords(petId) {
|
|
try {
|
|
const allRecords = uni.getStorageSync(this.storageKey) || {}
|
|
let records = allRecords[petId] || []
|
|
|
|
// 如果没有数据,初始化一些测试数据
|
|
if (records.length === 0) {
|
|
records = this.initializeTestData(petId)
|
|
allRecords[petId] = records
|
|
uni.setStorageSync(this.storageKey, allRecords)
|
|
}
|
|
|
|
return records
|
|
} catch (error) {
|
|
console.error('获取疫苗记录失败:', error)
|
|
return this.initializeTestData(petId)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 初始化测试数据
|
|
* @param {string} petId 宠物ID
|
|
* @returns {Array} 测试数据数组
|
|
*/
|
|
initializeTestData(petId) {
|
|
const now = new Date()
|
|
const testData = []
|
|
|
|
// 狂犬病疫苗记录
|
|
testData.push({
|
|
id: Date.now() + 1,
|
|
petId: petId,
|
|
vaccineType: 'rabies',
|
|
vaccineName: '狂犬病疫苗',
|
|
vaccineDate: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
expiryDate: new Date(now.getTime() + 335 * 24 * 60 * 60 * 1000).toISOString(),
|
|
batchNumber: 'RAB2024001',
|
|
hospital: '宠物医院',
|
|
veterinarian: '张医生',
|
|
note: '首次接种',
|
|
category: 'core',
|
|
status: 'completed'
|
|
})
|
|
|
|
// 猫三联疫苗记录
|
|
testData.push({
|
|
id: Date.now() + 2,
|
|
petId: petId,
|
|
vaccineType: 'fvrcp',
|
|
vaccineName: '猫三联疫苗',
|
|
vaccineDate: new Date(now.getTime() - 45 * 24 * 60 * 60 * 1000).toISOString(),
|
|
expiryDate: new Date(now.getTime() + 320 * 24 * 60 * 60 * 1000).toISOString(),
|
|
batchNumber: 'FVRCP2024001',
|
|
hospital: '宠物医院',
|
|
veterinarian: '李医生',
|
|
note: '年度接种',
|
|
category: 'core',
|
|
status: 'completed'
|
|
})
|
|
|
|
// 猫白血病疫苗记录
|
|
testData.push({
|
|
id: Date.now() + 3,
|
|
petId: petId,
|
|
vaccineType: 'felv',
|
|
vaccineName: '猫白血病疫苗',
|
|
vaccineDate: new Date(now.getTime() - 60 * 24 * 60 * 60 * 1000).toISOString(),
|
|
expiryDate: new Date(now.getTime() + 305 * 24 * 60 * 60 * 1000).toISOString(),
|
|
batchNumber: 'FELV2024001',
|
|
hospital: '宠物医院',
|
|
veterinarian: '王医生',
|
|
note: '可选接种',
|
|
category: 'nonCore',
|
|
status: 'completed'
|
|
})
|
|
|
|
return testData
|
|
}
|
|
|
|
/**
|
|
* 添加疫苗记录
|
|
* @param {string} petId 宠物ID
|
|
* @param {Object} record 疫苗记录
|
|
*/
|
|
addVaccineRecord(petId, record) {
|
|
try {
|
|
const allRecords = uni.getStorageSync(this.storageKey) || {}
|
|
if (!allRecords[petId]) {
|
|
allRecords[petId] = []
|
|
}
|
|
|
|
const vaccineInfo = this.getVaccineInfo(record.vaccineType)
|
|
const vaccineDate = new Date(record.vaccineDate)
|
|
const expiryDate = new Date(vaccineDate.getTime() + vaccineInfo.duration * 24 * 60 * 60 * 1000)
|
|
|
|
const newRecord = {
|
|
id: Date.now(),
|
|
petId: petId,
|
|
vaccineType: record.vaccineType,
|
|
vaccineName: vaccineInfo.name,
|
|
vaccineDate: record.vaccineDate,
|
|
expiryDate: expiryDate.toISOString(),
|
|
batchNumber: record.batchNumber || '',
|
|
hospital: record.hospital || '',
|
|
veterinarian: record.veterinarian || '',
|
|
note: record.note || '',
|
|
category: vaccineInfo.category,
|
|
status: 'completed'
|
|
}
|
|
|
|
allRecords[petId].push(newRecord)
|
|
allRecords[petId].sort((a, b) => new Date(b.vaccineDate) - new Date(a.vaccineDate))
|
|
|
|
uni.setStorageSync(this.storageKey, allRecords)
|
|
return newRecord
|
|
} catch (error) {
|
|
console.error('添加疫苗记录失败:', error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取疫苗信息
|
|
* @param {string} vaccineType 疫苗类型
|
|
* @returns {Object} 疫苗信息
|
|
*/
|
|
getVaccineInfo(vaccineType) {
|
|
const coreVaccine = this.vaccineTypes.core[vaccineType]
|
|
if (coreVaccine) {
|
|
return { ...coreVaccine, category: 'core' }
|
|
}
|
|
|
|
const nonCoreVaccine = this.vaccineTypes.nonCore[vaccineType]
|
|
if (nonCoreVaccine) {
|
|
return { ...nonCoreVaccine, category: 'nonCore' }
|
|
}
|
|
|
|
return {
|
|
name: '未知疫苗',
|
|
duration: 365,
|
|
interval: 365,
|
|
required: false,
|
|
category: 'unknown'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取疫苗状态统计
|
|
* @param {string} petId 宠物ID
|
|
* @returns {Object} 状态统计
|
|
*/
|
|
getVaccineStatusSummary(petId) {
|
|
const records = this.getVaccineRecords(petId)
|
|
const now = new Date()
|
|
|
|
let completed = 0
|
|
let expiringSoon = 0 // 30天内到期
|
|
let expired = 0
|
|
let missing = 0
|
|
|
|
// 检查核心疫苗
|
|
Object.keys(this.vaccineTypes.core).forEach(vaccineType => {
|
|
const latestRecord = records
|
|
.filter(r => r.vaccineType === vaccineType)
|
|
.sort((a, b) => new Date(b.vaccineDate) - new Date(a.vaccineDate))[0]
|
|
|
|
if (!latestRecord) {
|
|
missing++
|
|
} else {
|
|
const expiryDate = new Date(latestRecord.expiryDate)
|
|
const daysUntilExpiry = Math.ceil((expiryDate - now) / (1000 * 60 * 60 * 24))
|
|
|
|
if (daysUntilExpiry < 0) {
|
|
expired++
|
|
} else if (daysUntilExpiry <= 30) {
|
|
expiringSoon++
|
|
} else {
|
|
completed++
|
|
}
|
|
}
|
|
})
|
|
|
|
const total = Object.keys(this.vaccineTypes.core).length
|
|
const completionRate = Math.round((completed / total) * 100)
|
|
|
|
return {
|
|
completed,
|
|
expiringSoon,
|
|
expired,
|
|
missing,
|
|
total,
|
|
completionRate
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取疫苗状态
|
|
* @param {Object} record 疫苗记录
|
|
* @returns {string} 状态
|
|
*/
|
|
getVaccineStatus(record) {
|
|
const now = new Date()
|
|
const expiryDate = new Date(record.expiryDate)
|
|
const daysUntilExpiry = Math.ceil((expiryDate - now) / (1000 * 60 * 60 * 24))
|
|
|
|
if (daysUntilExpiry < 0) {
|
|
return 'expired'
|
|
} else if (daysUntilExpiry <= 30) {
|
|
return 'expiring'
|
|
} else {
|
|
return 'valid'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 生成疫苗接种计划
|
|
* @param {string} petId 宠物ID
|
|
* @param {Object} petInfo 宠物信息
|
|
* @returns {Array} 接种计划
|
|
*/
|
|
generateVaccinePlan(petId, petInfo) {
|
|
const records = this.getVaccineRecords(petId)
|
|
const now = new Date()
|
|
const plan = []
|
|
|
|
// 检查所有疫苗类型
|
|
const allVaccineTypes = { ...this.vaccineTypes.core, ...this.vaccineTypes.nonCore }
|
|
|
|
Object.entries(allVaccineTypes).forEach(([vaccineType, vaccineInfo]) => {
|
|
const latestRecord = records
|
|
.filter(r => r.vaccineType === vaccineType)
|
|
.sort((a, b) => new Date(b.vaccineDate) - new Date(a.vaccineDate))[0]
|
|
|
|
let nextDueDate
|
|
let priority = 'low'
|
|
let reason = ''
|
|
|
|
if (!latestRecord) {
|
|
// 从未接种
|
|
if (vaccineInfo.required) {
|
|
nextDueDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000) // 一周后
|
|
priority = 'high'
|
|
reason = '必需疫苗,建议尽快接种'
|
|
} else {
|
|
nextDueDate = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000) // 一个月后
|
|
priority = 'medium'
|
|
reason = '可选疫苗,建议接种'
|
|
}
|
|
} else {
|
|
// 已接种,计算下次接种时间
|
|
const lastVaccineDate = new Date(latestRecord.vaccineDate)
|
|
nextDueDate = new Date(lastVaccineDate.getTime() + vaccineInfo.interval * 24 * 60 * 60 * 1000)
|
|
|
|
const daysUntilDue = Math.ceil((nextDueDate - now) / (1000 * 60 * 60 * 24))
|
|
|
|
if (daysUntilDue <= 0) {
|
|
priority = 'high'
|
|
reason = '疫苗已过期,需要立即接种'
|
|
} else if (daysUntilDue <= 30) {
|
|
priority = 'medium'
|
|
reason = '疫苗即将到期,建议提前接种'
|
|
} else {
|
|
priority = 'low'
|
|
reason = '疫苗有效期内'
|
|
}
|
|
}
|
|
|
|
plan.push({
|
|
vaccineType,
|
|
vaccineName: vaccineInfo.name,
|
|
category: vaccineType in this.vaccineTypes.core ? 'core' : 'nonCore',
|
|
nextDueDate: nextDueDate.toISOString(),
|
|
priority,
|
|
reason,
|
|
required: vaccineInfo.required,
|
|
lastVaccineDate: latestRecord ? latestRecord.vaccineDate : null
|
|
})
|
|
})
|
|
|
|
// 按优先级和到期时间排序
|
|
plan.sort((a, b) => {
|
|
const priorityOrder = { 'high': 3, 'medium': 2, 'low': 1 }
|
|
if (priorityOrder[a.priority] !== priorityOrder[b.priority]) {
|
|
return priorityOrder[b.priority] - priorityOrder[a.priority]
|
|
}
|
|
return new Date(a.nextDueDate) - new Date(b.nextDueDate)
|
|
})
|
|
|
|
return plan
|
|
}
|
|
|
|
/**
|
|
* 生成AI分析建议
|
|
* @param {string} petId 宠物ID
|
|
* @param {Object} petInfo 宠物信息
|
|
* @returns {Object} AI分析结果
|
|
*/
|
|
generateAIAnalysis(petId, petInfo) {
|
|
const records = this.getVaccineRecords(petId)
|
|
const statusSummary = this.getVaccineStatusSummary(petId)
|
|
const vaccinePlan = this.generateVaccinePlan(petId, petInfo)
|
|
|
|
// 疫苗完整性分析
|
|
let completenessAnalysis = ''
|
|
if (statusSummary.completionRate >= 100) {
|
|
completenessAnalysis = `${petInfo.name}的核心疫苗接种完整,免疫保护良好。`
|
|
} else if (statusSummary.completionRate >= 50) {
|
|
completenessAnalysis = `${petInfo.name}的疫苗接种基本完整,但还有${statusSummary.missing}种核心疫苗需要接种。`
|
|
} else {
|
|
completenessAnalysis = `${petInfo.name}的疫苗接种不完整,缺少${statusSummary.missing}种核心疫苗,存在健康风险。`
|
|
}
|
|
|
|
// 时效性分析
|
|
let timelinessAnalysis = ''
|
|
if (statusSummary.expired > 0) {
|
|
timelinessAnalysis = `有${statusSummary.expired}种疫苗已过期,免疫保护可能失效,建议立即补种。`
|
|
} else if (statusSummary.expiringSoon > 0) {
|
|
timelinessAnalysis = `有${statusSummary.expiringSoon}种疫苗即将到期,建议提前安排接种。`
|
|
} else {
|
|
timelinessAnalysis = '所有疫苗均在有效期内,免疫保护充分。'
|
|
}
|
|
|
|
// 个性化建议
|
|
const highPriorityVaccines = vaccinePlan.filter(v => v.priority === 'high')
|
|
let recommendations = ''
|
|
if (highPriorityVaccines.length > 0) {
|
|
const vaccineNames = highPriorityVaccines.map(v => v.vaccineName).join('、')
|
|
recommendations = `建议优先接种:${vaccineNames}。根据${petInfo.name}的年龄(${petInfo.age}岁)和生活环境,这些疫苗对健康保护至关重要。`
|
|
} else {
|
|
recommendations = `当前疫苗状态良好,建议按计划进行常规疫苗接种。定期检查疫苗有效期,确保免疫保护持续有效。`
|
|
}
|
|
|
|
// 风险评估
|
|
let riskAssessment = ''
|
|
if (statusSummary.expired > 0 || statusSummary.missing > 0) {
|
|
riskAssessment = '存在免疫空白期,建议避免接触其他动物,减少外出,直到完成疫苗接种。'
|
|
}
|
|
|
|
return {
|
|
completenessAnalysis,
|
|
timelinessAnalysis,
|
|
recommendations,
|
|
riskAssessment
|
|
}
|
|
}
|
|
}
|
|
|
|
export default new VaccineManager()
|