|
|
@ -8,10 +8,7 @@ import com.alibaba.fastjson2.TypeReference; |
|
|
|
import com.google.common.collect.Lists; |
|
|
|
import com.google.common.collect.Maps; |
|
|
|
import com.google.common.collect.Range; |
|
|
|
import com.mathvision.diet.domian.MealType; |
|
|
|
import com.mathvision.diet.domian.MeasurementType; |
|
|
|
import com.mathvision.diet.domian.MenuDishItemDTO; |
|
|
|
import com.mathvision.diet.domian.RuleItemDTO; |
|
|
|
import com.mathvision.diet.domian.*; |
|
|
|
import com.mathvision.diet.entity.*; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.collections4.CollectionUtils; |
|
|
@ -24,10 +21,8 @@ import org.springframework.stereotype.Service; |
|
|
|
import javax.annotation.Resource; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.*; |
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@Slf4j |
|
|
@ -57,7 +52,12 @@ public class MenuReportService { |
|
|
|
.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)); |
|
|
|
//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));
|
|
|
|
|
|
|
|
//update 今日食材种类改成标准的四种分类,去除烹调油、调味品。按照【谷薯杂豆类】【蔬菜水果】【畜禽鱼蛋】【奶豆坚果类】
|
|
|
|
Map<String, String> categoryType = new HashMap<>(); |
|
|
|
nutrition.getFoodCategoryDay().forEach(foodCategoryDay -> foodCategoryDay.getCategory().forEach(category -> categoryType.put(category, foodCategoryDay.getName()))); |
|
|
|
Map<String, Integer> types = dishes.stream().flatMap(dish -> dish.getIngredient().stream().filter(item -> ingredientMap.containsKey(item.getKey())).map(item -> ingredientMap.get(item.getKey()).getType()).filter(categoryType::containsKey).map(categoryType::get)).collect(Collectors.toMap(categoryName -> categoryName, categoryName -> 1, Integer::sum)); |
|
|
|
|
|
|
|
itemStandard.forEach((key, value) -> { |
|
|
|
if (!items.containsKey(key)) { |
|
|
@ -93,7 +93,7 @@ public class MenuReportService { |
|
|
|
} |
|
|
|
JSONObject content = new JSONObject(); |
|
|
|
content.put("nutrition", String.format("%s/%s", foodNutrient.getValue(), foodNutrient.getMeasurement())); |
|
|
|
content.put("virtual", value); |
|
|
|
content.put("virtual", "energy".equals(key) ? value.setScale(0, RoundingMode.HALF_UP) : value); |
|
|
|
|
|
|
|
Map<String, BigDecimal> standard = itemStandard.get(key); |
|
|
|
BigDecimal max = standard == null ? null : standard.get("max"); |
|
|
@ -133,9 +133,9 @@ public class MenuReportService { |
|
|
|
content.put("overload", "-"); |
|
|
|
content.put("conclusion", "适量"); |
|
|
|
} else { |
|
|
|
if(value.compareTo(max) > 0) { |
|
|
|
if (value.compareTo(max) > 0) { |
|
|
|
byMax = true; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
byMin = true; |
|
|
|
} |
|
|
|
} |
|
|
@ -145,7 +145,7 @@ public class MenuReportService { |
|
|
|
if (byMin) { |
|
|
|
BigDecimal overload = calculatePercentage(value, min); |
|
|
|
content.put("overload", overload + "%"); |
|
|
|
if(overload.abs().compareTo(overflow) > 0) { |
|
|
|
if (overload.abs().compareTo(overflow) > 0) { |
|
|
|
content.put("conclusion", "不足"); |
|
|
|
} else { |
|
|
|
content.put("conclusion", "适量"); |
|
|
@ -155,8 +155,8 @@ public class MenuReportService { |
|
|
|
if (byMax) { |
|
|
|
BigDecimal overload = calculatePercentage(value, max); |
|
|
|
content.put("overload", overload + "%"); |
|
|
|
if(overload.compareTo(overflow) > 0) { |
|
|
|
if(ul != null && value.compareTo(ul) > 0) { |
|
|
|
if (overload.compareTo(overflow) > 0) { |
|
|
|
if (ul != null && value.compareTo(ul) > 0) { |
|
|
|
content.put("conclusion", "严重超标"); |
|
|
|
} else { |
|
|
|
content.put("conclusion", "过量"); |
|
|
@ -168,7 +168,10 @@ public class MenuReportService { |
|
|
|
|
|
|
|
contents.add(content); |
|
|
|
}); |
|
|
|
result.put("ingredient", contents); |
|
|
|
|
|
|
|
// update 按规则排序
|
|
|
|
JSONArray sortContents = NutritionSortEnum.sortByRule(contents); |
|
|
|
result.put("ingredient", sortContents); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
@ -181,6 +184,7 @@ public class MenuReportService { |
|
|
|
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<Pair<Long, String>, Integer> typesDay = dishes.stream().flatMap(dish -> dish.getIngredient().stream().filter(item -> ingredientMap.containsKey(item.getKey())).map(item -> Pair.of(dish.getDay(), ingredientMap.get(item.getKey()).getType()))).collect(Collectors.toMap(x -> x, x -> 1, Integer::sum)); |
|
|
|
Map<Pair<Long, String>, BigDecimal> weightDay = dishes.stream().flatMap(dish -> dish.getIngredient().stream().filter(item -> ingredientMap.containsKey(item.getKey())).map(item -> Triple.of(dish.getDay(), ingredientMap.get(item.getKey()).getType(), item.getValue().getOrDefault(crow, BigDecimal.ZERO)))).collect(Collectors.toMap(x -> Pair.of(x.getLeft(), x.getMiddle()), Triple::getRight, BigDecimal::add)); |
|
|
|
Map<Pair<Long, String>, String> ingredientDetailsDay = dishes.stream().flatMap(dish -> dish.getIngredient().stream().filter(item -> ingredientMap.containsKey(item.getKey())).map(item -> Triple.of(dish.getDay(), ingredientMap.get(item.getKey()).getType(), ingredientMap.get(item.getKey()).getName()))).collect(Collectors.toMap(x -> Pair.of(x.getLeft(), x.getMiddle()), Triple::getRight,(existing, replacement) -> existing + ", " + replacement)); |
|
|
|
|
|
|
|
Map<Long, Object> dayRule = Maps.newHashMap(); |
|
|
|
dishes.stream().map(MenuDish::getDay).forEach(day -> dayRule.put(day, dayStandard.stream().map(standard -> { |
|
|
@ -188,6 +192,8 @@ public class MenuReportService { |
|
|
|
content.put("day", day); |
|
|
|
content.put("name", standard.getName()); |
|
|
|
content.put("standard", standard.getRange()); |
|
|
|
String details = ingredientDetailsDay.entrySet().stream().filter(x -> x.getKey().getKey().equals(day) && standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).collect(Collectors.joining(",")); |
|
|
|
content.put("details", details); |
|
|
|
if (MeasurementType.quantity.equals(standard.getType())) { |
|
|
|
long supplied = typesDay.entrySet().stream().filter(x -> x.getKey().getKey().equals(day) && standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).reduce(Integer::sum).orElse(0); |
|
|
|
content.put("measurement", standard.getType()); |
|
|
@ -206,6 +212,8 @@ public class MenuReportService { |
|
|
|
JSONObject content = new JSONObject(); |
|
|
|
content.put("name", standard.getName()); |
|
|
|
content.put("standard", standard.getRange()); |
|
|
|
String details = ingredientDetailsDay.entrySet().stream().filter(x -> standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).collect(Collectors.joining(",")); |
|
|
|
content.put("details", details); |
|
|
|
if (MeasurementType.quantity.equals(standard.getType())) { |
|
|
|
long supplied = typesDay.entrySet().stream().filter(x -> standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).reduce(Integer::sum).orElse(0); |
|
|
|
content.put("measurement", standard.getType()); |
|
|
@ -238,7 +246,7 @@ public class MenuReportService { |
|
|
|
} |
|
|
|
|
|
|
|
public JSONObject energy(long day, String crow, List<MenuDish> dishes) { |
|
|
|
List<String> allConcerned= Lists.newArrayList("protein", "fat", "carbs"); |
|
|
|
List<String> allConcerned = Lists.newArrayList("protein", "fat", "carbs"); |
|
|
|
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()))) |
|
|
@ -281,17 +289,17 @@ public class MenuReportService { |
|
|
|
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<Long, BigDecimal> salt = dishes.stream().collect(Collectors.groupingBy(MenuDish::getDay)).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, |
|
|
|
entry -> entry.getValue().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)))) |
|
|
|
.filter(x -> StringUtils.equalsIgnoreCase("sodium", x.getKey())) |
|
|
|
.map(x -> x.getValue().multiply(new BigDecimal("0.0025"))) |
|
|
|
.reduce(BigDecimal :: add) |
|
|
|
.orElse(BigDecimal.ZERO))); |
|
|
|
.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)))) |
|
|
|
.filter(x -> StringUtils.equalsIgnoreCase("sodium", x.getKey())) |
|
|
|
.map(x -> x.getValue().multiply(new BigDecimal("0.0025"))) |
|
|
|
.reduce(BigDecimal::add) |
|
|
|
.orElse(BigDecimal.ZERO))); |
|
|
|
|
|
|
|
Map<Long, BigDecimal> sugar = dishes.stream().collect(Collectors.groupingBy(MenuDish::getDay)).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, |
|
|
|
entry -> entry.getValue().stream().flatMap(dish -> dish.getIngredient().stream().filter(item -> item.getValue().containsKey(crow) && item.getValue().get(crow).doubleValue() > 0 && ingredientMap.containsKey(item.getKey())) |
|
|
|
.map(x -> Pair.of(ingredientMap.get(x.getKey()), x.getValue())) |
|
|
|
.filter(x -> StringUtils.equals("糖类", x.getKey().getType())) |
|
|
|
.map(x -> x.getValue().values().stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO)) |
|
|
|
.map(x -> Pair.of(ingredientMap.get(x.getKey()), x.getValue())) |
|
|
|
.filter(x -> StringUtils.equals("糖类", x.getKey().getType())) |
|
|
|
.map(x -> x.getValue().values().stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO)) |
|
|
|
).reduce(BigDecimal::add).orElse(BigDecimal.ZERO))); |
|
|
|
|
|
|
|
Map<Long, BigDecimal> oil = dishes.stream().collect(Collectors.groupingBy(MenuDish::getDay)).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, |
|
|
@ -316,7 +324,7 @@ public class MenuReportService { |
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "营养素")); |
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "实际摄入")); |
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "标准范围")); |
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "UL值")); |
|
|
|
//headers.add(Lists.newArrayList("日均营养分析", "UL值"));
|
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "溢出范围")); |
|
|
|
headers.add(Lists.newArrayList("日均营养分析", "评价")); |
|
|
|
|
|
|
@ -325,8 +333,8 @@ public class MenuReportService { |
|
|
|
if (ingredient == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
List<List<Object>> contents = ingredient.stream().map(x -> (JSONObject)x).map(x -> Lists.newArrayList(x.get("nutrition"), x.get("virtual"), x.get("standard"), x.get("ul"), x.get("overload"), x.get("conclusion"))).collect(Collectors.toList()); |
|
|
|
//List<List<Object>> contents = ingredient.stream().map(x -> (JSONObject) x).map(x -> Lists.newArrayList(x.get("nutrition"), x.get("virtual"), x.get("standard"), x.get("ul"), x.get("overload"), x.get("conclusion"))).collect(Collectors.toList());
|
|
|
|
List<List<Object>> contents = ingredient.stream().map(x -> (JSONObject) x).map(x -> Lists.newArrayList(x.get("nutrition"), x.get("virtual"), x.get("standard"), x.get("overload"), x.get("conclusion"))).collect(Collectors.toList()); |
|
|
|
excelWriter.write(contents, EasyExcel.writerSheet("日均营养分析-" + crow).head(headers).build()); |
|
|
|
}); |
|
|
|
|
|
|
@ -342,7 +350,7 @@ public class MenuReportService { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
List<List<Object>> contents = energy.stream().map(x -> (JSONObject)x).map(x -> Lists.newArrayList(x.get("name"), x.get("standard"), x.get("value"), x.get("conclusion"))).collect(Collectors.toList()); |
|
|
|
List<List<Object>> contents = energy.stream().map(x -> (JSONObject) x).map(x -> Lists.newArrayList(x.get("name"), x.get("standard"), x.get("value"), x.get("conclusion"))).collect(Collectors.toList()); |
|
|
|
excelWriter.write(contents, EasyExcel.writerSheet("日均能量来源分布-" + crow).head(headers).build()); |
|
|
|
}); |
|
|
|
|
|
|
@ -352,6 +360,8 @@ public class MenuReportService { |
|
|
|
headers.add(Lists.newArrayList("食材种类统计", "种类名称")); |
|
|
|
headers.add(Lists.newArrayList("食材种类统计", "至少需要")); |
|
|
|
headers.add(Lists.newArrayList("食材种类统计", "当前含有")); |
|
|
|
//update 《食材种类统计》表格增加包含食材明细清单
|
|
|
|
headers.add(Lists.newArrayList("食材种类统计", "包含食材")); |
|
|
|
headers.add(Lists.newArrayList("食材种类统计", "还需")); |
|
|
|
|
|
|
|
JSONObject types = types(menu, crow, menuDishService.query(menu.getId(), menu.getVender())); |
|
|
@ -361,12 +371,16 @@ public class MenuReportService { |
|
|
|
|
|
|
|
List<List<Object>> contents = Lists.newArrayList(); |
|
|
|
JSONArray weekRule = types.getJSONArray("weekRule"); |
|
|
|
//update 《食材种类统计》表格“至少需要”一栏去掉单位“克”,包含食材明细;
|
|
|
|
if (weekRule != null) { |
|
|
|
contents.addAll(weekRule.stream().map(x -> (JSONObject)x).map(x -> Lists.newArrayList("周合计", x.get("name"), MeasurementType.quantity.name().equals(x.getString("measurement")) ? x.get("standard") + "种" : x.get("standard") + "克", x.get("supplied"), x.get("lack"))).collect(Collectors.toList())); |
|
|
|
//contents.addAll(weekRule.stream().map(x -> (JSONObject) x).map(x -> Lists.newArrayList("周合计", x.get("name"), MeasurementType.quantity.name().equals(x.getString("measurement")) ? x.get("standard") + "种" : x.get("standard") + "克", x.get("supplied"), x.get("lack"))).collect(Collectors.toList()));
|
|
|
|
contents.addAll(weekRule.stream().map(x -> (JSONObject) x).map(x -> Lists.newArrayList("周合计", x.get("name"), x.get("standard"), x.get("supplied"), x.get("details"), x.get("lack"))).collect(Collectors.toList())); |
|
|
|
} |
|
|
|
Map<Long, List<JSONObject>> dayRule = types.getObject("dayRule", new TypeReference<Map<Long, List<JSONObject>>>() {}); |
|
|
|
Map<Long, List<JSONObject>> dayRule = types.getObject("dayRule", new TypeReference<Map<Long, List<JSONObject>>>() { |
|
|
|
}); |
|
|
|
if (dayRule != null) { |
|
|
|
dayRule.forEach((k, v) -> contents.addAll(v.stream().map(x -> Lists.newArrayList("周" + x.getString("day"), x.get("name"), MeasurementType.quantity.name().equals(x.getString("measurement")) ? x.get("standard") + "种" : x.get("standard") + "克", x.get("supplied"), x.get("lack"))).collect(Collectors.toList()))); |
|
|
|
//dayRule.forEach((k, v) -> contents.addAll(v.stream().map(x -> Lists.newArrayList("周" + x.getString("day"), x.get("name"), MeasurementType.quantity.name().equals(x.getString("measurement")) ? x.get("standard") + "种" : x.get("standard") + "克", x.get("supplied"), x.get("lack"))).collect(Collectors.toList())));
|
|
|
|
dayRule.forEach((k, v) -> contents.addAll(v.stream().map(x -> Lists.newArrayList("周" + x.getString("day"), x.get("name"), x.get("standard"), x.get("supplied"), x.get("details"), x.get("lack"))).collect(Collectors.toList()))); |
|
|
|
} |
|
|
|
excelWriter.write(contents, EasyExcel.writerSheet("食材种类统计-" + crow).head(headers).build()); |
|
|
|
}); |
|
|
@ -382,7 +396,7 @@ public class MenuReportService { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
List<List<Object>> contents = polys.entrySet().stream().filter(kv -> StringUtils.isNumeric(kv.getKey())).map(kv -> ((Map<Object, Object>)kv.getValue()).entrySet().stream().map(x -> Lists.newArrayList(kv.getKey().equals("0") ? "周合计" : "周" + kv.getKey(), x.getKey(), x.getValue())).collect(Collectors.toList())).flatMap(Collection::stream).collect(Collectors.toList()); |
|
|
|
List<List<Object>> contents = polys.entrySet().stream().filter(kv -> StringUtils.isNumeric(kv.getKey())).map(kv -> ((Map<Object, Object>) kv.getValue()).entrySet().stream().map(x -> Lists.newArrayList(kv.getKey().equals("0") ? "周合计" : "周" + kv.getKey(), x.getKey(), x.getValue())).collect(Collectors.toList())).flatMap(Collection::stream).collect(Collectors.toList()); |
|
|
|
excelWriter.write(contents, EasyExcel.writerSheet("烹饪方式统计-" + crow).head(headers).build()); |
|
|
|
}); |
|
|
|
} |
|
|
@ -405,10 +419,14 @@ public class MenuReportService { |
|
|
|
VenderConfig config = venderService.queryConfig(menu.getVender()); |
|
|
|
BigDecimal scale = menu.getMeals().stream().map(MealType::toType).distinct().map(x -> { |
|
|
|
switch (x) { |
|
|
|
case breakfast: return config.getBreakfast(); |
|
|
|
case lunch: return config.getLunch(); |
|
|
|
case dinner: return config.getDinner(); |
|
|
|
default: return BigDecimal.ZERO; |
|
|
|
case breakfast: |
|
|
|
return config.getBreakfast(); |
|
|
|
case lunch: |
|
|
|
return config.getLunch(); |
|
|
|
case dinner: |
|
|
|
return config.getDinner(); |
|
|
|
default: |
|
|
|
return BigDecimal.ZERO; |
|
|
|
} |
|
|
|
}).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); |
|
|
|
|
|
|
|