package com.liquidnet.service.goblin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.*;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceConfig;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceConfigMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper;
import com.liquidnet.service.goblin.enums.GoblinStoreConf;
import com.liquidnet.service.goblin.service.GoblinCouponService;
import com.liquidnet.service.goblin.service.GoblinFrontService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import com.liquidnet.service.goblin.util.QueueUtils;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.mongodb.BasicDBObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GoblinFrontServiceImpl implements GoblinFrontService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    GoblinCouponService goblinCouponService;
    @Autowired
    private GoblinSqbPerformanceGoodsMapper goblinSqbPerformanceGoodsMapper;
    @Autowired
    private GoblinSqbPerformanceConfigMapper goblinSqbPerformanceConfigMapper;
    private static final String SELECT_GOODS_EXCLUDE_NAME = "护照专属";

    private boolean isPassportExclusive(GoblinGoodsInfoVo vo) {
        return null != vo && StringUtil.isNotBlank(vo.getName()) && vo.getName().contains(SELECT_GOODS_EXCLUDE_NAME);
    }

    /** 收钱吧演出关联商品（与后台约定 spuType=33），精选列表不展示 */
    private boolean isSqbSpuGoods(GoblinGoodsInfoVo vo) {
        return vo != null && vo.getSpuType() == 33;
    }

    /** showInMall=0 时不展示到商城精选列表；历史数据无该字段时默认展示 */
    private boolean isNotShowInMall(GoblinGoodsInfoVo vo) {
        return vo != null && vo.getShowInMall() != null && vo.getShowInMall() == 0;
    }

    /**
     * 单场次演出下全部关联关系（status=1）：先读 Redis {@link GoblinRedisUtils#getSqbPerformanceGoodsListCache}，
     * 未命中再查库并回写，与 {@link #getPerformanceSelectGoods} 一致。
     */
    private List<GoblinSqbPerformanceGoods> loadSqbPerformanceGoodsRelationsFromCacheOrDb(String performancesId) {
        if (StringUtil.isBlank(performancesId)) {
            return new ArrayList<>();
        }
        String pid = performancesId.trim();
        List<GoblinSqbPerformanceGoods> relations = goblinRedisUtils.getSqbPerformanceGoodsListCache(pid);
        if (relations == null) {
            relations = goblinSqbPerformanceGoodsMapper.selectList(
                    new LambdaQueryWrapper<GoblinSqbPerformanceGoods>()
                            .eq(GoblinSqbPerformanceGoods::getPerformancesId, pid)
                            .eq(GoblinSqbPerformanceGoods::getStatus, 1)
                            .orderByAsc(GoblinSqbPerformanceGoods::getSort, GoblinSqbPerformanceGoods::getMid));
            if (relations == null) {
                relations = new ArrayList<>();
            }
            goblinRedisUtils.setSqbPerformanceGoodsListCache(pid, relations);
        }
        return relations;
    }

    /**
     * 收钱吧演出-SKU 关联（status=1）。<br>
     * 有 performancesId 时与列表接口共用 Redis 缓存，仅内存过滤当前 spu 的 skuId；<br>
     * 无 performancesId 时（详情并集）当前无按 SPU 的缓存结构，仍查库。
     */
    private Set<String> loadSqbLinkedSkuIdSet(String spuId, String performancesId) {
        if (StringUtil.isBlank(spuId)) {
            return Collections.emptySet();
        }
        String spu = spuId.trim();
        if (StringUtil.isNotBlank(performancesId)) {
            List<GoblinSqbPerformanceGoods> relations = loadSqbPerformanceGoodsRelationsFromCacheOrDb(performancesId);
            LinkedHashSet<String> ids = new LinkedHashSet<>();
            for (GoblinSqbPerformanceGoods r : relations) {
                if (r == null || StringUtil.isBlank(r.getSkuId())) {
                    continue;
                }
                if (StringUtil.isBlank(r.getSpuId()) || !spu.equals(r.getSpuId().trim())) {
                    continue;
                }
                ids.add(r.getSkuId().trim());
            }
            return ids;
        }
        LambdaQueryWrapper<GoblinSqbPerformanceGoods> w = new LambdaQueryWrapper<GoblinSqbPerformanceGoods>()
                .eq(GoblinSqbPerformanceGoods::getSpuId, spu)
                .eq(GoblinSqbPerformanceGoods::getStatus, 1);
        List<GoblinSqbPerformanceGoods> rows = goblinSqbPerformanceGoodsMapper.selectList(w);
        LinkedHashSet<String> ids = new LinkedHashSet<>();
        if (rows != null) {
            for (GoblinSqbPerformanceGoods r : rows) {
                if (r != null && StringUtil.isNotBlank(r.getSkuId())) {
                    ids.add(r.getSkuId().trim());
                }
            }
        }
        return ids;
    }

    @Override
    public ArrayList<GoblinFrontBannerVo> getListBanner() {
        List<GoblinFrontBanner> list = goblinRedisUtils.getListBanner();
        if (null == list) {
            return null;
        }
        LocalDateTime nowTime = LocalDateTime.now();
        ArrayList<GoblinFrontBanner> goblinFrontBannerArrayList = ObjectUtil.getGoblinFrontBannerArrayList();
        //查看是否有失效的时间
        for (GoblinFrontBanner goblinFrontBanner : list) {
            if (null != goblinFrontBanner.getEndTime() && null != goblinFrontBanner.getStartTime()) {
                if (nowTime.isAfter(goblinFrontBanner.getEndTime())) {
                } else {
                    if (nowTime.isBefore(goblinFrontBanner.getStartTime())) {
                    } else {
                        goblinFrontBannerArrayList.add(goblinFrontBanner);
                    }
                }
            } else {
                goblinFrontBannerArrayList.add(goblinFrontBanner);
            }
        }
        ArrayList<GoblinFrontBannerVo> list1 = ObjectUtil.goblinFrontBannerVoArrayList();
        for (GoblinFrontBanner goblinFrontBanner : goblinFrontBannerArrayList) {
            GoblinFrontBannerVo goblinFrontBannerVo = GoblinFrontBannerVo.getNew();
            BeanUtils.copyProperties(goblinFrontBanner, goblinFrontBannerVo);
            list1.add(goblinFrontBannerVo);
        }
        return list1;
    }

    public ArrayList<GoblinFrontBannerVo> getMiddleBanner() {
        List<GoblinFrontBanner> list = goblinRedisUtils.getMiddleBanner();
        if (null == list) {
            return null;
        }
        LocalDateTime nowTime = LocalDateTime.now();
        ArrayList<GoblinFrontBanner> goblinFrontBannerArrayList = ObjectUtil.getGoblinFrontBannerArrayList();
        //查看是否有失效的时间
        for (GoblinFrontBanner goblinFrontBanner : list) {
            if (null != goblinFrontBanner.getEndTime()) {
                if (nowTime.isAfter(goblinFrontBanner.getEndTime())) {
                } else {
                    if (nowTime.isBefore(goblinFrontBanner.getStartTime())) {
                    } else {
                        goblinFrontBannerArrayList.add(goblinFrontBanner);
                    }
                }
            } else {
                goblinFrontBannerArrayList.add(goblinFrontBanner);
            }
        }
        ArrayList<GoblinFrontBannerVo> list1 = ObjectUtil.goblinFrontBannerVoArrayList();
        for (GoblinFrontBanner goblinFrontBanner : goblinFrontBannerArrayList) {
            GoblinFrontBannerVo goblinFrontBannerVo = GoblinFrontBannerVo.getNew();
            BeanUtils.copyProperties(goblinFrontBanner, goblinFrontBannerVo);
            list1.add(goblinFrontBannerVo);
        }
        return list1;
    }

    @Override
    public GoblinFrontHotWord getHotWord() {
        List<GoblinFrontHotWord> list = goblinRedisUtils.getHotWord();
        // int index= (int) redisUtil.get(GoblinRedisConst.FRONT_HOTWORD_INDEX);
        //获得value
       /* index++;
        String hotWord="";
        redisUtil.set(GoblinRedisConst.FRONT_HOTWORD_INDEX,index);
        if(index<list.size()){
            hotWord= list.get(index).getWord();
        }else{
            hotWord= list.get(0).getWord();
        }*/
        if (null == list || list.size() == 0) {
            return null;
        } else {
            return list.get(0);
        }
    }

    @Override
    public GoblinFrontNavigationVoo getNavigation() {
        if (!redisUtil.hasKey(GoblinRedisConst.FRONT_NAVIGATION)) {
            return null;
        }
        GoblinFrontNavigationVoo goblinFrontNavigationVoo = GoblinFrontNavigationVoo.getNew();
        List<GoblinFrontNavigation> list = (List<GoblinFrontNavigation>) redisUtil.get(GoblinRedisConst.FRONT_NAVIGATION);
        ArrayList<GoblinFrontNavigationVo> list1 = ObjectUtil.getgoblinFrontNavigationVoArrayList();
        for (GoblinFrontNavigation navigation : list) {
            goblinFrontNavigationVoo.setDisplayType(navigation.getDisplayType());
            GoblinFrontNavigationVo goblinFrontNavigationVo = GoblinFrontNavigationVo.getNew();
            BeanUtils.copyProperties(navigation, goblinFrontNavigationVo);
            list1.add(goblinFrontNavigationVo);
        }
        goblinFrontNavigationVoo.setList(list1);
        return goblinFrontNavigationVoo;
    }

    @Override
    public GoblinFrontSeckillVo getSeckilll() throws ParseException {
        //获得秒杀列表绑定
        List<GoblinFrontSeckill> list = (List<GoblinFrontSeckill>) redisUtil.get(GoblinRedisConst.FRONT_SECKILL);
        GoblinFrontSeckillVo goblinFrontSeckillVo = GoblinFrontSeckillVo.getNew();
        ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList = ObjectUtil.goblinGoodsInfoVoArrayList();
        //判断是否有
        if (null != list && list.size() > 0) {
            //遍历秒杀， 找到对应的  官方、商铺
            GoblinFrontSeckill goblinFrontSeckill = list.get(0);
            boolean openBoolean = goblinFrontSeckill.getActivityType() == 2;
            String ids = goblinFrontSeckill.getSelfActivityids();
            if (StringUtil.isNotBlank(ids)) {
                String[] idss = ids.split(",");
                for (String id : idss) {
                    String type = id.split("_")[0];
                    String idM = id.split("_")[1];
                    if (type.equals("g")) {
                        //找到对应官方的活动 判断时间是否过期，
                        GoblinSelfMarketingVo goblinSelfMarketingVo = goblinRedisUtils.getSelfMarket(idM);
                        if (!StringUtil.isNotBlank(goblinFrontSeckillVo.getStartTime())) {
                            goblinFrontSeckillVo.setStartTime(goblinSelfMarketingVo.getStartTime());
                            goblinFrontSeckillVo.setEndTime(goblinSelfMarketingVo.getEndTime());
                        }
                        if (goblinSelfMarketingVo == null) {
                            break;
                        }
                        if (!openBoolean) {
                            //效验该活动是否在当前时间
                            if (!belongCalendar(goblinSelfMarketingVo.getStartTime(), goblinSelfMarketingVo.getEndTime())) {
                                //如果不是在当前时间
                                break;
                            }
                        }
                        //查看 活动绑定的 spu   sku
                        List<GoblinMarketRelationVo> list1 = goblinRedisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_PURCHASE.getValue(), goblinSelfMarketingVo.getSelfMarketId());
                        //遍历 活动表
                        for (GoblinMarketRelationVo goblinMarketRelationVo : list1) {
                            //找到对应的spu商品
                            GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(goblinMarketRelationVo.getSpuId());
                            //遍历sku 找到
                            List<String> skuList = goblinMarketRelationVo.getSkuList();
                            int sellPrice = 0;
                            int i = 0;
                            for (String skuId : skuList) {
                                GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                                if (null != goblinGoodsSkuInfoVo) {
                                    if (i == 0) {
                                        sellPrice = goblinGoodsSkuInfoVo.getSellPrice().intValue();
                                    }
                                    if (sellPrice > goblinGoodsSkuInfoVo.getSellPrice().intValue()) {
                                        sellPrice = goblinGoodsSkuInfoVo.getSellPrice().intValue();
                                    }
                                }
                            }
                            goblinGoodsInfoVo.setSellPrice(new BigDecimal(sellPrice));
                            goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo);
                        }
                    } else if (type.equals("s")) {
                        //商铺活动的vo
                        GoblinStoreMarketVo goblinStoreMarketVo = goblinRedisUtils.getGoblinStoreMarketVo(idM);
                        if (!StringUtil.isNotBlank(goblinFrontSeckillVo.getStartTime())) {
                            goblinFrontSeckillVo.setStartTime(goblinStoreMarketVo.getStartTime());
                            goblinFrontSeckillVo.setEndTime(goblinStoreMarketVo.getEndTime());
                        }
                        if (goblinStoreMarketVo == null) {
                            break;
                        }
                        boolean isGet = false;
                        if (openBoolean) {
                            //不做效验时间直接放true
                            isGet = true;
                        } else if (goblinStoreMarketVo.getIsPre() == 1 && afterCalendar(goblinStoreMarketVo.getPreTime()) && beforeCalendar(goblinStoreMarketVo.getEndTime())) {
                            isGet = true;
                        } else if (goblinStoreMarketVo.getIsPre() == 0 && belongCalendar(goblinStoreMarketVo.getStartTime(), goblinStoreMarketVo.getEndTime())) {
                            isGet = true;
                        }
                        if (isGet) {
                            //获取商铺 对应关系
                            List<GoblinMarketRelationVo> list1 = goblinRedisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_PURCHASE.getValue(), goblinStoreMarketVo.getStoreMarketId());
                            //获得商品
                            //遍历 活动表
                            for (GoblinMarketRelationVo goblinMarketRelationVo : list1) {
                                //找到对应的spu商品
                                GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(goblinMarketRelationVo.getSpuId());
                                //遍历sku 找到
                                List<String> skuList = goblinMarketRelationVo.getSkuList();
                                int sellPrice = 0;
                                int i = 0;
                                for (String skuId : skuList) {
                                    GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                                    if (null != goblinGoodsSkuInfoVo) {
                                        if (i == 0) {
                                            sellPrice = goblinGoodsSkuInfoVo.getSellPrice().intValue();
                                        }
                                        if (sellPrice > goblinGoodsSkuInfoVo.getSellPrice().intValue()) {
                                            sellPrice = goblinGoodsSkuInfoVo.getSellPrice().intValue();
                                        }
                                    }
                                }
                                goblinGoodsInfoVo.setSellPrice(new BigDecimal(sellPrice));
                                goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo);
                            }
                        }

                    }
                }
                goblinFrontSeckillVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);
            }
        }
        return goblinFrontSeckillVo;
    }

    //获取库存设置的报警数量
    public int getStockCount(String storeId) {
        String configVal = "";
        List<GoblinStoreConfigVo> listVo = goblinRedisUtils.getStoreConfigVos(storeId);
        //ONOFF_SOLD_OUT_SHOW  ON  开启
        for (GoblinStoreConfigVo goblinStoreConfigVo : listVo) {
            //获取是 售罄是否开启
            if (goblinStoreConfigVo.getConfigKey().equals(GoblinStoreConf.LIMIT_WARNING_STOCK)) {
                configVal = goblinStoreConfigVo.getConfigVal();
            }
        }
        if (StringUtil.isNotBlank(configVal)) {
            return Integer.parseInt(configVal);
        } else {
            return -1;
        }
    }

    /** SKU 主图未维护时，用 SPU 封面兜底（前台详情/列表展示） */
    private void fillSkuPicIfBlank(GoblinGoodsSkuInfoDetailVo skuDetail, GoblinGoodsInfoVo spuVo) {
        if (skuDetail == null || spuVo == null) {
            return;
        }
        if (StringUtil.isBlank(skuDetail.getSkuPic()) && StringUtil.isNotBlank(spuVo.getCoverPic())) {
            skuDetail.setSkuPic(spuVo.getCoverPic());
        }
    }

    /**
     * 前台展示用：仅包含未删除且已上架的 SKU，并填充库存、限购可买数等（与 {@link #getGoodsDetail} 一致）
     */
    private ArrayList<GoblinGoodsSkuInfoDetailVo> buildOnShelfSkuDetailList(GoblinGoodsInfoVo goblinGoodsInfoVo) {
        return buildOnShelfSkuDetailList(goblinGoodsInfoVo, null);
    }

    /**
     * @param allowedSkuIds 非 null 时仅保留集合内的 SKU（用于收钱吧演出关联 SKU、spuType=33 详情）
     */
    private ArrayList<GoblinGoodsSkuInfoDetailVo> buildOnShelfSkuDetailList(GoblinGoodsInfoVo goblinGoodsInfoVo, Set<String> allowedSkuIds) {
        ArrayList<GoblinGoodsSkuInfoDetailVo> list = ObjectUtil.goblinGoodsSkuInfoDetailVos();
        if (goblinGoodsInfoVo == null) {
            return list;
        }
        String spuId = goblinGoodsInfoVo.getSpuId();
        List<String> skuIdList = goblinGoodsInfoVo.getSkuIdList();
        if (CollectionUtils.isEmpty(skuIdList)) {
            return list;
        }
        Integer buyCount = 0;
        for (String sku : skuIdList) {
            if (allowedSkuIds != null && !allowedSkuIds.contains(sku)) {
                continue;
            }
            String userId = CurrentUtil.getCurrentUid();
            if (StringUtils.isNotBlank(userId)) {
                buyCount = goblinRedisUtils.getSkuCountByUid(userId, sku);
            }
            GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(sku);
            if (null != goblinGoodsSkuInfoVo && goblinGoodsSkuInfoVo.getDelFlg().equals("0") && goblinGoodsSkuInfoVo.getShelvesStatus().equals("3")) {
                String pre = GoblinStatusConst.MarketPreStatus.getPre(spuId);
                int stock = goblinRedisUtils.getSkuStock(pre, goblinGoodsSkuInfoVo.getSkuId());
                log.debug("skuId:{},库存数量{}", goblinGoodsSkuInfoVo.getSkuId(), stock);
                GoblinGoodsSkuInfoDetailVo goblinGoodsSkuInfoDetailVo = GoblinGoodsSkuInfoDetailVo.getNew();
                BeanUtils.copyProperties(goblinGoodsSkuInfoVo, goblinGoodsSkuInfoDetailVo);
                fillSkuPicIfBlank(goblinGoodsSkuInfoDetailVo, goblinGoodsInfoVo);
                if (0 != goblinGoodsSkuInfoDetailVo.getBuyLimit()) {
                    if (null == buyCount) {
                        buyCount = 0;
                    }
                    goblinGoodsSkuInfoDetailVo.setCanBuy(goblinGoodsSkuInfoDetailVo.getBuyLimit() - buyCount);
                } else {
                    goblinGoodsSkuInfoDetailVo.setCanBuy(-9999);
                }
                if (stock <= 0) {
                    goblinGoodsSkuInfoDetailVo.setStockLess(true);
                } else {
                    goblinGoodsSkuInfoDetailVo.setStockLess(false);
                }
                goblinGoodsSkuInfoDetailVo.setRestStock(stock);
                list.add(goblinGoodsSkuInfoDetailVo);
            }
        }
        return list;
    }

    /**
     * 获得商品详情
     */
    public GoblinFrontGoodDetailVo getGoodsDetail(String spuId) {
        return getGoodsDetail(spuId, null);
    }

    /**
     * @param performancesId 可选；spuType=33 时传入则只返回该演出已关联的 SKU，不传则返回该商品在任意演出下已关联 SKU 的并集
     */
    public GoblinFrontGoodDetailVo getGoodsDetail(String spuId, String performancesId) {
        GoblinFrontGoodDetailVo goblinFrontGoodDetailVo = GoblinFrontGoodDetailVo.getNew();
        GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
        GoblinGoodsInfoDetailVo goblinGoodsInfoDetailVo = GoblinGoodsInfoDetailVo.getNew();
        //skuIdList
        if (null != goblinGoodsInfoVo) {
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoDetailVo);
            goblinFrontGoodDetailVo.setGoblinGoodsInfoVo(goblinGoodsInfoDetailVo);
            // int limit= getStockCount(goblinGoodsInfoVo.getStoreId());
            Set<String> sqbSkuAllow = null;
            if (isSqbSpuGoods(goblinGoodsInfoVo)) {
                sqbSkuAllow = loadSqbLinkedSkuIdSet(spuId, performancesId);
            }
            ArrayList<GoblinGoodsSkuInfoDetailVo> list = buildOnShelfSkuDetailList(goblinGoodsInfoVo, sqbSkuAllow);
            //goblinGoodsInfoVo
            GoblinStoreInfoVo goblinStoreInfoVo = this.getStore(goblinGoodsInfoVo.getStoreId());
            if (null != goblinStoreInfoVo) {
                goblinFrontGoodDetailVo.setStoreName(goblinStoreInfoVo.getStoreName());
            }
            goblinFrontGoodDetailVo.setGoblinGoodsSkuInfoVolist(list);
        } else {
            return null;
        }
        ArrayList<String> list = goblinCouponService.getSpuType(spuId, goblinGoodsInfoDetailVo.getStoreId());
        goblinFrontGoodDetailVo.setGetSpuType(list);
        return goblinFrontGoodDetailVo;
    }

    /**
     * 根据条码获得商品详情
     */
    public GoblinFrontGoodDetailVo getGoodsDetailByScanner(String barCode, String storeId, String marketId) {
        Criteria skuCriteria = Criteria.where("delFlg").is("0").and("storeId").is(storeId).and("skuBarCode").is(barCode);
        Query skuQuery = Query.query(skuCriteria);
        skuQuery.fields().include("spuId").include("skuId");
        List<GoblinGoodsSkuInfoVo> skuQueryResultList = mongoTemplate.find(skuQuery, GoblinGoodsSkuInfoVo.class, GoblinGoodsSkuInfoVo.class.getSimpleName());
        if (CollectionUtils.isEmpty(skuQueryResultList)) {
            return null;
        }
        List<String> skuQueryResultSpuIdList = skuQueryResultList.stream().map(GoblinGoodsSkuInfoVo::getSpuId).collect(Collectors.toList());
        Criteria criteria = Criteria.where("delFlg").is("0").and("storeId").is(storeId).and("spuId").in(skuQueryResultSpuIdList)
                .and("marketId").is(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue().concat(marketId));
        Query query = Query.query(criteria);
        List<GoblinGoodsInfoVo> goblinGoodsInfoVos = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        if (CollectionUtils.isEmpty(goblinGoodsInfoVos)) {
            return null;
        } else if (goblinGoodsInfoVos.size() > 1) {
            throw new LiquidnetServiceException("-1", "条码识别到多个商品，请更正处理");
        }
        String spuId = goblinGoodsInfoVos.get(0).getSpuId();


        Integer buyCount = 0;
        GoblinFrontGoodDetailVo goblinFrontGoodDetailVo = GoblinFrontGoodDetailVo.getNew();
        GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
        GoblinGoodsInfoDetailVo goblinGoodsInfoDetailVo = GoblinGoodsInfoDetailVo.getNew();
        //skuIdList
        if (null != goblinGoodsInfoVo) {
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoDetailVo);
            goblinFrontGoodDetailVo.setGoblinGoodsInfoVo(goblinGoodsInfoDetailVo);
            // int limit= getStockCount(goblinGoodsInfoVo.getStoreId());
            List<String> skuIdList = goblinGoodsInfoVo.getSkuIdList();
            ArrayList<GoblinGoodsSkuInfoDetailVo> list = ObjectUtil.goblinGoodsSkuInfoDetailVos();
            for (String sku : skuIdList) {
                String userId = CurrentUtil.getCurrentUid();
                if (StringUtils.isNotBlank(userId)) {
                    buyCount = goblinRedisUtils.getSkuCountByUid(userId, sku);
                }
                GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(sku);
                if (null != goblinGoodsSkuInfoVo && goblinGoodsSkuInfoVo.getDelFlg().equals("0") && goblinGoodsSkuInfoVo.getShelvesStatus().equals("3")) {
                    //获取 sku 库存数量
                    String pre = GoblinStatusConst.MarketPreStatus.getPre(spuId);
                    int stock = goblinRedisUtils.getSkuStock(pre, goblinGoodsSkuInfoVo.getSkuId());
                    log.debug("skuId:{},库存数量{}", goblinGoodsSkuInfoVo.getSkuId(), stock);
                    GoblinGoodsSkuInfoDetailVo goblinGoodsSkuInfoDetailVo = GoblinGoodsSkuInfoDetailVo.getNew();
                    BeanUtils.copyProperties(goblinGoodsSkuInfoVo, goblinGoodsSkuInfoDetailVo);
                    fillSkuPicIfBlank(goblinGoodsSkuInfoDetailVo, goblinGoodsInfoVo);
                    if (0 != goblinGoodsSkuInfoDetailVo.getBuyLimit()) {
                        if (null == buyCount) {
                            buyCount = 0;
                        }
                        goblinGoodsSkuInfoDetailVo.setCanBuy(goblinGoodsSkuInfoDetailVo.getBuyLimit() - buyCount);
                    } else {
                        goblinGoodsSkuInfoDetailVo.setCanBuy(-9999);
                    }
                    if (stock <= 0) {
                        goblinGoodsSkuInfoDetailVo.setStockLess(true);
                    } else {
                        goblinGoodsSkuInfoDetailVo.setStockLess(false);
                    }
                    goblinGoodsSkuInfoDetailVo.setRestStock(stock);
                    list.add(goblinGoodsSkuInfoDetailVo);
                }
            }
            //goblinGoodsInfoVo
            GoblinStoreInfoVo goblinStoreInfoVo = this.getStore(goblinGoodsInfoVo.getStoreId());
            if (null != goblinStoreInfoVo) {
                goblinFrontGoodDetailVo.setStoreName(goblinStoreInfoVo.getStoreName());
            }
            goblinFrontGoodDetailVo.setGoblinGoodsSkuInfoVolist(list);
        } else {
            return null;
        }
        ArrayList<String> list = goblinCouponService.getSpuType(spuId, goblinGoodsInfoDetailVo.getStoreId());
        goblinFrontGoodDetailVo.setGetSpuType(list);


        // 设置条码命中的SKUID列表
        List<String> hitSkuIdList = skuQueryResultList.stream().filter(r -> r.getSpuId().equals(spuId)).map(GoblinGoodsSkuInfoVo::getSkuId).collect(Collectors.toList());
        goblinFrontGoodDetailVo.setHitSkuIdList(hitSkuIdList);
        return goblinFrontGoodDetailVo;
    }

    /**
     * 获取组件排序
     */
    public List getMoudleIndex() {
        if (!redisUtil.hasKey(GoblinRedisConst.MOUDLE_INDEX)) {
            return null;
        }
        //GoblinGoodsInfoVo goblinGoodsInfoVo=goblinRedisUtils.get(spuId);
        List<GoblinFrontMoudleIndex> list = (List<GoblinFrontMoudleIndex>) redisUtil.get(GoblinRedisConst.MOUDLE_INDEX);
        return list;
    }

    /***
     * @author zhangfuxin
     * @Description:获取魔方
     * @date 2022/1/10 下午4:49
     */
    public GoblinFrontCubeVo getRecommend() {
        GoblinFrontCubeVo goblinFrontCubeVo = GoblinFrontCubeVo.getNew();
        ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList = ObjectUtil.getGoblinGoodsInfoVos();
        if (!redisUtil.hasKey(GoblinRedisConst.FRONT_GOBLIN_RECOMMEND)) {
            return null;
        }
        List<GoblinFrontCube> list = (List<GoblinFrontCube>) redisUtil.get(GoblinRedisConst.FRONT_GOBLIN_RECOMMEND);
        if (list.size() > 0) {
            BeanUtils.copyProperties(list.get(0), goblinFrontCubeVo);
            for (String spuid : goblinFrontCubeVo.getSpuId().split(",")) {
                GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuid);
                if (null != goblinGoodsInfoVo) {
                    GoblinGoodsInfoVo goblinGoodsInfoVo1 = GoblinGoodsInfoVo.getNew();
                    BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoVo1);
                    goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo1);
                }
            }
            goblinFrontCubeVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);

        } else {
            return null;
        }
        return goblinFrontCubeVo;
    }

    /***
     * @author zhangfuxin
     * @Description:获取魔方
     * @date 2022/1/10 下午4:49
     */
    public GoblinFrontCubeVo getCube() {
        GoblinFrontCubeVo goblinFrontCubeVo = GoblinFrontCubeVo.getNew();
        ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList = ObjectUtil.getGoblinGoodsInfoVos();
        if (!redisUtil.hasKey(GoblinRedisConst.FRONT_GOBLINFRONTCUBE)) {
            return null;
        }
        List<GoblinFrontCube> list = (List<GoblinFrontCube>) redisUtil.get(GoblinRedisConst.FRONT_GOBLINFRONTCUBE);
        if (list.size() > 0) {
            BeanUtils.copyProperties(list.get(0), goblinFrontCubeVo);
            for (String spuid : goblinFrontCubeVo.getSpuId().split(",")) {
                GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuid);
                if (null != goblinGoodsInfoVo) {
                    GoblinGoodsInfoVo goblinGoodsInfoVo1 = GoblinGoodsInfoVo.getNew();
                    BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoVo1);
                    goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo1);
                }
            }
            goblinFrontCubeVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);

        }
        return goblinFrontCubeVo;
    }

    public GoblinStoreInfoVo getStore(String storId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("storeId").is(storId).and("spuAppear").is("0").and("delFlg").is("0").and("shelvesStatus").is("3"));
        long count = mongoTemplate.count(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        GoblinStoreInfoVo goblinStoreInfoVo = goblinRedisUtils.getStoreInfoVo(storId);
        //GoblinStoreNoticeVo goblinStoreNoticeVo=goblinRedisUtils.getStoreNoticeVo(storId,LocalDateTime.now());
        goblinStoreInfoVo.setCount((int) count);
        return goblinStoreInfoVo;
    }

    /***
     * @author zhangfuxin
     * @Description:获得商铺分类
     * @date 2022/1/18 下午1:44
     */
    public List<GoblinStoreGoodsCategoryVo> getStoreCategory(String storId) {
        //店铺分类数据源
        List<GoblinStoreGoodsCategoryVo> list = goblinRedisUtils.getStoreGoodsCategoryVos(storId);
        return list;
    }

    /**
     * 找到分类
     */
    public GoblinCategoryzfVo getCategory(String categoryId) {
        GoblinCategoryzfVo goblinCategoryzfVo = GoblinCategoryzfVo.getNew();
        ArrayList<GoblinSelfGoodsCategoryVo> list1 = ObjectUtil.getGoblinSelfGoodsCategoryVoArrayList();
        //先找到   当前的分类id
        GoblinSelfGoodsCategoryVo pa = null;
        //获取到分类
        List<GoblinSelfGoodsCategoryVo> list = goblinRedisUtils.getSelfGoodsCategoryVos();
        for (GoblinSelfGoodsCategoryVo goblinSelfGoodsCategoryVo : list) {
            if (categoryId.equals(goblinSelfGoodsCategoryVo.getCateId())) {
                goblinCategoryzfVo.setGoblinSelfGoodsCategoryVo(goblinSelfGoodsCategoryVo);
                pa = goblinSelfGoodsCategoryVo;
            }
        }
        //找到  该分类的子集
        if (null != pa) {
            for (GoblinSelfGoodsCategoryVo goblinSelfGoodsCategoryVo : list) {
                if (pa.getCateId().equals(goblinSelfGoodsCategoryVo.getCatePid())) {
                    list1.add(goblinSelfGoodsCategoryVo);
                }

            }
        }
        goblinCategoryzfVo.setList(list1);
        return goblinCategoryzfVo;

    }

    public GoblinGoodsInfoListVoo searchGoodesName(String name, int page, int pageSize) {
        List<String> listStore = mongoUtils.getStoreInfoVoRegexName(name);
        Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        query.addCriteria(Criteria.where("spuAppear").is("0").and("delFlg").is("0").and("shelvesStatus").is("3").and("marketId").is(null).and("cateFid").nin("22196120924543", "22196122839313").andOperator(
                new Criteria().orOperator(
                        Criteria.where("name").regex(pattern),
                        Criteria.where("storeId").in(listStore),
                        Criteria.where("extagVoList.tagName").is(name)
                ),
                new Criteria().orOperator(Criteria.where("spuType").exists(false), (Criteria.where("spuType").in(0, 2)))
        ));
        long count = mongoTemplate.count(query, GoblinGoodsInfoVo.class.getSimpleName());
        query.with(PageRequest.of(page, pageSize)).with(Sort.by(
                //Sort.Order.desc("count"),
                Sort.Order.desc("shelvesAt")
        ));
        List<GoblinGoodsInfoVo> list = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());

        GoblinGoodsInfoListVoo goblinGoodsInfoListVoo = GoblinGoodsInfoListVoo.getNew();
        goblinGoodsInfoListVoo.setCount(count);
        ArrayList<GoblinGoodsInfoListVo> list1 = ObjectUtil.getGoblinGoodsInfoListVo();
        //遍历
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            //有音乐人的放前面
            if (null != goblinGoodsInfoVo.getExtagVoList() && goblinGoodsInfoVo.getExtagVoList().size() > 0) {
                GoblinStoreInfoVo goblinStoreInfoVo = goblinRedisUtils.getStoreInfoVo(goblinGoodsInfoVo.getStoreId());
                if (null != goblinStoreInfoVo) {
                    goblinGoodsInfoVo.setStoreName(goblinStoreInfoVo.getStoreName());
                }
                GoblinGoodsInfoListVo goblinGoodsInfoListVo = GoblinGoodsInfoListVo.getNew();
                BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoListVo);
                list1.add(goblinGoodsInfoListVo);
            }
        }
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            if (null != goblinGoodsInfoVo.getExtagVoList() && goblinGoodsInfoVo.getExtagVoList().size() > 0) {
            } else {
                //无音乐人标签的
                GoblinStoreInfoVo goblinStoreInfoVo = goblinRedisUtils.getStoreInfoVo(goblinGoodsInfoVo.getStoreId());
                if (null != goblinStoreInfoVo) {
                    goblinGoodsInfoVo.setStoreName(goblinStoreInfoVo.getStoreName());
                }
                GoblinGoodsInfoListVo goblinGoodsInfoListVo = GoblinGoodsInfoListVo.getNew();
                BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoListVo);
                list1.add(goblinGoodsInfoListVo);
            }
        }
        goblinGoodsInfoListVoo.setList(list1);
        return goblinGoodsInfoListVoo;
        //return list1;
    }

    public GoblinFrontCategoryListVo getStoreGoodes(String storeId, String categoryId, String name) {
        String configVal = "";
        List<GoblinStoreConfigVo> listVo = goblinRedisUtils.getStoreConfigVos(storeId);
        //ONOFF_SOLD_OUT_SHOW  ON  开启
        for (GoblinStoreConfigVo goblinStoreConfigVo : listVo) {
            //获取是 售罄是否开启
            if (goblinStoreConfigVo.getConfigKey().equals(GoblinStoreConf.ONOFF_SOLD_OUT_SHOW)) {
                configVal = goblinStoreConfigVo.getConfigVal();
            }
        }
        //
        Query query = new Query();
        query.addCriteria(Criteria.where("storeId").is(storeId).and("spuAppear").is("0").and("delFlg").is("0").and("shelvesStatus").is("3").and("marketId").is(null).and("cateFid").nin("22196120924543", "22196122839313"));
        if (StringUtil.isNotBlank(categoryId)) {
            query.addCriteria(new Criteria().orOperator(
                    Criteria.where("storeCateFid").is(categoryId),
                    Criteria.where("storeCateSid").is(categoryId),
                    Criteria.where("storeCateTid").is(categoryId)
            ));
        }
        if (StringUtil.isNotBlank(name)) {
            Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(pattern));
        }
        query.with(Sort.by(Sort.Direction.DESC, "shelvesAt"));
        // 查询总数
        List<GoblinGoodsInfoVo> list = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        // 计算库存
        Iterator<GoblinGoodsInfoVo> iterator = list.iterator();
        //删掉库存没有的商品
        while (iterator.hasNext()) {
            GoblinGoodsInfoVo goblinGoodsInfoVo = iterator.next();
            List<String> skuIdList = goblinGoodsInfoVo.getSkuIdList();
            int count = 0;
            for (String skuId : skuIdList) {
                count = count + goblinRedisUtils.getSkuStock(null, skuId);
            }
            if (StringUtil.isNotBlank(configVal) && !configVal.equals("ON")) {
                if (count == 0) {
                    iterator.remove();
                }
            }
        }
        ArrayList<GoblinGoodsInfoListVo> listVos = ObjectUtil.getGoblinGoodsInfoListVo();
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            GoblinGoodsInfoListVo goblinGoodsInfoListVo = GoblinGoodsInfoListVo.getNew();
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoListVo);
            listVos.add(goblinGoodsInfoListVo);
        }
        GoblinFrontCategoryListVo goblinFrontCategoryListVo = GoblinFrontCategoryListVo.getNew();
        goblinFrontCategoryListVo.setSpuList(listVos);
        return goblinFrontCategoryListVo;
    }

    /**
     * 音乐人列表
     */
    public GoblinFrontCategoryListVo getMusic(String tagId, String type, int page, int pageSize) {
        //
        Query query = new Query();
        query.addCriteria(new Criteria().orOperator(
                Criteria.where("extagVoList.tagId").is(tagId).and("spuAppear").is("0").and("delFlg").is("0").and("shelvesStatus").is("3").and("cateFid").nin("22196120924543", "22196122839313").and("marketId").is(null)
        ));
        Pageable pageable = null;
        //
        boolean isRe = false;
        if (type.equals("1")) {
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "count"));
        } else if (type.equals("2")) {
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "shelvesAt"));
        } else if (type.equals("3")) {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "priceGe"));
        } else if (type.equals("4")) {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.ASC, "priceGe"));
        }
        // 排序 分页
        // Query query = Query.query(Criteria.where("status").ne(1).and("status").ne(0));

        // 查询总数
        long count = mongoTemplate.count(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        query.with(pageable);
        List<GoblinGoodsInfoVo> list = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        /*if(list.size()>0&&isRe){
            //找到 销量
            for(GoblinGoodsInfoVo goblinGoodsInfoVo:list){
                Integer counts=goblinRedisUtils.getSpuSaleCount(goblinGoodsInfoVo.getSpuId());
                if(counts==null){
                    goblinGoodsInfoVo.setCount(0);
                }else{
                    goblinGoodsInfoVo.setCount(counts);
                }
            }
            Collections.sort(list, new Comparator<GoblinGoodsInfoVo>() {
                public int compare(GoblinGoodsInfoVo arg0, GoblinGoodsInfoVo arg1) {
                    return -(arg0.getCount().compareTo(arg1.getCount()));
                }});
        }*/
        ArrayList<GoblinGoodsInfoListVo> listVos = ObjectUtil.getGoblinGoodsInfoListVo();
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            GoblinGoodsInfoListVo goblinGoodsInfoListVo = GoblinGoodsInfoListVo.getNew();
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoListVo);
            listVos.add(goblinGoodsInfoListVo);
        }
        GoblinFrontCategoryListVo goblinFrontCategoryListVo = GoblinFrontCategoryListVo.getNew();
        goblinFrontCategoryListVo.setCount(count);
        goblinFrontCategoryListVo.setSpuList(listVos);
        return goblinFrontCategoryListVo;
    }

    /**
     * 获取分类列表
     * 1、销量优先、2、新品优先、3、价格降序、4、价格升序
     */
    public GoblinFrontCategoryListVo getCategoryList(String type, String categoryId, int page, int pageSize) {
        //
        Query query = new Query();
        query.addCriteria(new Criteria().orOperator(
                Criteria.where("cateFid").is(categoryId),
                Criteria.where("cateSid").is(categoryId),
                Criteria.where("cateTid").is(categoryId)
        ));
        query.addCriteria(Criteria.where("spuAppear").is("0").and("delFlg").is("0").and("shelvesStatus").is("3").and("marketId").is(null));
        Pageable pageable = null;
        //
        if (type.equals("1")) {
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "count", "createdAt"));
        } else if (type.equals("2")) {
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "shelvesAt", "createdAt"));
        } else if (type.equals("3")) {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "priceGe", "createdAt"));
        } else if (type.equals("4")) {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.ASC, "priceGe", "createdAt"));
        }
        // 排序 分页
        // Query query = Query.query(Criteria.where("status").ne(1).and("status").ne(0));

        // 查询总数
        long count = mongoTemplate.count(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        query.with(pageable);
        List<GoblinGoodsInfoVo> list = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        GoblinFrontCategoryListVo goblinFrontCategoryListVo = GoblinFrontCategoryListVo.getNew();
        goblinFrontCategoryListVo.setCount(count);
        ArrayList<GoblinGoodsInfoListVo> listVos = ObjectUtil.getGoblinGoodsInfoListVo();
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            GoblinGoodsInfoListVo goblinGoodsInfoListVo = GoblinGoodsInfoListVo.getNew();
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoListVo);
            listVos.add(goblinGoodsInfoListVo);
        }
        goblinFrontCategoryListVo.setSpuList(listVos);
        return goblinFrontCategoryListVo;
    }

    /**
     * 获取 mongodb里面的spuId
     *
     * @return
     */
    public String getspuId(String spuids, int page, int pageSize) {
        Query query = new Query();
        if (StringUtil.isNotBlank(spuids)) {
            query.addCriteria(Criteria.where("spuId").nin(spuids.split(",")));
        }
        query.addCriteria(Criteria.where("delFlg").is("0").and("shelvesStatus").is("3").and("spuAppear").is("0").and("marketId").is(null)
                .and("spuType").ne(33).and("showInMall").ne(0).and("cateFid").nin("22196120924543", "22196122839313").and("name").not().regex(Pattern.compile(SELECT_GOODS_EXCLUDE_NAME)));


        //redis里面获取排序规则 1、上架时间2、销量3、价格高到低4、价格低到高
        int sortType = 0;
        if (redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS_SORT)) {
            sortType = (int) redisUtil.get(GoblinRedisConst.SELECT_GOODS_SORT);
        }
        Sort sortName = null;
        if (sortType == 1) {
            sortName = Sort.by(Sort.Direction.DESC, "shelvesAt");
        } else if (sortType == 2) {
            sortName = Sort.by(Sort.Direction.DESC, "count", "createdAt");
        } else if (sortType == 3) {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            sortName = Sort.by(Sort.Direction.DESC, "priceGe");
        } else {
            Document source = new Document();
            source.put("locale", "zh");
            source.put("numericOrdering", true);
            Collation collation = Collation.from(source);
            query.collation(collation);
            sortName = Sort.by(Sort.Direction.ASC, "priceGe");
        }
       /* Pageable pageable = PageRequest.of(page, pageSize, sortName);
        query.with(pageable);*/
        query.with(sortName);
        List<GoblinGoodsInfoVo> list = mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
        StringBuffer sb = new StringBuffer();
        int index = 0;
        for (GoblinGoodsInfoVo goblinGoodsInfoVo : list) {
            if (index == 0) {
                sb.append(goblinGoodsInfoVo.getSpuId());
            } else {
                sb.append("," + goblinGoodsInfoVo.getSpuId());
            }
            index++;
        }
        return sb.toString();
    }

    public void setPage1(List<GoblinFrontSelectGoods> list, int pageSize) {
        StringBuffer sb = new StringBuffer();
        //足够了  拼接字符串
        int i = 0;
        for (GoblinFrontSelectGoods goblinFrontSelectGoods : list) {
            if (i == 0) {
                sb.append(goblinFrontSelectGoods.getSpuId());
            } else {
                sb.append("," + goblinFrontSelectGoods.getSpuId());
            }
            i++;
            if (i == pageSize) break;
        }
        redisUtil.set(GoblinRedisConst.SELECT_GOODS_PAGE1, sb.toString());
    }

    public void setPage1AndSpu(List<GoblinFrontSelectGoods> list, int pageSize) {
        validate(list);
        //sb 为配置的 精选商品 spuid
        StringBuffer sb = new StringBuffer();
        if (null != list && list.size() > 0) {
            int i = 0;
            for (GoblinFrontSelectGoods goblinFrontSelectGoods : list) {
                if (i == 0) {
                    sb.append(goblinFrontSelectGoods.getSpuId());
                } else {
                    sb.append("," + goblinFrontSelectGoods.getSpuId());
                }
                i++;
            }
        }
        //获得没有配置的spuid   s 是没有配置的精选商品spuid
        String s = this.getspuId(sb.toString(), 0, 0);
        String supids = "";
        if (StringUtil.isNotBlank(sb.toString()) && StringUtil.isNotBlank(s)) {
            supids = sb.toString() + "," + s;
        } else if (StringUtil.isNotBlank(sb.toString())) {
            supids = sb.toString();
        } else if (StringUtil.isNotBlank(s)) {
            supids = s;
        }
        log.debug("spuid所有的为:{}", supids);
        int index = 0;
        //sb1 为 第一页的 spuid
        StringBuffer sb1 = new StringBuffer();
        for (String ss : supids.split(",")) {
            if (index == 0) {
                sb1.append(ss);
            } else {
                sb1.append("," + ss);
            }

            index++;
            if (index == pageSize) {
                break;
            }
        }
        redisUtil.set(GoblinRedisConst.SELECT_GOODS_PAGE1, sb1.toString());
        redisUtil.set(GoblinRedisConst.SELECT_GOODS_SPUIDS, supids);
        if (StringUtil.isBlank(supids)) {
            redisUtil.set(GoblinRedisConst.SELECT_GOODS_SPUIDS_ISHAVE, "1");
        }
    }

    public void validate(List<GoblinFrontSelectGoods> list) {
        if (null != list && list.size() > 0) {
            Iterator<GoblinFrontSelectGoods> it = list.iterator();
            while (it.hasNext()) {
                GoblinFrontSelectGoods goblinFrontSelectGoods = it.next();
                if (StringUtils.isBlank(goblinFrontSelectGoods.getSpuId())) {
                    it.remove();
                } else {
                    GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(goblinFrontSelectGoods.getSpuId());
                    if (null == goblinGoodsInfoVo || StringUtil.isNotBlank(goblinGoodsInfoVo.getMarketId()) || isPassportExclusive(goblinGoodsInfoVo)
                            || isSqbSpuGoods(goblinGoodsInfoVo) || isNotShowInMall(goblinGoodsInfoVo)) {
                        it.remove();
                    }
                }
            }
        }
    }

    public String getRedisKey(String key) {
        Object value = redisUtil.get(key);
        if (null != value) {
            return value.toString();
        } else {
            return "";
        }
    }

    /**
     * @author zhangfuxin
     * @Description:精选商品列表
     * @date 2022/1/5 下午3:00
     */
    @Override
    public GoblinFrontSelectGoodVo getSelectGoods(int page, int pageSize) {
        GoblinFrontSelectGoodVo goblinFrontSelectGoodVo = GoblinFrontSelectGoodVo.getNew();
        if (redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS_SPUIDS_ISHAVE)) {
            return goblinFrontSelectGoodVo;
        }
        //先从redis里 查 是否有第一页的值
        String spuIds = "";
        if (page == 0) {
            String selectGoodsPage1 = getRedisKey(GoblinRedisConst.SELECT_GOODS_PAGE1);
            if (StringUtil.isNotBlank(selectGoodsPage1)) {
                String[] spuids = selectGoodsPage1.split(",");
                log.debug("spuids{}", spuids);
                ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList = ObjectUtil.getGoblinGoodsInfoVos();
                for (String id : spuids) {
                    GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(id);
                    if (null != goblinGoodsInfoVo) {
                        if (isHidden(goblinGoodsInfoVo.getCateFid())) {
                            continue;
                        }
                        if (isPassportExclusive(goblinGoodsInfoVo)) {
                            continue;
                        }
                        if (isSqbSpuGoods(goblinGoodsInfoVo)) {
                            continue;
                        }
                        if (isNotShowInMall(goblinGoodsInfoVo)) {
                            continue;
                        }
                        goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo);
                    }
                }
                goblinFrontSelectGoodVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);
                return goblinFrontSelectGoodVo;
            } else {
                //从redis里面查出配置的 spu
                if (redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS)) {
                    List<GoblinFrontSelectGoods> list = (List<GoblinFrontSelectGoods>) redisUtil.get(GoblinRedisConst.SELECT_GOODS);
                    validate(list);
                    if (list.size() >= pageSize) {
                        this.setPage1(list, pageSize);
                        return this.getSelectGoods(page, pageSize);
                    } else {
                        setPage1AndSpu(list, pageSize);
                        return this.getSelectGoods(page, pageSize);
                    }
                } else {
                    setPage1AndSpu(null, pageSize);
                    return this.getSelectGoods(page, pageSize);
                }
            }
        } else {
        /*    //查看是否有 配置的 spuid的顺序
            String selectGoodsSpuids= getRedisKey(GoblinRedisConst.SELECT_GOODS_PAGE1);
            if(StringUtil.isBlank(selectGoodsSpuids)){
                List<GoblinFrontSelectGoods> list= (List<GoblinFrontSelectGoods>) redisUtil.get(GoblinRedisConst.SELECT_GOODS);
                setPage1AndSpu(list,pageSize);
                this.getSelectGoods(page,pageSize);
            }
            String[] spuidss=selectGoodsSpuids.split(",");*/

            //查看是否有 配置的 spuid的顺序
            /*  String selectGoodsSpuids= getRedisKey(GoblinRedisConst.SELECT_GOODS_PAGE1);*/
            if (!redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS_SPUIDS)) {
                List<GoblinFrontSelectGoods> list = (List<GoblinFrontSelectGoods>) redisUtil.get(GoblinRedisConst.SELECT_GOODS);
                setPage1AndSpu(list, pageSize);
                this.getSelectGoods(page, pageSize);
            }
            String[] spuidss = redisUtil.get(GoblinRedisConst.SELECT_GOODS_SPUIDS).toString().split(",");
            //String[] spuidss=selectGoodsSpuids.split(",");

            //找到对应的spuid
            int start = page * pageSize;
            int end = (page + 1) * pageSize;
            if (end > spuidss.length) {
                end = spuidss.length;
            }
            ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList = ObjectUtil.getGoblinGoodsInfoVos();
            for (int i = 0; i < end; i++) {
                if (i >= start) {
                    GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuidss[i]);
                    if (null == goblinGoodsInfoVo) {
                        continue;
                    }
                    if (isHidden(goblinGoodsInfoVo.getCateFid())) {
                        continue;
                    }
                    if (isPassportExclusive(goblinGoodsInfoVo)) {
                        continue;
                    }
                    if (isSqbSpuGoods(goblinGoodsInfoVo)) {
                        continue;
                    }
                    if (isNotShowInMall(goblinGoodsInfoVo)) {
                        continue;
                    }
                    goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo);
                }
            }
            goblinFrontSelectGoodVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);
            goblinFrontSelectGoodVo.setCount(spuidss.length);
            return goblinFrontSelectGoodVo;
        }


      /*  String spuIds="";
        if(!redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS)){
            //查看redis里面第一页的商品
            if(redisUtil.hasKey(GoblinRedisConst.SELECT_GOODS_PAGE1)){
                spuIds= (String) redisUtil.get(GoblinRedisConst.SELECT_GOODS_PAGE1);
            }else{
                Query query = new Query();
                query.addCriteria(Criteria.where("delFlg").is("0").and("shelvesStatus").is("3"));
                //直接从库里查
                PageRequest pageable = PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "count"));
                query.with(pageable);
                List<GoblinGoodsInfoVo> voList=mongoTemplate.find(query, GoblinGoodsInfoVo.class, GoblinGoodsInfoVo.class.getSimpleName());
            return null;
        }else{

        }*/
        /*//redis 取出精选商品列表
        List<GoblinFrontSelectGoods> list= (List<GoblinFrontSelectGoods>) redisUtil.get(GoblinRedisConst.SELECT_GOODS);
        if(null!=list&&list.size()==1){
            //获取商品列表
            String spuId=list.get(0).getSpuId();
            int start=page*pageSize;
            int end =start+pageSize;
            String[] ids=spuId.split(",");
            if(end>ids.length){
                end=ids.length;
            }
            //创建
            GoblinFrontSelectGoodVo goblinFrontSelectGoodVo=GoblinFrontSelectGoodVo.getNew();
            goblinFrontSelectGoodVo.setCount(ids.length);
            //
            ArrayList<GoblinGoodsInfoVo> goblinGoodsInfoVoArrayList= ObjectUtil.getGoblinGoodsInfoVos();
            for(int i=0;i<end;i++){
               if (i>=start){
                   GoblinGoodsInfoVo goblinGoodsInfoVo= goblinRedisUtils.getGoodsInfoVo(ids[i]);
                   goblinGoodsInfoVoArrayList.add(goblinGoodsInfoVo);
               }
            }
            goblinFrontSelectGoodVo.setGoblinGoodsInfoVoList(goblinGoodsInfoVoArrayList);
            return goblinFrontSelectGoodVo;
        }*/
