重构优化促销模块。移除促销相关的mongo

This commit is contained in:
paulGao
2021-12-10 20:15:03 +08:00
parent 8a29ce048d
commit d9d19f8cbd
118 changed files with 2998 additions and 3885 deletions

View File

@@ -4,7 +4,7 @@ import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,7 +34,7 @@ public class RegisteredCouponActivityExecute implements MemberRegisterEvent {
public void memberRegister(Member member) {
List<CouponActivity> couponActivities = couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name()));
.eq(CouponActivity::getPromotionStatus, PromotionsStatusEnum.START.name()));
couponActivityService.registered(couponActivities, member);
}

View File

@@ -15,6 +15,7 @@ import cn.lili.modules.promotion.entity.dos.KanjiaActivity;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.KanjiaActivityGoodsDTO;
import cn.lili.modules.promotion.entity.vos.PointsGoodsVO;
import cn.lili.modules.promotion.entity.vos.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -202,10 +203,10 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
switch (promotionTypeEnum) {
case KANJIA:
cache.put(cacheKey, kanjiaActivityGoodsService.getKanJiaGoodsBySku(orderItem.getSkuId()).getStock().intValue());
cache.put(cacheKey, kanjiaActivityGoodsService.getKanjiaGoodsBySkuId(orderItem.getSkuId()).getStock());
return;
case POINTS_GOODS:
cache.put(cacheKey, pointsGoodsService.getPointsGoodsVOByMongo(orderItem.getSkuId()).getActiveStock().intValue());
cache.put(cacheKey, pointsGoodsService.getPointsGoodsDetailBySkuId(orderItem.getSkuId()).getActiveStock());
return;
case SECKILL:
case PINTUAN:
@@ -303,14 +304,20 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
pointsGoodsService.updateById(pointsGoodsVO);
this.mongoTemplate.save(pointsGoodsVO);
} else {
PromotionGoods pGoods = promotionGoodsService.getPromotionGoods(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
searchParams.setPromotionStatus(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);

View File

@@ -3,9 +3,9 @@ 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.properties.RocketmqCustomProperties;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.distribution.entity.dos.DistributionSelectedGoods;
@@ -17,6 +17,7 @@ import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
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.BrandService;
@@ -27,13 +28,16 @@ import cn.lili.modules.member.entity.dos.FootPrint;
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.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.BasePromotions;
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
import cn.lili.modules.promotion.entity.vos.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.search.utils.EsIndexUtil;
import cn.lili.modules.store.entity.dos.StoreGoodsLabel;
import cn.lili.modules.store.service.StoreGoodsLabelService;
import cn.lili.modules.store.service.StoreService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -41,14 +45,11 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
* 商品消息
@@ -122,16 +123,8 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
@Autowired
private StoreGoodsLabelService storeGoodsLabelService;
/**
* rocketMq
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* rocketMq配置
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
private PromotionGoodsService promotionGoodsService;
@Override
public void onMessage(MessageExt messageExt) {
@@ -152,6 +145,12 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
log.error("生成商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
}
break;
case UPDATE_GOODS_INDEX_PROMOTIONS:
this.updateGoodsIndexPromotions(new String(messageExt.getBody()));
break;
case DELETE_GOODS_INDEX_PROMOTIONS:
this.goodsIndexService.deleteEsGoodsPromotionByPromotionId(null, new String(messageExt.getBody()));
break;
case UPDATE_GOODS_INDEX:
try {
String goodsIdsJsonStr = new String(messageExt.getBody());
@@ -226,6 +225,32 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
}
}
private void updateGoodsIndexPromotions(String promotionsJsonStr) {
try {
log.info("更新商品索引促销信息: {}", promotionsJsonStr);
JSONObject jsonObject = JSONUtil.parseObj(promotionsJsonStr);
BasePromotions promotions = (BasePromotions) jsonObject.get("promotions",
ClassLoaderUtil.loadClass(jsonObject.get("promotionsType").toString()));
String esPromotionKey = jsonObject.get("esPromotionKey").toString();
if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(promotions.getScopeType())) {
PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
searchParams.setPromotionId(promotions.getId());
List<PromotionGoods> promotionGoodsList = this.promotionGoodsService.listFindAll(searchParams);
this.goodsIndexService.updateEsGoodsIndexByList(promotionGoodsList, promotions, esPromotionKey);
} else if (PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name().equals(promotions.getScopeType())) {
GoodsSearchParams searchParams = new GoodsSearchParams();
searchParams.setCategoryPath(promotions.getScopeId());
List<GoodsSku> goodsSkuByList = this.goodsSkuService.getGoodsSkuByList(searchParams);
List<String> skuIds = goodsSkuByList.stream().map(GoodsSku::getId).collect(Collectors.toList());
this.goodsIndexService.updateEsGoodsIndexPromotions(skuIds, promotions, esPromotionKey);
} else if (PromotionsScopeTypeEnum.ALL.name().equals(promotions.getScopeType())) {
this.goodsIndexService.updateEsGoodsIndexAllByList(promotions, esPromotionKey);
}
} catch (Exception e) {
log.error("生成商品索引促销信息执行异常,参数信息 {}", promotionsJsonStr);
}
}
/**
* 更新商品索引
*
@@ -415,13 +440,10 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
goodsSku.setBuyCount(buyCount);
goodsSkuService.update(goodsSku);
//修改规格索引,发送mq消息
Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(
MapUtil.builder().put("id", goodsCompleteMessage.getSkuId()).build(),
MapUtil.builder().put("buyCount", buyCount).build());
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.UPDATE_GOODS_INDEX_FIELD.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(updateIndexFieldsMap), RocketmqSendCallbackBuilder.commonCallback());
goodsIndexService.updateIndex(goodsCompleteMessage.getSkuId(), new EsGoodsIndex().setBuyCount(buyCount));
this.goodsIndexService.updateIndex(
MapUtil.builder(new HashMap<String, Object>()).put("id", goodsCompleteMessage.getSkuId()).build(),
MapUtil.builder(new HashMap<String, Object>()).put("buyCount", buyCount).build());
} else {
log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}

View File

@@ -1,34 +1,18 @@
package cn.lili.timetask.handler.impl.promotion;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import cn.lili.modules.promotion.entity.vos.PintuanVO;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.promotion.service.SeckillService;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.SeckillSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 促销活动每日定时器
*
@@ -39,41 +23,11 @@ import java.util.List;
@Component
public class PromotionEverydayExecute implements EveryDayExecute {
/**
* Mongo
*/
@Autowired
private MongoTemplate mongoTemplate;
/**
* ES商品索引
*/
@Autowired
private EsGoodsIndexService esGoodsIndexService;
/**
* 满额活动
*/
@Autowired
private FullDiscountService fullDiscountService;
/**
* 拼团
*/
@Autowired
private PintuanService pintuanService;
/**
* 优惠券
*/
@Autowired
private CouponService couponService;
/**
* 会员优惠券
*/
@Autowired
private MemberCouponService memberCouponService;
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
/**
* 系统设置
*/
@@ -90,125 +44,13 @@ public class PromotionEverydayExecute implements EveryDayExecute {
*/
@Override
public void execute() {
//mongo查询条件
Query query = new Query();
//结束条件 活动未关闭/活动未结束
query.addCriteria(Criteria.where("promotionStatus").ne(PromotionStatusEnum.END.name())
.orOperator(Criteria.where("promotionStatus").ne(PromotionStatusEnum.CLOSE.name())));
//结束条件 活动结束时间大于当前时间
query.addCriteria(Criteria.where("endTime").lte(new Date()));
//结束满减活动
endFullDiscount(query);
//关闭拼团活动
endPintuan(query);
//结束优惠券
endCoupon(query);
//查询条件
this.esGoodsIndexService.cleanInvalidPromotion();
//定时创建活动
addSeckill();
}
/**
* 结束优惠券活动
*
* @param query
*/
private void endCoupon(Query query) {
try {
//关闭优惠券活动
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
// //关闭的优惠券活动
for (CouponVO vo : couponVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
couponService.update(this.getUpdatePromotionWrapper(ids));
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
memberCouponService.update(memberCouponLambdaUpdateWrapper);
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("优惠券活动关闭错误", e);
}
}
/**
* 结束拼团活动
*
* @param query
*/
private void endPintuan(Query query) {
try {
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
//准备修改活动的id
List<String> ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
pintuanService.update(this.getUpdatePromotionWrapper(ids));
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("拼团活动关闭错误", e);
}
}
/**
* 结束满减活动
*
* @param query
*/
private void endFullDiscount(Query query) {
try {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
}
} catch (Exception e) {
log.error("满减活动关闭错误", e);
}
}
/**
* 添加秒杀活动
* 从系统设置中获取秒杀活动的配置
@@ -218,32 +60,6 @@ public class PromotionEverydayExecute implements EveryDayExecute {
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
Seckill seckill = new Seckill(SeckillService.PRE_CREATION, seckillSetting.getHours(), seckillSetting.getSeckillRule());
seckillService.saveSeckill(seckill);
}
/**
* 获取促销修改查询条件 修改活动状态
*
* @param ids 促销活动ID
* @return 促销活动商品查询Wrapper
*/
private UpdateWrapper getUpdatePromotionWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.in("id", ids);
updateWrapper.set("promotion_status", PromotionStatusEnum.END.name());
return updateWrapper;
}
/**
* 获取商品的促销修改查询条件 修改商品状态
*
* @param ids 促销活动ID
* @return 促销活动商品修改Wrapper
*/
private UpdateWrapper getUpdatePromotionGoodsWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.in("promotion_id", ids);
updateWrapper.set("promotion_status", PromotionStatusEnum.END.name());
return updateWrapper;
seckillService.savePromotions(seckill);
}
}

