|
@@ -1,5 +1,15 @@
|
|
|
package org.dromara.system.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.util.ObjUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.json.JSON;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import org.dromara.common.core.constant.BizConst;
|
|
|
+import org.dromara.common.core.constant.SystemConstants;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
@@ -9,16 +19,43 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.system.domain.SysDiseaseLabel;
|
|
|
+import org.dromara.system.domain.SysFoodCategory;
|
|
|
+import org.dromara.system.domain.SysFoodIngredient;
|
|
|
+import org.dromara.system.domain.SysRecipeCategory;
|
|
|
+import org.dromara.system.domain.SysRecipeFoodIngredient;
|
|
|
+import org.dromara.system.domain.SysRole;
|
|
|
+import org.dromara.system.domain.bo.SysRecipeFoodIngredientBo;
|
|
|
+import org.dromara.system.domain.vo.SysDictDataVo;
|
|
|
+import org.dromara.system.domain.vo.SysDiseaseLabelVo;
|
|
|
+import org.dromara.system.domain.vo.SysFoodCategoryVo;
|
|
|
+import org.dromara.system.domain.vo.SysFoodIngredientVo;
|
|
|
+import org.dromara.system.domain.vo.SysRecipeFoodIngredientVo;
|
|
|
+import org.dromara.system.mapper.SysDiseaseLabelMapper;
|
|
|
+import org.dromara.system.mapper.SysFoodCategoryMapper;
|
|
|
+import org.dromara.system.mapper.SysFoodIngredientMapper;
|
|
|
+import org.dromara.system.mapper.SysRecipeCategoryMapper;
|
|
|
+import org.dromara.system.mapper.SysRecipeFoodIngredientMapper;
|
|
|
+import org.dromara.system.service.ISysDictDataService;
|
|
|
+import org.dromara.system.service.ISysDiseaseLabelService;
|
|
|
+import org.dromara.system.service.ISysRecipeCategoryService;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.dromara.system.domain.bo.SysRecipeBo;
|
|
|
import org.dromara.system.domain.vo.SysRecipeVo;
|
|
|
import org.dromara.system.domain.SysRecipe;
|
|
|
import org.dromara.system.mapper.SysRecipeMapper;
|
|
|
import org.dromara.system.service.ISysRecipeService;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
+import java.io.ObjectInput;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 食谱管理Service业务层处理
|
|
@@ -32,6 +69,85 @@ import java.util.Collection;
|
|
|
public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
|
|
|
private final SysRecipeMapper baseMapper;
|
|
|
+ private final ISysDictDataService dictDataService;
|
|
|
+ private final SysRecipeCategoryMapper recipeCategoryMapper;
|
|
|
+ private final SysRecipeFoodIngredientMapper sysRecipeFoodIngredientMapper;
|
|
|
+ private final SysDiseaseLabelMapper diseaseLabelMapper;
|
|
|
+ private final SysFoodCategoryMapper foodCategoryMapper;
|
|
|
+ private final SysFoodIngredientMapper foodIngredientMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int updateRecipeStatus(List<Long> recipeIds, String status) {
|
|
|
+ return baseMapper.update(null,
|
|
|
+ new LambdaUpdateWrapper<SysRecipe>()
|
|
|
+ .set(SysRecipe::getSmartRecommend, status)
|
|
|
+ .in(SysRecipe::getRecipeId, recipeIds));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<com.alibaba.fastjson.JSONObject> nutrientAnalysis(Long recipeId) {
|
|
|
+ List<SysRecipeFoodIngredient> recipeFoodIngredientList =
|
|
|
+ sysRecipeFoodIngredientMapper.selectList(Wrappers.lambdaQuery(SysRecipeFoodIngredient.class)
|
|
|
+ .eq(SysRecipeFoodIngredient::getRecipeId, recipeId));
|
|
|
+ if (CollUtil.isEmpty(recipeFoodIngredientList)) {
|
|
|
+ return R.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<SysFoodIngredient> foodIngredientList = foodIngredientMapper.selectList(Wrappers.lambdaQuery(SysFoodIngredient.class)
|
|
|
+ .in(SysFoodIngredient::getFoodIngredientId, recipeFoodIngredientList.stream().map(v -> v.getFoodIngredientId()).collect(Collectors.toList())));
|
|
|
+
|
|
|
+ List<JSONObject> leftList = CollUtil.newArrayList();
|
|
|
+ List<JSONObject> rightList = CollUtil.newArrayList();
|
|
|
+ List<JSONObject> pieList = CollUtil.newArrayList();
|
|
|
+ List<JSONObject> pieLegendList = CollUtil.newArrayList();
|
|
|
+
|
|
|
+ JSONObject protein = new JSONObject();
|
|
|
+ JSONObject fat = new JSONObject();
|
|
|
+ JSONObject carbohydrate = new JSONObject();
|
|
|
+ BigDecimal treeNutrient = BigDecimal.ZERO;
|
|
|
+ for (SysFoodIngredient v : foodIngredientList) {
|
|
|
+ protein.put("val", protein.getBigDecimal("val", BigDecimal.ZERO).add(v.getProtein()).setScale(4, BigDecimal.ROUND_HALF_UP));
|
|
|
+ treeNutrient = treeNutrient.add(protein.getBigDecimal("val"));
|
|
|
+
|
|
|
+ fat.put("val", fat.getBigDecimal("val", BigDecimal.ZERO).add(v.getFat()).setScale(4, BigDecimal.ROUND_HALF_UP));
|
|
|
+ treeNutrient = treeNutrient.add(fat.getBigDecimal("val"));
|
|
|
+
|
|
|
+ carbohydrate.put("val", carbohydrate.getBigDecimal("val", BigDecimal.ZERO).add(v.getCarbohydrate()).setScale(4, BigDecimal.ROUND_HALF_UP));
|
|
|
+ treeNutrient = treeNutrient.add(carbohydrate.getBigDecimal("val"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (treeNutrient.equals(BigDecimal.ZERO)) {
|
|
|
+ protein.put("ratio", BigDecimal.ZERO);
|
|
|
+ fat.put("ratio", BigDecimal.ZERO);
|
|
|
+ carbohydrate.put("ratio", BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ protein.put("ratio", protein.getBigDecimal("val", BigDecimal.ZERO).divide(treeNutrient).setScale(2, BigDecimal.ROUND_HALF_UP));
|
|
|
+ fat.put("ratio", protein.getBigDecimal("val", BigDecimal.ZERO).divide(treeNutrient).setScale(2, BigDecimal.ROUND_HALF_UP));
|
|
|
+ carbohydrate.put("ratio", protein.getBigDecimal("val", BigDecimal.ZERO).divide(treeNutrient).setScale(2, BigDecimal.ROUND_HALF_UP));
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, SysDictDataVo> dictDataVoMap = dictDataService.selectMapByType(BizConst.NUTRIENT_REFERENCE).getData();
|
|
|
+ SysDictDataVo nutrientProtein = dictDataVoMap.get(BizConst.NUTRIENT_PROTEIN);
|
|
|
+ SysDictDataVo nutrientFat = dictDataVoMap.get(BizConst.NUTRIENT_FAT);
|
|
|
+ SysDictDataVo nutrientCarbohydrate = dictDataVoMap.get(BizConst.NUTRIENT_CARBOHYDRATE);
|
|
|
+
|
|
|
+ protein.put("name", nutrientProtein.getRemark());
|
|
|
+ fat.put("name", nutrientFat.getRemark());
|
|
|
+ carbohydrate.put("name", nutrientCarbohydrate.getRemark());
|
|
|
+
|
|
|
+ protein.put("referenceValue", nutrientProtein.getDictValue());
|
|
|
+ fat.put("referenceValue", nutrientFat.getDictValue());
|
|
|
+ carbohydrate.put("referenceValue", nutrientCarbohydrate.getDictValue());
|
|
|
+
|
|
|
+ leftList.add(protein);
|
|
|
+ leftList.add(fat);
|
|
|
+ leftList.add(carbohydrate);
|
|
|
+
|
|
|
+ com.alibaba.fastjson.JSONObject result = new com.alibaba.fastjson.JSONObject();
|
|
|
+ result.put("left", leftList);
|
|
|
+
|
|
|
+ return R.ok(result);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 查询食谱管理
|
|
@@ -40,8 +156,83 @@ public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
* @return 食谱管理
|
|
|
*/
|
|
|
@Override
|
|
|
- public SysRecipeVo queryById(Long recipeId){
|
|
|
- return baseMapper.selectVoById(recipeId);
|
|
|
+ public SysRecipeVo queryById(Long recipeId) {
|
|
|
+ SysRecipeVo vo = baseMapper.selectVoById(recipeId);
|
|
|
+ Set<String> diseaseLabelIdList = CollUtil.newHashSet();
|
|
|
+ Map<String, List<SysDictDataVo>> dictDataMap = dictDataService.selectGroupByType(List.of(BizConst.DIETARY_TYPES, BizConst.FOOD_UNIT)).getData();
|
|
|
+ Map<String, SysDictDataVo> foodUnitMap = dictDataMap.get(BizConst.FOOD_UNIT).stream().collect(Collectors.toMap(v -> v.getDictValue(), v -> v, (k, v) -> k));
|
|
|
+ Map<String, SysDictDataVo> dietaryTypesMap = dictDataMap.get(BizConst.DIETARY_TYPES).stream().collect(Collectors.toMap(v -> v.getDictValue(), v -> v, (k, v) -> k));
|
|
|
+
|
|
|
+ if (StrUtil.isNotBlank(vo.getAvoidDisease())) {
|
|
|
+ diseaseLabelIdList.addAll(Arrays.stream(vo.getAvoidDisease().split(",")).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(vo.getSuitableDisease())) {
|
|
|
+ diseaseLabelIdList.addAll(Arrays.stream(vo.getSuitableDisease().split(",")).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ if (CollUtil.isNotEmpty(diseaseLabelIdList)) {
|
|
|
+ List<SysDiseaseLabel> diseaseLabelList = diseaseLabelMapper.selectList(Wrappers.lambdaQuery(SysDiseaseLabel.class)
|
|
|
+ .select(SysDiseaseLabel::getLabelId, SysDiseaseLabel::getLabelName, SysDiseaseLabel::getLabelCode, SysDiseaseLabel::getCategory)
|
|
|
+ .in(SysDiseaseLabel::getLabelId, diseaseLabelIdList));
|
|
|
+
|
|
|
+ Map<String, SysDiseaseLabelVo> diseaseLabelMap = diseaseLabelList
|
|
|
+ .stream().map(v -> MapstructUtils.convert(v, SysDiseaseLabelVo.class))
|
|
|
+ .collect(Collectors.toMap(k -> String.valueOf(k.getLabelId()), v -> v, (k, v) -> k));
|
|
|
+
|
|
|
+ vo.setAvoidDiseaseList(Arrays.stream(vo.getAvoidDisease().split(",")).map(v -> {
|
|
|
+ SysDiseaseLabelVo labelVo = diseaseLabelMap.get(v);
|
|
|
+ if (ObjUtil.isNotNull(labelVo)) {
|
|
|
+ SysDictDataVo dataVo = dietaryTypesMap.get(labelVo.getCategory());
|
|
|
+ if (ObjUtil.isNotNull(dataVo)) {
|
|
|
+ labelVo.setCategoryName(dataVo.getDictLabel());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return labelVo;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+
|
|
|
+ vo.setSuitableDiseaseList(Arrays.stream(vo.getSuitableDisease().split(",")).map(v -> {
|
|
|
+ SysDiseaseLabelVo labelVo = diseaseLabelMap.get(v);
|
|
|
+ if (ObjUtil.isNotNull(labelVo)) {
|
|
|
+ SysDictDataVo dataVo = dietaryTypesMap.get(labelVo.getCategory());
|
|
|
+ if (ObjUtil.isNotNull(dataVo)) {
|
|
|
+ labelVo.setCategoryName(dataVo.getDictLabel());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return labelVo;
|
|
|
+ }).collect(Collectors.toList()));
|
|
|
+
|
|
|
+ List<SysFoodIngredient> foodIngredientList = sysRecipeFoodIngredientMapper.selectRecipeFood(recipeId);
|
|
|
+ if (CollUtil.isNotEmpty(foodIngredientList)) {
|
|
|
+ Set<String> categoryIdList = CollUtil.newHashSet();
|
|
|
+ foodIngredientList.forEach(foodIngredient -> {
|
|
|
+ if (StrUtil.isNotBlank(foodIngredient.getFoodCategoryId())) {
|
|
|
+ categoryIdList.addAll(Arrays.stream(foodIngredient.getFoodCategoryId().split(",")).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ Map<String, String> foodCategoryMap = foodCategoryMapper.selectList(Wrappers.lambdaQuery(SysFoodCategory.class)
|
|
|
+ .select(SysFoodCategory::getFoodCategoryId, SysFoodCategory::getName)
|
|
|
+ .in(SysFoodCategory::getFoodCategoryId, categoryIdList))
|
|
|
+ .stream().collect(Collectors.toMap(k -> String.valueOf(k.getFoodCategoryId()), v -> v.getName(), (k, v) -> k));
|
|
|
+
|
|
|
+ foodIngredientList.forEach(foodIngredient -> {
|
|
|
+ if (StrUtil.isNotBlank(foodIngredient.getFoodCategoryId())) {
|
|
|
+ Arrays.stream(foodIngredient.getFoodCategoryId().split(",")).forEach(v -> {
|
|
|
+ foodIngredient.setSubCategory(foodCategoryMap.get(v));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ SysDictDataVo dataVo = foodUnitMap.get(foodIngredient.getUnit());
|
|
|
+ if (ObjUtil.isNotNull(dataVo)) {
|
|
|
+ foodIngredient.setUnitName(dataVo.getDictLabel());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ vo.setFoodList(MapstructUtils.convert(foodIngredientList, SysFoodIngredientVo.class));
|
|
|
+ }
|
|
|
+
|
|
|
+// vo.setNutrientAnalysis(nutrientAnalysis(recipeId).getData());
|
|
|
+
|
|
|
+ return vo;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -55,6 +246,22 @@ public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
public TableDataInfo<SysRecipeVo> queryPageList(SysRecipeBo bo, PageQuery pageQuery) {
|
|
|
LambdaQueryWrapper<SysRecipe> lqw = buildQueryWrapper(bo);
|
|
|
Page<SysRecipeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
+
|
|
|
+ if (CollUtil.isNotEmpty(result.getRecords())) {
|
|
|
+ Map<String, SysDictDataVo> dietaryTypesMap = dictDataService.selectMapByType(BizConst.DIETARY_TYPES).getData();
|
|
|
+ Map<Long, String> recipeCategoryMap = recipeCategoryMapper.selectList(Wrappers.lambdaQuery(SysRecipeCategory.class)
|
|
|
+ .select(SysRecipeCategory::getRecipeCategoryId, SysRecipeCategory::getName)
|
|
|
+ .in(SysRecipeCategory::getRecipeCategoryId, result.getRecords().stream().map(SysRecipeVo::getCategoryId).collect(Collectors.toList())))
|
|
|
+ .stream().collect(Collectors.toMap(k1 -> k1.getRecipeCategoryId(), k2 -> k2.getName(), (k1, k2) -> k1));
|
|
|
+
|
|
|
+ result.getRecords().forEach(v -> {
|
|
|
+ SysDictDataVo dataVo = dietaryTypesMap.get(v.getBaseDiet());
|
|
|
+ if (ObjUtil.isNotNull(dataVo)) {
|
|
|
+ v.setBaseDietName(dataVo.getDictLabel());
|
|
|
+ }
|
|
|
+ v.setCategoryName(recipeCategoryMap.get(v.getCategoryId()));
|
|
|
+ });
|
|
|
+ }
|
|
|
return TableDataInfo.build(result);
|
|
|
}
|
|
|
|
|
@@ -95,11 +302,21 @@ public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
* @return 是否新增成功
|
|
|
*/
|
|
|
@Override
|
|
|
+ @Transactional
|
|
|
public Boolean insertByBo(SysRecipeBo bo) {
|
|
|
SysRecipe add = MapstructUtils.convert(bo, SysRecipe.class);
|
|
|
validEntityBeforeSave(add);
|
|
|
boolean flag = baseMapper.insert(add) > 0;
|
|
|
if (flag) {
|
|
|
+ List<SysRecipeFoodIngredient> fList = bo.getFoodList().stream().map(food -> {
|
|
|
+ SysRecipeFoodIngredient foodIngredient = MapstructUtils.convert(food, SysRecipeFoodIngredient.class);
|
|
|
+ if (ObjUtil.isNull(foodIngredient.getQuantity())) {
|
|
|
+ throw new ServiceException("食材用量不能为空");
|
|
|
+ }
|
|
|
+ foodIngredient.setRecipeId(add.getRecipeId());
|
|
|
+ return foodIngredient;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ sysRecipeFoodIngredientMapper.insertBatch(fList);
|
|
|
bo.setRecipeId(add.getRecipeId());
|
|
|
}
|
|
|
return flag;
|
|
@@ -112,16 +329,32 @@ public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
* @return 是否修改成功
|
|
|
*/
|
|
|
@Override
|
|
|
+ @Transactional
|
|
|
public Boolean updateByBo(SysRecipeBo bo) {
|
|
|
+ if (ObjUtil.isNull(bo.getRecipeId())) {
|
|
|
+ throw new ServiceException("膳食Id不能为空");
|
|
|
+ }
|
|
|
SysRecipe update = MapstructUtils.convert(bo, SysRecipe.class);
|
|
|
validEntityBeforeSave(update);
|
|
|
+ sysRecipeFoodIngredientMapper.delete(Wrappers.lambdaUpdate(SysRecipeFoodIngredient.class)
|
|
|
+ .eq(SysRecipeFoodIngredient::getRecipeId, bo.getRecipeId()));
|
|
|
+
|
|
|
+ List<SysRecipeFoodIngredient> fList = bo.getFoodList().stream().map(food -> {
|
|
|
+ SysRecipeFoodIngredient foodIngredient = MapstructUtils.convert(food, SysRecipeFoodIngredient.class);
|
|
|
+ if (ObjUtil.isNull(foodIngredient.getQuantity())) {
|
|
|
+ throw new ServiceException("食材用量不能为空");
|
|
|
+ }
|
|
|
+ foodIngredient.setRecipeId(bo.getRecipeId());
|
|
|
+ return foodIngredient;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ sysRecipeFoodIngredientMapper.insertBatch(fList);
|
|
|
return baseMapper.updateById(update) > 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 保存前的数据校验
|
|
|
*/
|
|
|
- private void validEntityBeforeSave(SysRecipe entity){
|
|
|
+ private void validEntityBeforeSave(SysRecipe entity) {
|
|
|
//TODO 做一些数据校验,如唯一约束
|
|
|
}
|
|
|
|
|
@@ -134,7 +367,7 @@ public class SysRecipeServiceImpl implements ISysRecipeService {
|
|
|
*/
|
|
|
@Override
|
|
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
- if(isValid){
|
|
|
+ if (isValid) {
|
|
|
//TODO 做一些业务上的校验,判断是否需要校验
|
|
|
}
|
|
|
return baseMapper.deleteByIds(ids) > 0;
|