|
@ -22,6 +22,7 @@ import javax.annotation.Resource; |
|
|
import javax.persistence.criteria.Predicate; |
|
|
import javax.persistence.criteria.Predicate; |
|
|
import java.math.BigDecimal; |
|
|
import java.math.BigDecimal; |
|
|
import java.math.RoundingMode; |
|
|
import java.math.RoundingMode; |
|
|
|
|
|
import java.text.DecimalFormat; |
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@ -29,6 +30,7 @@ import java.util.stream.Collectors; |
|
|
@Service |
|
|
@Service |
|
|
public class DishService { |
|
|
public class DishService { |
|
|
private static final List<String> MUST_DISPLAY_ITEM = Lists.newArrayList("energy", "fat", "sodium"); |
|
|
private static final List<String> MUST_DISPLAY_ITEM = Lists.newArrayList("energy", "fat", "sodium"); |
|
|
|
|
|
private static final List<String> WANT_DISPLAY_ITEM = Lists.newArrayList("energy", "protein", "fat", "carbs", "sugar", "sodium"); |
|
|
|
|
|
|
|
|
@Resource |
|
|
@Resource |
|
|
private EnumService enumService; |
|
|
private EnumService enumService; |
|
@ -137,46 +139,45 @@ public class DishService { |
|
|
return Lists.newArrayList(); |
|
|
return Lists.newArrayList(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DecimalFormat format = new DecimalFormat(); |
|
|
|
|
|
format.setMaximumFractionDigits(1); |
|
|
|
|
|
format.setMinimumFractionDigits(0); |
|
|
|
|
|
format.setRoundingMode(RoundingMode.HALF_UP); |
|
|
|
|
|
|
|
|
Map<String, Ingredient> ingredientMap = ingredientService.getFullByKeys(dishes.stream().filter(x -> CollectionUtils.isNotEmpty(x.getIngredient())).flatMap(x -> x.getIngredient().stream().map(DishItemDTO::getKey)).collect(Collectors.toSet())).stream().collect(Collectors.toMap(Ingredient::getKey, v -> v)); |
|
|
Map<String, Ingredient> ingredientMap = ingredientService.getFullByKeys(dishes.stream().filter(x -> CollectionUtils.isNotEmpty(x.getIngredient())).flatMap(x -> x.getIngredient().stream().map(DishItemDTO::getKey)).collect(Collectors.toSet())).stream().collect(Collectors.toMap(Ingredient::getKey, v -> v)); |
|
|
return dishes.parallelStream().filter(dish -> CollectionUtils.isNotEmpty(dish.getIngredient())).map(dish -> { |
|
|
return dishes.parallelStream().filter(dish -> CollectionUtils.isNotEmpty(dish.getIngredient())).map(dish -> { |
|
|
List<String> ingredients = dish.getIngredient().stream().filter(item -> BooleanUtils.isTrue(item.getIsMain())).map(DishItemDTO::getKey).filter(ingredientMap::containsKey).map(x -> ingredientMap.get(x).getName()).collect(Collectors.toList()); |
|
|
List<String> ingredients = dish.getIngredient().stream().filter(item -> BooleanUtils.isTrue(item.getIsMain())).map(DishItemDTO::getKey).filter(ingredientMap::containsKey).map(x -> ingredientMap.get(x).getName()).collect(Collectors.toList()); |
|
|
List<ComponentAnalysisDO> component = dish.getIngredient().stream().filter(x -> ingredientMap.containsKey(x.getKey())).flatMap(x -> { |
|
|
|
|
|
Ingredient ingredient = ingredientMap.get(x.getKey()); |
|
|
|
|
|
return ingredient.getNutrient().entrySet().stream().map(n -> Pair.of(n.getKey(), n.getValue().multiply(x.getValue()).divide(new BigDecimal(100), RoundingMode.HALF_UP))); |
|
|
|
|
|
}).collect(Collectors.toMap(Pair::getKey, Pair::getValue, BigDecimal::add)).entrySet().stream().filter(r -> r.getValue() != null && r.getValue().compareTo(BigDecimal.ZERO) > 0).map(r -> { |
|
|
|
|
|
FoodNutrient foodNutrient = enumService.getNutrient(r.getKey()); |
|
|
|
|
|
if (foodNutrient == null) { |
|
|
|
|
|
return ComponentAnalysisDO.builder().key(r.getKey()).name(r.getKey()).nutrition(String.format("%.2f(-)", r.getValue())).nvr("-").build(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.endsWithIgnoreCase(r.getKey(), "sodium")) { |
|
|
Map<String, BigDecimal> items = dish.getIngredient().stream().filter(x -> ingredientMap.containsKey(x.getKey())).flatMap(x -> |
|
|
return ComponentAnalysisDO.builder().key(r.getKey()).name(foodNutrient.getValue() + "/食盐").nutrition(String.format("%.1f(%s)/%.2f(g)", r.getValue().floatValue(), foodNutrient.getMeasurement(), r.getValue().multiply(new BigDecimal("0.0025")).floatValue())).nvr(foodNutrient.getNrv() == null || foodNutrient.getNrv().floatValue() == 0 ? "-" : String.format("%.2f%%", r.getValue().divide(foodNutrient.getNrv(), RoundingMode.HALF_UP).multiply(new BigDecimal(100)))).build(); |
|
|
ingredientMap.get(x.getKey()).getNutrient().entrySet().stream().map(n -> Pair.of(n.getKey(), n.getValue().multiply(x.getValue()).divide(new BigDecimal(100), RoundingMode.HALF_UP))) |
|
|
} else { |
|
|
).filter(x -> x.getValue() != null && x.getValue().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toMap(Pair::getKey, Pair::getValue, BigDecimal::add)); |
|
|
return ComponentAnalysisDO.builder().key(r.getKey()).name(foodNutrient.getValue()).nutrition(String.format("%.2f(%s)", r.getValue().floatValue(), foodNutrient.getMeasurement())).nvr(foodNutrient.getNrv() == null || foodNutrient.getNrv().floatValue() == 0 ? "-" : String.format("%.2f%%", r.getValue().divide(foodNutrient.getNrv(), RoundingMode.HALF_UP).multiply(new BigDecimal(100)))).build(); |
|
|
|
|
|
} |
|
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
|
|
|
MUST_DISPLAY_ITEM.forEach(item -> { |
|
|
items.put("sugar", dish.getIngredient().stream().filter(x -> ingredientMap.containsKey(x.getKey())) |
|
|
if(component.stream().noneMatch(x -> StringUtils.equals(x.getKey(), item))) { |
|
|
.map(x -> Pair.of(ingredientMap.get(x.getKey()), x.getValue())) |
|
|
FoodNutrient foodNutrient = enumService.getNutrient(item); |
|
|
.filter(x -> StringUtils.equals("糖类", x.getKey().getType())).map(Pair::getValue).reduce(BigDecimal::add).orElse(BigDecimal.ZERO)); |
|
|
if(foodNutrient == null) { |
|
|
|
|
|
component.add(ComponentAnalysisDO.builder().key(item).name(item).nutrition(String.format("%.2f(-)", 0.0)).nvr("-").build()); |
|
|
MUST_DISPLAY_ITEM.forEach(x -> { |
|
|
} else { |
|
|
if (!items.containsKey(x)) { |
|
|
if (StringUtils.endsWithIgnoreCase(item, "sodium")) { |
|
|
items.put(x, BigDecimal.ZERO); |
|
|
component.add(ComponentAnalysisDO.builder().key(foodNutrient.getKey()).name(foodNutrient.getValue() + "/食盐").nutrition(String.format("0(%s)/0(g)", foodNutrient.getMeasurement())).nvr("-").build() ); |
|
|
|
|
|
} else { |
|
|
|
|
|
component.add(ComponentAnalysisDO.builder().key(foodNutrient.getKey()).name(foodNutrient.getValue()).nutrition(String.format("0(%s)", foodNutrient.getMeasurement())).nvr("-").build() ); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
BigDecimal sugar = dish.getIngredient().stream().filter(x -> ingredientMap.containsKey(x.getKey())) |
|
|
List<ComponentAnalysisDO> component = items.entrySet().stream().filter(x -> MUST_DISPLAY_ITEM.contains(x.getKey()) || WANT_DISPLAY_ITEM.contains(x.getKey()) && x.getValue() != null && x.getValue().compareTo(BigDecimal.ZERO) > 0).map(x -> { |
|
|
.map(x -> Pair.of(ingredientMap.get(x.getKey()), x.getValue())) |
|
|
FoodNutrient foodNutrient = enumService.getNutrient(x.getKey()); |
|
|
.filter(x -> StringUtils.equals("糖类", x.getKey().getType())).map(Pair::getValue).reduce(BigDecimal::add).orElse(null); |
|
|
if (foodNutrient == null) { |
|
|
if (sugar != null && sugar.compareTo(BigDecimal.ZERO) > 0) { |
|
|
foodNutrient = FoodNutrient.builder().key(x.getKey()).measurement("-").build(); |
|
|
component.add(ComponentAnalysisDO.builder().key("sugar").name("糖").nutrition(String.format("%.2f(g)", sugar)).nvr("-").build()); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
String name = x.getKey().equals("sugar") ? "糖" : StringUtils.isBlank(foodNutrient.getValue()) ? x.getKey() : foodNutrient.getValue(); |
|
|
|
|
|
String value = String.format("%s(%s)", format.format(x.getValue().floatValue()), foodNutrient.getMeasurement() == null ? "-" : foodNutrient.getMeasurement()); |
|
|
|
|
|
String nvr = foodNutrient.getNrv() == null || foodNutrient.getNrv().floatValue() == 0 ? "-" : String.format("%.2f%%", x.getValue().divide(foodNutrient.getNrv(), RoundingMode.HALF_UP).multiply(new BigDecimal(100))); |
|
|
|
|
|
if (StringUtils.equalsIgnoreCase(x.getKey(), "sodium")) { |
|
|
|
|
|
float salt = x.getValue().multiply(new BigDecimal("0.0025")).floatValue(); |
|
|
|
|
|
name = "钠/食盐"; |
|
|
|
|
|
value = String.format("%s(mg)/%s(g)", format.format(x.getValue().floatValue()), format.format(salt)); |
|
|
} |
|
|
} |
|
|
|
|
|
return ComponentAnalysisDO.builder().key(x.getKey()).name(name).nutrition(value).nvr(nvr).build(); |
|
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
return DishLabelDO.builder().name(dish.getName()).ingredients(ingredients).component(component).build(); |
|
|
return DishLabelDO.builder().name(dish.getName()).ingredients(ingredients).component(component).build(); |
|
|
}).collect(Collectors.toList()); |
|
|
}).collect(Collectors.toList()); |
|
|