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

import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
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.*;
import com.liquidnet.service.goblin.dto.manage.vo.*;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinSqbGoodsExt;
import com.liquidnet.service.goblin.enums.GoblinStoreConf;
import com.liquidnet.service.goblin.mapper.GoblinSqbGoodsExtMapper;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreMgtExtraService;
import com.liquidnet.service.goblin.service.manage.IGoblinZhengzaiService;
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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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;
    @Autowired
    IGoblinZhengzaiService goblinZhengzaiService;
    @Autowired
    GoblinSqbGoodsExtMapper goblinSqbGoodsExtMapper;

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

            // 存在关联活动的SPUNO获取
            List<String> relateMarketSpuNoList = goblinMongoUtils.getMgtSpuNosForMarketBySpuNos(
                    voList.stream().map(GoblinStoreMgtGoodsListVo::getSpuNo).collect(Collectors.toList()), "3");

            // 库存预警配置获取
            List<GoblinStoreConfigVo> storeConfigVos = goblinRedisUtils
                    .getStoreConfigVos(mgtGoodsFilterParam.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.getGoodsInfoVo(vo.getSpuId());

                int totalStock = 0, surplusStock = 0;
                for (String skuId : mgtGoodsInfoVo.getSkuIdList()) {
                    GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                    if (null != mgtGoodsSkuInfoVo && mgtGoodsSkuInfoVo.getDelFlg().equals("0")) {
                        totalStock += mgtGoodsSkuInfoVo.getStock();
                        surplusStock += goblinRedisUtils.getSkuStock(null, skuId);

                        List<String> skuReList = goblinRedisUtils.getSkuRe(skuId);
                        if (!CollectionUtils.isEmpty(skuReList))
                            for (String skuRe : skuReList)
                                surplusStock += goblinRedisUtils
                                        .getSkuStock(GoblinStatusConst.MarketPreStatus.getPre(skuRe), skuRe);

                        if (mgtGoodsSkuInfoVo.getErpHosting() == 1) {
                            vo.setErpHostingStatus(1);
                        }
                    }
                }
                vo.setTotalStock(totalStock);
                vo.setSurplusStock(surplusStock);
                vo.setWarningStock(warningStock);
                vo.setRelateMarket(relateMarketSpuNoList.contains(vo.getSpuNo()) ? 1 : 0);

                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 PagedResult<GoblinStoreMgtGoodsSkuSimpleVo> skuList(
            GoblinStoreMgtGoodsSkuSimpleFilterParam mgtGoodsSkuSimpleFilterParam) {
        return goblinMongoUtils.getMgtGoodsSkuSimpleVos(mgtGoodsSkuSimpleFilterParam);
    }

    @Override
    public PagedResult<GoblinStoreMgtGoodsSkuListVo> skusList(
            GoblinStoreMgtGoodsSkuFilterParam mgtGoodsSkuFilterParam) {
        if (mgtGoodsSkuFilterParam.getType() == null) {
            mgtGoodsSkuFilterParam.setType(0);
        }
        PagedResult<GoblinStoreMgtGoodsSkuListVo> voList = goblinMongoUtils.getSkuSearch(mgtGoodsSkuFilterParam);
        return voList;
    }

    @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.getSkuBarCode(),
                    skuInfoVo.getSkuErpCode(),
                    skuInfoVo.getErpType(), skuInfoVo.getErpHosting(), skuInfoVo.getErpWarehouseNo(),
                    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.getSpuBarCode(), goodsInfoVo.getSpuErpCode(),
                goodsInfoVo.getErpType(),
                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_byreplace"));
        LinkedList<Object[]> initGoodsSpecObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spec_value.insert_byreplace"));
        LinkedList<Object[]> initGoodsSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_byreplace"));// SPU规格信息
        LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_byreplace"));// 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_byreplace"));// 分类关联规格信息

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

    @Override
    public void digitalGoodsAdd(GoblinGoodsInfoVo goodsInfoVo) {
        goblinMongoUtils.setGoodsInfoVo(goodsInfoVo);

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        toMqSqls.add(SqlMapping.get("goblin_goods.insert_for_digital"));
        LinkedList<Object[]> initGoodsObjs = CollectionUtil.linkedListObjectArr();
        String spuId = goodsInfoVo.getSpuId();
        initGoodsObjs.add(new Object[] {
                spuId, goodsInfoVo.getSpuNo(), goodsInfoVo.getSpuType(), goodsInfoVo.getName(), goodsInfoVo.getIntro(),
                goodsInfoVo.getAttention(), goodsInfoVo.getStoreId(), goodsInfoVo.getCateFid(),
                goodsInfoVo.getCateSid(), goodsInfoVo.getCateTid(),
                goodsInfoVo.getVirtualFlg(), goodsInfoVo.getStatus(), goodsInfoVo.getShelvesStatus(),
                goodsInfoVo.getSpuAppear(), goodsInfoVo.getAuthor(),
                goodsInfoVo.getPublisher(), goodsInfoVo.getCreatedBy(), goodsInfoVo.getCreatedAt(),
                goodsInfoVo.getSpuErpCode()
        });
        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" }));
        }

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

    @Override
    public void couponGoodsAdd(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 }));
                }
            }
        }

        LinkedList<Object[]> initGoodsSkuCouponObjs = CollectionUtil.linkedListObjectArr();// 券类商品信息
        LinkedList<Object[]> initCandyCouponObjs = CollectionUtil.linkedListObjectArr();// 券信息
        LinkedList<Object[]> initCandyCouponRuleObjs = CollectionUtil.linkedListObjectArr();// 券规则信息
        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.getSkuBarCode(),
                    skuInfoVo.getSkuErpCode(),
                    skuInfoVo.getErpType(), skuInfoVo.getErpHosting(), skuInfoVo.getErpWarehouseNo(),
                    skuInfoVo.getSkuType(), 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()
            });
            if (2 == goodsInfoVo.getSpuType()) {// 券类商品为一个SPU对应一个SKU
                initGoodsSkuCouponObjs.add(
                        new Object[] { skuId, skuInfoVo.getBusiType(), skuInfoVo.getCouType(), skuInfoVo.getUseScope(),
                                skuInfoVo.getValFace(), skuInfoVo.getIsTrueName(), skuInfoVo.getValidity(),
                                skuInfoVo.getEffectAt(), skuInfoVo.getExpireAt() });
                initCandyCouponObjs.add(
                        new Object[] { skuId, goodsInfoVo.getName(), goodsInfoVo.getIntro(), skuInfoVo.getBusiType(),
                                skuInfoVo.getCouType(), skuInfoVo.getValFace(), skuInfoVo.getValidity(),
                                skuInfoVo.getIsTrueName(),
                                skuInfoVo.getEffectAt(), skuInfoVo.getExpireAt(), createdBy, createdAt
                        });
                String busiName = "%s";
                switch (skuInfoVo.getUseScope()) {// 适用范围[101-音乐节｜102-小型演出（livehouse演出）｜103-巡演]
                    case 101:// 音乐节
                        busiName = String.format(busiName, "草莓、M_DSK、五百里音乐节");// 按杨要求文案'音乐节'改'草莓、M_DSK、五百里音乐节'
                        break;
                    case 102:// 小型演出（LiveHouse演出）
                        busiName = String.format(busiName, "小型演出（LiveHouse演出）系列");
                        break;
                    case 103:// 巡演
                        busiName = String.format(busiName, "巡演 系列");
                        break;
                }
                initCandyCouponRuleObjs
                        .add(new Object[] { IDGenerator.nextTimeId2(), skuId, skuInfoVo.getUseScope(), busiName, "" });
            }

            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_for_coupon"));
        LinkedList<Object[]> initGoodsObjs = CollectionUtil.linkedListObjectArr();
        initGoodsObjs.add(new Object[] {
                spuId, goodsInfoVo.getSpuNo(), goodsInfoVo.getSpuBarCode(), goodsInfoVo.getSpuErpCode(),
                goodsInfoVo.getErpType(), goodsInfoVo.getSpuType(),
                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_for_coupon"));
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_coupon.insert"));
        toMqSqls.add(SqlMapping.get("candy_coupon.goods_insert"));
        toMqSqls.add(SqlMapping.get("candy_coupon_rule.goods_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_byreplace"));
        LinkedList<Object[]> initGoodsSpecObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spec_value.insert_byreplace"));
        LinkedList<Object[]> initGoodsSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_byreplace"));// SPU规格信息
        LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_byreplace"));// 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_byreplace"));// 分类关联规格信息

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

    @Override
    public GoblinStoreMgtGoodsInfoVo goodsInfo(String storeId, String spuId) {
        GoblinStoreMgtGoodsInfoVo vo = GoblinStoreMgtGoodsInfoVo.getNew();
        GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
        if (null != goodsInfoVo && goodsInfoVo.getStoreId().equals(storeId) && goodsInfoVo.getDelFlg().equals("0")) {
            vo.setGoodsInfoVo(goodsInfoVo);

            // 获取收钱吧扩展信息 (spuId 级别，取第一条即可) - 仅针对 spuType 为 33 的收钱吧商品
            if (goodsInfoVo.getSpuType() == 33) {
                List<GoblinSqbGoodsExt> extList = goblinSqbGoodsExtMapper.selectList(
                        new LambdaQueryWrapper<GoblinSqbGoodsExt>()
                                .eq(GoblinSqbGoodsExt::getSpuId, spuId)
                                .eq(GoblinSqbGoodsExt::getDelFlg, "0")
                                .last("limit 1")
                );
                if (!CollectionUtils.isEmpty(extList)) {
                    GoblinSqbGoodsExt ext = extList.get(0);
                    goodsInfoVo.setSqbSpuId(ext.getSqbSpuId());
                    goodsInfoVo.setMallSn(ext.getMallSn());
                }
            }

            List<String> skuIdList = goodsInfoVo.getSkuIdList();
            if (!CollectionUtils.isEmpty(skuIdList)) {
                List<GoblinGoodsSkuInfoVo> goodsSkuInfoVoList = ObjectUtil.getGoblinGoodsSkuInfoVoArrayList();
                skuIdList.forEach(skuId -> {
                    GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                    if (null != mgtGoodsSkuInfoVo && mgtGoodsSkuInfoVo.getDelFlg().equals("0")) {
                        mgtGoodsSkuInfoVo.setSurplusStock(goblinRedisUtils.getSkuStock(null, skuId));
                        goodsSkuInfoVoList.add(mgtGoodsSkuInfoVo);
                    }
                });
                vo.setGoodsSkuInfoVoList(goodsSkuInfoVoList);
            }
        }
        return vo;
    }

    @Override
    public boolean goodsEditSpu(String uid, GoblinStoreMgtGoodsAddParam storeMgtGoodsAddParam,
            GoblinGoodsInfoVo mgtGoodsInfoVo) {
        String spuId = storeMgtGoodsAddParam.getSpuId();

        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)) {
            log.info("商品管理:SPU编辑[UID={},PARAMS={}]", uid, JsonUtils.toJson(storeMgtGoodsAddParam));
            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(), updateSpuInfoVo.getSpuErpCode(),
                            marketSpuId
                    });
                    updateGoodsSkuObjs.add(new Object[] {
                            updateSkuInfoVo.getSkuNo(), updateSkuInfoVo.getVirtualFlg(),
                            updateSkuInfoVo.getLogisticsTemplate(),
                            updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), marketSpuId
                    });
                });
            }

            // goblinMongoUtils.updateGoodsSkuInfoVoBySpuId(updateSkuInfoVo);
            goblinMongoUtils.updateGoodsSkuInfoVoPropBySpuId(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.getSpuErpCode(),
                    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 digitalGoodsEditSpu(String uid, GoblinStoreMgtDigitalGoodsAddParam mgtDigitalGoodsAddParam,
            GoblinGoodsInfoVo mgtGoodsInfoVo) {
        String spuId = mgtDigitalGoodsAddParam.getSpuId();
        GoblinGoodsInfoVo updateSpuInfoVo = mgtDigitalGoodsAddParam.initEditGoodsInfoVo();

        List<GoblinGoodsTagVo> befTagVoList = mgtGoodsInfoVo.getTagVoList();
        boolean updateTagFlg = false, befTagIsEmptyFlg = CollectionUtils.isEmpty(befTagVoList), paramTagIsEmptyFlg;
        {// 标签处理
            List<GoblinGoodsTagVo> paramTagVoList = ObjectUtil.getGoblinGoodsTagVoArrayList();
            List<String> goodsTagIdList = mgtDigitalGoodsAddParam.getTagList();
            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;
                        }
            }
            paramTagIsEmptyFlg = CollectionUtils.isEmpty(paramTagVoList);
            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);
            }
        }
        updateSpuInfoVo.setUpdatedBy(uid);
        updateSpuInfoVo.setUpdatedAt(LocalDateTime.now());
        if (goblinMongoUtils.updateGoodsInfoVo(updateSpuInfoVo)) {
            log.info("商品管理:SPU编辑-数字藏品[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtDigitalGoodsAddParam));
            goblinRedisUtils.delGoodsInfoVo(spuId);

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit_for_digital"));
            LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsInfoObjs.add(new Object[] {
                    updateSpuInfoVo.getName(), updateSpuInfoVo.getIntro(), updateSpuInfoVo.getCateFid(),
                    updateSpuInfoVo.getCateSid(),
                    updateSpuInfoVo.getCateTid(), updateSpuInfoVo.getUpdatedBy(), updateSpuInfoVo.getUpdatedAt(),
                    updateSpuInfoVo.getSpuErpCode(), updateSpuInfoVo.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" }));
                }
            }

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsInfoObjs, deleteGoodsTagObjs, initGoodsTagObjs));
            return true;
        }
        return false;
    }

    @Override
    public boolean couponGoodsEditSpu(String uid, GoblinStoreMgtGoodsCouponAddParam mgtGoodsAddParam,
            GoblinGoodsInfoVo mgtGoodsInfoVo) {
        String spuId = mgtGoodsAddParam.getSpuId();

        GoblinGoodsInfoVo updateSpuInfoVo = mgtGoodsAddParam.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 = mgtGoodsAddParam.getTagList(),
                    goodsExtagIdList = mgtGoodsAddParam.getExtagList(),
                    goodsArtagIdList = mgtGoodsAddParam.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 = mgtGoodsAddParam.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 = mgtGoodsAddParam.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)) {
            goblinRedisUtils.delGoodsInfoVo(updateSpuInfoVo.getSpuId());
            log.info("商品管理:SPU编辑[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsAddParam));
            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.setSkuPic(updateSpuInfoVo.getCoverPic());// 默认使用SPU的
            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(), updateSpuInfoVo.getSpuErpCode(),
                            marketSpuId
                    });
                    updateGoodsSkuObjs.add(new Object[] {
                            updateSkuInfoVo.getSkuNo(), updateSkuInfoVo.getVirtualFlg(),
                            updateSkuInfoVo.getLogisticsTemplate(),
                            updateSkuInfoVo.getSkuPic(), updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(),
                            marketSpuId
                    });
                });
            }

            // goblinMongoUtils.updateGoodsSkuInfoVoBySpuId(updateSkuInfoVo);
            goblinMongoUtils.updateGoodsSkuInfoVoPropBySpuId(updateSkuInfoVo);
            goblinRedisUtils.delGoodsSkuInfoVo(mgtGoodsInfoVo.getSkuIdList().get(0));

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit"));
            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.getSpuErpCode(),
                    updateSpuInfoVo.getSpuId()
            });
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_coupon_spu"));
            updateGoodsSkuObjs.add(new Object[] {
                    updateSkuInfoVo.getSkuNo(), updateSkuInfoVo.getVirtualFlg(), updateSkuInfoVo.getLogisticsTemplate(),
                    updateSkuInfoVo.getSkuPic(), updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(),
                    updateSkuInfoVo.getSpuId()
            });
            toMqSqls.add(SqlMapping.get("candy_coupon.goods_spu_update"));
            LinkedList<Object[]> updateCandyCouponObjs = CollectionUtil.linkedListObjectArr();
            updateCandyCouponObjs.add(new Object[] { updateSpuInfoVo.getName(), updateSpuInfoVo.getIntro(),
                    updateSpuInfoVo.getUpdatedBy(), updateSpuInfoVo.getUpdatedAt(), spuId });

            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' });
                }
                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' });
                }
                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, updateCandyCouponObjs,
                            deleteGoodsTagObjs, initGoodsTagObjs, deleteGoodsArTagObjs, initGoodsArTagObjs,
                            deleteServiceSupportObjs, initServiceSupportObjs, deleteGoodsImageObjs,
                            initGoodsImageObjs));
            return true;
        }
        return false;
    }

    @Override
    public boolean goodsEditSku(String uid, GoblinStoreMgtGoodsEditSkuParam mgtGoodsEditSkuParam,
            GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo,
            GoblinGoodsInfoVo goodsInfoVo, Map<String, String> delSpuSpecMap, Map<String, String> addSpuSpecMap) {
        LocalDateTime now = LocalDateTime.now();

        GoblinGoodsSkuInfoVo updateSkuInfoVo = mgtGoodsEditSkuParam.initEditGoodsSkuInfoVo(mgtGoodsSkuInfoVo);
        updateSkuInfoVo.setUpdatedBy(uid);
        updateSkuInfoVo.setUpdatedAt(now);
        String skuId = updateSkuInfoVo.getSkuId();
        if (goblinMongoUtils.updateGoodsSkuInfoVo(updateSkuInfoVo)) {
            log.info("商品管理:SKU编辑[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsEditSkuParam));
            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.getSkuBarCode(), updateSkuInfoVo.getName(), updateSkuInfoVo.getSkuPic(),
                            updateSkuInfoVo.getSellPrice(), updateSkuInfoVo.getWeight(),
                            updateSkuInfoVo.getStock(), updateSkuInfoVo.getWarningStock(),
                            updateSkuInfoVo.getSkuAppear(), updateSkuInfoVo.getSkuIsbn(),
                            updateSkuInfoVo.getSkuValidity(),
                            updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(),
                            updateSkuInfoVo.getSkuErpCode(), updateSkuInfoVo.getErpHosting(),
                            updateSkuInfoVo.getErpWarehouseNo(),
                            marketSkuId
                    });
                });
            }

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

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

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

                GoblinGoodsSpecVo specVo = specVoList.stream().filter(r -> r.getSpecName().equals(specName)).findAny()
                        .get();
                specVo.getSpecValues().forEach(r -> initSpuSpecValueObjs
                        .add(new Object[] { spuId, specName, r.getSpecVname(), r.getSpecVsort() }));
                updateSkuSpecValueObjs.add(new Object[] { specVname, skuId, specName });
                if (!CollectionUtils.isEmpty(marketSkuIdList)) {
                    marketSkuIdList.forEach(marketSkuId -> updateSkuSpecValueObjs
                            .add(new Object[] { specVname, marketSkuId, specName }));
                }
            });
            if (!delSpuSpecMap.isEmpty()) {// 删除了规格值，需要同步SPU里的规格信息
                updateGoodsInfoVoFlg = true;
                goodsInfoVo.setUpdatedBy(uid);
                goodsInfoVo.setUpdatedAt(now);
                delSpuSpecMap.forEach((k, v) -> delSpuSpecValueObjs.add(new Object[] { spuId, k, v }));
            }
            if (!addSpuSpecMap.isEmpty()) {// 新增了规格值，需要同步SPU里的规格信息
                updateGoodsInfoVoFlg = true;
                goodsInfoVo.setUpdatedBy(uid);
                goodsInfoVo.setUpdatedAt(now);
            }

            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (String skuIdStr : goodsInfoVo.getSkuIdList()) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuIdStr);
                if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                    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) {
                updateGoodsInfoVoFlg = true;
                goodsInfoVo.setPriceGe(priceGe);
                goodsInfoVo.setPriceLe(priceLe);
                goodsInfoVo.setUpdatedBy(uid);
                goodsInfoVo.setUpdatedAt(now);

                updateGoodsObjs.add(new Object[] { priceGe, priceLe, uid, now, spuId });
            }
            if (updateGoodsInfoVoFlg) {
                goblinMongoUtils.updateGoodsInfoVo(goodsInfoVo);
                goblinRedisUtils.delGoodsInfoVo(spuId);
            }
            String buyRoster = mgtGoodsEditSkuParam.getBuyRoster();
            if (StringUtils.isNotEmpty(buyRoster)) {
                queueUtils.sendMsgByRedisXls(buyRoster, mgtGoodsEditSkuParam.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(), updateSkuInfoVo.getSkuErpCode(), updateSkuInfoVo.getErpHosting(),
                    updateSkuInfoVo.getErpWarehouseNo(), 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_byreplace"));
            // 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.update_by_edit_sku"));
            // LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsSkuForMarketObjs, updateGoodsSkuObjs,
                            updateSkuSpecValueObjs, initSpuSpecValueObjs, delSpuSpecValueObjs, updateGoodsObjs));
            return true;
        }
        return false;
    }

    @Override
    public boolean digitalGoodsEditSku(String uid, GoblinStoreMgtDigitalGoodsAddSkuParam mgtDigitalGoodsAddSkuParam,
            GoblinGoodsInfoVo mgtGoodsInfoVo) {
        GoblinGoodsSkuInfoVo updateSkuInfoVo = mgtDigitalGoodsAddSkuParam.initEditGoodsSkuInfoVo();

        String skuId = updateSkuInfoVo.getSkuId();
        LocalDateTime now = LocalDateTime.now();
        updateSkuInfoVo.setUpdatedBy(uid);
        updateSkuInfoVo.setUpdatedAt(now);

        LinkedList<Object[]> deleteGoodsSkuTagObjs = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> initGoodsSkuTagObjs = CollectionUtil.linkedListObjectArr();
        {// 标签处理
            List<GoblinGoodsExtagVo> befExtagVoList = mgtGoodsInfoVo.getExtagVoList();
            List<GoblinGoodsExtagVo> paramExtagVoList = ObjectUtil.getGoblinGoodsExtagVoArrayList();
            List<String> paramExtagIdList = mgtDigitalGoodsAddSkuParam.getExtagList();
            if (!CollectionUtils.isEmpty(paramExtagIdList)) {
                List<GoblinSelfTagVo> selfExtagVos = goblinRedisUtils.getSelfExtagVos();
                for (int i = 0; i < paramExtagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfExtagVos)
                        if (r.getTagId().equals(paramExtagIdList.get(i)) && r.getTagBelong().equals("1")
                                && !r.getTagType().equals("5")) {
                            paramExtagVoList.add(GoblinGoodsExtagVo.getNew().copy(r).setSort(i));
                            break;
                        }
            }
            boolean paramExtagIsEmptyFlg = CollectionUtils.isEmpty(paramExtagVoList),
                    befExtagIsEmptyFlg = CollectionUtils.isEmpty(befExtagVoList);
            if (!befExtagIsEmptyFlg || !paramExtagIsEmptyFlg) {
                boolean updateExtagFlg = false;
                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) {
                    updateSkuInfoVo.setExtagVoList(
                            paramExtagIsEmptyFlg ? ObjectUtil.getGoblinGoodsExtagVoArrayList() : paramExtagVoList);
                    if (!befExtagIsEmptyFlg) {
                        deleteGoodsSkuTagObjs.add(new Object[] { skuId, '1' });
                    }
                    if (!paramExtagIsEmptyFlg) {
                        updateSkuInfoVo.getExtagVoList().forEach(vo -> initGoodsSkuTagObjs
                                .add(new Object[] { skuId, vo.getTagId(), vo.getSort(), "1" }));
                    }
                }
            }
        }

        if (goblinMongoUtils.updateGoodsSkuInfoVo(updateSkuInfoVo)) {
            log.info("商品管理:SKU编辑[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtDigitalGoodsAddSkuParam));
            goblinRedisUtils.delGoodsSkuInfoVo(skuId);

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();

            if ("1".equals(mgtDigitalGoodsAddSkuParam.getUnbox())) {
                BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
                for (String skuIdStr : mgtGoodsInfoVo.getSkuIdList()) {
                    GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuIdStr);
                    if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                        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;
                    }
                }
                if (priceGe.compareTo(mgtGoodsInfoVo.getPriceGe()) != 0
                        || priceLe.compareTo(mgtGoodsInfoVo.getPriceLe()) != 0) {
                    mgtGoodsInfoVo.setPriceGe(priceGe);
                    mgtGoodsInfoVo.setPriceLe(priceLe);
                    mgtGoodsInfoVo.setUpdatedBy(uid);
                    mgtGoodsInfoVo.setUpdatedAt(now);

                    goblinMongoUtils.updateGoodsInfoVo(mgtGoodsInfoVo);
                    goblinRedisUtils.delGoodsInfoVo(mgtGoodsInfoVo.getSpuId());
                    updateGoodsObjs.add(new Object[] { priceGe, priceLe, uid, now, mgtGoodsInfoVo.getSpuId() });
                }

                toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_box_digital"));
                updateGoodsSkuObjs.add(new Object[] {
                        updateSkuInfoVo.getName(), updateSkuInfoVo.getSubtitle(), updateSkuInfoVo.getSkuPic(),
                        updateSkuInfoVo.getSkuWatch(), updateSkuInfoVo.getWatchType(),
                        updateSkuInfoVo.getSkuWatchPic(), updateSkuInfoVo.getPrice(), updateSkuInfoVo.getPriceMember(),
                        updateSkuInfoVo.getIntro(), updateSkuInfoVo.getDetails(),
                        updateSkuInfoVo.getShelvesHandle(), updateSkuInfoVo.getShelvesTime(),
                        updateSkuInfoVo.getSaleStartTime(), updateSkuInfoVo.getOpeningTime(),
                        updateSkuInfoVo.getUpdatedBy(),
                        updateSkuInfoVo.getUpdatedAt(), updateSkuInfoVo.getSkuErpCode(),
                        updateSkuInfoVo.getErpHosting(), updateSkuInfoVo.getErpWarehouseNo(), skuId
                });
            } else {
                // String buyRoster = mgtDigitalGoodsAddSkuParam.getBuyRoster();
                // if (StringUtils.isNotEmpty(buyRoster)) {
                // queueUtils.sendMsgByRedisXls(buyRoster,
                // mgtDigitalGoodsAddSkuParam.getBuyRosterType(), skuId);
                // }

                toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_for_digital"));
                updateGoodsSkuObjs.add(new Object[] {
                        updateSkuInfoVo.getHitRatio(), updateSkuInfoVo.getBuyFactor(), updateSkuInfoVo.getBuyLimit(),
                        updateSkuInfoVo.getSkuAppear(), updateSkuInfoVo.getSkuCanbuy(),
                        updateSkuInfoVo.getShelvesHandle(), updateSkuInfoVo.getShelvesTime(),
                        updateSkuInfoVo.getSaleStartTime(), updateSkuInfoVo.getUpdatedBy(),
                        updateSkuInfoVo.getUpdatedAt(),
                        updateSkuInfoVo.getSkuErpCode(), updateSkuInfoVo.getErpHosting(),
                        updateSkuInfoVo.getErpWarehouseNo(), skuId
                });
            }
            toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit_sku"));
            // LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku_tag.delete"));
            // LinkedList<Object[]> deleteGoodsSkuTagObjs =
            // CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku_tag.insert_byreplace"));
            // LinkedList<Object[]> initGoodsSkuTagObjs =
            // CollectionUtil.linkedListObjectArr();

            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                    SqlMapping.gets(toMqSqls, updateGoodsSkuObjs, updateGoodsObjs, deleteGoodsSkuTagObjs,
                            initGoodsSkuTagObjs));
            return true;
        }
        return false;
    }

    @Override
    public boolean couponGoodsEditSku(String uid, GoblinStoreMgtGoodsCouponEditSkuParam mgtGoodsEditSkuParam,
            GoblinGoodsInfoVo goodsInfoVo) {
        LocalDateTime nowTime = LocalDateTime.now();

        GoblinGoodsSkuInfoVo updateSkuInfoVo = mgtGoodsEditSkuParam.initEditGoodsSkuInfoVo();
        updateSkuInfoVo.setUpdatedBy(uid);
        updateSkuInfoVo.setUpdatedAt(nowTime);
        String skuId = updateSkuInfoVo.getSkuId();
        if (goblinMongoUtils.updateGoodsSkuInfoVo(updateSkuInfoVo)) {
            goblinRedisUtils.delGoodsSkuInfoVo(skuId);
            log.info("商品管理:SKU编辑[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsEditSkuParam));
            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.getStock(), updateSkuInfoVo.getIsTrueName(), updateSkuInfoVo.getUseScope(),
                            updateSkuInfoVo.getValFace(), updateSkuInfoVo.getEffectAt(), updateSkuInfoVo.getExpireAt(),
                            updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), marketSkuId
                    });
                });
            }

            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (String skuIdStr : goodsInfoVo.getSkuIdList()) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuIdStr);
                if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                    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;
                }
            }
            boolean updateGoodsInfoVoFlg = false;
            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            if (priceGe.compareTo(goodsInfoVo.getPriceGe()) != 0 || priceLe.compareTo(goodsInfoVo.getPriceLe()) != 0) {
                updateGoodsInfoVoFlg = true;
                goodsInfoVo.setPriceGe(priceGe);
                goodsInfoVo.setPriceLe(priceLe);
                goodsInfoVo.setUpdatedBy(uid);
                goodsInfoVo.setUpdatedAt(nowTime);

                updateGoodsObjs.add(new Object[] { priceGe, priceLe, uid, nowTime, goodsInfoVo.getSpuId() });
            }
            if (updateGoodsInfoVoFlg) {
                goblinMongoUtils.updateGoodsInfoVo(goodsInfoVo);
                goblinRedisUtils.delGoodsInfoVo(goodsInfoVo.getSpuId());
            }

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_for_market2"));
            // LinkedList<Object[]> updateGoodsSkuForMarketObjs =
            // CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_edit_for_coupon"));
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsSkuObjs.add(new Object[] {
                    updateSkuInfoVo.getPrice(), updateSkuInfoVo.getPriceMember(), updateSkuInfoVo.getStock(),
                    updateSkuInfoVo.getSkuStock(),
                    updateSkuInfoVo.getBuyLimit(), updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), skuId
            });
            toMqSqls.add(SqlMapping.get("goblin_goods_sku_coupon.update"));
            LinkedList<Object[]> updateGoodsSkuCouponObjs = CollectionUtil.linkedListObjectArr();
            updateGoodsSkuCouponObjs.add(new Object[] {
                    updateSkuInfoVo.getUseScope(), updateSkuInfoVo.getValFace(), updateSkuInfoVo.getIsTrueName(),
                    updateSkuInfoVo.getEffectAt(), updateSkuInfoVo.getExpireAt(), skuId });
            toMqSqls.add(SqlMapping.get("candy_coupon.goods_sku_update"));
            LinkedList<Object[]> updateCandyCouponObjs = CollectionUtil.linkedListObjectArr();
            updateCandyCouponObjs.add(new Object[] {
                    updateSkuInfoVo.getValFace(), updateSkuInfoVo.getIsTrueName(), updateSkuInfoVo.getEffectAt(),
                    updateSkuInfoVo.getExpireAt(), updateSkuInfoVo.getUpdatedBy(), updateSkuInfoVo.getUpdatedAt(), skuId
            });
            toMqSqls.add(SqlMapping.get("candy_coupon_rule.goods_sku_update"));
            LinkedList<Object[]> updateCandyCouponRuleObjs = CollectionUtil.linkedListObjectArr();
            String busiName = "%s";
            switch (updateSkuInfoVo.getUseScope()) {// 适用范围[101-音乐节｜102-小型演出（livehouse演出）｜103-巡演]
                case 101:// 音乐节
                    busiName = String.format(busiName, "草莓、M_DSK、五百里音乐节");// 按杨要求文案'音乐节'改'草莓、M_DSK、五百里音乐节'
                    break;
                case 102:// 小型演出（LiveHouse演出）
                    busiName = String.format(busiName, "小型演出（LiveHouse演出）系列");
                    break;
                case 103:// 巡演
                    busiName = String.format(busiName, "巡演 系列");
                    break;
            }
            updateCandyCouponRuleObjs.add(new Object[] { updateSkuInfoVo.getUseScope(), busiName, skuId });
            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, updateGoodsSkuCouponObjs,
                            updateCandyCouponObjs, updateCandyCouponRuleObjs, updateGoodsObjs));
            return true;
        }
        return false;
    }

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

        GoblinGoodsSkuInfoVo addSkuInfoVo = mgtGoodsEditSkuParam.initEditAddGoodsSkuInfoVo();
        addSkuInfoVo.setSkuId(skuId);
        addSkuInfoVo.setSpuId(spuId);
        if (StringUtils.isNotBlank(mgtGoodsEditSkuParam.getSkuNo())) {
            addSkuInfoVo.setSkuNo(mgtGoodsEditSkuParam.getSkuNo());
        } else {
            addSkuInfoVo.setSkuNo(goodsInfoVo.getSpuNo());
        }
        if (StringUtils.isNotBlank(mgtGoodsEditSkuParam.getSkuBarCode())) {
            addSkuInfoVo.setSkuBarCode(mgtGoodsEditSkuParam.getSkuBarCode());
        } else {
            addSkuInfoVo.setSkuBarCode(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());
        addSkuInfoVo.setErpType(goodsInfoVo.getErpType());

        goblinMongoUtils.setGoodsSkuInfoVo(addSkuInfoVo);
        log.info("商品管理:SKU添加[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsEditSkuParam));

        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.getGoodsSkuInfoVo(skuIdStr);
            if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                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.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.getSkuBarCode(),
                addSkuInfoVo.getSkuErpCode(),
                addSkuInfoVo.getErpType(), addSkuInfoVo.getErpHosting(), addSkuInfoVo.getErpWarehouseNo(),
                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_byreplace"));
        LinkedList<Object[]> initGoodsSpecObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spec_value.insert_byreplace"));
        LinkedList<Object[]> initGoodsSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_byreplace"));// SPU规格信息
        LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_byreplace"));// 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() });
                });
            });
        }

        // 同步正在下单商品
        GoblinStoreZhengzaiCommonSingleParam param = GoblinStoreZhengzaiCommonSingleParam.getNew();
        param.setSkuId(skuId);
        param.setSpuId(spuId);
        goblinZhengzaiService.zhengzaiSkuInsertSingle(param);

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

    @Override
    public void digitalGoodsAddSku(String uid, GoblinGoodsSkuInfoVo initGoodsSkuInfoVo,
            GoblinGoodsInfoVo mgtGoodsInfoVo) {
        LocalDateTime now = LocalDateTime.now();
        // initGoodsSkuInfoVo.setRouteType("zxinchain");
        initGoodsSkuInfoVo.setUpchain(0);
        initGoodsSkuInfoVo.setCreatedAt(now);
        initGoodsSkuInfoVo.setCreatedBy(uid);

        String spuId = initGoodsSkuInfoVo.getSpuId(), skuId = initGoodsSkuInfoVo.getSkuId();
        List<String> skuIdList = mgtGoodsInfoVo.getSkuIdList();
        if (CollectionUtils.isEmpty(skuIdList)) {
            skuIdList = CollectionUtil.linkedListString();
            mgtGoodsInfoVo.setCoverPic(initGoodsSkuInfoVo.getSkuPic());// 默认使用第一个SKU图片作为SPU封面图
        }
        skuIdList.add(initGoodsSkuInfoVo.getSkuId());
        mgtGoodsInfoVo.setSkuIdList(skuIdList);
        BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO, hitRatioSum = BigDecimal.ZERO;
        for (String skuIdStr : skuIdList) {
            GoblinGoodsSkuInfoVo skuInfoVo = skuIdStr.equals(skuId) ? initGoodsSkuInfoVo
                    : goblinRedisUtils.getGoodsSkuInfoVo(skuIdStr);
            if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                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;

                BigDecimal hitRatio = skuInfoVo.getHitRatio();
                if ("0".equals(skuInfoVo.getSoldoutStatus()) && "0".equals(skuInfoVo.getUnbox()) && null != hitRatio) {
                    hitRatioSum = hitRatioSum.add(hitRatio);
                }
            }
        }
        if (hitRatioSum.compareTo(new BigDecimal("100")) > 0) {
            throw new LiquidnetServiceException(ErrorCode.HTTP_PARAM_ERROR.getCode(), "各藏品概率之和不能大于100");
        }
        LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
        if (priceGe.compareTo(mgtGoodsInfoVo.getPriceGe()) != 0
                || priceLe.compareTo(mgtGoodsInfoVo.getPriceLe()) != 0) {
            mgtGoodsInfoVo.setPriceGe(priceGe);
            mgtGoodsInfoVo.setPriceLe(priceLe);

            updateGoodsObjs
                    .add(new Object[] { priceGe, priceLe, mgtGoodsInfoVo.getShelvesStatus(), now, uid, now, spuId });
        }
        mgtGoodsInfoVo.setUpdatedBy(uid);
        mgtGoodsInfoVo.setUpdatedAt(now);

        if ("2".equals(initGoodsSkuInfoVo.getShelvesHandle())) {// 直接上架处理
            initGoodsSkuInfoVo.setShelvesStatus("3");
            initGoodsSkuInfoVo.setShelvesAt(now);
            initGoodsSkuInfoVo.setShelvesTime(null);
            if (!"3".equals(mgtGoodsInfoVo.getShelvesStatus())) {
                mgtGoodsInfoVo.setShelvesStatus("3");
                mgtGoodsInfoVo.setShelvesAt(now);

                updateGoodsObjs.clear();
                updateGoodsObjs.add(new Object[] { mgtGoodsInfoVo.getPriceGe(), mgtGoodsInfoVo.getPriceLe(),
                        mgtGoodsInfoVo.getShelvesStatus(), now, uid, now, spuId });
            }
            goblinRedisUtils.delGoblinNftGoodsInfoListVo();// NFT商品列表刷新
        }
        log.info("藏品管理:SKU添加[UID={},PARAMS={}]", uid, JsonUtils.toJson(initGoodsSkuInfoVo));
        goblinMongoUtils.updateGoodsInfoVo(mgtGoodsInfoVo);
        goblinRedisUtils.delGoodsInfoVo(spuId);
        goblinMongoUtils.setGoodsSkuInfoVo(initGoodsSkuInfoVo);
        if (initGoodsSkuInfoVo.getUnbox().equals("0")) {
            goblinRedisUtils.setSkuStock(null, initGoodsSkuInfoVo.getSkuId(), initGoodsSkuInfoVo.getSkuStock());
        }

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        toMqSqls.add(SqlMapping.get("goblin_goods_sku.insert_for_digital"));
        LinkedList<Object[]> initGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
        initGoodsSkuObjs.add(new Object[] {
                skuId, spuId, initGoodsSkuInfoVo.getSkuNo(), initGoodsSkuInfoVo.getSkuType(),
                initGoodsSkuInfoVo.getName(),
                initGoodsSkuInfoVo.getSubtitle(), initGoodsSkuInfoVo.getSkuPic(), initGoodsSkuInfoVo.getSkuWatch(),
                initGoodsSkuInfoVo.getWatchType(), initGoodsSkuInfoVo.getSkuWatchPic(),
                initGoodsSkuInfoVo.getStock(), initGoodsSkuInfoVo.getSkuStock(), initGoodsSkuInfoVo.getHitRatio(),
                initGoodsSkuInfoVo.getPrice(), initGoodsSkuInfoVo.getPriceV(),
                initGoodsSkuInfoVo.getProductId(), initGoodsSkuInfoVo.getPriceMember(), initGoodsSkuInfoVo.getIntro(),
                initGoodsSkuInfoVo.getDetails(), initGoodsSkuInfoVo.getBuyFactor(),
                initGoodsSkuInfoVo.getBuyLimit(), initGoodsSkuInfoVo.getStoreId(),
                initGoodsSkuInfoVo.getShelvesHandle(), initGoodsSkuInfoVo.getShelvesTime(),
                initGoodsSkuInfoVo.getSaleStartTime(),
                initGoodsSkuInfoVo.getVirtualFlg(), initGoodsSkuInfoVo.getStatus(),
                initGoodsSkuInfoVo.getShelvesStatus(), initGoodsSkuInfoVo.getSkuAppear(),
                initGoodsSkuInfoVo.getSkuCanbuy(),
                initGoodsSkuInfoVo.getUnbox(), initGoodsSkuInfoVo.getOpeningTime(), initGoodsSkuInfoVo.getShelvesAt(),
                uid, now,
                initGoodsSkuInfoVo.getSkuErpCode(), initGoodsSkuInfoVo.getErpType(), initGoodsSkuInfoVo.getErpHosting(),
                initGoodsSkuInfoVo.getErpWarehouseNo()
        });
        toMqSqls.add(SqlMapping.get("goblin_goods_sku_nft.insert_for_digital"));
        LinkedList<Object[]> initGoodsSkuNftObjs = CollectionUtil.linkedListObjectArr();
        if ("0".equals(initGoodsSkuInfoVo.getUnbox())) {
            initGoodsSkuNftObjs.add(new Object[] {
                    skuId, initGoodsSkuInfoVo.getRouteType(), initGoodsSkuInfoVo.getMaterialType(),
                    initGoodsSkuInfoVo.getMaterialUrl(), initGoodsSkuInfoVo.getUpchain(),
                    initGoodsSkuInfoVo.getDisplayUrl(), initGoodsSkuInfoVo.getNftUrl(), now
            });
        }
        toMqSqls.add(SqlMapping.get("goblin_goods.update_by_edit_sku_for_digital"));
        // LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();

        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                SqlMapping.gets(toMqSqls, initGoodsSkuObjs, initGoodsSkuNftObjs, updateGoodsObjs));
        if ("0".equals(initGoodsSkuInfoVo.getUnbox())) {
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.BIZ_ARTWORK_UPL.getKey(), skuId);// 藏品NFT上传、声明通过队列处理
        }
    }

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

        List<String> skuIdList = mgtGoodsInfoVo.getSkuIdList();
        skuIdList.removeIf(r -> r.equals(delSkuId));
        List<GoblinGoodsSkuInfoVo> remainGoodsSkuInfoVos = goblinMongoUtils.getGoodsSkuInfoVos(skuIdList);

        Map<String, Set<String>> remainSkuSpecNameVnameMap = new HashMap<>();
        int remainGoodsSkuInfoVoSize = remainGoodsSkuInfoVos.size();
        for (int i = 0; i < remainGoodsSkuInfoVoSize; i++) {
            GoblinGoodsSkuInfoVo remainGoodsSkuInfoVo = remainGoodsSkuInfoVos.get(i);
            if (remainGoodsSkuInfoVo.getDelFlg().equals("0")) {// 有效SKU
                List<GoblinGoodsSpecDto> remainGoodsSkuSpecDtoList = remainGoodsSkuInfoVo.getSkuSpecList();
                for (GoblinGoodsSpecDto remainGoodsSkuSpecDto : remainGoodsSkuSpecDtoList) {
                    String remainGoodsSkuSpecDtoSpecName = remainGoodsSkuSpecDto.getSpecName();
                    String remainGoodsSkuSpecDtoSpecVname = remainGoodsSkuSpecDto.getSpecVname();

                    Set<String> remainSkuSpecVnameTmpSet = remainSkuSpecNameVnameMap.get(remainGoodsSkuSpecDtoSpecName);
                    if (CollectionUtils.isEmpty(remainSkuSpecVnameTmpSet)) {
                        remainSkuSpecVnameTmpSet = CollectionUtil.getStringArraySet();
                    }
                    remainSkuSpecVnameTmpSet.add(remainGoodsSkuSpecDtoSpecVname);
                    remainSkuSpecNameVnameMap.put(remainGoodsSkuSpecDtoSpecName, remainSkuSpecVnameTmpSet);
                }
            }
        }
        List<GoblinGoodsSpecVo> goodsInfoVoSpecVoList = mgtGoodsInfoVo.getSpecVoList();
        List<GoblinGoodsSpecDto> delGoodsSkuInfoVoSkuSpecList = delGoodsSkuInfoVo.getSkuSpecList();
        LinkedList<Object[]> updateGoodsSpuSpecObjs = CollectionUtil.linkedListObjectArr();
        for (int i = 0; i < delGoodsSkuInfoVoSkuSpecList.size(); i++) {
            GoblinGoodsSpecDto delGoodsSpecDto = delGoodsSkuInfoVoSkuSpecList.get(i);
            String delGoodsSpecDtoSpecName = delGoodsSpecDto.getSpecName();
            String delGoodsSpecDtoSpecVname = delGoodsSpecDto.getSpecVname();

            Set<String> remainSkuSpecVnameSet = remainSkuSpecNameVnameMap.get(delGoodsSpecDtoSpecName);

            if (CollectionUtils.isEmpty(remainSkuSpecVnameSet)
                    || !remainSkuSpecVnameSet.contains(delGoodsSpecDtoSpecVname)) {// 其他SKU规格值中不存在当前删除SKU规格值，则删除该规格值
                for (GoblinGoodsSpecVo goodsSpecVo : goodsInfoVoSpecVoList) {
                    if (goodsSpecVo.getSpecName().equals(delGoodsSpecDtoSpecName)) {
                        List<GoblinGoodsSpecValueVo> goodsSpecVoSpecValues = goodsSpecVo.getSpecValues();

                        goodsSpecVoSpecValues.removeIf(r -> r.getSpecVname().equals(delGoodsSpecDtoSpecVname));
                        goodsSpecVoSpecValues.sort(Comparator.comparing(GoblinGoodsSpecValueVo::getSpecVsort));

                        updateGoodsSpuSpecObjs
                                .add(new Object[] { 0, "1", spuId, delGoodsSpecDtoSpecName, delGoodsSpecDtoSpecVname });
                        for (int j = 0; j < goodsSpecVoSpecValues.size(); j++) {
                            GoblinGoodsSpecValueVo goodsSpecVoSpecValue = goodsSpecVoSpecValues.get(j);
                            goodsSpecVoSpecValue.setSpecVsort(j);
                            updateGoodsSpuSpecObjs.add(new Object[] { j, "0", spuId, delGoodsSpecDtoSpecName,
                                    goodsSpecVoSpecValue.getSpecVname() });
                        }
                        break;
                    }
                }
            }
        }
        LocalDateTime now = LocalDateTime.now();
        delGoodsSkuInfoVo.setUpdatedBy(uid);
        delGoodsSkuInfoVo.setUpdatedAt(now);
        delGoodsSkuInfoVo.setDeletedBy(uid);
        delGoodsSkuInfoVo.setDeletedAt(now);

        List<String> delSkuIdList = goblinRedisUtils.getSkuRe(delSkuId);
        delSkuIdList = null == delSkuIdList ? CollectionUtil.arrayListString() : delSkuIdList;
        delSkuIdList.add(delSkuId);
        if (log.isDebugEnabled()) {
            log.debug("商品管理:商品编辑:SKU删除[delSkuId={},skuReId={}]", delSkuId, JsonUtils.toJson(delSkuIdList));
        }
        if (goblinMongoUtils.delGoodsSkuInfoVo(delSkuIdList, uid, now)) {
            delSkuIdList.forEach(skuId -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
            });

            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (String skuId : skuIdList) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                    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);
            goblinRedisUtils.delGoodsInfoVoByUnShelves(spuId);

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_del"));
            LinkedList<Object[]> delGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            delSkuIdList.forEach(skuId -> delGoodsSkuObjs.add(new Object[] { uid, now, uid, now, skuId }));
            toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.update_by_del_sku"));
            // LinkedList<Object[]> updateGoodsSpuSpecObjs =
            // CollectionUtil.linkedListObjectArr();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.update_by_del_sku"));
            LinkedList<Object[]> deleteGoodsSkuSpecObjs = CollectionUtil.linkedListObjectArr();
            deleteGoodsSkuSpecObjs.add(new Object[] { delSkuId });
            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, updateGoodsSpuSpecObjs, deleteGoodsSkuSpecObjs,
                            updateGoodsInfoObjs));

            return true;
        }
        return false;
    }

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

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

        // if (!shelvesFlg) {// 下架操作，需处理关联活动的商品数据
        // spuIdList.addAll(goblinMongoUtils.getMgtSpuIdsForMarketBySpuNos(spuNoList,
        // "3"));
        // }
        if (shelvesFlg) {
            spuIdList.addAll(goblinMongoUtils.getMgtSpuIdsForMarketBySpuNos(spuNoList, "0", "1"));
        } else {
            spuIdList.addAll(goblinMongoUtils.getMgtSpuIdsForMarketBySpuNos(spuNoList, "3"));
        }

        if (goblinMongoUtils.updateGoodsInfoVoByShelves(storeId, spuIdList, shelvesFlg, uid, now)) {
            if (goblinMongoUtils.updateGoodsSkuInfoVoByShelves(storeId, spuIdList, shelvesFlg, uid, now)) {
                log.info("商品管理:SPU管理:上下架处理[UID={},SHELVES={},PARAMS={}]", uid, shelvesFlg,
                        JsonUtils.toJson(mgtGoodsActionParam));
                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();
                String shelvesStatus = shelvesFlg ? "3" : "1";
                LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
                if (shelvesFlg) {
                    toMqSqls.add(SqlMapping.get("goblin_goods.update_by_shelves"));
                    spuIdList.forEach(spuId -> updateGoodsObjs
                            .add(new Object[] { shelvesStatus, now, uid, now, spuId, storeId }));
                } else {
                    toMqSqls.add(SqlMapping.get("goblin_goods.update_by_unshelves"));
                    spuIdList.forEach(spuId -> updateGoodsObjs
                            .add(new Object[] { "1", 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));
                return true;
            } else {
                goblinMongoUtils.updateGoodsInfoVoByShelves(storeId, spuIdList, !shelvesFlg, uid, now);
            }
        }
        return false;
    }

    @Override
    public boolean goodsSkuShelvesProcessing(GoblinStoreMgtGoodsSkuActionParam mgtGoodsSkuActionParam, String uid,
            boolean shelvesFlg) {
        String storeId = mgtGoodsSkuActionParam.getStoreId(), spuId = mgtGoodsSkuActionParam.getSpuId();
        List<String> skuIdList = mgtGoodsSkuActionParam.getSkuIdList();
        LocalDateTime now = LocalDateTime.now();

        if (goblinMongoUtils.updateGoodsSkuInfoVoByShelvesSku(storeId, skuIdList, shelvesFlg, uid, now)) {
            log.info("藏品管理:SKU管理:上下架处理[UID={},SHELVES={},PARAMS={}]", uid, shelvesFlg,
                    JsonUtils.toJson(mgtGoodsSkuActionParam));

            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            if (!shelvesFlg) {// 下架，判断是否全部下架以更改SPU上架状态
                boolean toUpdateSpuShelvesFlg = true;
                GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
                List<String> remainSkuIdList = mgtGoodsInfoVo.getSkuIdList();
                remainSkuIdList.removeAll(skuIdList);
                if (!CollectionUtils.isEmpty(remainSkuIdList)) {
                    List<GoblinGoodsSkuInfoVo> remainSkuInfoVoList = goblinMongoUtils
                            .getGoodsSkuInfoVos(remainSkuIdList);
                    for (int i = 0; i < remainSkuInfoVoList.size(); i++) {
                        GoblinGoodsSkuInfoVo remainSkuInfoVo = remainSkuInfoVoList.get(i);
                        if (remainSkuInfoVo.getDelFlg().equals("0") && remainSkuInfoVo.getShelvesStatus().equals("3")) {
                            toUpdateSpuShelvesFlg = false;
                            break;
                        }
                    }
                }
                if (toUpdateSpuShelvesFlg) {
                    goblinMongoUtils.updateGoodsInfoVoByShelves(storeId, Collections.singletonList(spuId), shelvesFlg,
                            uid, now);
                    goblinRedisUtils.delGoodsInfoVo(spuId);
                    goblinRedisUtils.delGoodsInfoVoByUnShelves(spuId);
                    updateGoodsObjs.add(new Object[] { "1", "1", now, uid, now, spuId, storeId });
                }
            }

            skuIdList.forEach(skuId -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
            });

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

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

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

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

        // 删除操作，需处理关联活动的商品数据
        spuIdList.addAll(goblinMongoUtils.getMgtSpuIdsForMarketBySpuNos(spuNoList, "0", "1", "2"));

        if (goblinMongoUtils.delGoodsInfoVoBySpuIds(storeId, spuIdList, uid, now)) {
            log.info("商品管理:SPU管理:删除处理[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsActionParam));
            goblinRedisUtils.deleteKeyForSelectGoods();// 精选商品:商品上架、下架、删除 调用的方法

            LinkedList<Object[]> updateGoodsObjs = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            spuIdList.forEach(spuId -> {
                goblinRedisUtils.delGoodsInfoVo(spuId);
                goblinRedisUtils.delGoodsInfoVoByUnShelves(spuId);
                updateGoodsObjs.add(new Object[] { uid, now, uid, now, spuId });
                updateGoodsSkuObjs.add(new Object[] { uid, now, uid, now, spuId });
            });
            List<String> skuIdList = goblinMongoUtils.getMgtGoodsSkuIds(storeId, spuIdList);
            skuIdList.forEach(skuId -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
            });
            goblinMongoUtils.delGoodsSkuInfoVo(skuIdList, uid, now);

            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}));
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_del_spu"));
            // LinkedList<Object[]> updateGoodsSkuObjs =
            // CollectionUtil.linkedListObjectArr();
            // spuIdList.forEach(spuId -> updateGoodsSkuObjs.add(new Object[]{uid, now, uid,
            // now, spuId}));

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

    @Override
    public boolean goodsSkuRemove(GoblinStoreMgtGoodsSkuActionParam mgtGoodsSkuActionParam, String uid) {
        List<String> delSkuIdList = mgtGoodsSkuActionParam.getSkuIdList();
        String spuId = mgtGoodsSkuActionParam.getSpuId();

        GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
        List<String> remainSkuIdList = mgtGoodsInfoVo.getSkuIdList();
        remainSkuIdList.removeAll(delSkuIdList);

        LocalDateTime now = LocalDateTime.now();
        LinkedList<Object[]> updateGoodsInfoObjs = CollectionUtil.linkedListObjectArr();
        if (CollectionUtils.isEmpty(remainSkuIdList)) {
            mgtGoodsInfoVo.setPriceGe(BigDecimal.ZERO);
            mgtGoodsInfoVo.setPriceLe(BigDecimal.ZERO);
        } else {
            List<GoblinGoodsSkuInfoVo> remainGoodsSkuInfoVoList = goblinMongoUtils.getGoodsSkuInfoVos(remainSkuIdList);
            BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
            for (GoblinGoodsSkuInfoVo skuInfoVo : remainGoodsSkuInfoVoList) {
                if (null != skuInfoVo && skuInfoVo.getDelFlg().equals("0")) {
                    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;
                }
            }
            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 });
            }
        }

        if (goblinMongoUtils.delGoodsSkuInfoVo(delSkuIdList, uid, now)) {
            delSkuIdList.forEach(skuId -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
            });

            mgtGoodsInfoVo.setUpdatedBy(uid);
            mgtGoodsInfoVo.setUpdatedAt(now);
            goblinMongoUtils.updateGoodsInfoVo(mgtGoodsInfoVo);
            goblinRedisUtils.delGoodsInfoVo(spuId);
            goblinRedisUtils.delGoodsInfoVoByUnShelves(spuId);

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_del"));
            LinkedList<Object[]> delGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            delSkuIdList.forEach(skuId -> delGoodsSkuObjs.add(new Object[] { uid, now, uid, now, skuId }));
            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, updateGoodsInfoObjs));

            return true;
        }
        return false;
    }

    @Override
    public boolean goodsSkuSoldOutProcessing(GoblinStoreMgtGoodsSkuActionParam mgtGoodsSkuActionParam, String uid) {
        List<String> skuIdList = mgtGoodsSkuActionParam.getSkuIdList();
        LocalDateTime now = LocalDateTime.now();
        String soldoutStatus = "1";

        if (goblinMongoUtils.updateGoodsSkuInfoVoBySoldoutSku(mgtGoodsSkuActionParam.getStoreId(), skuIdList,
                soldoutStatus, uid, now)) {
            log.info("藏品管理:SKU管理:售罄处理[UID={},PARAMS={}]", uid, JsonUtils.toJson(mgtGoodsSkuActionParam));

            skuIdList.forEach(skuId -> {
                goblinRedisUtils.delGoodsSkuInfoVo(skuId);
                goblinRedisUtils.delGoodsSkuInfoVoByUnShelves(skuId);
            });

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.update_by_soldout"));
            LinkedList<Object[]> updateGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
            skuIdList.forEach(skuId -> updateGoodsSkuObjs.add(new Object[] { soldoutStatus, uid, now, skuId }));

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