orderItems) {
+
+ //如果促销类型需要库存判定,则做对应处理
+ orderItems.forEach(orderItem -> {
+ if (orderItem.getPromotionType() != null) {
+ //如果此促销有库存概念,则计入
+ if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
+
+ PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
+
+ String cacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
+
+ switch (promotionTypeEnum) {
+ case KANJIA:
+ cache.put(cacheKey, kanjiaActivityGoodsService.getKanjiaGoodsBySkuId(orderItem.getSkuId()).getStock());
+ return;
+ case POINTS_GOODS:
+ cache.put(cacheKey, pointsGoodsService.getPointsGoodsDetailBySkuId(orderItem.getSkuId()).getActiveStock());
+ return;
+ case SECKILL:
+ case PINTUAN:
+ cache.put(cacheKey, promotionGoodsService.getPromotionGoodsStock(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId()));
+ return;
+ default:
+ break;
+ }
+ }
+ }
+ });
+ }
+
+
/**
* 订单出库失败
*
* @param orderSn 失败入库订单信息
*/
private void errorOrder(String orderSn) {
- orderService.systemCancel(orderSn, "库存不足,出库失败");
+ orderService.systemCancel(orderSn, outOfStockMessage);
}
@@ -128,8 +246,15 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
}
}
+
/**
- * 写入需要更改促销库存的商品
+ * 同步库存和促销库存
+ *
+ * 需修改:DB:商品库存、Sku商品库存、活动商品库存
+ * 1.获取需要修改的Sku列表、活动商品列表
+ * 2.写入sku商品库存,批量修改
+ * 3.写入促销商品的卖出数量、剩余数量,批量修改
+ * 4.调用方法修改商品库存
*
* @param order 订单
*/
@@ -144,32 +269,58 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
//促销库存key 集合
List promotionKey = new ArrayList<>();
- // 循环订单
+ //循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
+
GoodsSku goodsSku = new GoodsSku();
goodsSku.setId(orderItem.getSkuId());
+ goodsSku.setGoodsId(orderItem.getGoodsId());
//如果有促销信息
- if (null != orderItem.getPromotionType() && null != orderItem.getPromotionId()) {
+ if (null != orderItem.getPromotionType() && null != orderItem.getPromotionId() && PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
//如果促销有库存信息
- if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
- PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
- PromotionGoods pGoods = promotionGoodsService.getPromotionGoods(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
+ PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
+
+ //修改砍价商品库存
+ if (promotionTypeEnum.equals(PromotionTypeEnum.KANJIA)) {
+ KanjiaActivity kanjiaActivity = kanjiaActivityService.getById(orderItem.getPromotionId());
+ KanjiaActivityGoodsDTO kanjiaActivityGoodsDTO = kanjiaActivityGoodsService.getKanjiaGoodsDetail(kanjiaActivity.getKanjiaActivityGoodsId());
+
+ Integer stock = Integer.parseInt(cache.get(PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId())).toString());
+ kanjiaActivityGoodsDTO.setStock(stock);
+
+ kanjiaActivityGoodsService.updateById(kanjiaActivityGoodsDTO);
+ //修改积分商品库存
+ } else if (promotionTypeEnum.equals(PromotionTypeEnum.POINTS_GOODS)) {
+ PointsGoodsVO pointsGoodsVO = pointsGoodsService.getPointsGoodsDetail(orderItem.getPromotionId());
+ Integer stock = Integer.parseInt(cache.get(PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId())).toString());
+ pointsGoodsVO.setActiveStock(stock);
+ pointsGoodsService.updateById(pointsGoodsVO);
+ } else {
+ PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
+ searchParams.setPromotionType(promotionTypeEnum.name());
+ searchParams.setPromotionId(orderItem.getPromotionId());
+ searchParams.setSkuId(orderItem.getSkuId());
+ PromotionGoods pGoods = promotionGoodsService.getPromotionsGoods(searchParams);
+ //记录需要更新的促销库存信息
promotionKey.add(
PromotionGoodsService.getPromotionGoodsStockCacheKey(
promotionTypeEnum,
orderItem.getPromotionId(), orderItem.getSkuId())
);
- promotionGoods.add(pGoods);
+ if (pGoods != null) {
+ promotionGoods.add(pGoods);
+ }
}
}
goodsSkus.add(goodsSku);
}
+ //批量获取商品库存
List skuStocks = cache.multiGet(skuKeys);
//循环写入商品库存
for (int i = 0; i < skuStocks.size(); i++) {
- goodsSkus.get(i).setQuantity(Integer.parseInt(skuStocks.get(i).toString()));
+ goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
}
//批量修改商品库存
goodsSkuService.updateBatchById(goodsSkus);
@@ -178,14 +329,48 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
if (!promotionKey.isEmpty()) {
List promotionStocks = cache.multiGet(promotionKey);
for (int i = 0; i < promotionKey.size(); i++) {
- promotionGoods.get(i).setQuantity(Integer.parseInt(promotionStocks.get(i).toString()));
+ promotionGoods.get(i).setQuantity(Convert.toInt(promotionStocks.get(i).toString()));
Integer num = promotionGoods.get(i).getNum();
promotionGoods.get(i).setNum((num != null ? num : 0) + order.getOrder().getGoodsNum());
}
- promotionGoodsService.updateBatchById(promotionGoods);
+ promotionGoodsService.updatePromotionGoodsStock(promotionGoods);
}
+ //商品库存,包含sku库存集合,批量更新商品库存相关
goodsSkuService.updateGoodsStuck(goodsSkus);
+ log.info("订单确认,库存同步:商品信息--{};促销信息---{}", goodsSkus, promotionGoods);
+
}
+ /**
+ * 恢复商品库存
+ *
+ * @param order 订单
+ */
+ private void rollbackOrderStock(OrderDetailVO order) {
+
+ //sku商品
+ List goodsSkus = new ArrayList<>();
+ //sku库存key 集合
+ List skuKeys = new ArrayList<>();
+ //循环订单
+ for (OrderItem orderItem : order.getOrderItems()) {
+ skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
+ GoodsSku goodsSku = new GoodsSku();
+ goodsSku.setId(orderItem.getSkuId());
+ goodsSku.setGoodsId(orderItem.getGoodsId());
+ goodsSkus.add(goodsSku);
+ }
+ //批量获取商品库存
+ List skuStocks = cache.multiGet(skuKeys);
+ //循环写入商品SKU库存
+ for (int i = 0; i < skuStocks.size(); i++) {
+ goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
+ }
+ log.info("订单取消,库存还原:{}", goodsSkus);
+ //批量修改商品库存
+ goodsSkuService.updateBatchById(goodsSkus);
+ goodsSkuService.updateGoodsStuck(goodsSkus);
+
+ }
}
diff --git a/consumer/src/main/java/cn/lili/event/impl/StoreChangeEvent.java b/consumer/src/main/java/cn/lili/event/impl/StoreChangeEvent.java
new file mode 100644
index 00000000..af500156
--- /dev/null
+++ b/consumer/src/main/java/cn/lili/event/impl/StoreChangeEvent.java
@@ -0,0 +1,206 @@
+package cn.lili.event.impl;
+
+import cn.lili.event.StoreSettingChangeEvent;
+import cn.lili.modules.distribution.service.DistributionGoodsService;
+import cn.lili.modules.distribution.service.DistributionOrderService;
+import cn.lili.modules.goods.service.DraftGoodsService;
+import cn.lili.modules.member.service.MemberEvaluationService;
+import cn.lili.modules.message.service.StoreMessageService;
+import cn.lili.modules.order.aftersale.service.AfterSaleService;
+import cn.lili.modules.order.order.service.OrderComplaintService;
+import cn.lili.modules.order.order.service.OrderService;
+import cn.lili.modules.order.order.service.ReceiptService;
+import cn.lili.modules.order.order.service.StoreFlowService;
+import cn.lili.modules.promotion.service.*;
+import cn.lili.modules.store.entity.dos.Store;
+import cn.lili.modules.store.service.BillService;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author ftyy
+ * @description: 店铺名称修改同步对应场景
+ * @date 2023/4/24
+ */
+@Service
+public class StoreChangeEvent implements StoreSettingChangeEvent {
+ /**
+ * 优惠券活动表
+ */
+ @Autowired
+ private CouponActivityService couponActivityService;
+
+ /**
+ * 砍价活动商品
+ */
+ @Autowired
+ private KanjiaActivityGoodsService kanjiaActivityGoodsService;
+
+ /**
+ * 积分商品
+ */
+ @Autowired
+ private PointsGoodsService pointsGoodsService;
+
+ /**
+ * 促销商品
+ */
+ @Autowired
+ private PromotionGoodsService promotionGoodsService;
+
+ /**
+ * 秒杀活动活动
+ */
+ @Autowired
+ private SeckillService seckillService;
+
+ /**
+ * 优惠券
+ */
+ @Autowired
+ private CouponService couponService;
+
+ /**
+ * 满优惠活动
+ */
+ @Autowired
+ private FullDiscountService fullDiscountService;
+
+ /**
+ * 拼团
+ */
+ @Autowired
+ private PintuanService pintuanService;
+
+ /**
+ * 秒杀活动
+ */
+ @Autowired
+ private SeckillApplyService seckillApplyService;
+ /**
+ * 订单
+ */
+ @Autowired
+ private OrderService orderService;
+
+ /**
+ * 店铺流水
+ */
+ @Autowired
+ private StoreFlowService storeFlowService;
+
+ /**
+ * 售后
+ */
+ @Autowired
+ private AfterSaleService afterSaleService;
+
+ /**
+ * 订单投诉
+ */
+ @Autowired
+ private OrderComplaintService orderComplaintService;
+ /**
+ * 发票
+ */
+ @Autowired
+ private ReceiptService receiptService;
+
+ /**
+ * 会员优惠券
+ */
+ @Autowired
+ private MemberCouponService memberCouponService;
+
+ /**
+ * 店铺消息
+ */
+ @Autowired
+ private StoreMessageService storeMessageService;
+
+ /**
+ * 会员评价
+ */
+ @Autowired
+ private MemberEvaluationService memberEvaluationService;
+
+ /**
+ * 结算单
+ */
+ @Autowired
+ private BillService billService;
+ /**
+ * 分销商品
+ */
+ @Autowired
+ private DistributionGoodsService distributionGoodsService;
+ /**
+ * 分销订单
+ */
+ @Autowired
+ private DistributionOrderService distributionOrderService;
+
+ /**
+ * 草稿商品
+ */
+ @Autowired
+ private DraftGoodsService draftGoodsService;
+
+
+ /**
+ * 店铺名称修改 同步更新相关店铺名称
+ *
+ * @param store 店铺信息
+ */
+ @Override
+ public void storeSettingChange(Store store) {
+
+ UpdateWrapper updateWrapper = new UpdateWrapper<>()
+ .eq("store_id", store.getId())
+ .set("store_name", store.getStoreName());
+
+ //修改会员优惠券中店铺名称
+ memberCouponService.update(updateWrapper);
+ //修改优惠券活动中店铺名称
+ couponActivityService.update(updateWrapper);
+ //修改砍价活动商品中店铺名称
+ kanjiaActivityGoodsService.update(updateWrapper);
+ //修改积分商品中店铺名称
+ pointsGoodsService.update(updateWrapper);
+ //修改促销商品中店铺名称
+ promotionGoodsService.update(updateWrapper);
+ //修改秒杀活动活动中店铺名称
+ seckillService.update(updateWrapper);
+ //修改优惠券中店铺名称
+ couponService.update(updateWrapper);
+ //修改满优惠活动中店铺名称
+ fullDiscountService.update(updateWrapper);
+ //修改拼团中店铺名称
+ pintuanService.update(updateWrapper);
+ //修改秒杀活动中店铺名称
+ seckillApplyService.update(updateWrapper);
+ //修改发票中店铺名称
+ receiptService.update(updateWrapper);
+ //修改订单中的店铺名称
+ orderService.update(updateWrapper);
+ //修改店铺流水中店铺名称
+ storeFlowService.update(updateWrapper);
+ //修改售后中店铺名称
+ afterSaleService.update(updateWrapper);
+ //修改订单投诉中店铺名称
+ orderComplaintService.update(updateWrapper);
+ //修改店铺消息中的店铺名称
+ storeMessageService.update(updateWrapper);
+ //修改会员评价中店铺名称
+ memberEvaluationService.update(updateWrapper);
+ //修改结算单中店铺名称
+ billService.update(updateWrapper);
+ //修改分销订单中店铺名称
+ distributionOrderService.update(updateWrapper);
+ //修改分销商品中店铺名称
+ distributionGoodsService.update(updateWrapper);
+ //修改草稿商品中店铺名称
+ draftGoodsService.update(updateWrapper);
+ }
+}
diff --git a/consumer/src/main/java/cn/lili/event/impl/VerificationOrderExecute.java b/consumer/src/main/java/cn/lili/event/impl/VerificationOrderExecute.java
new file mode 100644
index 00000000..a0b50055
--- /dev/null
+++ b/consumer/src/main/java/cn/lili/event/impl/VerificationOrderExecute.java
@@ -0,0 +1,70 @@
+package cn.lili.event.impl;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.lili.event.OrderStatusChangeEvent;
+import cn.lili.modules.order.order.entity.dos.Order;
+import cn.lili.modules.order.order.entity.dos.OrderItem;
+import cn.lili.modules.order.order.entity.dto.OrderMessage;
+import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
+import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
+import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
+import cn.lili.modules.order.order.service.OrderItemService;
+import cn.lili.modules.order.order.service.OrderService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 虚拟商品
+ *
+ * @author Bulbasaur
+ * @since 2021/5/29 9:17 上午
+ */
+@Component
+public class VerificationOrderExecute implements OrderStatusChangeEvent {
+
+ @Autowired
+ private OrderService orderService;
+ @Autowired
+ private OrderItemService orderItemService;
+ @Override
+ public void orderChange(OrderMessage orderMessage) {
+ //订单状态为待核验,添加订单添加核验码
+ if (orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE) || orderMessage.getNewStatus().equals(OrderStatusEnum.STAY_PICKED_UP)) {
+ //获取订单信息
+ Order order = orderService.getBySn(orderMessage.getOrderSn());
+ //获取随机数,判定是否存在
+ String code = getCode(order.getStoreId());
+ //设置订单验证码
+ orderService.update(new LambdaUpdateWrapper()
+ .set(Order::getVerificationCode, code)
+ .eq(Order::getSn, orderMessage.getOrderSn()));
+ //修改虚拟订单货物可以进行售后、投诉
+ orderItemService.update(new LambdaUpdateWrapper().eq(OrderItem::getOrderSn, orderMessage.getOrderSn())
+ .set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.NOT_APPLIED)
+ .set(OrderItem::getCommentStatus, OrderComplaintStatusEnum.NO_APPLY));
+ }
+ }
+
+ /**
+ * 获取随机数
+ * 判断当前店铺下是否使用验证码,如果已使用则重新获取
+ *
+ * @param storeId 店铺ID
+ * @return
+ */
+ private String getCode(String storeId) {
+ //获取八位验证码
+ String code = Long.toString(RandomUtil.randomLong(10000000, 99999999));
+
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper()
+ .eq(Order::getVerificationCode, code)
+ .eq(Order::getStoreId, storeId);
+ if (orderService.getOne(lambdaQueryWrapper) == null) {
+ return code;
+ } else {
+ return this.getCode(storeId);
+ }
+ }
+}
diff --git a/consumer/src/main/java/cn/lili/event/impl/WechatMessageExecute.java b/consumer/src/main/java/cn/lili/event/impl/WechatMessageExecute.java
index 79e58f45..acb730e8 100644
--- a/consumer/src/main/java/cn/lili/event/impl/WechatMessageExecute.java
+++ b/consumer/src/main/java/cn/lili/event/impl/WechatMessageExecute.java
@@ -2,11 +2,10 @@ package cn.lili.event.impl;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.event.TradeEvent;
-import cn.lili.modules.message.util.WechatMessageUtil;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.vo.OrderVO;
-import lombok.RequiredArgsConstructor;
+import cn.lili.modules.wechat.util.WechatMessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -20,7 +19,6 @@ import org.springframework.stereotype.Service;
*/
@Slf4j
@Service
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WechatMessageExecute implements OrderStatusChangeEvent, TradeEvent {
@Autowired
@@ -41,15 +39,16 @@ public class WechatMessageExecute implements OrderStatusChangeEvent, TradeEvent
public void orderChange(OrderMessage orderMessage) {
switch (orderMessage.getNewStatus()) {
- case PAID:
case UNDELIVERED:
case DELIVERED:
+ case STAY_PICKED_UP:
case COMPLETED:
try {
wechatMessageUtil.sendWechatMessage(orderMessage.getOrderSn());
} catch (Exception e) {
log.error("微信消息发送失败", e);
}
+ break;
default:
break;
}
diff --git a/consumer/src/main/java/cn/lili/init/SensitiveWordsInit.java b/consumer/src/main/java/cn/lili/init/SensitiveWordsInit.java
new file mode 100644
index 00000000..7099d68c
--- /dev/null
+++ b/consumer/src/main/java/cn/lili/init/SensitiveWordsInit.java
@@ -0,0 +1,34 @@
+package cn.lili.init;
+
+import cn.lili.modules.system.service.SensitiveWordsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * SensitiveWordsInit
+ *
+ * @author Chopper
+ * @version v1.0
+ * 2021-11-29 11:38
+ */
+@Slf4j
+@Component
+public class SensitiveWordsInit implements ApplicationRunner {
+
+ @Autowired
+ private SensitiveWordsService sensitiveWordsService;
+
+ /**
+ * consumer 启动时,实时更新一下过滤词
+ *
+ * @param args 启动参数
+ */
+ @Override
+ public void run(ApplicationArguments args) {
+ sensitiveWordsService.resetCache();
+ }
+
+}
\ No newline at end of file
diff --git a/consumer/src/main/java/cn/lili/listener/AfterSaleMessageListener.java b/consumer/src/main/java/cn/lili/listener/AfterSaleMessageListener.java
index 59d7f71c..13dd5860 100644
--- a/consumer/src/main/java/cn/lili/listener/AfterSaleMessageListener.java
+++ b/consumer/src/main/java/cn/lili/listener/AfterSaleMessageListener.java
@@ -1,10 +1,9 @@
package cn.lili.listener;
import cn.hutool.json.JSONUtil;
-import cn.lili.common.rocketmq.tags.AfterSaleTagsEnum;
import cn.lili.event.AfterSaleStatusChangeEvent;
-import cn.lili.modules.order.order.entity.dos.AfterSale;
-import lombok.RequiredArgsConstructor;
+import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
+import cn.lili.rocketmq.tags.AfterSaleTagsEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
@@ -18,33 +17,32 @@ import java.util.List;
* 售后通知
*
* @author paulG
- * @since 2020/12/9
*/
@Slf4j
@Component
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RocketMQMessageListener(topic = "${lili.data.rocketmq.after-sale-topic}", consumerGroup = "${lili.data.rocketmq.after-sale-group}")
public class AfterSaleMessageListener implements RocketMQListener {
- //售后订单状态
- private final List afterSaleStatusChangeEvents;
+ /**
+ * 售后订单状态
+ */
+ @Autowired
+ private List afterSaleStatusChangeEvents;
@Override
public void onMessage(MessageExt messageExt) {
- switch (AfterSaleTagsEnum.valueOf(messageExt.getTags())) {
- case AFTER_SALE_STATUS_CHANGE:
- for (AfterSaleStatusChangeEvent afterSaleStatusChangeEvent : afterSaleStatusChangeEvents) {
- try {
- AfterSale afterSale = JSONUtil.toBean(new String(messageExt.getBody()), AfterSale.class);
- afterSaleStatusChangeEvent.afterSaleStatusChange(afterSale);
- } catch (Exception e) {
- log.error("售后{},在{}业务中,状态修改事件执行异常",
- new String(messageExt.getBody()),
- afterSaleStatusChangeEvent.getClass().getName(),
- e);
- }
+ if (AfterSaleTagsEnum.valueOf(messageExt.getTags()) == AfterSaleTagsEnum.AFTER_SALE_STATUS_CHANGE) {
+ for (AfterSaleStatusChangeEvent afterSaleStatusChangeEvent : afterSaleStatusChangeEvents) {
+ try {
+ AfterSale afterSale = JSONUtil.toBean(new String(messageExt.getBody()), AfterSale.class);
+ afterSaleStatusChangeEvent.afterSaleStatusChange(afterSale);
+ } catch (Exception e) {
+ log.error("售后{},在{}业务中,状态修改事件执行异常",
+ new String(messageExt.getBody()),
+ afterSaleStatusChangeEvent.getClass().getName(),
+ e);
}
- break;
+ }
}
}
diff --git a/consumer/src/main/java/cn/lili/listener/GoodsMessageListener.java b/consumer/src/main/java/cn/lili/listener/GoodsMessageListener.java
index 44f58e89..8ed979cb 100644
--- a/consumer/src/main/java/cn/lili/listener/GoodsMessageListener.java
+++ b/consumer/src/main/java/cn/lili/listener/GoodsMessageListener.java
@@ -1,24 +1,41 @@
package cn.lili.listener;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ClassLoaderUtil;
+import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import cn.lili.common.rocketmq.tags.GoodsTagsEnum;
+import cn.lili.common.aop.annotation.RetryOperation;
+import cn.lili.common.exception.RetryException;
+import cn.lili.common.vo.PageVO;
import cn.lili.event.GoodsCommentCompleteEvent;
-import cn.lili.event.MemberRegisterEvent;
-import cn.lili.modules.goods.entity.dos.Goods;
-import cn.lili.modules.goods.entity.dos.GoodsSku;
+import cn.lili.modules.distribution.entity.dos.DistributionGoods;
+import cn.lili.modules.distribution.entity.dto.DistributionGoodsSearchParams;
+import cn.lili.modules.distribution.service.DistributionGoodsService;
+import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
+import cn.lili.modules.goods.entity.dos.*;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
-import cn.lili.modules.goods.service.GoodsService;
-import cn.lili.modules.goods.service.GoodsSkuService;
+import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
+import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
+import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
+import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
+import cn.lili.modules.goods.service.*;
import cn.lili.modules.member.entity.dos.FootPrint;
-import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.FootprintService;
import cn.lili.modules.member.service.GoodsCollectionService;
+import cn.lili.modules.promotion.entity.dos.BasePromotions;
+import cn.lili.modules.promotion.entity.dos.PromotionGoods;
+import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
+import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
+import cn.lili.modules.promotion.service.PromotionGoodsService;
+import cn.lili.modules.promotion.service.PromotionService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
-import cn.lili.modules.store.service.StoreService;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import lombok.RequiredArgsConstructor;
+import cn.lili.rocketmq.tags.GoodsTagsEnum;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
@@ -26,7 +43,8 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
/**
* 商品消息
@@ -36,25 +54,75 @@ import java.util.List;
**/
@Component
@Slf4j
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RocketMQMessageListener(topic = "${lili.data.rocketmq.goods-topic}", consumerGroup = "${lili.data.rocketmq.goods-group}")
public class GoodsMessageListener implements RocketMQListener {
- //ES商品
- private final EsGoodsIndexService goodsIndexService;
- //店铺
- private final StoreService storeService;
- //商品
- private final GoodsService goodsService;
- //商品
- private final GoodsSkuService goodsSkuService;
- //用户足迹
- private final FootprintService footprintService;
- //商品收藏
- private final GoodsCollectionService goodsCollectionService;
- //商品评价
- private final List goodsCommentCompleteEvents;
+ private static final int BATCH_SIZE = 10;
+
+ /**
+ * ES商品
+ */
+ @Autowired
+ private EsGoodsIndexService goodsIndexService;
+ /**
+ * 商品
+ */
+ @Autowired
+ private GoodsService goodsService;
+ /**
+ * 商品Sku
+ */
+ @Autowired
+ private GoodsSkuService goodsSkuService;
+ /**
+ * 用户足迹
+ */
+ @Autowired
+ private FootprintService footprintService;
+ /**
+ * 商品收藏
+ */
+ @Autowired
+ private GoodsCollectionService goodsCollectionService;
+ /**
+ * 商品评价
+ */
+ @Autowired
+ private List goodsCommentCompleteEvents;
+ /**
+ * 分销商品
+ */
+ @Autowired
+ private DistributionGoodsService distributionGoodsService;
+ /**
+ * 分销员-商品关联表
+ */
+ @Autowired
+ private DistributionSelectedGoodsService distributionSelectedGoodsService;
+ /**
+ * 分类
+ */
+ @Autowired
+ private CategoryService categoryService;
+ /**
+ * 品牌
+ */
+ @Autowired
+ private BrandService brandService;
+ /**
+ * 店铺商品分类
+ */
+ @Autowired
+ private StoreGoodsLabelService storeGoodsLabelService;
+
+ @Autowired
+ private PromotionService promotionService;
+
+ @Autowired
+ private PromotionGoodsService promotionGoodsService;
+
@Override
+ @RetryOperation
public void onMessage(MessageExt messageExt) {
switch (GoodsTagsEnum.valueOf(messageExt.getTags())) {
@@ -65,18 +133,90 @@ public class GoodsMessageListener implements RocketMQListener {
break;
//生成索引
case GENERATOR_GOODS_INDEX:
- String goodsIndexJsonStr = new String(messageExt.getBody());
- List goodsIndices = JSONUtil.toList(JSONUtil.parseArray(goodsIndexJsonStr), EsGoodsIndex.class);
- for (EsGoodsIndex goodsIndex : goodsIndices) {
- log.info("生成商品索引" + goodsIndex);
- this.goodsIndexService.addIndex(goodsIndex);
+ try {
+ String goodsId = new String(messageExt.getBody());
+ log.info("生成索引: {}", goodsId);
+ Goods goods = this.goodsService.getById(goodsId);
+ this.updateGoodsIndex(goods);
+ } catch (Exception e) {
+ log.error("生成商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ case GENERATOR_STORE_GOODS_INDEX:
+ try {
+ String storeId = new String(messageExt.getBody());
+ this.updateGoodsIndex(storeId);
+ } catch (Exception e) {
+ log.error("生成店铺商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ case UPDATE_GOODS_INDEX_PROMOTIONS:
+ this.updateGoodsIndexPromotions(new String(messageExt.getBody()));
+ break;
+ case DELETE_GOODS_INDEX_PROMOTIONS:
+ JSONObject jsonObject = JSONUtil.parseObj(new String(messageExt.getBody()));
+ String promotionKey = jsonObject.getStr("promotionKey");
+ if (CharSequenceUtil.isEmpty(promotionKey)) {
+ break;
+ }
+ if (CharSequenceUtil.isNotEmpty(jsonObject.getStr("scopeId"))) {
+ this.goodsIndexService.deleteEsGoodsPromotionByPromotionKey(Arrays.asList(jsonObject.getStr("scopeId").split(",")), promotionKey);
+ } else {
+ this.goodsIndexService.deleteEsGoodsPromotionByPromotionKey(promotionKey);
+ }
+ break;
+ case UPDATE_GOODS_INDEX:
+ try {
+ String goodsIdsJsonStr = new String(messageExt.getBody());
+ GoodsSearchParams searchParams = new GoodsSearchParams();
+ searchParams.setId(ArrayUtil.join(JSONUtil.toList(goodsIdsJsonStr, String.class).toArray(), ","));
+ List goodsList = goodsService.queryListByParams(searchParams);
+ this.updateGoodsIndex(goodsList);
+ } catch (Exception e) {
+ log.error("更新商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ case UPDATE_GOODS_INDEX_FIELD:
+ try {
+ String updateIndexFieldsJsonStr = new String(messageExt.getBody());
+ JSONObject updateIndexFields = JSONUtil.parseObj(updateIndexFieldsJsonStr);
+ @SuppressWarnings("unchecked") Map queryFields = updateIndexFields.get("queryFields", Map.class);
+ @SuppressWarnings("unchecked") Map updateFields = updateIndexFields.get("updateFields", Map.class);
+ goodsIndexService.updateIndex(queryFields, updateFields);
+ } catch (Exception e) {
+ log.error("更新商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ case RESET_GOODS_INDEX:
+ try {
+ String goodsIdsJsonStr = new String(messageExt.getBody());
+ List goodsIndices = JSONUtil.toList(goodsIdsJsonStr, EsGoodsIndex.class);
+ goodsIndexService.updateBulkIndex(goodsIndices);
+ } catch (Exception e) {
+ log.error("重置商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
}
break;
//审核商品
case GOODS_AUDIT:
+ Goods goods = JSONUtil.toBean(new String(messageExt.getBody()), Goods.class);
+ updateGoodsIndex(goods);
+ break;
//删除商品
case GOODS_DELETE:
- storeService.updateStoreGoodsNum(new String(messageExt.getBody()));
+ try {
+ String goodsIdsJsonStr = new String(messageExt.getBody());
+ for (String goodsId : JSONUtil.toList(goodsIdsJsonStr, String.class)) {
+ goodsIndexService.deleteIndex(MapUtil.builder(new HashMap()).put("goodsId", goodsId).build());
+ }
+
+ promotionService.removeByGoodsIds(goodsIdsJsonStr);
+ } catch (Exception e) {
+ log.error("删除商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ case DOWN:
+ String goodsIdsJsonStr = new String(messageExt.getBody());
+ promotionService.removeByGoodsIds(goodsIdsJsonStr);
break;
//规格删除
case SKU_DELETE:
@@ -84,58 +224,281 @@ public class GoodsMessageListener implements RocketMQListener {
List skuIds = JSONUtil.toList(message, String.class);
goodsCollectionService.deleteSkuCollection(skuIds);
break;
- //收藏商品
- case GOODS_COLLECTION:
- storeService.updateStoreCollectionNum(new String(messageExt.getBody()));
+ case STORE_GOODS_DELETE:
+ try {
+ String storeId = new String(messageExt.getBody());
+ goodsIndexService.deleteIndex(MapUtil.builder(new HashMap()).put("storeId", storeId).build());
+ } catch (RetryException re) {
+ throw re;
+ } catch (Exception e) {
+ log.error("删除店铺商品索引事件执行异常,商品信息: " + new String(messageExt.getBody()), e);
+ }
+ break;
+ //同步商品分类名称
+ case CATEGORY_GOODS_NAME:
+ //分类ID
+ String id = new String(messageExt.getBody());
+ goodsService.categoryGoodsName(id);
break;
//商品评价
case GOODS_COMMENT_COMPLETE:
+ MemberEvaluation memberEvaluation = JSONUtil.toBean(new String(messageExt.getBody()), MemberEvaluation.class);
for (GoodsCommentCompleteEvent goodsCommentCompleteEvent : goodsCommentCompleteEvents) {
try {
- MemberEvaluation memberEvaluation = JSONUtil.toBean(new String(messageExt.getBody()), MemberEvaluation.class);
goodsCommentCompleteEvent.goodsComment(memberEvaluation);
} catch (Exception e) {
- log.error("评价{},在{}业务中,状态修改事件执行异常",
- new String(messageExt.getBody()),
- goodsCommentCompleteEvent.getClass().getName(),
- e);
+ log.error("评价{},在{}业务中,状态修改事件执行异常", new String(messageExt.getBody()), goodsCommentCompleteEvent.getClass().getName(), e);
}
}
break;
//购买商品完成
case BUY_GOODS_COMPLETE:
- String goodsCompleteMessageStr = new String(messageExt.getBody());
- List goodsCompleteMessageList = JSONUtil.toList(JSONUtil.parseArray(goodsCompleteMessageStr), GoodsCompleteMessage.class);
- for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
- Goods goods = goodsService.getById(goodsCompleteMessage.getGoodsId());
- if (goods != null) {
- // 更新商品购买数量
- if (goods.getBuyCount() == null) {
- goods.setBuyCount(0);
- }
- int buyCount = goods.getBuyCount() + goodsCompleteMessage.getBuyNum();
- LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
- updateWrapper.eq(Goods::getId, goodsCompleteMessage.getGoodsId());
- updateWrapper.set(Goods::getBuyCount, buyCount);
- goodsService.update(updateWrapper);
- } else {
- log.error("商品Id为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
- }
- GoodsSku goodsSku = goodsSkuService.getById(goodsCompleteMessage.getSkuId());
- if (goodsSku != null) {
- // 更新商品购买数量
- if (goodsSku.getBuyCount() == null) {
- goodsSku.setBuyCount(0);
- }
- int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
- goodsSku.setBuyCount(buyCount);
- goodsSkuService.update(goodsSku);
- goodsIndexService.updateIndexBuyNum(goodsCompleteMessage.getSkuId(), buyCount);
- } else {
- log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
- }
- }
+ this.goodsBuyComplete(messageExt);
+ break;
+ default:
+ log.error("商品执行异常:{}", new String(messageExt.getBody()));
break;
}
}
+
+ private void updateGoodsIndexPromotions(String promotionsJsonStr) {
+ try {
+ log.info("更新商品索引促销信息: {}", promotionsJsonStr);
+ JSONObject jsonObject = JSONUtil.parseObj(promotionsJsonStr);
+ // 转换为详细的促销信息(注:促销信息必须继承自 BasePromotions,且必须保证派生类存在与sdk包下)
+ BasePromotions promotions = (BasePromotions) jsonObject.get("promotions", ClassLoaderUtil.loadClass(jsonObject.get("promotionsType").toString()));
+ // 获取促销唯一key,由 促销类型 + 促销id 组成
+ String esPromotionKey = jsonObject.get("esPromotionKey").toString();
+ if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(promotions.getScopeType())) {
+ for (int i = 0; ; i++) {
+ PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
+ searchParams.setPromotionId(promotions.getId());
+ PageVO pageVO = new PageVO();
+ pageVO.setPageNumber(i);
+ pageVO.setPageSize(BATCH_SIZE);
+ Page promotionGoodsPage = this.promotionGoodsService.pageFindAll(searchParams, pageVO);
+ if (promotionGoodsPage == null || promotionGoodsPage.getRecords().isEmpty()) {
+ break;
+ }
+ List skuIds = promotionGoodsPage.getRecords().stream().map(PromotionGoods::getSkuId).collect(Collectors.toList());
+ // 更新商品索引促销信息(删除原索引中相关的促销信息,更新索引中促销信息)
+ this.goodsIndexService.deleteEsGoodsPromotionByPromotionKey(skuIds, esPromotionKey);
+ this.goodsIndexService.updateEsGoodsIndexByList(promotionGoodsPage.getRecords(), promotions, esPromotionKey);
+ }
+
+ } else if (PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name().equals(promotions.getScopeType())) {
+ for (int i = 0; ; i++) {
+ GoodsSearchParams searchParams = new GoodsSearchParams();
+ searchParams.setCategoryPath(promotions.getScopeId());
+ searchParams.setPageNumber(i);
+ searchParams.setPageSize(BATCH_SIZE);
+ IPage goodsSkuByPage = this.goodsSkuService.getGoodsSkuByPage(searchParams);
+ if (goodsSkuByPage == null || goodsSkuByPage.getRecords().isEmpty()) {
+ break;
+ }
+ List skuIds = goodsSkuByPage.getRecords().stream().map(GoodsSku::getId).collect(Collectors.toList());
+ // 更新商品索引促销信息(删除原索引中相关的促销信息,更新索引中促销信息)
+ this.goodsIndexService.deleteEsGoodsPromotionByPromotionKey(skuIds, esPromotionKey);
+ this.goodsIndexService.updateEsGoodsIndexPromotions(skuIds, promotions, esPromotionKey);
+ }
+
+ } else if (PromotionsScopeTypeEnum.ALL.name().equals(promotions.getScopeType())) {
+ this.goodsIndexService.updateEsGoodsIndexAllByList(promotions, esPromotionKey);
+ }
+ } catch (Exception e) {
+ log.error("生成商品索引促销信息执行异常", e);
+ }
+ }
+
+ /**
+ * 更新商品索引
+ *
+ * @param goodsList 商品列表消息
+ */
+ private void updateGoodsIndex(List goodsList) {
+ for (Goods goods : goodsList) {
+ this.updateGoodsIndex(goods);
+ }
+ }
+
+
+ /**
+ * 更新商品索引根据店铺id
+ *
+ * @param storeId 店铺id
+ */
+ private void updateGoodsIndex(String storeId) {
+ //如果商品通过审核&&并且已上架
+ GoodsSearchParams searchParams = new GoodsSearchParams();
+ searchParams.setStoreId(storeId);
+ for (Goods goods : this.goodsService.queryListByParams(searchParams)) {
+ this.updateGoodsIndex(goods);
+ }
+
+ }
+
+ /**
+ * 更新商品索引
+ *
+ * @param goods 商品消息
+ */
+ private void updateGoodsIndex(Goods goods) {
+ for (int i = 1; ; i++) {
+ //如果商品通过审核&&并且已上架
+ GoodsSearchParams searchParams = new GoodsSearchParams();
+ searchParams.setGoodsId(goods.getId());
+ searchParams.setPageNumber(i);
+ searchParams.setPageSize(BATCH_SIZE);
+ searchParams.setGeQuantity(0);
+ IPage goodsSkuByPage = this.goodsSkuService.getGoodsSkuByPage(searchParams);
+ if (goodsSkuByPage == null || goodsSkuByPage.getRecords().isEmpty()) {
+ break;
+ }
+ log.info("goods:{}", goods);
+ log.info("goodsSkuList:{}", goodsSkuByPage.getRecords());
+ if (goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name()) && goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name()) && Boolean.FALSE.equals(goods.getDeleteFlag())) {
+ this.generatorGoodsIndex(goods, goodsSkuByPage.getRecords());
+ } else {
+ //如果商品状态值不支持es搜索,那么将商品信息做下架处理
+ for (GoodsSku goodsSku : goodsSkuByPage.getRecords()) {
+ EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
+ if (esGoodsOld != null) {
+ goodsIndexService.deleteIndexById(goodsSku.getId());
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * 生成商品索引
+ *
+ * @param goods 商品信息
+ * @param goodsSkuList 商品sku信息
+ */
+ private void generatorGoodsIndex(Goods goods, List