--- a/app/terminal/service/analysis/Analysis.php +++ b/app/terminal/service/analysis/Analysis.php @@ -18,9 +18,22 @@ use app\terminal\service\meal\Meal; use app\common\service\BaseService; use app\store\service\store\User as StoreUserService; +use app\common\service\FixedScaleDecimalResponse; +use app\common\database\Dm; +use think\facade\Db; class Analysis extends BaseService { + // Source DECIMAL(10,2) direct projections; missing columns retain original numeric zero. + private static function decimalProjection(array $row, string $field) + { + $value = $row[$field] ?? 0; + if (!isset($row[$field]) || !(Db::connect() instanceof Dm) + || (!is_int($value) && !is_float($value))) { + return $value; + } + return FixedScaleDecimalResponse::fields([$field => $value], [$field])[$field]; + } // 推荐早午晚营养类型字段 private $nurtirtion_type = [ 1 => [ @@ -110,23 +123,23 @@ 'is_delete' => 0, 'meal_date' => $lastMeal['meal_date'],], '*'); - $data['energy']['reality'] = $current_meal['energy'] ?? 0; - $data['energy']['recommend'] = $recommend_meal[$this->nurtirtion_type[$lastMeal['meal_times']][0]] ?? 0; + $data['energy']['reality'] = self::decimalProjection($current_meal, 'energy'); + $data['energy']['recommend'] = self::decimalProjection($recommend_meal, $this->nurtirtion_type[$lastMeal['meal_times']][0]); $energy_res = Algorithm::divScale($data['energy']['reality'],$data['energy']['recommend']); $data['energy']['ratio'] = !empty($energy_res) ? round($energy_res * 100,2) : 0; $data['energy']['evaluate'] = isset($score_array[1]) ? $score_array[1]['evaluate'] : 0; - $data['carbohydrate']['reality'] = $current_meal['carbohydrate'] ?? 0; - $data['carbohydrate']['recommend'] = $recommend_meal[$this->nurtirtion_type[$lastMeal['meal_times']][1]] ?? 0; + $data['carbohydrate']['reality'] = self::decimalProjection($current_meal, 'carbohydrate'); + $data['carbohydrate']['recommend'] = self::decimalProjection($recommend_meal, $this->nurtirtion_type[$lastMeal['meal_times']][1]); $carbohydrate_res = Algorithm::divScale($data['carbohydrate']['reality'],$data['carbohydrate']['recommend']); $data['carbohydrate']['ratio'] = !empty($carbohydrate_res) ? round($carbohydrate_res * 100,2) : 0; $data['carbohydrate']['evaluate'] = isset($score_array[2]) ? $score_array[2]['evaluate'] : 0; - $data['protein']['reality'] = $current_meal['protein'] ?? 0; - $data['protein']['recommend'] = $recommend_meal[$this->nurtirtion_type[$lastMeal['meal_times']][2]] ?? 0; + $data['protein']['reality'] = self::decimalProjection($current_meal, 'protein'); + $data['protein']['recommend'] = self::decimalProjection($recommend_meal, $this->nurtirtion_type[$lastMeal['meal_times']][2]); $protein_res = Algorithm::divScale($data['protein']['reality'],$data['protein']['recommend']); $data['protein']['ratio'] = !empty($protein_res) ? round($protein_res * 100,2) : 0; $data['protein']['evaluate'] = isset($score_array[3]) ? $score_array[3]['evaluate'] : 0; - $data['fat']['reality'] = $current_meal['fat'] ?? 0; - $data['fat']['recommend'] = $recommend_meal[$this->nurtirtion_type[$lastMeal['meal_times']][3]] ?? 0; + $data['fat']['reality'] = self::decimalProjection($current_meal, 'fat'); + $data['fat']['recommend'] = self::decimalProjection($recommend_meal, $this->nurtirtion_type[$lastMeal['meal_times']][3]); $fat_res = Algorithm::divScale($data['fat']['reality'],$data['fat']['recommend']); $data['fat']['ratio'] = !empty($fat_res) ? round($fat_res * 100,2) : 0; $data['fat']['evaluate'] = isset($score_array[4]) ? $score_array[4]['evaluate'] : 0; @@ -282,7 +295,7 @@ $recommend_v = isset($recommend_values[$meals['field']]) ? $recommend_values[$meals['field']] : 0; $recommend_value = round($recommend_v * $meal_ratio,2); $meals_detary[$key]['recommend_value'] = $recommend_value; - $meals_detary[$key]['actual_value'] = $current_meal[$lastMeal['meal_times']][$meals['field']]; + $meals_detary[$key]['actual_value'] = self::decimalProjection($current_meal[$lastMeal['meal_times']], $meals['field']); $ratio = Algorithm::divScale($meals_detary[$key]['actual_value'],$meals_detary[$key]['recommend_value']); $meals_detary[$key]['ratio'] = round($ratio * 100,2); $accumulate = array_sum(array_column($current_meal,$meals['field'])); @@ -354,8 +367,8 @@ $recommend_value = MealRecommend::getCurrentRemmendMeal($recommend_where,$recommend_field); foreach ($fields as $field){ $meal_recommend = isset($recommend_value[$field]) ? round($recommend_value[$field] * $recommend_value[$this->meal_times[$lastMeal['meal_times']]],2) : 0; - $data[$field]['recommend'] = isset($recommend_value[$field]) ? $recommend_value[$field] : 0; - $data[$field]['actual'] = isset($current_meal[$lastMeal['meal_times']][$field]) ? $current_meal[$lastMeal['meal_times']][$field] : 0; + $data[$field]['recommend'] = self::decimalProjection($recommend_value, $field); + $data[$field]['actual'] = self::decimalProjection($current_meal[$lastMeal['meal_times']], $field); $ratio = Algorithm::divScale($data[$field]['actual'],$meal_recommend); $data[$field]['ratio'] = round($ratio * 100,2); $accumulate = array_sum(array_column($current_meal,$field)); @@ -429,7 +442,7 @@ foreach ($times_dishes[$lastMeal['meal_times']] as $current_dishe){ if (isset($current_dishe['category']) && !empty($current_dishe['dishe']) && !empty($current_dishe['category'])){ $data['dishes_cate'][$current_dishe['category']]['actual'] += $current_dishe['dietary_fiber']; - $data['dishes_cate'][$current_dishe['category']]['dishes'][] = ['name' => $current_dishe['dishe']['name'],'weight' => $current_dishe['dietary_fiber']]; + $data['dishes_cate'][$current_dishe['category']]['dishes'][] = ['name' => $current_dishe['dishe']['name'],'weight' => self::decimalProjection($current_dishe, 'dietary_fiber')]; } } $data['dishes_cate'] = array_map(function ($item){