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

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreMgtGoodsActionParam;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreMgtGoodsAddParam;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreMgtGoodsEditSkuParam;
import com.liquidnet.service.goblin.dto.manage.GoblinStoreMgtGoodsFilterParam;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinMgtCategorySpecVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinStoreMgtGoodsInfoVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinStoreMgtGoodsListVo;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.enums.GoblinStoreConf;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreMgtExtraService;
import com.liquidnet.service.goblin.service.manage.IGoblinstoreMgtGoodsService;
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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GoblinStoreMgtGoodsServiceImpl implements IGoblinstoreMgtGoodsService {
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;
    @Autowired
    IGoblinStoreMgtExtraService goblinStoreMgtExtraService;

    @Override
    public PagedResult<GoblinStoreMgtGoodsListVo> goodsList(GoblinStoreMgtGoodsFilterParam filterParam) {
        PagedResult<GoblinStoreMgtGoodsListVo> goodsListVoPagedResult = goblinMongoUtils.getMgtGoodsInfoVos(filterParam);
        if (goodsListVoPagedResult.getTotal() > 0) {
            List<GoblinStoreMgtGoodsListVo> voList = goodsListVoPagedResult.getList();

            List<GoblinStoreConfigVo> storeConfigVos = goblinRedisUtils.getStoreConfigVos(filterParam.getStoreId());
            Optional<GoblinStoreConfigVo> optional = storeConfigVos.stream().filter(r -> r.getConfigKey().equals(GoblinStoreConf.LIMIT_WARNING_STOCK.name())).findAny();
            Integer warningStock = optional.map(goblinStoreConfigVo -> Integer.parseInt(goblinStoreConfigVo.getConfigVal())).orElse(5);

            List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinStoreMgtExtraService.listCategoryVo();
            voList.forEach(vo -> {
                GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getMgtGoodsInfoVo(vo.getSpuId());

                int totalStock = 0, surplusStock = 0;
                for (String skuId : mgtGoodsInfoVo.getSkuIdList()) {
                    GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getMgtGoodsSkuInfoVo(skuId);

                    totalStock += mgtGoodsSkuInfoVo.getStock();
                    surplusStock += goblinRedisUtils.getSkuStock(null, skuId);

//                    if (!mgtGoodsSkuInfoVo.getStock().equals(mgtGoodsSkuInfoVo.getSkuStock())) {// 总库存<>当前SKU库存，则存在活动商品分库存
                        List<String> skuReList = goblinRedisUtils.getSkuRe(skuId);
                        if (!CollectionUtils.isEmpty(skuReList)) {
                            for (String skuRe : skuReList) {
                                surplusStock += goblinRedisUtils.getSkuStock(GoblinStatusConst.MarketPreStatus.getPre(skuRe), skuRe);
                            }
                        }
//                    }
                }
                vo.setTotalStock(totalStock);
                vo.setSurplusStock(surplusStock);
                vo.setWarningStock(warningStock);

                String cateFid = vo.getCateFid(), cateSid = vo.getCateSid(), cateTid = vo.getCateTid();
                List<GoblinSelfGoodsCategoryVo> categoryVoList = selfGoodsCategoryVos.stream()
                        .filter(cr -> Arrays.asList(cateFid, cateSid, cateTid).contains(cr.getCateId())).collect(Collectors.toList());
                categoryVoList.forEach(cr -> {
                    if (cr.getCateId().equals(cateFid)) vo.setCateFid(cr.getName());
                    if (cr.getCateId().equals(cateSid)) vo.setCateSid(cr.getName());
                    if (cr.getCateId().equals(cateTid)) vo.setCateTid(cr.getName());
                });
            });
            goodsListVoPagedResult.setList(voList);
        }
        return goodsListVoPagedResult;
    }

    @Override
    public void goodsAdd(GoblinGoodsInfoVo goodsInfoVo, List<GoblinGoodsSkuInfoVo> goodsSkuInfoVoList) {
        goblinMongoUtils.setGoodsInfoVo(goodsInfoVo);
        goblinMongoUtils.setGoodsSkuInfoVos(goodsSkuInfoVoList);

        if (goodsInfoVo.getShelvesHandle().equals("2")) {
            goblinRedisUtils.deleteKeyForSelectGoods();// 精选商品:商品上架、下架、删除 调用的方法
        }

        String createdBy = goodsInfoVo.getCreatedBy();
        LocalDateTime createdAt = goodsInfoVo.getCreatedAt();
        String spuId = goodsInfoVo.getSpuId();

        LinkedList<Object[]> initGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> initGoodsSkuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> initGoodsCategorySpecObjs = CollectionUtil.linkedListObjectArr();
        {// 分类规格记录
            String cateFid = goodsInfoVo.getCateFid(), cateSid = goodsInfoVo.getCateSid(), cateTid = goodsInfoVo.getCateTid();
            String filterCateId = StringUtils.isBlank(cateTid) ? (StringUtils.isBlank(cateSid) ? cateFid : cateSid) : cateTid;
            GoblinMgtCategorySpecVo mgtCategorySpecVoCache = goblinRedisUtils.getCategorySpec(filterCateId);// 分类绑定的规格信息
            List<String> addSpecNameList = goodsSkuInfoVoList.get(0).getSkuSpecList().stream().map(GoblinGoodsSpecDto::getSpecName).collect(Collectors.toList());
            if (null == mgtCategorySpecVoCache) {// 根据分类ID未查取到规格信息，则Cache、数据库新增
                GoblinMgtCategorySpecVo initMgtCategorySpecVo = GoblinMgtCategorySpecVo.getNew().setCateId(filterCateId).setSpecNameList(addSpecNameList);
                goblinMongoUtils.setCategorySpecVo(initMgtCategorySpecVo);
                goblinRedisUtils.setCategorySpec(filterCateId, initMgtCategorySpecVo);
                addSpecNameList.forEach(r -> initGoodsCategorySpecObjs.add(new Object[]{filterCateId, r}));
            } else {// 根据分类ID查取到规格信息，则进一步比对判断是否新增
                List<String> confirmAddSpecNameList = addSpecNameList.stream().filter(r -> !mgtCategorySpecVoCache.getSpecNameList().contains(r)).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(confirmAddSpecNameList)) {// 不存在于`mgtCategorySpecVoCache`的，则更新Cache，数据库新增
                    mgtCategorySpecVoCache.getSpecNameList().addAll(confirmAddSpecNameList);
                    goblinMongoUtils.updateCategorySpecVo(mgtCategorySpecVoCache);
                    goblinRedisUtils.setCategorySpec(filterCateId, mgtCategorySpecVoCache);
                    confirmAddSpecNameList.forEach(r -> initGoodsCategorySpecObjs.add(new Object[]{filterCateId, r}));
                }
            }
        }

        int skuSize = goodsSkuInfoVoList.size();
        for (int i = 0; i < skuSize; i++) {
            GoblinGoodsSkuInfoVo skuInfoVo = goodsSkuInfoVoList.get(i);
            String skuId = skuInfoVo.getSkuId();
            String buyRoster = skuInfoVo.getBuyRoster();

            goblinRedisUtils.setSkuStock(null, skuId, skuInfoVo.getSkuStock());

            initGoodsSkuObjs.add(new Object[]{
                    skuId, skuInfoVo.getSpuId(), skuInfoVo.getSkuNo(), skuInfoVo.getName(), skuInfoVo.getSubtitle(),
                    skuInfoVo.getSellPrice(), skuInfoVo.getSkuPic(), skuInfoVo.getSkuIsbn(), skuInfoVo.getStock(), skuInfoVo.getSkuStock(),
                    skuInfoVo.getWarningStock(), skuInfoVo.getPrice(), skuInfoVo.getPriceMember(), skuInfoVo.getWeight(), skuInfoVo.getBuyFactor(),
                    buyRoster, skuInfoVo.getBuyLimit(), skuInfoVo.getStoreId(), skuInfoVo.getSkuValidity(), skuInfoVo.getVirtualFlg(),
                    skuInfoVo.getStatus(), skuInfoVo.getShelvesStatus(), skuInfoVo.getSkuAppear(), skuInfoVo.getShelvesAt(), createdBy,
                    createdAt, skuInfoVo.getLogisticsTemplate()
            });

            skuInfoVo.getSkuSpecList().forEach(skuSpecDto -> initGoodsSkuSpecValueObjs.add(new Object[]{
                    spuId, skuId, skuSpecDto.getSpecName(), skuSpecDto.getSpecVname()
            }));
            if (skuInfoVo.getBuyFactor().equals("2") && StringUtils.isNotBlank(buyRoster) && buyRoster.startsWith("http")) {
                queueUtils.sendMsgByRedisXls(buyRoster, "1", skuId);
            }
        }

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        toMqSqls.add(SqlMapping.get("goblin_goods.insert"));
        LinkedList<Object[]> initGoodsObjs = CollectionUtil.linkedListObjectArr();
        initGoodsObjs.add(new Object[]{
                spuId, goodsInfoVo.getSpuNo(), goodsInfoVo.getName(), goodsInfoVo.getSubtitle(), goodsInfoVo.getSellPrice(),
                goodsInfoVo.getPriceGe(), goodsInfoVo.getPriceLe(), goodsInfoVo.getIntro(), goodsInfoVo.getDetails(), goodsInfoVo.getCoverPic(),
                goodsInfoVo.getVideo(), goodsInfoVo.getSpecMode(), goodsInfoVo.getStoreId(), goodsInfoVo.getCateFid(), goodsInfoVo.getCateSid(),
                goodsInfoVo.getCateTid(), goodsInfoVo.getStoreCateFid(), goodsInfoVo.getStoreCateSid(), goodsInfoVo.getStoreCateTid(), goodsInfoVo.getBrandId(),
                goodsInfoVo.getShelvesHandle(), goodsInfoVo.getShelvesTime(), goodsInfoVo.getSpuValidity(), goodsInfoVo.getVirtualFlg(), goodsInfoVo.getStatus(),
                goodsInfoVo.getShelvesStatus(), goodsInfoVo.getSpuAppear(), goodsInfoVo.getShelvesAt(), createdBy, createdAt,
                goodsInfoVo.getLogisticsTemplate()
        });
        toMqSqls.add(SqlMapping.get("goblin_goods_sku.insert"));
        toMqSqls.add(SqlMapping.get("goblin_goods_image.insert_byreplace"));
        LinkedList<Object[]> initGoodsImageObjs = CollectionUtil.linkedListObjectArr();
        if (CollectionUtils.isEmpty(goodsInfoVo.getImageList())) {
            goodsInfoVo.getImageList().forEach(imageUrl -> initGoodsImageObjs.add(new Object[]{spuId, imageUrl}));
        }
        toMqSqls.add(SqlMapping.get("goblin_goods_tag.insert_byreplace"));
        LinkedList<Object[]> initGoodsTagObjs = CollectionUtil.linkedListObjectArr();
        if (!CollectionUtils.isEmpty(goodsInfoVo.getTagVoList())) {
            goodsInfoVo.getTagVoList().forEach(tagVo -> initGoodsTagObjs.add(new Object[]{spuId, tagVo.getTagId(), tagVo.getSort(), "0"}));
        }
        if (!CollectionUtils.isEmpty(goodsInfoVo.getExtagVoList())) {
            goodsInfoVo.getExtagVoList().forEach(exTagVo -> initGoodsTagObjs.add(new Object[]{spuId, exTagVo.getTagId(), exTagVo.getSort(), "1"}));
        }
        toMqSqls.add(SqlMapping.get("goblin_goods_artag.insert_byreplace"));
        LinkedList<Object[]> initGoodsArTagObjs = CollectionUtil.linkedListObjectArr();
        if (!CollectionUtils.isEmpty(goodsInfoVo.getArtagVoList())) {
            goodsInfoVo.getArtagVoList().forEach(arTagVo -> initGoodsArTagObjs.add(new Object[]{spuId, arTagVo.getTagId(), arTagVo.getSort(), "1"}));
        }
        toMqSqls.add(SqlMapping.get("goblin_goods_service_support.insert_byreplace"));
        LinkedList<Object[]> initGoodsServiceSupportObjs = CollectionUtil.linkedListObjectArr();
        if (!CollectionUtils.isEmpty(goodsInfoVo.getServiceSupportVoList())) {
            goodsInfoVo.getServiceSupportVoList().forEach(ssvo -> initGoodsServiceSupportObjs.add(new Object[]{spuId, ssvo.getSsid()}));
        }
        toMqSqls.add(SqlMapping.get("goblin_goods_spec.insert_by_ignore"));
        LinkedList<Object[]> initGoodsSpecObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spec_value.insert_by_ignore"));
        LinkedList<Object[]> initGoodsSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_by_ignore"));// SPU规格信息
        LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_by_ignore"));// SKU规格信息
        {// 规格记录
            List<GoblinGoodsSpecVo> specVoList = goodsInfoVo.getSpecVoList();
            specVoList.forEach(s -> {
                initGoodsSpecObjs.add(new Object[]{s.getSpecName(), createdAt});
                s.getSpecValues().forEach(sv -> {
                    initGoodsSpecValueObjs.add(new Object[]{s.getSpecName(), sv.getSpecVname(), createdAt});
                    initGoodsSpuSpecValueObjs.add(new Object[]{spuId, s.getSpecName(), sv.getSpecVname(), sv.getSpecVsort()});
                });
            });
        }
        toMqSqls.add(SqlMapping.get("goblin_goods_category_spec.insert"));// 分类关联规格信息

        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                SqlMapping.gets(toMqSqls, initGoodsObjs, initGoodsSkuObjs, initGoodsImageObjs,
                        initGoodsTagObjs, initGoodsArTagObjs, initGoodsServiceSupportObjs, initGoodsSpecObjs, initGoodsSpecValueObjs,
                        initGoodsSpuSpecValueObjs, initGoodsSkuSpecValueObjs, initGoodsCategorySpecObjs)
        );
    }

    @Override
    public GoblinStoreMgtGoodsInfoVo goodsInfo(String storeId, String spuId) {
        GoblinStoreMgtGoodsInfoVo vo = GoblinStoreMgtGoodsInfoVo.getNew();
        GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getMgtGoodsInfoVo(spuId);
        if (null != goodsInfoVo) {
            vo.setGoodsInfoVo(goodsInfoVo);
            List<String> skuIdList = goodsInfoVo.getSkuIdList();
            if (!CollectionUtils.isEmpty(skuIdList)) {
                List<GoblinGoodsSkuInfoVo> goodsSkuInfoVoList = ObjectUtil.getGoblinGoodsSkuInfoVoArrayList();
                skuIdList.forEach(skuId -> {
                    GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getMgtGoodsSkuInfoVo(skuId);
                    mgtGoodsSkuInfoVo.setSurplusStock(goblinRedisUtils.getSkuStock(null, skuId));
                    goodsSkuInfoVoList.add(mgtGoodsSkuInfoVo);
                });
                vo.setGoodsSkuInfoVoList(goodsSkuInfoVoList);
            }
        }
        return vo;
    }

    @Override
    public boolean goodsEditSpu(String uid, GoblinStoreMgtGoodsAddParam storeMgtGoodsAddParam) {
        String spuId = storeMgtGoodsAddParam.getSpuId();
        GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getMgtGoodsInfoVo(spuId);
        if (null == mgtGoodsInfoVo) {
            log.warn("商品管理:商品编辑:SPU编辑:[uid={},storeId={},spuId={}]", uid, storeMgtGoodsAddParam.getStoreId(), spuId);
            return false;
        }
        GoblinGoodsInfoVo updateSpuInfoVo = storeMgtGoodsAddParam.initEditGoodsInfoVo();

        boolean updateTagFlg = false, updateExtagFlg = false, updateArtagFlg = false;
        List<GoblinGoodsTagVo> befTagVoList = mgtGoodsInfoVo.getTagVoList();
        boolean befTagIsEmptyFlg = CollectionUtils.isEmpty(befTagVoList);
        List<GoblinGoodsExtagVo> befExtagVoList = mgtGoodsInfoVo.getExtagVoList();
        boolean befExtagIsEmptyFlg = CollectionUtils.isEmpty(befExtagVoList);
        List<GoblinGoodsExtagVo> befArtagVoList = mgtGoodsInfoVo.getArtagVoList();
        boolean befArtagIsEmptyFlg = CollectionUtils.isEmpty(befArtagVoList);
        boolean paramTagIsEmptyFlg, paramExtagIsEmptyFlg, paramArtagIsEmptyFlg;
        List<GoblinGoodsTagVo> paramTagVoList = ObjectUtil.getGoblinGoodsTagVoArrayList();
        List<GoblinGoodsExtagVo> paramExtagVoList = ObjectUtil.getGoblinGoodsExtagVoArrayList();
        List<GoblinGoodsExtagVo> paramArtagVoList = ObjectUtil.getGoblinGoodsExtagVoArrayList();
        {// 标签处理
            List<String> goodsTagIdList = storeMgtGoodsAddParam.getTagList(),
                    goodsExtagIdList = storeMgtGoodsAddParam.getExtagList(),
                    goodsArtagIdList = storeMgtGoodsAddParam.getArtagList();
            if (!CollectionUtils.isEmpty(goodsTagIdList)) {
                List<GoblinSelfTagVo> selfGoodsTagVos = goblinRedisUtils.getSelfTagVos();
                for (int i = 0; i < goodsTagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfGoodsTagVos)
                        if (r.getTagId().equals(goodsTagIdList.get(i)) && r.getTagBelong().equals("0")) {
                            paramTagVoList.add(GoblinGoodsTagVo.getNew().copy(r).setSort(i));
                            break;
                        }
            }
            List<GoblinSelfTagVo> selfExtagVos = null;
            if (!CollectionUtils.isEmpty(goodsExtagIdList)) {
                selfExtagVos = goblinRedisUtils.getSelfExtagVos();
                for (int i = 0; i < goodsExtagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfExtagVos)
                        if (r.getTagId().equals(goodsExtagIdList.get(i)) && r.getTagBelong().equals("1") && !r.getTagType().equals("5")) {
                            paramExtagVoList.add(GoblinGoodsExtagVo.getNew().copy(r).setSort(i));
                            break;
                        }
            }
            if (!CollectionUtils.isEmpty(goodsArtagIdList)) {
                selfExtagVos = CollectionUtils.isEmpty(selfExtagVos) ? goblinRedisUtils.getSelfExtagVos() : selfExtagVos;
                for (int i = 0; i < goodsArtagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfExtagVos)
                        if (r.getTagId().equals(goodsArtagIdList.get(i)) && r.getTagBelong().equals("1")) {
                            paramArtagVoList.add(GoblinGoodsExtagVo.getNew().copy(r).setSort(i));
                            break;
                        }
            }

            paramTagIsEmptyFlg = CollectionUtils.isEmpty(paramTagVoList);
            paramExtagIsEmptyFlg = CollectionUtils.isEmpty(paramExtagVoList);
            paramArtagIsEmptyFlg = CollectionUtils.isEmpty(paramArtagVoList);
            if (!befTagIsEmptyFlg || !paramTagIsEmptyFlg) {
                if (!befTagIsEmptyFlg && !paramTagIsEmptyFlg) {
                    if (paramTagVoList.size() != befTagVoList.size()) {
                        updateTagFlg = true;
                    } else {
                        List<String> befTagIdList = befTagVoList.stream().map(GoblinGoodsTagVo::getTagId).collect(Collectors.toList());
                        for (GoblinGoodsTagVo vo : paramTagVoList) {
                            if (!befTagIdList.contains(vo.getTagId())) {
                                updateTagFlg = true;
                                break;
                            }
                        }
                    }
                } else {
                    updateTagFlg = true;
                }
            }
            if (updateTagFlg) {
                updateSpuInfoVo.setTagVoList(paramTagIsEmptyFlg ? ObjectUtil.getGoblinGoodsTagVoArrayList() : paramTagVoList);
            }

            if (!befExtagIsEmptyFlg || !paramExtagIsEmptyFlg) {
                if (!befExtagIsEmptyFlg && !paramExtagIsEmptyFlg) {
                    if (paramExtagVoList.size() != befExtagVoList.size()) {
                        updateExtagFlg = true;
                    } else {
                        List<String> befExtagIdList = befExtagVoList.stream().map(GoblinGoodsExtagVo::getTagId).collect(Collectors.toList());
                        for (GoblinGoodsExtagVo vo : paramExtagVoList) {
                            if (!befExtagIdList.contains(vo.getTagId())) {
                                updateExtagFlg = true;
                                break;
                            }
                        }
                    }
                } else {
                    updateExtagFlg = true;
                }
            }
            if (updateExtagFlg) {
                updateSpuInfoVo.setExtagVoList(paramExtagIsEmptyFlg ? ObjectUtil.getGoblinGoodsExtagVoArrayList() : paramExtagVoList);
            }

            if (!befArtagIsEmptyFlg || !paramArtagIsEmptyFlg) {
                if (!befArtagIsEmptyFlg && !paramArtagIsEmptyFlg) {
                    if (paramArtagVoList.size() != befArtagVoList.size()) {
                        updateArtagFlg = true;
                    } else {
                        List<String> befArtagIdList = befArtagVoList.stream().map(GoblinGoodsExtagVo::getTagId).collect(Collectors.toList());
                        for (GoblinGoodsExtagVo vo : paramArtagVoList) {
                            if (!befArtagIdList.contains(vo.getTagId())) {
                                updateArtagFlg = true;
                                break;
                            }
                        }
                    }
                } else {
                    updateArtagFlg = true;
                }
            }
            if (updateArtagFlg) {
                updateSpuInfoVo.setArtagVoList(paramArtagIsEmptyFlg ? ObjectUtil.getGoblinGoodsExtagVoArrayList() : paramArtagVoList);
            }
        }

        boolean updateSsidFlg = false;
        List<String> ssidList = storeMgtGoodsAddParam.getSsidList();
        boolean paramSsidListIsEmptyFlg = CollectionUtils.isEmpty(ssidList);
        List<GoblinServiceSupportVo> serviceSupportVoList = mgtGoodsInfoVo.getServiceSupportVoList();
        boolean befServiceSupportVoListIsEmptyFlg = CollectionUtils.isEmpty(serviceSupportVoList);
        {// 服务支持处理
            if (!befServiceSupportVoListIsEmptyFlg || !paramSsidListIsEmptyFlg) {
                if (!befServiceSupportVoListIsEmptyFlg && !paramSsidListIsEmptyFlg) {
                    if (serviceSupportVoList.size() != ssidList.size()) {
                        updateSsidFlg = true;
                    } else {
                        List<String> befSsidList = serviceSupportVoList.stream().map(GoblinServiceSupportVo::getSsid).collect(Collectors.toList());
                        for (String ssid : ssidList) {
                            if (!befSsidList.contains(ssid)) {
                                updateSsidFlg = true;
                                break;
                            }
                        }
                    }
                } else {
                    updateSsidFlg = true;
                }
            }
            if (updateSsidFlg) {
                updateSpuInfoVo.setServiceSupportVoList(paramSsidListIsEmptyFlg ? ObjectUtil.getGoblinServiceSupportVoArrayList() : goblinMongoUtils.getServiceSupportVos(ssidList));
            }
        }

        boolean updateImageFlg = false;
        List<String> paramImageList = storeMgtGoodsAddParam.getImageList();
        List<String> befImageList = mgtGoodsInfoVo.getImageList();
        {// 图片处理
            if (befImageList.size() != paramImageList.size()) {
                updateImageFlg = true;
            } else {
                for (String imageUrl : paramImageList) {
                    if (!befImageList.contains(imageUrl)) {
                        updateImageFlg = true;
                        break;
                    }
                }
            }
            if (updateImageFlg) {
                updateSpuInfoVo.setImageList(paramImageList);
            }
        }
        updateSpuInfoVo.setUpdatedBy(uid);
        updateSpuInfoVo.setUpdatedAt(LocalDateTime.now());
        if (goblinMongoUtils.updateGoodsInfoVo(updateSpuInfoVo)) {
            GoblinGoodsSkuInfoVo updateSkuInfoVo = GoblinGoodsSkuInfoVo.getNew();
            updateSkuInfoVo.setSpuId(updateSpuInfoVo.getSpuId());
            updateSkuInfoVo.setSkuNo(updateSpuInfoVo.getSpuNo());
//            updateSkuInfoVo.setName(updateSpuInfoVo.getName());
//            updateSkuInfoVo.setSubtitle(updateSpuInfoVo.getSubtitle());
            updateSkuInfoVo.setVirtualFlg(updateSpuInfoVo.getVirtualFlg());
            updateSkuInfoVo.setLogisticsTemplate(updateSpuInfoVo.getLogisticsTemplate());
            updateSkuInfoVo.setUpdatedBy(updateSpuInfoVo.getUpdatedBy());
            updateSkuInfoVo.setUpdatedAt(updateSpuInfoVo.getUpdatedAt());

            LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            // 参与活动的同一商品更新处理
            List<String> marketSpuIdList = goblinMongoUtils.updateGoodsInfoVoForMarket(spuId, mgtGoodsInfoVo.getSpuNo(), updateSpuInfoVo);
            if (!CollectionUtils.isEmpty(marketSpuIdList)) {
                marketSpuIdList.forEach(marketSpuId -> {
                    goblinRedisUtils.delGoodsInfoVo(marketSpuId);
                    updateGoodsInfoObjs.add(new Object[]{
                            updateSpuInfoVo.getSpuNo(), updateSpuInfoVo.getName(), updateSpuInfoVo.getSubtitle(), updateSpuInfoVo.getSellPrice(),
                            updateSpuInfoVo.getIntro(), updateSpuInfoVo.getDetails(), updateSpuInfoVo.getCoverPic(), updateSpuInfoVo.getVideo(),
                            "2", updateSpuInfoVo.getCateFid(), updateSpuInfoVo.getCateSid(), updateSpuInfoVo.getCateTid(),
                            updateSpuInfoVo.getShelvesHandle(), updateSpuInfoVo.getShelvesTime(), updateSpuInfoVo.getSpuValidity(), updateSpuInfoVo.getVirtualFlg(),
                            updateSpuInfoVo.getLogisticsTemplate(), updateSpuInfoVo.getUpdatedBy(), updateSpuInfoVo.getUpdatedAt(), marketSpuId
                    });
                    updateGoodsSkuObjs.add(new Object[]{
                            updateSkuInfoVo.getSkuNo(), updateSkuInfoVo.getVirtualFlg(), updateSkuInfoVo.getLogisticsTemplate(),
                            updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), marketSpuId
                    });
                });
            }

            goblinMongoUtils.updateGoodsSkuInfoVoBySpuId(updateSkuInfoVo);
            goblinRedisUtils.delGoodsInfoVo(updateSpuInfoVo.getSpuId());

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit"));
//            LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsInfoObjs.add(new Object[]{
                    updateSpuInfoVo.getSpuNo(), updateSpuInfoVo.getName(), updateSpuInfoVo.getSubtitle(), updateSpuInfoVo.getSellPrice(),
                    updateSpuInfoVo.getIntro(), updateSpuInfoVo.getDetails(), updateSpuInfoVo.getCoverPic(), updateSpuInfoVo.getVideo(),
                    updateSpuInfoVo.getSpecMode(), updateSpuInfoVo.getCateFid(), updateSpuInfoVo.getCateSid(), updateSpuInfoVo.getCateTid(),
                    updateSpuInfoVo.getShelvesHandle(), updateSpuInfoVo.getShelvesTime(), updateSpuInfoVo.getSpuValidity(), updateSpuInfoVo.getVirtualFlg(),
                    updateSpuInfoVo.getLogisticsTemplate(), updateSpuInfoVo.getUpdatedBy(), updateSpuInfoVo.getUpdatedAt(), updateSpuInfoVo.getSpuId()
            });
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_spu"));
//            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsSkuObjs.add(new Object[]{
                    updateSkuInfoVo.getSkuNo(), updateSkuInfoVo.getVirtualFlg(), updateSkuInfoVo.getLogisticsTemplate(),
                    updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), updateSkuInfoVo.getSpuId()
            });

            toMqSqls.add(SqlMapping.get("goblin_goods_tag.delete"));
            LinkedList<Object[]> deleteGoodsTagObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_tag.insert_byreplace"));
            LinkedList<Object[]> initGoodsTagObjs = CollectionUtil.linkedListObjectArr();
            if (updateTagFlg) {
                if (!befTagIsEmptyFlg) {
                    deleteGoodsTagObjs.add(new Object[]{spuId, '0'});
                }
                if (!paramTagIsEmptyFlg) {
                    updateSpuInfoVo.getTagVoList().forEach(vo -> initGoodsTagObjs.add(new Object[]{spuId, vo.getTagId(), vo.getSort(), "0"}));
                }
            }
            if (updateExtagFlg) {
                if (!befExtagIsEmptyFlg) {
                    deleteGoodsTagObjs.add(new Object[]{spuId, '1'});
//                    List<GoblinGoodsExtagVo> artagVoList = updateArtagFlg ? updateSpuInfoVo.getArtagVoList() : mgtGoodsInfoVo.getArtagVoList();
//                    artagVoList.forEach(vo -> initGoodsTagObjs.add(new Object[]{spuId, vo.getTagId(), vo.getSort(), "1"}));
                }
                if (!paramExtagIsEmptyFlg) {
                    updateSpuInfoVo.getExtagVoList().forEach(vo -> initGoodsTagObjs.add(new Object[]{spuId, vo.getTagId(), vo.getSort(), "1"}));
                }
            }
            toMqSqls.add(SqlMapping.get("goblin_goods_artag.delete"));
            LinkedList<Object[]> deleteGoodsArTagObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_artag.insert_byreplace"));
            LinkedList<Object[]> initGoodsArTagObjs = CollectionUtil.linkedListObjectArr();
            if (updateArtagFlg) {
                if (!befArtagIsEmptyFlg) {
                    deleteGoodsArTagObjs.add(new Object[]{spuId, '1'});
//                    List<GoblinGoodsExtagVo> extagVoList = updateExtagFlg ? updateSpuInfoVo.getExtagVoList() : mgtGoodsInfoVo.getExtagVoList();
//                    extagVoList.forEach(vo -> initGoodsArTagObjs.add(new Object[]{spuId, vo.getTagId(), vo.getSort(), "1"}));
                }
                if (!paramArtagIsEmptyFlg) {
                    updateSpuInfoVo.getArtagVoList().forEach(vo -> initGoodsArTagObjs.add(new Object[]{spuId, vo.getTagId(), vo.getSort(), "1"}));
                }
            }

            toMqSqls.add(SqlMapping.get("goblin_goods_service_support.delete"));
            LinkedList<Object[]> deleteServiceSupportObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_service_support.insert_byreplace"));
            LinkedList<Object[]> initServiceSupportObjs = CollectionUtil.linkedListObjectArr();
            if (updateSsidFlg) {
                if (!befServiceSupportVoListIsEmptyFlg) {
                    deleteServiceSupportObjs.add(new Object[]{spuId});
                }
                if (!paramSsidListIsEmptyFlg) {
                    updateSpuInfoVo.getServiceSupportVoList().forEach(vo -> initServiceSupportObjs.add(new Object[]{spuId, vo.getSsid()}));
                }
            }

            toMqSqls.add(SqlMapping.get("goblin_goods_image.delete"));
            LinkedList<Object[]> deleteGoodsImageObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_image.insert_byreplace"));
            LinkedList<Object[]> initGoodsImageObjs = CollectionUtil.linkedListObjectArr();
            if (updateImageFlg) {
                deleteGoodsImageObjs.add(new Object[]{spuId});
                updateSpuInfoVo.getImageList().forEach(imageUrl -> initGoodsImageObjs.add(new Object[]{spuId, imageUrl}));
            }

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsInfoObjs, updateGoodsSkuObjs,
                            deleteGoodsTagObjs, initGoodsTagObjs, deleteGoodsArTagObjs, initGoodsArTagObjs,
                            deleteServiceSupportObjs, initServiceSupportObjs, deleteGoodsImageObjs, initGoodsImageObjs));
            return true;
        }
        return false;
    }

    @Override
    public boolean goodsEditSku(String uid, GoblinStoreMgtGoodsEditSkuParam storeMgtGoodsEditSkuParam, GoblinGoodsInfoVo goodsInfoVo,
                                Map<String, String> updateSpuSpecMap, boolean beUpdateSpuSpecFlg) {
        LocalDateTime now = LocalDateTime.now();

        GoblinGoodsSkuInfoVo updateSkuInfoVo = storeMgtGoodsEditSkuParam.initEditGoodsSkuInfoVo();
        updateSkuInfoVo.setUpdatedBy(uid);
        updateSkuInfoVo.setUpdatedAt(now);
        String skuId = updateSkuInfoVo.getSkuId();
        if (goblinMongoUtils.updateGoodsSkuInfoVo(updateSkuInfoVo)) {
            LinkedList<Object[]> updateGoodsSkuForMarketObjs = CollectionUtil.linkedListObjectArr();
            // 参与活动的同一商品更新处理
            List<String> marketSkuIdList = goblinRedisUtils.getSkuRe(updateSkuInfoVo.getSkuId());
            if (!CollectionUtils.isEmpty(marketSkuIdList)) {
                goblinMongoUtils.updateGoodsSkuInfoVoForMarket(marketSkuIdList, updateSkuInfoVo);
                marketSkuIdList.forEach(marketSkuId -> {
                    goblinRedisUtils.delGoodsSkuInfoVo(marketSkuId);
                    updateGoodsSkuForMarketObjs.add(new Object[]{
                            updateSkuInfoVo.getName(), updateSkuInfoVo.getSkuPic(), updateSkuInfoVo.getSellPrice(),
                            updateSkuInfoVo.getWeight(), updateSkuInfoVo.getStock(), updateSkuInfoVo.getWarningStock(),
                            updateSkuInfoVo.getSkuAppear(), updateSkuInfoVo.getSkuIsbn(), updateSkuInfoVo.getSkuValidity(),
                            updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), marketSkuId
                    });
                });
            }

            String spuId = goodsInfoVo.getSpuId();
            goblinRedisUtils.delGoodsSkuInfoVo(skuId);

            LinkedList<Object[]> updateSkuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> initSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> delSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> updateSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();

            List<GoblinGoodsSpecVo> specVoList = goodsInfoVo.getSpecVoList();
            List<GoblinGoodsSpecDto> skuSpecList = storeMgtGoodsEditSkuParam.getSkuSpecList();
            skuSpecList.forEach(spec -> {
                String specName = spec.getSpecName(), specVname = spec.getSpecVname();

                GoblinGoodsSpecVo specVo = specVoList.stream().filter(r -> r.getSpecName().equals(specName)).findAny().get();
                GoblinGoodsSpecValueVo specValueVo = specVo.getSpecValues().stream().filter(rv -> rv.getSpecVname().equals(specVname)).findAny().get();

                initSpuSpecValueObjs.add(new Object[]{spuId, specName, specVname, specValueVo.getSpecVsort()});
                updateSkuSpecValueObjs.add(new Object[]{specVname, skuId, specName});
                if (!CollectionUtils.isEmpty(marketSkuIdList)) {
                    marketSkuIdList.forEach(marketSkuId -> updateSkuSpecValueObjs.add(new Object[]{specVname, marketSkuId, specName}));
                }
            });

            if (beUpdateSpuSpecFlg) {
                for (GoblinGoodsSpecVo specVo : specVoList) {
                    List<GoblinGoodsSpecValueVo> specValues = specVo.getSpecValues();
                    specValues.sort(Comparator.comparing(GoblinGoodsSpecValueVo::getSpecVsort));
                    for (int i = 0; i < specValues.size(); i++) {
                        GoblinGoodsSpecValueVo specValueVo = specValues.get(i);
                        specValueVo.setSpecVsort(i);

                        updateSpuSpecValueObjs.add(new Object[]{i, spuId, specVo.getSpecName(), specValueVo.getSpecVname()});
                    }
                }

                if (!CollectionUtils.isEmpty(updateSpuSpecMap)) {// 更改了规格，需要同步SPU里的规格信息
                    goodsInfoVo.setUpdatedBy(uid);
                    goodsInfoVo.setUpdatedAt(now);
                    goblinMongoUtils.updateGoodsInfoVo(goodsInfoVo);
                    goblinRedisUtils.delGoodsInfoVo(spuId);

                    updateSpuSpecMap.forEach((k, v) -> delSpuSpecValueObjs.add(new Object[]{spuId, k, v}));
                }
            }

            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (String skuIdStr : goodsInfoVo.getSkuIdList()) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getMgtGoodsSkuInfoVo(skuIdStr);

                priceGe = priceGe.compareTo(BigDecimal.ZERO) == 0 ? skuInfoVo.getPrice() : (priceGe.compareTo(skuInfoVo.getPrice()) > 0 ? skuInfoVo.getPrice() : priceGe);
                priceLe = priceLe.compareTo(skuInfoVo.getPrice()) < 0 ? skuInfoVo.getPrice() : priceLe;
            }
            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            if (priceGe.compareTo(goodsInfoVo.getPriceGe()) != 0 || priceLe.compareTo(goodsInfoVo.getPriceLe()) != 0) {
                goodsInfoVo.setPriceGe(priceGe);
                goodsInfoVo.setPriceLe(priceLe);
                goodsInfoVo.setUpdatedBy(uid);
                goodsInfoVo.setUpdatedAt(now);

                goblinMongoUtils.updateGoodsInfoVo(goodsInfoVo);
                goblinRedisUtils.delGoodsInfoVo(spuId);

                updateGoodsObjs.add(new Object[]{priceGe, priceLe, uid, now, spuId});
            }
            String buyRoster = storeMgtGoodsEditSkuParam.getBuyRoster();
            if (storeMgtGoodsEditSkuParam.getBuyFactor().equals("2") && StringUtils.isNotBlank(buyRoster) && buyRoster.startsWith("http")) {
                queueUtils.sendMsgByRedisXls(buyRoster, storeMgtGoodsEditSkuParam.getBuyRosterType(), skuId);
            }

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_for_market"));
//            LinkedList<Object[]> updateGoodsSkuForMarketObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit"));
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsSkuObjs.add(new Object[]{
                    updateSkuInfoVo.getName(), updateSkuInfoVo.getSkuPic(), updateSkuInfoVo.getSellPrice(), updateSkuInfoVo.getPrice(),
                    updateSkuInfoVo.getPriceMember(), updateSkuInfoVo.getWeight(), updateSkuInfoVo.getStock(), updateSkuInfoVo.getSkuStock(),
                    updateSkuInfoVo.getWarningStock(), updateSkuInfoVo.getSkuAppear(), updateSkuInfoVo.getSkuIsbn(), updateSkuInfoVo.getBuyFactor(),
                    updateSkuInfoVo.getBuyRoster(), updateSkuInfoVo.getBuyLimit(), updateSkuInfoVo.getSkuValidity(), updateSkuInfoVo.getUpdatedBy(),
                    updateSkuInfoVo.getUpdatedAt(), skuId
            });
            toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.update_by_edit"));
