优化商品草稿/商品模版,sku和批发规则保存规则。

BREAKING CHANGE: li_wholesale 表 增加 template_id(商品模版id)字段
This commit is contained in:
paulGao 2022-10-13 12:02:02 +08:00
parent 6c87de7a97
commit d75bb7b7cf
17 changed files with 137 additions and 103 deletions

View File

@ -44,3 +44,5 @@ CREATE TABLE `li_wholesale`
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin COMMENT '批发规则表';
ALTER TABLE li_wholesale
ADD template_id bigint DEFAULT NULL COMMENT '商品模版id';

View File

@ -111,7 +111,7 @@ public class DraftGoods extends BaseEntity {
private String goodsVideo;
@ApiModelProperty(value = "是否为推荐商品")
private boolean recommend;
private Boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum

View File

@ -6,6 +6,7 @@ import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dto.DraftGoodsDTO;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
@ -204,6 +205,30 @@ public class Goods extends BaseEntity {
}
}
public Goods(DraftGoodsDTO goodsDTO) {
this.goodsName = goodsDTO.getGoodsName();
this.categoryPath = goodsDTO.getCategoryPath();
this.storeCategoryPath = goodsDTO.getStoreCategoryPath();
this.brandId = goodsDTO.getBrandId();
this.templateId = goodsDTO.getTemplateId();
this.recommend = goodsDTO.getRecommend();
this.sellingPoint = goodsDTO.getSellingPoint();
this.salesModel = goodsDTO.getSalesModel();
this.goodsUnit = goodsDTO.getGoodsUnit();
this.intro = goodsDTO.getIntro();
this.mobileIntro = goodsDTO.getMobileIntro();
this.goodsVideo = goodsDTO.getGoodsVideo();
this.price = goodsDTO.getPrice();
if (goodsDTO.getGoodsParamsDTOList() != null && goodsDTO.getGoodsParamsDTOList().isEmpty()) {
this.params = JSONUtil.toJsonStr(goodsDTO.getGoodsParamsDTOList());
}
//如果立即上架则
this.marketEnable = GoodsStatusEnum.DOWN.name();
this.goodsType = goodsDTO.getGoodsType();
this.grade = 100D;
}
public String getIntro() {
if (CharSequenceUtil.isNotEmpty(intro)) {
return HtmlUtil.unescape(intro);

View File

@ -23,6 +23,8 @@ public class Wholesale extends BaseIdEntity {
private String goodsId;
@ApiModelProperty(value = "SkuID")
private String skuId;
@ApiModelProperty(value = "模版id")
private String templateId;
@ApiModelProperty(value = "数量")
private Integer num;
@ApiModelProperty(value = "金额")

View File

@ -30,4 +30,10 @@ public class DraftGoodsDTO extends DraftGoods {
@Valid
private List<Map<String, Object>> skuList;
/**
* 批发商品规则
*/
@ApiModelProperty(value = "批发商品规则")
private List<WholesaleDTO> wholesaleList;
}

View File

@ -1,6 +1,6 @@
package cn.lili.modules.goods.entity.dto;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.modules.goods.entity.enums.DraftGoodsSaveType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
@ -26,7 +26,7 @@ public class DraftGoodsSearchParams extends GoodsSearchParams {
@Override
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = super.queryWrapper();
if (StrUtil.isNotEmpty(saveType)) {
if (CharSequenceUtil.isNotEmpty(saveType)) {
queryWrapper.eq("save_type", saveType);
}
return queryWrapper;

View File

@ -2,8 +2,7 @@ package cn.lili.modules.goods.entity.dto;
import cn.lili.common.validation.EnumValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import lombok.*;
import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
@ -20,6 +19,9 @@ import java.util.Map;
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class GoodsOperationDTO implements Serializable {
private static final long serialVersionUID = -509667581371776913L;
@ -116,6 +118,8 @@ public class GoodsOperationDTO implements Serializable {
@Valid
private List<Map<String, Object>> skuList;
@ApiModelProperty(value = "是否为商品模版")
private Boolean goodsTemplateFlag = false;
/**
* 批发商品规则
*/

View File

@ -6,8 +6,7 @@ import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.*;
import java.util.Arrays;
@ -19,6 +18,9 @@ import java.util.Arrays;
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GoodsSearchParams extends PageVO {
private static final long serialVersionUID = 2544015852728566887L;

View File

@ -3,6 +3,8 @@ package cn.lili.modules.goods.entity.dto;
import cn.lili.modules.goods.entity.dos.Wholesale;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
/**
* @author paulG
@ -10,7 +12,12 @@ import lombok.EqualsAndHashCode;
**/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class WholesaleDTO extends Wholesale {
private static final long serialVersionUID = 853297561151783335L;
public WholesaleDTO(Wholesale wholesale) {
BeanUtils.copyProperties(wholesale, this);
}
}

View File

@ -1,6 +1,7 @@
package cn.lili.modules.goods.entity.vos;
import cn.lili.modules.goods.entity.dos.DraftGoods;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -29,4 +30,10 @@ public class DraftGoodsVO extends DraftGoods {
@ApiModelProperty(value = "sku列表")
private List<GoodsSkuVO> skuList;
/**
* 批发商品规则
*/
@ApiModelProperty(value = "批发商品规则")
private List<Wholesale> wholesaleList;
}

View File

@ -241,4 +241,12 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @return sku总数
*/
Long countSkuNum(String storeId);
/**
* 批量渲染商品sku
*
* @param goodsSkuList SKU基础数据列表
* @param goodsOperationDTO 商品操作信息
*/
void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO);
}

View File

@ -14,8 +14,13 @@ public interface WholesaleService extends IService<Wholesale> {
List<Wholesale> findByGoodsId(String goodsId);
List<Wholesale> findByTemplateId(String templateId);
Boolean removeByGoodsId(String goodsId);
Boolean removeByTemplateId(String templateId);
/**
* 匹配批发规则
*

View File

@ -1,29 +1,27 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.DraftGoods;
import cn.lili.modules.goods.entity.dos.GoodsGallery;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.*;
import cn.lili.modules.goods.entity.dto.DraftGoodsDTO;
import cn.lili.modules.goods.entity.dto.DraftGoodsSearchParams;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.vos.DraftGoodsVO;
import cn.lili.modules.goods.mapper.DraftGoodsMapper;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.DraftGoodsService;
import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.*;
import cn.lili.modules.goods.sku.GoodsSkuBuilder;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 草稿商品业务层实现
@ -49,6 +47,9 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
@Autowired
private GoodsSkuService goodsSkuService;
@Autowired
private WholesaleService wholesaleService;
@Override
public boolean addGoodsDraft(DraftGoodsDTO draftGoods) {
draftGoods.setGoodsGalleryListJson(JSONUtil.toJsonStr(draftGoods.getGoodsGalleryList()));
@ -75,7 +76,10 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
draftGoods.setThumbnail(goodsGallery.getThumbnail());
}
draftGoods.setGoodsGalleryListJson(JSONUtil.toJsonStr(draftGoods.getGoodsGalleryList()));
draftGoods.setSkuListJson(JSONUtil.toJsonStr(this.getGoodsSkuList(draftGoods.getSkuList())));
// 检查是否需要生成索引
List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(new Goods(draftGoods), draftGoods.getSkuList());
goodsSkuService.renderGoodsSkuList(goodsSkus, GoodsOperationDTO.builder().goodsTemplateFlag(true).wholesaleList(draftGoods.getWholesaleList()).salesModel(draftGoods.getSalesModel()).build());
draftGoods.setSkuListJson(JSONUtil.toJsonStr(goodsSkus));
draftGoods.setGoodsParamsListJson(JSONUtil.toJsonStr(draftGoods.getGoodsParamsDTOList()));
this.saveOrUpdate(draftGoods);
}
@ -83,6 +87,7 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
@Override
public void deleteGoodsDraft(String id) {
this.removeById(id);
this.wholesaleService.removeByTemplateId(id);
}
@Override
@ -104,6 +109,10 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
JSONArray jsonArray = JSONUtil.parseArray(draftGoods.getSkuListJson());
List<GoodsSku> list = JSONUtil.toList(jsonArray, GoodsSku.class);
draftGoodsVO.setSkuList(goodsSkuService.getGoodsSkuVOList(list));
List<Wholesale> wholesaleList = wholesaleService.findByTemplateId(draftGoods.getId());
if (CollUtil.isNotEmpty(wholesaleList)) {
draftGoodsVO.setWholesaleList(wholesaleList);
}
return draftGoodsVO;
}
@ -112,48 +121,4 @@ public class DraftGoodsServiceImpl extends ServiceImpl<DraftGoodsMapper, DraftGo
return this.page(PageUtil.initPage(searchParams), searchParams.queryWrapper());
}
/**
* 获取sku集合
*
* @param skuList sku列表
* @return sku集合
*/
private List<GoodsSku> getGoodsSkuList(List<Map<String, Object>> skuList) {
List<GoodsSku> skus = new ArrayList<>();
for (Map<String, Object> skuVO : skuList) {
GoodsSku add = this.add(skuVO);
skus.add(add);
}
return skus;
}
private GoodsSku add(Map<String, Object> map) {
Map<String, Object> specMap = new LinkedHashMap<>();
GoodsSku sku = new GoodsSku();
for (Map.Entry<String, Object> m : map.entrySet()) {
switch (m.getKey()) {
case "sn":
sku.setSn(m.getValue() != null ? m.getValue().toString() : "");
break;
case "cost":
sku.setCost(Convert.toDouble(m.getValue()));
break;
case "price":
sku.setPrice(Convert.toDouble(m.getValue()));
break;
case "quantity":
sku.setQuantity(Convert.toInt(m.getValue()));
break;
case "weight":
sku.setWeight(Convert.toDouble(m.getValue()));
break;
default:
specMap.put(m.getKey(), m.getValue());
break;
}
}
sku.setSpecs(JSONUtil.toJsonStr(specMap));
return sku;
}
}

View File

@ -132,7 +132,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU);
}
// 检查是否需要生成索引
List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO.getSkuList());
renderGoodsSkuList(goodsSkus, goodsOperationDTO);
if (!goodsSkus.isEmpty()) {
@ -151,7 +151,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
List<GoodsSku> skuList;
//删除旧的sku信息
if (Boolean.TRUE.equals(goodsOperationDTO.getRegeneratorSkuFlag())) {
skuList = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
skuList = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO.getSkuList());
renderGoodsSkuList(skuList, goodsOperationDTO);
List<GoodsSkuVO> goodsListByGoodsId = getGoodsListByGoodsId(goods.getId());
List<String> oldSkuIds = new ArrayList<>();
@ -170,7 +170,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
} else {
skuList = new ArrayList<>();
for (Map<String, Object> map : goodsOperationDTO.getSkuList()) {
GoodsSku sku = GoodsSkuBuilder.build(goods, map, goodsOperationDTO);
GoodsSku sku = GoodsSkuBuilder.build(goods, map);
renderGoodsSku(sku, goodsOperationDTO);
skuList.add(sku);
//如果商品状态值不对则es索引移除
@ -639,7 +639,8 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
* @param goodsSkuList sku集合
* @param goodsOperationDTO 商品操作DTO
*/
void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO) {
@Override
public void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO) {
// 商品销售模式渲染器
salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderBatch(goodsSkuList, goodsOperationDTO));
for (GoodsSku goodsSku : goodsSkuList) {

View File

@ -36,6 +36,23 @@ public class WholesaleServiceImpl extends ServiceImpl<WholesaleMapper, Wholesale
return this.list(queryWrapper).stream().sorted(Comparator.comparing(Wholesale::getNum)).collect(Collectors.toList());
}
@Override
@Cacheable(key = "#templateId+'_template'")
public List<Wholesale> findByTemplateId(String templateId) {
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Wholesale::getTemplateId, templateId);
return this.list(queryWrapper).stream().sorted(Comparator.comparing(Wholesale::getNum)).collect(Collectors.toList());
}
@Override
@CacheEvict(key = "#templateId+'_template'")
public Boolean removeByTemplateId(String templateId) {
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Wholesale::getTemplateId, templateId);
cache.remove("{wholesale}_" + templateId + "_template");
return this.remove(queryWrapper);
}
@Override
@CacheEvict(key = "#goodsId")
public Boolean removeByGoodsId(String goodsId) {

View File

@ -6,7 +6,6 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import org.springframework.stereotype.Component;
import java.util.*;
@ -25,48 +24,42 @@ public class GoodsSkuBuilder {
/**
* 构建商品sku
*
* @param goods 商品
* @param skuInfo sku信息列表
* @param goodsOperationDTO 商品操作信息如需处理额外信息传递不需可传空
* @param goods 商品
* @param skuInfo sku信息列表
* @return 商品sku
*/
public static GoodsSku build(Goods goods, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
public static GoodsSku build(Goods goods, Map<String, Object> skuInfo) {
GoodsSku goodsSku = new GoodsSku(goods);
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
builderSingle(goodsSku, skuInfo);
return goodsSku;
}
/**
* 批量构建商品sku
*
* @param goods 商品
* @param goodsOperationDTO 商品操作信息
* @param goods 商品
* @return 商品sku
*/
public static List<GoodsSku> buildBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) {
return builderBatch(goods, goodsOperationDTO);
public static List<GoodsSku> buildBatch(Goods goods, List<Map<String, Object>> skuList) {
Assert.notEmpty(skuList, "skuList不能为空");
Assert.notNull(goods, "goods不能为空");
List<GoodsSku> goodsSkus = new ArrayList<>();
for (Map<String, Object> skuInfo : skuList) {
GoodsSku goodsSku = new GoodsSku(goods);
builderSingle(goodsSku, skuInfo);
goodsSkus.add(goodsSku);
}
return goodsSkus;
}
/**
* 从已有的商品sku中构建商品sku
*
* @param goodsSku 原商品sku
* @param skuInfo sku信息列表
* @param goodsOperationDTO 商品操作信息如需处理额外信息传递不需可传空
* @return 商品sku
*/
public static GoodsSku build(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
return goodsSku;
}
private static void builderSingle(GoodsSku goodsSku, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
private static void builderSingle(GoodsSku goodsSku, Map<String, Object> skuInfo) {
Assert.notNull(goodsSku, "goodsSku不能为空");
Assert.notEmpty(skuInfo, "skuInfo不能为空");
//规格简短信息
StringBuilder simpleSpecs = new StringBuilder();
//商品名称
StringBuilder goodsName = new StringBuilder(goodsOperationDTO.getGoodsName());
StringBuilder goodsName = new StringBuilder(goodsSku.getGoodsName());
//规格值
Map<String, Object> specMap = new LinkedHashMap<>();
@ -100,17 +93,5 @@ public class GoodsSkuBuilder {
goodsSku.setSimpleSpecs(simpleSpecs.toString());
}
private static List<GoodsSku> builderBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) {
Assert.notEmpty(goodsOperationDTO.getSkuList(), "goodsOperationDTO.getSkuList()不能为空");
Assert.notNull(goods, "goods不能为空");
List<GoodsSku> goodsSkus = new ArrayList<>();
for (Map<String, Object> skuInfo : goodsOperationDTO.getSkuList()) {
GoodsSku goodsSku = new GoodsSku(goods);
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
goodsSkus.add(goodsSku);
}
return goodsSkus;
}
}

View File

@ -55,7 +55,9 @@ public class WholesaleSaleModelRenderImpl implements SalesModelRender {
skus.setPrice(collect.get(0).getPrice());
skus.setCost(collect.get(0).getPrice());
}
wholesaleService.removeByGoodsId(goodsSkus.get(0).getGoodsId());
if (Boolean.FALSE.equals(goodsOperationDTO.getGoodsTemplateFlag())) {
wholesaleService.removeByGoodsId(goodsSkus.get(0).getGoodsId());
}
wholesaleService.saveOrUpdateBatch(collect);
}