123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- <?php
- namespace app\common\model;
- use think\Model;
- /**
- * AI身体测试报告模型
- */
- class BodyAiReport extends Model
- {
- // 表名
- protected $table = 'fa_body_ai_report';
-
- // 开启自动写入时间戳字段
- protected $autoWriteTimestamp = 'int';
- // 定义时间戳字段名
- protected $createTime = 'createtime';
- protected $updateTime = 'updatetime';
- protected $deleteTime = false;
- // 追加属性
- protected $append = [
- 'report_type_text',
- 'ai_analysis_data',
- 'recommendations_data',
- 'report_images_data',
- 'generated_time_text',
- 'health_level_text'
- ];
- /**
- * 关联身体档案
- */
- public function profile()
- {
- return $this->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;
- }
- }
|