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

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.GoblinStoreMgtGoodsListVoExcel;
import com.liquidnet.service.goblin.dto.manage.*;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinStoreMgtGoodsInfoVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinStoreMgtGoodsListVo;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreMgtExtraService;
import com.liquidnet.service.goblin.service.manage.IGoblinstoreMgtGoodsService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@ApiSupport(order = 149004)
@Api(tags = "商品管理")
@Slf4j
@Validated
@RestController
@RequestMapping("store/mgt/goods")
public class GoblinStoreMgtGoodsController {
    @Autowired
    IGoblinstoreMgtGoodsService goblinstoreMgtGoodsService;
    @Autowired
    IGoblinStoreMgtExtraService goblinStoreMgtExtraService;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "SPU列表")
    @PostMapping("list")
    public ResponseDto<PagedResult<GoblinStoreMgtGoodsListVo>> list(@Valid @RequestBody GoblinStoreMgtGoodsFilterParam storeMgtGoodsFilterParam) {
        String currentUid = CurrentUtil.getCurrentUid();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeMgtGoodsFilterParam.getStoreId())) {
            log.warn("商品管理:SPU列表:无权操作该店铺，请核实[UID={},GoblinStoreMgtGoodsFilterParam={}]", currentUid, JsonUtils.toJson(storeMgtGoodsFilterParam));
            return ResponseDto.success();
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:SPU列表:[GoblinStoreMgtGoodsFilterParam={}]", JsonUtils.toJson(storeMgtGoodsFilterParam));
        }
        return ResponseDto.success(goblinstoreMgtGoodsService.goodsList(storeMgtGoodsFilterParam));
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "SPU导出")
    @PostMapping("export")
    public void export(@Valid @RequestBody GoblinStoreMgtGoodsFilterParam storeMgtGoodsFilterParam, HttpServletResponse response) {
        String currentUid = CurrentUtil.getCurrentUid();
        ServletOutputStream servletOutputStream = null;
        try {
            if (!goblinRedisUtils.hasStoreId(currentUid, storeMgtGoodsFilterParam.getStoreId())) {
                log.warn("商品管理:SPU导出:无权操作该店铺，请核实[UID={},GoblinStoreMgtGoodsFilterParam={}]", currentUid, JsonUtils.toJson(storeMgtGoodsFilterParam));
                return;
            }
            if (log.isDebugEnabled()) {
                log.debug("商品管理:SPU导出:[UID={},GoblinStoreMgtGoodsFilterParam={}]", currentUid, JsonUtils.toJson(storeMgtGoodsFilterParam));
            }
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=".concat(DateUtil.Formatter.ddHHmmssTrim.format(LocalDateTime.now()))
                    .concat(new String(("商品数据").getBytes("gb2312"), StandardCharsets.ISO_8859_1)).concat(ExcelTypeEnum.XLSX.getValue()));
            response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            servletOutputStream = response.getOutputStream();

            storeMgtGoodsFilterParam.setPageNum(1);
            storeMgtGoodsFilterParam.setPageSize(5000);
            PagedResult<GoblinStoreMgtGoodsListVo> pagedResult = goblinstoreMgtGoodsService.goodsList(storeMgtGoodsFilterParam);
            List<GoblinStoreMgtGoodsListVo> rows = pagedResult.getList();
            List<GoblinStoreMgtGoodsListVoExcel> rowsToExcels = ObjectUtil.getGoblinStoreMgtGoodsListVoExcelArrayList();
            rows.forEach(row -> rowsToExcels.add(GoblinStoreMgtGoodsListVoExcel.getNew().copy(row)));

            EasyExcel.write(servletOutputStream, GoblinStoreMgtGoodsListVoExcel.class).sheet("商品数据").doWrite(rowsToExcels);
        } catch (IOException e) {
            log.error("商品管理:SPU导出:异常[UID={},ex.msg={}]", currentUid, e.getLocalizedMessage());
        } finally {
            if (null != servletOutputStream) {
                try {
                    servletOutputStream.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "SPU管理")
    @PostMapping("operate")
    public ResponseDto<Object> action(@Valid @RequestBody GoblinStoreMgtGoodsActionParam mgtGoodsActionParam) {
        String currentUid = CurrentUtil.getCurrentUid(), storeId = mgtGoodsActionParam.getStoreId();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        List<String> spuIdList = mgtGoodsActionParam.getSpuIdList();
        if (CollectionUtils.isEmpty(spuIdList)) {
            return ResponseDto.failure(ErrorMapping.get("149009"));
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:SPU管理:[UID={},GoblinStoreMgtGoodsActionParam={}]", currentUid, JsonUtils.toJson(mgtGoodsActionParam));
        }
        boolean resultFlg;
        List<String> spuNoList = CollectionUtil.arrayListString();
        switch (mgtGoodsActionParam.getAction()) {
            case "ONSHELVES":
                for (String spuId : spuIdList) {
                    GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
                    if (null == goodsInfoVo || !goodsInfoVo.getDelFlg().equals("0")) {
                        log.warn("商品管理:SPU管理:上架警告:商品不存在或已删除[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品不存在或已删除");
                    }
                    if (!goodsInfoVo.getStoreId().equals(storeId)) {
                        log.warn("商品管理:SPU管理:上架警告:非本店铺商品，无权操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "非本店铺商品，无权操作");
                    }
                    if (goodsInfoVo.getShelvesStatus().equals("3")) {
                        log.warn("商品管理:SPU管理:上架警告:请先将商品下架后操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "无效操作，商品已上架");
                    }
                    spuNoList.add(goodsInfoVo.getSpuNo());
                }
                resultFlg = goblinstoreMgtGoodsService.goodsShelvesProcessing(mgtGoodsActionParam, currentUid, true, spuNoList);
                break;
            case "UNSHELVE":
                for (String spuId : spuIdList) {
                    GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
                    if (null == goodsInfoVo || !goodsInfoVo.getDelFlg().equals("0")) {
                        log.warn("商品管理:SPU管理:下架警告:商品不存在或已删除[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品不存在或已删除");
                    }
                    if (!goodsInfoVo.getStoreId().equals(storeId)) {
                        log.warn("商品管理:SPU管理:下架警告:非本店铺商品，无权操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "非本店铺商品，无权操作");
                    }
                    if (!goodsInfoVo.getShelvesStatus().equals("3")) {// 非上架中不允许下架
                        log.warn("商品管理:SPU管理:下架警告:非上架中商品不允许此操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "非上架中商品不允许此操作");
                    }
                    spuNoList.add(goodsInfoVo.getSpuNo());
                }
                resultFlg = goblinstoreMgtGoodsService.goodsShelvesProcessing(mgtGoodsActionParam, currentUid, false, spuNoList);
                break;
            case "REMOVE":
                for (String spuId : spuIdList) {
                    GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(spuId);
                    if (null == goodsInfoVo || !goodsInfoVo.getDelFlg().equals("0")) {
                        log.warn("商品管理:SPU管理:删除警告:商品不存在或已删除[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品不存在或已删除");
                    }
                    if (!goodsInfoVo.getStoreId().equals(storeId)) {
                        log.warn("商品管理:SPU管理:删除警告:非本店铺商品，无权操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "非本店铺商品，无权操作");
                    }
                    if (goodsInfoVo.getShelvesStatus().equals("3")) {// 上架中不允许删除
                        log.warn("商品管理:SPU管理:删除警告:请先将商品下架后操作[UID={},spuId={}]", currentUid, spuId);
                        return ResponseDto.failure(ErrorMapping.get("149016"));
                    }
                    spuNoList.add(goodsInfoVo.getSpuNo());
                }
                resultFlg = goblinstoreMgtGoodsService.goodsRemove(mgtGoodsActionParam, currentUid, spuNoList);
                break;
            default:
                log.warn("商品管理:SPU管理:Invalid operation[UID={},mgtGoodsActionParam={}]", currentUid, JsonUtils.toJson(mgtGoodsActionParam));
                return ResponseDto.failure(ErrorMapping.get("149001"));
        }
        return resultFlg ? ResponseDto.success() : ResponseDto.failure();
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "SPU添加")
    @PutMapping("add")
    public ResponseDto<Object> add(@Valid @RequestBody GoblinStoreMgtGoodsAddParam storeMgtGoodsAddParam) {
        String currentUid = CurrentUtil.getCurrentUid();
        String storeId = storeMgtGoodsAddParam.getStoreId();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:SPU添加:[GoblinStoreMgtGoodsAddParam={}]", JsonUtils.toJson(storeMgtGoodsAddParam));
        }
        List<GoblinStoreMgtGoodsAddSkuParam> skuParamList = storeMgtGoodsAddParam.getSkuParamList();
        if (CollectionUtils.isEmpty(skuParamList)) {
            return ResponseDto.failure(ErrorMapping.get("149006"));
        }
        if (CollectionUtils.isEmpty(storeMgtGoodsAddParam.getImageList())) {
            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品图片不能为空");
        }
        {// 分类、ISBN校验
            String cateSid = storeMgtGoodsAddParam.getCateSid(), cateTid = storeMgtGoodsAddParam.getCateTid();
            List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinStoreMgtExtraService.listCategoryVo();
            Optional<GoblinSelfGoodsCategoryVo> categoryVoOptional = selfGoodsCategoryVos.stream()
                    .filter(r -> r.getCateId().equals(storeMgtGoodsAddParam.getCateFid()) && r.getGrade().equals("1")).findAny();
            if (!categoryVoOptional.isPresent()) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品一级分类无效");
            }
            GoblinSelfGoodsCategoryVo selfGoodsCategoryVo = categoryVoOptional.get();
            if (selfGoodsCategoryVo.getNeIsbn().equals("1") && skuParamList.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
            }
            if (StringUtils.isNotBlank(cateSid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品二级分类无效");
                }
                selfGoodsCategoryVo = categoryVoOptional.get();
                if (selfGoodsCategoryVo.getNeIsbn().equals("1") && skuParamList.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
            if (StringUtils.isNotBlank(cateTid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品三级分类无效");
                }
                selfGoodsCategoryVo = categoryVoOptional.get();
                if (selfGoodsCategoryVo.getNeIsbn().equals("1") && skuParamList.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
//        if (selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(storeMgtGoodsAddParam.getCateFid()) && r.getGrade().equals("1"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品一级分类无效");
//        }
//        if (StringUtils.isNotBlank(cateSid) && selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品二级分类无效");
//        }
//        if (StringUtils.isNotBlank(cateTid) && selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品三级分类无效");
//        }
        }
        GoblinGoodsInfoVo mgtGoodsInfoVo = goblinMongoUtils.getMgtGoodsInfoVo(storeId, storeMgtGoodsAddParam.getName());
        if (null != mgtGoodsInfoVo) {
            return ResponseDto.failure(ErrorMapping.get("149007"));
        }
        if (storeMgtGoodsAddParam.getShelvesHandle().equals("3") && null == storeMgtGoodsAddParam.getShelvesTime()) {
            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "预约上架时间未指定");
        }

        LocalDateTime now = LocalDateTime.now();
        GoblinGoodsInfoVo goodsInfoVo = storeMgtGoodsAddParam.initGoodsInfoVo();
        goodsInfoVo.setCreatedBy(currentUid);
        goodsInfoVo.setCreatedAt(now);

        ArrayList<GoblinGoodsSpecVo> goodsSpecVoList = ObjectUtil.getGoblinGoodsSpecVoArrayList();
        List<GoblinGoodsSkuInfoVo> goodsSkuInfoVoList = ObjectUtil.getGoblinGoodsSkuInfoVoArrayList();

        storeMgtGoodsAddParam.initGoodsSkuInfoVo(goodsInfoVo, goodsSkuInfoVoList, goodsSpecVoList);

        {// 标签处理
            List<String> goodsTagIdList = storeMgtGoodsAddParam.getTagList(),
                    goodsExtagIdList = storeMgtGoodsAddParam.getExtagList(),
                    goodsArtagIdList = storeMgtGoodsAddParam.getExtagList();
            if (!CollectionUtils.isEmpty(goodsTagIdList)) {
                List<GoblinSelfTagVo> selfGoodsTagVos = goblinRedisUtils.getSelfTagVos();
                List<GoblinGoodsTagVo> goodsTagVoList = ObjectUtil.getGoblinGoodsTagVoArrayList();
                for (int i = 0; i < goodsTagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfGoodsTagVos)
                        if (r.getTagId().equals(goodsTagIdList.get(i)) && r.getTagBelong().equals("0")) {
                            goodsTagVoList.add(GoblinGoodsTagVo.getNew().copy(r).setSort(i));
                            break;
                        }
                goodsInfoVo.setTagVoList(goodsTagVoList);
            }
            if (!CollectionUtils.isEmpty(goodsExtagIdList)) {
                List<GoblinSelfTagVo> selfExtagVos = goblinRedisUtils.getSelfExtagVos();
                List<GoblinGoodsExtagVo> goodsExtagVoList = ObjectUtil.getGoblinGoodsExtagVoArrayList();
                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")) {
                            goodsExtagVoList.add(GoblinGoodsExtagVo.getNew().copy(r).setSort(i));
                            break;
                        }
                goodsInfoVo.setExtagVoList(goodsExtagVoList);
            }
            if (!CollectionUtils.isEmpty(goodsArtagIdList)) {
                List<GoblinSelfTagVo> selfExtagVos = goblinRedisUtils.getSelfExtagVos();
                List<GoblinGoodsExtagVo> goodsArtagVoList = ObjectUtil.getGoblinGoodsExtagVoArrayList();
                for (int i = 0; i < goodsArtagIdList.size(); i++)
                    for (GoblinSelfTagVo r : selfExtagVos)
                        if (r.getTagId().equals(goodsArtagIdList.get(i)) && r.getTagBelong().equals("1")) {
                            goodsArtagVoList.add(GoblinGoodsExtagVo.getNew().copy(r).setSort(i));
                            break;
                        }
                goodsInfoVo.setArtagVoList(goodsArtagVoList);
            }
        }

        // 服务保障处理
        List<String> ssidList = storeMgtGoodsAddParam.getSsidList();
        if (!CollectionUtils.isEmpty(ssidList)) {
            goodsInfoVo.setServiceSupportVoList(goblinMongoUtils.getServiceSupportVos(ssidList));
        }

        goblinstoreMgtGoodsService.goodsAdd(goodsInfoVo, goodsSkuInfoVoList);

        return ResponseDto.success(goodsInfoVo.getSpuId());
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "SPU详情")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "spuId", value = "商品ID"),
    })
    @GetMapping("info")
    public ResponseDto<GoblinStoreMgtGoodsInfoVo> info(@NotBlank(message = "店铺ID不能为空") @RequestParam String storeId,
                                                       @NotBlank(message = "商品ID不能为空") @RequestParam String spuId) {
        if (!goblinRedisUtils.hasStoreId(CurrentUtil.getCurrentUid(), storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:SPU详情:[spuId={}]", spuId);
        }
        return ResponseDto.success(goblinstoreMgtGoodsService.goodsInfo(storeId, spuId));
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "商品编辑:SPU编辑", notes = "只修改商品信息，不包含规格相关信息")
    @PostMapping("edit_spu")
    public ResponseDto<Object> editSpu(@Valid @RequestBody GoblinStoreMgtGoodsAddParam mgtGoodsAddParam) {
        String currentUid = CurrentUtil.getCurrentUid(), storeId = mgtGoodsAddParam.getStoreId();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        if (CollectionUtils.isEmpty(mgtGoodsAddParam.getImageList())) {
            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品图片不能为空");
        }
        GoblinGoodsInfoVo mgtGoodsInfoVo;
        if (StringUtils.isBlank(mgtGoodsAddParam.getSpuId())
                || null == (mgtGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(mgtGoodsAddParam.getSpuId()))
                || !mgtGoodsInfoVo.getStoreId().equals(storeId)
                || !mgtGoodsInfoVo.getDelFlg().equals("0")) {
            return ResponseDto.failure(ErrorMapping.get("149010"));
        }
        if (!mgtGoodsInfoVo.getName().equals(mgtGoodsAddParam.getName())
                && null != goblinMongoUtils.getMgtGoodsInfoVo(storeId, mgtGoodsAddParam.getName())) {
            return ResponseDto.failure(ErrorMapping.get("149007"));
        }
        if (!mgtGoodsAddParam.getShelvesHandle().equals(mgtGoodsInfoVo.getShelvesHandle())
                && mgtGoodsInfoVo.getShelvesStatus().equals("3")) {
            return ResponseDto.failure(ErrorMapping.get("149016"));
        }

        List<String> skuIdList = mgtGoodsInfoVo.getSkuIdList();
        List<GoblinGoodsSkuInfoVo> goodsSkuInfoVos = CollectionUtils.isEmpty(skuIdList) ? null : goblinMongoUtils.getGoodsSkuInfoVos(skuIdList);
        boolean hasSkuFlg = !CollectionUtils.isEmpty(goodsSkuInfoVos);
        {// 分类、ISBN校验
            String cateSid = mgtGoodsAddParam.getCateSid(), cateTid = mgtGoodsAddParam.getCateTid();
            List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinStoreMgtExtraService.listCategoryVo();
            Optional<GoblinSelfGoodsCategoryVo> categoryVoOptional = selfGoodsCategoryVos.stream()
                    .filter(r -> r.getCateId().equals(mgtGoodsAddParam.getCateFid()) && r.getGrade().equals("1")).findAny();
            if (!categoryVoOptional.isPresent()) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品一级分类无效");
            }
            GoblinSelfGoodsCategoryVo selfGoodsCategoryVo = categoryVoOptional.get();
            if (selfGoodsCategoryVo.getNeIsbn().equals("1") && hasSkuFlg && goodsSkuInfoVos.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
            }
            if (StringUtils.isNotBlank(cateSid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品二级分类无效");
                }
                selfGoodsCategoryVo = categoryVoOptional.get();
                if (selfGoodsCategoryVo.getNeIsbn().equals("1") && hasSkuFlg && goodsSkuInfoVos.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
            if (StringUtils.isNotBlank(cateTid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品三级分类无效");
                }
                selfGoodsCategoryVo = categoryVoOptional.get();
                if (selfGoodsCategoryVo.getNeIsbn().equals("1") && hasSkuFlg && goodsSkuInfoVos.stream().anyMatch(r -> StringUtils.isBlank(r.getSkuIsbn()))) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
//        if (selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(mgtGoodsAddParam.getCateFid()) && r.getGrade().equals("1"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品分类1无效");
//        }
//        if (StringUtils.isNotBlank(cateSid) && selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品分类2无效");
//        }
//        if (StringUtils.isNotBlank(cateTid) && selfGoodsCategoryVos.stream().noneMatch(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3"))) {
//            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品分类3无效");
//        }
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:商品编辑:SPU编辑:[GoblinStoreMgtGoodsAddParam={}]", JsonUtils.toJson(mgtGoodsAddParam));
        }
        boolean resultFlg = goblinstoreMgtGoodsService.goodsEditSpu(currentUid, mgtGoodsAddParam, mgtGoodsInfoVo);
        return resultFlg ? ResponseDto.success() : ResponseDto.failure();
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "商品编辑:SKU编辑", notes = "只修改单品信息，不包含商品信息")
    @PostMapping("edit_sku")
    public ResponseDto<Object> editSku(@Valid @RequestBody GoblinStoreMgtGoodsEditSkuParam mgtGoodsEditSkuParam) {
        String currentUid = CurrentUtil.getCurrentUid(), storeId = mgtGoodsEditSkuParam.getStoreId();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        String paramSkuId = mgtGoodsEditSkuParam.getSkuId();
        GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo;
        if (StringUtils.isBlank(paramSkuId)
                || null == (mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(paramSkuId))
                || !mgtGoodsSkuInfoVo.getStoreId().equals(storeId)
                || !mgtGoodsSkuInfoVo.getDelFlg().equals("0")) {
            return ResponseDto.failure(ErrorMapping.get("149011"));
        }
        GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(mgtGoodsSkuInfoVo.getSpuId());
        if (null == goodsInfoVo || !goodsInfoVo.getDelFlg().equals("0")) {
            return ResponseDto.failure(ErrorMapping.get("149010"));
        }
        {// 分类、ISBN校验
            String cateFid = goodsInfoVo.getCateFid(), cateSid = goodsInfoVo.getCateSid(), cateTid = goodsInfoVo.getCateTid();
            List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinStoreMgtExtraService.listCategoryVo();
            Optional<GoblinSelfGoodsCategoryVo> categoryVoOptional = selfGoodsCategoryVos.stream()
                    .filter(r -> r.getCateId().equals(cateFid) && r.getGrade().equals("1")).findAny();
            if (!categoryVoOptional.isPresent()) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品一级分类无效");
            }
            if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
            }
            if (StringUtils.isNotBlank(cateSid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品二级分类无效");
                }
                if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
            if (StringUtils.isNotBlank(cateTid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品三级分类无效");
                }
                if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("商品管理:商品编辑:SKU编辑:[GoblinStoreMgtGoodsEditSkuParam={}]", JsonUtils.toJson(mgtGoodsEditSkuParam));
        }
        mgtGoodsEditSkuParam.setStock(mgtGoodsSkuInfoVo.getStock());
        mgtGoodsEditSkuParam.setSkuStock(mgtGoodsSkuInfoVo.getSkuStock());
        Integer operStock = mgtGoodsEditSkuParam.getOperStock();
        if (null != operStock && operStock != 0) {// 处理库存
            int operStockVal = Math.abs(operStock);
            Integer stock = mgtGoodsSkuInfoVo.getSkuStock();// 总库存
            Integer skuStock = mgtGoodsSkuInfoVo.getSkuStock();// SKU总库存

            int surplusStock = goblinRedisUtils.getSkuStock(null, paramSkuId);// 当前剩余库存
            if (operStock < 0 && surplusStock > 0 && surplusStock >= operStockVal) {// SKU实时库存充足时允许扣减
                if (goblinRedisUtils.decrSkuStock(null, paramSkuId, operStockVal) < 0) {// 过程中库存不足时，回滚库存，编辑无效
                    goblinRedisUtils.incrSkuStock(null, paramSkuId, operStockVal);
                    return ResponseDto.failure(ErrorMapping.get("149012"));
                } else {
                    mgtGoodsEditSkuParam.setSkuStock(skuStock - operStockVal);
                    mgtGoodsEditSkuParam.setStock(stock - operStockVal);
                }
            } else if (operStock > 0) {// 增加
                goblinRedisUtils.incrSkuStock(null, paramSkuId, operStockVal);
                mgtGoodsEditSkuParam.setSkuStock(skuStock + operStockVal);
                mgtGoodsEditSkuParam.setStock(stock + operStockVal);
            } else {
                return ResponseDto.failure(ErrorMapping.get("149012"));
            }
        }

        Map<String, String> delSpuSpecMap = CollectionUtil.mapStringString();
        Map<String, String> addSpuSpecMap = CollectionUtil.mapStringString();
        {// 规格校验、处理
            Map<String, String> befSkuSpecNameVnameMap = mgtGoodsSkuInfoVo.getSkuSpecList().stream()
                    .collect(Collectors.toMap(GoblinGoodsSpecDto::getSpecName, GoblinGoodsSpecDto::getSpecVname));
            List<GoblinGoodsSpecDto> paramSkuSpecList = mgtGoodsEditSkuParam.getSkuSpecList();
            Set<String> befSkuSpecNameSet = befSkuSpecNameVnameMap.keySet();
            Map<String, String> paramUpdateSkuSpecMap = CollectionUtil.mapStringString();
            Map<String, String> paramSkuSpecMap = CollectionUtil.mapStringString();
            for (GoblinGoodsSpecDto paramSkuSpecDto : paramSkuSpecList) {
                String paramSkuSpecDtoSpecName = paramSkuSpecDto.getSpecName();
                String paramSkuSpecDtoSpecVname = paramSkuSpecDto.getSpecVname();

                if (!befSkuSpecNameSet.contains(paramSkuSpecDtoSpecName)) return ResponseDto.failure(ErrorMapping.get("149014"));
                paramSkuSpecMap.put(paramSkuSpecDtoSpecName, paramSkuSpecDtoSpecVname);
                if (!befSkuSpecNameVnameMap.get(paramSkuSpecDtoSpecName).equals(paramSkuSpecDtoSpecVname)) {
                    paramUpdateSkuSpecMap.put(paramSkuSpecDtoSpecName, paramSkuSpecDtoSpecVname);
                }
            }
            if (!paramUpdateSkuSpecMap.isEmpty()) {
                List<String> skuIdList = goodsInfoVo.getSkuIdList();// SPU下所有SKUID
                ArrayList<String> skuIdListTmp = CollectionUtil.arrayListString();
                skuIdListTmp.addAll(skuIdList);
                skuIdListTmp.removeIf(r -> r.equals(paramSkuId));

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

                            if (!paramSkuSpecMap.get(remainGoodsSkuSpecDtoSpecName).equals(remainGoodsSkuSpecDtoSpecVname)) {
                                existingSkuSpecFlg = false;// 多个规格中只要又一个规格不一样即通过
                            }

                            Set<String> remainSkuSpecVnameTmpSet = remainSkuSpecNameVnameMap.get(remainGoodsSkuSpecDtoSpecName);
                            if (CollectionUtils.isEmpty(remainSkuSpecVnameTmpSet)) {
                                remainSkuSpecVnameTmpSet = CollectionUtil.getStringArraySet();
                            }
                            remainSkuSpecVnameTmpSet.add(remainGoodsSkuSpecDtoSpecVname);
                            remainSkuSpecNameVnameMap.put(remainGoodsSkuSpecDtoSpecName, remainSkuSpecVnameTmpSet);
                        }
                        if (existingSkuSpecFlg) {
                            log.warn("商品管理:商品编辑:SKU编辑:重复的规格信息[paramSkuId={},paramSkuSpecMap={} <==> existSkuId={},existSkuSpecDtoList={}]",
                                    paramSkuId, paramSkuSpecMap, remainGoodsSkuInfoVo.getSkuId(), JsonUtils.toJson(remainGoodsSkuSpecDtoList));
                            return ResponseDto.failure(ErrorMapping.get("149015"));
                        }
                    }
                }
                List<GoblinGoodsSpecVo> spuSpecVoList = goodsInfoVo.getSpecVoList();// SPU规格集
                for (Map.Entry<String, String> entrie : paramUpdateSkuSpecMap.entrySet()) {
                    String paramUpdateSkuSpecName = entrie.getKey(), paramUpdateSkuSpecVname = entrie.getValue();

                    String befSkuSpecVname = befSkuSpecNameVnameMap.get(paramUpdateSkuSpecName);
                    Set<String> remainSkuSpecVnameSet = remainSkuSpecNameVnameMap.get(paramUpdateSkuSpecName);

                    if (CollectionUtils.isEmpty(remainSkuSpecVnameSet) || !remainSkuSpecVnameSet.contains(befSkuSpecVname)) {// 其他SKU规格值中不存在当前编辑SKU旧规格值，则删除该规格值
                        delSpuSpecMap.put(paramUpdateSkuSpecName, befSkuSpecVname);
                        for (GoblinGoodsSpecVo spuSpecVo : spuSpecVoList) {
                            if (spuSpecVo.getSpecName().equals(paramUpdateSkuSpecName)) {
                                List<GoblinGoodsSpecValueVo> spuSpecVoSpecValueList = spuSpecVo.getSpecValues();
                                spuSpecVoSpecValueList.removeIf(r -> r.getSpecVname().equals(befSkuSpecVname));
                                spuSpecVoSpecValueList.sort(Comparator.comparing(GoblinGoodsSpecValueVo::getSpecVsort));
                                for (int i = 0; i < spuSpecVoSpecValueList.size(); i++)
                                    spuSpecVoSpecValueList.get(i).setSpecVsort(i);
                                break;
                            }
                        }
                    }
                    if (CollectionUtils.isEmpty(remainSkuSpecVnameSet) || !remainSkuSpecVnameSet.contains(paramUpdateSkuSpecVname)) {// 其他SKU规格值中不存在当前编辑SKU新规格值，则新增该规格值
                        addSpuSpecMap.put(paramUpdateSkuSpecName, paramUpdateSkuSpecVname);
                        for (GoblinGoodsSpecVo spuSpecVo : spuSpecVoList) {
                            if (spuSpecVo.getSpecName().equals(paramUpdateSkuSpecName)) {
                                List<GoblinGoodsSpecValueVo> spuSpecVoSpecValueList = spuSpecVo.getSpecValues();
                                spuSpecVoSpecValueList.add(GoblinGoodsSpecValueVo.getNew().setSpecVname(paramUpdateSkuSpecVname).setSpecVsort(spuSpecVoSpecValueList.size() * 100));
                                spuSpecVoSpecValueList.sort(Comparator.comparing(GoblinGoodsSpecValueVo::getSpecVsort));
                                for (int i = 0; i < spuSpecVoSpecValueList.size(); i++)
                                    spuSpecVoSpecValueList.get(i).setSpecVsort(i);
                                break;
                            }
                        }
                    }
                }
            } else {
                mgtGoodsEditSkuParam.setSkuSpecList(null);
            }
        }

        String buyRoster = mgtGoodsEditSkuParam.getBuyRoster(), befBuyRoster = mgtGoodsSkuInfoVo.getBuyRoster();
        if (!mgtGoodsEditSkuParam.getBuyFactor().equals("2") || StringUtils.equals(befBuyRoster, buyRoster) || !buyRoster.startsWith("http")) {
            mgtGoodsEditSkuParam.setBuyRoster(null);
        }
        if (goblinstoreMgtGoodsService.goodsEditSku(currentUid, mgtGoodsEditSkuParam, goodsInfoVo, delSpuSpecMap, addSpuSpecMap)) {
            mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(paramSkuId);
            mgtGoodsSkuInfoVo.setSurplusStock(goblinRedisUtils.getSkuStock(null, paramSkuId));
            return ResponseDto.success(mgtGoodsSkuInfoVo);
        } else {
            if (null != operStock && operStock != 0) {// 处理库存:回滚
                int operStockVal = Math.abs(operStock);
                if (operStock > 0) {// 增加的减回去
                    goblinRedisUtils.decrSkuStock(null, paramSkuId, operStockVal);
                } else {// 扣减的加回去
                    goblinRedisUtils.incrSkuStock(null, paramSkuId, operStockVal);
                }
            }
            return ResponseDto.failure(ErrorMapping.get("149013"));
        }
    }

    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "商品编辑:SKU添加")
    @PutMapping("edit_sku/add")
    public ResponseDto<Object> editSkuAdd(@Valid @RequestBody GoblinStoreMgtGoodsEditSkuParam mgtGoodsEditSkuParam) {
        String currentUid = CurrentUtil.getCurrentUid(), storeId = mgtGoodsEditSkuParam.getStoreId();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        if (mgtGoodsEditSkuParam.getPrice().compareTo(BigDecimal.ZERO) <= 0
                || mgtGoodsEditSkuParam.getPriceMember().compareTo(BigDecimal.ZERO) <= 0) {
            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "价格无效");
        }
        if (null == mgtGoodsEditSkuParam.getStock() || mgtGoodsEditSkuParam.getStock() <= 0) {
            return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "库存无效");
        }
        GoblinGoodsInfoVo goodsInfoVo = goblinRedisUtils.getGoodsInfoVo(mgtGoodsEditSkuParam.getSpuId());
        if (null == goodsInfoVo || !goodsInfoVo.getDelFlg().equals("0")
                || !goodsInfoVo.getStoreId().equals(storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149010"));
        }
        {// 分类、ISBN校验
            String cateFid = goodsInfoVo.getCateFid(), cateSid = goodsInfoVo.getCateSid(), cateTid = goodsInfoVo.getCateTid();
            List<GoblinSelfGoodsCategoryVo> selfGoodsCategoryVos = goblinStoreMgtExtraService.listCategoryVo();
            Optional<GoblinSelfGoodsCategoryVo> categoryVoOptional = selfGoodsCategoryVos.stream()
                    .filter(r -> r.getCateId().equals(cateFid) && r.getGrade().equals("1")).findAny();
            if (!categoryVoOptional.isPresent()) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品一级分类无效");
            }
            if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
            }
            if (StringUtils.isNotBlank(cateSid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateSid) && r.getGrade().equals("2")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品二级分类无效");
                }
                if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
            if (StringUtils.isNotBlank(cateTid)) {
                if (!(categoryVoOptional = selfGoodsCategoryVos.stream().filter(r -> r.getCateId().equals(cateTid) && r.getGrade().equals("3")).findAny()).isPresent()) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "商品三级分类无效");
                }
                if (categoryVoOptional.get().getNeIsbn().equals("1") && StringUtils.isBlank(mgtGoodsEditSkuParam.getSkuIsbn())) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "请核实输入ISBN");
                }
            }
        }
        List<String> skuIdList = goodsInfoVo.getSkuIdList();
        List<GoblinGoodsSpecDto> paramSkuSpecDtoList = mgtGoodsEditSkuParam.getSkuSpecList();
        for (String skuId : skuIdList) {// 比对所有SKU规格信息
            GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
            if (mgtGoodsSkuInfoVo.getSkuSpecList().size() != paramSkuSpecDtoList.size()) {
                log.warn("商品管理:商品编辑:SKU添加:规格信息有误[skuSpecMap={},paramSkuSpecMap={}]", JsonUtils.toJson(mgtGoodsSkuInfoVo.getSkuSpecList()), JsonUtils.toJson(paramSkuSpecDtoList));
                return ResponseDto.failure(ErrorMapping.get("149014"));
            }

            Map<String, String> skuSpecMap = mgtGoodsSkuInfoVo.getSkuSpecList().stream()
                    .collect(Collectors.toMap(GoblinGoodsSpecDto::getSpecName, GoblinGoodsSpecDto::getSpecVname, (k1, k2) -> k2));

            boolean diffSpecFlg = false;
            for (GoblinGoodsSpecDto goodsSpecDto : paramSkuSpecDtoList) {
                String skuSpecVname = skuSpecMap.get(goodsSpecDto.getSpecName());
                if (null == skuSpecVname) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "规格无效");
                }
                if (!skuSpecVname.equals(goodsSpecDto.getSpecVname())) {
                    diffSpecFlg = true;// 多个规格中只要存在一个不一致，即可跳过，标记为允许添加
                    break;
                }
            }
            if (!diffSpecFlg) {
                log.warn("商品管理:商品编辑:SKU添加:重复的规格信息[skuSpecMap={},paramSkuSpecMap={}]", skuSpecMap, JsonUtils.toJson(paramSkuSpecDtoList));
                return ResponseDto.failure(ErrorMapping.get("149015"));
            }
        }
        List<GoblinGoodsSpecVo> specVoList = goodsInfoVo.getSpecVoList();
        if (CollectionUtils.isEmpty(specVoList)) {
            if (null == specVoList) specVoList = ObjectUtil.getGoblinGoodsSpecVoArrayList();
            int size = paramSkuSpecDtoList.size();
            for (int i = 0; i < size; i++) {
                GoblinGoodsSpecDto specDto = paramSkuSpecDtoList.get(i);
                ArrayList<GoblinGoodsSpecValueVo> specValueVoList = ObjectUtil.getGoblinGoodsSpecValueVoArrayList();
                specValueVoList.add(GoblinGoodsSpecValueVo.getNew().setSpecVname(specDto.getSpecVname()).setSpecVsort(i));
                specVoList.add(GoblinGoodsSpecVo.getNew().setSpecName(specDto.getSpecName()).setSpecSort(i).setSpecValues(specValueVoList));
            }
        } else {
            Map<String, String> paramSkuSpecMap = paramSkuSpecDtoList.stream()
                    .collect(Collectors.toMap(GoblinGoodsSpecDto::getSpecName, GoblinGoodsSpecDto::getSpecVname, (k1, k2) -> k2));
            for (GoblinGoodsSpecVo specVo : specVoList) {// 同步添加SPU规格信息
                List<GoblinGoodsSpecValueVo> specValues = specVo.getSpecValues();
                String paramSkuSpecVname = paramSkuSpecMap.get(specVo.getSpecName());
                if (StringUtils.isBlank(paramSkuSpecVname)) {
                    return ResponseDto.failure(ErrorCode.HTTP_PARAM_ERROR.getCode(), "规格无效");
                }
                if (specValues.stream().noneMatch(r -> r.getSpecVname().equals(paramSkuSpecVname))) {
                    specValues.add(GoblinGoodsSpecValueVo.getNew().setSpecVname(paramSkuSpecVname).setSpecVsort(specValues.size()));
                }
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("商品管理:商品编辑:SKU添加:[GoblinStoreMgtGoodsEditSkuParam={}]", JsonUtils.toJson(mgtGoodsEditSkuParam));
        }
        goblinstoreMgtGoodsService.goodsEditSkuAdd(currentUid, mgtGoodsEditSkuParam, goodsInfoVo);
        return ResponseDto.success();
    }

    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "商品编辑:SKU删除")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "skuId", value = "单品ID"),
    })
    @PostMapping("edit_sku/del")
    public ResponseDto<Object> editSkuDel(@NotBlank(message = "店铺ID不能为空") String storeId,
                                          @NotBlank(message = "单品ID不能为空") String skuId) {
        String currentUid = CurrentUtil.getCurrentUid();
        if (!goblinRedisUtils.hasStoreId(currentUid, storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149002"));
        }
        GoblinGoodsSkuInfoVo mgtGoodsSkuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
        if (null == mgtGoodsSkuInfoVo || !mgtGoodsSkuInfoVo.getDelFlg().equals("0") || !mgtGoodsSkuInfoVo.getStoreId().equals(storeId)) {
            return ResponseDto.failure(ErrorMapping.get("149011"));
        }
        if (mgtGoodsSkuInfoVo.getShelvesStatus().equals("3")) {
            return ResponseDto.failure(ErrorMapping.get("149016"));
        }
        GoblinGoodsInfoVo mgtGoodsInfoVo = goblinRedisUtils.getGoodsInfoVo(mgtGoodsSkuInfoVo.getSpuId());
        if (null == mgtGoodsInfoVo || !mgtGoodsInfoVo.getDelFlg().equals("0")) {
            log.warn("商品管理:商品编辑:SKU删除警告:SPU不存在或已删除[uid={},skuId={}]", currentUid, skuId);
            return ResponseDto.failure(ErrorMapping.get("149010"));
        }
        boolean delResultFlg = goblinstoreMgtGoodsService.goodsEditSkuDel(currentUid, mgtGoodsSkuInfoVo, mgtGoodsInfoVo);
        return delResultFlg ? ResponseDto.success() : ResponseDto.failure(ErrorMapping.get("149003"));
    }

//    @ApiOperationSupport(order = 10)
//    @ApiOperation(value = "商品编辑:SKU批改")
//    @ApiImplicitParams({
//            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "storeId", value = "店铺ID"),
//            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "spuId", value = "商品ID"),
//            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "batField", value = "批量修改属性"),
//            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "batFieldVal", value = "批量修改属性值"),
//    })
//    @PostMapping("edit_sku/bat")
//    public ResponseDto<Object> editSkuBat(@NotBlank(message = "店铺ID不能为空") String storeId,
//                                          @NotBlank(message = "商品ID不能为空") String spuId,
//                                          @NotBlank(message = "批量修改属性不能为空") String batField,
//                                          @NotBlank(message = "批量修改属性值不能为空") String batFieldVal) {
//        if (!goblinRedisUtils.hasStoreId(CurrentUtil.getCurrentUid(), storeId)) {
//            return ResponseDto.failure(ErrorMapping.get("149002"));
//        }
//        goblinstoreMgtGoodsService.goodsEditSkuBat(spuId, batField, batFieldVal)
//        return ResponseDto.success();
//    }
}
