diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/domain/CookDishes.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/domain/CookDishes.java index a5500bc..218be5e 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/domain/CookDishes.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/domain/CookDishes.java @@ -1,7 +1,9 @@ package com.bonus.canteen.core.cook.domain; import java.math.BigDecimal; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.bonus.canteen.core.common.utils.FileUrlUtil; import com.bonus.common.core.annotation.Excel; @@ -367,6 +369,8 @@ public class CookDishes extends BaseEntity { @ApiModelProperty(value = "菜品类型id集合") private List typeIds; + private Set dishesNames = new HashSet(); + public String getImageUrl() { return FileUrlUtil.getFileUrl(this.imageUrl); } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/dto/ImportRecipeDishesDTO.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/dto/ImportRecipeDishesDTO.java new file mode 100644 index 0000000..f65808d --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/dto/ImportRecipeDishesDTO.java @@ -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; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/mapper/CookRecipeDetailMapper.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/mapper/CookRecipeDetailMapper.java index b2c333c..4d68620 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/mapper/CookRecipeDetailMapper.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/mapper/CookRecipeDetailMapper.java @@ -2,6 +2,8 @@ package com.bonus.canteen.core.cook.mapper; import java.time.LocalDate; import java.util.List; +import java.util.Set; + import com.bonus.canteen.core.cook.domain.CookRecipeDetail; import org.apache.ibatis.annotations.Param; @@ -73,4 +75,6 @@ public interface CookRecipeDetailMapper { List getCookRecipeDetailLTemplate(@Param("recipeId") Long recipeId, @Param("detailType") String detailType); + List getByRecipeIdAndDatesAndIntervalId(@Param("recipeId") Long recipeId, @Param("dateList") Set dateList, @Param("mealtimeType") Long mealtimeType); + } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/CookRecipeImportListener.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/CookRecipeImportListener.java new file mode 100644 index 0000000..088fc82 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/CookRecipeImportListener.java @@ -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> { + private static final Logger log = LoggerFactory.getLogger(CookRecipeImportListener.class); + private final String sheetName; + private final Long recipeId; + private final Long mealtimeType; + private final Map dateMap = new HashMap(); + private final Set dishesNames = new HashSet(); + private final Set notImportDishesNames = new HashSet(); + private final Map> datas = new HashMap(); + private final BigDecimal decimal = new BigDecimal(100); + + public Set 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 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 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 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 byRecipeIdAndDates = menuRecipeDetailService.getByRecipeIdAndDatesAndIntervalId(this.recipeId, dates, this.mealtimeType); + List byRecipeIdAndDates = cookRecipeDetailMapper.getByRecipeIdAndDatesAndIntervalId(this.recipeId, dates, this.mealtimeType); + Map 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 menuDishesList = menuDishesService.getByNames(this.dishesNames); + CookDishesMapper cookDishesMapper = SpringContextHolder.getBean(CookDishesMapper.class); + CookDishes cookDishes = new CookDishes(); + cookDishes.setDishesNames(this.dishesNames); + List menuDishesList = cookDishesMapper.selectCookDishesList(cookDishes); + + Set difference = DifferenceCalculator.calculateDifference(this.dishesNames, menuDishesList); + System.out.println("差集结果: " + difference); + if (difference != null && difference.size() > 0) { + throw new ServiceException("以下菜品不存在:" + difference); + } + Map nameMap = menuDishesList.stream().collect(Collectors.groupingBy(CookDishes::getDishesName, Collectors.collectingAndThen(Collectors.toList(), (list) -> { + return list.get(0); + }))); + ICookRecipeDishesService menuRecipeDishesService = SpringContextHolder.getBean(ICookRecipeDishesService.class); + List 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 importRecipeDishesDtos = this.datas.get(date); + CookRecipeDetail finalMenuRecipeDetail = menuRecipeDetail; + List 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 Predicate distinctByKey(Function keyExtractor) { + Map seen = new ConcurrentHashMap<>(); + return (t) -> { + return seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + }; + } + +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/DifferenceCalculator.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/DifferenceCalculator.java new file mode 100644 index 0000000..8b962d5 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/cook/utils/DifferenceCalculator.java @@ -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 calculateDifference(Set stringSet, List menuDishesList) { + // 从menuDishesList中提取所有dishesName的集合 + Set menuDishesNames = menuDishesList.stream() + .map(CookDishes::getDishesName) + .collect(Collectors.toSet()); + + // 计算差集:stringSet中有而menuDishesNames中没有的元素 + Set difference = new HashSet<>(stringSet); + difference.removeAll(menuDishesNames); + + return difference; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookDishesMapper.xml b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookDishesMapper.xml index 3ea3d99..3751faf 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookDishesMapper.xml +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookDishesMapper.xml @@ -105,6 +105,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{typeId} + + + #{dishesName} + + and cd.meal_type = #{mealType} and cd.custom_id = #{customId} and cd.inventory_id = #{inventoryId} diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookRecipeDetailMapper.xml b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookRecipeDetailMapper.xml index d151e29..857ba90 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookRecipeDetailMapper.xml +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/cook/CookRecipeDetailMapper.xml @@ -157,4 +157,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and detail_type = #{detailType} group by mealtime_type + +