package com.bonus.canteen.core.menu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.allocation.api.AllocCanteenApi;
import com.bonus.canteen.core.allocation.api.AllocDeliveryApi;
import com.bonus.canteen.core.allocation.api.AllocMealtimeApi;
import com.bonus.canteen.core.allocation.api.AllocStallApi;
import com.bonus.canteen.core.allocation.canteen.dto.AllocRecipeStallDTO;
import com.bonus.canteen.core.allocation.canteen.model.AllocCanteen;
import com.bonus.canteen.core.allocation.canteen.model.AllocDeliveryCostModel;
import com.bonus.canteen.core.allocation.canteen.model.AllocStall;
import com.bonus.canteen.core.allocation.canteen.vo.AllocRecipeStallVO;
import com.bonus.canteen.core.auth.api.MgrAuthApi;
import com.bonus.canteen.core.auth.po.MgrUserAuthPO;
import com.bonus.canteen.core.common.constant.LeMqConstant;
import com.bonus.canteen.core.common.enums.AllocMealtimeTypeEnum;
import com.bonus.canteen.core.common.enums.SourceTypeEnum;
import com.bonus.canteen.core.common.page.PageVO;
import com.bonus.canteen.core.common.redis.RedisUtil;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.customer.api.CustInfoApi;
import com.bonus.canteen.core.customer.model.CustInfo;
import com.bonus.canteen.core.device.android.common.dto.MenuSendByDTO;
import com.bonus.canteen.core.device.api.DeviceApi;
import com.bonus.canteen.core.device.manage.vo.DeviceInfoVO;
import com.bonus.canteen.core.marketing.constants.MktEffTypeEnum;
import com.bonus.canteen.core.marketing.constants.MktUserTypeEnum;
import com.bonus.canteen.core.marketing.vo.MktEffectiveUserVO;
import com.bonus.canteen.core.menu.constant.*;
import com.bonus.canteen.core.menu.dto.*;
import com.bonus.canteen.core.menu.easyexcel.MenuRecipeImportListener;
import com.bonus.canteen.core.menu.entity.*;
import com.bonus.canteen.core.menu.mapper.*;
import com.bonus.canteen.core.menu.model.*;
import com.bonus.canteen.core.menu.service.*;
import com.bonus.canteen.core.menu.vo.*;
import com.bonus.canteen.core.nutrition.api.NutritionApi;
import com.bonus.canteen.core.nutrition.common.po.DishNutritionParam;
import com.bonus.canteen.core.nutrition.common.vo.HealthDishRecommendScoreVO;
import com.bonus.canteen.core.order.api.OrderMenuApi;
import com.bonus.canteen.core.order.common.constants.OrderStateEnum;
import com.bonus.canteen.core.order.common.vo.OrderGoodsNumVO;
import com.bonus.canteen.core.order.mq.MqUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.CopyListUtil;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class MenuRecipeServiceImpl extends ServiceImpl<MenuRecipeMapper, MenuRecipe> implements MenuRecipeService {
    private static final Logger log = LoggerFactory.getLogger(MenuRecipeServiceImpl.class);

    @Autowired
    private MenuRecipeDetailService menuRecipeDetailService;

    @Autowired
    private MenuRecipeDishesService menuRecipeDishesService;

    @Autowired
    private MenuAppRecipeMapper menuAppRecipeMapper;

    @Autowired
    private MenuDishesSaleRecordMapper menuDishesSaleRecordMapper;

    @Autowired
    private MenuRecipeMapper menuRecipeMapper;

    @Autowired
    private AllocDeliveryApi allocDeliveryApi;

    @Autowired
    private AllocMealtimeApi allocMealtimeApi;

    @Autowired
    private MenuDishesMapper menuDishesMapper;

    @Autowired
    private NutritionApi nutritionApi;

    @Autowired
    private MenuRecipeDetailMapper menuRecipeDetailMapper;

    @Autowired
    private OrderMenuApi orderMenuApi;

    @Autowired
    private MenuRecipeDishesMapper menuRecipeDishesMapper;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    private TransactionDefinition transactionDefinition;

    @Autowired
    private AllocCanteenApi allocCanteenApi;

    @Resource
    private AllocStallApi allocStallApi;

    @Resource
    private DeviceApi deviceApi;

    @Resource
    private MenuDishesService menuDishesService;

    @Autowired
    private MgrAuthApi mgrAuthApi;

    @Autowired
    private CustInfoApi custInfoApi;
    @Autowired
    private MenuDishesTypeService menuDishesTypeService;



    @Override
    public List<AppletWeekCanteenVO> getWeekMealList(AppletWeekCanteenDTO content) {
        Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getCustId(), false);
        if (ObjectUtil.isEmpty(effIdSet)) {
            effIdSet = Sets.newTreeSet();
            effIdSet.add(-1L);
        }

        return this.menuAppRecipeMapper.selectWeekCanteenList(effIdSet);
    }

    @Override
    public Set<Long> getShopstallIdListByCustId(Long custId, boolean checkCustInfo) {
        Set<Long> effIdSet = Sets.newTreeSet();
        CustInfo custInfoQuery = new CustInfo();
        custInfoQuery.setCustId(custId);
        custInfoQuery.setCustState(1);
        CustInfo custInfo = menuRecipeMapper.selectOrgAndPsnByCustLimitId(custInfoQuery);
        if (ObjectUtil.isNull(custInfo)) {
            if (checkCustInfo) {
                throw new ServiceException("菜单绑定错误");
            } else {
                log.info("***[获取全档口菜谱信息]_未查询到人员信息,直接返回********************");
                return effIdSet;
            }
        } else {
            List<MktEffectiveUserVO> effectiveUserVOList = menuRecipeMapper.selectAllUserEff(MktEffTypeEnum.USER_SORT.key(), DelFlagEnum.DEL_FALSE.key());
            Long orgId = custInfo.getOrgId();
            Integer psnType = custInfo.getPsnType();
            if (ObjectUtil.isNotEmpty(effectiveUserVOList)) {
                List<MktEffectiveUserVO> collect = effectiveUserVOList.stream().filter((u) -> {
                    boolean containsOrg = ObjectUtil.isNotEmpty(u.getOrgIdList()) && u.getOrgIdList().contains(orgId);
                    boolean containsPsn = ObjectUtil.isNotEmpty(u.getPsnTypeList()) && u.getPsnTypeList().contains(psnType);
                    return MktUserTypeEnum.INTERSECTION.key().equals(u.getUserType()) && containsOrg && containsPsn || MktUserTypeEnum.UNION_SET.key().equals(u.getUserType()) && (containsOrg || containsPsn);
                }).collect(Collectors.toList());
                if (ObjectUtil.isNotEmpty(collect)) {
                    effIdSet = collect.stream().map(MktEffectiveUserVO::getEffId).collect(Collectors.toSet());
                    effIdSet.add(-1L);
                }
            }

            log.info("***[获取指定人员折扣比例]_指定人员的生效范围effIdSet: {}", effIdSet);
            return effIdSet;
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Set<String> recipeImportDishes(MultipartFile excel, Long recipeId) {
        MenuRecipe menuRecipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, recipeId)
                .eq(MenuRecipe::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
        if (menuRecipe == null) {
            throw new ServiceException(I18n.getMessage("menu_recipe_not_exist2", new Object[0]));
        } else {
            this.update(Wrappers.lambdaUpdate(MenuRecipe.class).eq(MenuRecipe::getRecipeId, recipeId).set(MenuRecipe::getUptime, LocalDateTime.now()));
            ExcelReader excelReader = null;
            Set<String> notImportDishesNames = new HashSet();
            List<MenuRecipeImportListener> listeners = new ArrayList();

            try {
                excelReader = EasyExcel.read(excel.getInputStream()).build();
                List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList();

                for (ReadSheet readSheet : readSheets) {
                    String sheetName = readSheet.getSheetName();
                    Integer mealtimeType = AllocMealtimeTypeEnum.getKeyByDesc(sheetName);
                    if (!Objects.isNull(mealtimeType)) {
                        MenuRecipeImportListener menuRecipeImportListener = new MenuRecipeImportListener(sheetName, recipeId, mealtimeType);
                        listeners.add(menuRecipeImportListener);
                        readSheet.getCustomReadListenerList().add(menuRecipeImportListener);
                    }
                }

                excelReader.read(readSheets);
                notImportDishesNames.addAll(
                        listeners.stream()
                                .flatMap(listener -> listener.getNotImportDishesNames().stream())
                                .collect(Collectors.toList())
                );
            } catch (Exception var16) {
                log.error("导入菜品失败", var16);
            } finally {
                if (excelReader != null) {
                    excelReader.finish();
                }

            }

            return notImportDishesNames;
        }
    }

    @Override
    public void deletebyInterval(MenuDeleteByDateAndIntervalDTO content) {
        MenuRecipeDetail menuRecipeDetail = this.menuRecipeDetailService.getByRecipeIdAndApplyDateAndIntervalId(content.getRecipeId(), content.getApplyDate(), content.getMealtimeType());
        if (Objects.nonNull(menuRecipeDetail)) {
            Long detailId = menuRecipeDetail.getDetailId();
            this.menuRecipeDishesService.deleteByDetailId(detailId);
        }

        this.update(Wrappers.lambdaUpdate(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId())
                .set(MenuRecipe::getUptime, LocalDateTime.now()));
    }


    @Override
    public List<MenuRecipeDateVO> getBetweenDate(MenuSelectByDateDTO content) {
        LocalDate applyStartDate = content.getApplyStartDate();
        LocalDate applyEndDate = content.getApplyEndDate();
        return this.menuRecipeDetailMapper.selectBetweenDateDetailList(Collections.singletonList(content.getRecipeId()), applyStartDate, applyEndDate);
    }


    @Override
    public List<AppletWeekRecipeVO> getWeekRecipeDetailList(AppletWeekRecipeDTO content) {
        List<Long> recipeIdList = Lists.newArrayList();
        if (ObjectUtil.isNull(content.getRecipeId())) {
            Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getCustId(), false);
            if (ObjectUtil.isEmpty(effIdSet)) {
                effIdSet = Sets.newTreeSet();
                effIdSet.add(-1L);
            }

            recipeIdList = this.menuAppRecipeMapper.selectWeekRecipeId(content.getRecipeId(), (Set) effIdSet);
            if (ObjectUtil.isEmpty(recipeIdList)) {
                return Lists.newArrayList();
            }
        } else {
            recipeIdList.add(content.getRecipeId());
        }

        this.generateRecipe(recipeIdList, content.getApplyDate());
        List<AppletWeekRecipeVO> resultList = menuRecipeMapper.selectWeekRecipe(content.getApplyDate(), content.getRecipeId(), (List) recipeIdList);
        resultList.sort(Collections.reverseOrder((s1, s2) -> {
            return s2.getMealtimeType() - s1.getMealtimeType();
        }));
        return resultList;
    }

    @Override
    public List<AppletReserveCanteenVO> getReserveMealCanteenList(AppletReserveCanteenDTO content) {
        Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getCustId(), false);
        if (ObjectUtil.isEmpty(effIdSet)) {
            effIdSet = Sets.newTreeSet();
            effIdSet.add(-1L);
        }

        List<AppletReserveCanteenVO> resultList = this.menuAppRecipeMapper.selectReserveMealCanteenList(effIdSet);
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            this.allocCanteenApi.checkAndDelReserveCanteen(resultList);
            List<Long> stallIdList = resultList.stream().flatMap((canteen) -> {
                return canteen.getStallList().stream().map(AppletReserveStallVO::getStallId);
            }).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(stallIdList)) {
                List<MenuStallSaleModel> stallMonthSalesList = this.menuDishesSaleRecordMapper.selectMonthSalesStall(stallIdList);
                Map<Long, Integer> stallSaleMap =
                        stallMonthSalesList.stream().collect(Collectors.toMap(MenuStallSaleModel::getStallId, MenuStallSaleModel::getMonthlySales));
                resultList.forEach((canteen) -> {
                    List<AppletReserveStallVO> stallList = canteen.getStallList();
                    if (ObjectUtil.isNotEmpty(stallList)) {
                        stallList.forEach((stall) -> {
                            stall.setMonthlySales(stallSaleMap.get(stall.getStallId()));
                        });
                    }

                });
            }

            resultList.forEach((c) -> {
                List<AppletReserveStallVO> stallList = c.getStallList();
                if (ObjectUtil.isNotEmpty(stallList)) {
                    stallList.forEach((s) -> {
                        List<Long> topDishesIdList = this.menuDishesSaleRecordMapper.selectTopDishesIdList(Collections.singletonList(s.getStallId()));
                        List<AppletRecommendDishesVO> recommendList = Lists.newArrayList();
                        List<AppletRecommendDishesVO> allRecipeDishesList = this.baseMapper.selectAllRecipeDishesList(s.getRecipeId(), (Integer) null);
                        if (ObjectUtil.isNotEmpty(allRecipeDishesList) && ObjectUtil.isNotEmpty(topDishesIdList)) {

                            for (Long dishesId : topDishesIdList) {
                                if (allRecipeDishesList.stream().map(AppletRecommendDishesVO::getDishesId).collect(Collectors.toList()).contains(dishesId)) {
                                    AppletRecommendDishesVO recommendDishes = allRecipeDishesList.stream().filter((a) -> {
                                        return a.getDishesId().equals(dishesId);
                                    }).collect(Collectors.toList()).get(0);
                                    if (!recommendList.contains(recommendDishes)) {
                                        recommendList.add(recommendDishes);
                                    }

                                    if (recommendList.size() >= 3) {
                                        s.setRecommendList(recommendList);
                                        return;
                                    }
                                }
                            }
                        }

                        s.setRecommendList(recommendList);
                    });
                }

            });
            return resultList;
        }
    }

    @Override
    public List<AppletReserveRecipeVO> getReserveRecipeDetailList(AppletReserveRecipeDTO content) {
        this.generateRecipe(content.getRecipeId(), content.getApplyDate());
        List<AppletReserveRecipeVO> resultList = this.baseMapper.selectReserveRecipe(content.getApplyDate(), content.getRecipeId());
        if (ObjectUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            resultList.sort(Collections.reverseOrder((s1, s2) -> {
                return s2.getMealtimeType() - s1.getMealtimeType();
            }));
            Long stallId = this.baseMapper.selectStallIdByWrappers(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, content.getRecipeId()).eq(MenuRecipe::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
            List<AllocDeliveryCostModel> costModelList = this.allocDeliveryApi.queryDeliveryCostModel(stallId);
            log.info("配置api查询的档口配送,档口id: {}, 配置: {}", stallId, JSON.toJSONString(costModelList));
            List<AllocMealtimeStateModel> mealTimeList = this.allocMealtimeApi.getAllocMealtimeMenuModel(stallId).getMealtimeStateModelList();
            if (ObjectUtil.isNotEmpty(mealTimeList)) {
                mealTimeList = mealTimeList.stream().filter((mealtimex) -> {
                    return mealtimex.getIfUse() == 1;
                }).collect(Collectors.toList());
            }

            log.info("配置api查询的档口餐次,档口id: {}, 配置: {}", stallId, JSON.toJSONString(mealTimeList));
            if (ObjectUtil.isEmpty(mealTimeList)) {
                log.info("未获取到开启餐次");
                return Lists.newArrayList();
            } else {
                if (LocalDate.now().isEqual(content.getApplyDate())) {
                    mealTimeList = mealTimeList.stream().filter((time) -> {
                        return LocalTime.now().isBefore(time.getStartTime());
                    }).collect(Collectors.toList());
                }

                if (ObjectUtil.isEmpty(mealTimeList)) {
                    log.info("未获取到餐次");
                    return Lists.newArrayList();
                } else {
                    List<AllocMealtimeStateModel> finalMealTimeList = mealTimeList;
                    resultList = resultList.stream().filter((time) -> {
                        return finalMealTimeList.stream().map(AllocMealtimeStateModel::getMealtimeType).collect(Collectors.toList()).contains(time.getMealtimeType());
                    }).collect(Collectors.toList());
                    resultList.forEach((time) -> {
                        List<AppletReserveRecipeTypeVO> typeList = time.getTypeList();
                        if (ObjectUtil.isNotEmpty(typeList)) {
                            typeList.forEach((type) -> {
                                List<AppletReserveRecipeDishesVO> dishesList = type.getDishesList();
                                if (ObjectUtil.isNotEmpty(dishesList)) {
                                    dishesList.forEach((dishes) -> {
                                        dishes.setCostModelList(costModelList);
                                    });
                                }

                            });
                        }

                    });
                    Set<Long> dishesIdSet = resultList.stream().flatMap((time) -> {
                        return time.getTypeList().stream().flatMap((type) -> {
                            return type.getDishesList().stream().map((item) -> {
                                return (item.getDishesDetailList().get(0)).getDishesId();
                            });
                        });
                    }).collect(Collectors.toSet());
                    if (ObjectUtil.isEmpty(dishesIdSet)) {
                        return resultList;
                    } else {
                        List<DishNutritionParam> dishNutritionParamList = this.menuDishesMapper.selectNutrition(dishesIdSet);
                        HealthDishRecommendScoreVO dishesRecommendScore = this.nutritionApi.getDishesRecommendScore(content.getCustId(), dishNutritionParamList);
                        if (dishesRecommendScore.getRecommendFlag()) {
                            resultList.forEach((time) -> {
                                List<AppletReserveRecipeTypeVO> typeList = time.getTypeList();
                                if (ObjectUtil.isNotEmpty(typeList)) {
                                    typeList.forEach((type) -> {
                                        List<AppletReserveRecipeDishesVO> dishesList = type.getDishesList();
                                        if (ObjectUtil.isNotEmpty(dishesList)) {
                                            dishesList.forEach((dishes) -> {
                                                Integer initialScore = (Integer) dishesRecommendScore.getDishRecommendMap().get(((AppletCurrentDishesDetailVO) dishes.getDishesDetailList().get(0)).getDishesId());
                                                if (ObjectUtil.isNotNull(initialScore)) {
                                                    dishes.setInitialScore(initialScore);
                                                }

                                            });
                                        }

                                    });
                                }

                            });
                        }

                        Iterator var10 = resultList.iterator();

                        while (true) {
                            List<AppletReserveRecipeTypeVO> typeList;
                            do {
                                if (!var10.hasNext()) {
                                    return resultList;
                                }

                                AppletReserveRecipeVO mealtime = (AppletReserveRecipeVO) var10.next();
                                typeList = mealtime.getTypeList();
                            } while (!ObjectUtil.isNotEmpty(typeList));

                            List<AppletReserveRecipeDishesVO> recommendList = Lists.newArrayList();

                            for (AppletReserveRecipeTypeVO type : typeList) {
                                List<AppletReserveRecipeDishesVO> dishesList = type.getDishesList();
                                if (ObjectUtil.isNotEmpty(dishesList)) {
                                    List<AppletReserveRecipeDishesVO> tempList = dishesList.stream().filter((d) -> {
                                        return d.getRecommendFlag() == 1;
                                    }).collect(Collectors.toList());
                                    if (ObjectUtil.isNotEmpty(tempList)) {
                                        recommendList.addAll(tempList);
                                    }
                                }
                            }

                            if (ObjectUtil.isNotEmpty(recommendList)) {
                                AppletReserveRecipeTypeVO recommend = new AppletReserveRecipeTypeVO();
                                recommend.setTypeId(999L);
                                recommend.setTypeName("推荐");
                                recommend.setDishesList(recommendList);
                                typeList.add(0, recommend);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void generateRecipe(Long recipeId, LocalDate applyDate) {
        if (!ObjectUtil.isEmpty(recipeId) && !ObjectUtil.isEmpty(applyDate)) {
            this.generateRecipe(Collections.singletonList(recipeId), applyDate);
        }
    }

    @Override
    public List<MenuRecipeDetailDateVO> queryRecipeTemplateDate(QueryRecipeTemplateDateDTO content) {
        return this.menuRecipeDetailMapper.selectTemplateDetailList(content);
    }

    @Override
    public List<MenuRecipeWeekVO> getWeek(Long recipeId) {
        return this.menuRecipeDetailMapper.selectWeekDetailList(recipeId);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void copyRecipeToStall(MenuCopyRecipeStallDTO content) {
        List<AllocStall> allocStallList = this.allocStallApi.listStallByStallIdList(content.getStallIdSet());
        MenuRecipe sourceRecipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId())
                .eq(MenuRecipe::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
        List<MenuRecipe> recipeList = Lists.newArrayList();
        List<MenuRecipeDetail> recipeDetailList = Lists.newArrayList();
        List<MenuRecipeDishes> recipeDishesList = Lists.newArrayList();
        long count = this.count();
        List<MenuRecipeDetail> sourceDetailList = this.menuRecipeDetailService.list(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId())
                .and((wp) -> {
                    wp.isNull(MenuRecipeDetail::getApplyDate)
                            .or()
                            .ge(MenuRecipeDetail::getApplyDate, LocalDate.now());
                }));
        Map<Long, List<MenuRecipeDishes>> dishesMap = Maps.newHashMap();
        if (ObjectUtil.isNotEmpty(sourceDetailList)) {
            List<Long> detailIdList =
                    sourceDetailList.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
            List<MenuRecipeDishes> sourceDishesList = this.menuRecipeDishesService.list(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                    .in(MenuRecipeDishes::getDetailId, detailIdList));
            if (ObjectUtil.isNotEmpty(sourceDishesList)) {
                dishesMap = sourceDishesList.stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId));
            }
        }

        for (AllocStall allocStall : allocStallList) {
            Long targetRecipeId = Id.next();
            MenuRecipe targetRecipe = this.generateTargetRecipe(allocStall, sourceRecipe, targetRecipeId, count++);
            recipeList.add(targetRecipe);
            this.generateTargetRecipeDetail(sourceDetailList, dishesMap, targetRecipeId, recipeDetailList, recipeDishesList);
        }

        super.saveBatch(recipeList);
        if (ObjectUtil.isNotEmpty(recipeDetailList)) {
            this.menuRecipeDetailService.saveBatch(recipeDetailList);
        }

        if (ObjectUtil.isNotEmpty(recipeDishesList)) {
            this.menuRecipeDishesService.saveBatch(recipeDishesList);
        }

    }
    public MenuRecipe generateTargetRecipe(AllocStall stall, MenuRecipe sourceRecipe, Long recipeId, long count) {
        MenuRecipe targetRecipe = new MenuRecipe();
        targetRecipe.setRecipeId(recipeId);
        targetRecipe.setRecipeType(sourceRecipe.getRecipeType());
        String var10001 = sourceRecipe.getRecipeName();
        targetRecipe.setRecipeName(var10001 + "-" + stall.getStallName() + count);
        targetRecipe.setCanteenId(stall.getCanteenId());
        targetRecipe.setStallId(stall.getStallId());
        targetRecipe.setEffId(sourceRecipe.getEffId());
        return targetRecipe;
    }

    public void generateTargetRecipeDetail(List<MenuRecipeDetail> sourceDetailList, Map<Long, List<MenuRecipeDishes>> dishesMap, Long targetRecipeId, List<MenuRecipeDetail> recipeDetailList, List<MenuRecipeDishes> recipeDishesList) {
        List<MenuRecipeDetail> targetDetailList = BeanUtil.copyToList(sourceDetailList, MenuRecipeDetail.class);
        Iterator<MenuRecipeDetail> var7 = targetDetailList.iterator();

        while(true) {
            Long targetDetailId;
            List<MenuRecipeDishes> sourceDishesList;
            do {
                if (!var7.hasNext()) {
                    recipeDetailList.addAll(targetDetailList);
                    return;
                }

                MenuRecipeDetail detail = var7.next();
                Long sourceDetailId = detail.getDetailId();
                targetDetailId = Id.next();
                detail.setId(null);
                detail.setDetailId(targetDetailId);
                detail.setRecipeId(targetRecipeId);
                sourceDishesList = dishesMap.get(sourceDetailId);
            } while(ObjectUtil.isEmpty(sourceDishesList));

            List<MenuRecipeDishes> targetDishesList = BeanUtil.copyToList(sourceDishesList, MenuRecipeDishes.class);

            for (MenuRecipeDishes dishes : targetDishesList) {
                dishes.setId( null);
                dishes.setDetailId(targetDetailId);
                dishes.setSaleNum(0);
                dishes.setSurplusNum(dishes.getSupplyNum());
            }

            if (ObjectUtil.isNotEmpty(targetDishesList)) {
                recipeDishesList.addAll(targetDishesList);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void editMenuRecipeByApplyDate(MenuRecipeDetailEditDTO content) {
        Long recipeId = content.getRecipeId();
        LocalDate applyDate = content.getApplyDate();
        Integer mealtimeType = content.getMealtimeType();
        this.changeBaseDishesId(content.getDishesList());
        this.checkDishesList(content.getDishesList());
        MenuRecipe menuRecipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, recipeId));
        MenuRecipeDetail recipeDetail = this.menuRecipeDetailService.getOne(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getApplyDate, applyDate)
                .eq(MenuRecipeDetail::getMealtimeType, mealtimeType)
                .eq(MenuRecipeDetail::getRecipeId, recipeId));
        String username = SecurityUtils.getUsername();
        if (ObjectUtil.isEmpty(recipeDetail)) {
            recipeDetail = new MenuRecipeDetail();
            Long detailId = Id.next();
            recipeDetail.setDetailId(detailId);
            recipeDetail.setRecipeId(recipeId);
            recipeDetail.setApplyDate(applyDate);
            if (ObjectUtil.equal(menuRecipe.getRecipeType(), 3)) {
                recipeDetail.setApplyWeek(applyDate.getDayOfWeek().getValue());
            }

            recipeDetail.setMealtimeType(mealtimeType);
            recipeDetail.setCrby(username);
            recipeDetail.setDetailType(2);
            this.menuRecipeDetailService.save(recipeDetail);
        }

        List<MenuRecipeDishes> recipeDishesV2List = new ArrayList<>();
        List<Long> haveDetailIds = Collections.singletonList(recipeDetail.getDetailId());
        this.getDayActiveMenuRecipeDetailDishes(Collections.singletonList(recipeDetail), Collections.singletonList(content), recipeDishesV2List, haveDetailIds);
        RecipeProcessResult result = new RecipeProcessResult();
        result.setHaveDetailIds(haveDetailIds);
        result.setRecipeDishes(recipeDishesV2List);
        result.setRecipeId(recipeId);
        result.setMenuRecipe(menuRecipe);
        result.setAdd(false);
        this.processResult(result);
    }
    public void processResult(RecipeProcessResult result) {
        List<Long> detailIds = result.getTemplateDetailIds();
        MenuRecipe menuRecipe = result.getMenuRecipe();
        if (ObjectUtil.isNotEmpty(detailIds)) {
            this.menuRecipeDetailService.remove(Wrappers.lambdaQuery(MenuRecipeDetail.class).in(MenuRecipeDetail::getDetailId, detailIds));
            this.menuRecipeDishesService.remove(Wrappers.lambdaQuery(MenuRecipeDishes.class).in(MenuRecipeDishes::getDetailId, detailIds));
        }

        List<Long> haveDetailIds = result.getHaveDetailIds();
        if (ObjectUtil.isNotEmpty(haveDetailIds)) {
            this.menuRecipeDishesService.remove(Wrappers.lambdaQuery(MenuRecipeDishes.class).in(MenuRecipeDishes::getDetailId, haveDetailIds));
        }

        List<MenuRecipeDetail> recipeDetailV2List = result.getRecipeDetails();
        if (ObjectUtil.isNotEmpty(recipeDetailV2List)) {
            this.menuRecipeDetailService.saveBatch(recipeDetailV2List);
        }

        List<MenuRecipeDishes> recipeDishesV2List = result.getRecipeDishes();
        if (ObjectUtil.isNotEmpty(recipeDishesV2List)) {
            recipeDishesV2List.forEach((r) -> {
                r.setId(null);
                Integer surplusNum = r.getSurplusNum();
                if (ObjectUtil.isNull(surplusNum) || surplusNum <= 0) {
                    r.setSurplusNum(0);
                }

            });
            this.menuRecipeDishesService.saveBatch(recipeDishesV2List);
        }

        LeMqConstant.DataChangeType type;
        String redisKey;
        if (result.getAdd()) {
            type = LeMqConstant.DataChangeType.ADD;
        } else {
            type = LeMqConstant.DataChangeType.UPDATE;
            redisKey = Optional.ofNullable(menuRecipe).map(MenuRecipe::getRecipeName).orElse(null);
            Long effId = Optional.ofNullable(menuRecipe).map(MenuRecipe::getEffId).orElse(-1L);
            this.update(Wrappers.lambdaUpdate(MenuRecipe.class).eq(MenuRecipe::getRecipeId, result.getRecipeId())
                    .set(MenuRecipe::getEffId, effId)
                            .set(ObjectUtil.isNotEmpty(redisKey), MenuRecipe::getRecipeName, redisKey)
                    .set(MenuRecipe::getUptime, LocalDateTime.now()));
            this.menuRecipeDetailService.update(Wrappers.lambdaUpdate(MenuRecipeDetail.class)
                    .eq(MenuRecipeDetail::getRecipeId, result.getRecipeId())
                    .set(MenuRecipeDetail::getUptime, LocalDateTime.now()));
            List<MenuAppRecipe> menuAppRecipes = this.menuAppRecipeMapper.selectList(Wrappers.lambdaQuery(MenuAppRecipe.class)
                    .eq(MenuAppRecipe::getRecipeId, result.getRecipeId()));
            if (ObjectUtil.isNotEmpty(menuAppRecipes)) {
                Map<Integer, MenuRecipeSortEnum> bindTypeMap = MenuRecipeSortEnum.getBindTypeMap();
                List<Integer> deviceBindTypes = MenuRecipeSortEnum.getDeviceBindTypes();
                List<MenuSendByDTO> menuSendByDTOS = menuAppRecipes.stream().filter((x) -> {
                    return deviceBindTypes.contains(x.getBindType());
                }).map((item) -> {
                    MenuSendByDTO menuSendByDTO = new MenuSendByDTO();
                    menuSendByDTO.setStallId(menuRecipe.getStallId());
                    menuSendByDTO.setCanteenId(menuRecipe.getCanteenId());
                    menuSendByDTO.setMealLineId(item.getMealLineId());
                    menuSendByDTO.setDeviceTypeList((bindTypeMap.get(item.getBindType())).getDeviceType());
                    return menuSendByDTO;
                }).collect(Collectors.toList());
                this.deviceApi.sendMenuByCanteen(result.getRecipeId(), menuSendByDTOS);
            }
        }

        MqUtil.sendDataChange(menuRecipe, type, LeMqConstant.Topic.DATA_CHANGE_RECIPE);
        redisKey = String.format("yst:%s:recipe:%s:detail:%s", TenantContextHolder.getTenantId(), result.getRecipeId(), "*");
        RedisUtil.deleteByPattern(redisKey);
    }
    public void changeBaseDishesId(List<MenuRecipeDishesV2AddDTO> menuRecipeDishesV2AddDTOS) {
        if (!ObjectUtil.isEmpty(menuRecipeDishesV2AddDTOS)) {
            List<Long> baseDishesIdList = menuRecipeDishesV2AddDTOS.stream().map(MenuRecipeDishesV2AddDTO::getDishesId).distinct().collect(Collectors.toList());
            List<MenuBaseModel> baseList = this.menuDishesMapper.selectBaseSizeDishesId(baseDishesIdList);
            Map<Long, List<MenuBaseDishesModel>> baseMap = baseList.stream().collect(Collectors.toMap(MenuBaseModel::getBaseDishesId, MenuBaseModel::getDishesList));
            menuRecipeDishesV2AddDTOS.forEach((dishes) -> {
                Long sizeType = dishes.getSizeType();
                List<MenuBaseDishesModel> baseDishesList;
                MenuBaseDishesModel tempDishes;
                if (sizeType == 2L) {
                    baseDishesList = baseMap.get(dishes.getDishesId());
                    tempDishes = baseDishesList.get(0);
                    if (CharSequenceUtil.contains(tempDishes.getSizeJson(), "大份")) {
                        dishes.setDishesId(tempDishes.getDishesId());
                    } else {
                        dishes.setDishesId((baseDishesList.get(1)).getDishesId());
                    }
                } else if (sizeType == 3L) {
                    baseDishesList = baseMap.get(dishes.getDishesId());
                    tempDishes = baseDishesList.get(0);
                    if (CharSequenceUtil.contains(tempDishes.getSizeJson(), "小份")) {
                        dishes.setDishesId(tempDishes.getDishesId());
                    } else {
                        dishes.setDishesId((baseDishesList.get(1)).getDishesId());
                    }
                } else {
                    baseDishesList = baseMap.get(dishes.getDishesId());
                    tempDishes = baseDishesList.get(0);
                    dishes.setDishesId(tempDishes.getDishesId());
                }

            });
        }
    }
    public void checkDishesList(List<MenuRecipeDishesV2AddDTO> dishesList) {
        long count = dishesList.stream().filter((x) -> {
            return x.getSizeType() != 3L;
        }).count();
        if (count > 99L) {
            throw new ServiceException(I18n.getMessage("menu_issue_dishes_max", new Object[0]));
        } else {
            dishesList.stream().filter((x) -> {
                return x.getSizeType() == 3L;
            }).forEach((dishes) -> {
                dishes.setRecommendFlag(2);
            });
            long dishesCount = dishesList.stream().filter((d) -> {
                return Integer.valueOf(1).equals(d.getRecommendFlag());
            }).count();
            if (dishesCount > 3L) {
                throw new ServiceException(I18n.getMessage("menu_recommend_dishes_over_three", new Object[0]));
            }
        }
    }
    public void getDayActiveMenuRecipeDetailDishes(List<MenuRecipeDetail> menuRecipeDetails, List<MenuRecipeDetailV2AddDTO> recipeDetailV2AddDTOS, List<MenuRecipeDishes> recipeDishesV2List, List<Long> haveDetailIds) {
        if (!ObjectUtil.isEmpty(menuRecipeDetails)) {
            List<MenuRecipeDishes> menuRecipeDishes = this.menuRecipeDishesService.list(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                    .in(MenuRecipeDishes::getDetailId, haveDetailIds));
            menuRecipeDishes.forEach((dishes) -> {
                dishes.setSizeType(Optional.ofNullable(dishes.getSizeType()).orElse(1L));
            });
            Map<Long, Map<String, MenuRecipeDishes>> dishesMap =
                    menuRecipeDishes.stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId,
                    Collectors.toMap(this.getDishesUniKeyFunction(), Function.identity())));
            Map<Integer, Map<Long, MenuRecipeDetail>> dayAndMealTimeMap = menuRecipeDetails.stream()
                    .collect(Collectors.groupingBy(MenuRecipeDetail::getMealtimeType,
                            Collectors.toMap(MenuRecipeDetail::getDetailId, Function.identity())));

            for (MenuRecipeDetailV2AddDTO detailV2AddDTO : recipeDetailV2AddDTOS) {
                Integer mealtimeType = detailV2AddDTO.getMealtimeType();
                List<MenuRecipeDishesV2AddDTO> dishesList = detailV2AddDTO.getDishesList();
                Map<String, MenuRecipeDishesV2AddDTO> editDishesMap = dishesList.stream().collect(Collectors.toMap(this.getUniKeyFunction(), Function.identity()));
                Map<Long, MenuRecipeDetail> detailMap = Optional.ofNullable(dayAndMealTimeMap.get(mealtimeType)).orElse(new HashMap());

                for (Long detailId : detailMap.keySet()) {
                    Map<String, MenuRecipeDishes> haveDishesMap = Optional.ofNullable(dishesMap.get(detailId)).orElse(new HashMap());

                    for (String dishesFlag : editDishesMap.keySet()) {
                        MenuRecipeDishesV2AddDTO addDishes = editDishesMap.get(dishesFlag);
                        MenuRecipeDishes haveDishes = haveDishesMap.get(dishesFlag);
                        MenuRecipeDishes dishesItem = this.getEditMenuDishes(dishesFlag, addDishes, haveDishes, detailId);
                        recipeDishesV2List.add(dishesItem);
                    }
                }
            }

        }
    }
    public Function<MenuRecipeDishes, String> getDishesUniKeyFunction() {
        return (item) -> {
            Long var10000 = item.getDishesId();
            return "" + var10000 + "_" + item.getSizeType();
        };
    }
    public Function<MenuRecipeDishesV2AddDTO, String> getUniKeyFunction() {
        return (item) -> {
            Long var10000 = item.getDishesId();
            return "" + var10000 + "_" + item.getSizeType();
        };
    }
    public MenuRecipeDishes getEditMenuDishes(String dishesFlag, MenuRecipeDishesV2AddDTO addDishes, MenuRecipeDishes haveDishes, Long detailId) {
        Integer salesSum = Optional.ofNullable(haveDishes).map(MenuRecipeDishes::getSaleNum).orElse(0);
        MenuRecipeDishes dishesItem = new MenuRecipeDishes();
        dishesItem.setDetailId(detailId);
        dishesItem.setDishesId(Long.parseLong(CharSequenceUtil.subBefore(dishesFlag, "_", true)));
        dishesItem.setPrice(addDishes.getPrice());
        dishesItem.setSaleNum(salesSum);
        dishesItem.setSupplyNum(addDishes.getSupplyNum());
        dishesItem.setSurplusNum(addDishes.getSupplyNum() - salesSum);
        dishesItem.setRestrictNum(addDishes.getRestrictNum());
        dishesItem.setSalePrice(Optional.ofNullable(addDishes.getSalePrice()).orElse(addDishes.getPrice()));
        dishesItem.setRecommendFlag(addDishes.getRecommendFlag());
        dishesItem.setSizeType(addDishes.getSizeType());
        dishesItem.setSortNum(addDishes.getSortNum());
        return dishesItem;
    }
    public RecipeProcessResult processDefault(MenuRecipeV2AddDTO content, Long recipeId) {
        return this.processDefault(content, recipeId, true);
    }
    public RecipeProcessResult processDefault(MenuRecipeV2AddDTO content, Long recipeId, Boolean isComplete) {
        RecipeProcessResult result = new RecipeProcessResult();
        String username = SecurityUtils.getUsername();
        List<MenuRecipeDateV2AddDTO> recipeDateList = content.getRecipeDateList();
        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
        List<Long> ids = recipeDateList.stream().filter((x) -> {
            return ObjectUtil.isNotNull(x.getDetailList());
        }).flatMap((x) -> {
            return x.getDetailList().stream();
        }).filter((x) -> {
            return ObjectUtil.isNotNull(x.getDishesList());
        }).flatMap((x) -> {
            return x.getDishesList().stream();
        }).map(MenuRecipeDishesV2AddDTO::getId).filter(ObjectUtil::isNotNull).collect(Collectors.toList());
        Map<Long, Integer> idAndSalesMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(ids)) {
            List<MenuRecipeDishes> menuRecipeDishes = this.menuRecipeDishesMapper.selectBatchIds(ids);
            idAndSalesMap = menuRecipeDishes.stream().collect(Collectors.groupingBy(MenuRecipeDishes::getId,
                    Collectors.collectingAndThen(Collectors.toList(), (x) -> {
                return (x.get(0)).getSaleNum();
            })));
        }

        Map<Long, Integer> finalIdAndSalesMap = idAndSalesMap;
        Iterator<MenuRecipeDateV2AddDTO> var12 = recipeDateList.iterator();

        List<MenuRecipeDetailV2AddDTO> detailIdList;
        while(var12.hasNext()) {
            MenuRecipeDateV2AddDTO rd = var12.next();
            detailIdList = rd.getDetailList();
            detailIdList = detailIdList.stream().filter((d) -> {
                return ObjectUtil.isNotEmpty(d.getDishesList());
            }).collect(Collectors.toList());
            if (!ObjectUtil.isEmpty(detailIdList)) {
                detailIdList.forEach((in) -> {
                    List<MenuRecipeDishesV2AddDTO> dishesList = in.getDishesList();
                    if (ObjectUtil.isNotEmpty(dishesList)) {
                        this.checkDishesList(dishesList);
                    }

                });
                detailIdList.forEach((in) -> {
                    List<MenuRecipeDishesV2AddDTO> dishesList = in.getDishesList();
                    MenuRecipeDetail detailItem = new MenuRecipeDetail();
                    Long detailId = Id.next();
                    detailItem.setDetailId(detailId);
                    detailItem.setRecipeId(recipeId);
                    detailItem.setApplyDate(rd.getApplyDate());
                    detailItem.setMealtimeType(in.getMealtimeType());
                    detailItem.setCrby(username);
                    recipeDetailV2List.add(detailItem);
                    dishesList.forEach((di) -> {
                        MenuRecipeDishes dishesItem = new MenuRecipeDishes();
                        Integer salesSum = Optional.ofNullable(finalIdAndSalesMap.get(di.getId())).orElse(0);
                        dishesItem.setDetailId(detailId);
                        dishesItem.setDishesId(di.getDishesId());
                        dishesItem.setPrice(di.getPrice());
                        dishesItem.setSizeType(di.getSizeType());
                        dishesItem.setSaleNum(salesSum);
                        dishesItem.setSupplyNum(di.getSupplyNum());
                        int surplusNum = di.getSupplyNum() - salesSum;
                        if (surplusNum <= 0) {
                            surplusNum = 0;
                        }

                        dishesItem.setSurplusNum(surplusNum);
                        dishesItem.setRestrictNum(di.getRestrictNum());
                        dishesItem.setSalePrice(Optional.ofNullable(di.getSalePrice()).orElse(di.getPrice()));
                        dishesItem.setRecommendFlag(di.getRecommendFlag());
                        dishesItem.setSortNum(di.getSortNum());
                        recipeDishesV2List.add(dishesItem);
                    });
                });
            }
        }

        List<LocalDate> applyDateList = recipeDateList.stream().map(MenuRecipeDateV2AddDTO::getApplyDate).collect(Collectors.toList());
        LambdaQueryWrapper<MenuRecipeDetail> wrapper = Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getRecipeId, recipeId)
                .in(MenuRecipeDetail::getApplyDate, applyDateList);
        if (Boolean.FALSE.equals(isComplete)) {
            wrapper.and((x) -> {
                Iterator<MenuRecipeDateV2AddDTO> var2 = recipeDateList.iterator();

                while(true) {
                    MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO;
                    do {
                        do {
                            if (!var2.hasNext()) {
                                return;
                            }

                            menuRecipeDateV2AddDTO = var2.next();
                        } while(ObjectUtil.isEmpty(menuRecipeDateV2AddDTO));
                    } while(ObjectUtil.isEmpty(menuRecipeDateV2AddDTO.getDetailList()));

                    for (MenuRecipeDetailV2AddDTO menuRecipeDetailV2AddDTO : menuRecipeDateV2AddDTO.getDetailList()) {
                        x.eq(MenuRecipeDetail::getApplyDate, menuRecipeDateV2AddDTO.getApplyDate());
                        x.eq(MenuRecipeDetail::getMealtimeType, menuRecipeDetailV2AddDTO.getMealtimeType());
                        x.or();
                    }
                }
            });
        }

        List<Long> detailIdLists = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(wrapper);
        result.setTemplateDetailIds(detailIdLists);
        result.setRecipeDetails(recipeDetailV2List);
        result.setRecipeDishes(recipeDishesV2List);
        return result;
    }

    @Override
    public PageVO<AllocRecipeStallVO> queryCurrentRecipe(AllocRecipeStallDTO content) {
        Map<Integer, MenuRecipeSortEnum> bindTypeMap = MenuRecipeSortEnum.getKeyMap();
        MenuRecipeSortEnum sortEnum = bindTypeMap.get(content.getKey());
        if (ObjectUtil.isEmpty(sortEnum)) {
            return PageVO.empty();
        } else {
            content.setDeviceTypeList(sortEnum.getDeviceType());
            content.setBindType(sortEnum.getBindType());
            boolean isMeal = MenuRecipeSortEnum.MEALLINE.getKey().equals(content.getKey());
            if (isMeal) {
                content.setIfQueryMealLine(1);
            } else {
                content.setIfQueryMealLine(2);
            }

            Page<AllocRecipeStallVO> allocRecipeStallVOPage = this.allocStallApi.pageRecipeStallInfo(content);
            List<AllocRecipeStallVO> records = allocRecipeStallVOPage.getRecords();
            if (ObjectUtil.isNotEmpty(records)) {
                List<Long> recipeIds;
                Map<Long ,Long> maping;
                List<Long> menuRecipeDateVOS;
                List<MenuAppRecipe> menuAppRecipes;
                if (isMeal) {
                    menuRecipeDateVOS = records.stream().map(AllocRecipeStallVO::getMealLineId).collect(Collectors.toList());
                    menuAppRecipes = this.menuAppRecipeMapper.selectList(Wrappers.lambdaQuery(MenuAppRecipe.class)
                            .eq(MenuAppRecipe::getBindType, content.getBindType())
                            .in(MenuAppRecipe::getMealLineId, menuRecipeDateVOS));
                    recipeIds = menuAppRecipes.stream().map(MenuAppRecipe::getRecipeId).distinct().collect(Collectors.toList());
                    maping = menuAppRecipes.stream().collect(Collectors.toMap(MenuAppRecipe::getMealLineId, MenuAppRecipe::getRecipeId));
                } else {
                    menuRecipeDateVOS = records.stream().map(AllocRecipeStallVO::getStallId).collect(Collectors.toList());
                   List<StallAndRecipeBindDto> stallAndRecipeBindDtos = this.menuAppRecipeMapper.selectRecipeByStallIdsAndBindType(menuRecipeDateVOS, content.getBindType());
                    maping = stallAndRecipeBindDtos.stream().collect(Collectors.toMap(StallAndRecipeBindDto::getStallId, StallAndRecipeBindDto::getRecipeId));
                    recipeIds = stallAndRecipeBindDtos.stream().map(StallAndRecipeBindDto::getRecipeId).distinct().collect(Collectors.toList());
                }

                if (ObjectUtil.isEmpty(recipeIds)) {
                    return PageVO.of(allocRecipeStallVOPage);
                }

                this.generateRecipe(recipeIds, content.getApplyDate());
                List<MenuRecipeDateVO> menuRecipeDateVOS1 = this.menuRecipeDetailMapper.selectTmpBetweenDateDetailList(recipeIds, content.getApplyDate(), content.getApplyDate());
                Map<Long, MenuRecipe> recipeMap = this.list(Wrappers.lambdaQuery(MenuRecipe.class)
                        .in(MenuRecipe::getRecipeId, recipeIds)).stream()
                        .collect(Collectors.toMap(MenuRecipe::getRecipeId, Function.identity()));
                Map<Long, MenuRecipeDateVO> detailMap = menuRecipeDateVOS1.stream().collect(Collectors.toMap(MenuRecipeDateVO::getRecipeId, Function.identity(), (t1, t2) -> {
                    return t1;
                }));

                AllocRecipeStallVO item;
                long count;
                for(Iterator<AllocRecipeStallVO> var12 = records.iterator(); var12.hasNext(); item.setDishesCount(count)) {
                    item = var12.next();
                    Long recipeId;
                    if (isMeal) {
                        recipeId = maping.get(item.getMealLineId());
                    } else {
                        recipeId = maping.get(item.getStallId());
                    }

                    item.setRecipeId(recipeId);
                    item.setDetail(detailMap.get(recipeId));
                    item.setRecipeName(Optional.ofNullable(recipeMap.get(recipeId)).map(MenuRecipe::getRecipeName).orElse(null));
                    item.setUptime(Optional.ofNullable(recipeMap.get(recipeId)).map(MenuRecipe::getUptime).orElse(null));
                    count = 0L;
                    if (ObjectUtil.isNotEmpty(item.getDetail()) && ObjectUtil.isNotEmpty(item.getDetail().getDetails())) {
                        count = item.getDetail().getDetails().stream().filter((x) -> {
                            return ObjectUtil.isNotEmpty(x.getDishesList());
                        }).flatMap((x) -> {
                            return x.getDishesList().stream();
                        }).map(MenuRecipeDetailDishesVO::getDishesId).distinct().count();
                    }
                }
            }

            return PageVO.of(allocRecipeStallVOPage);
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void editRecipeByTemplate(MenuRecipeDetailEditDTO content) {
        Long recipeId = content.getRecipeId();
        LocalDate applyDate = content.getApplyDate();
        this.changeBaseDishesId(content.getDishesList());
        this.checkDishesList(content.getDishesList());
        MenuRecipe menuRecipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, recipeId));
        Integer recipeType = menuRecipe.getRecipeType();
        MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO = new MenuRecipeDateV2AddDTO();
        menuRecipeDateV2AddDTO.setApplyDate(applyDate);
        menuRecipeDateV2AddDTO.setApplyWeek(applyDate.getDayOfWeek().getValue());
        menuRecipeDateV2AddDTO.setDetailList(Collections.singletonList(content));
        MenuRecipeV2AddDTO menuRecipeV2AddDTO = new MenuRecipeV2AddDTO();
        menuRecipeV2AddDTO.setRecipeDateList(Collections.singletonList(menuRecipeDateV2AddDTO));
        RecipeProcessResult result;
        if (ObjectUtil.equal(recipeType, 3)) {
            result = this.processWeek(menuRecipeV2AddDTO, recipeId, false);
        } else if (ObjectUtil.equal(recipeType, 2)) {
            result = this.processDay(menuRecipeV2AddDTO, recipeId, false);
        } else {
            result = this.processDefault(menuRecipeV2AddDTO, recipeId, false);
        }

        result.setRecipeId(recipeId);
        result.setMenuRecipe(menuRecipe);
        result.setAdd(false);
        this.processResult(result);
    }
    public RecipeProcessResult processDay(MenuRecipeV2AddDTO content, Long recipeId) {
        return this.processDay(content, recipeId, true);
    }

    public RecipeProcessResult processDay(MenuRecipeV2AddDTO content, Long recipeId, Boolean isComplete) {
        RecipeProcessResult result = new RecipeProcessResult();
        List<MenuRecipeDateV2AddDTO> recipeDateList = content.getRecipeDateList();
        GetRecipeDto getRecipeDto = new GetRecipeDto();
        getRecipeDto.setRecipeId(recipeId).setRecipeType(2).setIsComplete(isComplete).setMenuRecipeV2Add(content);
        List<Long> detailIds = this.getTemplateDetailIds(getRecipeDto);
        MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO = recipeDateList.get(0);
        List<MenuRecipeDetailV2AddDTO> detailList = menuRecipeDateV2AddDTO.getDetailList();
        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
        if (ObjectUtil.isNotEmpty(detailList)) {
            String username = SecurityUtils.getUsername();

            for (MenuRecipeDetailV2AddDTO menuRecipeDetailV2AddDTO : detailList) {
                Integer mealtimeType = menuRecipeDetailV2AddDTO.getMealtimeType();
                MenuRecipeDetail detailItem = new MenuRecipeDetail();
                Long detailId = Id.next();
                detailItem.setDetailId(detailId);
                detailItem.setRecipeId(recipeId);
                detailItem.setMealtimeType(mealtimeType);
                detailItem.setCrby(username);
                detailItem.setDetailType(1);
                recipeDetailV2List.add(detailItem);
                List<MenuRecipeDishesV2AddDTO> dishesList = menuRecipeDetailV2AddDTO.getDishesList();
                if (ObjectUtil.isNotEmpty(dishesList)) {
                    this.checkDishesList(dishesList);
                    this.addMenuDishesToList(recipeDishesV2List, detailId, dishesList);
                }
            }
        }

        List<MenuRecipeDetail> menuRecipeDetails = this.getGeNowMenuRecipeDetail(getRecipeDto);
        List<Long> haveDetailIds = menuRecipeDetails.stream().map(MenuRecipeDetail::getDetailId)
                .collect(Collectors.toList());
        this.getDayActiveMenuRecipeDetailDishes(menuRecipeDetails, detailList, recipeDishesV2List, haveDetailIds);
        this.creatLastWeekRecipe(menuRecipeDateV2AddDTO, recipeDishesV2List, recipeDetailV2List, recipeId);
        result.setTemplateDetailIds(detailIds);
        result.setHaveDetailIds(haveDetailIds);
        result.setRecipeDetails(recipeDetailV2List);
        result.setRecipeDishes(recipeDishesV2List);
        return result;
    }

    public RecipeProcessResult processWeek(MenuRecipeV2AddDTO content, Long recipeId) {
        return this.processWeek(content, recipeId, true);
    }
    public RecipeProcessResult processWeek(MenuRecipeV2AddDTO content, Long recipeId, Boolean isComplete) {
        RecipeProcessResult result = new RecipeProcessResult();
        List<MenuRecipeDateV2AddDTO> recipeDateList = content.getRecipeDateList();
        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
        String username = SecurityUtils.getUsername();
        List<Integer> weeks = recipeDateList.stream()
                .map(MenuRecipeDateV2AddDTO::getApplyWeek)
                .collect(Collectors.toList());
        GetRecipeDto getRecipeDto = new GetRecipeDto();
        getRecipeDto.setRecipeId(recipeId).setRecipeType(3).setMenuRecipeV2Add(content).setWeeks(weeks).setIsComplete(isComplete);
        List<Long> detailIds = this.getTemplateDetailIds(getRecipeDto);
        Iterator<MenuRecipeDateV2AddDTO> var12 = recipeDateList.iterator();

        while(true) {
            Integer applyWeek;
            List<MenuRecipeDetailV2AddDTO> detailList;
            do {
                if (!var12.hasNext()) {
                    List<MenuRecipeDetail> menuRecipeDetails = this.getGeNowMenuRecipeDetail(getRecipeDto);
                    List<Long> haveDetailIds = menuRecipeDetails.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
                    this.getActiveMenuRecipeDetailDisnes(menuRecipeDetails, recipeDateList, recipeDishesV2List, haveDetailIds);
                    this.creatLastWeekRecipe(recipeDateList, recipeDishesV2List, recipeDetailV2List, recipeId, weeks);
                    result.setTemplateDetailIds(detailIds);
                    result.setHaveDetailIds(haveDetailIds);
                    result.setRecipeDetails(recipeDetailV2List);
                    result.setRecipeDishes(recipeDishesV2List);
                    return result;
                }
                MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO = var12.next();
                applyWeek = menuRecipeDateV2AddDTO.getApplyWeek();
                detailList = menuRecipeDateV2AddDTO.getDetailList();
            } while(ObjectUtil.isEmpty(detailList));

            for (MenuRecipeDetailV2AddDTO menuRecipeDetailV2AddDTO : detailList) {
                Integer mealtimeType = menuRecipeDetailV2AddDTO.getMealtimeType();
                MenuRecipeDetail detailItem = new MenuRecipeDetail();
                Long detailId = Id.next();
                detailItem.setDetailId(detailId);
                detailItem.setRecipeId(recipeId);
                detailItem.setApplyWeek(applyWeek);
                detailItem.setMealtimeType(mealtimeType);
                detailItem.setCrby(username);
                detailItem.setDetailType(1);
                recipeDetailV2List.add(detailItem);
                List<MenuRecipeDishesV2AddDTO> dishesList = menuRecipeDetailV2AddDTO.getDishesList();
                if (ObjectUtil.isNotEmpty(dishesList)) {
                    this.checkDishesList(dishesList);
                    this.addMenuDishesToList(recipeDishesV2List, detailId, dishesList);
                }
            }
        }
    }
    public List<Long> getTemplateDetailIds(GetRecipeDto getRecipeDto) {
        LambdaQueryWrapper<MenuRecipeDetail> wrapper = Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .select(MenuRecipeDetail::getDetailId)
                .eq(MenuRecipeDetail::getRecipeId, getRecipeDto.getRecipeId())
                .eq(MenuRecipeDetail::getDetailType, 1);
        this.editRecipeWrapper(getRecipeDto, wrapper);
        return this.menuRecipeDetailService.listObjs(wrapper, (item) -> {
            return Long.valueOf(item.toString());
        });
    }
    public void editRecipeWrapper(GetRecipeDto getRecipeDto, LambdaQueryWrapper<MenuRecipeDetail> wrapper) {
        if (ObjectUtil.equal(3, getRecipeDto.getRecipeType())) {
            if (getRecipeDto.getIsComplete()) {
                wrapper.in(MenuRecipeDetail::getApplyWeek, getRecipeDto.getWeeks());
            } else {
                List<MenuRecipeDateV2AddDTO> recipeDateList = getRecipeDto.getMenuRecipeV2Add().getRecipeDateList();
                wrapper.and((x) -> {
                    Iterator<MenuRecipeDateV2AddDTO> var2 = recipeDateList.iterator();
                    while(true) {
                        MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO;
                        do {
                            do {
                                if (!var2.hasNext()) {
                                    return;
                                }
                                menuRecipeDateV2AddDTO = var2.next();
                            } while(ObjectUtil.isEmpty(menuRecipeDateV2AddDTO));
                        } while(ObjectUtil.isEmpty(menuRecipeDateV2AddDTO.getDetailList()));

                        for (MenuRecipeDetailV2AddDTO menuRecipeDetailV2AddDTO : menuRecipeDateV2AddDTO.getDetailList()) {
                            MenuRecipeDateV2AddDTO finalMenuRecipeDateV2AddDTO = menuRecipeDateV2AddDTO;
                            x.or((y) -> {
                                y.eq(MenuRecipeDetail::getApplyWeek, finalMenuRecipeDateV2AddDTO.getApplyWeek());
                                y.eq(MenuRecipeDetail::getMealtimeType, menuRecipeDetailV2AddDTO.getMealtimeType());
                            });
                        }
                    }
                });
            }
        } else if (!getRecipeDto.getIsComplete()) {
            Integer mealType = Optional.ofNullable(getRecipeDto).map(GetRecipeDto::getMenuRecipeV2Add)
                    .map(MenuRecipeV2AddDTO::getRecipeDateList).map((item) -> {
                return item.get(0);
            }).map(MenuRecipeDateV2AddDTO::getDetailList).map((item) -> {
                return item.get(0);
            }).map(MenuRecipeDetailV2AddDTO::getMealtimeType).orElseThrow(() -> {
                return new ServiceException(I18n.getMessage("menu_interval_id_null", new Object[0]));
            });
            wrapper.eq(MenuRecipeDetail::getMealtimeType, mealType);
        }
    }
    public void addMenuDishesToList(List<MenuRecipeDishes> recipeDishesV2List, Long detailId, List<MenuRecipeDishesV2AddDTO> dishesList) {
        for (MenuRecipeDishesV2AddDTO dishesV2AddDTO : dishesList) {
            MenuRecipeDishes dishesItem = BeanUtil.copyProperties(dishesV2AddDTO, MenuRecipeDishes.class, new String[0]);
            dishesItem.setSalePrice(Optional.ofNullable(dishesItem.getSalePrice()).orElse(dishesItem.getPrice()));
            dishesItem.setDetailId(detailId);
            dishesItem.setSurplusNum(dishesV2AddDTO.getSupplyNum());
            recipeDishesV2List.add(dishesItem);
        }
    }
    public List<MenuRecipeDetail> getGeNowMenuRecipeDetail(GetRecipeDto getRecipeDto) {
        LambdaQueryWrapper<MenuRecipeDetail> wrapper = Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getRecipeId, getRecipeDto.getRecipeId())
                .ge(MenuRecipeDetail::getApplyDate, LocalDate.now())
                .eq(MenuRecipeDetail::getDetailType, 2);
        this.editRecipeWrapper(getRecipeDto, wrapper);
        return this.menuRecipeDetailService.list(wrapper);
    }
    public void getActiveMenuRecipeDetailDisnes(List<MenuRecipeDetail> menuRecipeDetails, List<MenuRecipeDateV2AddDTO> recipeDateList, List<MenuRecipeDishes> recipeDishesV2List, List<Long> haveDetailIds) {
        if (!ObjectUtil.isEmpty(menuRecipeDetails)) {
            List<MenuRecipeDishes> menuRecipeDishes = this.menuRecipeDishesService.list(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                    .in(MenuRecipeDishes::getDetailId, haveDetailIds));
            menuRecipeDishes.forEach((dishes) -> {
                dishes.setSizeType((Long)Optional.ofNullable(dishes.getSizeType()).orElse(1L));
            });
            Map<Long, Map<String, MenuRecipeDishes>> dishesMap = menuRecipeDishes.stream()
                    .collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId,
                            Collectors.toMap(this.getDishesUniKeyFunction(), Function.identity())));
            Map<Integer, Map<Integer, Map<Long, MenuRecipeDetail>>> weekAndMealTimeMap = menuRecipeDetails.stream()
                    .collect(Collectors.groupingBy(MenuRecipeDetail::getApplyWeek, Collectors.groupingBy(MenuRecipeDetail::getMealtimeType, Collectors.toMap(MenuRecipeDetail::getDetailId, Function.identity()))));

            for (MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO : recipeDateList) {
                Integer applyWeek = menuRecipeDateV2AddDTO.getApplyWeek();
                List<MenuRecipeDetailV2AddDTO> detailList = menuRecipeDateV2AddDTO.getDetailList();
                Map<Integer, Map<Long, MenuRecipeDetail>> byApplyWeekMap = Optional.ofNullable(weekAndMealTimeMap.get(applyWeek)).orElse(new HashMap());

                for (MenuRecipeDetailV2AddDTO detailV2AddDTO : detailList) {
                    Integer mealtimeType = detailV2AddDTO.getMealtimeType();
                    List<MenuRecipeDishesV2AddDTO> dishesList = detailV2AddDTO.getDishesList();
                    Map<String, MenuRecipeDishesV2AddDTO> editDishesMap =  dishesList.stream().collect(Collectors.toMap(this.getUniKeyFunction(), Function.identity()));
                    Map<Long, MenuRecipeDetail> detailMap = Optional.ofNullable(byApplyWeekMap.get(mealtimeType)).orElse(new HashMap());

                    for (Long detailId : detailMap.keySet()) {
                        Map<String, MenuRecipeDishes> haveDishesMap = Optional.ofNullable(dishesMap.get(detailId)).orElse(new HashMap());
                        for (String dishesFlag : editDishesMap.keySet()) {
                            MenuRecipeDishesV2AddDTO addDishes = editDishesMap.get(dishesFlag);
                            MenuRecipeDishes haveDishes = haveDishesMap.get(dishesFlag);
                            MenuRecipeDishes dishesItem = this.getEditMenuDishes(dishesFlag, addDishes, haveDishes, detailId);
                            recipeDishesV2List.add(dishesItem);
                        }
                    }
                }
            }
        }
    }
    public void creatLastWeekRecipe(MenuRecipeDateV2AddDTO recipeDate, List<MenuRecipeDishes> recipeDishesV2List, List<MenuRecipeDetail> recipeDetailV2List, Long recipeId) {
        if (!ObjectUtil.isEmpty(recipeDate)) {
            String username = SecurityUtils.getUsername();
            LocalDate now = LocalDate.now();
            List<LocalDate> dates = this.getLastWeek();
            List<MenuRecipeDetail> menuRecipeDetails = this.menuRecipeDetailService.getBaseMapper()
                    .selectList(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                            .eq(MenuRecipeDetail::getRecipeId, recipeId)
                            .ge(MenuRecipeDetail::getApplyDate, now)
                            .le(MenuRecipeDetail::getApplyDate, now.plusDays(6L))
                            .eq(MenuRecipeDetail::getDetailType, 2));
            Map<LocalDate, Map<Integer, MenuRecipeDetail>> haveDetail = menuRecipeDetails.stream()
                    .collect(Collectors.groupingBy(MenuRecipeDetail::getApplyDate, Collectors.toMap(MenuRecipeDetail::getMealtimeType, Function.identity())));
            Iterator<LocalDate> var10 = dates.iterator();

            label35:
            while(var10.hasNext()) {
                LocalDate date = var10.next();
                Map<Integer, MenuRecipeDetail> haveDayDetail = Optional.ofNullable(haveDetail.get(date)).orElse(new HashMap());
                List<MenuRecipeDetailV2AddDTO> detailList = recipeDate.getDetailList();
                Iterator<MenuRecipeDetailV2AddDTO> var14 = detailList.iterator();

                while(true) {
                    MenuRecipeDetailV2AddDTO addDetail;
                    Integer mealtimeType;
                    MenuRecipeDetail menuRecipeDetail;
                    do {
                        if (!var14.hasNext()) {
                            continue label35;
                        }
                        addDetail = var14.next();
                        mealtimeType = addDetail.getMealtimeType();
                        menuRecipeDetail = haveDayDetail.get(mealtimeType);
                    } while(!ObjectUtil.isEmpty(menuRecipeDetail));

                    MenuRecipeDetail detailItem = new MenuRecipeDetail();
                    Long detailId = Id.next();
                    detailItem.setDetailId(detailId);
                    detailItem.setRecipeId(recipeId);
                    detailItem.setApplyDate(date);
                    detailItem.setMealtimeType(mealtimeType);
                    detailItem.setCrby(username);
                    recipeDetailV2List.add(detailItem);
                    List<MenuRecipeDishesV2AddDTO> dishesList = addDetail.getDishesList();

                    for (MenuRecipeDishesV2AddDTO menuRecipeDishesV2AddDTO : dishesList) {
                        MenuRecipeDishes dishesItem = BeanUtil.copyProperties(menuRecipeDishesV2AddDTO, MenuRecipeDishes.class, new String[0]);
                        dishesItem.setDetailId(detailId);
                        dishesItem.setSaleNum(0);
                        dishesItem.setSurplusNum(menuRecipeDishesV2AddDTO.getSupplyNum());
                        dishesItem.setSalePrice(Optional.ofNullable(menuRecipeDishesV2AddDTO.getSalePrice()).orElse(menuRecipeDishesV2AddDTO.getPrice()));
                        recipeDishesV2List.add(dishesItem);
                    }
                }
            }

        }
    }
    public void creatLastWeekRecipe(List<MenuRecipeDateV2AddDTO> recipeDateList, List<MenuRecipeDishes> recipeDishesV2List, List<MenuRecipeDetail> recipeDetailV2List, Long recipeId, List<Integer> weeks) {
        if (!ObjectUtil.isEmpty(recipeDateList)) {
            String username = SecurityUtils.getUsername();
            LocalDate now = LocalDate.now();
            HashMap<Integer, LocalDate> dateHashMap = new HashMap<>();

            for(int i = 0; i < 7; ++i) {
                LocalDate applyWeek = now.plusDays((long)i);
                dateHashMap.put(applyWeek.getDayOfWeek().getValue(), applyWeek);
            }

            List<MenuRecipeDetail> menuRecipeDetails = this.menuRecipeDetailService.getBaseMapper()
                    .selectList(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                            .eq(MenuRecipeDetail::getRecipeId, recipeId)
                            .in(MenuRecipeDetail::getApplyWeek, weeks)
                            .ge(MenuRecipeDetail::getApplyDate, now)
                            .le(MenuRecipeDetail::getApplyDate, now.plusDays(6L))
                            .eq(MenuRecipeDetail::getDetailType, 2));
            Map<Integer, Map<Integer, MenuRecipeDetail>> haveDetail = menuRecipeDetails.stream()
                    .collect(Collectors.groupingBy(MenuRecipeDetail::getApplyWeek,
                            Collectors.toMap(MenuRecipeDetail::getMealtimeType, Function.identity())));
            Iterator<MenuRecipeDateV2AddDTO> var11 = recipeDateList.iterator();

            label38:
            while(var11.hasNext()) {
                MenuRecipeDateV2AddDTO menuRecipeDateV2AddDTO = var11.next();
                Integer applyWeek = menuRecipeDateV2AddDTO.getApplyWeek();
                Map<Integer, MenuRecipeDetail> haveWeekDetail = Optional.ofNullable(haveDetail.get(applyWeek)).orElse(new HashMap());
                List<MenuRecipeDetailV2AddDTO> detailList = menuRecipeDateV2AddDTO.getDetailList();
                Iterator<MenuRecipeDetailV2AddDTO> var16 = detailList.iterator();
                while(true) {
                    MenuRecipeDetailV2AddDTO addDetail;
                    Integer mealtimeType;
                    MenuRecipeDetail menuRecipeDetail;
                    do {
                        if (!var16.hasNext()) {
                            continue label38;
                        }
                        addDetail = var16.next();
                        mealtimeType = addDetail.getMealtimeType();
                        menuRecipeDetail = haveWeekDetail.get(mealtimeType);
                    } while(!ObjectUtil.isEmpty(menuRecipeDetail));

                    MenuRecipeDetail detailItem = new MenuRecipeDetail();
                    Long detailId = Id.next();
                    detailItem.setDetailId(detailId);
                    detailItem.setRecipeId(recipeId);
                    detailItem.setApplyWeek(applyWeek);
                    detailItem.setApplyDate(dateHashMap.get(applyWeek));
                    detailItem.setMealtimeType(mealtimeType);
                    detailItem.setCrby(username);
                    recipeDetailV2List.add(detailItem);
                    List<MenuRecipeDishesV2AddDTO> dishesList = addDetail.getDishesList();

                    for (MenuRecipeDishesV2AddDTO menuRecipeDishesV2AddDTO : dishesList) {
                        MenuRecipeDishes dishesItem = BeanUtil.copyProperties(menuRecipeDishesV2AddDTO, MenuRecipeDishes.class, new String[0]);
                        dishesItem.setDetailId(detailId);
                        dishesItem.setSaleNum(0);
                        dishesItem.setSurplusNum(menuRecipeDishesV2AddDTO.getSupplyNum());
                        dishesItem.setSalePrice(Optional.ofNullable(menuRecipeDishesV2AddDTO.getSalePrice()).orElse(menuRecipeDishesV2AddDTO.getPrice()));
                        recipeDishesV2List.add(dishesItem);
                    }
                }
            }

        }
    }

    public List<LocalDate> getLastWeekDate() {
        List<LocalDate> objects = new ArrayList();
        LocalDate sunday = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        LocalDate now = LocalDate.now();
        for(LocalDate date = now; date.isBefore(sunday) || date.isEqual(sunday); date = date.plusDays(1L)) {
            objects.add(date);
        }
        return objects;
    }
    public List<LocalDate> getLastWeek() {
        List<LocalDate> dates = new ArrayList();
        LocalDate now = LocalDate.now();
        for(int i = 0; i < 7; ++i) {
            dates.add(now.plusDays((long)i));
        }
        return dates;
    }
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void addDishesByDate(AddDishes2RecipeDto content) {
        Long recipeId = content.getRecipeId();
        List<AddDishes2RecipeDateDto> dates = content.getDates();
        Map<LocalDate, Map<Integer, Integer>> editMap = dates.stream().collect(Collectors.groupingBy(AddDishes2RecipeDateDto::getApplyDate, Collectors.toMap(AddDishes2RecipeDateDto::getMealType, AddDishes2RecipeDateDto::getAdd, (x, y) -> {
            return x;
        })));
        Map<LocalDate, Set<Integer>> dateMealTypeMap = dates.stream().collect(Collectors.groupingBy(AddDishes2RecipeDateDto::getApplyDate, Collectors.mapping(AddDishes2RecipeDateDto::getMealType, Collectors.toSet())));
        Map<LocalDate, Set<Integer>> addDateMealTypeMap = dates.stream().filter((x) -> {
            return ObjectUtil.equal(1, x.getAdd());
        }).collect(Collectors.groupingBy(AddDishes2RecipeDateDto::getApplyDate, Collectors.mapping(AddDishes2RecipeDateDto::getMealType, Collectors.toSet())));
        this.changeBaseDishesId(content.getDishesList());
        MenuRecipe menuRecipe = (MenuRecipe)this.getOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, recipeId));
        LambdaQueryWrapper<MenuRecipeDetail> wrapper =Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getDetailType, 2)
                .eq(MenuRecipeDetail::getRecipeId, recipeId);
        wrapper.and((x) -> {

            for (LocalDate localDate : dateMealTypeMap.keySet()) {
                x.or((y) -> {
                    Set<Integer> mealTypes = dateMealTypeMap.get(localDate);
                    y.eq(MenuRecipeDetail::getApplyDate, localDate);
                    y.in(MenuRecipeDetail::getMealtimeType, mealTypes);
                });
            }

        });
        List<MenuRecipeDetail> details = this.menuRecipeDetailService.list(wrapper);
        Map<Long, MenuRecipeDishesV2AddDTO> addDishesMap = content.getDishesList().stream().collect(Collectors.toMap(MenuRecipeDishesV2AddDTO::getDishesId, Function.identity()));
        Map<LocalDate, Map<Integer, MenuRecipeDetail>> detailMap = new HashMap();
        Map<Long, Map<Long, MenuRecipeDishes>> detailDishesMap = new HashMap();
        if (ObjectUtil.isNotEmpty(details)) {
            Map<Boolean, List<MenuRecipeDetail>> addOrDeleteMap = details.stream().collect(Collectors.groupingBy((x) -> {
                return (Boolean)Optional.ofNullable((Map)editMap.get(x.getApplyDate())).map((item) -> {
                    return (Integer)item.get(x.getMealtimeType());
                }).map((item) -> {
                    return ObjectUtil.equal(1, item);
                }).orElse(true);
            }));
            List<MenuRecipeDetail> addDetails = addOrDeleteMap.getOrDefault(true, new ArrayList());
            List<MenuRecipeDetail> deleteDetails = addOrDeleteMap.get(false);
            detailMap = addDetails.stream().collect(Collectors.groupingBy(MenuRecipeDetail::getApplyDate, Collectors.groupingBy(MenuRecipeDetail::getMealtimeType, Collectors.collectingAndThen(Collectors.toList(), (value) -> {
                return value.get(0);
            }))));
            List<Long> detailIds = addDetails.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
            List<Long> list;
            if (ObjectUtil.isNotEmpty(deleteDetails)) {
                list = deleteDetails.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
                this.menuRecipeDishesService.remove(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                        .in(MenuRecipeDishes::getDetailId, list)
                        .in(MenuRecipeDishes::getDishesId, addDishesMap.keySet()));
            }

            if (ObjectUtil.isNotEmpty(detailIds)) {
               List<MenuRecipeDishes> list1 = this.menuRecipeDishesService.list(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                        .in(MenuRecipeDishes::getDishesId, addDishesMap.keySet())
                        .in(MenuRecipeDishes::getDetailId, detailIds));
                detailDishesMap = list1.stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId, Collectors.groupingBy(MenuRecipeDishes::getDishesId, Collectors.collectingAndThen(Collectors.toList(), (value) -> {
                    return value.get(0);
                }))));
            }
        }

        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
        List<Long> ids = Lists.newArrayList();
        String username = SecurityUtils.getUsername();
        Iterator var34 = addDateMealTypeMap.entrySet().iterator();

        while(var34.hasNext()) {
            Map.Entry<LocalDate, Set<Integer>> entry = (Map.Entry)var34.next();
            LocalDate date = (LocalDate)entry.getKey();
            Map<Integer, MenuRecipeDetail> dayMap = (Map)((Map)detailMap).getOrDefault(date, new HashMap());
            Iterator var21 = ((Set)entry.getValue()).iterator();

            while(var21.hasNext()) {
                Integer mealType = (Integer)var21.next();
                MenuRecipeDetail menuRecipeDetail = (MenuRecipeDetail)dayMap.get(mealType);
                if (ObjectUtil.isEmpty(menuRecipeDetail)) {
                    menuRecipeDetail = new MenuRecipeDetail();
                    Long detailId = Id.next();
                    menuRecipeDetail.setApplyDate(date);
                    menuRecipeDetail.setDetailId(detailId);
                    menuRecipeDetail.setRecipeId(recipeId);
                    menuRecipeDetail.setMealtimeType(mealType);
                    menuRecipeDetail.setCrby(username);
                    menuRecipeDetail.setDetailType(2);
                    recipeDetailV2List.add(menuRecipeDetail);
                }

                Map<Long, MenuRecipeDishes> dishesMap = (Map)((Map)detailDishesMap).getOrDefault(menuRecipeDetail.getDetailId(), new HashMap());
                Iterator var25 = addDishesMap.keySet().iterator();

                while(var25.hasNext()) {
                    Long dishesId = (Long)var25.next();
                    MenuRecipeDishes menuRecipeDishes = (MenuRecipeDishes)dishesMap.get(dishesId);
                    MenuRecipeDishesV2AddDTO addDishes = (MenuRecipeDishesV2AddDTO)addDishesMap.get(dishesId);
                    if (ObjectUtil.isNotEmpty(menuRecipeDishes)) {
                        ids.add(menuRecipeDishes.getId());
                    } else {
                        menuRecipeDishes = new MenuRecipeDishes();
                    }

                    MenuRecipeDishes addMenuRecipe = this.getEditMenuDishes("" + dishesId + "_", addDishes, menuRecipeDishes, menuRecipeDetail.getDetailId());
                    recipeDishesV2List.add(addMenuRecipe);
                }
            }
        }

        RecipeProcessResult result = new RecipeProcessResult();
        result.setAdd(false);
        result.setMenuRecipe(menuRecipe);
        result.setRecipeId(recipeId);
        result.setRecipeDetails(recipeDetailV2List);
        result.setRecipeDishes(recipeDishesV2List);
        if (ObjectUtil.isNotEmpty(ids)) {
            this.menuRecipeDishesService.removeByIds(ids);
        }

        this.processResult(result);
    }

    @Override
    public List<ExistDateVo> queryDishesByDate(QueryDishes2RecipeDto content) {
        MenuRecipeDishesV2AddDTO menuRecipeDishesV2AddDTO = new MenuRecipeDishesV2AddDTO();
        menuRecipeDishesV2AddDTO.setDishesId(content.getDishesId());
        menuRecipeDishesV2AddDTO.setSizeType(content.getSizeType());
        this.changeBaseDishesId(Collections.singletonList(menuRecipeDishesV2AddDTO));
        Map<LocalDate, Set<Integer>> localDateSetMap = this.menuRecipeDishesService.queryDishesByDate(content.getDates(), content.getRecipeId(), menuRecipeDishesV2AddDTO.getDishesId());
        return localDateSetMap.keySet().stream().map((item) -> {
            ExistDateVo existDateVo = new ExistDateVo();
            existDateVo.setApplyDate(item);
            existDateVo.setMealType(localDateSetMap.get(item));
            return existDateVo;
        }).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = {Exception.class})
    public synchronized void generateRecipe(List<Long> recipeIdList, LocalDate applyDate) {
        if (!ObjectUtil.isEmpty(recipeIdList) && !ObjectUtil.isEmpty(applyDate)) {
            recipeIdList = new ArrayList(recipeIdList);
            Map<Long, Long> recipeDetailContMap = (Map) this.menuRecipeDetailService.list((Wrapper<MenuRecipeDetail>) ((LambdaQueryWrapper<MenuRecipeDetail>) Wrappers.lambdaQuery(MenuRecipeDetail.class).select(MenuRecipeDetail::getRecipeId).eq(MenuRecipeDetail::getApplyDate, applyDate)).in(MenuRecipeDetail::getRecipeId, recipeIdList)).stream().collect(Collectors.groupingBy(MenuRecipeDetail::getRecipeId, Collectors.counting()));
            recipeIdList.removeAll(recipeDetailContMap.keySet());
            if (!ObjectUtil.isEmpty(recipeIdList)) {
                List<MenuRecipe> menuRecipes = this.list((Wrapper) ((LambdaQueryWrapper) Wrappers.lambdaQuery(MenuRecipe.class).in(MenuRecipe::getRecipeType, new Object[]{2, 3})).apply(CollUtil.isNotEmpty(recipeIdList), "recipe_id IN (" + recipeIdList.stream().map(String::valueOf).collect(Collectors.joining(", ")) + ")"));
                if (!ObjectUtil.isEmpty(menuRecipes)) {
                    Map<Long, MenuRecipe> recipeMap = (Map) menuRecipes.stream().collect(Collectors.toMap(MenuRecipe::getRecipeId, Function.identity()));
                    List<MenuRecipeDetail> menuRecipeDetails = this.menuRecipeDetailService.list((Wrapper) ((LambdaQueryWrapper) Wrappers.lambdaQuery(MenuRecipeDetail.class).eq(MenuRecipeDetail::getDetailType, 1)).apply(CollUtil.isNotEmpty(recipeIdList), "recipe_id IN (" + recipeIdList.stream().map(String::valueOf).collect(Collectors.joining(", ")) + ")"));
                    Map<Long, Integer> recipeTypeMap = (Map) menuRecipes.stream().collect(Collectors.toMap(MenuRecipe::getRecipeId, MenuRecipe::getRecipeType));
                    menuRecipeDetails = this.filterMenuRecipeDetails(recipeTypeMap, menuRecipeDetails, applyDate);
                    if (!ObjectUtil.isEmpty(menuRecipeDetails)) {
                        Map<Long, List<MenuRecipeDetail>> detailMap = (Map) menuRecipeDetails.stream().collect(Collectors.groupingBy(MenuRecipeDetail::getRecipeId));
                        List<Long> detailIds = (List) menuRecipeDetails.stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
                        Map<Long, List<MenuRecipeDishes>> recipeDishes = (Map) this.menuRecipeDishesService.list((Wrapper) Wrappers.lambdaQuery(MenuRecipeDishes.class).in(MenuRecipeDishes::getDetailId, detailIds)).stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId));
                        List<MenuRecipeDetail> recipeDetailV2List = Lists.newArrayList();
                        List<MenuRecipeDishes> recipeDishesV2List = Lists.newArrayList();
                        Iterator var13 = recipeMap.keySet().iterator();

                        label59:
                        while (true) {
                            Long recipeId;
                            Integer type;
                            List menuRecipeDetail;
                            do {
                                if (!var13.hasNext()) {
                                    this.menuRecipeDetailService.saveBatch(recipeDetailV2List);
                                    if (ObjectUtil.isNotEmpty(recipeDishesV2List)) {
                                        this.menuRecipeDishesService.saveBatch(recipeDishesV2List);
                                    }
                                    return;
                                }
                                recipeId = (Long) var13.next();
                                type = (Integer) recipeTypeMap.get(recipeId);
                                menuRecipeDetail = (List) detailMap.get(recipeId);
                            } while (!ObjectUtil.isNotEmpty(menuRecipeDetail));
                            Iterator var17 = menuRecipeDetail.iterator();
                            while (true) {
                                Long detailId;
                                List dishes;
                                do {
                                    if (!var17.hasNext()) {
                                        continue label59;
                                    }
                                    MenuRecipeDetail recipeDetail = (MenuRecipeDetail) var17.next();
                                    MenuRecipeDetail detailItem = new MenuRecipeDetail();
                                    detailId = Id.next();
                                    detailItem.setDetailId(detailId);
                                    detailItem.setRecipeId(recipeId);
                                    if (ObjectUtil.equal(type, 3)) {
                                        detailItem.setApplyWeek(applyDate.getDayOfWeek().getValue());
                                    }
                                    detailItem.setApplyDate(applyDate);
                                    detailItem.setMealtimeType(recipeDetail.getMealtimeType());
                                    detailItem.setCrby("");
                                    detailItem.setDetailType(2);
                                    recipeDetailV2List.add(detailItem);
                                    dishes = (List) recipeDishes.get(recipeDetail.getDetailId());
                                } while (!ObjectUtil.isNotEmpty(dishes));
                                Iterator var22 = dishes.iterator();
                                while (var22.hasNext()) {
                                    MenuRecipeDishes dish = (MenuRecipeDishes) var22.next();
                                    MenuRecipeDishes dishesItem = (MenuRecipeDishes) BeanUtil.copyProperties(dish, MenuRecipeDishes.class, new String[0]);
                                    dishesItem.setDetailId(detailId);
                                    dishesItem.setId((Long) null);
                                    recipeDishesV2List.add(dishesItem);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    public void generateRecipe(Long recipeId, LocalDate beginDate, LocalDate endDate) {
        for(LocalDate date = beginDate; date.isBefore(endDate) || date.isEqual(endDate); date = date.plusDays(1L)) {
            this.generateRecipe(recipeId, date);
        }

    }
    public List<MenuRecipeDetail> filterMenuRecipeDetails(Map<Long, Integer> recipeTypeMap, List<MenuRecipeDetail> menuRecipeDetails, LocalDate applyDate) {
        return menuRecipeDetails.stream().filter((item) -> {
            Long recipeId = item.getRecipeId();
            Integer type = (Integer) recipeTypeMap.get(recipeId);
            if (type == 3) {
                return ObjectUtil.equal(item.getApplyWeek(), applyDate.getDayOfWeek().getValue());
            } else {
                return type == 2;
            }
        }).collect(Collectors.toList());
    }

    @Override
    public Set<Long> changeSurplusNum(List<MenuRecipeChangeSurplusNum> changeSurplusNumList, Long custId, Integer mealtimeType,
                                      LocalDate ordGoodsDate) {
        this.checkChangeSurplusNum(changeSurplusNumList, ordGoodsDate, mealtimeType);
        Set<Long> goodIdSet = new HashSet();
        log.info("[扣减库存]_custId:{}, mealtimeType: {}, ordGoodsDate: {}", new Object[]{custId, mealtimeType, ordGoodsDate});
        List<OrderGoodsNumVO> custQuantityList = Lists.newArrayList();
        if (ObjectUtil.isNotNull(custId) && ObjectUtil.isNotNull(mealtimeType) && ObjectUtil.isNotNull(ordGoodsDate)) {
            custQuantityList = this.orderMenuApi.getQuantityByCustId(custId, mealtimeType, ordGoodsDate);
        }

        List<MenuRecipeChangeDetail> updateDetailList = Lists.newArrayList();
        Iterator var8 = changeSurplusNumList.iterator();

        while (var8.hasNext()) {
            MenuRecipeChangeSurplusNum changeSurplusNum = (MenuRecipeChangeSurplusNum) var8.next();
            Integer saleNum = changeSurplusNum.getSaleNum();
            Long detailId = changeSurplusNum.getDetailId();
            Long productId = changeSurplusNum.getProductId();
            log.info("***接收到的变更库存数量参数详情changeSurplusNum : {}*******************", changeSurplusNum);
            log.info("***下单请求售出菜品 : {} 份", saleNum);
            MenuRecipeDishes recipeDishes = this.menuRecipeDishesMapper.selectOne(Wrappers
                    .lambdaQuery(MenuRecipeDishes.class).eq(MenuRecipeDishes::getDetailId, detailId)
                    .eq(MenuRecipeDishes::getDishesId, productId));
            Integer originalSaleNum = recipeDishes.getSaleNum();
            Integer surplusNum = recipeDishes.getSurplusNum();
            log.info("***扣减库存当前detailId: {},productId: {},剩余库存数量surplusNum: {}", new Object[]{detailId, productId, surplusNum});
            Integer restrictNum = recipeDishes.getRestrictNum();
            int historySaleNum = 0;
            if (ObjectUtil.isNotEmpty(custQuantityList)) {
                List<OrderGoodsNumVO> historyList = (custQuantityList).stream().filter((o) -> {
                    return productId.equals(o.getGoodsDishesId());
                }).collect(Collectors.toList());
                if (ObjectUtil.isNotEmpty(historyList)) {
                    historySaleNum = (historyList.get(0)).getQuantity();
                }
            }

            if (restrictNum < saleNum + historySaleNum) {
                log.info("***下单数量 {} 超出个人限购数量 {}", saleNum, restrictNum);
                goodIdSet.add(productId);
            } else if (surplusNum < saleNum) {
                log.info("***下单数量 {} 超出库存 {}", saleNum, surplusNum);
                goodIdSet.add(productId);
            } else {
                Integer newSaleNum = originalSaleNum + saleNum;
                Integer newSurplusNum = surplusNum - saleNum;
                MenuRecipeDishes newRecipeDishes = new MenuRecipeDishes();
                newRecipeDishes.setId(recipeDishes.getId());
                newRecipeDishes.setSaleNum(newSaleNum);
                newRecipeDishes.setSurplusNum(newSurplusNum);
                MenuRecipeChangeDetail recipeChangeDetail = new MenuRecipeChangeDetail();
                recipeChangeDetail.setId(recipeDishes.getId());
                recipeChangeDetail.setSaleNum(saleNum);
                recipeChangeDetail.setProductId(productId);
                recipeChangeDetail.setShopstallId(((MenuRecipeMapper) this.baseMapper).selectShopstallIdByDetailId(detailId));
                updateDetailList.add(recipeChangeDetail);
            }
        }

        if (ObjectUtil.isEmpty(goodIdSet) && ObjectUtil.isNotEmpty(updateDetailList)) {
            TransactionStatus transaction = this.dataSourceTransactionManager.getTransaction(this.transactionDefinition);
            Iterator var24 = updateDetailList.iterator();

            while (var24.hasNext()) {
                MenuRecipeChangeDetail updateDetail = (MenuRecipeChangeDetail) var24.next();

                try {
                    this.menuRecipeDishesMapper.updateNumById(updateDetail.getId(), updateDetail.getSaleNum());
                    MenuDishesSaleRecord sourceRecord = this.menuDishesSaleRecordMapper
                            .selectOne(Wrappers.lambdaQuery(MenuDishesSaleRecord.class)
                                    .eq(MenuDishesSaleRecord::getDishesId, updateDetail.getProductId())
                                    .eq(MenuDishesSaleRecord::getStallId, updateDetail.getShopstallId()));
                    if (!ObjectUtil.isNotNull(sourceRecord)) {
                        MenuDishesSaleRecord item = new MenuDishesSaleRecord();
                        item.setDishesId(updateDetail.getProductId());
                        item.setStallId(updateDetail.getShopstallId());
                        item.setSaleNum(updateDetail.getSaleNum());
                        item.setMonthlySales(updateDetail.getSaleNum());
                        item.setSaleMonth(LocalDate.now().getMonthValue());
                        item.setEvaluateNum(0);
                        item.setEvaluateLevel(BigDecimal.ZERO);
                        item.setGoodProbability(BigDecimal.ZERO);
                        item.setUpdateTime(LocalDateTime.now());
                        this.menuDishesSaleRecordMapper.insert(item);
                    } else {
                        int monthValue = LocalDate.now().getMonthValue();
                        if (ObjectUtil.isNull(sourceRecord.getSaleMonth()) || sourceRecord.getSaleMonth() != monthValue) {
                            MenuDishesSaleRecord updateMonth = new MenuDishesSaleRecord();
                            updateMonth.setId(sourceRecord.getId());
                            updateMonth.setSaleMonth(monthValue);
                            updateMonth.setMonthlySales(0);
                            this.menuDishesSaleRecordMapper.updateById(updateMonth);
                        }

                        this.menuDishesSaleRecordMapper.updateSaleNum(updateDetail.getProductId(), updateDetail.getShopstallId(), updateDetail.getSaleNum());
                    }
                } catch (Exception var22) {
                    this.dataSourceTransactionManager.rollback(transaction);
                    goodIdSet.add(updateDetail.getProductId());
                    return goodIdSet;
                }
            }

            this.dataSourceTransactionManager.commit(transaction);
        }

        return goodIdSet;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Long addMenuRecipeV2(MenuRecipeV2AddDTO content) {
        this.changeBaseDishesIdTo(content);
        Long recipeId = content.getRecipeId();
        String username = SecurityUtils.getUsername();
        Integer recipeType = content.getRecipeType();
        MenuRecipe recipe;
        Boolean add;
        if (ObjectUtil.isNull(recipeId)) {
            Long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(MenuRecipe.class)
                    .eq(MenuRecipe::getRecipeName, content.getRecipeName())
                    .eq(MenuRecipe::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
            if (ObjectUtil.isNotNull(count) && count > 0L) {
                throw new ServiceException(I18n.getMessage("menu_recipe_name_repeat", new Object[0]));
            }

            recipeId = Id.next();
            recipe = new MenuRecipe();
            recipe.setRecipeId(recipeId);
            recipe.setRecipeType(content.getRecipeType());
            recipe.setRecipeName(content.getRecipeName());
            recipe.setCanteenId(ObjectUtil.isNull(content.getCanteenId()) ? -1L : content.getCanteenId());
            recipe.setStallId(ObjectUtil.isNull(content.getStallId()) ? -1L : content.getStallId());
            recipe.setEffId(ObjectUtil.isNull(content.getEffId()) ? -1L : content.getEffId());
            recipe.setCrby(username);
            this.baseMapper.insert(recipe);
            add = true;
        } else {
            recipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, recipeId));
            recipe.setRecipeName(content.getRecipeName());
            recipe.setEffId(content.getEffId());
            recipeType = recipe.getRecipeType();
            add = false;
        }

        if (ObjectUtil.isEmpty(content.getRecipeDateList())) {
            return recipeId;
        } else {
            RecipeProcessResult result;
            if (ObjectUtil.equal(recipeType, 3)) {
                result = this.processWeek(content, recipeId);
            } else if (ObjectUtil.equal(recipeType, 2)) {
                result = this.processDay(content, recipeId);
            } else {
                result = this.processDefault(content, recipeId);
            }

            result.setRecipeId(recipeId);
            result.setMenuRecipe(recipe);
            result.setAdd(add);
            this.processResult(result);
            return recipeId;
        }
    }
    public void changeBaseDishesIdTo(MenuRecipeV2AddDTO content) {
        List<MenuRecipeDateV2AddDTO> recipeDateList = content.getRecipeDateList();
        if (!ObjectUtil.isEmpty(recipeDateList)) {
            List<MenuRecipeDishesV2AddDTO> menuRecipeDishesV2AddDTOS = recipeDateList.stream().filter((x) -> {
                return ObjectUtil.isNotEmpty(x.getDetailList());
            }).flatMap((x) -> {
                return x.getDetailList().stream();
            }).filter((x) -> {
                return ObjectUtil.isNotEmpty(x.getDishesList());
            }).flatMap((x) -> {
                return x.getDishesList().stream();
            }).collect(Collectors.toList());
            this.changeBaseDishesId(menuRecipeDishesV2AddDTOS);
        }
    }
    @Override
    public Page<MenuRecipeV2PageVO> getMenuRecipeV2Page(MenuRecipeV2PageDTO content) {
        Page<MenuRecipeV2PageVO> resultPage = new Page(content.getCurrent(), content.getSize());
        MgrUserAuthPO authPO = this.mgrAuthApi.getUserAuthPO();
        log.info("获取登录用户权限authPO: {}", authPO);
        resultPage = this.baseMapper.selectAllRecipeV2List(resultPage, content, DelFlagEnum.DEL_FALSE.key(), authPO);
        List<MenuRecipeV2PageVO> records = resultPage.getRecords();
        List<LocalDate> last = this.getLastWeekDate();
        if (ObjectUtil.isNotEmpty(records)) {
            List<Long> recipeIds = records.stream().map(MenuRecipeV2PageVO::getRecipeId).collect(Collectors.toList());
            Map<Long, Integer> dishesCountByRecipeIds = this.menuRecipeDishesService.getDishesCountByRecipeIds(recipeIds);
            Map<Long, Set<LocalDate>> recipeDates = this.menuRecipeDetailService.selectApplyDateListByRecipeId(recipeIds);
            records.forEach((r) -> {
                Long recipeId = r.getRecipeId();
                r.setDishesCount(dishesCountByRecipeIds.getOrDefault(recipeId, 0));
                Set<LocalDate> applyDateList = recipeDates.getOrDefault(recipeId, new HashSet());
                List<LocalDate> finalDate;
                if (ObjectUtil.equal(r.getRecipeType(), 3)) {
                    Stream<LocalDate> var10000 = last.stream();
                    Objects.requireNonNull(applyDateList);
                    finalDate = var10000.filter(applyDateList::contains).collect(Collectors.toList());
                } else if (ObjectUtil.equal(r.getRecipeType(), 2)) {
                    finalDate = this.getLastWeek();
                } else {
                    finalDate = new ArrayList<>(applyDateList);
                }

                List<String> applyDateStringList = Lists.newArrayList();
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd");
                finalDate.forEach((d) -> {
                    applyDateStringList.add(dateTimeFormatter.format(d));
                });
                r.setApplyDateList(finalDate);
                r.setApplyDateStringList(applyDateStringList);
            });
        }

        return resultPage;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void removeByRecipeId(List<Long> recipeIds) {
        Integer recipeMacBindNumber = this.deviceApi.getRecipeBindCount(recipeIds);
        if (recipeMacBindNumber > 0) {
            throw new ServiceException(I18n.getMessage("menu_recipe_mac_bind_del", new Object[0]));
        } else if (this.menuAppRecipeMapper.exists(Wrappers.lambdaQuery(MenuAppRecipe.class)
                .in(MenuAppRecipe::getRecipeId, recipeIds))) {
            throw new ServiceException(I18n.getMessage("menu_recipe_applet_bind_del", new Object[0]));
        } else {
            this.baseMapper.update(null, Wrappers.lambdaUpdate(MenuRecipe.class)
                    .in(MenuRecipe::getRecipeId, recipeIds)
                    .set(MenuRecipe::getDelFlag, DelFlagEnum.DEL_TRUE.key()));
            List<Long> detailIdList = this.menuRecipeDetailMapper
                    .selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                            .in(MenuRecipeDetail::getRecipeId, recipeIds));
            if (ObjectUtil.isNotEmpty(detailIdList)) {
                this.menuRecipeDetailMapper.delete(Wrappers.lambdaQuery(MenuRecipeDetail.class).in(MenuRecipeDetail::getDetailId, detailIdList));
                this.menuRecipeDishesMapper.delete(Wrappers.lambdaQuery(MenuRecipeDishes.class).in(MenuRecipeDishes::getDetailId, detailIdList));
            }

            for (Long recipeId : recipeIds) {
                String redisKey = String.format("yst:%s:recipe:%s:detail:%s", TenantContextHolder.getTenantId(), recipeId, "*");
                RedisUtil.deleteByPattern(redisKey);
                MqUtil.sendDataChange(recipeId, LeMqConstant.DataChangeType.REMOVE, LeMqConstant.Topic.DATA_CHANGE_RECIPE);
            }

        }
    }

    @Override
    public void removeDetailByRecipeId(MenuRecipeDetailRemoveDTO content) {
        MenuRecipe menuRecipe = this.getOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId()));
        List<Long> detailIdList;
        List<Long> detailIdListByWrapper;
        if (ObjectUtil.equal(menuRecipe.getRecipeType(), 3)) {
            detailIdList = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .ge(MenuRecipeDetail::getApplyDate, LocalDate.now())
                    .eq(MenuRecipeDetail::getApplyWeek, content.getApplyWeek())
                    .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId()));
            detailIdListByWrapper = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .ge(MenuRecipeDetail::getDetailType, 1)
                    .eq(MenuRecipeDetail::getApplyWeek, content.getApplyWeek())
                    .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId()));
            detailIdList.addAll(detailIdListByWrapper);
        } else if (ObjectUtil.equal(menuRecipe.getRecipeType(), 2)) {
            detailIdList = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .ge(MenuRecipeDetail::getApplyDate, LocalDate.now())
                    .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId()));
            detailIdListByWrapper = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .ge(MenuRecipeDetail::getDetailType, 1)
                    .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId()));
            detailIdList.addAll(detailIdListByWrapper);
        } else {
            detailIdList = this.menuRecipeDetailMapper.selectDetailIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .eq(MenuRecipeDetail::getApplyDate, content.getApplyDate())
                    .eq(MenuRecipeDetail::getRecipeId, content.getRecipeId()));
        }

        if (ObjectUtil.isNotEmpty(detailIdList)) {
            this.menuRecipeDetailMapper.delete(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                    .in(MenuRecipeDetail::getDetailId, detailIdList));
            this.menuRecipeDishesMapper.delete(Wrappers.lambdaQuery(MenuRecipeDishes.class)
                    .in(MenuRecipeDishes::getDetailId, detailIdList));
        }

        this.update(Wrappers.lambdaUpdate(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId())
                .set(MenuRecipe::getUptime, LocalDateTime.now()));
    }
    @Override
    public Page<MenuRecipeDetailV2PageVO> getMenuRecipeDetailV2Page(MenuRecipeDetailV2PageDTO content) {
        Page<MenuRecipeDetailV2PageVO> resultPage = new Page(content.getCurrent(), content.getSize());
        resultPage = this.menuRecipeDetailMapper.selectDetailDateByRecipeId(resultPage, content.getRecipeId(), LocalDate.now());
        List<MenuRecipeDetailV2PageVO> records = resultPage.getRecords();
        if (ObjectUtil.isNotEmpty(records)) {
            records.forEach((r) -> {
                List<Integer> mealtimeTypeList = this.menuRecipeDetailMapper.selectIntervalNameListByRecipeId(r.getRecipeId(), r.getApplyDate());
                List<String> mealtimeNameList = Lists.newArrayList();
                if (ObjectUtil.isNotEmpty(mealtimeTypeList)) {
                    mealtimeTypeList.forEach((m) -> {
                        mealtimeNameList.add(AllocMealtimeTypeEnum.getDescByKey(m));
                    });
                }

                r.setMealtimeNameList(mealtimeNameList);
            });
        }

        return resultPage;
    }


    @Override
    public List<MenuRecipeDetailDateVO> getMenuRecipeDateDetail(MenuRecipeDetailDateDTO content) {
        this.generateRecipe(content.getRecipeId(), content.getApplyDate());
        List<MenuRecipeDetailDateVO> menuRecipeDetailDateVOS = this.menuRecipeDetailMapper.selectDateDetailList(content.getRecipeId(), content.getApplyDate());
        return menuRecipeDetailDateVOS.stream().sorted(Comparator.comparing(MenuRecipeDetailDateVO::getMealtimeType)).collect(Collectors.toList());
    }

    @Override
    public void addMenuRecipeV2Copy(MenuRecipeV2AddCopyDTO content) {
        String username = SecurityUtils.getUsername();
        List<MenuRecipeDetail> insertRecipeDetailList = this.menuRecipeDetailMapper.selectSourceDetailByWrapper(Wrappers.lambdaQuery(MenuRecipeDetail.class)
                .eq(MenuRecipeDetail::getRecipeId, content.getSourceRecipeId())
                .eq(MenuRecipeDetail::getApplyDate, content.getSourceApplyDate()));
        if (ObjectUtil.isEmpty(insertRecipeDetailList)) {
            throw new ServiceException(I18n.getMessage("menu_source_recipe_no_detail", new Object[0]));
        } else {
            List<MenuRecipeDishes> insertRecipeDishesList = Lists.newArrayList();
            insertRecipeDetailList.forEach((d) -> {
                List<LocalDate> targetApplyDateList = content.getTargetApplyDateList();
                targetApplyDateList.forEach((targetApplyDate) -> {
                    Long detailId = Id.next();
                    Long sourceDetailId = d.getDetailId();
                    d.setDetailId(detailId);
                    d.setRecipeId(content.getTargetRecipeId());
                    d.setApplyDate(targetApplyDate);
                    d.setCrby(username);
                    List<MenuRecipeDishes> tempRecipeDishesList = this.menuRecipeDishesMapper.selectSourceDishesByWrapper(Wrappers.lambdaQuery(MenuRecipeDishes.class).eq(MenuRecipeDishes::getDetailId, sourceDetailId));
                    if (ObjectUtil.isNotEmpty(tempRecipeDishesList)) {
                        tempRecipeDishesList.forEach((rd) -> {
                            rd.setDetailId(detailId);
                            rd.setSaleNum(0);
                            rd.setSurplusNum(rd.getSupplyNum());
                            rd.setCrby(username);
                        });
                        insertRecipeDishesList.addAll(tempRecipeDishesList);
                    }

                });
            });
            this.update(Wrappers.lambdaUpdate(MenuRecipe.class)
                    .eq(MenuRecipe::getRecipeId, content.getTargetRecipeId())
                    .set(MenuRecipe::getUptime, LocalDateTime.now()));
            this.menuRecipeDetailService.saveBatch(insertRecipeDetailList);
            this.menuRecipeDishesService.saveBatch(insertRecipeDishesList);
        }
    }

    @Override
    public List<MenuRecipeDetailV2VO> getMenuRecipeDetailById(MenuRecipeDetailV2DTO content) {
        return this.menuRecipeDetailMapper.selectRecipeDetailByIdPc(content.getRecipeId());
    }

    @Override
    public void editRecipeBase(MenuRecipeV2EditDTO content) {
        this.baseMapper.update(null,Wrappers.lambdaUpdate(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId())
                .set(MenuRecipe::getRecipeName, content.getRecipeName())
                .set(MenuRecipe::getEffId, content.getEffId()));
    }
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void bindAppRecipe(MenuRecipeBindDTO content) {
        MenuRecipe menuRecipe = this.baseMapper.selectOne(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, content.getRecipeId()));
        MenuRecipeSortEnum sortEnum = MenuRecipeSortEnum.getBindTypeMap().get(content.getBindType());
        if (ObjectUtil.isEmpty(sortEnum)) {
            throw new ServiceException(I18n.getMessage("menu_bind_not_type", new Object[0]));
        } else {
            List<Integer> deviceTypes = sortEnum.getDeviceType();
            if (content.getHandleType().equals(1)) {
                boolean exists;
                if (MenuBindTypeEnum.RESERVE.key().equals(content.getBindType())) {
                    exists = this.allocCanteenApi.checkCanteenIfReserve(menuRecipe.getCanteenId(), menuRecipe.getStallId());
                    if (!exists) {
                        throw new ServiceException(I18n.getMessage("menu_recipe_canteen_not_reserve", new Object[0]));
                    }
                }

                exists = this.menuAppRecipeMapper.exists(Wrappers.lambdaQuery(MenuAppRecipe.class)
                        .eq(MenuAppRecipe::getRecipeId, content.getRecipeId())
                        .eq(ObjectUtil.isNotEmpty(content.getMealLineId()), MenuAppRecipe::getMealLineId, content.getMealLineId())
                        .eq(MenuAppRecipe::getBindType, content.getBindType()));
                if (exists) {
                    throw new ServiceException(I18n.getMessage("menu_recipe_issue_repeat", new Object[0]));
                }

                List<Long> sourceRecipeList = this.menuAppRecipeMapper.selectRecipeInSameShop(menuRecipe.getStallId(), null, content.getBindType(), content.getMealLineId());
                if (ObjectUtil.isNotEmpty(sourceRecipeList)) {
                    this.menuAppRecipeMapper.delete(Wrappers.lambdaQuery(MenuAppRecipe.class)
                            .eq(MenuAppRecipe::getBindType, content.getBindType())
                            .eq(ObjectUtil.isNotEmpty(content.getMealLineId()), MenuAppRecipe::getMealLineId, content.getMealLineId())
                            .in(MenuAppRecipe::getRecipeId, sourceRecipeList));
                }

                MenuAppRecipe appRecipe = new MenuAppRecipe();
                appRecipe.setRecipeId(content.getRecipeId());
                appRecipe.setBindType(content.getBindType());
                appRecipe.setMealLineId(content.getMealLineId());
                appRecipe.setBindTime(LocalDateTime.now());
                this.menuAppRecipeMapper.insert(appRecipe);
                if (ObjectUtil.isNotEmpty(deviceTypes)) {
                    this.deviceApi.updateRecipeByCanteeStallMeal(content.getRecipeId(), menuRecipe.getCanteenId(), menuRecipe.getStallId(), content.getMealLineId(), deviceTypes);
                }

                MqUtil.sendDataChange(menuRecipe, LeMqConstant.DataChangeType.ADD, LeMqConstant.Topic.DATA_CHANGE_RECIPE_RELEASE);
            } else {
                this.menuAppRecipeMapper.delete(Wrappers.lambdaQuery(MenuAppRecipe.class)
                        .eq(MenuAppRecipe::getRecipeId, content.getRecipeId())
                        .eq(ObjectUtil.isNotEmpty(content.getMealLineId()), MenuAppRecipe::getMealLineId, content.getMealLineId())
                        .eq(MenuAppRecipe::getBindType, content.getBindType()));
                if (ObjectUtil.isNotEmpty(deviceTypes)) {
                    this.deviceApi.deleteRecipeByCanteeStallMeal(content.getRecipeId(), menuRecipe.getCanteenId(), menuRecipe.getStallId(), content.getMealLineId(), deviceTypes);
                }
            }

        }
    }


    @Override
    public List<MenuAppBindRecipeVO> getBindAppRecipeList(MenuAppBindRecipeDTO content) {
        return this.menuAppRecipeMapper.selectRecipeBindApp(Wrappers.lambdaQuery(MenuAppRecipe.class)
                .eq(MenuAppRecipe::getRecipeId, content.getRecipeId()));
    }

    public void checkChangeSurplusNum(List<MenuRecipeChangeSurplusNum> changeSurplusNumList, LocalDate applyDate, Integer mealtimeType) {
        log.info("扣减库存传入参数: {}, 日期: {}, 餐次: {}", new Object[]{JSON.toJSONString(changeSurplusNumList), applyDate, mealtimeType});
        if (ObjectUtil.isEmpty(changeSurplusNumList)) {
            throw new ServiceException(I18n.getMessage("menu_param_null_continue", new Object[0]));
        } else {
            Iterator var4 = changeSurplusNumList.iterator();

            while (var4.hasNext()) {
                MenuRecipeChangeSurplusNum changeSurplusNum = (MenuRecipeChangeSurplusNum) var4.next();
                Long detailId = changeSurplusNum.getDetailId();
                Long productId = changeSurplusNum.getProductId();
                Integer saleNum = changeSurplusNum.getSaleNum();
                if (ObjectUtil.hasNull(new Object[]{detailId, productId, saleNum})) {
                    throw new ServiceException(I18n.getMessage("menu_type_num_detail_product_null", new Object[0]));
                }

                if (saleNum == 0) {
                    throw new ServiceException(I18n.getMessage("menu_order_num_not_zero", new Object[0]));
                }

                if (ObjectUtil.isNotNull(applyDate)) {
                    Integer dishesCount = this.menuRecipeDetailMapper.selectDishesCount(detailId, productId, applyDate, mealtimeType);
                    if (ObjectUtil.isNull(dishesCount) || dishesCount <= 0) {
                        throw new ServiceException(I18n.getMessage("menu_not_select_dishes_detail", new Object[0]));
                    }
                }
            }

        }
    }

    @Override
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public IssueRecipeCompressVO issueRecipeV2Compress(IssueRecipeV2DTO issueRecipeV2DTO) {
        IssueRecipeCompressVO result = new IssueRecipeCompressVO();
        if (issueRecipeV2DTO.getRecipeId() == null) {
            return result;
        } else {
            MenuRecipe menuRecipe = this.baseMapper.selectOne(Wrappers.lambdaQuery(MenuRecipe.class)
                    .eq(MenuRecipe::getRecipeId, issueRecipeV2DTO.getRecipeId()));
            if (ObjectUtil.isNull(menuRecipe)) {
                throw new ServiceException(I18n.getMessage("menu_recipe_not_exist2", new Object[0]));
            } else {
                this.generateRecipe(menuRecipe.getRecipeId(), issueRecipeV2DTO.getBeginDate(), issueRecipeV2DTO.getEndDate());
                result.setRecipeType(menuRecipe.getRecipeType());
                result.setUptime(menuRecipe.getUptime());
                result.setRecipeId(menuRecipe.getRecipeId());
                Long stallId = menuRecipe.getStallId();
                List<IssueRecipeDateCompressVO> dateList = this.menuRecipeDetailMapper.selectIssueRecipeV2Compress(issueRecipeV2DTO);
                if (ObjectUtil.isEmpty(dateList)) {
                    result.setDateList(new ArrayList<>());
                    return result;
                } else {
                    List<AllocMealtimeModel> mealtimeList = this.allocMealtimeApi.listUseAvailableMealtime(null, stallId, null);
                    log.info("***餐次api接口返回所有餐次信息: {}", mealtimeList);
                    List<IssueRecipeIntervalCompressVO> sysIntervalList = mealtimeList.stream().map(this::getIssueRecipeIntervalCompressVO).collect(Collectors.toList());
                    Map<Long, IssueRecipeIntervalCompressVO> intervalMap = sysIntervalList.stream().collect(Collectors.toMap(IssueRecipeIntervalCompressVO::getIntervalId, Function.identity()));
                    List<Long> dishesIds = this.getAllDishesId(dateList);
                    if (ObjectUtil.isNotEmpty(dishesIds)) {
                        List<IssueRecipeMealCompressVO> mealList = this.getMealList(dishesIds);
                        Map<Long, DishesStallSaleModel> salesAndGoodProbabilityMap = this.getSalesAndGoodProbabilityMap(stallId, dishesIds);
                        Map<Long, List<String>> dishesLabelMap = this.menuDishesService.selectDishesLabelByDishesIds(dishesIds);
                        Map<String, List<String>> dishesMaterialMap = this.menuDishesService.selectMaterialByTypeAndDishesIds(dishesIds);
                        mealList.forEach((item) -> {
                            item.setLabelList(dishesLabelMap.get(item.getDishesId()));
                            Long var10002 = item.getDishesId();
                            item.setMainList(dishesMaterialMap.get("" + var10002 + "_" + MenuMaterialTypeEnum.MAIN_INGREDIENT.key()));
                            var10002 = item.getDishesId();
                            item.setAuxList(dishesMaterialMap.get("" + var10002 + "_" + MenuMaterialTypeEnum.AUX_INGREDIENT.key()));
                            var10002 = item.getDishesId();
                            item.setDosList(dishesMaterialMap.get("" + var10002 + "_" + MenuMaterialTypeEnum.DOS_INGREDIENT.key()));
                            DishesStallSaleModel dishesStallSaleModel = salesAndGoodProbabilityMap.get(item.getDishesId());
                            if (ObjectUtil.isNotNull(dishesStallSaleModel)) {
                                item.setMonthlySales(dishesStallSaleModel.getMonthlySales());
                                item.setGoodProbability(dishesStallSaleModel.getGoodProbability());
                            }

                        });
                        result.setMealList(mealList);
                    }

                    dateList.forEach((d) -> {
                        List<IssueRecipeIntervalCompressVO> intervalList = d.getIntervalList();
                        if (intervalList.size() < sysIntervalList.size()) {
                            List<Long> hasinterval =intervalList.stream().map(IssueRecipeIntervalCompressVO::getIntervalId).collect(Collectors.toList());
                            intervalList.addAll(sysIntervalList.stream().filter((s) -> {
                                return !hasinterval.contains(s.getIntervalId());
                            }).collect(Collectors.toList()));
                        }

                        intervalList.forEach((i) -> {
                            IssueRecipeIntervalCompressVO issueRecipeIntervalVO = intervalMap.get(i.getIntervalId());
                            i.setStartTime(issueRecipeIntervalVO.getStartTime());
                            i.setEndTime(issueRecipeIntervalVO.getEndTime());
                            i.setIntervalName(issueRecipeIntervalVO.getIntervalName());
                        });
                    });
                    result.setDateList(dateList);
                    return result;
                }
            }
        }
    }
    public IssueRecipeIntervalCompressVO getIssueRecipeIntervalCompressVO(AllocMealtimeModel m) {
        IssueRecipeIntervalCompressVO recipeIntervalVO = new IssueRecipeIntervalCompressVO();
        recipeIntervalVO.setIntervalId(m.getMealtimeType().longValue());
        recipeIntervalVO.setIntervalName(m.getMealtimeName());
        recipeIntervalVO.setStartTime(m.getStartTime());
        recipeIntervalVO.setEndTime(m.getEndTime());
        return recipeIntervalVO;
    }

    public List<Long> getAllDishesId(List<IssueRecipeDateCompressVO> dateList) {
        return dateList.stream().filter((item) -> {
            return ObjectUtil.isNotEmpty(item.getIntervalList());
        }).flatMap((item) -> {
            return item.getIntervalList().stream();
        }).filter((item) -> {
            return ObjectUtil.isNotEmpty(item.getProductList());
        }).flatMap((item) -> {
            return item.getProductList().stream();
        }).map(IssueRecipeDetailCompressVO::getDishesId).distinct().collect(Collectors.toList());
    }

    public List<IssueRecipeMealCompressVO> getMealList(List<Long> dishesIds) {
        return this.menuDishesMapper.getMealListByDishesIds(dishesIds);
    }

    public Map<Long, DishesStallSaleModel> getSalesAndGoodProbabilityMap(Long stallId, List<Long> dishesIds) {
        List<DishesStallSaleModel> dishesStallSaleModels = this.menuDishesSaleRecordMapper.selectSalesAndGoodProbability(Collections.singletonList(stallId), dishesIds);
        return dishesStallSaleModels.stream().collect(Collectors.toMap(DishesStallSaleModel::getDishesId, Function.identity()));
    }

    @Override
    public IssueRecipeVO issueRecipeV2(IssueRecipeV2DTO issueRecipeV2DTO) {
        IssueRecipeVO result = new IssueRecipeVO();
        result.setRecipeType(MenuRecipeTypeEnum.DEFAULT.key());
        Long stallId = this.baseMapper.selectStallIdByWrappers(Wrappers.lambdaQuery(MenuRecipe.class)
                .eq(MenuRecipe::getRecipeId, issueRecipeV2DTO.getRecipeId()));
        if (ObjectUtil.isNull(stallId)) {
            throw new ServiceException(I18n.getMessage("menu_recipe_not_exist2", new Object[0]));
        } else {
            List<IssueRecipeDateVO> dateList = this.menuRecipeDetailMapper.selectIssueRecipeV2(issueRecipeV2DTO);
            if (ObjectUtil.isEmpty(dateList)) {
                throw new ServiceException(I18n.getMessage("menu_recipe_not_exist2", new Object[0]));
            } else {
                List<AllocMealtimeModel> mealtimeList = this.allocMealtimeApi.listUseAvailableMealtime((Long)null, stallId, (Integer)null);
                log.info("***餐次api接口返回所有餐次信息: {}", mealtimeList);
                List<IssueRecipeIntervalVO> sysIntervalList = Lists.newArrayList();
                mealtimeList.forEach((m) -> {
                    IssueRecipeIntervalVO recipeIntervalVO = new IssueRecipeIntervalVO();
                    recipeIntervalVO.setIntervalId(m.getMealtimeType().longValue());
                    recipeIntervalVO.setIntervalName(m.getMealtimeName());
                    recipeIntervalVO.setStartTime(m.getStartTime());
                    recipeIntervalVO.setEndTime(m.getEndTime());
                    sysIntervalList.add(recipeIntervalVO);
                });
                List<IssueRecipeMealVO> mealList = Lists.newArrayList();
                dateList.forEach((d) -> {
                    List<IssueRecipeIntervalVO> intervalList = d.getIntervalList();
                    intervalList.forEach((i) -> {
                        List<IssueRecipeDetailVO> productList = i.getProductList();
                        if (ObjectUtil.isNotEmpty(productList)) {
                            List<IssueRecipeMealVO> recipeMealList = CopyListUtil.copyListProperties(productList, IssueRecipeMealVO.class);
                            mealList.addAll(recipeMealList);
                        } else {
                            i.setProductList(new ArrayList());
                        }

                    });
                    if (intervalList.size() < sysIntervalList.size()) {
                        intervalList.addAll(sysIntervalList.stream().filter((s) -> {
                            return !intervalList.stream().map(IssueRecipeIntervalVO::getIntervalId).collect(Collectors.toList()).contains(s.getIntervalId());
                        }).collect(Collectors.toList()));
                    }

                    Map<Long, IssueRecipeIntervalVO> intervalMap = Maps.newHashMap();
                    sysIntervalList.forEach((s) -> {
                        intervalMap.put(s.getIntervalId(), s);
                    });
                    intervalList.forEach((i) -> {
                        IssueRecipeIntervalVO issueRecipeIntervalVO = (IssueRecipeIntervalVO)intervalMap.get(i.getIntervalId());
                        i.setStartTime(issueRecipeIntervalVO.getStartTime());
                        i.setEndTime(issueRecipeIntervalVO.getEndTime());
                        i.setIntervalName(issueRecipeIntervalVO.getIntervalName());
                    });
                });
                result.setDateList(dateList);
                return result;
            }
        }
    }

    public List<AndroidRecipeDetailVO> getAndroidRecipeDetail(String content) {
        AndroidRecipeDetailDTO recipeDetailDTO = (AndroidRecipeDetailDTO)JSON.parseObject(content, AndroidRecipeDetailDTO.class);
        LocalDate applyDate = recipeDetailDTO.getApplyDate();
        if (!ObjectUtil.isNull(recipeDetailDTO) && applyDate != null) {
            Long recipeId = recipeDetailDTO.getRecipeId();
            if (ObjectUtil.isNull(recipeId)) {
                log.info("***[安卓_菜谱计划]_根据菜谱id获取菜谱详情_商家未设置菜谱,返回前端空值*****************");
                return new ArrayList();
            } else {
                recipeDetailDTO.setRecipeId(recipeId);
                this.generateRecipe(recipeId, applyDate);
                return ((MenuRecipeMapper)this.baseMapper).selectAndroidRecipeTwo(recipeId, applyDate);
            }
        } else {
            throw new ServiceException(I18n.getMessage("menu_apply_date_null"));
        }
    }

    public List<AndroidRecipeTypeDetailVO> getProductionMachineRecipe() {
        return this.menuDishesMapper.selectAllDishesByType();
    }

    public MenuHeartBeatVO getHeartBeat(MenuHeartBeatDTO content) {
        DeviceInfoVO machine = this.deviceApi.getDeviceInfoVoBySnCacheable(content.getMachineSn());
        LocalDateTime intervalUpdateTime = this.allocMealtimeApi.getMealtimeLastUpdateTime();
        log.info("***餐次api接口返回最新更新时间intervalUpdateTime: {}", intervalUpdateTime);
        if (!ObjectUtil.isNull(machine) && !ObjectUtil.isNull(machine.getFirstRecipeId())) {
            LocalDateTime recipeUpdateTime = this.menuRecipeDetailMapper.selectLastUptimeByRecipeId(machine.getFirstRecipeId());
            MenuHeartBeatVO result = new MenuHeartBeatVO();
            BeanUtil.copyProperties(machine, result, new String[0]);
            result.setIntervalUpdateTime(intervalUpdateTime);
            result.setRecipeUpdateTime(recipeUpdateTime);
            return result;
        } else {
            throw new ServiceException(I18n.getMessage("menu_mac_no_recipe"));
        }
    }

    public List<MenuEleDishRowRecipeVO> getEleDishRowRecipe(MenuEleDishRowRecipeDTO content) {
        Long recipeId = this.deviceApi.getFirstRecipeIdBySn(content.getMachineSn());
        Long stallId = this.baseMapper.selectStallIdByWrappers(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, recipeId));
        if (ObjectUtil.isNull(stallId)) {
            return Lists.newArrayList();
        } else {
            List<AllocMealtimeModel> mealtimeList = this.allocMealtimeApi.listUseAvailableMealtime((Long)null, stallId, (Integer)null);
            log.info("***餐次api接口返回所有餐次信息: {}", mealtimeList);
            Map<Integer, AllocMealtimeModel> mealTimeMap = Maps.newHashMap();
            mealtimeList.forEach((m) -> {
                mealTimeMap.put(m.getMealtimeType(), m);
            });
            LocalDate applyDate = content.getApplyDate();
            this.generateRecipe(recipeId, applyDate);
            List<MenuEleDishRowRecipeVO> resultList = ((MenuRecipeMapper)this.baseMapper).selectEleDishRowRecipe(recipeId, applyDate);
            if (ObjectUtil.isNotEmpty(resultList)) {
                resultList.forEach((r) -> {
                    AllocMealtimeModel mealTime = mealTimeMap.get(r.getIntervalId().intValue());
                    r.setStartTime(mealTime.getStartTime());
                    r.setEndTime(mealTime.getEndTime());
                });
            }

            return resultList;
        }
    }

    public List<PersonalDietRecordVO> getPersonalDietRecord(PersonalDietRecordDTO content) {
        Long custId = content.getCustId();
        if (ObjectUtil.isNull(custId)) {
            custId = this.custInfoApi.getCustIdBySerialNum(content.getSerialNum());
        }

        if (ObjectUtil.isNull(custId)) {
            throw new ServiceException(I18n.getMessage("menu_cust_info_not_exist"));
        } else {
            Integer analyseScope = content.getAnalyseScope();
            LocalDate startTime;
            LocalDate endTime;
            if (MenuAnalyseScopeEnum.THE_SAME_DAY.key().equals(analyseScope)) {
                startTime = LocalDate.now();
                endTime = LocalDate.now();
            } else {
                startTime = LocalDate.now().with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 1L);
                endTime = LocalDate.now().with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 7L);
            }

            return this.baseMapper.selectOrdDetailByCustId(custId, startTime, endTime, CollUtil.toList(new Integer[]{OrderStateEnum.FINISH.getKey()}));
        }
    }

    public List<AndroidAllProductsRecipeVO> getAllProductsRecipe(AndroidAllProductsRecipeDTO content) {
        List<Long> recipeIdList = this.deviceApi.listRecipeIdsByDeviceType(SourceTypeEnum.PRODUCTION.getKey());
        if (ObjectUtil.isEmpty(recipeIdList)) {
            log.info("***[获取所有出品机绑定菜谱详情]_未查询到绑定菜谱,返回空*************************");
            return Lists.newArrayList();
        } else {
            Integer mealtimeType = content.getIntervalId().intValue();
            this.generateRecipe(recipeIdList, content.getApplyDate());
            return ((MenuRecipeMapper)this.baseMapper).selectAndroidRecipeDetail(content.getApplyDate(), mealtimeType, recipeIdList, DelFlagEnum.DEL_FALSE.key());
        }
    }

    public List<AndroidRecipeDetailThreeVO> getAndroidAllRecipe(MenuAndroidAllRecipeDTO content, String machineSn) {
        Set<Long> effIdSet = this.getShopstallIdListByCustId(content.getCustId(), false);
        if (ObjectUtil.isEmpty(effIdSet)) {
            effIdSet = Sets.newTreeSet();
            ((Set)effIdSet).add(-1L);
        }

        LocalDate applyDate = content.getApplyDate();
        DeviceInfoVO deviceInfo = this.deviceApi.getDeviceInfoVoBySn(machineSn);
        if (ObjectUtil.isNull(deviceInfo)) {
            return Lists.newArrayList();
        } else {
            List<DeviceInfoVO.RecipeVO> recipeList = deviceInfo.getRecipeList();
            if (ObjectUtil.isEmpty(recipeList)) {
                return Lists.newArrayList();
            } else {
                List<Long> recipeIdList = deviceInfo.getRecipeList().stream().map(DeviceInfoVO.RecipeVO::getRecipeId).collect(Collectors.toList());
                if (ObjectUtil.isEmpty(recipeIdList)) {
                    return Lists.newArrayList();
                } else {
                    this.generateRecipe(recipeIdList, applyDate);
                    return ((MenuRecipeMapper)this.baseMapper).selectAndroidRecipeThree(recipeIdList, (Set)effIdSet, applyDate);
                }
            }
        }
    }

    public AppletMenuRecipeCanteenVO getRecipeInfoByRecipeId(Long recipeId) {
        return ((MenuRecipeMapper)this.baseMapper).getRecipeInfoByRecipeId(recipeId);
    }

    @Transactional(
            rollbackFor = {Exception.class}
    )
    public void androidAddRecipeDishes(AndroidAddRecipeDishesDTO content) {
        if (content.getRecipeId() != 0L && !ObjectUtil.isEmpty(content.getRecipeId())) {
            Long canteenId = content.getCanteenId();
            AllocCanteen allocCanteen = this.allocCanteenApi.getAllocCanteen(canteenId);
            Long areaId = (Long)Optional.ofNullable(allocCanteen).map(AllocCanteen::getAreaId).orElse(-1L);
            MenuRecipe menuRecipe = (MenuRecipe)this.getOne(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, content.getRecipeId()));
            Integer mealtimeType = content.getIntervalId().intValue();
            Long tempDetailId = null;
            List<Long> detailIds = new ArrayList();
            MenuRecipeDetail recipeDetail;
            if (menuRecipe.getRecipeType() == 1) {
                Long detailId = this.menuRecipeDetailMapper.selectDetailIdByWrapper(((Wrappers.lambdaQuery(MenuRecipeDetail.class).eq(MenuRecipeDetail::getRecipeId, content.getRecipeId())).eq(MenuRecipeDetail::getApplyDate, LocalDate.now())).eq(MenuRecipeDetail::getMealtimeType, mealtimeType));
                if (ObjectUtil.isNull(detailId)) {
                    detailId = Id.next();
                    recipeDetail = new MenuRecipeDetail();
                    recipeDetail.setDetailId(detailId);
                    recipeDetail.setRecipeId(content.getRecipeId());
                    recipeDetail.setApplyDate(LocalDate.now());
                    recipeDetail.setMealtimeType(mealtimeType);
                    recipeDetail.setDetailType(2);
                    this.menuRecipeDetailMapper.insert(recipeDetail);
                }

                ((List)detailIds).add(detailId);
            } else {
                boolean isWeek = menuRecipe.getRecipeType() == 3;
                tempDetailId = this.menuRecipeDetailMapper.selectDetailIdByWrapper((((Wrappers.lambdaQuery(MenuRecipeDetail.class).eq(MenuRecipeDetail::getRecipeId, content.getRecipeId())).eq(MenuRecipeDetail::getDetailType, 1)).eq(isWeek, MenuRecipeDetail::getApplyWeek, LocalDate.now().getDayOfWeek().getValue())).eq(MenuRecipeDetail::getMealtimeType, mealtimeType));
                if (tempDetailId == null) {
                    tempDetailId = Id.next();
                    recipeDetail = new MenuRecipeDetail();
                    recipeDetail.setDetailId(tempDetailId);
                    recipeDetail.setRecipeId(content.getRecipeId());
                    recipeDetail.setMealtimeType(mealtimeType);
                    if (isWeek) {
                        recipeDetail.setApplyWeek(LocalDate.now().getDayOfWeek().getValue());
                    }

                    recipeDetail.setDetailType(1);
                    this.menuRecipeDetailMapper.insert(recipeDetail);
                    MenuRecipeDetail dayDetail = (MenuRecipeDetail)BeanUtil.copyProperties(recipeDetail, MenuRecipeDetail.class, new String[0]);
                    dayDetail.setDetailId(Id.next());
                    dayDetail.setId((Long)null);
                    dayDetail.setApplyDate(LocalDate.now());
                    dayDetail.setDetailType(2);
                    this.menuRecipeDetailMapper.insert(dayDetail);
                }

                detailIds = this.menuRecipeDetailMapper.selectList(((((Wrappers.lambdaQuery(MenuRecipeDetail.class).select(MenuRecipeDetail::getDetailId).eq(MenuRecipeDetail::getDetailType, 2)).eq(MenuRecipeDetail::getRecipeId, content.getRecipeId())).eq(MenuRecipeDetail::getMealtimeType, mealtimeType)).eq(isWeek, MenuRecipeDetail::getApplyWeek, LocalDate.now().getDayOfWeek().getValue())).ge(MenuRecipeDetail::getApplyDate, LocalDate.now())).stream().map(MenuRecipeDetail::getDetailId).collect(Collectors.toList());
            }

            Map<Long, List<Long>> sourceIdListMap = new HashMap();
            if (ObjectUtil.isNotEmpty(detailIds)) {
                sourceIdListMap = this.menuRecipeDishesMapper.selectList(Wrappers.lambdaQuery(MenuRecipeDishes.class).select(MenuRecipeDishes::getDetailId, MenuRecipeDishes::getDishesId).in(MenuRecipeDishes::getDetailId, (Collection)detailIds)).stream().collect(Collectors.groupingBy(MenuRecipeDishes::getDetailId, Collectors.mapping(MenuRecipeDishes::getDishesId, Collectors.toList())));
            }

            List<MenuRecipeDishes> recipeDishesList = Lists.newArrayList();
            List<Long> tempSourceIdList = new ArrayList();
            if (ObjectUtil.isNotNull(tempDetailId)) {
                tempSourceIdList = this.menuRecipeDishesMapper.selectDishesIdListByWrapper(Wrappers.lambdaQuery(MenuRecipeDishes.class).eq(MenuRecipeDishes::getDetailId, tempDetailId));
            }

            List<AndroidAddRecipeDishesDetailDTO> detailList = content.getDetailList();
            Long defaultTypeId = this.menuDishesTypeService.getDefaultTypeId();
            Iterator var14 = detailList.iterator();

            label79:
            while(var14.hasNext()) {
                AndroidAddRecipeDishesDetailDTO d = (AndroidAddRecipeDishesDetailDTO)var14.next();
                Long dishesId = d.getDishesId();
                Long finalDetailId;
                if (ObjectUtil.isNull(dishesId)) {
                    dishesId = this.menuDishesMapper.selectDishesIdByWrapper(((Wrappers.lambdaQuery(MenuDishes.class).eq(MenuDishes::getDishesName, d.getDishesName())).eq(MenuDishes::getDelFlag, DelFlagEnum.DEL_FALSE.key())).last("limit 1"));
                    if (ObjectUtil.isNull(dishesId)) {
                        MenuDishesV2AddDTO menuDishesV2AddDTO = (MenuDishesV2AddDTO)BeanUtil.copyProperties(d, MenuDishesV2AddDTO.class, new String[0]);
                        menuDishesV2AddDTO.setMealType(MenuMealTypeEnum.DISHES.key());
                        menuDishesV2AddDTO.setPublicDishes(LeConstants.COMMON_NO);
                        menuDishesV2AddDTO.setDishesName(d.getDishesName());
                        menuDishesV2AddDTO.setSizeType(1L);
                        menuDishesV2AddDTO.setPrice(d.getPrice());
                        menuDishesV2AddDTO.setImageUrl(d.getPicUrl());
                        menuDishesV2AddDTO.setShopstallId(content.getShopstallId());
                        menuDishesV2AddDTO.setCanteenId(content.getCanteenId());
                        menuDishesV2AddDTO.setAreaId(areaId);
                        finalDetailId = (Long)Optional.ofNullable(d.getTypeId()).orElse(defaultTypeId);
                        menuDishesV2AddDTO.setTypeId(finalDetailId);
                        AddDishesVo addDishesVo = this.menuDishesService.addMenuDishesV2(menuDishesV2AddDTO);
                        dishesId = (Long)addDishesVo.getDishesIds().get(0);
                    } else if (ObjectUtil.isNotEmpty(d.getPicUrl())) {
                        this.menuDishesMapper.update(null, (Wrappers.lambdaUpdate(MenuDishes.class).eq(MenuDishes::getDishesId, dishesId)).set(MenuDishes::getImageUrl, d.getPicUrl()));
                    }
                }

                if (tempDetailId != null && !((List)tempSourceIdList).contains(dishesId)) {
                    MenuRecipeDishes recipeDishes = this.getAndroAddRecipeDishes(d, tempDetailId, dishesId);
                    recipeDishesList.add(recipeDishes);
                }

                Iterator var27 = ((List)detailIds).iterator();

                while(true) {
                    List sourceIdList;
                    do {
                        if (!var27.hasNext()) {
                            continue label79;
                        }

                        finalDetailId = (Long)var27.next();
                        sourceIdList = (List)((Map)sourceIdListMap).get(finalDetailId);
                    } while(!ObjectUtil.isEmpty(sourceIdList) && sourceIdList.contains(dishesId));

                    MenuRecipeDishes recipeDishes = this.getAndroAddRecipeDishes(d, finalDetailId, dishesId);
                    recipeDishesList.add(recipeDishes);
                }
            }

            if (ObjectUtil.isNotEmpty(recipeDishesList)) {
                this.menuRecipeDishesService.saveBatch(recipeDishesList);
            }

            RecipeProcessResult processResult = new RecipeProcessResult();
            processResult.setRecipeId(content.getRecipeId());
            processResult.setMenuRecipe(menuRecipe);
            processResult.setAdd(false);
            this.processResult(processResult);
        } else {
            throw new ServiceException("请在管理端绑定菜谱");
        }
    }

    public MenuRecipeDishes getAndroAddRecipeDishes(AndroidAddRecipeDishesDetailDTO androidAddRecipeDishesDetailDTO, Long detailId, Long dishesId) {
        MenuRecipeDishes recipeDishes = new MenuRecipeDishes();
        recipeDishes.setDetailId(detailId);
        recipeDishes.setDishesId(dishesId);
        recipeDishes.setPrice(androidAddRecipeDishesDetailDTO.getPrice());
        recipeDishes.setSalePrice(androidAddRecipeDishesDetailDTO.getPrice());
        recipeDishes.setSizeType(1L);
        recipeDishes.setSupplyNum(androidAddRecipeDishesDetailDTO.getSupplyNum());
        recipeDishes.setSaleNum(0);
        recipeDishes.setSurplusNum(androidAddRecipeDishesDetailDTO.getSupplyNum());
        recipeDishes.setRestrictNum(androidAddRecipeDishesDetailDTO.getRestrictNum());
        return recipeDishes;
    }

    public List<AndroidGetRecipeDishesVO> androidGetRecipeDishes(AndroidGetRecipeDishesDTO content) {
        MenuRecipe menuRecipe = this.baseMapper.selectOne(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, content.getRecipeId()).select(MenuRecipe::getCanteenId, MenuRecipe::getStallId));
        if (ObjectUtil.isNull(menuRecipe)) {
            return Lists.newArrayList();
        } else {
            this.generateRecipe(content.getRecipeId(), content.getApplyDate());
            List<AndroidGetRecipeDishesVO> resultList = this.baseMapper.selectAndroidRecipeDetailByRecipeId(content.getApplyDate(), content.getRecipeId());
            if (ObjectUtil.isEmpty(resultList)) {
                return resultList;
            } else {
                List<AllocMealtimeModel> mealtimeList = this.allocMealtimeApi.listUseAvailableMealtime((Long)null, menuRecipe.getStallId(), LeConstants.COMMON_YES);
                log.info("***餐次api接口返回所有餐次信息: {}", mealtimeList);
                if (ObjectUtil.isEmpty(mealtimeList)) {
                    return Lists.newArrayList();
                } else {
                    Map<Integer, AllocMealtimeModel> mealTimeMap = mealtimeList.stream().collect(Collectors.toMap(AllocMealtimeModel::getMealtimeType, Function.identity()));
                    return resultList.stream().filter((item) -> {
                        return mealTimeMap.containsKey(item.getIntervalId().intValue());
                    }).sorted(Comparator.comparing(AndroidGetRecipeDishesVO::getIntervalId)).collect(Collectors.toList());
                }
            }
        }
    }

    public void androidRemoveRecipeDishes(AndroidRemoveRecipeDishesDTO content) {
        Integer mealtimeType = content.getIntervalId().intValue();
        Long detailId = this.menuRecipeDetailMapper.selectDetailIdByWrapper(((Wrappers.lambdaQuery(MenuRecipeDetail.class).eq(MenuRecipeDetail::getRecipeId, content.getRecipeId())).eq(MenuRecipeDetail::getMealtimeType, mealtimeType)).eq(MenuRecipeDetail::getApplyDate, content.getApplyDate()));
        if (ObjectUtil.isNotNull(detailId)) {
            this.menuRecipeDishesMapper.delete((Wrappers.lambdaQuery(MenuRecipeDishes.class).eq(MenuRecipeDishes::getDetailId, detailId)).in(MenuRecipeDishes::getDishesId, content.getDishesIdList()));
            this.menuRecipeDetailMapper.update(null, (Wrappers.lambdaUpdate(MenuRecipeDetail.class).eq(MenuRecipeDetail::getDetailId, detailId)).set(MenuRecipeDetail::getUptime, LocalDateTime.now()));
        }
    }

    public List<AndroidProductionRecipeVO> getProductionRecipeDetail(AndroidProductionRecipeDTO content) {
        Long recipeId = content.getRecipeId();
        List<AndroidProductionRecipeVO> resultList = this.menuRecipeDetailMapper.selectProductionRecipe(recipeId, content.getApplyDateList());
        if (ObjectUtil.isEmpty(resultList)) {
            log.info("出品机获取菜谱信息为空");
            return resultList;
        } else {
            Long stallId = this.baseMapper.selectStallIdByWrappers(Wrappers.lambdaQuery(MenuRecipe.class).eq(MenuRecipe::getRecipeId, recipeId));
            List<AllocMealtimeModel> mealtimeList = this.allocMealtimeApi.listUseAvailableMealtime(null, stallId, null);
            log.info("***餐次api接口返回所有餐次信息: {}", mealtimeList);
            Map<Long, AllocMealtimeModel> mealtimeMap = Maps.newHashMap();
            mealtimeList.forEach((mealtime) -> {
                mealtimeMap.put(mealtime.getMealtimeType().longValue(), mealtime);
            });
            resultList.forEach((date) -> {
                List<AndroidProductionMealtimeVO> intervalList = date.getIntervalList();
                if (ObjectUtil.isNotEmpty(intervalList)) {
                    Iterator<AndroidProductionMealtimeVO> iterator = intervalList.iterator();

                    while(iterator.hasNext()) {
                        AndroidProductionMealtimeVO mealtime = iterator.next();
                        if (ObjectUtil.isEmpty(mealtime.getProductList())) {
                            iterator.remove();
                        } else {
                            AllocMealtimeModel stallMealtime = mealtimeMap.get(mealtime.getIntervalId());
                            mealtime.setStartTime(stallMealtime.getStartTime());
                            mealtime.setEndTime(stallMealtime.getEndTime());
                        }
                    }
                }

            });
            return resultList;
        }
    }

    public List<AndroidGetRecipeByShopVO> androidGetRecipeListByShop(AndroidGetRecipeByShopDTO content) {
        return ((MenuRecipeMapper)this.baseMapper).selectRecipeListByShop(((Wrappers.lambdaQuery(MenuRecipe.class).eq(ObjectUtil.isNotNull(content.getCanteenId()), MenuRecipe::getCanteenId, content.getCanteenId())).eq(ObjectUtil.isNotNull(content.getShopstallId()), MenuRecipe::getStallId, content.getShopstallId())).eq(MenuRecipe::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
    }
}