//        return null;
    }

    @Override
    public GoblinSqbPerformanceSelectGoodVo getPerformanceSelectGoods(String performancesId, int page, int pageSize) {
        GoblinSqbPerformanceSelectGoodVo respVo = GoblinSqbPerformanceSelectGoodVo.getNew();
        if (StringUtil.isBlank(performancesId)) {
            respVo.setCount(0);
            respVo.setGoblinGoodsInfoVoList(new ArrayList<GoblinSqbPerformanceGoodsInfoVo>());
            return respVo;
        }

        int safePage = Math.max(page, 0);
        int safePageSize = pageSize <= 0 ? 40 : Math.min(pageSize, 100);

        // 演出结束且后台开启「演出结束自动下架」时，前台列表不返回商品（仅展示控制，不取消关联、不修改商品上下架）
        GoblinSqbPerformanceConfig sqbPerfCfg = goblinSqbPerformanceConfigMapper.selectById(performancesId.trim());
        boolean hideListWhenPerformanceEnded = sqbPerfCfg != null && sqbPerfCfg.getAutoOffline() != null && sqbPerfCfg.getAutoOffline() == 1;
        if (hideListWhenPerformanceEnded) {
            KylinPerformanceVo perfVo = goblinRedisUtils.getPerformanceVo(performancesId);
            if (perfVo != null && StringUtil.isNotBlank(perfVo.getTimeEnd())) {
                try {
                    String nowTimeStr = DateUtil.getNowTime();
                    if (1 == DateUtil.compareStrDay(nowTimeStr, perfVo.getTimeEnd())) {
                        respVo.setCount(0);
                        respVo.setGoblinGoodsInfoVoList(new ArrayList<GoblinSqbPerformanceGoodsInfoVo>());
                        return respVo;
                    }
                } catch (Exception e) {
                    log.warn("演出结束时间比较异常 performancesId={}, timeEnd={}", performancesId, perfVo.getTimeEnd(), e);
                }
            }
        }

        // 1. 全量关联关系：Redis → DB → 回写（与 loadSqbLinkedSkuIdSet 有演出 ID 时共用）
        List<GoblinSqbPerformanceGoods> relations = loadSqbPerformanceGoodsRelationsFromCacheOrDb(performancesId);

        // 4. 每次请求都实时校验商品状态（delFlg, shelvesStatus 等）
        // 这样如果商品在 SPU 层面下架，虽然关联关系还在缓存，但这里会动态过滤掉
        ArrayList<GoblinSqbPerformanceGoodsInfoVo> allGoods = new ArrayList<GoblinSqbPerformanceGoodsInfoVo>();
        if (!CollectionUtils.isEmpty(relations)) {
            // relations 按 SKU 关联：同一 SPU 可多条；列表按 SPU 去重展示，但 SKU 列表只保留本演出已关联的 SKU。
            LinkedHashMap<String, GoblinSqbPerformanceGoods> firstRelBySpu = new LinkedHashMap<>();
            LinkedHashMap<String, LinkedHashSet<String>> linkedSkusBySpu = new LinkedHashMap<>();
            for (GoblinSqbPerformanceGoods rel : relations) {
                if (rel == null || StringUtil.isBlank(rel.getSpuId())) {
                    continue;
                }
                firstRelBySpu.putIfAbsent(rel.getSpuId(), rel);
                if (StringUtil.isNotBlank(rel.getSkuId())) {
                    linkedSkusBySpu.computeIfAbsent(rel.getSpuId(), k -> new LinkedHashSet<>()).add(rel.getSkuId().trim());
                }
            }

            for (GoblinSqbPerformanceGoods rel : firstRelBySpu.values()) {
                if (rel == null || StringUtil.isBlank(rel.getSpuId())) {
                    continue;
                }
                LinkedHashSet<String> linkedSkuIds = linkedSkusBySpu.get(rel.getSpuId());
                if (linkedSkuIds == null) {
                    linkedSkuIds = new LinkedHashSet<>();
                }
                if (linkedSkuIds.isEmpty()) {
                    continue;
                }
                // 从 Redis SPU 缓存获取详情（SPU 详情由其他逻辑负责更新缓存，这里始终拿最新状态）
                GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(rel.getSpuId());
                if (goodsInfoVo == null) {
                    continue;
                }
                // 动态过滤：演出关联列表只展示在线、未删除、且上架状态为 3 的商品
                if (!"0".equals(goodsInfoVo.getDelFlg())) {
                    continue;
                }
                if (!"0".equals(goodsInfoVo.getSpuAppear())) {
                    continue;
                }
                if (!"3".equals(goodsInfoVo.getShelvesStatus())) {
                    continue;
                }
                if (StringUtil.isNotBlank(goodsInfoVo.getMarketId())) {
                    continue;
                }

                GoblinSqbPerformanceGoodsInfoVo frontGoods = new GoblinSqbPerformanceGoodsInfoVo();
                BeanUtils.copyProperties(goodsInfoVo, frontGoods);
                BigDecimal normalPrice = resolveGoodsSellPrice(goodsInfoVo, linkedSkuIds);
                frontGoods.setSellPrice(normalPrice);
                frontGoods.setPrice(normalPrice);
                frontGoods.setSettlementPrice(rel.getSettlementPrice());
                frontGoods.setGoblinGoodsSkuInfoVolist(buildOnShelfSkuDetailList(goodsInfoVo, linkedSkuIds));
                allGoods.add(frontGoods);
            }
        }

        int total = allGoods.size();
        respVo.setCount(total);
        int start = safePage * safePageSize;
        if (start >= total) {
            respVo.setGoblinGoodsInfoVoList(allGoods);
            return respVo;
        }
        int end = Math.min(start + safePageSize, total);
        ArrayList<GoblinSqbPerformanceGoodsInfoVo> pageList = new ArrayList<GoblinSqbPerformanceGoodsInfoVo>();
        pageList.addAll(allGoods.subList(start, end));
        respVo.setGoblinGoodsInfoVoList(pageList);

        return respVo;
    }

    private BigDecimal resolveGoodsSellPrice(GoblinGoodsInfoVo goodsInfoVo, Set<String> allowedSkuIds) {
        if (goodsInfoVo == null) {
            return null;
        }
        if (goodsInfoVo.getSellPrice() != null) {
            return goodsInfoVo.getSellPrice();
        }

        BigDecimal minSkuPrice = null;
        if (!CollectionUtils.isEmpty(goodsInfoVo.getSkuIdList())) {
            for (String skuId : goodsInfoVo.getSkuIdList()) {
                if (allowedSkuIds != null && !allowedSkuIds.contains(skuId)) {
                    continue;
                }
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                if (skuInfoVo == null) {
                    continue;
                }

                BigDecimal skuShowPrice = skuInfoVo.getSellPrice() != null ? skuInfoVo.getSellPrice()
                        : skuInfoVo.getPrice();
                if (skuShowPrice == null) {
                    continue;
                }

                if (minSkuPrice == null || skuShowPrice.compareTo(minSkuPrice) < 0) {
                    minSkuPrice = skuShowPrice;
                }
            }
        }
        if (minSkuPrice != null) {
            return minSkuPrice;
        }
        if (goodsInfoVo.getPriceGe() != null) {
            return goodsInfoVo.getPriceGe();
        }
        return goodsInfoVo.getPriceLe();
    }

    @Override
    public List<GoblinGoodsInfoVo> getGoodByMusicTagP(String musicTag, String performanceId) {
        return goblinRedisUtils.getMusicTagList(musicTag, performanceId);
    }

    public boolean belongCalendar(String startString, String endString) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.DATE_FULL_STR);//注意月份是MM
        Date from = simpleDateFormat.parse(startString);
        Date end = simpleDateFormat.parse(endString);
        Calendar date = Calendar.getInstance();
        date.setTime(new Date());
        Calendar after = Calendar.getInstance();
        after.setTime(from);
        Calendar before = Calendar.getInstance();
        before.setTime(end);
        if (date.after(after) && date.before(before)) {
            return true;
        } else {
            return false;
        }
    }

    //判断是否是该时间之后
    public boolean afterCalendar(String time) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.DATE_FULL_STR);//注意月份是MM
        Calendar date = Calendar.getInstance();
        date.setTime(new Date());
        Date timefrom = simpleDateFormat.parse(time);
        if (date.after(timefrom)) {
            return true;
        } else {
            return false;
        }
    }

    //判断是否是该时间之后
    public boolean beforeCalendar(String time) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.DATE_FULL_STR);//注意月份是MM
        Calendar date = Calendar.getInstance();
        date.setTime(new Date());
        Date timefrom = simpleDateFormat.parse(time);
        if (date.before(timefrom)) {
            return true;
        } else {
            return false;
        }
    }

    public boolean validateShoopCartNumber(String skuId, String type, Integer buyCount, String userId) {
        if (!type.equals("1")) {
            return true;
        }
        //获取sku
        GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
        if (null == goblinGoodsSkuInfoVo) {
            return false;
        }
        if (null == goblinGoodsSkuInfoVo.getBuyLimit() || goblinGoodsSkuInfoVo.getBuyLimit() == 0) {
            return true;
        }
        //已经购买的数量
        Integer buyCounts = goblinRedisUtils.getSkuCountByUid(userId, skuId);
        if (goblinGoodsSkuInfoVo.getBuyLimit() < (buyCounts + buyCount)) {
            //
            return false;
        }
        return true;
    }

    /**
     * @author zhangfuxin
     * @Description:添加购物车
     * @date 2022/1/11 下午4:16
     */
    public ResponseDto addShoopCart(String spuId, String storeId, String skuId, Integer number, String userId, String type) {
        if (null == number || number <= 0) {
            return ResponseDto.success(false);
        }
        boolean isGoods = false;
        String cardId = "";
        //判断该用户 redis里是否有购物车
        GoblinShoppingCartVoo goblinShoppingCartVoo = (GoblinShoppingCartVoo) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type.toString()));
        if (null == goblinShoppingCartVoo) {
            //创建 voo
            GoblinShoppingCartVoo goblinShoppingCartVoo1 = GoblinShoppingCartVoo.getNew();
            // 根据shop分类
            ArrayList<GoblinShoppingCartVo> list = ObjectUtil.goblinShoppingCartVoArrayList();
            GoblinShoppingCartVo goblinShoppingCartVo = GoblinShoppingCartVo.getNew();
            goblinShoppingCartVo.setStoreId(storeId);
            //该商铺下的所有商品
            ArrayList<GoblinShoppingCartVoDetail> list1 = ObjectUtil.goblinShoppingCartVoDetailArrayList();
            if (!validateShoopCartNumber(skuId, type, number, userId)) {
                return ResponseDto.failure("当前商品购买数量超过了限购数量");
            }
            //创建 购物车vo
            GoblinShoppingCartVoDetail goblinShoppingCartVoDetail = this.setValue(userId, storeId, spuId, skuId, number);
            list1.add(goblinShoppingCartVoDetail);
            goblinShoppingCartVo.setSkuList(list1);
            list.add(goblinShoppingCartVo);
            goblinShoppingCartVoo1.setShopList(list);
            goblinShoppingCartVoo1.setGoblinShoppingCartId(IDGenerator.nextSnowId());
            saveRedisMongodbMysqlShop(goblinShoppingCartVoo1, userId, type);
            insertShopCartMysql(goblinShoppingCartVoDetail.getCarId(), spuId, storeId, skuId, number, userId, type);
        } else {
            //查看是否有该商铺
            List<GoblinShoppingCartVo> list = goblinShoppingCartVoo.getShopList();
            boolean isShop = false;
            for (GoblinShoppingCartVo goblinShoppingCartVo : list) {
                if (storeId.equals(goblinShoppingCartVo.getStoreId())) {
                    //有这个商铺的 东西
                    List<GoblinShoppingCartVoDetail> list1 = goblinShoppingCartVo.getSkuList();
                    //查看是否有这个商品

                    for (GoblinShoppingCartVoDetail goblinShoppingCartVoDetail : list1) {
                        if (skuId.equals(goblinShoppingCartVoDetail.getSkuId())) {
                            isGoods = true;
                            if (!validateShoopCartNumber(skuId, type, (goblinShoppingCartVoDetail.getNumber() + number), userId)) {
                                return ResponseDto.failure("当前商品购买数量超过了限购数量");
                            }
                            goblinShoppingCartVoDetail.setNumber((goblinShoppingCartVoDetail.getNumber() + number));
                            cardId = goblinShoppingCartVoDetail.getCarId();
                        }
                    }
                    if (isGoods) {
                        //添加商品 数量
                        //不需要做
                    } else {
                        //创建商品放入到list
                        if (!validateShoopCartNumber(skuId, type, number, userId)) {
                            return ResponseDto.failure("当前商品购买数量超过了限购数量");
                        }
                        GoblinShoppingCartVoDetail goblinShoppingCartVoDetail = this.setValue(userId, storeId, spuId, skuId, number);
                        cardId = goblinShoppingCartVoDetail.getCarId();
                        list1.add(goblinShoppingCartVoDetail);
                    }
                    isShop = true;
                }
            }
            if (!isShop) {
                GoblinShoppingCartVo goblinShoppingCartVo = GoblinShoppingCartVo.getNew();
                goblinShoppingCartVo.setStoreId(storeId);
                //该商铺下的所有商品
                ArrayList<GoblinShoppingCartVoDetail> list1 = ObjectUtil.goblinShoppingCartVoDetailArrayList();
                if (!validateShoopCartNumber(skuId, type, number, userId)) {
                    return ResponseDto.failure("当前商品购买数量超过了限购数量");
                }
                //创建 购物车vo
                GoblinShoppingCartVoDetail goblinShoppingCartVoDetail = this.setValue(userId, storeId, spuId, skuId, number);
                list1.add(goblinShoppingCartVoDetail);
                goblinShoppingCartVo.setSkuList(list1);
                list.add(goblinShoppingCartVo);
            }
            saveRedisMongodbMysqlShop(goblinShoppingCartVoo, userId, type);
            if (isGoods) {
                updateShopCartMysql(cardId, number, userId);
            } else {
                insertShopCartMysql(cardId, spuId, storeId, skuId, number, userId, type);
            }
        }
        return ResponseDto.success(true);
    }

    /***
     * @author zhangfuxin
     * @Description: 修改 购物车里 数量
     * @date 2022/1/11 下午6:24
     */
    public boolean updateShopCart(String spuId, String storeId, String skuId, Integer number, String userId, String type) {
        if (null == number || number <= 0) {
            return false;
        }
        GoblinShoppingCartVoo goblinShoppingCartVoo = (GoblinShoppingCartVoo) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type));
        String cardId = "";
        if (null != goblinShoppingCartVoo) {
            List<GoblinShoppingCartVo> list = goblinShoppingCartVoo.getShopList();
            //遍历商铺
            for (GoblinShoppingCartVo goblinShoppingCartVo : list) {
                if (storeId.equals(goblinShoppingCartVo.getStoreId())) {
                    //找到 商品id
                    List<GoblinShoppingCartVoDetail> list1 = goblinShoppingCartVo.getSkuList();
                    for (GoblinShoppingCartVoDetail goblinShoppingCartVoDetail : list1) {
                        if (skuId.equals(goblinShoppingCartVoDetail.getSkuId())) {
                            cardId = goblinShoppingCartVoDetail.getCarId();
                            goblinShoppingCartVoDetail.setNumber(number);
                        }
                    }
                }
            }
            //调用储存方法
            saveRedisMongodbMysqlShop(goblinShoppingCartVoo, userId, type);
            updateShopCartMysql(cardId, number, userId);
        }
        return true;
    }

    public int getShopCartCount(String userId, String type) {
        log.debug("获取商品数量{}", userId);
        int count = 0;
        GoblinShoppingCartVoo goblinShoppingCartVoo = (GoblinShoppingCartVoo) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type.toString()));
        if (null != goblinShoppingCartVoo) {
            List<GoblinShoppingCartVo> shopList = goblinShoppingCartVoo.getShopList();
            for (GoblinShoppingCartVo goblinShoppingCartVo : shopList) {
                List<GoblinShoppingCartVoDetail> skuList = goblinShoppingCartVo.getSkuList();
                for (GoblinShoppingCartVoDetail goblinShoppingCartVoDetail : skuList) {
                    count = goblinShoppingCartVoDetail.getNumber() + count;
                }
            }
        }
        return count;
    }

    /***
     * @author zhangfuxin
     * @Description:存储信息
     * @date 2022/1/17 下午4:55
     */
    public boolean saveDate(String data, String userId, String type) {
        redisUtil.set(GoblinRedisConst.FRONT_SHOPCART_TWO.concat(userId).concat(type.toString()), data, 60 * 60 * 24);
        return true;
    }

    public ResponseDto getDate(String userId, String type) {
        if (redisUtil.get(GoblinRedisConst.FRONT_SHOPCART_TWO.concat(userId).concat(type.toString())) == null) {
            return ResponseDto.failure(ErrorMapping.get("20003"));
        }
        return ResponseDto.success(redisUtil.get(GoblinRedisConst.FRONT_SHOPCART_TWO.concat(userId).concat(type.toString())));
        //return (String) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART_TWO.concat(userId).concat(type.toString()));
    }

    /**
     * 删除购物车里面的商品
     */
    public boolean delteShoppingCart(String[] skuIds, String userId, String type) {
        boolean isDeleteAll = false;
        GoblinShoppingCartVoo goblinShoppingCartVoo = (GoblinShoppingCartVoo) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type));
        if (null != goblinShoppingCartVoo) {
            List<GoblinShoppingCartVo> shopList = goblinShoppingCartVoo.getShopList();
            Iterator<GoblinShoppingCartVo> shopIter = shopList.iterator();
            while (shopIter.hasNext()) {
                GoblinShoppingCartVo goblinShoppingCartVo = shopIter.next();
                List<GoblinShoppingCartVoDetail> skuList = goblinShoppingCartVo.getSkuList();
                Iterator<GoblinShoppingCartVoDetail> iterator = skuList.iterator();
                while (iterator.hasNext()) {
                    GoblinShoppingCartVoDetail goblinShoppingCartVoDetail = iterator.next();
                    for (String skuId : skuIds) {
                        if (goblinShoppingCartVoDetail.getSkuId().equals(skuId)) {
                            //skuList.remove(goblinShoppingCartVoDetail);
                            iterator.remove();
                        }
                    }
                }
                if (skuList.size() == 0) {
                    shopIter.remove();
                }
            }
            if (shopList.size() == 0) {
                deleteRedisMongodbMysqlShop(goblinShoppingCartVoo, userId, skuIds, type);
                deleteMysql(userId, skuIds);
            } else {
                saveRedisMongodbMysqlShop(goblinShoppingCartVoo, userId, type);
                deleteMysql(userId, skuIds);
            }
        }

       /* if(this.getShopCartCount(userId)==0){
            //删除redis、删除mongodb
            deleteRedisMongodbMysqlShop(goblinShoppingCartVoo,userId);
        }else{
            saveRedisMongodbMysqlShop(goblinShoppingCartVoo,userId);
        }
*/
        return true;
    }

    //获得spu
    public GoblinGoodsInfoVo getGoodsInfoVo(GoblinShoppingCartVoDetail goblinShoppingCartVoDetail) {
        GoblinGoodsInfoVo goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(goblinShoppingCartVoDetail.getSpuId());
        if (null == goblinGoodsInfoVo) {
            goblinGoodsInfoVo = goblinRedisUtils.getGoodsInfoVoByUnShelves(goblinShoppingCartVoDetail.getSpuId());
        }
        return goblinGoodsInfoVo;
    }

    //获得sku
    public GoblinGoodsSkuInfoVo getGoblinGoodsSkuInfoVo(GoblinShoppingCartVoDetail goblinShoppingCartVoDetail) {
        GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(goblinShoppingCartVoDetail.getSkuId());
        if (null == goblinGoodsSkuInfoVo) {
            goblinGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVoByUnShelves(goblinShoppingCartVoDetail.getSkuId());
        }
        return goblinGoodsSkuInfoVo;
    }

    //copy spu
    public GoblinGoodsInfoShopCartVo copySpuVo(GoblinGoodsInfoVo goblinGoodsInfoVo) {
        GoblinGoodsInfoShopCartVo goblinGoodsInfoShopCartVo = GoblinGoodsInfoShopCartVo.getNew();
        if (null != goblinGoodsInfoVo) {
            BeanUtils.copyProperties(goblinGoodsInfoVo, goblinGoodsInfoShopCartVo);
        }
        return goblinGoodsInfoShopCartVo;
    }

    //copy sku
    public GoblinGoodsSkuShopCartInfoVo copySkuVo(GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo, String userId) {
        GoblinGoodsSkuShopCartInfoVo goblinGoodsSkuShopCartInfoVo = GoblinGoodsSkuShopCartInfoVo.getNew();
        if (null != goblinGoodsSkuInfoVo) {
            BeanUtils.copyProperties(goblinGoodsSkuInfoVo, goblinGoodsSkuShopCartInfoVo);
            //查看是否有库存
            String pre = GoblinStatusConst.MarketPreStatus.getPre(goblinGoodsSkuInfoVo.getSpuId());
            int stock = goblinRedisUtils.getSkuStock(pre, goblinGoodsSkuInfoVo.getSkuId());
            if (stock <= 0) {
                goblinGoodsSkuShopCartInfoVo.setStockLess(true);
            } else {
                goblinGoodsSkuShopCartInfoVo.setStockLess(false);
            }
            //查看已经购买数量
            Integer buyCount = goblinRedisUtils.getSkuCountByUid(userId, goblinGoodsSkuShopCartInfoVo.getSkuId());
            //查看限购数量
            if (null == buyCount) {
                buyCount = 0;
            }
            if (null != goblinGoodsSkuShopCartInfoVo.getBuyLimit() && goblinGoodsSkuShopCartInfoVo.getBuyLimit() > 0) {
                goblinGoodsSkuShopCartInfoVo.setCanBuy(goblinGoodsSkuShopCartInfoVo.getBuyLimit() - buyCount);
            } else {
                goblinGoodsSkuShopCartInfoVo.setCanBuy(-9999);
            }
        }
        return goblinGoodsSkuShopCartInfoVo;
    }

    /**
     * @author zhangfuxin
     * @Description: 获得购物车列表
     * @date 2022/1/12 下午2:36
     */
    public GoblinShoppingCartVoo getShoppCart(String userId, String type) {
        //判断该用户 redis里是否有购物车
        GoblinShoppingCartVoo goblinShoppingCartVoo = (GoblinShoppingCartVoo) redisUtil.get(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type.toString()));
        if (null == goblinShoppingCartVoo) {
            return null;
        }
        //遍历里面信息
        for (GoblinShoppingCartVo goblinShoppingCartVo : goblinShoppingCartVoo.getShopList()) {
            if (null != goblinRedisUtils.getStoreInfoVo(goblinShoppingCartVo.getStoreId())) {
                goblinShoppingCartVo.setStoreName(goblinRedisUtils.getStoreInfoVo(goblinShoppingCartVo.getStoreId()).getStoreName());
            }
            for (GoblinShoppingCartVoDetail goblinShoppingCartVoDetail : goblinShoppingCartVo.getSkuList()) {
                //找到对应的  spu
                GoblinGoodsInfoVo goblinGoodsInfoVo = getGoodsInfoVo(goblinShoppingCartVoDetail);
                // 找到对应 sku
                GoblinGoodsSkuInfoVo goblinGoodsSkuInfoVo = getGoblinGoodsSkuInfoVo(goblinShoppingCartVoDetail);
                //spu copy
                GoblinGoodsInfoShopCartVo goblinGoodsInfoShopCartVo = copySpuVo(goblinGoodsInfoVo);
                //sku copy
                GoblinGoodsSkuShopCartInfoVo goblinGoodsSkuShopCartInfoVo = copySkuVo(goblinGoodsSkuInfoVo, userId);
                goblinShoppingCartVoDetail.setGoblinGoodsInfoVo(goblinGoodsInfoShopCartVo);
                goblinShoppingCartVoDetail.setGoblinGoodsSkuInfoVo(goblinGoodsSkuShopCartInfoVo);
            }
        }
        goblinShoppingCartVoo.setShoopingCount(this.getShopCartCount(userId, type));
        return goblinShoppingCartVoo;
    }

    public GoblinShoppingCartVoDetail setValue(String userId, String storeId, String spuId, String skuId, Integer number) {
        GoblinShoppingCartVoDetail goblinShoppingCartVoDetail = GoblinShoppingCartVoDetail.getNew();
        goblinShoppingCartVoDetail.setCarId(IDGenerator.nextSnowId());
        goblinShoppingCartVoDetail.setUserId(userId);
        goblinShoppingCartVoDetail.setStoreId(storeId);
        goblinShoppingCartVoDetail.setSpuId(spuId);
        goblinShoppingCartVoDetail.setSkuId(skuId);
        goblinShoppingCartVoDetail.setNumber(number);
        goblinShoppingCartVoDetail.setDelTag(0);
        goblinShoppingCartVoDetail.setCreatedAt(LocalDateTime.now());
        goblinShoppingCartVoDetail.setUpdatedAt(LocalDateTime.now());
        return goblinShoppingCartVoDetail;
    }

    public void saveRedisMongodbMysqlShop(GoblinShoppingCartVoo goblinShoppingCartVoo, String userId, String type) {
        goblinShoppingCartVoo.setUserId(userId);
        //redis存储
        redisUtil.set(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type.toString()), goblinShoppingCartVoo);
        //mongodb存储
        boolean exists2 = mongoTemplate.exists(Query.query(Criteria.where("goblinShoppingCartId").is(goblinShoppingCartVoo.getGoblinShoppingCartId())), GoblinShoppingCartVoo.class, GoblinShoppingCartVoo.class.getSimpleName());
        goblinShoppingCartVoo.setType(type);
        if (exists2) {
            BasicDBObject orderObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(goblinShoppingCartVoo)));
            mongoTemplate.getCollection(GoblinShoppingCartVoo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("goblinShoppingCartId").is(goblinShoppingCartVoo.getGoblinShoppingCartId())).getQueryObject(),
                    orderObject
            );
        } else {
            mongoTemplate.save(goblinShoppingCartVoo, GoblinShoppingCartVoo.class.getSimpleName());
        }
        //mysql 消息队列
    }

    //删除redis 删除mongodb
    public void deleteRedisMongodbMysqlShop(GoblinShoppingCartVoo goblinShoppingCartVoo, String userId, String[] skuIds, String type) {
        //redis存储
        redisUtil.del(GoblinRedisConst.FRONT_SHOPCART.concat(userId).concat(type.toString()));
        //mongodb 删除
        mongoTemplate.remove(Query.query(Criteria.where("goblinShoppingCartId").is(goblinShoppingCartVoo.getGoblinShoppingCartId())), GoblinShoppingCartVoo.class, GoblinShoppingCartVoo.class.getSimpleName());
        //mysql  删除  按照 userid 、skuid
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin_shop.cart.delete"));
        LinkedList<Object[]> sqlData = CollectionUtil.linkedListObjectArr();
        for (String sku : skuIds) {
            sqlData.add(new Object[]{
                    userId, sku, 0
            });
        }
        String sqlDatas = SqlMapping.gets(sqls, sqlData);
        log.debug("sql信息{}", sqlDatas);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SHOP_CART.getKey(), sqlDatas);
    }

    public void insertShopCartMysql(String carId, String spuId, String storeId, String skuId, Integer number, String userId, String type) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin_shop.cart.insert"));
        LinkedList<Object[]> sqlData = CollectionUtil.linkedListObjectArr();
        sqlData.add(new Object[]{
                //car_id, user_id, store_id,spu_id, sku_id, `number`,marketing_id, del_tag, `comment`
                carId, userId, storeId, spuId, skuId, number, "", 0, "", type
        });
        String sqlDatas = SqlMapping.gets(sqls, sqlData);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SHOP_CART.getKey(), sqlDatas);
    }

    public void updateShopCartMysql(String carId, Integer number, String userId) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin_shop.cart.update"));
        LinkedList<Object[]> sqlData = CollectionUtil.linkedListObjectArr();
        sqlData.add(new Object[]{
                //update goblin_shopping_cart set `number` = ? where car_id=? and user_id=?
                number, carId, userId
        });
        String sqlDatas = SqlMapping.gets(sqls, sqlData);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SHOP_CART.getKey(), sqlDatas);
    }

    //删除
    public void deleteMysql(String userId, String[] skuIds) {
        //mysql  删除  按照 userid 、skuid
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin_shop.cart.delete"));
        LinkedList<Object[]> sqlData = CollectionUtil.linkedListObjectArr();
        for (String sku : skuIds) {
            sqlData.add(new Object[]{
                    1, userId, sku
            });
        }
        String sqlDatas = SqlMapping.gets(sqls, sqlData);
        log.debug(sqlDatas);
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_SHOP_CART.getKey(), sqlDatas);
    }


    private boolean isHidden(String fcateId) {
        ArrayList<String> hiddenIds = CollectionUtil.arrayListString();
        hiddenIds.add("22196120924543");
        hiddenIds.add("22196122839313");
        if (hiddenIds.contains(fcateId)) {
            return true;
        }
        return false;
    }
}
