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

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.constant.LnsRegex;
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.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinGoodsShowInMallHelper;
import com.liquidnet.service.goblin.dto.GoblinGoodsImportDto;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSpecValueVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSpecVo;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
@Service
public class GoblinStoreMgtGoodsImportService {
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    /**
     * 批量导入SPU.SQL队列入库分批处理数量
     */
    private static final int BATCH_COUNT_SPU_SQL_TO_QUEUE = 10;
    /**
     * 批量导入SKU.SQL队列入库分批处理数量
     */
    private static final int BATCH_COUNT_SKU_SQL_TO_QUEUE = 20;
    /**
     * 缓存记录同一个SPU下SKU规格值
     */
    private static final String LAST_SKU_SPEC_VALUE_STR = "%#V1%#V2%#V3%#V4%#V5";

    public String goodsInformationDataAnalysisProcessing(MultipartFile file, String uid, String storeId)
            throws IOException {
        String originalFilename = file.getOriginalFilename();
        AnalysisEventListener<GoblinGoodsImportDto> analysisEventListener = new AnalysisEventListener<GoblinGoodsImportDto>() {
            List<GoblinGoodsSkuInfoVo> goodsSkuInfoVos;
            List<GoblinGoodsInfoVo> goodsInfoVos;
            List<String> dtoSkuBarCodeTmpList;
            List<String> dtoSpuSpecNameTmpList;
            List<String> dtoSkuSpecValueTmpList;
            LocalDateTime now;

            @Override
            public void onException(Exception exception, AnalysisContext context) throws Exception {
                if (exception instanceof ExcelDataConvertException) {
                    Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex();
                    Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex();
                    throw new LiquidnetServiceException("-1",
                            String.format("数据内容不规范【第%s行，第%s列数据格式有误】", rowIndex + 1, columnIndex + 1));
                }
                super.onException(exception, context);
            }

            @Override
            public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
                Integer approximateTotalRowNumber = context.readSheetHolder().getApproximateTotalRowNumber();
                if (approximateTotalRowNumber > 501) {
                    log.warn("店铺商品管理:批量导入数据:异常[UID={},storeId={},totalRowNumber={}]", uid, storeId,
                            approximateTotalRowNumber);
                    throw new LiquidnetServiceException("-1", "超出总行数限制500");
                } else if (approximateTotalRowNumber <= 1) {
                    throw new LiquidnetServiceException("-1", "导入文件不能为空");
                }
                log.info("DT-IN-BEGIN:[storeId={},uid={},fileName={},totalRow={}]", uid, storeId, originalFilename,
                        approximateTotalRowNumber);

                goodsSkuInfoVos = ObjectUtil.getGoblinGoodsSkuInfoVoArrayList();
                goodsInfoVos = ObjectUtil.goblinGoodsInfoVoArrayList();
                // skuBarCodeTmpList = CollectionUtil.arrayListString();
                dtoSpuSpecNameTmpList = CollectionUtil.arrayListString();
                dtoSkuSpecValueTmpList = CollectionUtil.arrayListString();
                now = LocalDateTime.now();
                super.invokeHead(headMap, context);
            }

            @Override
            public void invoke(GoblinGoodsImportDto dto, AnalysisContext analysisContext) {
                if (log.isDebugEnabled()) {
                    log.debug("dt1:{}", dto.toString());
                }
                Integer rowIndex = analysisContext.readRowHolder().getRowIndex();

                GoblinGoodsInfoVo lastGoodsInfoVo = CollectionUtils.isEmpty(goodsInfoVos) ? null
                        : goodsInfoVos.get(goodsInfoVos.size() - 1);
                boolean tobeNextSpuFlg = null == lastGoodsInfoVo || !lastGoodsInfoVo.getName().equals(dto.getSpuName());

                goodsInformationDataAnalysisProcessingValid(dto, rowIndex + 1, tobeNextSpuFlg, dtoSpuSpecNameTmpList,
                        dtoSkuSpecValueTmpList, dtoSkuBarCodeTmpList);

                if (tobeNextSpuFlg) {
                    lastGoodsInfoVo = goodsInformationDataAnalysisProcessingForSpu(dto, uid, storeId, now);
                    if (log.isDebugEnabled()) {
                        log.debug("dt2:{}", lastGoodsInfoVo);
                    }
                    goodsInfoVos.add(lastGoodsInfoVo);
                }

                GoblinGoodsSkuInfoVo lastGoodsSkuInfoVo = goodsInformationDataAnalysisProcessingForSku(dto,
                        lastGoodsInfoVo, tobeNextSpuFlg);
                if (null != lastGoodsSkuInfoVo) {
                    goodsSkuInfoVos.add(lastGoodsSkuInfoVo);
                } else {
                    dto.setFailureReason(String.valueOf(rowIndex + 1));
                }

                dto.setSkuSpecDtos(null);
                dto.setSpuImgList(null);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {// 解析完成...
                if (log.isDebugEnabled()) {
                    log.debug("dt3-1:{}", JsonUtils.toJson(goodsInfoVos));
                    log.debug("dt3-2:{}", JsonUtils.toJson(goodsSkuInfoVos));
                }

                if (!CollectionUtils.isEmpty(goodsInfoVos)) {
                    // List<String> existGoodsSkuNoList =
                    // goblinMongoUtils.existGoodsSkuNoBySkuNoList(storeId, skuBarCodeTmpList);
                    // if (!CollectionUtils.isEmpty(existGoodsSkuNoList)) {
                    // if (existGoodsSkuNoList.size() > 3) {
                    // throw new LiquidnetServiceException("-1",
                    // String.format("规格条码与已添加商品条码重复，重复条码如下： %s,...",
                    // StringUtils.join(existGoodsSkuNoList.subList(0, 3), ",")));
                    // }
                    // throw new LiquidnetServiceException("-1",
                    // String.format("规格条码与已添加商品条码重复，重复条码如下： %s",
                    // StringUtils.join(existGoodsSkuNoList, ",")));
                    // }
                    log.info("DT-IN-ToMDB:[storeId={},uid={},fileName={},spuCount={},skuCount={}]", uid, storeId,
                            originalFilename, goodsInfoVos.size(), goodsSkuInfoVos.size());
                    goblinMongoUtils.insertMgtGoodsInfoVos(goodsInfoVos);
                    goblinMongoUtils.insertMgtGoodsSkuInfoVos(goodsSkuInfoVos);

                    log.info("DT-IN-ToSQL1:[storeId={},uid={},fileName={}]", uid, storeId, originalFilename);
                    LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
                    toMqSqls.add(SqlMapping.get("goblin_goods.insert"));
                    LinkedList<Object[]> initGoodsObjs = CollectionUtil.linkedListObjectArr();
                    toMqSqls.add(SqlMapping.get("goblin_goods_image.insert_byreplace"));// SPU图片
                    LinkedList<Object[]> initGoodsImageObjs = CollectionUtil.linkedListObjectArr();
                    toMqSqls.add(SqlMapping.get("goblin_goods_spu_spec_value.insert_byreplace"));// SPU规格信息
                    LinkedList<Object[]> initGoodsSpuSpecValueObjs = CollectionUtil.linkedListObjectArr();
                    for (int i = 0, size = goodsInfoVos.size(); i < size; i++) {
                        GoblinGoodsInfoVo goodsInfoVo = goodsInfoVos.get(i);
                        initGoodsObjs.add(new Object[] { goodsInfoVo.getSpuId(), goodsInfoVo.getSpuNo(),
                                goodsInfoVo.getSpuBarCode(), goodsInfoVo.getSpuErpCode(),
                                StringUtils.isBlank(goodsInfoVo.getErpType()) ? "WANGDIAN" : 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(),
                                GoblinGoodsShowInMallHelper.resolve(goodsInfoVo),
                                goodsInfoVo.getShelvesAt(), goodsInfoVo.getCreatedBy(),
                                goodsInfoVo.getCreatedAt(), goodsInfoVo.getLogisticsTemplate() });
                        if (!CollectionUtils.isEmpty(goodsInfoVo.getImageList())) {
                            goodsInfoVo.getImageList().forEach(imageUrl -> initGoodsImageObjs
                                    .add(new Object[] { goodsInfoVo.getSpuId(), imageUrl }));
                        }
                        goodsInfoVo.getSpecVoList().forEach(specVo -> {
                            specVo.getSpecValues().forEach(specValues -> {
                                initGoodsSpuSpecValueObjs.add(new Object[] { goodsInfoVo.getSpuId(),
                                        specVo.getSpecName(), specValues.getSpecVname(), specValues.getSpecVsort() });
                            });
                        });
                        if (initGoodsObjs.size() == BATCH_COUNT_SPU_SQL_TO_QUEUE) {
                            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(), SqlMapping.gets(toMqSqls,
                                    initGoodsObjs, initGoodsImageObjs, initGoodsSpuSpecValueObjs));
                            initGoodsObjs.clear();
                            initGoodsImageObjs.clear();
                            initGoodsSpuSpecValueObjs.clear();
                        }
                    }
                    if (initGoodsObjs.size() > 0) {
                        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(), SqlMapping.gets(toMqSqls,
                                initGoodsObjs, initGoodsImageObjs, initGoodsSpuSpecValueObjs));
                    }
                    log.info("DT-IN-ToSQL2:[storeId={},uid={},fileName={}]", uid, storeId, originalFilename);
                    toMqSqls.clear();
                    toMqSqls.add(SqlMapping.get("goblin_goods_sku.insert"));
                    LinkedList<Object[]> initGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
                    toMqSqls.add(SqlMapping.get("goblin_goods_sku_spec_value.insert_byreplace"));// SKU规格信息
                    LinkedList<Object[]> initGoodsSkuSpecValueObjs = CollectionUtil.linkedListObjectArr();
                    goodsSkuInfoVos.forEach(goodsSkuInfoVo -> {
                        goblinRedisUtils.setSkuStock(null, goodsSkuInfoVo.getSkuId(), goodsSkuInfoVo.getSkuStock());
                        initGoodsSkuObjs.add(new Object[] { goodsSkuInfoVo.getSkuId(), goodsSkuInfoVo.getSpuId(),
                                goodsSkuInfoVo.getSkuNo(), goodsSkuInfoVo.getSkuBarCode(), goodsSkuInfoVo.getName(),
                                goodsSkuInfoVo.getSubtitle(), goodsSkuInfoVo.getSellPrice(), goodsSkuInfoVo.getSkuPic(),
                                goodsSkuInfoVo.getSkuIsbn(), goodsSkuInfoVo.getStock(),
                                goodsSkuInfoVo.getSkuStock(), goodsSkuInfoVo.getWarningStock(),
                                goodsSkuInfoVo.getPrice(), goodsSkuInfoVo.getPriceMember(), goodsSkuInfoVo.getWeight(),
                                goodsSkuInfoVo.getBuyFactor(), goodsSkuInfoVo.getBuyRoster(),
                                goodsSkuInfoVo.getBuyLimit(), goodsSkuInfoVo.getStoreId(),
                                goodsSkuInfoVo.getSkuValidity(),
                                goodsSkuInfoVo.getVirtualFlg(), goodsSkuInfoVo.getStatus(),
                                goodsSkuInfoVo.getShelvesStatus(), goodsSkuInfoVo.getSkuAppear(),
                                goodsSkuInfoVo.getShelvesAt(),
                                uid, goodsSkuInfoVo.getCreatedAt(), goodsSkuInfoVo.getLogisticsTemplate()
                        });
                        goodsSkuInfoVo.getSkuSpecList()
                                .forEach(skuSpecDto -> initGoodsSkuSpecValueObjs.add(new Object[] {
                                        goodsSkuInfoVo.getSpuId(), goodsSkuInfoVo.getSkuId(), skuSpecDto.getSpecName(),
                                        skuSpecDto.getSpecVname()
                                }));

                        if (initGoodsSkuObjs.size() == BATCH_COUNT_SKU_SQL_TO_QUEUE) {
                            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                                    SqlMapping.gets(toMqSqls, initGoodsSkuObjs, initGoodsSkuSpecValueObjs));
                            initGoodsSkuObjs.clear();
                            initGoodsSkuSpecValueObjs.clear();
                        }
                    });
                    if (initGoodsSkuObjs.size() > 0) {
                        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(),
                                SqlMapping.gets(toMqSqls, initGoodsSkuObjs, initGoodsSkuSpecValueObjs));
                    }
                }

            }
        };
        List<GoblinGoodsImportDto> readDtoList = EasyExcel
                .read(file.getInputStream(), GoblinGoodsImportDto.class, analysisEventListener).sheet(0).doReadSync();
        if (CollectionUtils.isEmpty(readDtoList)) {
            throw new LiquidnetServiceException("-1", "导入文件不能为空");
        }

        long failureRows = readDtoList.stream().filter(r -> StringUtils.isNotEmpty(r.getFailureReason())).count();
        String analysisResultMsg = String.format("导入成功%s条数据，导入失败%s条数据", readDtoList.size() - failureRows, failureRows);
        log.info("DT-IN-END:[storeId={},uid={},fileName={},readResult:{}]", uid, storeId, originalFilename,
                analysisResultMsg);
        return analysisResultMsg;
    }

    private void goodsInformationDataAnalysisProcessingValid(GoblinGoodsImportDto dto, Integer rowNum,
            boolean tobeNextSpuFlg,
            List<String> dtoSpuSpecNameTmpList, List<String> dtoSkuSpecValueTmpList,
            List<String> dtoSkuBarCodeTmpList) {
        /*
         * 商品编码校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isNotEmpty(dto.getSpuCode())
                && !Pattern.matches(LnsRegex.Valid.ALPHABET_NUMBER_UNDER_50, dto.getSpuCode())) {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品编码有误】", rowNum));
        }
        /*
         * 商品名称校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isEmpty(dto.getSpuName()) || dto.getSpuName().length() > 30) {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品名称有误】", rowNum));
        }
        /*
         * 商品图片校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isNotEmpty(dto.getSpuImgs())) {
            if (dto.getSpuImgs().startsWith("【图片链接】")) {
                String[] spuImgsArr = dto.getSpuImgs().replace("【图片链接】", "").replace(";", "；").split("；");
                if (spuImgsArr.length > 9) {
                    throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品图片最多支持15张】", rowNum));
                }
                ArrayList<String> spuImgList = CollectionUtil.arrayListString();
                for (String spuImg : spuImgsArr) {
                    if (StringUtils.isNotBlank(spuImg)) {
                        spuImgList.add(spuImg);
                    }
                }
                if (!CollectionUtils.isEmpty(spuImgList)) {
                    dto.setSpuImgList(spuImgList);
                }
            } else {
                throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品图片格式有误】", rowNum));
            }
        }
        /*
         * 商品规格校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isEmpty(dto.getSkuSpec())) {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格信息缺失】", rowNum));
        }
        String skuSpecStr = dto.getSkuSpec().replace(":", "：").replace(";", "；");
        if (tobeNextSpuFlg) {
            dtoSpuSpecNameTmpList.clear();
            dtoSkuSpecValueTmpList.clear();
        }
        String lastSkuSpecValueStr = LAST_SKU_SPEC_VALUE_STR;
        String[] lastSkuSpecStrArr = skuSpecStr.split("；");
        if (lastSkuSpecStrArr.length > 5) {// 分割开的规格项数量超限
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格项超出5个】", rowNum));
        }
        List<GoblinGoodsSpecDto> skuSpecDtos = ObjectUtil.getGoblinGoodsSpecDtoArrayList();
        for (int i = 0, size = lastSkuSpecStrArr.length; i < size; i++) {
            String lastSkuSpecStr = lastSkuSpecStrArr[i];
            if (StringUtils.isEmpty(lastSkuSpecStr)) {// 分割出的规格信息为空
                throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格信息无效】", rowNum));
            }
            String[] lastSpecArr = lastSkuSpecStr.split("：");
            if (ArrayUtils.isEmpty(lastSpecArr) || lastSpecArr.length != 2 || lastSpecArr[0].length() > 5
                    || lastSpecArr[1].length() > 40) {
                // 分割出的规格（项：值）内容不规范
                throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格信息有误】", rowNum));
            }
            if (tobeNextSpuFlg) {
                dtoSpuSpecNameTmpList.add(lastSpecArr[0]);
                lastSkuSpecValueStr = lastSkuSpecValueStr.replace("%#V" + (i + 1), lastSpecArr[1]);
            } else {
                if (lastSkuSpecStrArr.length != dtoSpuSpecNameTmpList.size()) {// 规格数量与SPU规格数量不一致
                    throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格数量不一致】", rowNum));
                }
                int tempSpuSpecIdx = dtoSpuSpecNameTmpList.indexOf(lastSpecArr[0]);
                if (tempSpuSpecIdx < 0) {// 规格项在SPU中不存在
                    throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格项不一致】", rowNum));
                }
                lastSkuSpecValueStr = lastSkuSpecValueStr.replace("%#V" + (tempSpuSpecIdx + 1), lastSpecArr[1]);
            }

            GoblinGoodsSpecDto skuSpecDto = GoblinGoodsSpecDto.getNew();
            skuSpecDto.setSpecName(lastSpecArr[0]);
            skuSpecDto.setSpecVname(lastSpecArr[1]);
            skuSpecDtos.add(skuSpecDto);
        }
        if (tobeNextSpuFlg || !dtoSkuSpecValueTmpList.contains(lastSkuSpecValueStr)) {
            dtoSkuSpecValueTmpList.add(lastSkuSpecValueStr);
        } else {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行商品规格信息重复】", rowNum));
        }
        dto.setSkuSpecDtos(skuSpecDtos);
        /*
         * 规格编码校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isNotEmpty(dto.getSkuCode())
                && !Pattern.matches(LnsRegex.Valid.ALPHABET_NUMBER_UNDER_50, dto.getSkuCode())) {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行规格编码格式有误】", rowNum));
        }
        /*
         * 价格校验｜------------------------------------------------------------------------
         * ------
         */
        if (null == dto.getPrice() || dto.getPrice().compareTo(BigDecimal.valueOf(0.01)) < 0
                || dto.getPrice().compareTo(BigDecimal.valueOf(9999999)) > 0) {
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行价格信息有误】", rowNum));
        }
        /*
         * 库存校验｜------------------------------------------------------------------------
         * ------
         */
        if (null == dto.getStock() || dto.getStock() < 0 || dto.getStock() > 9999999) {// 数据不规范停止解析并提示用户
            throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行库存信息有误】", rowNum));
        }
        /*
         * 规格图片校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isNotEmpty(dto.getSkuImg())) {
            if (dto.getSkuImg().startsWith("【图片链接】")) {
                String[] skuImgArr = dto.getSkuImg().replace("【图片链接】", "").replace(";", "；").split("；");
                if (skuImgArr.length == 1) {
                    dto.setSkuImg(StringUtils.isNotBlank(skuImgArr[0]) ? skuImgArr[0] : null);
                } else {
                    throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行规格图片仅支持1张】", rowNum));
                }
            } else {
                throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行规格图片格式有误】", rowNum));
            }
        }
        /*
         * 规格条码校验｜----------------------------------------------------------------------
         * --------
         */
        if (StringUtils.isNotEmpty(dto.getSkuBarCode())) {
            if (Pattern.matches(LnsRegex.Valid.ALPHABET_NUMBER_32, dto.getSkuBarCode())) {
                // if (dtoSkuBarCodeTmpList.contains(dto.getSkuBarCode())) {
                // throw new LiquidnetServiceException("-1",
                // String.format("数据内容不规范【第%s行表格内规格条码重复】", rowNum));
                // }
                // dtoSkuBarCodeTmpList.add(dto.getSkuBarCode());
            } else {
                throw new LiquidnetServiceException("-1", String.format("数据内容不规范【第%s行规格条码格式有误】", rowNum));
            }
        }
        /*
         * 校验｜--------------------------------------------------------------------------
         * ----
         */
        /*
         * 校验｜--------------------------------------------------------------------------
         * ----
         */
        /*
         * 校验｜--------------------------------------------------------------------------
         * ----
         */
    }

    private GoblinGoodsInfoVo goodsInformationDataAnalysisProcessingForSpu(GoblinGoodsImportDto dt, String uid,
            String storeId, LocalDateTime now) {
        GoblinGoodsInfoVo lastGoodsInfoVo = GoblinGoodsInfoVo.getNew();
        lastGoodsInfoVo.setName(dt.getSpuName());// *
        lastGoodsInfoVo.setSpuId(IDGenerator.nextSnowId());// *
        if (StringUtils.isNotEmpty(dt.getSpuCode())) {
            lastGoodsInfoVo.setSpuNo(dt.getSpuCode());
        } else {
            lastGoodsInfoVo.setSpuNo(lastGoodsInfoVo.getSpuId());
        }
        // if (StringUtils.isNotEmpty(dt.getSpuBarCode())) {
        // lastGoodsInfoVo.setSpuBarCode(dt.getSpuBarCode());
        // } else {
        // lastGoodsInfoVo.setSpuBarCode(lastGoodsInfoVo.getSpuId());
        // }
        if (!CollectionUtils.isEmpty(dt.getSpuImgList())) {
            lastGoodsInfoVo.setImageList(dt.getSpuImgList());
            lastGoodsInfoVo.setCoverPic(lastGoodsInfoVo.getImageList().get(0));
        }

        lastGoodsInfoVo.setDetails(lastGoodsInfoVo.getName());
        lastGoodsInfoVo.setSpuType(0);// *
        lastGoodsInfoVo.setSpecMode("1");// *
        lastGoodsInfoVo.setShelvesHandle("1");
        lastGoodsInfoVo.setVirtualFlg("0");
        lastGoodsInfoVo.setStatus("3");
        lastGoodsInfoVo.setShelvesStatus("0");
        lastGoodsInfoVo.setSpuAppear("0");// *
        lastGoodsInfoVo.setShowInMall(GoblinGoodsShowInMallHelper.SHOW_IN_MALL_YES);
        lastGoodsInfoVo.setSpuCanbuy("1");
        lastGoodsInfoVo.setDelFlg("0");
        lastGoodsInfoVo.setCreatedAt(now);
        lastGoodsInfoVo.setCreatedBy(uid);// *
        lastGoodsInfoVo.setStoreId(storeId);// *
        return lastGoodsInfoVo;
    }

    private GoblinGoodsSkuInfoVo goodsInformationDataAnalysisProcessingForSku(GoblinGoodsImportDto dt,
            GoblinGoodsInfoVo lastGoodsInfoVo, boolean tobeNextSpuFlg) {
        GoblinGoodsSkuInfoVo skuInfoVo = GoblinGoodsSkuInfoVo.getNew();

        skuInfoVo.setName("");
        List<GoblinGoodsSpecDto> skuSpecDtos = dt.getSkuSpecDtos();
        List<GoblinGoodsSpecVo> spuSpecVos = tobeNextSpuFlg ? ObjectUtil.getGoblinGoodsSpecVoArrayList()
                : lastGoodsInfoVo.getSpecVoList();
        for (int i = 0, size = skuSpecDtos.size(); i < size; i++) {
            GoblinGoodsSpecDto skuSpecDto = skuSpecDtos.get(i);

            skuInfoVo.setName(skuInfoVo.getName().concat(skuSpecDto.getSpecVname()));

            if (tobeNextSpuFlg) {
                List<GoblinGoodsSpecValueVo> spuSpecValueVos = ObjectUtil.getGoblinGoodsSpecValueVoArrayList();
                spuSpecValueVos
                        .add(GoblinGoodsSpecValueVo.getNew().setSpecVname(skuSpecDto.getSpecVname()).setSpecVsort(1));
                GoblinGoodsSpecVo spuSpecVo = GoblinGoodsSpecVo.getNew().setSpecName(skuSpecDto.getSpecName())
                        .setSpecSort(i + 1).setSpecValues(spuSpecValueVos);
                spuSpecVos.add(spuSpecVo);
            } else {
                Optional<GoblinGoodsSpecVo> hasSpecOptional = spuSpecVos.stream()
                        .filter(r -> r.getSpecName().equals(skuSpecDto.getSpecName())).findAny();
                if (hasSpecOptional.isPresent()) {
                    GoblinGoodsSpecVo spuSpecVo = hasSpecOptional.get();

                    List<GoblinGoodsSpecValueVo> spuSpecValueVos = spuSpecVo.getSpecValues();
                    Optional<GoblinGoodsSpecValueVo> any = spuSpecValueVos.stream()
                            .filter(r -> r.getSpecVname().equals(skuSpecDto.getSpecVname())).findAny();
                    if (!any.isPresent()) {
                        spuSpecValueVos.add(GoblinGoodsSpecValueVo.getNew().setSpecVname(skuSpecDto.getSpecVname())
                                .setSpecVsort(lastGoodsInfoVo.getSkuIdList().size() + 1));
                    }
                } else {// 不匹配的规格直接跳过（默认只匹配商品第一行数据中的规格项）
                    return null;
                }
            }
        }

        skuInfoVo.setStock(dt.getStock());// *
        skuInfoVo.setSkuStock(dt.getStock());// *
        skuInfoVo.setPrice(dt.getPrice());// *
        skuInfoVo.setPriceMember(dt.getPrice());// *
        skuInfoVo.setSkuId(lastGoodsInfoVo.getSpuId().concat(StringUtils.right(String.valueOf(System.nanoTime()), 5)));// *
        if (StringUtils.isNotEmpty(dt.getSkuCode())) {
            skuInfoVo.setSkuNo(dt.getSkuCode());
        } else {
            skuInfoVo.setSkuNo(lastGoodsInfoVo.getSpuNo());
        }
        if (StringUtils.isNotEmpty(dt.getSkuImg())) {
            skuInfoVo.setSkuPic(dt.getSkuImg());
        } else {
            // skuInfoVo.setSkuPic("");// 设置默认图片
        }
        if (StringUtils.isNotEmpty(dt.getSkuBarCode())) {
            skuInfoVo.setSkuBarCode(dt.getSkuBarCode());
        } else {
            skuInfoVo.setSkuBarCode(lastGoodsInfoVo.getSpuNo());
        }

        skuInfoVo.setSpuId(lastGoodsInfoVo.getSpuId());// *
        skuInfoVo.setSkuType(0);// *
        skuInfoVo.setBuyFactor("0");
        skuInfoVo.setBuyLimit(0);
        skuInfoVo.setStatus("3");
        skuInfoVo.setShelvesStatus(lastGoodsInfoVo.getShelvesStatus());
        skuInfoVo.setSoldoutStatus("0");// *
        skuInfoVo.setSkuAppear("0");// *
        skuInfoVo.setSkuCanbuy("1");
        skuInfoVo.setDelFlg("0");
        skuInfoVo.setCreatedAt(lastGoodsInfoVo.getCreatedAt());// *
        skuInfoVo.setCreatedBy(lastGoodsInfoVo.getCreatedBy());// *
        skuInfoVo.setStoreId(lastGoodsInfoVo.getStoreId());
        skuInfoVo.setSkuSpecList(skuSpecDtos);

        if (tobeNextSpuFlg) {
            List<String> skuIdList = CollectionUtil.arrayListString();
            skuIdList.add(skuInfoVo.getSkuId());
            lastGoodsInfoVo.setSkuIdList(skuIdList);
            lastGoodsInfoVo.setSpecVoList(spuSpecVos);
            lastGoodsInfoVo.setPriceGe(skuInfoVo.getPrice());
            lastGoodsInfoVo.setPriceLe(skuInfoVo.getPrice());
        } else {
            BigDecimal priceGe = lastGoodsInfoVo.getPriceGe();
            BigDecimal priceLe = lastGoodsInfoVo.getPriceLe();
            List<String> skuIdList = lastGoodsInfoVo.getSkuIdList();

            skuIdList.add(skuInfoVo.getSkuId());

            lastGoodsInfoVo.setSkuIdList(skuIdList);
            lastGoodsInfoVo.setSpecVoList(spuSpecVos);
            lastGoodsInfoVo.setPriceGe(skuInfoVo.getPrice().compareTo(priceGe) < 0 ? skuInfoVo.getPrice() : priceGe);
            lastGoodsInfoVo.setPriceLe(priceLe.compareTo(skuInfoVo.getPrice()) < 0 ? skuInfoVo.getPrice() : priceLe);
        }
        return skuInfoVo;
    }
}
