caoyiwen 2 years ago
parent
commit
a890e88d58
  1. 11
      diet-core/src/main/java/com/mathvision/diet/service/EnumService.java
  2. 76
      diet-core/src/main/java/com/mathvision/diet/service/MenuReportService.java
  3. 22
      diet-dao/src/main/java/com/mathvision/diet/domian/MeasurementType.java
  4. 19
      diet-dao/src/main/java/com/mathvision/diet/domian/RuleItemDTO.java
  5. 10
      diet-dao/src/main/java/com/mathvision/diet/entity/Nutrition.java
  6. 2
      diet-web/src/main/java/com/mathvision/diet/aspect/GlobalExceptionHandler.java
  7. 2
      diet-web/src/main/java/com/mathvision/diet/controller/MenuReportController.java
  8. 25
      diet-web/src/main/java/com/mathvision/diet/controller/NutritionController.java
  9. 102
      diet-web/src/main/resources/static/basic.html
  10. 330
      diet-web/src/main/resources/static/menu/report.html
  11. 95
      diet-web/src/main/resources/static/nutrition.html
  12. 102
      doc/basic.md
  13. 330
      doc/menu/report.md
  14. 107
      doc/nutrition.md

11
diet-core/src/main/java/com/mathvision/diet/service/EnumService.java

@ -104,6 +104,17 @@ public class EnumService {
return x.getType(); return x.getType();
} }
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
result.put("measurementType", Arrays.stream(MeasurementType.values()).map(x -> new KeyValue<String, String>() {
@Override
public String getKey() {
return x.name();
}
@Override
public String getValue() {
return x.getType();
}
}).collect(Collectors.toList()));
return result; return result;
} }

76
diet-core/src/main/java/com/mathvision/diet/service/MenuReportService.java

