199 lines
7.4 KiB
Kotlin
199 lines
7.4 KiB
Kotlin
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,
|
|
)
|
|
} |