View File

@@ -1,16 +1,10 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.PromotionService;
import cn.lili.trigger.TimeTriggerExecutor;
import cn.lili.trigger.interfaces.TimeTrigger;
import cn.lili.trigger.message.PintuanOrderMessage;
import cn.lili.trigger.message.PromotionMessage;
import cn.lili.trigger.model.TimeExecuteConstant;
import cn.lili.trigger.model.TimeTriggerMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -25,21 +19,6 @@ import org.springframework.stereotype.Component;
@Slf4j
@Component(TimeExecuteConstant.PROMOTION_EXECUTOR)
public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
/**
* 促销
*/
@Autowired
private PromotionService promotionService;
/**
* RocketMQ
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
/**
* 延时任务
*/
@Autowired
private TimeTrigger timeTrigger;
/**
* 订单
*/
@@ -49,32 +28,6 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
@Override
public void execute(Object object) {
PromotionMessage promotionMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PromotionMessage.class);
//促销延时信息
if (promotionMessage != null && promotionMessage.getPromotionId() != null) {
log.info("促销活动信息消费:{}", promotionMessage);
//如果为促销活动开始,则需要发布促销活动结束的定时任务
if (PromotionStatusEnum.START.name().equals(promotionMessage.getPromotionStatus())) {
if (!promotionService.updatePromotionStatus(promotionMessage)) {
log.error("开始促销活动失败: {}", promotionMessage);
return;
}
//促销活动开始后,设置促销活动结束的定时任务
promotionMessage.setPromotionStatus(PromotionStatusEnum.END.name());
String uniqueKey = "{TIME_TRIGGER_" + promotionMessage.getPromotionType() + "}_" + promotionMessage.getPromotionId();
if (promotionMessage.getEndTime() != null) {
//结束时间(延时一分钟)
long closeTime = promotionMessage.getEndTime().getTime() + 60000;
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR, closeTime, promotionMessage, uniqueKey, rocketmqCustomProperties.getPromotionTopic());
//添加延时任务
timeTrigger.addDelay(timeTriggerMsg);
}
} else {
//不是开始,则修改活动状态
promotionService.updatePromotionStatus(promotionMessage);
}
return;
}
//拼团订单消息
PintuanOrderMessage pintuanOrderMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PintuanOrderMessage.class);
if (pintuanOrderMessage != null && pintuanOrderMessage.getPintuanId() != null) {