商品增加库存功能,前端页面要求显示表单修改库存(三)---完结

该贴为学习记录贴,记录博主开发项目时遇到的各种问题和解决方法

需求:对商品购买增加库存功能,并且在编辑商品页面中,根据商品拥有的规格生成From表单,用户可在From表单中修改商品各个规格的库存。

在第二章中已经处理完前端传送数据给后端,后端进行保存sku的。这一章解决后端从数据库获取sku进行封装的问题

有一个关于商品规格的遗漏点:

在这里商品的规格是总规格,所有商品共用同样的规格属性。比如规格有颜色、尺码、衣长、裤长。那么A商品可以选择只有颜色和尺码,B商品也可以选择颜色和尺码外加衣长,也可以把所有规格全选了,但是商品不能有总规格总没有的规格。而规格下有具体的规格值,颜色:蓝色,黄色;尺码:120,130。

基于以上补充的条件,从数据库获取数据的时候要先考虑一个问题,如果商品已经有了sku数据,之后用户对规格进行操作,比如原来只有颜色只有黄色和蓝色,然后用户增加了一条新的规格值,让颜色有蓝色、黄色、红色三种,而商品原来有颜色这一规格sku中只有蓝色和黄色没有红色,那么就要思考:用户增删规格后,需要对sku数据进行增删,并且还要对商品下的规格值也进行增删操作。

首先根据商品下的规格ID获取所有规格值ID(注意区分规格和规格值,颜色是规格,蓝色是规格值),将所有的规格值ID保存在specificationItemIdList中(注:specificationItemIdList保存的是所有规格值,包括新增的)。

Map < Long, List < SchoolSpecificationItem >> spItemMap = new HashMap <  > ();
List < Long > specificationItemIdList = new ArrayList <  > ();
if (CollectionUtils.isNotEmpty(specificationIdList)) {
    for (Long specificationId: specificationIdList) {
        List < SchoolSpecificationItem > schoolSpecificationItemList =
            schoolSpecificationItemRepository.findBySpecificationId(specificationId);
        if (CollectionUtils.isNotEmpty(schoolSpecificationItemList)) {
            for (SchoolSpecificationItem schoolSpecificationItem: schoolSpecificationItemList) {
                spItemMap.computeIfAbsent(schoolSpecificationItem.getSpecificationId(), key->new ArrayList <  > ())
                .add(schoolSpecificationItem);
                Long specificationItemId = schoolSpecificationItem.getId();
                specificationItemIdList.add(specificationItemId);
            }
        }
    }
}

为方便后续操作,使用Map来进行规格值的保存,key为规格ID,Value为规格值的集合,这之后将用来进行新增的sku数据封装。

Map<Long, List<Object>> spItemMap = new HashMap<>();

在获取到商品的sku数据后,根据sku的规格值来对specificationItemIdList进行remove,最后留下的是新增的规格值。

根据商品sku数据中的规格值ID来查询数据库,判断规格值是否已删除,从而删除商品下对应的规格值。

再根据specificationItemIdList来获取对应的规格值,对商品下的规格值进行增加。

