增加商品批发销售模式的处理。优化生成商品sku的结构。

This commit is contained in:
paulGao 2022-05-27 16:32:00 +08:00
parent e9fdec6bb0
commit acb9e78a36
24 changed files with 642 additions and 236 deletions

View File

@ -1,7 +1,10 @@
/** 增加签到日期 **/
ALTER TABLE li_member_sign ADD day int DEFAULT NULL COMMENT '签到日 ';
ALTER TABLE li_member_sign DROP INDEX uk_member_day;
ALTER TABLE li_member_sign add unique uk_member_day (member_id, day) COMMENT 'uk_member_day';
ALTER TABLE li_member_sign
ADD day int DEFAULT NULL COMMENT '签到日 ';
ALTER TABLE li_member_sign
DROP INDEX uk_member_day;
ALTER TABLE li_member_sign
add unique uk_member_day (member_id, day) COMMENT 'uk_member_day';
@ -9,10 +12,35 @@ ALTER TABLE li_member_sign add unique uk_member_day (member_id, day) COMMENT 'uk
-- Table structure for li_hot_words_history
-- ----------------------------
DROP TABLE IF EXISTS `li_hot_words_history`;
CREATE TABLE `li_hot_words_history` (
`id` bigint NOT NULL COMMENT 'ID',
`create_time` datetime(6) DEFAULT NULL COMMENT '创建时间',
`keywords` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '热词',
`score` int DEFAULT NULL COMMENT '热词分数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
CREATE TABLE `li_hot_words_history`
(
`id` bigint NOT NULL COMMENT 'ID',
`create_time` datetime(6) DEFAULT NULL COMMENT '创建时间',
`keywords` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '热词',
`score` int DEFAULT NULL COMMENT '热词分数',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3 COLLATE = utf8_bin COMMENT '热词历史表';
-- ----------------------------
-- Records of li_hot_words_history
-- ----------------------------
-- ----------------------------
-- Table structure for li_wholesale
-- ----------------------------
DROP TABLE IF EXISTS `li_wholesale`;
CREATE TABLE `li_wholesale`
(
`id` bigint NOT NULL,
`create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`create_time` datetime(6) DEFAULT NULL,
`delete_flag` bit(1) DEFAULT NULL,
`update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`update_time` datetime(6) DEFAULT NULL,
`price` decimal(10, 2) DEFAULT NULL COMMENT '价格',
`goods_id` bigint DEFAULT NULL COMMENT '商品id',
`sku_id` bigint DEFAULT NULL COMMENT '商品skuId',
`num` int DEFAULT NULL COMMENT '起购量',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin COMMENT '批发规则表';

View File

@ -76,6 +76,10 @@ public enum ResultCode {
GOODS_SKU_QUANTITY_ERROR(11011, "商品库存数量不能为负数"),
GOODS_SKU_QUANTITY_NOT_ENOUGH(11011, "商品库存不足"),
MUST_HAVE_GOODS_SKU(11012, "规格必须要有一个!"),
MUST_HAVE_SALES_MODEL(11022, "销售模式为批发时必须要有批发规则!"),
HAVE_INVALID_SALES_MODEL(11023, "批发规则存在小于等于0的无效数据"),
GOODS_PARAMS_ERROR(11013, "商品参数错误,刷新后重试"),
PHYSICAL_GOODS_NEED_TEMP(11014, "实物商品需选择配送模板"),
VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "虚拟商品无需选择配送模板"),

View File

@ -12,7 +12,6 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Max;
@ -114,6 +113,9 @@ public class DraftGoods extends BaseEntity {
@ApiModelProperty(value = "是否为推荐商品")
private boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@ApiModelProperty(value = "销售模式")
private String salesModel;

View File

@ -8,6 +8,7 @@ import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import cn.lili.mybatis.BaseEntity;
@ -133,6 +134,9 @@ public class Goods extends BaseEntity {
@ApiModelProperty(value = "是否为推荐商品", required = true)
private Boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
@ -179,10 +183,10 @@ public class Goods extends BaseEntity {
if (!sku.containsKey("sn") || sku.get("sn") == null) {
throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR);
}
if (!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) {
if ((!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString()) || Convert.toDouble(sku.get("price")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR);
}
if (!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) {
if ((!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString()) || Convert.toDouble(sku.get("cost")) <= 0) && !goodsOperationDTO.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR);
}
//虚拟商品没有重量字段

View File

@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Max;
@ -24,6 +25,7 @@ import java.util.Date;
@Data
@TableName("li_goods_sku")
@ApiModel(value = "商品sku对象")
@NoArgsConstructor
public class GoodsSku extends BaseEntity {
private static final long serialVersionUID = 4865908658161118934L;
@ -150,6 +152,9 @@ public class GoodsSku extends BaseEntity {
@ApiModelProperty(value = "是否为推荐商品", required = true)
private Boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
/**
@ -173,4 +178,36 @@ public class GoodsSku extends BaseEntity {
return super.getUpdateTime();
}
}
/**
* 设置规格商品的基本商品信息
*
* @param goods 基本商品信息
*/
public GoodsSku(Goods goods) {
//商品基本信息
this.goodsId = goods.getId();
this.goodsName = goods.getGoodsName();
this.goodsType = goods.getGoodsType();
this.selfOperated = goods.getSelfOperated();
this.sellingPoint = goods.getSellingPoint();
this.categoryPath = goods.getCategoryPath();
this.brandId = goods.getBrandId();
this.marketEnable = goods.getMarketEnable();
this.intro = goods.getIntro();
this.mobileIntro = goods.getMobileIntro();
this.goodsUnit = goods.getGoodsUnit();
this.grade = 100D;
//商品状态
this.authFlag = goods.getAuthFlag();
this.salesModel = goods.getSalesModel();
//卖家信息
this.storeId = goods.getStoreId();
this.storeName = goods.getStoreName();
this.storeCategoryPath = goods.getStoreCategoryPath();
this.freightTemplateId = goods.getTemplateId();
this.recommend = goods.getRecommend();
}
}

View File

@ -0,0 +1,30 @@
package cn.lili.modules.goods.entity.dos;
import cn.lili.mybatis.BaseIdEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author paulG
* @since 2022/5/20
**/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("li_wholesale")
@ApiModel(value = "批发商品")
public class Wholesale extends BaseIdEntity {
private static final long serialVersionUID = -6389806138583086068L;
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "SkuID")
private String skuId;
@ApiModelProperty(value = "数量")
private Integer num;
@ApiModelProperty(value = "金额")
private Double price;
}

View File

@ -13,7 +13,7 @@ import java.util.List;
import java.util.Map;
/**
* 商品编辑DTO
* 商品操作DTO
*
* @author pikachu
* @since 2020-02-24 19:27:20
@ -77,13 +77,12 @@ public class GoodsOperationDTO implements Serializable {
@Min(value = 0, message = "运费模板值不正确")
private String templateId;
@ApiModelProperty(value = "sku列表")
@Valid
private List<Map<String, Object>> skuList;
@ApiModelProperty(value = "卖点")
private String sellingPoint;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
@ -112,6 +111,17 @@ public class GoodsOperationDTO implements Serializable {
@ApiModelProperty(value = "商品视频")
private String goodsVideo;
@ApiModelProperty(value = "sku列表")
@Valid
private List<Map<String, Object>> skuList;
/**
* 批发商品规则
*/
@ApiModelProperty(value = "批发商品规则")
private List<WholesaleDTO> wholesaleList;
public String getGoodsName() {
//对商品对名称做一个极限处理这里没有用xss过滤是因为xss过滤为全局过滤影响很大
// 业务中全局代码中只有商品名称不能拥有英文逗号是由于商品名称存在一个数据库联合查询结果要根据逗号分组

View File

@ -77,6 +77,12 @@ public class GoodsSearchParams extends PageVO {
@ApiModelProperty(value = "商品类型")
private String goodsType;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (CharSequenceUtil.isNotEmpty(goodsId)) {
@ -121,6 +127,9 @@ public class GoodsSearchParams extends PageVO {
if (CharSequenceUtil.isNotEmpty(goodsType)) {
queryWrapper.eq("goods_type", goodsType);
}
if (CharSequenceUtil.isNotEmpty(salesModel)) {
queryWrapper.eq("sales_model", salesModel);
}
queryWrapper.eq("delete_flag", false);
this.betweenWrapper(queryWrapper);

View File

@ -0,0 +1,16 @@
package cn.lili.modules.goods.entity.dto;
import cn.lili.modules.goods.entity.dos.Wholesale;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author paulG
* @since 2022/5/25
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class WholesaleDTO extends Wholesale {
private static final long serialVersionUID = 853297561151783335L;
}

View File

@ -1,19 +1,14 @@
package cn.lili.modules.goods.entity.enums;
/**
* 商品审核
* 销售模式
*
* @author pikachu
* @since 2020-02-26 23:24:13
*/
public enum GoodsSalesModeEnum {
/**
* 需要审核 并且待审核
*/
RETAIL("零售"),
/**
* 审核通过
*/
WHOLESALE("批发");
private final String description;

View File

@ -1,9 +1,11 @@
package cn.lili.modules.goods.entity.vos;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@ -14,6 +16,7 @@ import java.util.List;
* @since 2020-02-26 23:24:13
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class GoodsVO extends Goods {
private static final long serialVersionUID = 6377623919990713567L;
@ -29,4 +32,7 @@ public class GoodsVO extends Goods {
@ApiModelProperty(value = "sku列表")
private List<GoodsSkuVO> skuList;
@ApiModelProperty(value = "批发商品消费规则列表")
private List<Wholesale> wholesaleList;
}

View File

@ -0,0 +1,11 @@
package cn.lili.modules.goods.mapper;
import cn.lili.modules.goods.entity.dos.Wholesale;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author paulG
* @since 2022/5/24
**/
public interface WholesaleMapper extends BaseMapper<Wholesale> {
}

View File

@ -0,0 +1,19 @@
package cn.lili.modules.goods.render;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import java.util.List;
import java.util.Map;
/**
* 商品sku渲染器
*
* @author paulG
* @since 2022/5/20
**/
public interface GoodsSkuRender {
GoodsSku render(List<Map<String, Object>> skuList);
}

View File

@ -3,6 +3,7 @@ package cn.lili.modules.goods.service;
import cn.lili.cache.CachePrefix;
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 cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
@ -43,19 +44,18 @@ public interface GoodsSkuService extends IService<GoodsSku> {
/**
* 添加商品sku
*
* @param skuList sku列表
* @param goods 商品信息
* @param goods 商品信息
* @param goodsOperationDTO 商品操作信息
*/
void add(List<Map<String, Object>> skuList, Goods goods);
void add(Goods goods, GoodsOperationDTO goodsOperationDTO);
/**
* 更新商品sku
*
* @param skuList sku列表
* @param goods 商品信息
* @param regeneratorSkuFlag 是否是否重新生成sku
* @param goods 商品信息
* @param goodsOperationDTO 商品操作信息
*/
void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag);
void update(Goods goods, GoodsOperationDTO goodsOperationDTO);
/**
* 更新商品sku
@ -154,9 +154,9 @@ public interface GoodsSkuService extends IService<GoodsSku> {
/**
* 更新商品sku状态根据店铺id
*
* @param storeId 店铺id
* @param storeId 店铺id
* @param marketEnable 市场启用状态
* @param authFlag 审核状态
* @param authFlag 审核状态
*/
void updateGoodsSkuStatusByStoreId(String storeId, String marketEnable, String authFlag);

View File

@ -0,0 +1,28 @@
package cn.lili.modules.goods.service;
import cn.lili.modules.goods.entity.dos.Wholesale;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author paulG
* @since 2022/5/24
**/
public interface WholesaleService extends IService<Wholesale> {
List<Wholesale> findByGoodsId(String goodsId);
Boolean removeByGoodsId(String goodsId);
/**
* 匹配批发规则
*
* @param goodsId 商品规则
* @param num 数量
* @return 批发规则
*/
Wholesale match(String goodsId, Integer num);
}

View File

@ -1,5 +1,6 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
@ -14,6 +15,7 @@ import cn.lili.common.security.enums.UserEnums;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsGallery;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
@ -22,10 +24,7 @@ import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.vos.GoodsSkuVO;
import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.mapper.GoodsMapper;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.*;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
import cn.lili.modules.member.service.MemberEvaluationService;
@ -110,6 +109,9 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Autowired
private FreightTemplateService freightTemplateService;
@Autowired
private WholesaleService wholesaleService;
@Autowired
private Cache<GoodsVO> cache;
@ -168,7 +170,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
//添加商品
this.save(goods);
//添加商品sku信息
this.goodsSkuService.add(goodsOperationDTO.getSkuList(), goods);
this.goodsSkuService.add(goods, goodsOperationDTO);
//添加相册
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
@ -192,7 +194,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
//修改商品
this.updateById(goods);
//修改商品sku信息
this.goodsSkuService.update(goodsOperationDTO.getSkuList(), goods, goodsOperationDTO.getRegeneratorSkuFlag());
this.goodsSkuService.update(goods, goodsOperationDTO);
//添加相册
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
@ -247,6 +249,12 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
if (CharSequenceUtil.isNotEmpty(goods.getParams())) {
goodsVO.setGoodsParamsDTOList(JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class));
}
List<Wholesale> wholesaleList = wholesaleService.findByGoodsId(goodsId);
if (CollUtil.isNotEmpty(wholesaleList)) {
goodsVO.setWholesaleList(wholesaleList);
}
cache.put(CachePrefix.GOODS.getPrefix() + goodsId, goodsVO);
return goodsVO;
}

View File

@ -1,6 +1,5 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
@ -16,6 +15,7 @@ import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.SnowFlake;
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 cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.dto.GoodsSkuStockDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
@ -26,10 +26,9 @@ import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.entity.vos.SpecValueVO;
import cn.lili.modules.goods.event.GeneratorEsGoodsIndexEvent;
import cn.lili.modules.goods.mapper.GoodsSkuMapper;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.*;
import cn.lili.modules.goods.sku.GoodsSkuBuilder;
import cn.lili.modules.goods.sku.render.SalesModelRender;
import cn.lili.modules.member.entity.dos.FootPrint;
import cn.lili.modules.member.entity.dto.EvaluationQueryParams;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
@ -38,7 +37,6 @@ import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.enums.CouponGetEnum;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.search.entity.dos.EsGoodsAttribute;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.search.utils.EsIndexUtil;
@ -114,35 +112,42 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Autowired
private WholesaleService wholesaleService;
@Autowired
private List<SalesModelRender> salesModelRenders;
@Override
@Transactional(rollbackFor = Exception.class)
public void add(List<Map<String, Object>> skuList, Goods goods) {
// 检查是否需要生成索引
List<GoodsSku> newSkuList;
//如果有规格
if (skuList != null && !skuList.isEmpty()) {
// 添加商品sku
newSkuList = this.addGoodsSku(skuList, goods);
} else {
public void add(Goods goods, GoodsOperationDTO goodsOperationDTO) {
// 是否存在规格
if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) {
throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU);
}
// 检查是否需要生成索引
List<GoodsSku> goodsSkus = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
renderGoodsSkuList(goodsSkus, goodsOperationDTO);
this.updateStock(newSkuList);
if (!newSkuList.isEmpty()) {
generateEs(goods);
if (!goodsSkus.isEmpty()) {
this.saveOrUpdateBatch(goodsSkus);
this.updateStock(goodsSkus);
this.generateEs(goods);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(List<Map<String, Object>> skuList, Goods goods, Boolean regeneratorSkuFlag) {
public void update(Goods goods, GoodsOperationDTO goodsOperationDTO) {
// 是否存在规格
if (skuList == null || skuList.isEmpty()) {
if (goodsOperationDTO.getSkuList() == null || goodsOperationDTO.getSkuList().isEmpty()) {
throw new ServiceException(ResultCode.MUST_HAVE_GOODS_SKU);
}
List<GoodsSku> newSkuList;
List<GoodsSku> skuList;
//删除旧的sku信息
if (Boolean.TRUE.equals(regeneratorSkuFlag)) {
if (Boolean.TRUE.equals(goodsOperationDTO.getRegeneratorSkuFlag())) {
skuList = GoodsSkuBuilder.buildBatch(goods, goodsOperationDTO);
renderGoodsSkuList(skuList, goodsOperationDTO);
List<GoodsSkuVO> goodsListByGoodsId = getGoodsListByGoodsId(goods.getId());
List<String> oldSkuIds = new ArrayList<>();
//删除旧索引
@ -154,40 +159,34 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
//删除sku相册
goodsGalleryService.removeByGoodsId(goods.getId());
getGoodsListByGoodsId(goods.getId());
// 添加商品sku
newSkuList = this.addGoodsSku(skuList, goods);
//发送mq消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.SKU_DELETE.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(oldSkuIds), RocketmqSendCallbackBuilder.commonCallback());
} else {
newSkuList = new ArrayList<>();
for (Map<String, Object> map : skuList) {
skuList = new ArrayList<>();
for (Map<String, Object> map : goodsOperationDTO.getSkuList()) {
GoodsSku sku = null;
if (map.get("id") != null) {
sku = this.getGoodsSkuByIdFromCache(map.get("id").toString());
sku = GoodsSkuBuilder.build(this.getGoodsSkuByIdFromCache(map.get("id").toString()), map, goodsOperationDTO);
}
if (sku == null || map.get("id") == null) {
sku = new GoodsSku();
sku = GoodsSkuBuilder.build(goods, map, goodsOperationDTO);
}
//设置商品信息
goodsInfo(sku, goods);
//设置商品规格信息
skuInfo(sku, goods, map, null);
newSkuList.add(sku);
renderGoodsSku(sku, goodsOperationDTO);
skuList.add(sku);
//如果商品状态值不对则es索引移除
if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name()) && goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())) {
goodsIndexService.deleteIndexById(sku.getId());
this.clearCache(sku.getId());
}
}
this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
this.saveOrUpdateBatch(newSkuList);
}
this.updateStock(newSkuList);
if (GoodsAuthEnum.PASS.name().equals(goods.getAuthFlag()) && !newSkuList.isEmpty()) {
generateEs(goods);
if (!skuList.isEmpty()) {
this.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
this.saveOrUpdateBatch(skuList);
this.updateStock(skuList);
this.generateEs(goods);
}
}
@ -257,9 +256,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
//商品下架||商品未审核通过||商品删除则提示商品已下架
if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable())
|| !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag())
|| Boolean.TRUE.equals(goodsVO.getDeleteFlag())) {
if (GoodsStatusEnum.DOWN.name().equals(goodsVO.getMarketEnable()) || !GoodsAuthEnum.PASS.name().equals(goodsVO.getAuthFlag()) || Boolean.TRUE.equals(goodsVO.getDeleteFlag())) {
throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
}
@ -278,13 +275,10 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
promotionMap = promotionMap.entrySet().stream().parallel().filter(i -> {
JSONObject jsonObject = JSONUtil.parseObj(i.getValue());
// 过滤活动赠送优惠券和无效时间的活动
return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) &&
(jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) &&
(jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis());
return (jsonObject.get("getType") == null || jsonObject.get("getType", String.class).equals(CouponGetEnum.FREE.name())) && (jsonObject.get("startTime") != null && jsonObject.get("startTime", Date.class).getTime() <= System.currentTimeMillis()) && (jsonObject.get("endTime") == null || jsonObject.get("endTime", Date.class).getTime() >= System.currentTimeMillis());
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i ->
i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
Optional<Map.Entry<String, Object>> containsPromotion = promotionMap.entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (containsPromotion.isPresent()) {
JSONObject jsonObject = JSONUtil.parseObj(containsPromotion.get().getValue());
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
@ -305,6 +299,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//获取分类
String[] split = goodsSkuDetail.getCategoryPath().split(",");
map.put("wholesaleList", wholesaleService.findByGoodsId(goodsSkuDetail.getGoodsId()));
map.put("categoryName", categoryService.getCategoryNameByIds(Arrays.asList(split)));
//获取规格信息
@ -347,7 +342,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
cache.put(GoodsSkuService.getCacheKeys(sku.getId()), sku);
}
if (!goodsSkus.isEmpty()) {
generateEs(goods);
this.generateEs(goods);
}
}
}
@ -565,10 +560,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//修改规格索引,发送mq消息
Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(
MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(),
MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum)
.put("grade", grade).build());
Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(MapUtil.builder(new HashMap<String, Object>()).put("id", goodsSku.getId()).build(), MapUtil.builder(new HashMap<String, Object>()).put("commentNum", goodsSku.getCommentNum()).put("highPraiseNum", highPraiseNum).put("grade", grade).build());
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.UPDATE_GOODS_INDEX_FIELD.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(updateIndexFieldsMap), RocketmqSendCallbackBuilder.commonCallback());
@ -632,153 +624,25 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
/**
* 增加sku集合
* 批量渲染商品sku
*
* @param skuList sku列表
* @param goods 商品信息
* @param goodsSkuList sku集合
* @param goodsOperationDTO 商品操作DTO
*/
List<GoodsSku> addGoodsSku(List<Map<String, Object>> skuList, Goods goods) {
List<GoodsSku> skus = new ArrayList<>();
for (Map<String, Object> skuVO : skuList) {
Map<String, Object> resultMap = this.add(skuVO, goods);
GoodsSku goodsSku = (GoodsSku) resultMap.get("goodsSku");
if (goods.getSelfOperated() != null) {
goodsSku.setSelfOperated(goods.getSelfOperated());
}
goodsSku.setGoodsType(goods.getGoodsType());
skus.add(goodsSku);
cache.put(GoodsSkuService.getStockCacheKey(goodsSku.getId()), goodsSku.getQuantity());
}
this.saveOrUpdateBatch(skus);
return skus;
void renderGoodsSkuList(List<GoodsSku> goodsSkuList, GoodsOperationDTO goodsOperationDTO) {
// 商品销售模式渲染器
salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderBatch(goodsSkuList, goodsOperationDTO));
}
/**
* 添加商品规格
* 渲染商品sku
*
* @param map 规格属性
* @param goods 商品
* @return 规格商品
* @param goodsSku sku
* @param goodsOperationDTO 商品操作DTO
*/
private Map<String, Object> add(Map<String, Object> map, Goods goods) {
Map<String, Object> resultMap = new HashMap<>(2);
GoodsSku sku = new GoodsSku();
//商品索引
EsGoodsIndex esGoodsIndex = new EsGoodsIndex();
//设置商品信息
goodsInfo(sku, goods);
//设置商品规格信息
skuInfo(sku, goods, map, esGoodsIndex);
esGoodsIndex.setGoodsSku(sku);
resultMap.put("goodsSku", sku);
resultMap.put("goodsIndex", esGoodsIndex);
return resultMap;
}
/**
* 设置规格商品的商品信息
*
* @param sku 规格
* @param goods 商品
*/
private void goodsInfo(GoodsSku sku, Goods goods) {
//商品基本信息
sku.setGoodsId(goods.getId());
sku.setSellingPoint(goods.getSellingPoint());
sku.setCategoryPath(goods.getCategoryPath());
sku.setBrandId(goods.getBrandId());
sku.setMarketEnable(goods.getMarketEnable());
sku.setIntro(goods.getIntro());
sku.setMobileIntro(goods.getMobileIntro());
sku.setGoodsUnit(goods.getGoodsUnit());
sku.setGrade(100D);
//商品状态
sku.setAuthFlag(goods.getAuthFlag());
sku.setSalesModel(goods.getSalesModel());
//卖家信息
sku.setStoreId(goods.getStoreId());
sku.setStoreName(goods.getStoreName());
sku.setStoreCategoryPath(goods.getStoreCategoryPath());
sku.setFreightTemplateId(goods.getTemplateId());
sku.setRecommend(goods.getRecommend());
}
/**
* 设置商品规格信息
*
* @param sku 规格商品
* @param goods 商品
* @param map 规格信息
* @param esGoodsIndex 商品索引
*/
private void skuInfo(GoodsSku sku, Goods goods, Map<String, Object> map, EsGoodsIndex esGoodsIndex) {
//规格简短信息
StringBuilder simpleSpecs = new StringBuilder();
//商品名称
StringBuilder goodsName = new StringBuilder(goods.getGoodsName());
//规格商品缩略图
String thumbnail = "";
String small = "";
//规格值
Map<String, Object> specMap = new HashMap<>(16);
//商品属性
List<EsGoodsAttribute> attributes = new ArrayList<>();
//获取规格信息
for (Map.Entry<String, Object> spec : map.entrySet()) {
//保存规格信息
if (("id").equals(spec.getKey()) || ("sn").equals(spec.getKey()) || ("cost").equals(spec.getKey())
|| ("price").equals(spec.getKey()) || ("quantity").equals(spec.getKey())
|| ("weight").equals(spec.getKey())) {
continue;
} else {
specMap.put(spec.getKey(), spec.getValue());
if (("images").equals(spec.getKey())) {
//设置规格商品缩略图
List<Map<String, String>> images = (List<Map<String, String>>) spec.getValue();
if (images == null || images.isEmpty()) {
continue;
}
//设置规格商品缩略图
//如果规格没有图片则用商品图片复盖有则增加规格图片放在商品图片集合之前
if (CharSequenceUtil.isNotEmpty(spec.getValue().toString())) {
thumbnail = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getThumbnail();
small = goodsGalleryService.getGoodsGallery(images.get(0).get("url")).getSmall();
}
} else {
if (spec.getValue() != null) {
//设置商品名称
goodsName.append(" ").append(spec.getValue());
//规格简短信息
simpleSpecs.append(" ").append(spec.getValue());
}
}
}
}
//设置规格信息
sku.setGoodsName(goodsName.toString());
sku.setThumbnail(thumbnail);
sku.setSmall(small);
//规格信息
sku.setId(Convert.toStr(map.get("id"), ""));
sku.setSn(Convert.toStr(map.get("sn")));
sku.setWeight(Convert.toDouble(map.get("weight"), 0D));
sku.setPrice(Convert.toDouble(map.get("price"), 0D));
sku.setCost(Convert.toDouble(map.get("cost"), 0D));
sku.setQuantity(Convert.toInt(map.get("quantity"), 0));
sku.setSpecs(JSONUtil.toJsonStr(specMap));
sku.setSimpleSpecs(simpleSpecs.toString());
if (esGoodsIndex != null) {
//商品索引
esGoodsIndex.setAttrList(attributes);
}
void renderGoodsSku(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) {
// 商品销售模式渲染器
salesModelRenders.stream().filter(i -> i.getSalesMode().equals(goodsOperationDTO.getSalesModel())).findFirst().ifPresent(i -> i.renderSingle(goodsSku, goodsOperationDTO));
}
/**

View File

@ -0,0 +1,64 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.collection.CollUtil;
import cn.lili.cache.Cache;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.mapper.WholesaleMapper;
import cn.lili.modules.goods.service.WholesaleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author paulG
* @since 2022/5/24
**/
@Service
@CacheConfig(cacheNames = "{wholesale}_")
public class WholesaleServiceImpl extends ServiceImpl<WholesaleMapper, Wholesale> implements WholesaleService {
@Autowired
private Cache<List<Wholesale>> cache;
@Override
@Cacheable(key = "#goodsId")
public List<Wholesale> findByGoodsId(String goodsId) {
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Wholesale::getGoodsId, goodsId);
return this.list(queryWrapper).stream().sorted(Comparator.comparing(Wholesale::getNum)).collect(Collectors.toList());
}
@Override
@CacheEvict(key = "#goodsId")
public Boolean removeByGoodsId(String goodsId) {
LambdaQueryWrapper<Wholesale> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Wholesale::getGoodsId, goodsId);
return this.remove(queryWrapper);
}
@Override
public Wholesale match(String goodsId, Integer num) {
List<Wholesale> wholesaleList = cache.get("{wholesale}_" + goodsId);
if (wholesaleList == null) {
wholesaleList = this.findByGoodsId(goodsId);
cache.put("{wholesale}_" + goodsId, wholesaleList);
}
List<Wholesale> matchList = wholesaleList.stream()
.filter(wholesale -> wholesale.getNum() <= num)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(matchList)) {
return matchList.get(matchList.size() - 1);
} else if (CollUtil.isNotEmpty(wholesaleList) && CollUtil.isEmpty(matchList)) {
return wholesaleList.get(0);
}
return null;
}
}

View File

@ -0,0 +1,114 @@
package cn.lili.modules.goods.sku;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
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.*;
/**
* @author paulG
* @since 2022/5/20
**/
@Component
public class GoodsSkuBuilder {
private static final String IMAGES_KEY = "images";
/**
* 构建商品sku
*
* @param goods 商品
* @param skuInfo sku信息列表
* @param goodsOperationDTO 商品操作信息如需处理额外信息传递不需可传空
* @return 商品sku
*/
public static GoodsSku build(Goods goods, Map<String, Object> skuInfo, GoodsOperationDTO goodsOperationDTO) {
GoodsSku goodsSku = new GoodsSku(goods);
builderSingle(goodsSku, skuInfo, goodsOperationDTO);
return goodsSku;
}
/**
* 批量构建商品sku
*
* @param goods 商品
* @param goodsOperationDTO 商品操作信息
* @return 商品sku
*/
public static List<GoodsSku> buildBatch(Goods goods, GoodsOperationDTO goodsOperationDTO) {
return builderBatch(goods, goodsOperationDTO);
}
/**
* 从已有的商品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) {
Assert.notNull(goodsSku, "goodsSku不能为空");
Assert.notEmpty(skuInfo, "skuInfo不能为空");
//规格简短信息
StringBuilder simpleSpecs = new StringBuilder();
//商品名称
StringBuilder goodsName = new StringBuilder(goodsOperationDTO.getGoodsName());
//规格值
Map<String, Object> specMap = new HashMap<>(16);
// 原始规格项
String[] ignoreOriginKeys = {"id", "sn", "cost", "price", "quantity", "weight", IMAGES_KEY};
//获取规格信息
for (Map.Entry<String, Object> spec : skuInfo.entrySet()) {
//保存新增规格信息
if (!CollUtil.contains(Arrays.asList(ignoreOriginKeys), spec.getKey()) && spec.getValue() != null) {
specMap.put(spec.getKey(), spec.getValue());
//设置商品名称
goodsName.append(" ").append(spec.getValue());
//规格简短信息
simpleSpecs.append(" ").append(spec.getValue());
}
}
//设置规格信息
goodsSku.setGoodsName(goodsName.toString());
//规格信息
goodsSku.setId(Convert.toStr(skuInfo.get("id"), ""));
goodsSku.setSn(Convert.toStr(skuInfo.get("sn")));
goodsSku.setWeight(Convert.toDouble(skuInfo.get("weight"), 0D));
goodsSku.setPrice(Convert.toDouble(skuInfo.get("price"), 0D));
goodsSku.setCost(Convert.toDouble(skuInfo.get("cost"), 0D));
goodsSku.setQuantity(Convert.toInt(skuInfo.get("quantity"), 0));
goodsSku.setSpecs(JSONUtil.toJsonStr(specMap));
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

@ -0,0 +1,23 @@
package cn.lili.modules.goods.sku.render;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import java.util.List;
/**
* 根据商品销售模型渲染商品sku
*
* @author paulG
* @since 2022/5/20
**/
public interface SalesModelRender {
String getSalesMode();
void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO);
void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO);
}

View File

@ -0,0 +1,76 @@
package cn.lili.modules.goods.sku.render.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.dto.WholesaleDTO;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.service.WholesaleService;
import cn.lili.modules.goods.sku.render.SalesModelRender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author paulG
* @since 2022/5/24
**/
@Component
public class WholesaleSaleModelRenderImpl implements SalesModelRender {
/**
* 批发商品
*/
@Autowired
private WholesaleService wholesaleService;
@Override
@Transactional(rollbackFor = Exception.class)
public void renderSingle(GoodsSku goodsSku, GoodsOperationDTO goodsOperationDTO) {
Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空");
this.checkWholesaleList(goodsOperationDTO.getWholesaleList());
List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList());
wholesaleService.removeByGoodsId(goodsOperationDTO.getGoodsId());
wholesaleService.saveOrUpdateBatch(collect);
goodsSku.setPrice(collect.get(0).getPrice());
goodsSku.setCost(collect.get(0).getPrice());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void renderBatch(List<GoodsSku> goodsSkus, GoodsOperationDTO goodsOperationDTO) {
Assert.notEmpty(goodsOperationDTO.getWholesaleList(), "批发规则不能为空");
this.checkWholesaleList(goodsOperationDTO.getWholesaleList());
List<Wholesale> collect = goodsOperationDTO.getWholesaleList().stream().sorted(Comparator.comparing(Wholesale::getPrice)).collect(Collectors.toList());
for (GoodsSku skus : goodsSkus) {
skus.setPrice(collect.get(0).getPrice());
skus.setCost(collect.get(0).getPrice());
}
wholesaleService.removeByGoodsId(goodsOperationDTO.getGoodsId());
wholesaleService.saveOrUpdateBatch(collect);
}
private void checkWholesaleList(List<WholesaleDTO> wholesaleList) {
if (CollUtil.isEmpty(wholesaleList)) {
throw new ServiceException(ResultCode.MUST_HAVE_SALES_MODEL);
}
for (WholesaleDTO wholesaleDTO : wholesaleList) {
if (wholesaleDTO.getPrice() == null || wholesaleDTO.getPrice() <= 0 || wholesaleDTO.getNum() == null || wholesaleDTO.getNum() <= 0) {
throw new ServiceException(ResultCode.HAVE_INVALID_SALES_MODEL);
}
}
}
@Override
public String getSalesMode() {
return GoodsSalesModeEnum.WHOLESALE.name();
}
}

View File

@ -1,5 +1,6 @@
package cn.lili.modules.order.cart.render.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -7,10 +8,14 @@ import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.WholesaleService;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@ -55,6 +60,9 @@ public class CheckDataRender implements CartRenderStep {
@Autowired
private MemberService memberService;
@Autowired
private WholesaleService wholesaleService;
@Override
public RenderStepEnums step() {
@ -69,6 +77,7 @@ public class CheckDataRender implements CartRenderStep {
//校验商品有效性
checkData(tradeDTO);
preSaleModel(tradeDTO);
//店铺分组数据初始化
groupStore(tradeDTO);
@ -212,4 +221,29 @@ public class CheckDataRender implements CartRenderStep {
}
/**
* 商品销售模式特殊处理
*
* @param tradeDTO 交易信息
*/
private void preSaleModel(TradeDTO tradeDTO) {
// 寻找同goods下销售模式为批发的商品
Map<String, List<CartSkuVO>> goodsGroup = tradeDTO.getSkuList().stream().filter(i -> i.getGoodsSku().getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())).collect(Collectors.groupingBy(i -> i.getGoodsSku().getGoodsId()));
if (CollUtil.isNotEmpty(goodsGroup)) {
goodsGroup.forEach((k, v) -> {
// 获取购买总数
int sum = v.stream().mapToInt(CartSkuVO::getNum).sum();
// 匹配符合的批发规则
Wholesale match = wholesaleService.match(k, sum);
if (match != null) {
v.forEach(i -> {
// 将符合规则的商品设置批发价格
i.setPurchasePrice(match.getPrice());
i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
});
}
});
}
}
}

View File

@ -1,5 +1,6 @@
package cn.lili.modules.order.cart.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -11,11 +12,14 @@ import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dos.Wholesale;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.WholesaleService;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberAddress;
import cn.lili.modules.member.service.MemberAddressService;
@ -124,6 +128,9 @@ public class CartServiceImpl implements CartService {
@Autowired
private PromotionGoodsService promotionGoodsService;
@Autowired
private WholesaleService wholesaleService;
@Override
public void add(String skuId, Integer num, String cartType, Boolean cover) {
AuthUser currentUser = Objects.requireNonNull(UserContext.getCurrentUser());
@ -193,6 +200,7 @@ public class CartServiceImpl implements CartService {
cartSkuVOS.add(cartSkuVO);
}
this.checkGoodsSaleModel(dataSku, tradeDTO.getSkuList());
tradeDTO.setCartTypeEnum(cartTypeEnum);
//如购物车发生更改则重置优惠券
tradeDTO.setStoreCoupons(null);
@ -554,12 +562,9 @@ public class CartServiceImpl implements CartService {
goodsIndex = goodsIndexService.getResetEsGoodsIndex(dataSku, goodsVO.getGoodsParamsDTOList());
}
if (goodsIndex.getPromotionMap() != null && !goodsIndex.getPromotionMap().isEmpty()) {
if (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name())) ||
(goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.PINTUAN.name()))
&& CartTypeEnum.PINTUAN.name().equals(cartType))) {
if (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.SECKILL.name())) || (goodsIndex.getPromotionMap().keySet().stream().anyMatch(i -> i.contains(PromotionTypeEnum.PINTUAN.name())) && CartTypeEnum.PINTUAN.name().equals(cartType))) {
Optional<Map.Entry<String, Object>> containsPromotion = goodsIndex.getPromotionMap().entrySet().stream().filter(i ->
i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
Optional<Map.Entry<String, Object>> containsPromotion = goodsIndex.getPromotionMap().entrySet().stream().filter(i -> i.getKey().contains(PromotionTypeEnum.SECKILL.name()) || i.getKey().contains(PromotionTypeEnum.PINTUAN.name())).findFirst();
if (containsPromotion.isPresent()) {
JSONObject promotionsObj = JSONUtil.parseObj(containsPromotion.get().getValue());
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
@ -709,6 +714,24 @@ public class CartServiceImpl implements CartService {
}
}
private void checkGoodsSaleModel(GoodsSku dataSku, List<CartSkuVO> cartSkuVOS) {
if (dataSku.getSalesModel().equals(GoodsSalesModeEnum.WHOLESALE.name())) {
int numSum = 0;
List<CartSkuVO> sameGoodsIdSkuList = cartSkuVOS.stream().filter(i -> i.getGoodsSku().getGoodsId().equals(dataSku.getGoodsId())).collect(Collectors.toList());
if (CollUtil.isNotEmpty(sameGoodsIdSkuList)) {
numSum += sameGoodsIdSkuList.stream().mapToInt(CartSkuVO::getNum).sum();
}
Wholesale match = wholesaleService.match(dataSku.getGoodsId(), numSum);
if (match != null) {
sameGoodsIdSkuList.forEach(i -> {
i.setPurchasePrice(match.getPrice());
i.setSubTotal(CurrencyUtil.mul(i.getPurchasePrice(), i.getNum()));
});
}
}
}
/**
* 校验拼团信息
*

View File

@ -215,6 +215,7 @@ public class EsGoodsIndex implements Serializable {
/**
* 销售模式
* @see cn.lili.modules.goods.entity.enums.GoodsSalesModeEnum
*/
@Field(type = FieldType.Text)
@ApiModelProperty("销售模式")