提交 caf38ce3 编写于 作者: H hudingrong

rule_model_center

上级 070b7cdd
...@@ -11,6 +11,7 @@ import org.redisson.api.RedissonClient; ...@@ -11,6 +11,7 @@ import org.redisson.api.RedissonClient;
import org.redisson.client.codec.BaseCodec; import org.redisson.client.codec.BaseCodec;
import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder; import org.redisson.client.protocol.Encoder;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config; import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
...@@ -32,8 +33,9 @@ public class RedisClientConfig { ...@@ -32,8 +33,9 @@ public class RedisClientConfig {
public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) { public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
Config config = new Config(); Config config = new Config();
// 根据需要可以设定编解码器;https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96 // 根据需要可以设定编解码器;https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
config.setCodec(new RedisCodec()); // 需要手动从json转pojo
//config.setCodec(new RedisCodec());
config.setCodec(new JsonJacksonCodec());
config.useSingleServer() config.useSingleServer()
.setAddress("redis://" + properties.getHost() + ":" + properties.getPort()) .setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
.setPassword(properties.getPassword()) .setPassword(properties.getPassword())
......
...@@ -28,5 +28,9 @@ ...@@ -28,5 +28,9 @@
from strategy_award from strategy_award
where strategy_id = #{strategyId} where strategy_id = #{strategyId}
</select> </select>
<select id="queryStrategyAwardRuleModels" parameterType="cn.bugstack.infrastructure.persistent.po.StrategyAward" resultType="java.lang.String">
select rule_models from strategy_award
where strategy_id = #{strategyId} and award_id = #{awardId}
</select>
</mapper> </mapper>
...@@ -3,6 +3,9 @@ package cn.bugstack.test.domain; ...@@ -3,6 +3,9 @@ package cn.bugstack.test.domain;
import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity; import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity; import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.service.IRaffleStrategy; import cn.bugstack.domain.strategy.service.IRaffleStrategy;
import cn.bugstack.domain.strategy.service.armory.IStrategyArmory;
import cn.bugstack.domain.strategy.service.armory.StrategyArmory;
import cn.bugstack.domain.strategy.service.rule.impl.RuleLockLogicFilter;
import cn.bugstack.domain.strategy.service.rule.impl.RuleWeightLogicFilter; import cn.bugstack.domain.strategy.service.rule.impl.RuleWeightLogicFilter;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -25,17 +28,35 @@ import javax.annotation.Resource; ...@@ -25,17 +28,35 @@ import javax.annotation.Resource;
@SpringBootTest @SpringBootTest
public class RaffleStrategyTest { public class RaffleStrategyTest {
@Resource
private IStrategyArmory strategyArmory;
@Resource @Resource
private IRaffleStrategy raffleStrategy; private IRaffleStrategy raffleStrategy;
@Resource @Resource
private RuleWeightLogicFilter ruleWeightLogicFilter; private RuleWeightLogicFilter ruleWeightLogicFilter;
@Resource
private RuleLockLogicFilter ruleLockLogicFilter;
@Before @Before
public void setUp() { public void setUp() {
// 策略装配 100001、100002、100003
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100001L));
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100002L));
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100003L));
// 通过反射 mock 规则中的值
ReflectionTestUtils.setField(ruleWeightLogicFilter, "userScore", 40500L); ReflectionTestUtils.setField(ruleWeightLogicFilter, "userScore", 40500L);
ReflectionTestUtils.setField(ruleLockLogicFilter, "userRaffleCount", 10L);
}
@Test
public void test() {
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100001L));
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100002L));
log.info("测试结果:{}", strategyArmory.assembleLotteryStrategy(100003L));
} }
@Test @Test
public void test_performRaffle() { public void test_performRaffle() {
RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder() RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
...@@ -62,4 +83,21 @@ public class RaffleStrategyTest { ...@@ -62,4 +83,21 @@ public class RaffleStrategyTest {
log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity)); log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
} }
/**
* 次数错校验,抽奖n次后解锁。100003 策略,你可以通过调整 @Before 的 setUp 方法中个人抽奖次数来验证。比如最开始设置0,之后设置10
* ReflectionTestUtils.setField(ruleLockLogicFilter, "userRaffleCount", 10L);
*/
@Test
public void test_raffle_center_rule_lock(){
RaffleFactorEntity raffleFactorEntity = RaffleFactorEntity.builder()
.userId("xiaofuge")
.strategyId(100003L)
.build();
RaffleAwardEntity raffleAwardEntity = raffleStrategy.performRaffle(raffleFactorEntity);
log.info("请求参数:{}", JSON.toJSONString(raffleFactorEntity));
log.info("测试结果:{}", JSON.toJSONString(raffleAwardEntity));
}
} }
...@@ -22,4 +22,6 @@ public class RaffleFactorEntity { ...@@ -22,4 +22,6 @@ public class RaffleFactorEntity {
private String userId; private String userId;
/** 策略ID */ /** 策略ID */
private Long strategyId; private Long strategyId;
/** 奖品ID */
private Integer awardId;
} }
...@@ -7,6 +7,8 @@ import lombok.Data; ...@@ -7,6 +7,8 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
/** /**
* @description: 策略实体 * @description: 策略实体
* @author: hdr * @author: hdr
...@@ -17,7 +19,7 @@ import org.apache.commons.lang3.StringUtils; ...@@ -17,7 +19,7 @@ import org.apache.commons.lang3.StringUtils;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class StrategyEntity { public class StrategyEntity implements Serializable {
/** 抽奖策略ID */ /** 抽奖策略ID */
private Long strategyId; private Long strategyId;
...@@ -33,6 +35,9 @@ public class StrategyEntity { ...@@ -33,6 +35,9 @@ public class StrategyEntity {
public String getRuleWeight() { public String getRuleWeight() {
String[] ruleModels = this.ruleModels(); String[] ruleModels = this.ruleModels();
if (ruleModels == null) {
return null;
}
for (String ruleModel : ruleModels) { for (String ruleModel : ruleModels) {
if ("rule_weight".equals(ruleModel)) return ruleModel; if ("rule_weight".equals(ruleModel)) return ruleModel;
} }
......
package cn.bugstack.domain.strategy.model.valobj;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import cn.bugstack.types.common.Constants;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @description: 抽奖策略规则规则值对象;值对象,没有唯一ID,仅限于从数据库查询对象
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.model.valobj
* @DATE: 2024/4/16
*/
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StrategyAwardRuleModelVO {
private String ruleModels;
/**
* 获取抽奖中规则;或者使用 lambda 表达式
* <p>
* List<String> ruleModelList = Arrays.stream(ruleModels.split(Constants.SPLIT))
* .filter(DefaultLogicFactory.LogicModel::isCenter)
* .collect(Collectors.toList());
* return ruleModelList;
* <p>
* List<String> collect = Arrays.stream(ruleModelValues).filter(DefaultLogicFactory.LogicModel::isCenter).collect(Collectors.toList());
*/
public String[] raffleCenterRuleModelList() {
List<String> ruleModelList = new ArrayList<>();
String[] ruleModeValues = ruleModels.split(Constants.SPLIT);
Arrays.stream(ruleModeValues).forEach(item-> {
if (DefaultLogicFactory.LogicModel.isCenter(item)) {
ruleModelList.add(item);
}
});
return ruleModelList.toArray(new String[0]);
}
}
...@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.repository; ...@@ -3,6 +3,7 @@ package cn.bugstack.domain.strategy.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity; import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity; import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity; import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity;
import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
...@@ -76,4 +77,12 @@ public interface IStrategyRepository { ...@@ -76,4 +77,12 @@ public interface IStrategyRepository {
* @return * @return
*/ */
String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel); String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel);
/**
* 查询 ruleModel
* @param strategyId
* @param awardId
* @return
*/
StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId);
} }
...@@ -8,6 +8,7 @@ import cn.bugstack.types.enums.ResponseCode; ...@@ -8,6 +8,7 @@ import cn.bugstack.types.enums.ResponseCode;
import cn.bugstack.types.exception.AppException; import cn.bugstack.types.exception.AppException;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -44,8 +45,7 @@ public class StrategyArmory implements IStrategyArmory, IStrategyDispatch { ...@@ -44,8 +45,7 @@ public class StrategyArmory implements IStrategyArmory, IStrategyDispatch {
// 2. 权重策略陪住 - 使用于 rule_weight 权重规则配置 // 2. 权重策略陪住 - 使用于 rule_weight 权重规则配置
StrategyEntity strategyEntity = repository.queryStrategyEntityByStrategyId(strategy); StrategyEntity strategyEntity = repository.queryStrategyEntityByStrategyId(strategy);
System.out.println(JSONObject.toJSONString(strategyEntity)); if (StringUtils.isEmpty(strategyEntity.getRuleWeight())) return true;
if (null == strategyEntity.getRuleWeight()||null == strategyEntity) return true;
String ruleWeight = strategyEntity.getRuleWeight(); String ruleWeight = strategyEntity.getRuleWeight();
// 2.2 查询策略规则 // 2.2 查询策略规则
StrategyRuleEntity strategyRuleEntity = repository.queryStrategyRule(strategy, ruleWeight); StrategyRuleEntity strategyRuleEntity = repository.queryStrategyRule(strategy, ruleWeight);
......
...@@ -5,6 +5,7 @@ import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity; ...@@ -5,6 +5,7 @@ import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity; import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity; import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO; import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository; import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.IRaffleStrategy; import cn.bugstack.domain.strategy.service.IRaffleStrategy;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch; import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
...@@ -53,7 +54,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy { ...@@ -53,7 +54,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
.userId(userId) .userId(userId)
.strategyId(strategyId) .strategyId(strategyId)
.build(), strategy.ruleModels()); .build(), strategy.ruleModels());
log.info("ruleActionEntity:{}", JSON.toJSONString(ruleActionEntity));
if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntity.getCode())) { if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntity.getCode())) {
if (DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) { if (DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) {
...@@ -63,7 +63,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy { ...@@ -63,7 +63,6 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
.build(); .build();
} else if (DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode().equals(ruleActionEntity.getRuleModel())) { } else if (DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode().equals(ruleActionEntity.getRuleModel())) {
// 权重根据返回的信息进行抽奖 // 权重根据返回的信息进行抽奖
System.out.println("权重抽奖");
RuleActionEntity.RaffleBeforeEntity raffleBeforeEntity = ruleActionEntity.getData(); RuleActionEntity.RaffleBeforeEntity raffleBeforeEntity = ruleActionEntity.getData();
String ruleWeightValueKey = raffleBeforeEntity.getRuleWeightValueKey(); String ruleWeightValueKey = raffleBeforeEntity.getRuleWeightValueKey();
Integer awardId = strategyDispatch.getRandomAwardId(strategyId,ruleWeightValueKey); Integer awardId = strategyDispatch.getRandomAwardId(strategyId,ruleWeightValueKey);
...@@ -74,13 +73,31 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy { ...@@ -74,13 +73,31 @@ public abstract class AbstractRaffleStrategy implements IRaffleStrategy {
} }
// 4. 默认抽奖流程 // 4. 默认抽奖流程
System.out.println("默认抽奖");
Integer awardId = strategyDispatch.getRandomAwardId(strategyId); Integer awardId = strategyDispatch.getRandomAwardId(strategyId);
// 5. 查询奖品规则「抽奖中(拿到奖品ID时,过滤规则)、抽奖后(扣减完奖品库存后过滤,抽奖中拦截和无库存则走兜底)」
StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModelVO(strategyId, awardId);
// 6. 抽奖中 - 规则过滤
RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionCenterEntity = this.doCheckRaffleCenterLogic(RaffleFactorEntity.builder()
.userId(userId)
.strategyId(strategyId)
.awardId(awardId)
.build(), strategyAwardRuleModelVO.raffleCenterRuleModelList());
if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionCenterEntity.getCode())){
log.info("【临时日志】中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。");
return RaffleAwardEntity.builder()
.awardDesc("中奖中规则拦截,通过抽奖后规则 rule_luck_award 走兜底奖励。")
.build();
}
return RaffleAwardEntity.builder() return RaffleAwardEntity.builder()
.awardId(awardId) .awardId(awardId)
.build(); .build();
} }
protected abstract RuleActionEntity<RuleActionEntity.RaffleCenterEntity> doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics);
protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity factorEntity, String... logics); protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity factorEntity, String... logics);
} }
...@@ -36,9 +36,39 @@ public class DefaultRaffleStrategy extends AbstractRaffleStrategy{ ...@@ -36,9 +36,39 @@ public class DefaultRaffleStrategy extends AbstractRaffleStrategy{
public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) { public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch) {
super(repository, strategyDispatch); super(repository, strategyDispatch);
} }
@Override
protected RuleActionEntity<RuleActionEntity.RaffleCenterEntity> doCheckRaffleCenterLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
if (logics == null || 0 == logics.length) return RuleActionEntity.<RuleActionEntity.RaffleCenterEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
Map<String, ILogicFilter<RuleActionEntity.RaffleCenterEntity>> logicFilterGroup = logicFactory.openLogicFilter();
RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionEntity = null;
for (String ruleModel : logics) {
ILogicFilter<RuleActionEntity.RaffleCenterEntity> logicFilter = logicFilterGroup.get(ruleModel);
RuleMatterEntity ruleMatterEntity = new RuleMatterEntity();
ruleMatterEntity.setUserId(raffleFactorEntity.getUserId());
ruleMatterEntity.setAwardId(raffleFactorEntity.getAwardId());
ruleMatterEntity.setStrategyId(raffleFactorEntity.getStrategyId());
ruleMatterEntity.setRuleModel(ruleModel);
ruleActionEntity = logicFilter.filter(ruleMatterEntity);
// 非放行结果则顺序过滤
log.info("抽奖中规则过滤 userId: {} ruleModel: {} code: {} info: {}", raffleFactorEntity.getUserId(), ruleModel, ruleActionEntity.getCode(), ruleActionEntity.getInfo());
if (!RuleLogicCheckTypeVO.ALLOW.getCode().equals(ruleActionEntity.getCode())) return ruleActionEntity;
}
return ruleActionEntity;
}
@Override @Override
protected RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) { protected RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLogic(RaffleFactorEntity raffleFactorEntity, String... logics) {
if (logics == null || 0 == logics.length) return RuleActionEntity.<RuleActionEntity.RaffleBeforeEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
log.info("raffleFactorEntity:{},logics:{}", JSON.toJSONString(raffleFactorEntity),logics); log.info("raffleFactorEntity:{},logics:{}", JSON.toJSONString(raffleFactorEntity),logics);
Map<String, ILogicFilter<RuleActionEntity.RaffleBeforeEntity>> logicFilterGroup = logicFactory.openLogicFilter(); Map<String, ILogicFilter<RuleActionEntity.RaffleBeforeEntity>> logicFilterGroup = logicFactory.openLogicFilter();
......
...@@ -40,13 +40,23 @@ public class DefaultLogicFactory { ...@@ -40,13 +40,23 @@ public class DefaultLogicFactory {
@AllArgsConstructor @AllArgsConstructor
public enum LogicModel { public enum LogicModel {
RULE_WIGHT("rule_weight","【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"), RULE_WIGHT("rule_weight", "【抽奖前规则】根据抽奖权重返回可抽奖范围KEY", "before"),
RULE_BLACKLIST("rule_blacklist","【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回"), RULE_BLACKLIST("rule_blacklist", "【抽奖前规则】黑名单规则过滤,命中黑名单则直接返回", "before"),
RULE_LOCK("rule_lock", "【抽奖中规则】抽奖n次后,对应奖品可解锁抽奖", "center"),
RULE_LUCK_AWARD("rule_luck_award", "【抽奖后规则】抽奖n次后,对应奖品可解锁抽奖", "after"),
; ;
private final String code; private final String code;
private final String info; private final String info;
private final String type;
public static boolean isCenter(String code){
return "center".equals(LogicModel.valueOf(code.toUpperCase()).type);
}
public static boolean isAfter(String code){
return "after".equals(LogicModel.valueOf(code.toUpperCase()).type);
}
} }
......
package cn.bugstack.domain.strategy.service.rule.impl;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.entity.RuleMatterEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.annotation.LogicStrategy;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import cn.bugstack.domain.strategy.service.rule.factory.DefaultLogicFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @description: 用户抽奖n次后,对应奖品可解锁抽奖
* @author: hdr
* @PACKAGE_NAME: cn.bugstack.domain.strategy.service.raffle
* @DATE: 2024/4/16
*/
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.RULE_LOCK)
public class RuleLockLogicFilter implements ILogicFilter<RuleActionEntity.RaffleCenterEntity> {
@Resource
private IStrategyRepository repository;
// 测试数据
private Long userRaffleCount = 0L;
@Override
public RuleActionEntity<RuleActionEntity.RaffleCenterEntity> filter(RuleMatterEntity ruleMatterEntity) {
log.info("规则过滤-次数锁 userId:{} strategyId:{} ruleModel:{}", ruleMatterEntity.getUserId(), ruleMatterEntity.getStrategyId(), ruleMatterEntity.getRuleModel());
// 查询规则值配置;当前奖品ID,抽奖中规则对应的校验值。如;1、2、6
String ruleValue = repository.queryStrategyRuleValue(ruleMatterEntity.getStrategyId(), ruleMatterEntity.getAwardId(), ruleMatterEntity.getRuleModel());
long raffleCount = Long.parseLong(ruleValue);
// 用户抽奖次数大于规则限定值,规则放行
if (userRaffleCount>= raffleCount) {
return RuleActionEntity.<RuleActionEntity.RaffleCenterEntity>builder()
.code(RuleLogicCheckTypeVO.ALLOW.getCode())
.info(RuleLogicCheckTypeVO.ALLOW.getInfo())
.build();
}
// 用户抽奖次数小于规则限定值,规则拦截
return RuleActionEntity.<RuleActionEntity.RaffleCenterEntity>builder()
.code(RuleLogicCheckTypeVO.TAKE_OVER.getCode())
.info(RuleLogicCheckTypeVO.TAKE_OVER.getInfo())
.build();
}
}
...@@ -22,4 +22,11 @@ public interface IStrategyAwardDao { ...@@ -22,4 +22,11 @@ public interface IStrategyAwardDao {
* @return * @return
*/ */
List<StrategyAward> queryStrategyAwardListByStrategyId(@Param("strategyId") Long strategyId); List<StrategyAward> queryStrategyAwardListByStrategyId(@Param("strategyId") Long strategyId);
/**
* 查询ruleModels
* @param strategyAward
* @return
*/
String queryStrategyAwardRuleModels(StrategyAward strategyAward);
} }
...@@ -12,6 +12,7 @@ import java.util.Date; ...@@ -12,6 +12,7 @@ import java.util.Date;
*/ */
@Data @Data
public class Award { public class Award {
/** 自增ID */ /** 自增ID */
private Long id; private Long id;
/** 抽奖奖品ID - 内部流转使用 */ /** 抽奖奖品ID - 内部流转使用 */
......
...@@ -102,6 +102,7 @@ public class RedisService implements IRedisService { ...@@ -102,6 +102,7 @@ public class RedisService implements IRedisService {
return redissonClient.getMap(key); return redissonClient.getMap(key);
} }
@Override
public void addToMap(String key, String field, String value) { public void addToMap(String key, String field, String value) {
RMap<String, String> map = redissonClient.getMap(key); RMap<String, String> map = redissonClient.getMap(key);
map.put(field, value); map.put(field, value);
......
...@@ -3,6 +3,7 @@ package cn.bugstack.infrastructure.persistent.repository; ...@@ -3,6 +3,7 @@ package cn.bugstack.infrastructure.persistent.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity; import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity; import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity; import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity;
import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository; import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao; import cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.persistent.dao.IStrategyDao; import cn.bugstack.infrastructure.persistent.dao.IStrategyDao;
...@@ -16,6 +17,7 @@ import com.alibaba.fastjson.JSON; ...@@ -16,6 +17,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
...@@ -55,9 +57,10 @@ public class StrategyRepository implements IStrategyRepository { ...@@ -55,9 +57,10 @@ public class StrategyRepository implements IStrategyRepository {
public List<StrategyAwardEntity> queryStrategyAwardList(Long strategy) { public List<StrategyAwardEntity> queryStrategyAwardList(Long strategy) {
// 1. 查询redis中是否有保存策略数据有的话直接返回 // 1. 查询redis中是否有保存策略数据有的话直接返回
String cacheKey = Constants.RedisKey.STRATEGY_AWARD_KEY + strategy; String cacheKey = Constants.RedisKey.STRATEGY_AWARD_KEY + strategy;
Object json = redisService.getValue(cacheKey); List<StrategyAwardEntity> strategyAwardEntities = redisService.getValue(cacheKey);
List<StrategyAwardEntity> strategyAwardEntities = JSON.parseArray(json.toString(), StrategyAwardEntity.class);
if (strategyAwardEntities != null && !strategyAwardEntities.isEmpty()) { if (strategyAwardEntities != null && strategyAwardEntities.size() != 0) {
// List<StrategyAwardEntity> strategyAwardEntities = JSON.parseArray(json.toString(), StrategyAwardEntity.class);
return strategyAwardEntities; return strategyAwardEntities;
} }
...@@ -75,7 +78,7 @@ public class StrategyRepository implements IStrategyRepository { ...@@ -75,7 +78,7 @@ public class StrategyRepository implements IStrategyRepository {
// 2.1 保存到redis中 // 2.1 保存到redis中
// redisService.setValue(cacheKey, strategyAwardEntityList); redisService.setValue(cacheKey, strategyAwardEntityList);
return strategyAwardEntityList; return strategyAwardEntityList;
} }
...@@ -103,21 +106,33 @@ public class StrategyRepository implements IStrategyRepository { ...@@ -103,21 +106,33 @@ public class StrategyRepository implements IStrategyRepository {
public StrategyEntity queryStrategyEntityByStrategyId(Long strategyId) { public StrategyEntity queryStrategyEntityByStrategyId(Long strategyId) {
// 1. 优先从缓存获取 // 1. 优先从缓存获取
String cacheKey = Constants.RedisKey.STRATEGY_KEY + strategyId; String cacheKey = Constants.RedisKey.STRATEGY_KEY + strategyId;
Map<String,Object> maps = redisService.getValue(cacheKey);
StrategyEntity strategyEntity = StrategyEntity.builder() StrategyEntity strategyEntity = new StrategyEntity();
.strategyId(Long.parseLong(maps.get("strategyId").toString())) StrategyEntity maps = redisService.getValue(cacheKey);
.strategyDesc((String) maps.get("strategyDesc")) if (null != maps){
.ruleModels((String) maps.get("ruleModels")) // strategyEntity = StrategyEntity.builder()
.build(); // .strategyId(Long.parseLong(maps.get("strategyId").toString()))
if (null != strategyEntity) return strategyEntity; // .strategyDesc((String) maps.get("strategyDesc"))
// .ruleModels((String) maps.get("ruleModels"))
// .build();
return maps;
}
// 2. 没有数据从数据库获取 // 2. 没有数据从数据库获取
Strategy strategy = strategyDao.queryStrategyByStrategyId(strategyId); Strategy strategy = strategyDao.queryStrategyByStrategyId(strategyId);
strategyEntity = StrategyEntity.builder() strategyEntity.setStrategyId(strategy.getStrategyId());
.strategyId(strategy.getStrategyId()) if (StringUtils.isNotBlank(strategy.getRuleModels())) {
.strategyDesc(strategy.getStrategyDesc()) strategyEntity.setRuleModels(strategy.getRuleModels());
.ruleModels(strategy.getRuleModels()) }
.build(); strategyEntity.setStrategyDesc(strategy.getStrategyDesc());
// = StrategyEntity.builder()
// .strategyId(strategy.getStrategyId())
// .strategyDesc(strategy.getStrategyDesc())
// .ruleModels(strategy.getRuleModels())
// .build();
// 3. 写入缓存 // 3. 写入缓存
log.info("strategyEntity:{}",strategyEntity);
redisService.setValue(cacheKey,strategyEntity); redisService.setValue(cacheKey,strategyEntity);
return strategyEntity; return strategyEntity;
} }
...@@ -152,4 +167,14 @@ public class StrategyRepository implements IStrategyRepository { ...@@ -152,4 +167,14 @@ public class StrategyRepository implements IStrategyRepository {
return strategyRuleDao.queryStrategyRuleValue(strategyRule); return strategyRuleDao.queryStrategyRuleValue(strategyRule);
} }
@Override
public StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId) {
StrategyAward strategyAward = new StrategyAward();
strategyAward.setStrategyId(strategyId);
strategyAward.setAwardId(awardId);
String ruleModels = strategyAwardDao.queryStrategyAwardRuleModels(strategyAward);
return StrategyAwardRuleModelVO.builder().ruleModels(ruleModels).build();
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册