1、地址:QLExpress(先看一遍demo)
2、 规则中心使用规则表达式
@Test
public void t() throws Exception {
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<>();
context.put("a", Boolean.TRUE);
context.put("l", Boolean.TRUE);
context.put("lo", Boolean.TRUE);
context.put("s", Boolean.FALSE);
String express = "a&&l&&lo&&s";//false
// String express = "a&&llo||s"; //true
Object res = runner.execute(express, context, null, true, false);
System.out.println(res);
}
@Test
public void t() throws Exception {
DefaultContext<String, MetaRuleResult> context = new DefaultContext<>();
context.put("o", MetaRuleResult.builder().skuId(1L).result(true).metaRule("o").failureReason("").build());
context.put("l", MetaRuleResult.builder().skuId(1L).result(false).metaRule("l").failureReason("锁库存不可更改").build());
context.put("s", MetaRuleResult.builder().skuId(1L).result(true).metaRule("s").failureReason("").build());
context.put("w", MetaRuleResult.builder().skuId(1L).result(false).metaRule("w").failureReason("售罄预警").build());
context.put("lo", MetaRuleResult.builder().skuId(1L).result(true).metaRule("lo").failureReason("").build());
context.put("llo", MetaRuleResult.builder().skuId(1L).result(false).metaRule("llo").failureReason("锁库且修改值小于等于OR值可以更改").build());
Object result;
DefaultContext<String, Object> computeContext = new DefaultContext<>();
for (Map.Entry<String, MetaRuleResult> entry : context.entrySet()) {
computeContext.put(entry.getKey(), entry.getValue().getResult());
}
String ruleExpress = "o&&l&&s&&w&&lo&&llo";
result = runner.execute(ruleExpress, computeContext, null, true, false);
Boolean bResult = (Boolean) result;
System.out.println(bResult);//false
String failReason = buildFailureReason(ruleExpress, context);
System.out.println(failReason);//售罄预警且锁库存不可更改且锁库且修改值小于等于OR值可以更改
}
context
key为规则rule内容eg:”a“允许、"llo"锁库且小于OR允许、"s"即20点后修改值小于可履约库存允许修改,
value为,rpc查询依赖的各个数据,判断当前sku,是否满足这个规则,满足为true,不满足为false
eg:key = “s”,此时为20点后修改最大售卖量,想把最大售卖量从50 -> 30,计算发现可履约库存为40,30 < 40,则允许修改
express
表达式为修改规则的组合;
db中规则为"a&&llo"、"llo&&s&&t"等等,这个是根据由温层+用户+二级品类id决定的规则本身
execute执行
当满足所有的规则,全部为true,则本次此sku允许修改最大售卖量,一个规则不满足,最终结果res都会为false,不允许修改最大售卖量
然后将每个规则,不满足的原因都记录下来 ”且“,返回给档期展示即可。
1、按照网店 + 销售日期维度并发处理
2、db获取规则表达式
3、填充必要数据(履约日期、算法、锁库等) -:策略模式,类似noDependenceServices 和 dependenceServices
4、规则计算
规则计算步骤1:
定义context,key为规则表达式,val为每个规则的校验结果体。
每个规则根据传入的数据,取计算是否允许结果体(规则表达式、是否允许修改、不允许修改原因),这里计算每个规则的结果体也是使用的策略模式(类型returnplan根据不同taskCode的status调用对应的Servie去查询一样)
DefaultContext<String, MetaRuleResult> context.put(metaRuleType.getCode(), this.metaRuleCalculate(metaRuleType.getCode(), skuRuleResult.getSkuRuleComputeData()))
规则计算步骤2:
定义新的computeContext,key为规则表达式,val为是否允许修改的true、false,然后使用规则引擎QLExpress计算得出最终结果(llo&&w),是否允许修改,不允许修改的所有原因是什么(每个规则不允许修改的原因可配置,所有不允许修改的原因叠加)
DefaultContext<String, Object> computeContext = new DefaultContext<>();
for (Map.Entry<String, MetaRuleResult> entry : context.entrySet()) {
computeContext.put(entry.getKey(), entry.getValue().getResult());
}
result = runner.execute(ruleExpress, computeContext, null, true, false);
Boolean bResult = (Boolean) result;
skuRuleResult.setResult(bResult);
skuRuleResult.setFailureReason(bResult ? "" : buildFailureReason(ruleExpress, context));