开始对商品的sku表单数据进行处理:

  1. 根据商品ID和sku状态来获取所有的sku数据schoolCommoditySkuList进行封装;
  2. 删除封装后的sku数据中不存在的规格值,更改不存在的sku的状态进行逻辑删除;
    1. 在这里我用到了List的remove,但是在遍历List的时候对List进行remove会有错误,简单来讲就是原来List有3个,而遍历一开始就要遍历3次,remove掉一个之后第三个为空,这个时候没有对象遍历但是编译器还是要遍历,于是就产生了错误。专业讲解可以百度,解决方法可以用下面的代码。
      1. Iterator<Object> iterator = list.iterator();
        while(iterator..hasNext()){
        	Object obj = iterator.next();
        	iterator.remove();
        }

  3. 将新增的规格值保存在Map<Long,List<Object>> newSpItemMap中
  4. 使用递归的方式封装新增的规格值,要注意递归封装的时候会出现重复封装,比如新增规格值为颜色:红色和尺码:130。在第一次循环的时候就已经封装了红色130,但是在循环到130的时候,又会把130和红色封装一次。这时候需要在每次封装的时候将封装过的保存在一个集合中,并且每次封装之前都判断一遍是否已经封装过。
  5.  
    1. List < String > executedSkuIdList = new ArrayList <  > ();
      List < SchoolCommoditySkuSpecificationVO > addSchoolCommoditySkuSpecificationVOList = new ArrayList <  > ();
      for (Map.Entry < Long, List < SchoolSpecificationItem >> entry: newSpItemMap.entrySet()) {
          Long spId = entry.getKey();
          List < SchoolSpecificationItem > values = entry.getValue();
          Set < Long > executedIds = new HashSet <  > ();
          executedIds.add(spId);
          List < SchoolCommoditySkuSpecificationVO > results =
              this.combineSpecification(spItemMap, executedIds, values, new ArrayList <  > (), executedSkuIdList);
          addSchoolCommoditySkuSpecificationVOList.addAll(results);
      }
      
      // 递归方法
      private List < SchoolCommoditySkuSpecificationVO > combineSpecification(
          Map < Long, List < SchoolSpecificationItem >> spItemMap, Set < Long > executedIds,
          List < SchoolSpecificationItem > specificationItems, List < SchoolCommoditySkuSpecificationVO > skuSpecifications,
          List < String > excutedSkuIdList) {
          List < SchoolCommoditySkuSpecificationVO > newAlls = new ArrayList <  > ();
          if (CollectionUtils.isNotEmpty(skuSpecifications)) {
              for (SchoolCommoditySkuSpecificationVO skuSpecificationVO: skuSpecifications) {
                  if (CollectionUtils.isNotEmpty(specificationItems)) {
                      for (SchoolSpecificationItem nextItem: specificationItems) {
                          SchoolCommodityVO schoolCommodityVO = new SchoolCommodityVO();
                          Long specificationItemId = nextItem.getId();
                          String name = nextItem.getSchoolSpecification().getName();
                          String value = nextItem.getSpecifcationValue();
                          schoolCommodityVO.setId(specificationItemId);
                          schoolCommodityVO.setName(name);
                          schoolCommodityVO.setValue(value);
                          SchoolCommoditySkuSpecificationVO cloneCommoditySkuSpecificationVO =
                              new SchoolCommoditySkuSpecificationVO();
                          List < SchoolCommodityVO > specifications = new ArrayList <  > ();
                          specifications.add(schoolCommodityVO);
                          List < SchoolCommodityVO > oldSchoolCommodityVos = skuSpecificationVO.getSpecifications();
                          specifications.addAll(oldSchoolCommodityVos);
                          cloneCommoditySkuSpecificationVO.setSpecifications(specifications);
                          newAlls.add(cloneCommoditySkuSpecificationVO);
                      }
                  }
              }
          } else {
              if (CollectionUtils.isNotEmpty(specificationItems)) {
                  for (SchoolSpecificationItem nextItem: specificationItems) {
                      SchoolCommodityVO schoolCommodityVO = new SchoolCommodityVO();
                      Long specificationItemId = nextItem.getId();
                      String name = nextItem.getSchoolSpecification().getName();
                      String value = nextItem.getSpecifcationValue();
                      schoolCommodityVO.setId(specificationItemId);
                      schoolCommodityVO.setName(name);
                      schoolCommodityVO.setValue(value);
                      SchoolCommoditySkuSpecificationVO cloneCommoditySkuSpecificationVO = new SchoolCommoditySkuSpecificationVO();
                      List < SchoolCommodityVO > specifications = new ArrayList <  > ();
                      specifications.add(schoolCommodityVO);
                      cloneCommoditySkuSpecificationVO.setSpecifications(specifications);
                      newAlls.add(cloneCommoditySkuSpecificationVO);
                  }
              }
          }
          // 判断是否存在下一个处理节点
          for (Long key: spItemMap.keySet()) {
              if (!executedIds.contains(key)) {
                  // 如果未执行,就添加已执行列表内
                  executedIds.add(key);
                  return combineSpecification(spItemMap, executedIds, spItemMap.get(key), newAlls, excutedSkuIdList);
              }
          }
          //遍历删除,除去重复的sku数据
          Iterator < SchoolCommoditySkuSpecificationVO > iterator = newAlls.iterator();
          while (iterator.hasNext()) {
              SchoolCommoditySkuSpecificationVO schoolCommoditySkuSpecificationVO = iterator.next();
              List < SchoolCommodityVO > specifications = schoolCommoditySkuSpecificationVO.getSpecifications();
              String itemIdStr = getSkuSpecificationValues(specifications);
              if (excutedSkuIdList.contains(itemIdStr)) {
                  iterator.remove();
              } else {
                  excutedSkuIdList.add(itemIdStr);
              }
          }
          return newAlls;
      }
      

 总结:

  1. 所有商品共用同个规格属性,所以每次获取sku都必须判断规格和规格值的增删;
  2. 对List遍历时需要进行remove和add操作必须使用list.iterator()避免报错;
  3. 根据规格值的增删来对sku进行增删,必须考虑重复封装新数据的错误问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值