package com.sw.dualscreen.presentation import android.text.TextUtils import com.sw.dualscreen.ext.toSafeDouble import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.UserEnergy import com.sw.dualscreen.model.response.UserNutrition import com.sw.dualscreen.model.response.UserNutritionData import timber.log.Timber import kotlin.math.max /** * 用户营养信息计算工具 */ object UserNutritionUtils { /** * 计算热量信息 */ fun calculateNutrition2( foodInfo: FoodInfo, nutrition: UserNutrition, weight: Double, dinnerType: String ): UserEnergy { // 初始化变量 var totalKcal = 0.0 var (calorie, grain, fruitsVegetables, meatEggs) = List(4) { 0.0 } // 处理食物信息 calorie = calculateValue(foodInfo.calorie, weight) grain = calculateValue(foodInfo.stapleFood, weight) fruitsVegetables = calculateValue(foodInfo.fruitsVegetables, weight) meatEggs = calculateValue(foodInfo.meatEggs, weight) // 合并用户数据 //val maxKcal = (nutrition.calorie?:0.0) * calculateDinnerTypeRatio(dinnerType) / 10.0 calorie += nutrition.calorie ?: 0.0 grain += nutrition.stapleFood ?: 0.0 fruitsVegetables += nutrition.fruitsVegetables ?: 0.0 meatEggs += nutrition.meatEggs ?: 0.0 totalKcal = max(calorie, 0.0) // 判断当餐最大热量 //val maxKcal = userModel.totalEnergyCalculateScoreValue() * calculateDinnerTypeRatio(dinnerType) / 10 //Timber.d("calculateNutrition maxKcal = ${maxKcal}, CalculateScoreValue = ${userModel.totalEnergyCalculateScoreValue()}") // val calcResult = CalcResultInfo( // totalKcal = CalcInfo( // max = maxKcal, // min = 0.0, // current = totalKcal // ), // grain = parseRecommend(foodInfo.stapleFoodRecommend, grain), // fruits = parseRecommend(foodInfo.fruitsVegetablesRecommend, fruitsVegetables), // meat = parseRecommend(foodInfo.meatEggsRecommend, meatEggs) // ) return UserEnergy( calorie = totalKcal, grain = grain, fruitsVegetables = fruitsVegetables, meatEggs = meatEggs ) } // fun calculateNutrition( // foodInfo: FoodInfo, // userModel: UserNutritionData, //// userModel: UserNutrition, // weight: Double, // dinnerType: String // ): CalcResultInfo { // // // 初始化变量 // var foodKcal = 0.0 // var totalKcal = 0.0 // var (vegetable, meat, fruits, grain) = List(4) { 0.0 } // // // 处理食物信息 // foodKcal = calculateValue(foodInfo.stFoodInfoMaterial?.energyKcal, weight) // Timber.d("calculateNutrition foodKcal = ${foodKcal}, energyKcal = ${foodInfo.stFoodInfoMaterial?.energyKcal}, weight = $weight") // grain = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.grainValue(), weight) // fruits = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.fruitsValue(), weight) // vegetable = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.vegetableValue(), weight) // meat = calculateValue(foodInfo.stFoodInfoPagodaAPPVO?.meatValue(), weight) // // // 合并用户数据 // grain += userModel.stFoodInfoPagoda?.grainValue() ?: 0.0 // // fruits += userModel.stFoodInfoPagoda?.fruitsValue() ?: 0.0 // vegetable = vegetable.plus(userModel.stFoodInfoPagoda?.vegetableValue() ?: 0.0) // meat += userModel.stFoodInfoPagoda?.meatValue() ?: 0.0 // // totalKcal = foodKcal + userModel.energyValue() // Timber.d("calculateNutrition totalKcal = ${totalKcal}, energyValue = ${userModel.energyValue()}") // if (totalKcal < 0) { // totalKcal = 0.0 // } // // 判断当餐最大热量 // val maxKcal = // userModel.totalEnergyCalculateScoreValue() * calculateDinnerTypeRatio(dinnerType) / 10 // Timber.d("calculateNutrition maxKcal = ${maxKcal}, CalculateScoreValue = ${userModel.totalEnergyCalculateScoreValue()}") // val pagoda = userModel.stFoodInfoPagoda // val fruitsInfo = parseRecommend(pagoda?.fruitsRecommend, fruits) // val vegetableInfo = parseRecommend(pagoda?.vegetableRecommend, vegetable) // val calcResult = CalcResultInfo( // totalKcal = CalcInfo( // max = maxKcal, // min = 0.0, // current = totalKcal // ), // grain = parseRecommend(pagoda?.grainRecommend, grain), // fruits = CalcInfo( // 果蔬 = 水果+蔬菜 // max = fruitsInfo.max + vegetableInfo.max, // min = fruitsInfo.min + vegetableInfo.min, // current = fruitsInfo.current + vegetableInfo.current // ), // meat = parseRecommend(pagoda?.meatRecommend, meat) // ) // return calcResult // } fun parseRecommend(recommend: String?, current: Double): CalcInfo { val newCurrent = if (current < 0) 0.0 else current if (TextUtils.isEmpty(recommend) || !recommend!!.contains("-")) { Timber.e("parseRecommend recommend 格式错误") return CalcInfo( newCurrent, 0.0, newCurrent ) } val (min, max) = recommend.split("-") return CalcInfo(max = max.toSafeDouble(), min = min.toSafeDouble(), current = newCurrent) } private fun calculateDinnerTypeRatio(dinnerType: String): Int { return when (dinnerType) { "早餐", "晚餐" -> 3 "午餐" -> 4 else -> 0 } } /** * 计算每百克含量 */ private fun calculateValue(nutrient: Double?, weight: Double): Double { return weight * (nutrient ?: 1.0) / 100 } fun getMaxInt(calcResultInfo: CalcResultInfo): Int { val max1 = max(calcResultInfo.grain.max, calcResultInfo.fruits.max) return max(max1, calcResultInfo.meat.max).toInt() } fun getCalorieArray(left:String?, mid:String?, right: String?):DoubleArray { val leftArray = (left?.ifBlank { "0-0" } ?: "0-0").split("-").map { it.toSafeDouble() } val midArray = (mid?.ifBlank { "0-0" } ?: "0-0").split("-").map { it.toSafeDouble() } val rightArray = (right?.ifBlank { "0-0" } ?: "0-0").split("-").map { it.toSafeDouble() } return doubleArrayOf( 0.0, leftArray[0], midArray[0], rightArray[0], rightArray[1] ) } fun findCalorieIndex(num: Double, array: DoubleArray): Int { if (array.isEmpty()) return 0 if (num < array[0]) return 0 if (num >= array[array.lastIndex]) return array.lastIndex var left = 0 var right = array.lastIndex while (left < right) { val mid = left + (right - left) / 2 if (array[mid] <= num && num < array[mid + 1]) { return mid } else if (num < array[mid]) { right = mid } else { left = mid + 1 } } return 0 } data class CalcInfo( var max: Double, var min: Double, var current: Double, ) data class CalcResultInfo( var totalKcal: CalcInfo, var grain: CalcInfo, var fruits: CalcInfo, var meat: CalcInfo, ) }