6.28 人群标签节点过滤,活动是否对xx用户可见、可参与
This commit is contained in:
parent
b09e3bae76
commit
8ff266ff41
@ -95,7 +95,7 @@ CREATE TABLE `group_buy_activity` (
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of group_buy_activity
|
-- Records of group_buy_activity
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO `group_buy_activity` VALUES (1, 100123, '测试活动', '25120207', 0, 1, 1, 15, 1, '2025-06-19 10:19:40', '2025-06-19 10:19:40', '1', '1', '2025-06-19 10:19:40', '2025-06-26 15:27:48');
|
INSERT INTO `group_buy_activity` VALUES (1, 100123, '测试活动', '25120207', 0, 1, 1, 15, 1, '2025-06-19 10:19:40', '2025-06-19 10:19:40', 'RQ_KJHKL98UU78H66554GFDV', '1', '2025-06-19 10:19:40', '2025-06-26 15:27:48');
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for group_buy_discount
|
-- Table structure for group_buy_discount
|
||||||
|
@ -23,6 +23,9 @@ public class IIndexGroupBuyMarketServiceTest {
|
|||||||
@Resource
|
@Resource
|
||||||
private IIndexGroupBuyMarketService indexGroupBuyMarketService;
|
private IIndexGroupBuyMarketService indexGroupBuyMarketService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试人群标签功能的时候,可以进入 ITagServiceTest#test_tag_job 执行人群写入
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void test_indexMarketTrial() throws Exception {
|
public void test_indexMarketTrial() throws Exception {
|
||||||
MarketProductEntity marketProductEntity = new MarketProductEntity();
|
MarketProductEntity marketProductEntity = new MarketProductEntity();
|
||||||
@ -36,6 +39,19 @@ public class IIndexGroupBuyMarketServiceTest {
|
|||||||
log.info("返回结果:{}", JSON.toJSONString(trialBalanceEntity));
|
log.info("返回结果:{}", JSON.toJSONString(trialBalanceEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_indexMarketTrial_no_tag() throws Exception {
|
||||||
|
MarketProductEntity marketProductEntity = new MarketProductEntity();
|
||||||
|
marketProductEntity.setUserId("user01");
|
||||||
|
marketProductEntity.setSource("s01");
|
||||||
|
marketProductEntity.setChannel("c01");
|
||||||
|
marketProductEntity.setGoodsId("9890001");
|
||||||
|
|
||||||
|
TrialBalanceEntity trialBalanceEntity = indexGroupBuyMarketService.indexMarketTrial(marketProductEntity);
|
||||||
|
log.info("请求参数:{}", JSON.toJSONString(marketProductEntity));
|
||||||
|
log.info("返回结果:{}", JSON.toJSONString(trialBalanceEntity));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_indexMarketTrial_error() throws Exception {
|
public void test_indexMarketTrial_error() throws Exception {
|
||||||
MarketProductEntity marketProductEntity = new MarketProductEntity();
|
MarketProductEntity marketProductEntity = new MarketProductEntity();
|
||||||
|
@ -36,4 +36,10 @@ public class ITagServiceTest {
|
|||||||
log.info("gudebai 不存在,预期结果为 false,测试结果:{}", bitSet.get(redisService.getIndexFromUserId("gudebai")));
|
log.info("gudebai 不存在,预期结果为 false,测试结果:{}", bitSet.get(redisService.getIndexFromUserId("gudebai")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_null_tag_bitmap() {
|
||||||
|
RBitSet bitSet = redisService.getBitSet("null");
|
||||||
|
log.info("测试结果:{}", bitSet.isExists());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,4 +14,6 @@ public interface IActivityRepository {
|
|||||||
|
|
||||||
SCSkuActivityVO querySCSkuActivityBySCGoodsId(String source, String channel, String goodsId);
|
SCSkuActivityVO querySCSkuActivityBySCGoodsId(String source, String channel, String goodsId);
|
||||||
|
|
||||||
|
boolean isTagCrowdRange(String tagId, String userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package edu.whut.domain.activity.model.valobj;
|
package edu.whut.domain.activity.model.valobj;
|
||||||
|
|
||||||
|
import edu.whut.types.common.Constants;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼团活动营销配置值对象
|
* 拼团活动营销配置值对象
|
||||||
@ -73,10 +76,36 @@ public class GroupBuyActivityDiscountVO {
|
|||||||
*/
|
*/
|
||||||
private String tagId;
|
private String tagId;
|
||||||
/**
|
/**
|
||||||
* 人群标签规则范围
|
* 人群标签规则范围,如果有值,说明有限制
|
||||||
*/
|
*/
|
||||||
private String tagScope;
|
private String tagScope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可见限制,可以看见不等于能参加拼团
|
||||||
|
* 只要存在这样一个值,那么首次获得的默认值就是 false,false代表有限制
|
||||||
|
*/
|
||||||
|
public boolean isVisible() {
|
||||||
|
if(StringUtils.isBlank(this.tagScope)) return TagScopeEnumVO.VISIBLE.getAllow(); //等价于return true,放行
|
||||||
|
String[] split = this.tagScope.split(Constants.SPLIT);
|
||||||
|
if (split.length > 0 && Objects.equals(split[0], "1") && StringUtils.isNotBlank(split[0])) {
|
||||||
|
return TagScopeEnumVO.VISIBLE.getRefuse(); //等价于return false,待后续校验
|
||||||
|
}
|
||||||
|
return TagScopeEnumVO.VISIBLE.getAllow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参与限制
|
||||||
|
* 只要存在这样一个值,那么首次获得的默认值就是 false
|
||||||
|
*/
|
||||||
|
public boolean isEnable() {
|
||||||
|
if(StringUtils.isBlank(this.tagScope)) return TagScopeEnumVO.VISIBLE.getAllow();
|
||||||
|
String[] split = this.tagScope.split(Constants.SPLIT);
|
||||||
|
if (split.length == 2 && Objects.equals(split[1], "2") && StringUtils.isNotBlank(split[1])) {
|
||||||
|
return TagScopeEnumVO.ENABLE.getRefuse();
|
||||||
|
}
|
||||||
|
return TagScopeEnumVO.ENABLE.getAllow();
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package edu.whut.domain.activity.model.valobj;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动人群标签作用域范围枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public enum TagScopeEnumVO {
|
||||||
|
|
||||||
|
VISIBLE(true,false,"是否可看见拼团"),
|
||||||
|
ENABLE(true, false,"是否可参与拼团"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private Boolean allow;
|
||||||
|
private Boolean refuse;
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
}
|
@ -17,7 +17,7 @@ public class MJCalculateService extends AbstractDiscountCalculateService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
||||||
log.info("优惠策略折扣计算:{}", groupBuyDiscount.getDiscountType().getCode());
|
log.info("满减优惠策略折扣计算规则,0代表人人可参与,1代表指定标签人群参与:{}", groupBuyDiscount.getDiscountType().getCode());
|
||||||
|
|
||||||
// 获取折扣表达式 - 100,10 满100减10元
|
// 获取折扣表达式 - 100,10 满100减10元
|
||||||
String marketExpr = groupBuyDiscount.getMarketExpr();
|
String marketExpr = groupBuyDiscount.getMarketExpr();
|
||||||
|
@ -15,7 +15,7 @@ public class NCalculateService extends AbstractDiscountCalculateService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
||||||
log.info("优惠策略折扣计算:{}", groupBuyDiscount.getDiscountType().getCode());
|
log.info("N元购优惠策略折扣计算规则,0代表人人可参与,1代表指定标签人群参与:{}", groupBuyDiscount.getDiscountType().getCode());
|
||||||
|
|
||||||
// 折扣表达式 - 直接为优惠后的金额
|
// 折扣表达式 - 直接为优惠后的金额
|
||||||
String marketExpr = groupBuyDiscount.getMarketExpr();
|
String marketExpr = groupBuyDiscount.getMarketExpr();
|
||||||
|
@ -15,12 +15,12 @@ public class ZJCalculateService extends AbstractDiscountCalculateService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
||||||
log.info("优惠策略折扣计算:{}", groupBuyDiscount.getDiscountType().getCode());
|
log.info("直减优惠策略折扣计算规则,0代表人人可参与,1代表指定标签人群参与:{}", groupBuyDiscount.getDiscountType().getCode());
|
||||||
|
|
||||||
// 折扣表达式 - 直减为扣减金额
|
// 折扣表达式 - 直减为扣减金额
|
||||||
String marketExpr = groupBuyDiscount.getMarketExpr();
|
String marketExpr = groupBuyDiscount.getMarketExpr();
|
||||||
|
|
||||||
// 折扣价格
|
// 折扣后的实际支付金额
|
||||||
BigDecimal deductionPrice = originalPrice.subtract(new BigDecimal(marketExpr));
|
BigDecimal deductionPrice = originalPrice.subtract(new BigDecimal(marketExpr));
|
||||||
|
|
||||||
// 判断折扣后金额,最低支付1分钱
|
// 判断折扣后金额,最低支付1分钱
|
||||||
|
@ -15,7 +15,7 @@ public class ZKCalculateService extends AbstractDiscountCalculateService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
|
||||||
log.info("优惠策略折扣计算:{}", groupBuyDiscount.getDiscountType().getCode());
|
log.info("折扣优惠策略折扣计算规则,0代表人人可参与,1代表指定标签人群参与:{}", groupBuyDiscount.getDiscountType().getCode());
|
||||||
|
|
||||||
// 折扣表达式 - 折扣百分比
|
// 折扣表达式 - 折扣百分比
|
||||||
String marketExpr = groupBuyDiscount.getMarketExpr();
|
String marketExpr = groupBuyDiscount.getMarketExpr();
|
||||||
|
@ -34,6 +34,10 @@ public class DefaultActivityStrategyFactory {
|
|||||||
private SkuVO skuVO;
|
private SkuVO skuVO;
|
||||||
// 折扣价格
|
// 折扣价格
|
||||||
private BigDecimal deductionPrice;
|
private BigDecimal deductionPrice;
|
||||||
|
// 活动可见性限制
|
||||||
|
private boolean visible;
|
||||||
|
// 活动
|
||||||
|
private boolean enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ import edu.whut.domain.activity.model.valobj.SkuVO;
|
|||||||
import edu.whut.domain.activity.service.trial.AbstractGroupBuyMarketSupport;
|
import edu.whut.domain.activity.service.trial.AbstractGroupBuyMarketSupport;
|
||||||
import edu.whut.domain.activity.service.trial.factory.DefaultActivityStrategyFactory;
|
import edu.whut.domain.activity.service.trial.factory.DefaultActivityStrategyFactory;
|
||||||
import edu.whut.types.design.framework.tree.StrategyHandler;
|
import edu.whut.types.design.framework.tree.StrategyHandler;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -24,8 +22,9 @@ public class EndNode extends AbstractGroupBuyMarketSupport<MarketProductEntity,
|
|||||||
@Override
|
@Override
|
||||||
public TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
public TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
||||||
log.info("拼团商品查询试算服务-EndNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter));
|
log.info("拼团商品查询试算服务-EndNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter));
|
||||||
|
// 拼团活动配置
|
||||||
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
|
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
|
||||||
|
// 商品信息
|
||||||
SkuVO skuVO = dynamicContext.getSkuVO();
|
SkuVO skuVO = dynamicContext.getSkuVO();
|
||||||
|
|
||||||
// 折扣价格
|
// 折扣价格
|
||||||
@ -35,12 +34,12 @@ public class EndNode extends AbstractGroupBuyMarketSupport<MarketProductEntity,
|
|||||||
.goodsId(skuVO.getGoodsId())
|
.goodsId(skuVO.getGoodsId())
|
||||||
.goodsName(skuVO.getGoodsName())
|
.goodsName(skuVO.getGoodsName())
|
||||||
.originalPrice(skuVO.getOriginalPrice())
|
.originalPrice(skuVO.getOriginalPrice())
|
||||||
.deductionPrice(new BigDecimal("0.00"))
|
.deductionPrice(deductionPrice)
|
||||||
.targetCount(groupBuyActivityDiscountVO.getTarget())
|
.targetCount(groupBuyActivityDiscountVO.getTarget())
|
||||||
.startTime(groupBuyActivityDiscountVO.getStartTime())
|
.startTime(groupBuyActivityDiscountVO.getStartTime())
|
||||||
.endTime(groupBuyActivityDiscountVO.getEndTime())
|
.endTime(groupBuyActivityDiscountVO.getEndTime())
|
||||||
.isVisible(false)
|
.isVisible(dynamicContext.isVisible())
|
||||||
.isEnable(false)
|
.isEnable(dynamicContext.isEnable())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntit
|
|||||||
|
|
||||||
private final Map<String, IDiscountCalculateService> discountCalculateServiceMap;
|
private final Map<String, IDiscountCalculateService> discountCalculateServiceMap;
|
||||||
|
|
||||||
|
private final TagNode tagNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步加载数据
|
* 异步加载数据
|
||||||
* @param requestParameter
|
* @param requestParameter
|
||||||
@ -57,8 +59,10 @@ public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntit
|
|||||||
FutureTask<SkuVO> skuVOFutureTask = new FutureTask<>(querySkuVOFromDBThreadTask);
|
FutureTask<SkuVO> skuVOFutureTask = new FutureTask<>(querySkuVOFromDBThreadTask);
|
||||||
threadPoolExecutor.execute(skuVOFutureTask);
|
threadPoolExecutor.execute(skuVOFutureTask);
|
||||||
|
|
||||||
// 写入上下文 - 对于一些复杂场景,获取数据的操作,有时候会在下N个节点获取,这样前置查询数据,可以提高接口响应效率
|
// 写入上下文- 对于一些复杂场景,获取数据的操作,有时候会在下N个节点获取,这样前置查询数据,可以提高接口响应效率
|
||||||
|
// 写入活动配置信息
|
||||||
dynamicContext.setGroupBuyActivityDiscountVO(groupBuyActivityDiscountVOFutureTask.get(timeout, TimeUnit.MINUTES));
|
dynamicContext.setGroupBuyActivityDiscountVO(groupBuyActivityDiscountVOFutureTask.get(timeout, TimeUnit.MINUTES));
|
||||||
|
// 写入商品信息
|
||||||
dynamicContext.setSkuVO(skuVOFutureTask.get(timeout, TimeUnit.MINUTES));
|
dynamicContext.setSkuVO(skuVOFutureTask.get(timeout, TimeUnit.MINUTES));
|
||||||
|
|
||||||
log.info("拼团商品查询试算服务-MarketNode userId:{} 异步线程加载数据「GroupBuyActivityDiscountVO、SkuVO」完成", requestParameter.getUserId());
|
log.info("拼团商品查询试算服务-MarketNode userId:{} 异步线程加载数据「GroupBuyActivityDiscountVO、SkuVO」完成", requestParameter.getUserId());
|
||||||
@ -75,13 +79,14 @@ public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntit
|
|||||||
public TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
public TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
||||||
log.info("拼团商品查询试算服务-MarketNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter));
|
log.info("拼团商品查询试算服务-MarketNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter));
|
||||||
|
|
||||||
// 获取上下文数据
|
// 获取上下文数据(活动配置信息)
|
||||||
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
|
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
|
||||||
if (null == groupBuyActivityDiscountVO) {
|
if (null == groupBuyActivityDiscountVO) {
|
||||||
return router(requestParameter, dynamicContext);
|
return router(requestParameter, dynamicContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount = groupBuyActivityDiscountVO.getGroupBuyDiscount();
|
GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount = groupBuyActivityDiscountVO.getGroupBuyDiscount();
|
||||||
|
//获取商品信息
|
||||||
SkuVO skuVO = dynamicContext.getSkuVO();
|
SkuVO skuVO = dynamicContext.getSkuVO();
|
||||||
if (null == groupBuyDiscount || null == skuVO) {
|
if (null == groupBuyDiscount || null == skuVO) {
|
||||||
return router(requestParameter, dynamicContext);
|
return router(requestParameter, dynamicContext);
|
||||||
@ -96,6 +101,7 @@ public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntit
|
|||||||
|
|
||||||
// 折扣价格
|
// 折扣价格
|
||||||
BigDecimal deductionPrice = discountCalculateService.calculate(requestParameter.getUserId(), skuVO.getOriginalPrice(), groupBuyDiscount);
|
BigDecimal deductionPrice = discountCalculateService.calculate(requestParameter.getUserId(), skuVO.getOriginalPrice(), groupBuyDiscount);
|
||||||
|
//设置折扣价格到上下文中
|
||||||
dynamicContext.setDeductionPrice(deductionPrice);
|
dynamicContext.setDeductionPrice(deductionPrice);
|
||||||
|
|
||||||
return router(requestParameter, dynamicContext);
|
return router(requestParameter, dynamicContext);
|
||||||
@ -114,7 +120,7 @@ public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntit
|
|||||||
if (null == dynamicContext.getGroupBuyActivityDiscountVO() || null == dynamicContext.getSkuVO() || null == dynamicContext.getDeductionPrice()) {
|
if (null == dynamicContext.getGroupBuyActivityDiscountVO() || null == dynamicContext.getSkuVO() || null == dynamicContext.getDeductionPrice()) {
|
||||||
return errorNode;
|
return errorNode;
|
||||||
}
|
}
|
||||||
return endNode;
|
return tagNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package edu.whut.domain.activity.service.trial.node;
|
||||||
|
import edu.whut.domain.activity.model.entity.MarketProductEntity;
|
||||||
|
import edu.whut.domain.activity.model.entity.TrialBalanceEntity;
|
||||||
|
import edu.whut.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
|
||||||
|
import edu.whut.domain.activity.service.trial.AbstractGroupBuyMarketSupport;
|
||||||
|
import edu.whut.domain.activity.service.trial.factory.DefaultActivityStrategyFactory;
|
||||||
|
import edu.whut.types.design.framework.tree.StrategyHandler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人群标签判断
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class TagNode extends AbstractGroupBuyMarketSupport<MarketProductEntity, DefaultActivityStrategyFactory.DynamicContext, TrialBalanceEntity> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private EndNode endNode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
||||||
|
// 获取拼团活动配置
|
||||||
|
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
|
||||||
|
|
||||||
|
String tagId = groupBuyActivityDiscountVO.getTagId();
|
||||||
|
boolean visible = groupBuyActivityDiscountVO.isVisible();
|
||||||
|
boolean enable = groupBuyActivityDiscountVO.isEnable();
|
||||||
|
|
||||||
|
// 人群标签配置为空,说明该活动不限定人群参与
|
||||||
|
if (StringUtils.isBlank(tagId)) {
|
||||||
|
dynamicContext.setVisible(true);
|
||||||
|
dynamicContext.setEnable(true);
|
||||||
|
return router(requestParameter, dynamicContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否在人群范围内;visible、enable 如果值为 ture 则表示没有配置拼团限制,那么就直接保证为 true 即可
|
||||||
|
boolean isWithin = repository.isTagCrowdRange(tagId, requestParameter.getUserId());
|
||||||
|
dynamicContext.setVisible(visible || isWithin);
|
||||||
|
dynamicContext.setEnable(enable || isWithin);
|
||||||
|
return router(requestParameter, dynamicContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StrategyHandler<MarketProductEntity, DefaultActivityStrategyFactory.DynamicContext, TrialBalanceEntity> get(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
|
||||||
|
return endNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,7 +13,10 @@ import edu.whut.infrastructure.dao.po.GroupBuyActivity;
|
|||||||
import edu.whut.infrastructure.dao.po.GroupBuyDiscount;
|
import edu.whut.infrastructure.dao.po.GroupBuyDiscount;
|
||||||
import edu.whut.infrastructure.dao.po.SCSkuActivity;
|
import edu.whut.infrastructure.dao.po.SCSkuActivity;
|
||||||
import edu.whut.infrastructure.dao.po.Sku;
|
import edu.whut.infrastructure.dao.po.Sku;
|
||||||
|
import edu.whut.infrastructure.redis.IRedisService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.redisson.api.RBitSet;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -23,6 +26,7 @@ import javax.annotation.Resource;
|
|||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class ActivityRepository implements IActivityRepository {
|
public class ActivityRepository implements IActivityRepository {
|
||||||
|
|
||||||
private final IGroupBuyActivityDao groupBuyActivityDao;
|
private final IGroupBuyActivityDao groupBuyActivityDao;
|
||||||
@ -33,6 +37,8 @@ public class ActivityRepository implements IActivityRepository {
|
|||||||
|
|
||||||
private final ISCSkuActivityDao skuActivityDao;
|
private final ISCSkuActivityDao skuActivityDao;
|
||||||
|
|
||||||
|
private final IRedisService redisService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(Long activityId) {
|
public GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(Long activityId) {
|
||||||
GroupBuyActivity groupBuyActivityRes = groupBuyActivityDao.queryValidGroupBuyActivityId(activityId);
|
GroupBuyActivity groupBuyActivityRes = groupBuyActivityDao.queryValidGroupBuyActivityId(activityId);
|
||||||
@ -97,4 +103,15 @@ public class ActivityRepository implements IActivityRepository {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTagCrowdRange(String tagId, String userId) {
|
||||||
|
//根据标签id获取对应位图
|
||||||
|
RBitSet bitSet = redisService.getBitSet(tagId);
|
||||||
|
if (!bitSet.isExists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 判断用户是否存在人群中
|
||||||
|
return bitSet.get(redisService.getIndexFromUserId(userId));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import edu.whut.infrastructure.dao.po.CrowdTagsDetail;
|
|||||||
import edu.whut.infrastructure.dao.po.CrowdTagsJob;
|
import edu.whut.infrastructure.dao.po.CrowdTagsJob;
|
||||||
import edu.whut.infrastructure.redis.IRedisService;
|
import edu.whut.infrastructure.redis.IRedisService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.redisson.api.RBitSet;
|
import org.redisson.api.RBitSet;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
@ -21,6 +22,7 @@ import javax.annotation.Resource;
|
|||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class TagRepository implements ITagRepository {
|
public class TagRepository implements ITagRepository {
|
||||||
|
|
||||||
private final ICrowdTagsDao crowdTagsDao;
|
private final ICrowdTagsDao crowdTagsDao;
|
||||||
@ -73,11 +75,11 @@ public class TagRepository implements ITagRepository {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
crowdTagsDetailDao.addCrowdTagsUserId(crowdTagsDetailReq);
|
crowdTagsDetailDao.addCrowdTagsUserId(crowdTagsDetailReq);
|
||||||
|
|
||||||
// 获取BitSet
|
// 获取BitSet
|
||||||
RBitSet bitSet = redisService.getBitSet(tagId);
|
RBitSet bitSet = redisService.getBitSet(tagId);
|
||||||
bitSet.set(redisService.getIndexFromUserId(userId), true);
|
bitSet.set(redisService.getIndexFromUserId(userId));
|
||||||
} catch (DuplicateKeyException ignore) {
|
} catch (DuplicateKeyException ignore) {
|
||||||
|
log.info("用户id{}已在人群标签{}中",userId,tagId);
|
||||||
// 忽略唯一索引冲突
|
// 忽略唯一索引冲突
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,6 +283,11 @@ public interface IRedisService {
|
|||||||
//位图
|
//位图
|
||||||
RBitSet getBitSet(String key);
|
RBitSet getBitSet(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将userId 映射到一个哈希值,指定需存入位图的位置
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
default int getIndexFromUserId(String userId) {
|
default int getIndexFromUserId(String userId) {
|
||||||
try {
|
try {
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user