1. 程式人生 > 其它 >一個簡單的規則引擎例子

一個簡單的規則引擎例子

  本例使用的規則引擎包是RulesEngine,關於RulesEngine的介紹,請自行補充,這裡只是一個極簡單使用場景。

  例子大體就是使用者有一些優惠券,系統會根據使用者訂單情況,篩選可以使用的優惠券供使用者選擇,使用者選擇後會計算出優惠後金額。

  程式碼相對簡單,就不一一介紹了,奉上service中的程式碼:

using Microsoft.Extensions.Logging;
using RulesEngine.Extensions;
using RulesEngine.Models;
using System;
using System.Collections.Generic;
using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace RulesEngineSample.Services { public class CouponService : ICouponService { private readonly ILogger<CouponService> _logger; private readonly List<Coupon> _userCoupons;
private readonly Order _order; private readonly User _user; public CouponService(ILogger<CouponService> logger) { _logger = logger; //假裝使用者用的優惠券 _userCoupons = new List<Coupon>() { new Coupon { ID
= 1, Code="YH01", Name = "滿500減20", BeginTime = DateTime.Parse("2021-01-01"), EndTime = DateTime.Parse("2021-06-01"), Expression = "input1.Details.Sum(s => s.Price * Convert.ToDecimal(s.Quantity))>= 500", Symbol="-", Number=20 }, new Coupon { ID = 2, Code="YH02", Name = "新人5元券", BeginTime = DateTime.Parse("2021-01-01"), EndTime = DateTime.Parse("2021-06-01"), Expression = "input1.Details.Count>0", Symbol="-", Number=5 }, new Coupon { ID = 3, Code="YH03", Name = "商品C五折", BeginTime = DateTime.Parse("2021-01-01"), EndTime = DateTime.Parse("2021-06-01"), Expression = "input1.Details.Where(s=>s.GoodsID==\"SP0000003\").Count()>0", Symbol="*", Number=0.5f, GoodsID="SP0000003" }, }; //假裝當前使用者的訂單 _order = new Order { OrderNo = "NO00000001", OrderTime = DateTime.Now, Details = new List<Detail> { new Detail{ GoodsID="SP0000001", Name="商品A", Price=12.5m, Quantity=3}, new Detail{ GoodsID="SP0000002", Name="商品B", Price=100m, Quantity=4}, new Detail{ GoodsID="SP0000003", Name="商品C", Price=22.3m, Quantity=5}, } }; _user = new User { ID = 1, UserName = "zhangsan" }; } /// <summary> /// 適配優惠券 /// </summary> /// <returns></returns> public async Task<string> SelectCouponAsync() { var workRules = new RulesEngine.Models.WorkflowRules(); workRules.WorkflowName = "優惠券"; var rules = new List<Rule>(); foreach (var coupon in _userCoupons.Where(s => s.BeginTime < DateTime.Now && s.EndTime > DateTime.Now)) { var rule = new Rule { RuleName = coupon.Name, SuccessEvent = coupon.Code, ErrorMessage = "規則應用失敗", ErrorType = ErrorType.Error, RuleExpressionType = RuleExpressionType.LambdaExpression, Expression = coupon.Expression }; rules.Add(rule); } workRules.Rules = rules; var rulesEngine = new RulesEngine.RulesEngine(new WorkflowRules[] { workRules }, _logger, new ReSettings()); var ruleResults = await rulesEngine.ExecuteAllRulesAsync("優惠券", _order, _user); // var valueCoupons = new List<string>(); //處理結果 var discountCoupons = new StringBuilder(); foreach (var ruleResult in ruleResults) { if (ruleResult.IsSuccess) { discountCoupons.AppendLine($"可以使用的優惠券 “{_userCoupons.SingleOrDefault(s => s.Code == ruleResult.Rule.SuccessEvent)?.Name}”, Code是:{ruleResult.Rule.SuccessEvent}"); //valueCoupons.Add(ruleResult.Rule.SuccessEvent); } } //resultList.OnSuccess((eventName) => //{ // discountOffered += $"可以使用的優惠券“{userCoupons.SingleOrDefault(s => s.Code == eventName)?.Name}”,Code是:{eventName} "; //}); ruleResults.OnFail(() => { discountCoupons.AppendLine("您沒有適合的優惠券!"); }); return discountCoupons.ToString(); } /// <summary> /// 計算訂單支付總額 /// </summary> /// <param name="code"></param> /// <returns></returns> public string GetOrderAmount(string code) { var selectCoupon = _userCoupons.SingleOrDefault(s => s.Code == code); var orderAmount = 0m; switch (selectCoupon.Symbol) { case "-": orderAmount = _order.Details.Sum(s => s.Price * Convert.ToDecimal(s.Quantity)) - Convert.ToDecimal(selectCoupon.Number); break; case "*": if (!string.IsNullOrWhiteSpace(selectCoupon.GoodsID)) { orderAmount = _order.Details.Sum(s => s.Price * Convert.ToDecimal(s.Quantity)); var detail = _order.Details.SingleOrDefault(s => s.GoodsID == selectCoupon.GoodsID); if (detail != null) { orderAmount -= detail.Price * Convert.ToDecimal(detail.Quantity) * Convert.ToDecimal(1 - selectCoupon.Number); } } else { orderAmount = _order.Details.Sum(s => s.Price * Convert.ToDecimal(s.Quantity)) * Convert.ToDecimal(selectCoupon.Number); } break; } return $"訂單總金額:{_order.Details.Sum(s => s.Price * Convert.ToDecimal(s.Quantity)) },優惠後請支付:{orderAmount}"; } } public class Coupon { public int ID { get; set; } public string Code { get; set; } public string Name { get; set; } public DateTime BeginTime { get; set; } public DateTime EndTime { get; set; } public string Expression { get; set; } public string Symbol { get; set; } public float Number { get; set; } public string GoodsID { get; set; } } public class User { public int ID { get; set; } public string UserName { get; set; } } public class Order { public string OrderNo { get; set; } public DateTime OrderTime { get; set; } public List<Detail> Details { get; set; } } public class Detail { public string GoodsID { get; set; } public float Quantity { get; set; } public decimal Price { get; set; } public string Name { get; set; } } }

api /selectcoupon是查詢可使用的優惠券

/getamount按優惠券code,計算本次訂單的應付金額:

優惠券YH01

優惠券YH02

優惠券YH03

  想要更快更方便的瞭解相關知識,可以關注微信公眾號

****歡迎關注我的asp.net core系統課程****
《asp.net core精要講解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core專案實戰》 https://ke.qq.com/course/291868
《基於.net core微服務》 https://ke.qq.com/course/299524