//            LinkedList<Object[]> updateSkuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_by_ignore"));
//            LinkedList<Object[]> initSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.update_by_editdel"));
//            LinkedList<Object[]> delSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.update_by_edit"));
//            LinkedList<Object[]> updateSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit_sku"));
//            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsSkuForMarketObjs, updateGoodsSkuObjs,
                            updateSkuSpecValueObjs, initSpuSpecValueObjs, delSpuSpecValueObjs, updateSpuSpecValueObjs, updateGoodsObjs));
            return true;
        }
        Integer operStock = storeMgtGoodsEditSkuParam.getOperStock();
        if (null != operStock && operStock != 0) {
            if (operStock > 0) {
                goblinRedisUtils.decrSkuStock(null, skuId, Math.abs(operStock));
            } else {
                goblinRedisUtils.incrSkuStock(null, skuId, Math.abs(operStock));
            }
        }
        return false;
    }

    @Override
    public void goodsEditSkuAdd(String uid, GoblinStoreMgtGoodsEditSkuParam storeMgtGoodsEditSkuParam, GoblinGoodsInfoVo goodsInfoVo) {
        LocalDateTime now = LocalDateTime.now();
        String spuId = storeMgtGoodsEditSkuParam.getSpuId();
        String skuId = spuId.concat(StringUtils.right(String.valueOf(System.nanoTime()), 5));

        GoblinGoodsSkuInfoVo addSkuInfoVo = storeMgtGoodsEditSkuParam.initEditAddGoodsSkuInfoVo();
        addSkuInfoVo.setSkuId(skuId);
        addSkuInfoVo.setSpuId(spuId);
        addSkuInfoVo.setSkuNo(goodsInfoVo.getSpuNo());
        addSkuInfoVo.setName(goodsInfoVo.getName());
        addSkuInfoVo.setSubtitle(goodsInfoVo.getSubtitle());
        addSkuInfoVo.setVirtualFlg(goodsInfoVo.getVirtualFlg());
        addSkuInfoVo.setStatus("3");
        addSkuInfoVo.setShelvesStatus(goodsInfoVo.getShelvesStatus());
        addSkuInfoVo.setDelFlg("0");
        addSkuInfoVo.setCreatedAt(now);
        addSkuInfoVo.setCreatedBy(uid);
        addSkuInfoVo.setLogisticsTemplate(goodsInfoVo.getLogisticsTemplate());

        goblinMongoUtils.setGoodsSkuInfoVo(addSkuInfoVo);

        List<String> skuIdList = goodsInfoVo.getSkuIdList();
        skuIdList.add(addSkuInfoVo.getSkuId());
        goodsInfoVo.setSkuIdList(skuIdList);
        BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
        for (String skuIdStr : goodsInfoVo.getSkuIdList()) {
            GoblinGoodsSkuInfoVo skuInfoVo = skuIdStr.equals(skuId) ? addSkuInfoVo : goblinRedisUtils.getMgtGoodsSkuInfoVo(skuIdStr);

            priceGe = priceGe.compareTo(BigDecimal.ZERO) == 0 ? skuInfoVo.getPrice() : (priceGe.compareTo(skuInfoVo.getPrice()) > 0 ? skuInfoVo.getPrice() : priceGe);
            priceLe = priceLe.compareTo(skuInfoVo.getPrice()) < 0 ? skuInfoVo.getPrice() : priceLe;
        }
        LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
        if (priceGe.compareTo(goodsInfoVo.getPriceGe()) != 0 || priceLe.compareTo(goodsInfoVo.getPriceLe()) != 0) {
            goodsInfoVo.setPriceGe(priceGe);
            goodsInfoVo.setPriceLe(priceLe);
            goodsInfoVo.setUpdatedBy(uid);
            goodsInfoVo.setUpdatedAt(now);
            updateGoodsObjs.add(new Object[]{priceGe, priceLe, uid, now, spuId});
        }

        goblinMongoUtils.updateGoodsInfoVo(goodsInfoVo);
        goblinRedisUtils.delGoodsSkuInfoVo(spuId);
        goblinRedisUtils.delGoodsInfoVo(spuId);

        goblinRedisUtils.setSkuStock(null, addSkuInfoVo.getSkuId(), addSkuInfoVo.getSkuStock());

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku.insert"));
        LinkedList<Object[]> initGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
        initGoodsSkuObjs.add(new Object[]{
                addSkuInfoVo.getSkuId(), addSkuInfoVo.getSpuId(), addSkuInfoVo.getSkuNo(), addSkuInfoVo.getName(), addSkuInfoVo.getSubtitle(),
                addSkuInfoVo.getSellPrice(), addSkuInfoVo.getSkuPic(), addSkuInfoVo.getSkuIsbn(), addSkuInfoVo.getStock(), addSkuInfoVo.getSkuStock(),
                addSkuInfoVo.getWarningStock(), addSkuInfoVo.getPrice(), addSkuInfoVo.getPriceMember(), addSkuInfoVo.getWeight(), addSkuInfoVo.getBuyFactor(),
                addSkuInfoVo.getBuyRoster(), addSkuInfoVo.getBuyLimit(), addSkuInfoVo.getStoreId(), addSkuInfoVo.getSkuValidity(), addSkuInfoVo.getVirtualFlg(),
                addSkuInfoVo.getStatus(), addSkuInfoVo.getShelvesStatus(), addSkuInfoVo.getSkuAppear(), addSkuInfoVo.getShelvesAt(), uid,
                now, addSkuInfoVo.getLogisticsTemplate()
        });
        toMqSqls.add(SqlMapping.get("goblin_goods_spec.insert_by_ignore"));
        LinkedList<Object[]> initGoodsSpecObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spec_value.insert_by_ignore"));
        LinkedList<Object[]> initGoodsSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_by_ignore"));// SPU规格信息
        LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_by_ignore"));// SKU规格信息
        LinkedList<Object[]> initGoodsSkuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        addSkuInfoVo.getSkuSpecList().forEach(skuSpecDto -> initGoodsSkuSpecValueObjs.add(new Object[]{
                spuId, skuId, skuSpecDto.getSpecName(), skuSpecDto.getSpecVname()
        }));
        toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit_sku"));// SPU价格区间
//        LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
        {// 规格记录
            List<GoblinGoodsSpecVo> specVoList = goodsInfoVo.getSpecVoList();
            specVoList.forEach(s -> {
                initGoodsSpecObjs.add(new Object[]{s.getSpecName(), now});
                s.getSpecValues().forEach(sv -> {
                    initGoodsSpecValueObjs.add(new Object[]{s.getSpecName(), sv.getSpecVname(), now});
                    initGoodsSpuSpecValueObjs.add(new Object[]{spuId, s.getSpecName(), sv.getSpecVname(), sv.getSpecVsort()});
                });
            });
        }

        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                SqlMapping.gets(toMqSqls, initGoodsSkuObjs, initGoodsSpecObjs,
                        initGoodsSpecValueObjs, initGoodsSpuSpecValueObjs, initGoodsSkuSpecValueObjs, updateGoodsObjs)
        );
    }

    @Override
    public boolean goodsEditSkuDel(String uid, GoblinGoodsSkuInfoVo goodsSkuInfoVo) {
        String spuId = goodsSkuInfoVo.getSpuId();
        String delSkuId = goodsSkuInfoVo.getSkuId();

        GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getMgtGoodsInfoVo(spuId);
        mgtGoodsInfoVo.getSkuIdList().removeIf(r -> r.equals(delSkuId));

        List<GoblinGoodsSpecVo> specVoList = mgtGoodsInfoVo.getSpecVoList();
        Map<String, String> delGoodsSkuSpecMap = goodsSkuInfoVo.getSkuSpecList().stream()
                .collect(Collectors.toMap(GoblinGoodsSpecDto::getSpecName, GoblinGoodsSpecDto::getSpecVname));
        LinkedList<Object[]> updateGoodsSpuSpecObjs = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> updateGoodsSpuSpecDelObjs = CollectionUtil.linkedListObjectArr();
        for (int i = 0; i < specVoList.size(); i++) {// 处理商品规格信息
            GoblinGoodsSpecVo specVo = specVoList.get(i);
            List<GoblinGoodsSpecValueVo> modifySpecValues = ObjectUtil.getGoblinGoodsSpecValueVoArrayList();

            String delSpecVname = delGoodsSkuSpecMap.get(specVo.getSpecName());
            List<GoblinGoodsSpecValueVo> specValues = specVo.getSpecValues();
            Integer rmIdx = null;
            for (GoblinGoodsSpecValueVo specValue : specValues) {
                if (specValue.getSpecVname().equals(delSpecVname)) {
                    modifySpecValues.remove(specValue);
                    rmIdx = specValue.getSpecVsort();
                    updateGoodsSpuSpecDelObjs.add(new Object[]{spuId, specVo.getSpecName(), delSpecVname});
                } else {
                    modifySpecValues.add(specValue);
                }
                if (null != rmIdx && specValue.getSpecVsort() > rmIdx) {
                    specValue.setSpecVsort(specValue.getSpecVsort() - 1);
                    updateGoodsSpuSpecObjs.add(new Object[]{specValue.getSpecVsort(), spuId, specVo.getSpecName(), specValue.getSpecVname()});
                }
            }
            if (modifySpecValues.size() == 0) {// 规格下规格值为0的时候，移除规格
//                specVoList.remove(specVo);
            } else {
                specVo.setSpecValues(modifySpecValues);
            }
        }
        LocalDateTime now = LocalDateTime.now();
        goodsSkuInfoVo.setUpdatedBy(uid);
        goodsSkuInfoVo.setUpdatedAt(now);
        goodsSkuInfoVo.setDeletedBy(uid);
        goodsSkuInfoVo.setDeletedAt(now);

        List<String> skuReList = goblinRedisUtils.getSkuRe(delSkuId);
        skuReList = null == skuReList ? CollectionUtil.arrayListString() : skuReList;
        skuReList.add(delSkuId);
        if (goblinMongoUtils.delGoodsSkuInfoVo(goodsSkuInfoVo, skuReList)) {
//            goblinRedisUtils.delGoodsSkuInfoVo(delSkuId);
//            goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(delSkuId);
            skuReList.forEach(skuRe -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuRe);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuRe);
            });

            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (String skuId : mgtGoodsInfoVo.getSkuIdList()) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getMgtGoodsSkuInfoVo(skuId);

                priceGe = priceGe.compareTo(BigDecimal.ZERO) == 0 ? skuInfoVo.getPrice() : (priceGe.compareTo(skuInfoVo.getPrice()) > 0 ? skuInfoVo.getPrice() : priceGe);
                priceLe = priceLe.compareTo(skuInfoVo.getPrice()) < 0 ? skuInfoVo.getPrice() : priceLe;
            }
            mgtGoodsInfoVo.setUpdatedBy(uid);
            mgtGoodsInfoVo.setUpdatedAt(now);

            LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();
            if (priceGe.compareTo(mgtGoodsInfoVo.getPriceGe()) != 0 || priceLe.compareTo(mgtGoodsInfoVo.getPriceLe()) != 0) {
                mgtGoodsInfoVo.setPriceGe(priceGe);
                mgtGoodsInfoVo.setPriceLe(priceLe);
                updateGoodsInfoObjs.add(new Object[]{priceGe, priceLe, uid, now, spuId});
            }
            goblinMongoUtils.updateGoodsInfoVo(mgtGoodsInfoVo);
            goblinRedisUtils.delGoodsInfoVo(spuId);

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_del"));
            LinkedList<Object[]> delGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            delGoodsSkuObjs.add(new Object[]{uid, now, uid, now, spuId, goodsSkuInfoVo.getStoreId()});
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.update_by_del_sku1"));
//            LinkedList<Object[]> updateGoodsSpuSpecDelObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.update_by_del_sku2"));
//            LinkedList<Object[]> updateGoodsSpuSpecObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_del_sku"));
//            LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, delGoodsSkuObjs, updateGoodsSpuSpecDelObjs, updateGoodsSpuSpecObjs, updateGoodsInfoObjs));

            return true;
        }
        return false;
    }

