@ -9,7 +9,6 @@ import com.mathvision.diet.domian.MenuDishItemDTO;
import com.mathvision.diet.entity.* ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.commons.collections4.CollectionUtils ;
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.tuple.Pair ;
import org.springframework.stereotype.Service ;
@ -38,9 +37,17 @@ public class MenuReportService {
BigDecimal overflow = nutrition . getOverflow ( ) ;
Map < String , Map < String , BigDecimal > > itemStandard = nutrition . getIngredient ( ) . getOrDefault ( crow , new HashMap < > ( ) ) ;
Map < String , Ingredient > ingredientMap = ingredientService . getFullByKeys ( dishes . stream ( ) . filter ( x - > CollectionUtils . isNotEmpty ( x . getIngredient ( ) ) ) . flatMap ( x - > x . getIngredient ( ) . stream ( ) . map ( MenuDishItemDTO : : getKey ) ) . collect ( Collectors . toSet ( ) ) ) . stream ( ) . collect ( Collectors . toMap ( Ingredient : : getKey , v - > v ) ) ;
Map < String , BigDecimal > items = dishes . stream ( ) . flatMap ( dish - > dish . getIngredient ( ) . stream ( ) . filter ( item - > item . getValue ( ) . containsKey ( crow ) & & item . getValue ( ) . get ( crow ) . doubleValue ( ) > 0 & & ingredientMap . containsKey ( item . getKey ( ) ) ) ) . flatMap ( x - > ingredientMap . get ( x . getKey ( ) ) . getNutrient ( ) . entrySet ( ) . stream ( ) . map ( n - > Pair . of ( n . getKey ( ) , n . getValue ( ) . multiply ( x . getValue ( ) . get ( crow ) ) . divide ( new BigDecimal ( 100 ) , RoundingMode . HALF_UP ) ) ) ) . collect ( Collectors . toMap ( Pair : : getKey , Pair : : getValue , BigDecimal : : add ) ) ;
Map < String , BigDecimal > items = dishes . stream ( ) . flatMap ( dish - > dish . getIngredient ( ) . stream ( ) . filter ( item - > item . getValue ( ) . containsKey ( crow ) & & item . getValue ( ) . get ( crow ) . doubleValue ( ) > 0 & & ingredientMap . containsKey ( item . getKey ( ) ) ) )
. flatMap ( x - > ingredientMap . get ( x . getKey ( ) ) . getNutrient ( ) . entrySet ( ) . stream ( ) . map ( n - > Pair . of ( n . getKey ( ) , n . getValue ( ) . multiply ( x . getValue ( ) . get ( crow ) ) . divide ( new BigDecimal ( 100 ) , RoundingMode . HALF_UP ) ) ) )
. collect ( Collectors . toMap ( Pair : : getKey , Pair : : getValue , BigDecimal : : add ) ) ;
Map < String , Integer > types = dishes . stream ( ) . flatMap ( dish - > dish . getIngredient ( ) . stream ( ) . filter ( item - > ingredientMap . containsKey ( item . getKey ( ) ) ) . map ( item - > ingredientMap . get ( item . getKey ( ) ) . getType ( ) ) ) . collect ( Collectors . toMap ( x - > x , x - > 1 , Integer : : sum ) ) ;
itemStandard . forEach ( ( key , value ) - > {
if ( ! items . containsKey ( key ) ) {
items . put ( key , BigDecimal . ZERO ) ;
}
} ) ;
JSONObject result = new JSONObject ( ) ;
result . put ( "day" , day ) ;
result . put ( "crow" , crow ) ;
@ -62,73 +69,72 @@ public class MenuReportService {
BigDecimal max = standard = = null ? null : standard . get ( "max" ) ;
BigDecimal min = standard = = null ? null : standard . get ( "min" ) ;
BigDecimal ul = standard = = null ? null : standard . get ( "ul" ) ;
content . put ( "ul" , ul = = null ? "-" : ul . toString ( ) ) ;
boolean byMax = false ;
boolean byMin = false ;
if ( max = = null | | max . compareTo ( BigDecimal . ZERO ) = = 0 ) {
if ( min = = null | | min . compareTo ( BigDecimal . ZERO ) = = 0 ) {
content . put ( "standard" , "-" ) ;
content . put ( "ul" , ul = = null ? "-" : ul . toString ( ) ) ;
content . put ( "overload" , "-" ) ;
content . put ( "conclusion" , "-" ) ;
return ;
} else {
content . put ( "standard" , "≥" + min ) ;
content . put ( "ul" , ul = = null ? "-" : ul . toString ( ) ) ;
if ( min . compareTo ( value ) > 0 ) {
content . put ( "overload" , value . subtract ( min ) . divide ( min , RoundingMode . FLOOR ) ) ;
if ( min . subtract ( value ) . compareTo ( overflow . divide ( new BigDecimal ( 100 ) , RoundingMode . FLOOR ) . multiply ( value ) ) > 0 ) {
content . put ( "conclusion" , "不足" ) ;
} else {
content . put ( "conclusion" , "适量" ) ;
}
} else {
content . put ( "overload" , BigDecimal . ZERO ) ;
if ( value . compareTo ( min ) > = 0 ) {
content . put ( "overload" , "-" ) ;
content . put ( "conclusion" , "适量" ) ;
} else {
byMin = true ;
}
}
} else {
if ( min = = null | | min . compareTo ( BigDecimal . ZERO ) = = 0 ) {
content . put ( "standard" , "≤" + max ) ;
content . put ( "ul" , ul = = null ? "-" : ul . toString ( ) ) ;
if ( max . compareTo ( value ) < 0 ) {
if ( value . subtract ( max ) . compareTo ( overflow . divide ( new BigDecimal ( 100 ) , RoundingMode . FLOOR ) . multiply ( value ) ) > 0 ) {
if ( ul ! = null & & value . compareTo ( ul ) > 0 ) {
content . put ( "conclusion" , "严重超标" ) ;
} else {
content . put ( "conclusion" , "过量" ) ;
}
} else {
content . put ( "conclusion" , "适量" ) ;
}
content . put ( "overload" , value . subtract ( max ) . divide ( max , RoundingMode . FLOOR ) ) ;
if ( max . compareTo ( value ) > = 0 ) {
content . put ( "overload" , "-" ) ;
content . put ( "conclusion" , "适量" ) ;
} else {
content . put ( "overload" , BigDecimal . ZERO ) ;
byMax = true ;
}
} else {
content . put ( "standard" , min + "~" + max ) ;
content . put ( "ul" , ul = = null ? "-" : ul . toString ( ) ) ;
if ( min . compareTo ( value ) > 0 ) {
content . put ( "overload" , value . subtract ( min ) . divide ( min , RoundingMode . FLOOR ) ) ;
if ( min . subtract ( value ) . compareTo ( overflow . divide ( new BigDecimal ( 100 ) , RoundingMode . FLOOR ) . multiply ( value ) ) > 0 ) {
content . put ( "conclusion" , "不足" ) ;
} else {
content . put ( "conclusion" , "适量" ) ;
}
if ( Range . closed ( min , max ) . contains ( value ) ) {
content . put ( "overload" , "-" ) ;
content . put ( "conclusion" , "适量" ) ;
}
if ( value . compareTo ( max ) > 0 ) {
byMax = true ;
} else {
byMin = true ;
}
}
}
if ( byMin ) {
BigDecimal overload = calculatePercentage ( value , min ) ;
content . put ( "overload" , overload + "%" ) ;
if ( overload . abs ( ) . compareTo ( overflow ) > 0 ) {
content . put ( "conclusion" , "不足" ) ;
} else {
content . put ( "conclusion" , "适量" ) ;
}
}
if ( byMax ) {
BigDecimal overload = calculatePercentage ( value , max ) ;
content . put ( "overload" , overload + "%" ) ;
if ( overload . compareTo ( overflow ) > 0 ) {
if ( ul ! = null & & value . compareTo ( ul ) > 0 ) {
content . put ( "conclusion" , "严重超标" ) ;
} else {
if ( max . compareTo ( value ) < 0 ) {
content . put ( "overload" , value . subtract ( max ) . divide ( max , RoundingMode . FLOOR ) ) ;
if ( value . subtract ( max ) . compareTo ( overflow . divide ( new BigDecimal ( 100 ) , RoundingMode . FLOOR ) . multiply ( value ) ) > 0 ) {
if ( ul ! = null & & value . compareTo ( ul ) > 0 ) {
content . put ( "conclusion" , "严重超标" ) ;
} else {
content . put ( "conclusion" , "过量" ) ;
}
} else {
content . put ( "conclusion" , "适量" ) ;
}
} else {
content . put ( "overload" , "0%" ) ;
}
content . put ( "conclusion" , "过量" ) ;
}
} else {
content . put ( "conclusion" , "适量" ) ;
}
}
contents . add ( content ) ;
} ) ;
result . put ( "ingredient" , contents ) ;
@ -198,29 +204,44 @@ public class MenuReportService {
. filter ( x - > allConcerned . contains ( x . getKey ( ) ) )
. collect ( Collectors . toMap ( Pair : : getKey , Pair : : getValue , BigDecimal : : add ) ) ;
allConcerned . forEach ( key - > {
if ( ! items . containsKey ( key ) ) {
items . put ( key , BigDecimal . ZERO ) ;
}
} ) ;
JSONObject result = new JSONObject ( ) ;
result . put ( "day" , day ) ;
result . put ( "crow" , crow ) ;
result . put ( "meals" , dishes . stream ( ) . map ( MenuDish : : getMeal ) . collect ( Collectors . toSet ( ) ) ) ;
BigDecimal energy = items . get ( "energy" ) ;
if ( energy = = null | | energy . doubleValue ( ) < = 0 ) {
return result ;
}
//BigDecimal energy = items.get("energy").multiply(new BigDecimal("4.18"));
BigDecimal protein = items . get ( "protein" ) . multiply ( new BigDecimal ( "4" ) ) ;
BigDecimal fat = items . get ( "fat" ) . multiply ( new BigDecimal ( "9" ) ) ;
BigDecimal carbs = items . get ( "carbs" ) . multiply ( new BigDecimal ( "4" ) ) ;
BigDecimal total = protein . add ( fat ) . add ( carbs ) ;
JSONArray contents = new JSONArray ( ) ;
contents . add ( toEnergyContent ( energy , "protein" , Range . closed ( 10 , 20 ) , items ) ) ;
contents . add ( toEnergyContent ( energy , "fat" , Range . closed ( 20 , 30 ) , items ) ) ;
contents . add ( toEnergyContent ( energy , "carbs" , Range . closed ( 50 , 60 ) , items ) ) ;
contents . add ( toEnergyContent ( total , "protein" , protein , Range . closed ( 10 , 20 ) ) ) ;
contents . add ( toEnergyContent ( total , "fat" , fat , Range . closed ( 20 , 30 ) ) ) ;
contents . add ( toEnergyContent ( total , "carbs" , carbs , Range . closed ( 50 , 60 ) ) ) ;
result . put ( "energy" , contents ) ;
return result ;
}
private JSONObject toEnergyContent ( BigDecimal energy , String key , Range < Integer > standard , Map < String , BigDecimal > items ) {
double value = items . getOrDefault ( key , BigDecimal . ZERO ) . divide ( energy , RoundingMode . FLOOR ) . multiply ( new BigDecimal ( 100 ) ) . doubleValue ( ) ;
private JSONObject toEnergyContent ( BigDecimal total , String key , BigDecimal value , Range < Integer > standard ) {
BigDecimal percentage = total . intValue ( ) = = 0 ? BigDecimal . ZERO : value . divide ( total , 4 , RoundingMode . HALF_UP ) . multiply ( new BigDecimal ( 100 ) ) ;
percentage = percentage . setScale ( 2 , RoundingMode . HALF_UP ) ;
JSONObject result = JSONObject . of ( "name" , enumService . getNutrient ( key ) . getValue ( ) + "/总能量" ) ;
result . put ( "standard" , String . format ( "%s~%s" , standard . lowerEndpoint ( ) , standard . upperEndpoint ( ) ) ) ;
result . put ( "value" , valu e) ;
result . put ( "conclusion" , standard . lowerEndpoint ( ) > value ? "略低" : standard . upperEndpoint ( ) < value ? "略高" : "合适" ) ;
result . put ( "value" , percentag e) ;
result . put ( "conclusion" , standard . lowerEndpoint ( ) > percentage . intValue ( ) ? "略低" : standard . upperEndpoint ( ) < percentage . intValue ( ) ? "略高" : "合适" ) ;
return result ;
}
private static BigDecimal calculatePercentage ( BigDecimal value , BigDecimal base ) {
BigDecimal percentage = value . subtract ( base ) . divide ( base , 4 , RoundingMode . HALF_UP ) . multiply ( new BigDecimal ( 100 ) ) ;
return percentage . setScale ( 2 , RoundingMode . HALF_UP ) ;
}
}