@ -5,11 +5,14 @@ import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.mathvision.diet.domian.MeasurementType;
import com.mathvision.diet.domian.MenuDishItemDTO; import com.mathvision.diet.domian.MenuDishItemDTO;
import com.mathvision.diet.domian.RuleItemDTO;
import com.mathvision.diet.entity.*; import com.mathvision.diet.entity.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -32,12 +35,13 @@ public class MenuReportService {
@Resource @Resource
IngredientService ingredientService; IngredientService ingredientService;
public JSONObject assess(Menu menu, long day, String crow, List<MenuDish> dishes) { public JSONObject nutrition(Menu menu, long day, String crow, List<MenuDish> dishes) {
Nutrition nutrition = nutritionService.get(menu.getNutrient()); Nutrition nutrition = nutritionService.get(menu.getNutrient());
BigDecimal overflow = nutrition.getOverflow(); BigDecimal overflow = nutrition.getOverflow();
Map<String, Map<String, BigDecimal>> itemStandard = nutrition.getIngredient().getOrDefault(crow, new HashMap<>()); 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, 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()))) 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)))) .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)); .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));
@ -144,39 +148,50 @@ public class MenuReportService {
public JSONObject types(Menu menu, String crow, List<MenuDish> dishes) { public JSONObject types(Menu menu, String crow, List<MenuDish> dishes) {
dishes = dishes.stream().filter(menuDish -> menuDish.getIngredient().stream().anyMatch(item -> item.getValue().containsKey(crow))).collect(Collectors.toList()); dishes = dishes.stream().filter(menuDish -> menuDish.getIngredient().stream().anyMatch(item -> item.getValue().containsKey(crow))).collect(Collectors.toList());
Nutrition nutrition = nutritionService.get(menu.getNutrient()); Nutrition nutrition = nutritionService.get(menu.getNutrient());
Map<String, BigDecimal> dayStandard = nutrition.getFoodCategoryDay();
Map<String, BigDecimal> weekStandard = nutrition.getFoodCategoryWeek(); List<RuleItemDTO> dayStandard = nutrition.getFoodCategoryDay();
List<RuleItemDTO> weekStandard = nutrition.getFoodCategoryWeek();
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, 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>, 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));
JSONArray dayRule = new JSONArray(); 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<Long, JSONArray> dayMaps = Maps.newHashMap();
typesDay.forEach((key, num) -> { Map<Long, Object> dayRule = Maps.newHashMap();
Long day = key.getKey(); dishes.stream().map(MenuDish::getDay).forEach(day -> dayRule.put(day, dayStandard.stream().map(standard -> {
JSONArray dayCollection = dayMaps.getOrDefault(day, new JSONArray());
String type = key.getValue();
int standard = dayStandard.getOrDefault(type, BigDecimal.ZERO).intValue();
JSONObject content = new JSONObject(); JSONObject content = new JSONObject();
content.put("day", day); content.put("day", day);
content.put("name", type); content.put("name", standard.getName());
content.put("standard", standard); content.put("standard", standard.getRange());
content.put("supplied", num); if (MeasurementType.quantity.equals(standard.getType())) {
content.put("lack", num >= standard ? 0 : standard - num); 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);
dayCollection.add(content); content.put("measurement", standard.getType());
dayMaps.put(day, dayCollection); content.put("supplied", supplied);
}); content.put("lack", standard.getLack(new BigDecimal(supplied)));
dayRule.addAll(dayMaps.values()); } else {
BigDecimal supplied = weightDay.entrySet().stream().filter(x -> x.getKey().getKey().equals(day) && standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
content.put("measurement", standard.getType());
content.put("supplied", supplied);
content.put("lack", standard.getLack(supplied));
}
return content;
}).collect(Collectors.toList())));
Map<String, Integer> typesAll = 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)); List<JSONObject> weekRule = weekStandard.stream().map(standard -> {
JSONArray weekRule = new JSONArray();
typesAll.forEach((type, num) -> {
BigDecimal standard = weekStandard.getOrDefault(type, BigDecimal.ZERO);
JSONObject content = new JSONObject(); JSONObject content = new JSONObject();
content.put("name", type); content.put("name", standard.getName());
content.put("standard", standard); content.put("standard", standard.getRange());
content.put("supplied", num); if (MeasurementType.quantity.equals(standard.getType())) {
content.put("lack", num.compareTo(standard.intValue()) > 0 ? 0 : standard.intValue() - num); long supplied = typesDay.entrySet().stream().filter(x -> standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).reduce(Integer::sum).orElse(0);
weekRule.add(content); content.put("measurement", standard.getType());
}); content.put("supplied", supplied);
content.put("lack", standard.getLack(new BigDecimal(supplied)));
} else {
BigDecimal supplied = weightDay.entrySet().stream().filter(x -> standard.getCategory().contains(x.getKey().getValue())).map(Map.Entry::getValue).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
content.put("measurement", standard.getType());
content.put("supplied", supplied);
content.put("lack", standard.getLack(supplied));
}
return content;
}).collect(Collectors.toList());
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
result.put("crow", crow); result.put("crow", crow);
@ -196,7 +211,7 @@ public class MenuReportService {
} }
public JSONObject energy(long day, String crow, List<MenuDish> dishes) { public JSONObject energy(long day, String crow, List<MenuDish> dishes) {
List<String> allConcerned= Lists.newArrayList("energy", "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, 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() 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(dish -> dish.getIngredient().stream().filter(item -> item.getValue().containsKey(crow) && item.getValue().get(crow).doubleValue() > 0 && ingredientMap.containsKey(item.getKey())))
@ -215,7 +230,6 @@ public class MenuReportService {
result.put("crow", crow); result.put("crow", crow);
result.put("meals", dishes.stream().map(MenuDish::getMeal).collect(Collectors.toSet())); result.put("meals", dishes.stream().map(MenuDish::getMeal).collect(Collectors.toSet()));
//BigDecimal energy = items.get("energy").multiply(new BigDecimal("4.18"));
BigDecimal protein = items.get("protein").multiply(new BigDecimal("4")); BigDecimal protein = items.get("protein").multiply(new BigDecimal("4"));
BigDecimal fat = items.get("fat").multiply(new BigDecimal("9")); BigDecimal fat = items.get("fat").multiply(new BigDecimal("9"));
BigDecimal carbs = items.get("carbs").multiply(new BigDecimal("4")); BigDecimal carbs = items.get("carbs").multiply(new BigDecimal("4"));

22
diet-dao/src/main/java/com/mathvision/diet/domian/MeasurementType.java

@ -1,5 +1,25 @@
package com.mathvision.diet.domian; package com.mathvision.diet.domian;
import lombok.Getter;
import java.util.Arrays;
public enum MeasurementType { public enum MeasurementType {
weight, quantity weight("克"), quantity("种");
@Getter
private final String type;
MeasurementType(String type) {
this.type = type;
}
@Override
public String toString() {
return type;
}
public static MeasurementType toType(String s) {
return Arrays.stream(MeasurementType.values()).filter(x -> x.getType().equals(s)).findFirst().orElse(null);
}
} }

19
diet-dao/src/main/java/com/mathvision/diet/domian/RuleItemDTO.java

@ -35,7 +35,24 @@ public class RuleItemDTO {
*/ */
BigDecimal min; BigDecimal min;
public String getRange() {
if (max == null) return "≥" + min;
if (min == null) return "≤" + max;
return min + "~" + max;
}
public BigDecimal getLack(BigDecimal num) {
if (max == null) return min.compareTo(num) > 0 ? min.subtract(num) : BigDecimal.ZERO;
if (min == null) return max.compareTo(num) > 0 ? BigDecimal.ZERO : max.subtract(num);
return min.compareTo(num) > 0 ? min.subtract(num) : max.compareTo(num) > 0 ? BigDecimal.ZERO : max.subtract(num);
}
public boolean check() { public boolean check() {
return StringUtils.isNotBlank(name) && type != null && CollectionUtils.isNotEmpty(category) && (max != null || min != null); if(max != null && min != null && max.compareTo(min) < 0) {
BigDecimal temp = max;
max = min;
min = temp;
}
return StringUtils.isNotBlank(name) && type != null && CollectionUtils.isNotEmpty(category) && (max != null && min == null || max == null && min != null || max != null);
} }
} }

10
diet-dao/src/main/java/com/mathvision/diet/entity/Nutrition.java

@ -2,6 +2,8 @@ package com.mathvision.diet.entity;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import com.mathvision.diet.convert.IngredientConvert; import com.mathvision.diet.convert.IngredientConvert;
import com.mathvision.diet.convert.RuleItemConvert;
import com.mathvision.diet.domian.RuleItemDTO;
import com.vladmihalcea.hibernate.type.json.JsonStringType; import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.*; import lombok.*;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
@ -34,13 +36,13 @@ public class Nutrition {
@Column(name = "vendors", columnDefinition = "json", nullable = false) @Column(name = "vendors", columnDefinition = "json", nullable = false)
private List<Long> vendors; private List<Long> vendors;
@Type( type = "json" ) @Convert(converter = RuleItemConvert.class)
@Column(name = "food_category_day", columnDefinition = "json") @Column(name = "food_category_day", columnDefinition = "json")
private Map<String, BigDecimal> foodCategoryDay; private List<RuleItemDTO> foodCategoryDay;
@Type( type = "json" ) @Convert(converter = RuleItemConvert.class)
@Column(name = "food_category_week", columnDefinition = "json") @Column(name = "food_category_week", columnDefinition = "json")
private Map<String, BigDecimal> foodCategoryWeek; private List<RuleItemDTO> foodCategoryWeek;
@Convert(converter = IngredientConvert.class) @Convert(converter = IngredientConvert.class)
@Column(name = "ingredient", columnDefinition = "json") @Column(name = "ingredient", columnDefinition = "json")

2
diet-web/src/main/java/com/mathvision/diet/aspect/GlobalExceptionHandler.java

@ -33,7 +33,7 @@ public class GlobalExceptionHandler {
} }
@ResponseBody @ResponseBody
@ExceptionHandler({IllegalArgumentException.class}) @ExceptionHandler({IllegalArgumentException.class, IllegalStateException.class})
public Result errorHandler(IllegalArgumentException e) { public Result errorHandler(IllegalArgumentException e) {
return _innerHandler(Result.ILLEGAL_ARGUMENT, e, false); return _innerHandler(Result.ILLEGAL_ARGUMENT, e, false);
} }

2
diet-web/src/main/java/com/mathvision/diet/controller/MenuReportController.java

@ -38,7 +38,7 @@ public class MenuReportController extends BaseController {
day = checkAndGetDay(day, menu.getDay()); day = checkAndGetDay(day, menu.getDay());
crow = checkAndGetCrow(crow, menu.getCrows()); crow = checkAndGetCrow(crow, menu.getCrows());
List<MenuDish> dishes = menuDishService.query(id, menu.getVender(), day); List<MenuDish> dishes = menuDishService.query(id, menu.getVender(), day);
return menuReportService.assess(menu, day, crow, dishes); return menuReportService.nutrition(menu, day, crow, dishes);
} }
@ResponseBody @ResponseBody

25
diet-web/src/main/java/com/mathvision/diet/controller/NutritionController.java

@ -1,8 +1,11 @@
package com.mathvision.diet.controller; package com.mathvision.diet.controller;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.TypeReference; import com.alibaba.fastjson2.TypeReference;
import com.mathvision.diet.domian.RuleItemDTO;
import com.mathvision.diet.entity.Nutrition; import com.mathvision.diet.entity.Nutrition;
import com.mathvision.diet.service.EnumService;
import com.mathvision.diet.service.NutritionService; import com.mathvision.diet.service.NutritionService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -24,6 +27,9 @@ import java.util.Map;
@RequestMapping("/api/nutrition") @RequestMapping("/api/nutrition")
@Controller @Controller
public class NutritionController extends BaseController { public class NutritionController extends BaseController {
@Resource
EnumService enumService;
@Resource @Resource
NutritionService nutritionService; NutritionService nutritionService;
@ -52,8 +58,6 @@ public class NutritionController extends BaseController {
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
public Nutrition update(@RequestParam Long id, @RequestParam(required = false) String name, @RequestParam(required = false) BigDecimal overflow, @RequestParam(required = false) List<Long > vendors, @RequestParam(required = false) String foodCategoryDay, @RequestParam(required = false) String foodCategoryWeek, @RequestParam(required = false) String ingredient) { public Nutrition update(@RequestParam Long id, @RequestParam(required = false) String name, @RequestParam(required = false) BigDecimal overflow, @RequestParam(required = false) List<Long > vendors, @RequestParam(required = false) String foodCategoryDay, @RequestParam(required = false) String foodCategoryWeek, @RequestParam(required = false) String ingredient) {
Assert.isTrue(isAdmin(), "[参数错误]无操作权限!"); Assert.isTrue(isAdmin(), "[参数错误]无操作权限!");
Assert.isTrue(foodCategoryDay == null || JSON.isValid(foodCategoryDay), "[参数错误]日标准JSON解析错误!");
Assert.isTrue(foodCategoryWeek == null || JSON.isValid(foodCategoryWeek), "[参数错误]周标准JSON解析错误!");
Assert.isTrue(ingredient == null || JSON.isValid(ingredient), "[参数错误]食材JSON解析错误!"); Assert.isTrue(ingredient == null || JSON.isValid(ingredient), "[参数错误]食材JSON解析错误!");
Nutrition nutrition = nutritionService.get(id); Nutrition nutrition = nutritionService.get(id);
@ -72,12 +76,12 @@ public class NutritionController extends BaseController {
nutrition.setVendors(vendors); nutrition.setVendors(vendors);
flag = true; flag = true;
} }
if (JSON.isValid(foodCategoryDay)) { if (StringUtils.isNotBlank(foodCategoryDay)) {
nutrition.setFoodCategoryDay(JSON.parseObject(foodCategoryDay, new TypeReference<Map<String, BigDecimal>>(){})); nutrition.setFoodCategoryDay(checkAndConvert(foodCategoryDay, "日规则"));
flag = true; flag = true;
} }
if (JSON.isValid(foodCategoryWeek)) { if (StringUtils.isNotBlank(foodCategoryWeek)) {
nutrition.setFoodCategoryWeek(JSON.parseObject(foodCategoryWeek, new TypeReference<Map<String, BigDecimal>>(){})); nutrition.setFoodCategoryWeek(checkAndConvert(foodCategoryWeek, "周规则"));
flag = true; flag = true;
} }
if (JSON.isValid(ingredient)) { if (JSON.isValid(ingredient)) {
@ -99,10 +103,17 @@ public class NutritionController extends BaseController {
@ResponseBody @ResponseBody
@RequestMapping(value="select", method = RequestMethod.GET) @RequestMapping(value="select", method = RequestMethod.GET)
public Object query(@RequestParam(required = false) Long id, @RequestParam(required = false, value = "name") String keyword, @RequestParam(required = false) Long vender) { public Object query(@RequestParam(required = false) Long id, @RequestParam(required = false) String keyword, @RequestParam(required = false) Long vender) {
if (id != null) { if (id != null) {
return nutritionService.get(id); return nutritionService.get(id);
} }
return nutritionService.query(isAdmin() ? vender : getVender(), keyword); return nutritionService.query(isAdmin() ? vender : getVender(), keyword);
} }
private List<RuleItemDTO> checkAndConvert(String standard, String desc) {
Assert.isTrue(JSON.isValid(standard), "[参数错误]" + desc + "JSON解析错误!");
List<RuleItemDTO> result = JSONArray.parseArray(standard, RuleItemDTO.class);
Assert.isTrue(result.stream().allMatch(x -> x.check() && x.getCategory().stream().allMatch(c -> enumService.checkCategory(c))), "[参数错误]" + desc + ":规则名称/计量单位/食材种类必填, 最大值/最小值至少填一个!");
return result;
}
} }

102
diet-web/src/main/resources/static/basic.html

@ -110,6 +110,12 @@ password=BE56E057F20F883E //
&quot;nrv&quot;: 100.00, &quot;nrv&quot;: 100.00,
&quot;value&quot;: &quot;维生素C&quot; &quot;value&quot;: &quot;维生素C&quot;
}, },
{
&quot;key&quot;: &quot;sodium&quot;,
&quot;measurement&quot;: &quot;mg&quot;,
&quot;nrv&quot;: 2000.00,
&quot;value&quot;: &quot;ÄÆ&quot;
},
{ {
&quot;key&quot;: &quot;protein&quot;, &quot;key&quot;: &quot;protein&quot;,
&quot;measurement&quot;: &quot;g&quot;, &quot;measurement&quot;: &quot;g&quot;,
@ -138,7 +144,7 @@ password=BE56E057F20F883E //
&quot;key&quot;: &quot;energy&quot;, &quot;key&quot;: &quot;energy&quot;,
&quot;measurement&quot;: &quot;kcal&quot;, &quot;measurement&quot;: &quot;kcal&quot;,
&quot;nrv&quot;: 2000.00, &quot;nrv&quot;: 2000.00,
&quot;value&quot;: &quot;能量kcal&quot; &quot;value&quot;: &quot;ÄÜÁ¿&quot;
} }
], ],
&quot;menuStatus&quot;: [ &quot;menuStatus&quot;: [
@ -146,22 +152,6 @@ password=BE56E057F20F883E //
&quot;key&quot;: 0, &quot;key&quot;: 0,
&quot;value&quot;: &quot;草稿&quot; &quot;value&quot;: &quot;草稿&quot;
}, },
{
&quot;key&quot;: 1,
&quot;value&quot;: &quot;提交审核&quot;
},
{
&quot;key&quot;: 2,
&quot;value&quot;: &quot;审核通过&quot;
},
{
&quot;key&quot;: 3,
&quot;value&quot;: &quot;审核失败&quot;
},
{
&quot;key&quot;: 4,
&quot;value&quot;: &quot;禁用&quot;
},
{ {
&quot;key&quot;: 5, &quot;key&quot;: 5,
&quot;value&quot;: &quot;发布&quot; &quot;value&quot;: &quot;发布&quot;
@ -177,6 +167,64 @@ password=BE56E057F20F883E //
&quot;value&quot;: &quot;忌用&quot; &quot;value&quot;: &quot;忌用&quot;
} }
], ],
&quot;poly&quot;: [
{
&quot;key&quot;: &quot;¿¾&quot;,
&quot;name&quot;: &quot;¿¾&quot;
},
{
&quot;key&quot;: &quot;±&quot;,
&quot;name&quot;: &quot;±&quot;
},
{
&quot;key&quot;: &quot;ÎÞÐèÅëâ¿&quot;,
&quot;name&quot;: &quot;ÎÞÐèÅëâ¿&quot;
},
{
&quot;key&quot;: &quot;ÉÕ&quot;,
&quot;name&quot;: &quot;ÉÕ&quot;
},
{
&quot;key&quot;: &quot;ȉ&quot;,
&quot;name&quot;: &quot;ȉ&quot;
},
{
&quot;key&quot;: &quot;ëç&quot;,
&quot;name&quot;: &quot;ëç&quot;
},
{
&quot;key&quot;: &quot;¼å&quot;,
&quot;name&quot;: &quot;¼å&quot;
},
{
&quot;key&quot;: &quot;Öó&quot;,
&quot;name&quot;: &quot;Öó&quot;
},
{
&quot;key&quot;: &quot;Ѭ&quot;,
&quot;name&quot;: &quot;Ѭ&quot;
},
{
&quot;key&quot;: &quot;³´&quot;,
&quot;name&quot;: &quot;³´&quot;
},
{
&quot;key&quot;: &quot;ìÀ&quot;,
&quot;name&quot;: &quot;ìÀ&quot;
},
{
&quot;key&quot;: &quot;ìË&quot;,
&quot;name&quot;: &quot;ìË&quot;
},
{
&quot;key&quot;: &quot;Õô&quot;,
&quot;name&quot;: &quot;Õô&quot;
},
{
&quot;key&quot;: &quot;Õ¨&quot;,
&quot;name&quot;: &quot;Õ¨&quot;
}
],
&quot;mealType&quot;: [ &quot;mealType&quot;: [
{ {
&quot;key&quot;: &quot;早餐&quot;, &quot;key&quot;: &quot;早餐&quot;,
@ -191,6 +239,16 @@ password=BE56E057F20F883E //
&quot;value&quot;: &quot;晚餐&quot; &quot;value&quot;: &quot;晚餐&quot;
} }
], ],
&quot;measurementType&quot;: [
{
&quot;key&quot;: &quot;weight&quot;,
&quot;value&quot;: &quot;¿Ë&quot;
},
{
&quot;key&quot;: &quot;quantity&quot;,
&quot;value&quot;: &quot;ÖÖ&quot;
}
],
&quot;category&quot;: [ &quot;category&quot;: [
{ {
&quot;key&quot;: &quot;蛋类&quot;, &quot;key&quot;: &quot;蛋类&quot;,
@ -200,6 +258,10 @@ password=BE56E057F20F883E //
&quot;key&quot;: &quot;大豆类及其制品&quot;, &quot;key&quot;: &quot;大豆类及其制品&quot;,
&quot;value&quot;: &quot;大豆类及其制品&quot; &quot;value&quot;: &quot;大豆类及其制品&quot;
}, },
{
&quot;key&quot;: &quot;ÔÓ¶¹Àà&quot;,
&quot;value&quot;: &quot;ÔÓ¶¹Àà&quot;
},
{ {
&quot;key&quot;: &quot;婴幼儿食品&quot;, &quot;key&quot;: &quot;婴幼儿食品&quot;,
&quot;value&quot;: &quot;婴幼儿食品&quot; &quot;value&quot;: &quot;婴幼儿食品&quot;
@ -344,12 +406,6 @@ password=BE56E057F20F883E //
&quot;key&quot;: &quot;其他&quot;, &quot;key&quot;: &quot;其他&quot;,
&quot;value&quot;: &quot;其他&quot; &quot;value&quot;: &quot;其他&quot;
} }
],
&quot;poly&quot;:[
{
&quot;key&quot;: &quot;&quot;,
&quot;value&quot;: &quot;&quot;
}
] ]
}, },
&quot;code&quot;: 200, &quot;code&quot;: 200,