//    @Override
//    public boolean goodsEditSkuBat(String spuId, String batField, String batFieldVal) {
//        return false;
//    }

    @Override
    public void goodsShelvesProcessing(GoblinStoreMgtGoodsActionParam storeMgtGoodsActionParam, String uid, boolean shelvesFlg) {
        LocalDateTime now = LocalDateTime.now();
        String storeId = storeMgtGoodsActionParam.getStoreId();
        List<String> spuIdList = storeMgtGoodsActionParam.getSpuIdList();

        if (goblinMongoUtils.updateGoodsInfoVoByShelves(storeId, spuIdList, shelvesFlg, uid, now)) {
            if (goblinMongoUtils.updateGoodsSkuInfoVoByShelves(storeId, spuIdList, shelvesFlg, uid, now)) {
                goblinRedisUtils.deleteKeyForSelectGoods();// 精选商品:商品上架、下架、删除 调用的方法

                spuIdList.forEach(spuId -> {
                    goblinRedisUtils.delGoodsInfoVo(spuId);
                    goblinRedisUtils.delGoodsInfoVoByUnShelves(spuId);
                });
                List<String> skuIds = goblinMongoUtils.getMgtGoodsSkuIds(storeId, spuIdList);
                skuIds.forEach(skuId -> {
                    goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                    goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
                });

                LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
                toMqSqls.add(SqlMapping.get("goblin_goods.update_by_shelves"));
                LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
                String shelvesStatus = shelvesFlg ? "3" : "1";
                spuIdList.forEach(spuId -> updateGoodsObjs.add(new Object[]{shelvesStatus, now, uid, now, spuId, storeId}));
                toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_shelves"));
                LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
                spuIdList.forEach(spuId -> updateGoodsSkuObjs.add(new Object[]{shelvesStatus, now, uid, now, spuId, storeId}));

                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                        SqlMapping.gets(toMqSqls, updateGoodsObjs, updateGoodsSkuObjs));
            } else {
                goblinMongoUtils.updateGoodsInfoVoByShelves(storeId, spuIdList, !shelvesFlg, uid, now);
            }
        }
    }

    @Override
    public void goodsRemove(GoblinStoreMgtGoodsActionParam storeMgtGoodsActionParam, String uid) {
        LocalDateTime now = LocalDateTime.now();
        String storeId = storeMgtGoodsActionParam.getStoreId();
        List<String> spuIdList = storeMgtGoodsActionParam.getSpuIdList();

        if (goblinMongoUtils.delGoodsInfoVoBySpuIds(storeId, spuIdList, uid, now)) {
            goblinRedisUtils.deleteKeyForSelectGoods();// 精选商品:商品上架、下架、删除 调用的方法

            spuIdList.forEach(spuId -> goblinRedisUtils.delGoodsInfoVo(spuId));
            List<String> skuIdList = goblinMongoUtils.getMgtGoodsSkuIds(storeId, spuIdList);
            skuIdList.forEach(skuId -> goblinRedisUtils.delGoodsSkuInfoVo(skuId));

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_del"));
            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            spuIdList.forEach(spuId -> updateGoodsObjs.add(new Object[]{uid, now, uid, now, spuId, storeId}));
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_del"));
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            spuIdList.forEach(spuId -> updateGoodsSkuObjs.add(new Object[]{uid, now, uid, now, spuId, storeId}));

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsObjs, updateGoodsSkuObjs));
        }
    }
}
