belongsTo('BodyProfile', 'profile_id', 'id', [], 'LEFT')->setEagerlyType(0); } /** * 获取报告类型文本 */ public function getReportTypeTextAttr($value, $data) { $typeMap = [ 'comprehensive' => '综合分析报告', 'partial' => '局部分析报告', 'comparison' => '对比分析报告' ]; return isset($typeMap[$data['report_type']]) ? $typeMap[$data['report_type']] : '未知类型'; } /** * 获取AI分析数据 */ public function getAiAnalysisDataAttr($value, $data) { return !empty($data['ai_analysis']) ? json_decode($data['ai_analysis'], true) : []; } /** * 设置AI分析数据 */ public function setAiAnalysisAttr($value) { return is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value; } /** * 获取建议数据 */ public function getRecommendationsDataAttr($value, $data) { return !empty($data['recommendations']) ? json_decode($data['recommendations'], true) : []; } /** * 设置建议数据 */ public function setRecommendationsAttr($value) { return is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value; } /** * 获取报告图片数据 */ public function getReportImagesDataAttr($value, $data) { return !empty($data['report_images']) ? json_decode($data['report_images'], true) : []; } /** * 设置报告图片数据 */ public function setReportImagesAttr($value) { return is_array($value) ? json_encode($value) : $value; } /** * 获取生成时间文本 */ public function getGeneratedTimeTextAttr($value, $data) { return $data['generated_time'] ? date('Y-m-d H:i:s', $data['generated_time']) : ''; } /** * 获取健康等级文本 */ public function getHealthLevelTextAttr($value, $data) { $score = $data['health_score']; if ($score >= 90) { return '优秀'; } elseif ($score >= 80) { return '良好'; } elseif ($score >= 70) { return '一般'; } elseif ($score >= 60) { return '较差'; } else { return '差'; } } /** * 生成AI分析报告 */ public static function generateReport($profileId, $reportType = 'comprehensive') { $profile = BodyProfile::with(['latestMeasurement', 'bodyTypeSelections.typeConfig'])->find($profileId); if (!$profile) { return false; } // 获取基础数据 $measurements = $profile->latestMeasurement; $bodyTypes = $profile->bodyTypeSelections; // 生成AI分析结果 $aiAnalysis = self::generateAiAnalysis($profile, $measurements, $bodyTypes); // 生成建议内容 $recommendations = self::generateRecommendations($profile, $measurements, $aiAnalysis); // 计算健康评分 $healthScore = self::calculateHealthScore($profile, $measurements); // 计算身体年龄 $bodyAge = self::calculateBodyAge($profile, $measurements, $healthScore); // 创建报告记录 $report = new self(); $report->profile_id = $profileId; $report->report_type = $reportType; $report->ai_analysis = $aiAnalysis; $report->recommendations = $recommendations; $report->health_score = $healthScore; $report->body_age = $bodyAge; $report->generated_time = time(); if ($report->save()) { return $report; } return false; } /** * 生成AI分析内容 */ private static function generateAiAnalysis($profile, $measurements, $bodyTypes) { $analysis = [ 'basic_info' => [ 'bmi' => $profile->calculateBMI(), 'bmi_level' => $profile->getBMILevel(), 'age' => $profile->age, 'gender' => $profile->gender_text ], 'body_composition' => [], 'body_proportions' => [], 'body_types' => [], 'risk_assessment' => [] ]; // 身体成分分析 if ($measurements) { $analysis['body_composition'] = [ 'muscle_mass_estimate' => self::estimateMuscleMass($profile, $measurements), 'fat_percentage_estimate' => self::estimateFatPercentage($profile, $measurements), 'bone_density_level' => self::estimateBoneDensity($profile->age, $profile->gender) ]; // 身体比例分析 $ratios = $measurements->calculateBodyRatios(); $analysis['body_proportions'] = [ 'waist_hip_ratio' => $ratios['waist_hip_ratio'] ?? 0, 'waist_hip_assessment' => self::assessWaistHipRatio($ratios['waist_hip_ratio'] ?? 0, $profile->gender), 'symmetry_score' => self::calculateSymmetryScore($measurements) ]; } // 体型分析 $typeAnalysis = []; foreach ($bodyTypes as $selection) { $typeAnalysis[$selection->type_category] = [ 'selected_type' => $selection->typeConfig->type_name, 'suitability' => self::assessTypeSuitability($selection, $measurements) ]; } $analysis['body_types'] = $typeAnalysis; // 风险评估 $analysis['risk_assessment'] = self::assessHealthRisks($profile, $measurements); return $analysis; } /** * 生成建议内容 */ private static function generateRecommendations($profile, $measurements, $analysis) { $recommendations = [ 'exercise' => [], 'nutrition' => [], 'lifestyle' => [], 'clothing' => [] ]; // 运动建议 $bmi = $profile->calculateBMI(); if ($bmi < 18.5) { $recommendations['exercise'][] = '增加力量训练,促进肌肉增长'; $recommendations['exercise'][] = '适量有氧运动,提高体能'; } elseif ($bmi > 24) { $recommendations['exercise'][] = '增加有氧运动,控制体重'; $recommendations['exercise'][] = '结合力量训练,提高代谢'; } else { $recommendations['exercise'][] = '保持规律运动,维持现有状态'; } // 营养建议 if ($profile->age < 30) { $recommendations['nutrition'][] = '保证充足蛋白质摄入,支持肌肉发育'; } elseif ($profile->age >= 50) { $recommendations['nutrition'][] = '增加钙质摄入,预防骨质疏松'; } // 生活方式建议 $recommendations['lifestyle'][] = '保持充足睡眠,每天7-8小时'; $recommendations['lifestyle'][] = '减少久坐时间,每小时活动一次'; // 服装搭配建议 $waistHipRatio = $analysis['body_proportions']['waist_hip_ratio'] ?? 0; if ($waistHipRatio > 0.8 && $profile->gender == 2) { $recommendations['clothing'][] = 'A字裙装修饰腰臀比例'; $recommendations['clothing'][] = '高腰设计拉长腿部线条'; } return $recommendations; } /** * 计算健康评分 */ private static function calculateHealthScore($profile, $measurements) { $score = 0; $factors = 0; // BMI评分 (30分) $bmi = $profile->calculateBMI(); if ($bmi >= 18.5 && $bmi < 24) { $score += 30; } elseif ($bmi >= 17 && $bmi < 28) { $score += 20; } else { $score += 10; } $factors++; // 腰臀比评分 (20分) if ($measurements && $measurements->waist > 0 && $measurements->hip > 0) { $whr = $measurements->waist / $measurements->hip; $idealWhr = $profile->gender == 1 ? 0.9 : 0.8; if (abs($whr - $idealWhr) <= 0.05) { $score += 20; } elseif (abs($whr - $idealWhr) <= 0.1) { $score += 15; } else { $score += 10; } $factors++; } // 年龄调整评分 (10分) if ($profile->age <= 30) { $score += 10; } elseif ($profile->age <= 50) { $score += 8; } else { $score += 6; } $factors++; return $factors > 0 ? round($score / $factors * 100 / 60, 1) : 0; } /** * 计算身体年龄 */ private static function calculateBodyAge($profile, $measurements, $healthScore) { $baseAge = $profile->age; // 根据健康评分调整 if ($healthScore >= 90) { $adjustment = -5; } elseif ($healthScore >= 80) { $adjustment = -2; } elseif ($healthScore >= 70) { $adjustment = 0; } elseif ($healthScore >= 60) { $adjustment = 3; } else { $adjustment = 8; } // 根据BMI调整 $bmi = $profile->calculateBMI(); if ($bmi < 18.5 || $bmi > 28) { $adjustment += 2; } return max(18, min(80, $baseAge + $adjustment)); } // 辅助方法 private static function estimateMuscleMass($profile, $measurements) { // 简化的肌肉量估算 return $profile->gender == 1 ? '中等' : '一般'; } private static function estimateFatPercentage($profile, $measurements) { $bmi = $profile->calculateBMI(); if ($bmi < 18.5) return '偏低'; if ($bmi > 25) return '偏高'; return '正常'; } private static function estimateBoneDensity($age, $gender) { if ($age < 30) return '良好'; if ($age > 50 && $gender == 2) return '需关注'; return '一般'; } private static function assessWaistHipRatio($ratio, $gender) { if ($ratio == 0) return '无法评估'; $ideal = $gender == 1 ? 0.9 : 0.8; if (abs($ratio - $ideal) <= 0.05) return '理想'; if ($ratio > $ideal + 0.1) return '偏高'; return '一般'; } private static function calculateSymmetryScore($measurements) { return mt_rand(75, 95); // 简化实现 } private static function assessTypeSuitability($selection, $measurements) { return '适合'; // 简化实现 } private static function assessHealthRisks($profile, $measurements) { $risks = []; $bmi = $profile->calculateBMI(); if ($bmi > 28) { $risks[] = '肥胖相关疾病风险'; } if ($profile->age > 50) { $risks[] = '骨质疏松风险'; } return $risks; } }