330
diet-web/src/main/resources/static/menu/report.html

@ -10,96 +10,128 @@ crow=xxx //
<h3>输出:</h3> <h3>输出:</h3>
<pre><code class="json">{ <pre><code class="json">{
&quot;body&quot;: { &quot;body&quot;: {
&quot;day&quot;: 5, &quot;day&quot;: 1,
&quot;crow&quot;: &quot;10&quot;, &quot;crow&quot;: &quot;6岁~8岁 女&quot;,
&quot;meals&quot;: [ &quot;meals&quot;: [
&quot;午餐&quot;,
&quot;晚餐&quot;,
&quot;早餐&quot; &quot;早餐&quot;
], ],
&quot;types&quot;: { &quot;types&quot;: {
&quot;蛋类&quot;: 5, &quot;蛋类&quot;: 1,
&quot;鱼虾类&quot;: 2, &quot;大豆类及其制品&quot;: 1,
&quot;调味品&quot;: 1 &quot;鱼虾类&quot;: 1,
&quot;谷类&quot;: 5,
&quot;畜肉类&quot;: 1,
&quot;烹调油&quot;: 3,
&quot;奶及奶制品&quot;: 1,
&quot;调味品&quot;: 1,
&quot;蔬菜类&quot;: 6
}, },
&quot;ingredient&quot;: [ &quot;ingredient&quot;: [
{ {
&quot;nutrition&quot;: &quot;膳食纤维/g&quot;, &quot;nutrition&quot;: &quot;膳食纤维/g&quot;,
&quot;virtual&quot;: 0, &quot;virtual&quot;: 4.8,
&quot;standard&quot;: &quot;1~2&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: -1, &quot;standard&quot;: &quot;20~20&quot;,
&quot;overload&quot;: &quot;-76.00%&quot;,
&quot;conclusion&quot;: &quot;不足&quot; &quot;conclusion&quot;: &quot;不足&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;钙/mg&quot;, &quot;nutrition&quot;: &quot;钙/mg&quot;,
&quot;virtual&quot;: 2, &quot;virtual&quot;: 490,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;750~750&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;-34.67%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;维生素B1/mg&quot;, &quot;nutrition&quot;: &quot;维生素B1/mg&quot;,
&quot;virtual&quot;: 1, &quot;virtual&quot;: 1.05,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;0.9~0.9&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;16.67%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;碳水化合物/g&quot;, &quot;nutrition&quot;: &quot;碳水化合物/g&quot;,
&quot;virtual&quot;: 0.1, &quot;virtual&quot;: 267.4,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;193.75~251.88&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;6.16%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;蛋白质/g&quot;, &quot;nutrition&quot;: &quot;维生素B2/mg&quot;,
&quot;virtual&quot;: 0.1, &quot;virtual&quot;: 0.62,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;0.9~0.9&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;-31.11%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;维生素B2/mg&quot;, &quot;nutrition&quot;: &quot;维生素A/μgRAE&quot;,
&quot;virtual&quot;: 2, &quot;virtual&quot;: 516,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;standard&quot;: &quot;450~450&quot;,
&quot;overload&quot;: &quot;14.67%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
},
{
&quot;nutrition&quot;: &quot;维生素C/mg&quot;,
&quot;virtual&quot;: 117.5,
&quot;ul&quot;: &quot;-&quot;,
&quot;standard&quot;: &quot;60~60&quot;,
&quot;overload&quot;: &quot;95.83%&quot;,
&quot;conclusion&quot;: &quot;过量&quot;
},
{
&quot;nutrition&quot;: &quot;钠/mg&quot;,
&quot;virtual&quot;: 953.9,
&quot;ul&quot;: &quot;-&quot;,
&quot;standard&quot;: &quot;≤5000&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;overload&quot;: &quot;-&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;conclusion&quot;: &quot;适量&quot;
},
{
&quot;nutrition&quot;: &quot;蛋白质/g&quot;,
&quot;virtual&quot;: 70.2,
&quot;ul&quot;: &quot;-&quot;,
&quot;standard&quot;: &quot;32~48&quot;,
&quot;overload&quot;: &quot;46.25%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;脂肪/g&quot;, &quot;nutrition&quot;: &quot;脂肪/g&quot;,
&quot;virtual&quot;: 0.0, &quot;virtual&quot;: 47.4,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;34.44~51.67&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;37.63%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;铁/mg&quot;, &quot;nutrition&quot;: &quot;铁/mg&quot;,
&quot;virtual&quot;: 0.1, &quot;virtual&quot;: 10.8,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;12~12&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;-10.00%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;维生素A/μgRAE&quot;, &quot;nutrition&quot;: &quot;锌/mg&quot;,
&quot;virtual&quot;: 4, &quot;virtual&quot;: 7.15,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;6.5~6.5&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;10.00%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
}, },
{ {
&quot;nutrition&quot;: &quot;能量kcal/kcal&quot;, &quot;nutrition&quot;: &quot;能量/kcal&quot;,
&quot;virtual&quot;: 0.79, &quot;virtual&quot;: 1755,
&quot;standard&quot;: &quot;-&quot;,
&quot;ul&quot;: &quot;-&quot;, &quot;ul&quot;: &quot;-&quot;,
&quot;overload&quot;: &quot;-&quot;, &quot;standard&quot;: &quot;1395~1705&quot;,
&quot;conclusion&quot;: &quot;-&quot; &quot;overload&quot;: &quot;2.93%&quot;,
&quot;conclusion&quot;: &quot;适量&quot;
} }
] ]
}, },
@ -120,29 +152,31 @@ crow=xxx //
<h3>输出:</h3> <h3>输出:</h3>
<pre><code class="json">{ <pre><code class="json">{
&quot;body&quot;: { &quot;body&quot;: {
&quot;day&quot;: 5, &quot;day&quot;: 1,
&quot;crow&quot;: &quot;10&quot;, &quot;crow&quot;: &quot;6岁~8岁 女&quot;,
&quot;meals&quot;: [ &quot;meals&quot;: [
&quot;午餐&quot;,
&quot;晚餐&quot;,
&quot;早餐&quot; &quot;早餐&quot;
], ],
&quot;energy&quot;: [ &quot;energy&quot;: [
{ {
&quot;name&quot;: &quot;蛋白质/总能量&quot;, &quot;name&quot;: &quot;蛋白质/总能量&quot;,
&quot;standard&quot;: &quot;10~20&quot;, &quot;standard&quot;: &quot;10~20&quot;,
&quot;value&quot;: 10.0, &quot;value&quot;: 15.80,
&quot;conclusion&quot;: &quot;合适&quot; &quot;conclusion&quot;: &quot;合适&quot;
}, },
{ {
&quot;name&quot;: &quot;脂肪/总能量&quot;, &quot;name&quot;: &quot;脂肪/总能量&quot;,
&quot;standard&quot;: &quot;20~30&quot;, &quot;standard&quot;: &quot;20~30&quot;,
&quot;value&quot;: 0.0, &quot;value&quot;: 24.01,
&quot;conclusion&quot;: &quot;略低&quot; &quot;conclusion&quot;: &quot;合适&quot;
}, },
{ {
&quot;name&quot;: &quot;碳水化合物/总能量&quot;, &quot;name&quot;: &quot;碳水化合物/总能量&quot;,
&quot;standard&quot;: &quot;50~60&quot;, &quot;standard&quot;: &quot;50~60&quot;,
&quot;value&quot;: 10.0, &quot;value&quot;: 60.19,
&quot;conclusion&quot;: &quot;略低&quot; &quot;conclusion&quot;: &quot;合适&quot;
} }
] ]
}, },
@ -163,187 +197,25 @@ crow=xxx //
<pre><code class="json">{ <pre><code class="json">{
&quot;body&quot;: { &quot;body&quot;: {
&quot;crow&quot;: &quot;6岁~8岁 女&quot;, &quot;crow&quot;: &quot;6岁~8岁 女&quot;,
&quot;dayRule&quot;: [ &quot;dayRule&quot;: {
[ &quot;1&quot;: [
{
&quot;day&quot;: 1,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{ {
&quot;day&quot;: 1, &quot;day&quot;: 1,
&quot;name&quot;: &quot;鱼虾类&quot;, &quot;name&quot;: &quot;规则名称&quot;,
&quot;standard&quot;: 0, &quot;standard&quot;: &quot;10~100&quot;,
&quot;supplied&quot;: 2, &quot;measurement&quot;: &quot;weight&quot;,
&quot;lack&quot;: 0 &quot;supplied&quot;: 320,
}, &quot;lack&quot;: -220
{
&quot;day&quot;: 1,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 2,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 2,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 2,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 3,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 3,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 3,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 4,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 4,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 4,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 5,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 5,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 5,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 6,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 6,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 6,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
}
],
[
{
&quot;day&quot;: 7,
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 2,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 7,
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 5,
&quot;lack&quot;: 0
},
{
&quot;day&quot;: 7,
&quot;name&quot;: &quot;调味品&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 1,
&quot;lack&quot;: 0
} }
] ]
],
&quot;weekRule&quot;: [
{
&quot;name&quot;: &quot;蛋类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 35,
&quot;lack&quot;: 0
},
{
&quot;name&quot;: &quot;鱼虾类&quot;,
&quot;standard&quot;: 0,
&quot;supplied&quot;: 14,
&quot;lack&quot;: 0
}, },
&quot;weekRule&quot;: [
{ {
&quot;name&quot;: &quot;调味品&quot;, &quot;name&quot;: &quot;规则名称&quot;,
&quot;standard&quot;: 0, &quot;standard&quot;: &quot;10~100&quot;,
&quot;supplied&quot;: 7, &quot;measurement&quot;: &quot;weight&quot;,
&quot;lack&quot;: 0 &quot;supplied&quot;: 320,
&quot;lack&quot;: -220
} }
] ]
}, },

95
diet-web/src/main/resources/static/nutrition.html

@ -13,18 +13,8 @@ keyword=
&quot;body&quot;: { &quot;body&quot;: {
&quot;content&quot;: [ &quot;content&quot;: [
{ {
&quot;foodCategoryDay&quot;: { &quot;foodCategoryDay&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;quantity&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;水果类&quot;: 20, &quot;foodCategoryWeek&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;quantity&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;蔬菜类&quot;: 50,
&quot;谷薯类&quot;: 10,
&quot;畜肉禽类&quot;: 30
},
&quot;foodCategoryWeek&quot;: {
&quot;水果类&quot;: 100,
&quot;蔬菜类&quot;: 200,
&quot;谷薯类&quot;: 500,
&quot;畜肉禽类&quot;: 300
},
&quot;id&quot;: 1, &quot;id&quot;: 1,
&quot;ingredient&quot;: { &quot;ingredient&quot;: {
&quot;轻体力&quot;: { &quot;轻体力&quot;: {
@ -69,18 +59,8 @@ keyword=
<h3>输出:</h3> <h3>输出:</h3>
<pre><code>{ <pre><code>{
&quot;body&quot;: { &quot;body&quot;: {
&quot;foodCategoryDay&quot;: { &quot;foodCategoryDay&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;weight&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;水果类&quot;: 20, &quot;foodCategoryWeek&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;weight&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;蔬菜类&quot;: 50,
&quot;谷薯类&quot;: 10,
&quot;畜肉禽类&quot;: 30
},
&quot;foodCategoryWeek&quot;: {
&quot;水果类&quot;: 100,
&quot;蔬菜类&quot;: 200,
&quot;谷薯类&quot;: 500,
&quot;畜肉禽类&quot;: 300
},
&quot;id&quot;: 1, &quot;id&quot;: 1,
&quot;ingredient&quot;: { &quot;ingredient&quot;: {
&quot;轻体力&quot;: { &quot;轻体力&quot;: {
@ -121,18 +101,8 @@ keyword=
<pre><code>{ <pre><code>{
&quot;body&quot;: [ &quot;body&quot;: [
{ {
&quot;foodCategoryDay&quot;: { &quot;foodCategoryDay&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;weight&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;水果类&quot;: 20, &quot;foodCategoryWeek&quot;: [{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;weight&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}],
&quot;蔬菜类&quot;: 50,
&quot;谷薯类&quot;: 10,
&quot;畜肉禽类&quot;: 30
},
&quot;foodCategoryWeek&quot;: {
&quot;水果类&quot;: 100,
&quot;蔬菜类&quot;: 200,
&quot;谷薯类&quot;: 500,
&quot;畜肉禽类&quot;: 300
},
&quot;id&quot;: 1, &quot;id&quot;: 1,
&quot;ingredient&quot;: { &quot;ingredient&quot;: {
&quot;轻体力&quot;: { &quot;轻体力&quot;: {
@ -189,8 +159,8 @@ id=1 //
name=青少年就餐指导 // 名称 name=青少年就餐指导 // 名称
vendors=1,2,3 // 单位列表 vendors=1,2,3 // 单位列表
overflow=0.5 // 溢出 overflow=0.5 // 溢出
foodCategoryDay={&quot;水果类&quot;: 20, &quot;蔬菜类&quot;: 50, &quot;谷薯类&quot;: 10, &quot;畜肉禽类&quot;: 30} foodCategoryDay=[{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;weight&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}]
foodCategoryWeek={&quot;水果类&quot;: 200, &quot;蔬菜类&quot;: 500, &quot;谷薯类&quot;: 100, &quot;畜肉禽类&quot;: 300} foodCategoryWeek=[{&quot;max&quot;:100,&quot;min&quot;:10,&quot;name&quot;:&quot;¹æÔòÃû³Æ&quot;,&quot;type&quot;:&quot;quantity&quot;,&quot;category&quot;:[&quot;¹ÈÀà&quot;,&quot;ÊíÀà&quot;]}]
ingredient={&quot;中体力&quot;: {&quot;vitamin-a&quot;: {&quot;ul&quot;: 5, &quot;max&quot;: 10, &quot;min&quot;: 2}}, &quot;轻体力&quot;: {&quot;vitamin-a&quot;: {&quot;ul&quot;: 5, &quot;max&quot;: 10, &quot;min&quot;: 2}}} ingredient={&quot;中体力&quot;: {&quot;vitamin-a&quot;: {&quot;ul&quot;: 5, &quot;max&quot;: 10, &quot;min&quot;: 2}}, &quot;轻体力&quot;: {&quot;vitamin-a&quot;: {&quot;ul&quot;: 5, &quot;max&quot;: 10, &quot;min&quot;: 2}}}
</code></pre> </code></pre>
<h3>输出:</h3> <h3>输出:</h3>
@ -216,53 +186,4 @@ id=1 //
&quot;success&quot;: true &quot;success&quot;: true
} }
</code></pre> </code></pre>
<h1>5. 食材打标(业务端接口)</h1>
<blockquote>
<p>PUT /api/ingredient/mark</p>
</blockquote>
<h3>输入:</h3>
<pre><code>Content-Type:application/x-www-form-urlencoded
nutrient=010101
mark=常用 // 必填, 取值: 常用/忌用
</code></pre>
<h3>输出:</h3>
<pre><code>{
&quot;code&quot;: 200,
&quot;desc&quot;: &quot;成功&quot;,
&quot;success&quot;: true
}
</code></pre>
<h1>6. 取消打标(业务端接口)</h1>
<blockquote>
<p>DELETE /api/ingredient/mark</p>
</blockquote>
<h3>输入:</h3>
<pre><code>Content-Type:application/x-www-form-urlencoded
nutrient=010101
</code></pre>
<h3>输出:</h3>
<pre><code>{
&quot;code&quot;: 200,
&quot;desc&quot;: &quot;成功&quot;,
&quot;success&quot;: true
}
</code></pre>
<h1>7. 批量导入(管理端接口)</h1>
<blockquote>
<p>PUT /api/ingredient/mark</p>
</blockquote>
<h3>输入:</h3>
<pre><code>Content-Type: multipart/form-data
files // 必传
</code></pre>
<h3>输出:</h3>
<pre><code>{
&quot;code&quot;: 200,
&quot;desc&quot;: &quot;成功&quot;,
&quot;success&quot;: true
}
</code></pre>

102
doc/basic.md

@ -128,6 +128,12 @@ password=BE56E057F20F883E // 新密码
"nrv": 100.00, "nrv": 100.00,
"value": "维生素C" "value": "维生素C"
}, },
{
"key": "sodium",
"measurement": "mg",
"nrv": 2000.00,
"value": "钠"
},
{ {
"key": "protein", "key": "protein",
"measurement": "g", "measurement": "g",
@ -156,7 +162,7 @@ password=BE56E057F20F883E // 新密码
"key": "energy", "key": "energy",
"measurement": "kcal", "measurement": "kcal",
"nrv": 2000.00, "nrv": 2000.00,
"value": "能量kcal" "value": "能量"
} }
], ],
"menuStatus": [ "menuStatus": [
@ -164,22 +170,6 @@ password=BE56E057F20F883E // 新密码
"key": 0, "key": 0,
"value": "草稿" "value": "草稿"
}, },
{
"key": 1,
"value": "提交审核"
},
{
"key": 2,
"value": "审核通过"
},
{
"key": 3,
"value": "审核失败"
},
{
"key": 4,
"value": "禁用"
},
{ {
"key": 5, "key": 5,
"value": "发布" "value": "发布"
@ -195,6 +185,64 @@ password=BE56E057F20F883E // 新密码
"value": "忌用" "value": "忌用"
} }
], ],
"poly": [
{
"key": "烤",
"name": "烤"
},
{
"key": "卤",
"name": "卤"
},
{
"key": "无需烹饪",
"name": "无需烹饪"
},
{
"key": "烧",
"name": "烧"
},
{
"key": "烩",
"name": "烩"
},
{
"key": "腌",
"name": "腌"
},
{
"key": "煎",
"name": "煎"
},
{
"key": "煮",
"name": "煮"
},
{
"key": "熏",
"name": "熏"
},
{
"key": "炒",
"name": "炒"
},
{
"key": "炖",
"name": "炖"
},
{
"key": "焖",
"name": "焖"
},
{
"key": "蒸",
"name": "蒸"
},
{
"key": "炸",
"name": "炸"
}
],
"mealType": [ "mealType": [
{ {
"key": "早餐", "key": "早餐",
@ -209,6 +257,16 @@ password=BE56E057F20F883E // 新密码
"value": "晚餐" "value": "晚餐"
} }
], ],
"measurementType": [
{
"key": "weight",
"value": "克"
},
{
"key": "quantity",
"value": "种"
}
],
"category": [ "category": [
{ {
"key": "蛋类", "key": "蛋类",
@ -218,6 +276,10 @@ password=BE56E057F20F883E // 新密码
"key": "大豆类及其制品", "key": "大豆类及其制品",
"value": "大豆类及其制品" "value": "大豆类及其制品"
}, },
{
"key": "杂豆类",
"value": "杂豆类"
},
{ {
"key": "婴幼儿食品", "key": "婴幼儿食品",
"value": "婴幼儿食品" "value": "婴幼儿食品"
@ -362,12 +424,6 @@ password=BE56E057F20F883E // 新密码
"key": "其他", "key": "其他",
"value": "其他" "value": "其他"
} }
],
"poly":[
{
"key": "蒸",
"value": "蒸"
}
] ]
}, },
"code": 200, "code": 200,

330
doc/menu/report.md

@ -14,96 +14,128 @@ crow=xxx //
~~~json ~~~json
{ {
"body": { "body": {
"day": 5, "day": 1,
"crow": "10", "crow": "6岁~8岁 女",
"meals": [ "meals": [
"午餐",
"晚餐",
"早餐" "早餐"
], ],
"types": { "types": {
"蛋类": 5, "蛋类": 1,
"鱼虾类": 2, "大豆类及其制品": 1,
"调味品": 1 "鱼虾类": 1,
"谷类": 5,
"畜肉类": 1,
"烹调油": 3,
"奶及奶制品": 1,
"调味品": 1,
"蔬菜类": 6
}, },
"ingredient": [ "ingredient": [
{ {
"nutrition": "膳食纤维/g", "nutrition": "膳食纤维/g",
"virtual": 0, "virtual": 4.8,
"standard": "1~2",
"ul": "-", "ul": "-",
"overload": -1, "standard": "20~20",
"overload": "-76.00%",
"conclusion": "不足" "conclusion": "不足"
}, },
{ {
"nutrition": "钙/mg", "nutrition": "钙/mg",
"virtual": 2, "virtual": 490,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "750~750",
"conclusion": "-" "overload": "-34.67%",
"conclusion": "适量"
}, },
{ {
"nutrition": "维生素B1/mg", "nutrition": "维生素B1/mg",
"virtual": 1, "virtual": 1.05,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "0.9~0.9",
"conclusion": "-" "overload": "16.67%",
"conclusion": "适量"
}, },
{ {
"nutrition": "碳水化合物/g", "nutrition": "碳水化合物/g",
"virtual": 0.1, "virtual": 267.4,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "193.75~251.88",
"conclusion": "-" "overload": "6.16%",
"conclusion": "适量"
}, },
{ {
"nutrition": "蛋白质/g", "nutrition": "维生素B2/mg",
"virtual": 0.1, "virtual": 0.62,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "0.9~0.9",
"conclusion": "-" "overload": "-31.11%",
"conclusion": "适量"
}, },
{ {
"nutrition": "维生素B2/mg", "nutrition": "维生素A/μgRAE",
"virtual": 2, "virtual": 516,
"standard": "-",
"ul": "-", "ul": "-",
"standard": "450~450",
"overload": "14.67%",
"conclusion": "适量"
},
{
"nutrition": "维生素C/mg",
"virtual": 117.5,
"ul": "-",
"standard": "60~60",
"overload": "95.83%",
"conclusion": "过量"
},
{
"nutrition": "钠/mg",
"virtual": 953.9,
"ul": "-",
"standard": "≤5000",
"overload": "-", "overload": "-",
"conclusion": "-" "conclusion": "适量"
},
{
"nutrition": "蛋白质/g",
"virtual": 70.2,
"ul": "-",
"standard": "32~48",
"overload": "46.25%",
"conclusion": "适量"
}, },
{ {
"nutrition": "脂肪/g", "nutrition": "脂肪/g",
"virtual": 0.0, "virtual": 47.4,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "34.44~51.67",
"conclusion": "-" "overload": "37.63%",
"conclusion": "适量"
}, },
{ {
"nutrition": "铁/mg", "nutrition": "铁/mg",
"virtual": 0.1, "virtual": 10.8,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "12~12",
"conclusion": "-" "overload": "-10.00%",
"conclusion": "适量"
}, },
{ {
"nutrition": "维生素A/μgRAE", "nutrition": "锌/mg",
"virtual": 4, "virtual": 7.15,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "6.5~6.5",
"conclusion": "-" "overload": "10.00%",
"conclusion": "适量"
}, },
{ {
"nutrition": "能量kcal/kcal", "nutrition": "能量/kcal",
"virtual": 0.79, "virtual": 1755,
"standard": "-",
"ul": "-", "ul": "-",
"overload": "-", "standard": "1395~1705",
"conclusion": "-" "overload": "2.93%",
"conclusion": "适量"
} }
] ]
}, },
@ -129,29 +161,31 @@ crow=xxx //
~~~json ~~~json
{ {
"body": { "body": {
"day": 5, "day": 1,
"crow": "10", "crow": "6岁~8岁 女",
"meals": [ "meals": [
"午餐",
"晚餐",
"早餐" "早餐"
], ],
"energy": [ "energy": [
{ {
"name": "蛋白质/总能量", "name": "蛋白质/总能量",
"standard": "10~20", "standard": "10~20",
"value": 10.0, "value": 15.80,
"conclusion": "合适" "conclusion": "合适"
}, },
{ {
"name": "脂肪/总能量", "name": "脂肪/总能量",
"standard": "20~30", "standard": "20~30",
"value": 0.0, "value": 24.01,
"conclusion": "略低" "conclusion": "合适"
}, },
{ {
"name": "碳水化合物/总能量", "name": "碳水化合物/总能量",
"standard": "50~60", "standard": "50~60",
"value": 10.0, "value": 60.19,
"conclusion": "略低" "conclusion": "合适"
} }
] ]
}, },
@ -176,187 +210,25 @@ crow=xxx //
{ {
"body": { "body": {
"crow": "6岁~8岁 女", "crow": "6岁~8岁 女",
"dayRule": [ "dayRule": {
[ "1": [
{
"day": 1,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{ {
"day": 1, "day": 1,
"name": "鱼虾类", "name": "规则名称",
"standard": 0, "standard": "10~100",
"supplied": 2, "measurement": "weight",
"lack": 0 "supplied": 320,
}, "lack": -220
{
"day": 1,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 2,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 2,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 2,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 3,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 3,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 3,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 4,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 4,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 4,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 5,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 5,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 5,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 6,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 6,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 6,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
}
],
[
{
"day": 7,
"name": "鱼虾类",
"standard": 0,
"supplied": 2,
"lack": 0
},
{
"day": 7,
"name": "蛋类",
"standard": 0,
"supplied": 5,
"lack": 0
},
{
"day": 7,
"name": "调味品",
"standard": 0,
"supplied": 1,
"lack": 0
} }
] ]
],
"weekRule": [
{
"name": "蛋类",
"standard": 0,
"supplied": 35,
"lack": 0
},
{
"name": "鱼虾类",
"standard": 0,
"supplied": 14,
"lack": 0
}, },
"weekRule": [
{ {
"name": "调味品", "name": "规则名称",
"standard": 0, "standard": "10~100",
"supplied": 7, "measurement": "weight",
"lack": 0 "supplied": 320,
"lack": -220
} }
] ]
}, },

107
doc/nutrition.md

@ -18,18 +18,8 @@ keyword=青少年 // 查询关键字
"body": { "body": {
"content": [ "content": [
{ {
"foodCategoryDay": { "foodCategoryDay": [{"max":100,"min":10,"name":"规则名称","type":"quantity","category":["谷类","薯类"]}],
"水果类": 20, "foodCategoryWeek": [{"max":100,"min":10,"name":"规则名称","type":"quantity","category":["谷类","薯类"]}],
"蔬菜类": 50,
"谷薯类": 10,
"畜肉禽类": 30
},
"foodCategoryWeek": {
"水果类": 100,
"蔬菜类": 200,
"谷薯类": 500,
"畜肉禽类": 300
},
"id": 1, "id": 1,
"ingredient": { "ingredient": {
"轻体力": { "轻体力": {
@ -77,18 +67,8 @@ id=1
``` ```
{ {
"body": { "body": {
"foodCategoryDay": { "foodCategoryDay": [{"max":100,"min":10,"name":"规则名称","type":"weight","category":["谷类","薯类"]}],
"水果类": 20, "foodCategoryWeek": [{"max":100,"min":10,"name":"规则名称","type":"weight","category":["谷类","薯类"]}],
"蔬菜类": 50,
"谷薯类": 10,
"畜肉禽类": 30
},
"foodCategoryWeek": {
"水果类": 100,
"蔬菜类": 200,
"谷薯类": 500,
"畜肉禽类": 300
},
"id": 1, "id": 1,
"ingredient": { "ingredient": {
"轻体力": { "轻体力": {
@ -132,18 +112,8 @@ keyword=青
{ {
"body": [ "body": [
{ {
"foodCategoryDay": { "foodCategoryDay": [{"max":100,"min":10,"name":"规则名称","type":"weight","category":["谷类","薯类"]}],
"水果类": 20, "foodCategoryWeek": [{"max":100,"min":10,"name":"规则名称","type":"weight","category":["谷类","薯类"]}],
"蔬菜类": 50,
"谷薯类": 10,
"畜肉禽类": 30
},
"foodCategoryWeek": {
"水果类": 100,
"蔬菜类": 200,
"谷薯类": 500,
"畜肉禽类": 300
},
"id": 1, "id": 1,
"ingredient": { "ingredient": {
"轻体力": { "轻体力": {
@ -206,8 +176,8 @@ id=1 // 必填
name=青少年就餐指导 // 名称 name=青少年就餐指导 // 名称
vendors=1,2,3 // 单位列表 vendors=1,2,3 // 单位列表
overflow=0.5 // 溢出 overflow=0.5 // 溢出
foodCategoryDay={"水果类": 20, "蔬菜类": 50, "谷薯类": 10, "畜肉禽类": 30} foodCategoryDay=[{"max":100,"min":10,"name":"规则名称","type":"weight","category":["谷类","薯类"]}]
foodCategoryWeek={"水果类": 200, "蔬菜类": 500, "谷薯类": 100, "畜肉禽类": 300} foodCategoryWeek=[{"max":100,"min":10,"name":"规则名称","type":"quantity","category":["谷类","薯类"]}]
ingredient={"中体力": {"vitamin-a": {"ul": 5, "max": 10, "min": 2}}, "轻体力": {"vitamin-a": {"ul": 5, "max": 10, "min": 2}}} ingredient={"中体力": {"vitamin-a": {"ul": 5, "max": 10, "min": 2}}, "轻体力": {"vitamin-a": {"ul": 5, "max": 10, "min": 2}}}
``` ```
@ -238,64 +208,3 @@ id=1 // 必填
"success": true "success": true
} }
``` ```
# 5. 食材打标(业务端接口)
> PUT /api/ingredient/mark
### 输入:
```
Content-Type:application/x-www-form-urlencoded
nutrient=010101
mark=常用 // 必填, 取值: 常用/忌用
```
### 输出:
```
{
"code": 200,
"desc": "成功",
"success": true
}
```
# 6. 取消打标(业务端接口)
> DELETE /api/ingredient/mark
### 输入:
```
Content-Type:application/x-www-form-urlencoded
nutrient=010101
```
### 输出:
```
{
"code": 200,
"desc": "成功",
"success": true
}
```
# 7. 批量导入(管理端接口)
> PUT /api/ingredient/mark
### 输入:
```
Content-Type: multipart/form-data
files // 必传
```
### 输出:
```
{
"code": 200,
"desc": "成功",
"success": true
}
```
Loading…
Cancel
Save