diff --git a/pages/pets/health-charts.vue b/pages/pets/health-charts.vue index a353ae5..382dddc 100644 --- a/pages/pets/health-charts.vue +++ b/pages/pets/health-charts.vue @@ -1,27 +1,863 @@ diff --git a/utils/healthManager.js b/utils/healthManager.js new file mode 100644 index 0000000..655223d --- /dev/null +++ b/utils/healthManager.js @@ -0,0 +1,501 @@ +/** + * 宠物健康数据管理工具类 + * 负责整合体重、疫苗、健康记录等数据,提供综合健康评估 + */ + +import weightManager from './weightManager.js' +import vaccineManager from './vaccineManager.js' + +class HealthManager { + constructor() { + this.storageKey = 'pet_health_records' + + // 健康记录类型定义 + this.recordTypes = { + medical: { + name: '就医记录', + icon: '🏥', + color: '#F44336' + }, + checkup: { + name: '体检记录', + icon: '🔍', + color: '#2196F3' + }, + symptom: { + name: '异常症状', + icon: '⚠️', + color: '#FF9800' + }, + medication: { + name: '用药记录', + icon: '💊', + color: '#9C27B0' + }, + surgery: { + name: '手术记录', + icon: '🔪', + color: '#795548' + } + } + + // 健康评分权重配置 + this.scoreWeights = { + weight: 0.3, // 体重状态权重 + vaccine: 0.3, // 疫苗状态权重 + medical: 0.2, // 医疗记录权重 + growth: 0.2 // 生长发育权重 + } + } + + /** + * 获取宠物的健康记录 + * @param {string} petId 宠物ID + * @returns {Array} 健康记录数组 + */ + getHealthRecords(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, + type: 'checkup', + title: '年度体检', + date: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString(), + description: '全面体检,各项指标正常', + result: 'normal', + hospital: '宠物医院', + veterinarian: '张医生', + cost: 200, + note: '建议半年后复查' + }) + + // 就医记录 + testData.push({ + id: Date.now() + 2, + petId: petId, + type: 'medical', + title: '感冒治疗', + date: new Date(now.getTime() - 60 * 24 * 60 * 60 * 1000).toISOString(), + description: '轻微感冒症状,开具感冒药', + result: 'treated', + hospital: '宠物医院', + veterinarian: '李医生', + cost: 80, + note: '已康复' + }) + + // 异常症状记录 + testData.push({ + id: Date.now() + 3, + petId: petId, + type: 'symptom', + title: '食欲不振', + date: new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000).toISOString(), + description: '连续两天食欲不佳,精神状态一般', + result: 'resolved', + hospital: '', + veterinarian: '', + cost: 0, + note: '自行恢复' + }) + + return testData + } + + /** + * 添加健康记录 + * @param {string} petId 宠物ID + * @param {Object} record 健康记录 + */ + addHealthRecord(petId, record) { + try { + const allRecords = uni.getStorageSync(this.storageKey) || {} + if (!allRecords[petId]) { + allRecords[petId] = [] + } + + const newRecord = { + id: Date.now(), + petId: petId, + type: record.type, + title: record.title, + date: record.date || new Date().toISOString(), + description: record.description || '', + result: record.result || 'pending', + hospital: record.hospital || '', + veterinarian: record.veterinarian || '', + cost: record.cost || 0, + note: record.note || '' + } + + allRecords[petId].push(newRecord) + allRecords[petId].sort((a, b) => new Date(b.date) - new Date(a.date)) + + uni.setStorageSync(this.storageKey, allRecords) + return newRecord + } catch (error) { + console.error('添加健康记录失败:', error) + return null + } + } + + /** + * 获取综合健康数据 + * @param {string} petId 宠物ID + * @param {Object} petInfo 宠物信息 + * @returns {Object} 综合健康数据 + */ + getComprehensiveHealthData(petId, petInfo) { + // 获取各类数据 + const weightData = this.getWeightHealthData(petId) + const vaccineData = this.getVaccineHealthData(petId) + const medicalData = this.getMedicalHealthData(petId) + const growthData = this.getGrowthHealthData(petId, petInfo) + + // 计算综合健康评分 + const healthScore = this.calculateHealthScore(weightData, vaccineData, medicalData, growthData) + + // 生成健康趋势 + const healthTrend = this.analyzeHealthTrend(petId) + + // 识别风险因素 + const riskFactors = this.identifyRiskFactors(weightData, vaccineData, medicalData) + + return { + healthScore, + healthTrend, + riskFactors, + weightData, + vaccineData, + medicalData, + growthData + } + } + + /** + * 获取体重健康数据 + * @param {string} petId 宠物ID + * @returns {Object} 体重健康数据 + */ + getWeightHealthData(petId) { + const currentWeight = weightManager.getCurrentWeight(petId) + const weeklyChange = weightManager.calculateWeightChange(petId, 7) + const monthlyChange = weightManager.calculateWeightChange(petId, 30) + + // 体重状态评分 (0-100) + let weightScore = 85 // 默认良好 + if (Math.abs(weeklyChange.percent) > 10) { + weightScore = 60 // 变化过快 + } else if (Math.abs(weeklyChange.percent) > 5) { + weightScore = 75 // 变化较快 + } + + return { + currentWeight, + weeklyChange, + monthlyChange, + weightScore, + status: weightScore >= 80 ? 'good' : weightScore >= 60 ? 'warning' : 'poor' + } + } + + /** + * 获取疫苗健康数据 + * @param {string} petId 宠物ID + * @returns {Object} 疫苗健康数据 + */ + getVaccineHealthData(petId) { + const statusSummary = vaccineManager.getVaccineStatusSummary(petId) + + // 疫苗状态评分 + let vaccineScore = statusSummary.completionRate + if (statusSummary.expired > 0) { + vaccineScore -= 20 + } + if (statusSummary.expiringSoon > 0) { + vaccineScore -= 10 + } + + return { + statusSummary, + vaccineScore: Math.max(0, vaccineScore), + status: vaccineScore >= 80 ? 'good' : vaccineScore >= 60 ? 'warning' : 'poor' + } + } + + /** + * 获取医疗健康数据 + * @param {string} petId 宠物ID + * @returns {Object} 医疗健康数据 + */ + getMedicalHealthData(petId) { + const records = this.getHealthRecords(petId) + const now = new Date() + const threeMonthsAgo = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000) + + // 近三个月的医疗记录 + const recentRecords = records.filter(record => new Date(record.date) >= threeMonthsAgo) + const medicalVisits = recentRecords.filter(record => record.type === 'medical').length + const symptoms = recentRecords.filter(record => record.type === 'symptom').length + + // 医疗状态评分 + let medicalScore = 90 // 默认健康 + if (medicalVisits > 2) { + medicalScore = 60 // 就医频繁 + } else if (medicalVisits > 0 || symptoms > 1) { + medicalScore = 75 // 有健康问题 + } + + return { + totalRecords: records.length, + recentRecords: recentRecords.length, + medicalVisits, + symptoms, + medicalScore, + status: medicalScore >= 80 ? 'good' : medicalScore >= 60 ? 'warning' : 'poor' + } + } + + /** + * 获取生长发育数据 + * @param {string} petId 宠物ID + * @param {Object} petInfo 宠物信息 + * @returns {Object} 生长发育数据 + */ + getGrowthHealthData(petId, petInfo) { + const age = petInfo.age || 2 + const currentWeight = weightManager.getCurrentWeight(petId) + + // 根据年龄判断生长阶段 + let growthStage = 'adult' + if (age < 1) { + growthStage = 'kitten' + } else if (age < 2) { + growthStage = 'young' + } else if (age > 7) { + growthStage = 'senior' + } + + // 生长发育评分 + let growthScore = 85 + if (growthStage === 'kitten' && currentWeight < 2) { + growthScore = 70 // 幼猫体重偏轻 + } else if (growthStage === 'senior' && currentWeight > 6) { + growthScore = 75 // 老年猫超重 + } + + return { + age, + growthStage, + currentWeight, + growthScore, + status: growthScore >= 80 ? 'good' : growthScore >= 60 ? 'warning' : 'poor' + } + } + + /** + * 计算综合健康评分 + * @param {Object} weightData 体重数据 + * @param {Object} vaccineData 疫苗数据 + * @param {Object} medicalData 医疗数据 + * @param {Object} growthData 生长数据 + * @returns {number} 健康评分 + */ + calculateHealthScore(weightData, vaccineData, medicalData, growthData) { + const score = + weightData.weightScore * this.scoreWeights.weight + + vaccineData.vaccineScore * this.scoreWeights.vaccine + + medicalData.medicalScore * this.scoreWeights.medical + + growthData.growthScore * this.scoreWeights.growth + + return Math.round(score) + } + + /** + * 分析健康趋势 + * @param {string} petId 宠物ID + * @returns {string} 趋势分析 + */ + analyzeHealthTrend(petId) { + const weightChange = weightManager.calculateWeightChange(petId, 30) + const healthRecords = this.getHealthRecords(petId) + + // 简化的趋势分析 + if (healthRecords.length === 0) { + return 'stable' + } + + const recentRecords = healthRecords.filter(record => { + const recordDate = new Date(record.date) + const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) + return recordDate >= thirtyDaysAgo + }) + + if (recentRecords.length > 2) { + return 'declining' + } else if (recentRecords.length === 0 && Math.abs(weightChange.percent) < 3) { + return 'improving' + } else { + return 'stable' + } + } + + /** + * 识别风险因素 + * @param {Object} weightData 体重数据 + * @param {Object} vaccineData 疫苗数据 + * @param {Object} medicalData 医疗数据 + * @returns {Array} 风险因素列表 + */ + identifyRiskFactors(weightData, vaccineData, medicalData) { + const risks = [] + + if (weightData.status === 'poor') { + risks.push({ + type: 'weight', + level: 'high', + description: '体重变化异常,需要关注饮食和运动' + }) + } + + if (vaccineData.statusSummary.expired > 0) { + risks.push({ + type: 'vaccine', + level: 'high', + description: '疫苗已过期,免疫保护失效' + }) + } + + if (medicalData.medicalVisits > 2) { + risks.push({ + type: 'medical', + level: 'medium', + description: '近期就医频繁,需要关注健康状况' + }) + } + + return risks + } + + /** + * 生成AI健康分析 + * @param {string} petId 宠物ID + * @param {Object} petInfo 宠物信息 + * @returns {Object} AI分析结果 + */ + generateAIHealthAnalysis(petId, petInfo) { + const healthData = this.getComprehensiveHealthData(petId, petInfo) + + // 综合评估 + let overallAssessment = '' + if (healthData.healthScore >= 85) { + overallAssessment = `${petInfo.name}的整体健康状况优秀,各项指标均在正常范围内。` + } else if (healthData.healthScore >= 70) { + overallAssessment = `${petInfo.name}的健康状况良好,但有一些需要关注的方面。` + } else { + overallAssessment = `${petInfo.name}的健康状况需要改善,建议加强健康管理。` + } + + // 趋势分析 + const trendTexts = { + 'improving': '健康状况呈改善趋势,继续保持良好的护理习惯。', + 'stable': '健康状况保持稳定,维持当前的护理方式。', + 'declining': '健康状况有下降趋势,建议加强关注并考虑就医。' + } + const trendAnalysis = trendTexts[healthData.healthTrend] || '健康趋势需要进一步观察。' + + // 个性化建议 + const recommendations = this.generateHealthRecommendations(healthData, petInfo) + + // 预防措施 + const preventiveMeasures = this.generatePreventiveMeasures(healthData, petInfo) + + return { + overallAssessment, + trendAnalysis, + recommendations, + preventiveMeasures, + riskFactors: healthData.riskFactors + } + } + + /** + * 生成健康建议 + * @param {Object} healthData 健康数据 + * @param {Object} petInfo 宠物信息 + * @returns {string} 健康建议 + */ + generateHealthRecommendations(healthData, petInfo) { + const recommendations = [] + + if (healthData.weightData.status !== 'good') { + recommendations.push('调整饮食结构,控制食物分量') + } + + if (healthData.vaccineData.statusSummary.expiringSoon > 0) { + recommendations.push('及时安排疫苗接种,维持免疫保护') + } + + if (healthData.medicalData.symptoms > 0) { + recommendations.push('密切观察异常症状,必要时及时就医') + } + + // 根据年龄阶段添加建议 + if (healthData.growthData.growthStage === 'senior') { + recommendations.push('增加体检频率,关注老年期常见疾病') + } else if (healthData.growthData.growthStage === 'kitten') { + recommendations.push('确保营养充足,支持健康成长') + } + + return recommendations.length > 0 ? recommendations.join(';') + '。' : '继续保持良好的护理习惯。' + } + + /** + * 生成预防措施 + * @param {Object} healthData 健康数据 + * @param {Object} petInfo 宠物信息 + * @returns {string} 预防措施 + */ + generatePreventiveMeasures(healthData, petInfo) { + const measures = [] + + measures.push('定期体检,建议每6-12个月进行一次全面检查') + measures.push('保持适当运动,每日互动游戏15-30分钟') + measures.push('维护口腔健康,定期检查牙齿和牙龈') + + if (petInfo.age > 7) { + measures.push('老年宠物需要更频繁的健康监测') + } + + return measures.join(';') + '。' + } +} + +export default new HealthManager()