日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

阿里开源规则引擎QLExpress-入门实战

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 阿里开源规则引擎QLExpress-入门实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

規則引擎,顧名思義是針對我們業務系統中普世的規則進行統一管理,通過該引擎進行調度計算,可以動態調整規則的表達式內容,而不影響業務系統代碼,常見的業務典型場景有電商中促銷活動,單品折扣、整場活動滿減或滿折

規則引擎

常用的規則引擎目前主要有Drools、Aviator、Easyrule、QLExpress,如下表格是對這些規則引擎的分析對比:

結合本人實際項目,我們的項目業務屬性是電商,對性能要求比較高,因此發現阿里開源的QLExpress更適合現實的訴求,下面的章節將以電商促銷活動的例子介紹QLExpress如何落地實操到業務代碼中的

電商促銷活動示例

比如我們的購物車現在有兩個商品,對應的商品SKU分別為11120781和11120782,商品11120781參與的單品促銷優惠活動,11120782參與的是單品促銷打折活動,假設這兩個商品來自同一個店家,店家給的運費優惠是滿100減50關于兩個活動規則的介紹如下:

單品促銷優惠
該活動是在商品價格基礎上優惠xxx元,比如商品原價為150,促銷優惠50元,則優惠后的金額為150-50=100

單品促銷打折
該活動是在商品價格基礎上進行折扣,比如商品原價為150,促銷打折5折,則優惠后的金額為150*0.5=75

第一步 引入依賴包

如下圖所示,引入QLExpress的包

<dependency><groupId>com.alibaba</groupId><artifactId>QLExpress</artifactId><version>3.2.0</version></dependency>

編寫針對某一類活動規則的業務接口

此接口主要處理同一類型規則的邏輯,以上述的單品促銷為例,代碼示例如下:

/*** 查詢商品促銷活動匹配單品促銷規則計算后的優惠金額** @param promotionList 參與的促銷活動* @param productPrice 商品價格* @return*/private List<Double> querySinglePromotionPrice(List<Promotion> promotionList, double productPrice) {List<Double> nicePrices = Lists.newArrayList();DefaultContext<String, Object> context = new DefaultContext<>();ExpressRunner expressRunner = new ExpressRunner();promotionList = promotionList.stream().filter(r -> "singlePromotion".equals(r.getPromotionType())).collect(Collectors.toList());for (Promotion promotion : promotionList) {//查詢促銷活動對應的規則模版配置信息RuleTemplate template = queryRuleTemplate(promotion.getPromotionType());String express = template.getExpress();context.put("price", productPrice);context.put("promotionType", promotion.getPromotionWay());context.put("promotionValue", Double.parseDouble(promotion.getPromotionValue()));System.out.println("參與促銷活動【" + promotion.getPromotionName() + "】優惠前的商品金額:" + productPrice);Object execute = null;try {execute = expressRunner.execute(express, context, null, true, true);} catch (Exception e) {System.out.println("計算規則[" + template.getTemplateName() + "]時發生異常,原因:" + e.getMessage());}System.out.println("優惠后的金額:" + execute);nicePrices.add((Double) execute);}return nicePrices;}

涉及到的運費計算,代碼示例如下:

private double queryMinShippingFree(List<Promotion> promotionList,double productPrice,double freeShipping ){DefaultContext<String, Object> context = new DefaultContext<>();double minShipping = 0.0;List<Double> niceShipping = Lists.newArrayList();ExpressRunner expressRunner = new ExpressRunner();promotionList = promotionList.stream().filter(r -> "freeShipping".equals(r.getPromotionType())).collect(Collectors.toList());for (Promotion promotion : promotionList) {RuleTemplate template = queryRuleTemplate(promotion.getPromotionType());String express = template.getExpress();String condition = promotion.getConditionConfig();context.put("price", productPrice);context.put("amount", Double.parseDouble(JSONObject.parseObject(condition).getString("amountCondition")));context.put("shippingPrice",freeShipping);context.put("promotionValue", Double.parseDouble(JSONObject.parseObject(condition).getString("promotionAmount")));System.out.println("參與促銷活動【" + promotion.getPromotionName() + "】優惠前的運費:" + freeShipping);Object execute = null;try {execute = expressRunner.execute(express, context, null, true, true);} catch (Exception e) {System.out.println("計算規則[" + template.getTemplateName() + "]時發生異常,原因:" + e.getMessage());}niceShipping.add((Double) execute);}if(niceShipping.isEmpty()){return minShipping;}minShipping = Collections.min(niceShipping);System.out.println("優惠后的運費:" + minShipping);return minShipping;}

封裝以上兩個方法,輸出購物車中的最終優惠金額,代碼示例如下:

/*** 計算最優促銷活動價格** @param cart 購物車信息* @param shippingFee 運費* @return 計算出最優價格* @throws Exception*/@Overridepublic double queryMinPromotionPrice(String cart,double shippingFee) {JSONArray cartArray = JSONObject.parseArray(cart);double sum = 0.0,sumNicePrice = 0.0,sumNiceShipping = 0.0;for(int i=0;i<cartArray.size();i++){double minNicePrice = 0.0d;String productCode = cartArray.getJSONObject(i).getString("productCode");double productPrice = cartArray.getJSONObject(i).getDoubleValue("price");//查詢商品參與的促銷活動List<Promotion> promotionList = queryPromotion(productCode);sum += productPrice;//根據促銷活動匹配的規則計算出優惠價格List<Double> nicePrices = querySinglePromotionPrice(promotionList, productPrice);//計算出最便宜的優惠價格minNicePrice = Collections.min(nicePrices);sumNicePrice +=minNicePrice;//運費double niceShipping = queryMinShippingFree(promotionList,productPrice,shippingFee);sumNiceShipping+=niceShipping;}sum = sum+shippingFee;System.out.println("參與促銷之前購物車結算價格為:"+sum);sumNicePrice = sumNicePrice+sumNiceShipping;System.out.println("參與促銷之后購物車結算價格金額:" + sumNicePrice);return sumNicePrice;}

暴露給外部的http接口,代碼示例如下:

@PostMapping("/queryMinPromotionPrice")public double queryMinPromotionPrice(String cart,double shippingFee) {System.out.println("開始獲取商品優惠金額");long startTime = System.currentTimeMillis();double minPrice = expressService.queryMinPromotionPrice(cart,shippingFee);System.out.println("獲取商品優惠金額結束,耗時:"+(System.currentTimeMillis()-startTime)+"毫秒");return minPrice;}

以上的這行代碼 RuleTemplate template = queryRuleTemplate(promotion.getPromotionType());是代表規則表達式的模版,可以配置在數據看中,如下圖所示:

以上代碼,通過postman或者insomnia工具,執行結果如下圖所示:

執行過程打印log信息如下圖所示:

總結

以上是生活随笔為你收集整理的阿里开源规则引擎QLExpress-入门实战的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。