BodyProfile.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. namespace app\common\model;
  3. use think\Model;
  4. use traits\model\SoftDelete;
  5. /**
  6. * 身体档案模型
  7. */
  8. class BodyProfile extends Model
  9. {
  10. use SoftDelete;
  11. // 表名
  12. protected $table = 'fa_body_profile';
  13. // 开启自动写入时间戳字段
  14. protected $autoWriteTimestamp = 'int';
  15. // 定义时间戳字段名
  16. protected $createTime = 'createtime';
  17. protected $updateTime = 'updatetime';
  18. protected $deleteTime = 'deletetime';
  19. // 追加属性
  20. protected $append = [
  21. 'gender_text',
  22. 'body_photos_text',
  23. 'is_own_text'
  24. ];
  25. /**
  26. * 关联用户
  27. */
  28. public function user()
  29. {
  30. return $this->belongsTo('User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
  31. }
  32. /**
  33. * 关联身体测量数据
  34. */
  35. public function measurements()
  36. {
  37. return $this->hasMany('BodyMeasurements', 'profile_id', 'id');
  38. }
  39. /**
  40. * 关联最新的身体测量数据
  41. */
  42. public function latestMeasurement()
  43. {
  44. return $this->hasOne('BodyMeasurements', 'profile_id', 'id')->order('measurement_date DESC');
  45. }
  46. /**
  47. * 关联身体类型选择
  48. */
  49. public function bodyTypeSelections()
  50. {
  51. return $this->hasMany('BodyTypeSelection', 'profile_id', 'id');
  52. }
  53. /**
  54. * 关联AI报告
  55. */
  56. public function aiReports()
  57. {
  58. return $this->hasMany('BodyAiReport', 'profile_id', 'id');
  59. }
  60. /**
  61. * 关联最新AI报告
  62. */
  63. public function latestAiReport()
  64. {
  65. return $this->hasOne('BodyAiReport', 'profile_id', 'id')->order('generated_time DESC');
  66. }
  67. /**
  68. * 获取性别文本
  69. */
  70. public function getGenderTextAttr($value, $data)
  71. {
  72. $genderMap = [
  73. 1 => '男',
  74. 2 => '女'
  75. ];
  76. return isset($genderMap[$data['gender']]) ? $genderMap[$data['gender']] : '未知';
  77. }
  78. /**
  79. * 获取是否本人档案文本
  80. */
  81. public function getIsOwnTextAttr($value, $data)
  82. {
  83. return $data['is_own'] ? '本人档案' : '他人档案';
  84. }
  85. /**
  86. * 获取身体照片数组
  87. */
  88. public function getBodyPhotosTextAttr($value, $data)
  89. {
  90. if (empty($data['body_photos'])) {
  91. return [
  92. 'front' => '',
  93. 'side' => '',
  94. 'back' => ''
  95. ];
  96. }
  97. return json_decode($data['body_photos'], true);
  98. }
  99. /**
  100. * 设置身体照片
  101. */
  102. public function setBodyPhotosAttr($value)
  103. {
  104. return is_array($value) ? json_encode($value) : $value;
  105. }
  106. /**
  107. * 获取完整的档案信息(包含测量数据和体型选择)
  108. */
  109. public function getFullProfileData()
  110. {
  111. $profile = $this->toArray();
  112. // 获取最新测量数据
  113. $latestMeasurement = $this->latestMeasurement;
  114. $profile['measurements'] = $latestMeasurement ? $latestMeasurement->toArray() : null;
  115. // 获取体型选择
  116. $bodyTypes = $this->bodyTypeSelections()->with('typeConfig')->select();
  117. $profile['body_types'] = [];
  118. foreach ($bodyTypes as $selection) {
  119. $profile['body_types'][$selection['type_category']] = [
  120. 'type_id' => $selection['selected_type_id'],
  121. 'type_name' => $selection->typeConfig ? $selection->typeConfig['type_name'] : '',
  122. 'type_image' => $selection->typeConfig ? cdnurl($selection->typeConfig['type_image'], true) : ''
  123. ];
  124. }
  125. // 获取最新AI报告
  126. $latestReport = $this->latestAiReport;
  127. $profile['ai_report'] = $latestReport ? $latestReport->toArray() : null;
  128. return $profile;
  129. }
  130. /**
  131. * 计算BMI指数
  132. */
  133. public function calculateBMI()
  134. {
  135. if ($this->height <= 0 || $this->weight <= 0) {
  136. return 0;
  137. }
  138. $heightInMeters = $this->height / 100;
  139. return round($this->weight / ($heightInMeters * $heightInMeters), 2);
  140. }
  141. /**
  142. * 获取BMI等级
  143. */
  144. public function getBMILevel()
  145. {
  146. $bmi = $this->calculateBMI();
  147. if ($bmi < 18.5) {
  148. return '偏瘦';
  149. } elseif ($bmi < 24) {
  150. return '正常';
  151. } elseif ($bmi < 28) {
  152. return '超重';
  153. } else {
  154. return '肥胖';
  155. }
  156. }
  157. }