菜谱管理
This commit is contained in:
parent
a23ba1664e
commit
45bdb1d8c4
|
|
@ -1,7 +1,9 @@
|
||||||
package com.bonus.canteen.core.cook.domain;
|
package com.bonus.canteen.core.cook.domain;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bonus.canteen.core.common.utils.FileUrlUtil;
|
import com.bonus.canteen.core.common.utils.FileUrlUtil;
|
||||||
import com.bonus.common.core.annotation.Excel;
|
import com.bonus.common.core.annotation.Excel;
|
||||||
|
|
@ -367,6 +369,8 @@ public class CookDishes extends BaseEntity {
|
||||||
@ApiModelProperty(value = "菜品类型id集合")
|
@ApiModelProperty(value = "菜品类型id集合")
|
||||||
private List<Long> typeIds;
|
private List<Long> typeIds;
|
||||||
|
|
||||||
|
private Set<String> dishesNames = new HashSet();
|
||||||
|
|
||||||
public String getImageUrl() {
|
public String getImageUrl() {
|
||||||
return FileUrlUtil.getFileUrl(this.imageUrl);
|
return FileUrlUtil.getFileUrl(this.imageUrl);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.bonus.canteen.core.cook.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
|
||||||
|
public class ImportRecipeDishesDTO {
|
||||||
|
private Integer index;
|
||||||
|
private String dishesName;
|
||||||
|
@ApiModelProperty("菜品单价")
|
||||||
|
private Integer price;
|
||||||
|
@ApiModelProperty("供应数量")
|
||||||
|
private Integer supplyNum;
|
||||||
|
@ApiModelProperty("销售数量")
|
||||||
|
private Integer saleNum;
|
||||||
|
@ApiModelProperty("剩余数量")
|
||||||
|
private Integer surplusNum;
|
||||||
|
@ApiModelProperty("个人限购数量")
|
||||||
|
private Integer restrictNum;
|
||||||
|
@ApiModelProperty("菜品价格(优惠价)")
|
||||||
|
private Integer salePrice;
|
||||||
|
|
||||||
|
public Integer getIndex() {
|
||||||
|
return this.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDishesName() {
|
||||||
|
return this.dishesName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPrice() {
|
||||||
|
return this.price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSupplyNum() {
|
||||||
|
return this.supplyNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSaleNum() {
|
||||||
|
return this.saleNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSurplusNum() {
|
||||||
|
return this.surplusNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRestrictNum() {
|
||||||
|
return this.restrictNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSalePrice() {
|
||||||
|
return this.salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setIndex(final Integer index) {
|
||||||
|
this.index = index;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setDishesName(final String dishesName) {
|
||||||
|
this.dishesName = dishesName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setPrice(final Integer price) {
|
||||||
|
this.price = price;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setSupplyNum(final Integer supplyNum) {
|
||||||
|
this.supplyNum = supplyNum;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setSaleNum(final Integer saleNum) {
|
||||||
|
this.saleNum = saleNum;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setSurplusNum(final Integer surplusNum) {
|
||||||
|
this.surplusNum = surplusNum;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setRestrictNum(final Integer restrictNum) {
|
||||||
|
this.restrictNum = restrictNum;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportRecipeDishesDTO setSalePrice(final Integer salePrice) {
|
||||||
|
this.salePrice = salePrice;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package com.bonus.canteen.core.cook.mapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bonus.canteen.core.cook.domain.CookRecipeDetail;
|
import com.bonus.canteen.core.cook.domain.CookRecipeDetail;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
|
@ -73,4 +75,6 @@ public interface CookRecipeDetailMapper {
|
||||||
|
|
||||||
List<CookRecipeDetail> getCookRecipeDetailLTemplate(@Param("recipeId") Long recipeId, @Param("detailType") String detailType);
|
List<CookRecipeDetail> getCookRecipeDetailLTemplate(@Param("recipeId") Long recipeId, @Param("detailType") String detailType);
|
||||||
|
|
||||||
|
List<CookRecipeDetail> getByRecipeIdAndDatesAndIntervalId(@Param("recipeId") Long recipeId, @Param("dateList") Set<LocalDate> dateList, @Param("mealtimeType") Long mealtimeType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
package com.bonus.canteen.core.cook.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.alibaba.excel.context.AnalysisContext;
|
||||||
|
import com.alibaba.excel.event.AnalysisEventListener;
|
||||||
|
import com.bonus.canteen.core.common.utils.SpringContextHolder;
|
||||||
|
import com.bonus.canteen.core.cook.domain.CookDishes;
|
||||||
|
import com.bonus.canteen.core.cook.domain.CookRecipeDetail;
|
||||||
|
import com.bonus.canteen.core.cook.domain.CookRecipeDishes;
|
||||||
|
import com.bonus.canteen.core.cook.dto.ImportRecipeDishesDTO;
|
||||||
|
import com.bonus.canteen.core.cook.mapper.CookDishesMapper;
|
||||||
|
import com.bonus.canteen.core.cook.mapper.CookRecipeDetailMapper;
|
||||||
|
import com.bonus.canteen.core.cook.mapper.CookRecipeDishesMapper;
|
||||||
|
import com.bonus.canteen.core.cook.service.ICookDishesService;
|
||||||
|
import com.bonus.canteen.core.cook.service.ICookRecipeDetailService;
|
||||||
|
import com.bonus.canteen.core.cook.service.ICookRecipeDishesService;
|
||||||
|
import com.bonus.common.core.exception.ServiceException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CookRecipeImportListener extends AnalysisEventListener<Map<Integer, String>> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CookRecipeImportListener.class);
|
||||||
|
private final String sheetName;
|
||||||
|
private final Long recipeId;
|
||||||
|
private final Long mealtimeType;
|
||||||
|
private final Map<Integer, LocalDate> dateMap = new HashMap();
|
||||||
|
private final Set<String> dishesNames = new HashSet();
|
||||||
|
private final Set<String> notImportDishesNames = new HashSet();
|
||||||
|
private final Map<LocalDate, List<ImportRecipeDishesDTO>> datas = new HashMap();
|
||||||
|
private final BigDecimal decimal = new BigDecimal(100);
|
||||||
|
|
||||||
|
public Set<String> getNotImportDishesNames() {
|
||||||
|
return this.notImportDishesNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CookRecipeImportListener(String sheetName, Long recipeId, Long mealtimeType) {
|
||||||
|
this.sheetName = sheetName;
|
||||||
|
this.recipeId = recipeId;
|
||||||
|
this.mealtimeType = mealtimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
|
||||||
|
Integer rowIndex = analysisContext.readRowHolder().getRowIndex();
|
||||||
|
String no;
|
||||||
|
if (rowIndex == 1) {
|
||||||
|
no = (String)integerStringMap.get(1);
|
||||||
|
log.info("餐次名称:{}", no);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowIndex == 2) {
|
||||||
|
for(int i = 1; i < integerStringMap.size(); i += 3) {
|
||||||
|
String date = (String)integerStringMap.get(i);
|
||||||
|
if (date != null && !date.isEmpty()) {
|
||||||
|
Date parse = DateUtil.parse(date);
|
||||||
|
String format = DateUtil.format(parse, "yyyy/MM/dd");
|
||||||
|
String[] split = format.split("/");
|
||||||
|
LocalDate localDate = LocalDate.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
|
||||||
|
this.dateMap.put(i, localDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("导入的日期:{}", this.dateMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowIndex > 2) {
|
||||||
|
try {
|
||||||
|
no = (String)integerStringMap.get(0);
|
||||||
|
if (no != null && !no.isEmpty()) {
|
||||||
|
for(int i = 1; i < integerStringMap.size(); i += 3) {
|
||||||
|
String dishesName = (String)integerStringMap.get(i);
|
||||||
|
if (!ObjectUtil.isEmpty(dishesName)) {
|
||||||
|
ImportRecipeDishesDTO importRecipeDishesDto = new ImportRecipeDishesDTO();
|
||||||
|
this.dishesNames.add(dishesName);
|
||||||
|
BigDecimal price = (new BigDecimal((String)integerStringMap.get(i + 1))).multiply(this.decimal);
|
||||||
|
BigDecimal salePrice = (new BigDecimal((String)integerStringMap.get(i + 2))).multiply(this.decimal);
|
||||||
|
importRecipeDishesDto.setSurplusNum(9999).setIndex(i).setDishesName(dishesName).setSaleNum(0).setSupplyNum(9999).setRestrictNum(9999).setPrice(price.intValue()).setSalePrice(salePrice.intValue());
|
||||||
|
if (this.datas.containsKey(this.dateMap.get(i))) {
|
||||||
|
((List)this.datas.get(this.dateMap.get(i))).add(importRecipeDishesDto);
|
||||||
|
} else {
|
||||||
|
List<ImportRecipeDishesDTO> list = new ArrayList();
|
||||||
|
list.add(importRecipeDishesDto);
|
||||||
|
this.datas.put((LocalDate)this.dateMap.get(i), list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception var11) {
|
||||||
|
log.info("解析excel失败:DATA:{}", integerStringMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
|
||||||
|
try {
|
||||||
|
HashSet<LocalDate> dates = new HashSet(this.dateMap.values());
|
||||||
|
if (!dates.isEmpty()) {
|
||||||
|
ICookRecipeDetailService menuRecipeDetailService = SpringContextHolder.getBean(ICookRecipeDetailService.class);
|
||||||
|
CookRecipeDetailMapper cookRecipeDetailMapper = SpringContextHolder.getBean(CookRecipeDetailMapper.class);
|
||||||
|
CookRecipeDishesMapper cookRecipeDishesMapper = SpringContextHolder.getBean(CookRecipeDishesMapper.class);
|
||||||
|
//List<CookRecipeDetail> byRecipeIdAndDates = menuRecipeDetailService.getByRecipeIdAndDatesAndIntervalId(this.recipeId, dates, this.mealtimeType);
|
||||||
|
List<CookRecipeDetail> byRecipeIdAndDates = cookRecipeDetailMapper.getByRecipeIdAndDatesAndIntervalId(this.recipeId, dates, this.mealtimeType);
|
||||||
|
Map<LocalDate, CookRecipeDetail> dateDetailMap = byRecipeIdAndDates.stream().collect(Collectors.groupingBy(CookRecipeDetail::getApplyDate, Collectors.collectingAndThen(Collectors.toList(), (list) -> {
|
||||||
|
return list.get(0);
|
||||||
|
})));
|
||||||
|
if (!this.dishesNames.isEmpty()) {
|
||||||
|
//ICookDishesService menuDishesService = SpringContextHolder.getBean(ICookDishesService.class);
|
||||||
|
//List<CookDishes> menuDishesList = menuDishesService.getByNames(this.dishesNames);
|
||||||
|
CookDishesMapper cookDishesMapper = SpringContextHolder.getBean(CookDishesMapper.class);
|
||||||
|
CookDishes cookDishes = new CookDishes();
|
||||||
|
cookDishes.setDishesNames(this.dishesNames);
|
||||||
|
List<CookDishes> menuDishesList = cookDishesMapper.selectCookDishesList(cookDishes);
|
||||||
|
|
||||||
|
Set<String> difference = DifferenceCalculator.calculateDifference(this.dishesNames, menuDishesList);
|
||||||
|
System.out.println("差集结果: " + difference);
|
||||||
|
if (difference != null && difference.size() > 0) {
|
||||||
|
throw new ServiceException("以下菜品不存在:" + difference);
|
||||||
|
}
|
||||||
|
Map<String, CookDishes> nameMap = menuDishesList.stream().collect(Collectors.groupingBy(CookDishes::getDishesName, Collectors.collectingAndThen(Collectors.toList(), (list) -> {
|
||||||
|
return list.get(0);
|
||||||
|
})));
|
||||||
|
ICookRecipeDishesService menuRecipeDishesService = SpringContextHolder.getBean(ICookRecipeDishesService.class);
|
||||||
|
List<CookRecipeDishes> inserData = new ArrayList<>();
|
||||||
|
|
||||||
|
for (LocalDate date : dates) {
|
||||||
|
CookRecipeDetail menuRecipeDetail = dateDetailMap.get(date);
|
||||||
|
if (menuRecipeDetail == null) {
|
||||||
|
menuRecipeDetail = new CookRecipeDetail();
|
||||||
|
menuRecipeDetail.setRecipeId(this.recipeId);
|
||||||
|
menuRecipeDetail.setApplyDate(date);
|
||||||
|
menuRecipeDetail.setMealtimeType(this.mealtimeType);
|
||||||
|
//menuRecipeDetail.setDetailId(Id.next());
|
||||||
|
//menuRecipeDetailService.save(menuRecipeDetail);
|
||||||
|
cookRecipeDetailMapper.insertCookRecipeDetail(menuRecipeDetail);
|
||||||
|
} else {
|
||||||
|
//menuRecipeDishesService.deleteByDetailId(menuRecipeDetail.getDetailId());
|
||||||
|
Long[] recipeDetailIds = {menuRecipeDetail.getRecipeDetailId()};
|
||||||
|
cookRecipeDishesMapper.deleteCookRecipeDishesByCookRecipeDetailIds(recipeDetailIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ImportRecipeDishesDTO> importRecipeDishesDtos = this.datas.get(date);
|
||||||
|
CookRecipeDetail finalMenuRecipeDetail = menuRecipeDetail;
|
||||||
|
List<CookRecipeDishes> saveDatas = importRecipeDishesDtos.stream().filter(distinctByKey(ImportRecipeDishesDTO::getDishesName)).map((importRecipeDishesDto) -> {
|
||||||
|
CookRecipeDishes menuRecipeDishes = null;
|
||||||
|
CookDishes menuDishes = nameMap.get(importRecipeDishesDto.getDishesName());
|
||||||
|
if (menuDishes != null) {
|
||||||
|
menuRecipeDishes = BeanUtil.copyProperties(importRecipeDishesDto, CookRecipeDishes.class, new String[0]);
|
||||||
|
menuRecipeDishes.setRecipeDetailId(finalMenuRecipeDetail.getRecipeDetailId());
|
||||||
|
menuRecipeDishes.setSizeType(menuDishes.getSizeType());
|
||||||
|
menuRecipeDishes.setDishesId(menuDishes.getDishesId());
|
||||||
|
} else {
|
||||||
|
this.notImportDishesNames.add(importRecipeDishesDto.getDishesName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return menuRecipeDishes;
|
||||||
|
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
inserData.addAll(saveDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
//menuRecipeDishesService.saveBatch(inserData);
|
||||||
|
for (CookRecipeDishes cookRecipeDishes : inserData) {
|
||||||
|
cookRecipeDishesMapper.insertCookRecipeDishes(cookRecipeDishes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (Exception e){
|
||||||
|
throw new ServiceException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
|
||||||
|
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
|
||||||
|
return (t) -> {
|
||||||
|
return seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.bonus.canteen.core.cook.utils;
|
||||||
|
|
||||||
|
import com.bonus.canteen.core.cook.domain.CookDishes;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class DifferenceCalculator {
|
||||||
|
public static Set<String> calculateDifference(Set<String> stringSet, List<CookDishes> menuDishesList) {
|
||||||
|
// 从menuDishesList中提取所有dishesName的集合
|
||||||
|
Set<String> menuDishesNames = menuDishesList.stream()
|
||||||
|
.map(CookDishes::getDishesName)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 计算差集:stringSet中有而menuDishesNames中没有的元素
|
||||||
|
Set<String> difference = new HashSet<>(stringSet);
|
||||||
|
difference.removeAll(menuDishesNames);
|
||||||
|
|
||||||
|
return difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,6 +105,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
#{typeId}
|
#{typeId}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
|
<if test="dishesNames != null and dishesNames.size() > 0">
|
||||||
|
<foreach item="dishesName" collection="dishesNames" open="(" separator="," close=")">
|
||||||
|
#{dishesName}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
<if test="mealType != null "> and cd.meal_type = #{mealType}</if>
|
<if test="mealType != null "> and cd.meal_type = #{mealType}</if>
|
||||||
<if test="customId != null "> and cd.custom_id = #{customId}</if>
|
<if test="customId != null "> and cd.custom_id = #{customId}</if>
|
||||||
<if test="inventoryId != null and inventoryId != ''"> and cd.inventory_id = #{inventoryId}</if>
|
<if test="inventoryId != null and inventoryId != ''"> and cd.inventory_id = #{inventoryId}</if>
|
||||||
|
|
|
||||||
|
|
@ -157,4 +157,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
and detail_type = #{detailType}
|
and detail_type = #{detailType}
|
||||||
group by mealtime_type
|
group by mealtime_type
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="getByRecipeIdAndDatesAndIntervalId" resultMap="CookRecipeDetailResult">
|
||||||
|
select * from cook_recipe_detail
|
||||||
|
where recipe_id = #{recipeId}
|
||||||
|
and mealtime_type = #{mealtimeType}
|
||||||
|
and apply_date in
|
||||||
|
<foreach item="applyDate" collection="dateList" open="(" separator="," close=")">
|
||||||
|
#{applyDate}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue