买赠活动配置与解析<二>
解析:
/// <summary> /// 获取产品配置规则(重复产品配置,将重复执行) /// </summary> /// <param name="type">类型JingDong,YinTai</param> /// <returns>规则列表</returns> public static IList<Model.LocalRule.ProductRule> GetProductRules(string type) { IList<Model.LocalRule.ProductRule> rules = new List<Model.LocalRule.ProductRule>(); #region 产品规则 重复产品配置,将重复执行 string r = ConfigurationManager.AppSettings[type + "StartProductRule"]; if ("1".Equals(r)) { r = ConfigurationManager.AppSettings[type + "ProductRule"]; //"(\\[(?<time>[^\\]]+)\\])?\\((?<pids>[^\\)]+)\\)\\[(?<rule>[^\\]]+)\\]" string pat = "(\\[(?<time>[^\\]]+)\\])?\\((?<pids>[^\\)]+)\\)\\[(?<rule>[^\\]]+)\\]"; string rpat = "\\((?<cd>[^,]*),{(?<rst>[^}]+)}\\)"; string pidpat = "(?<pf>[A-Za-z]*)(?<idn>\\d+)"; //string ripat = "(?<F>\\d*)(?<C>N)?\\s*(((?<O>-)|(?<O>\\+)|(?<O>\\u002a)|(?<O>/))\\s*(?<V>\\d+))?=?(?<pid>[^,]+)?"; if (!string.IsNullOrEmpty(r) && r.Length > 0 && Regex.IsMatch(r, pat)) { MatchCollection mc = Regex.Matches(r, pat); MatchCollection mc2 = null; string rule = null; string cd = null; string rst = null; IList<Model.LocalRule.Rule> rs = null; Model.LocalRule.Rule robj = null; Model.LocalRule.ProductRule pr = null; string[] pids = null; string time = null; string[] times = null; foreach (Match m in mc) { DateTime bTime = DateTime.MinValue; DateTime eTime = DateTime.MaxValue; rule = m.Result("${rule}"); if (rule.Length > 0 && Regex.IsMatch(rule, rpat)) { mc2 = Regex.Matches(rule, rpat); rs = new List<Model.LocalRule.Rule>(); #region rule int factor = -1;//倍率 char op = '-';//默认操作减号 bool notFactor = false; foreach (Match m2 in mc2) { robj = new Model.LocalRule.Rule(); cd = m2.Result("${cd}"); if (cd.Length > 0) { robj.Condition = new Model.LocalRule.RuleCondition(cd); if (factor == -1 && robj.Condition.Factor > 1) { factor = robj.Condition.Factor; op = robj.Condition.Operate; } robj.Condition.Expression = cd; //if (robj.Condition.Factor >= 1) //{ // if (factor == -1) // { // factor = robj.Condition.Factor; // op = robj.Condition.Operate; // } // robj.Condition.Expression = cd; //} //else //{ // continue;//条件倍率小于2则无效配置 //} } else if (factor > 1)//没有设置配置条件 { if (!notFactor) { robj.Condition = new Model.LocalRule.RuleCondition(); robj.Condition.Factor = factor; robj.Condition.Operate = op; robj.Condition.Expression = null; notFactor = true; } else { continue;//已包含没有条件则无效 } } else { continue;//第一个配置没有条件则无效配置 } rst = m2.Result("${rst}"); if (rst.Length > 0) { robj.Result = new Model.LocalRule.RuleResult(rst); robj.Expression = m2.Value; rs.Add(robj); } else { continue;//没有配置结果则无效配置 } } #endregion if (rs.Count > 0) { #region ReBuildRules if (notFactor) { Model.LocalRule.Rule nfrule = null; IList<Model.LocalRule.Rule> trlst = new List<Model.LocalRule.Rule>(); foreach (Model.LocalRule.Rule trobj in rs) { if (trobj.Condition.Expression == null)//区间条件 { nfrule = trobj; for (int i = 0; i < trobj.Condition.Factor; i++)//从0开始 { bool exist = false; foreach (Model.LocalRule.Rule trobj2 in rs) { if (trobj2.Condition.Expression != null && trobj2.Condition.Factor.Equals(trobj.Condition.Factor) && trobj2.Condition.Operate.Equals(trobj.Condition.Operate) && trobj2.Condition.Value2.Equals(i)) { exist = true; } } if (!exist)//不存在需要添加该项 { trlst.Add(new Model.LocalRule.Rule() { Condition = new Model.LocalRule.RuleCondition() { Factor = nfrule.Condition.Factor, Const = false, Operate = nfrule.Condition.Operate, Value2 = i, Expression = nfrule.Condition.Factor.ToString() + "N" + nfrule.Condition.Operate.ToString() + i.ToString() }, Result = nfrule.Result, Expression = "(" + nfrule.Condition.Factor.ToString() + "N" + nfrule.Condition.Operate.ToString() + i.ToString() + ",{" + nfrule.Result.Expression + "})" }); } } break; } } if (nfrule != null) { rs.Remove(nfrule); if (trlst.Count > 0) { foreach (Model.LocalRule.Rule trobj in trlst) { rs.Add(trobj); } } } } #endregion time = m.Result("${time}"); if (time != null && time.Trim().Length > 0) { times = time.Split('~'); DateTime tm = DateTime.Now; if (times.Length > 0 && times[0].Length > 0 && DateTime.TryParse(times[0], out tm)) { bTime = tm; } if (times.Length > 1 && times[1].Length > 0 && DateTime.TryParse(times[1], out tm)) { eTime = tm; } } rule = m.Result("${pids}"); pids = rule.Split(','); string[] tpids = null; string pf = null; string idn = null; string idn2 = null; string pf2 = null; Match m3 = null; Match m4 = null; foreach (string pid in pids) { if (pid.Length > 0) { if (pid.IndexOf("~") > 0) { tpids = pid.Split('~'); if (tpids.Length > 1 && tpids[0].Length > 0 && tpids[1].Length > 0 && Regex.IsMatch(tpids[0], pidpat) && Regex.IsMatch(tpids[1], pidpat)) { m3 = Regex.Match(tpids[0], pidpat); pf = m3.Result("${pf}"); m4 = Regex.Match(tpids[1], pidpat); pf2 = m4.Result("${pf}"); if (pf.Equals(pf2) || (pf.Length > 0 && pf2.Length == 0))//是否可以递增 { idn = m3.Result("${idn}"); idn2 = m4.Result("${idn}"); int start = int.Parse(idn); int end = int.Parse(idn2); if (start > end) { start = end + 0 * (end = start);//交换两数 } for (; start <= end; start++) { pr = new Model.LocalRule.ProductRule(); pr.StartTime = bTime; pr.EndTime = eTime; pr.ProductID = pf + start.ToString().PadLeft(idn.Length, '0'); pr.Rules = rs; pr.RuleString = m.Value; rules.Add(pr); } } } } else { pr = new Model.LocalRule.ProductRule(); pr.StartTime = bTime; pr.EndTime = eTime; pr.ProductID = pid; pr.Rules = rs; pr.RuleString = m.Value; rules.Add(pr); } } } } } } } } #endregion return rules; } /// <summary> /// 返回在规则里的产品的回赠数量 /// </summary> /// <param name="rules">规则集</param> /// <param name="productid">产品编码</param> /// <param name="num">当前数量</param> /// <param name="rule">符合的规则</param>
/// <param name="otime">下单时间</param> /// <returns>回赠数量</returns> public static IList<KeyValuePair<string, int>> GetProductNum(IList<Model.LocalRule.ProductRule> rules, string productid, int num, out IList<string> rule,string otime) { DateTime tm = DateTime.Now; if (!DateTime.TryParse(otime, out tm)) { tm = DateTime.Now; } IList<KeyValuePair<string, int>> rst = new List<KeyValuePair<string, int>>(); rule = new List<string>(); if (rules != null && rules.Count > 0) { int n = 0; foreach (Model.LocalRule.ProductRule pr in rules) { if (pr.StartTime <= tm && pr.EndTime >= tm) { #region GetRule if (pr.ProductID.Equals(productid)) { foreach (Model.LocalRule.Rule r in pr.Rules) { if (r.Condition.Const)//常数 { if (r.Condition.Factor == num) { //N n = (int)Math.Ceiling((decimal)r.Condition.Factor / pr.Rules[0].Condition.Factor); foreach (KeyValuePair<Model.LocalRule.RuleCondition, string> prr in r.Result.Rules) { int tn = GetResultNum(prr.Key, n); if (tn > 0) { rule.Add("规则:" + pr.RuleString + ";下单时间:" + otime + ";原始数目:" + num.ToString() + ";应用数目:" + tn.ToString()); if (string.IsNullOrEmpty(prr.Value) || prr.Value.Equals(productid)) { num += tn; } rst.Add(new KeyValuePair<string, int>(prr.Value, tn)); } } break; } } else { //规则验证 if (ValidRuleNum(r, num, out n)) { foreach (KeyValuePair<Model.LocalRule.RuleCondition, string> prr in r.Result.Rules) { int tn = GetResultNum(prr.Key, n); if (tn > 0) { rule.Add("规则:" + pr.RuleString + ";下单时间:" + otime + ";原始数目:" + num.ToString() + ";应用数目:" + tn.ToString()); if (string.IsNullOrEmpty(prr.Value) || prr.Value.Equals(productid)) { num += tn; } rst.Add(new KeyValuePair<string, int>(prr.Value, tn)); //rule.Add(prr.Key.Expression); } } break; } } } } #endregion } } } return rst; } /// <summary> /// 验证产品数目是否符合规则并返回结果数 /// </summary> /// <param name="r">规则</param> /// <param name="num">产品数目</param> /// <param name="rst">结果</param> /// <returns>true or false</returns> static bool ValidRuleNum(Model.LocalRule.Rule r, int num, out int rst) { bool v = false; rst = 0; switch (r.Condition.Operate) { case '-': v = (num + r.Condition.Value2) % r.Condition.Factor == 0; rst = num + r.Condition.Value2; break; case '+': v = (num - r.Condition.Value2) % r.Condition.Factor == 0; rst = num - r.Condition.Value2; break; case '*': v = (num / r.Condition.Value2) % r.Condition.Factor == 0; rst = num / r.Condition.Value2; break; case '/': v = (num * r.Condition.Value2) % r.Condition.Factor == 0; rst = num * r.Condition.Value2; break; } v = v && rst > 0; if (v) { //求出的N rst = rst / r.Condition.Factor; } return v; } /// <summary> /// 获取产品赠送信息 /// </summary> /// <param name="ruleCondition">赠送条件</param> /// <param name="n">N的值</param> /// <returns>计算后数值</returns> private static int GetResultNum(Model.LocalRule.RuleCondition ruleCondition, int n) { if (ruleCondition.Const) { return ruleCondition.Factor; } else { switch (ruleCondition.Operate) { case '-': return ruleCondition.Factor * n - ruleCondition.Value2; case '+': return ruleCondition.Factor * n + ruleCondition.Value2; case '*': return ruleCondition.Factor * n * ruleCondition.Value2; case '/': return ruleCondition.Factor * n / ruleCondition.Value2; } } return 0; }
测试程序:
IList<Model.LocalRule.ProductRule> rules = TBTool.BLL.LocalInfo.GetProductRules("TaoBao"); IList<string> strs = null; IList<KeyValuePair<string, int>> nums = null; string pid = null; string pno = "rg000816"; string dateTime = "2012-08-22 11:00:00"; StringBuilder nsb = new StringBuilder(); for (int i = 1; i < 23; i++) { nums = TBTool.BLL.LocalInfo.GetProductNum(rules, pno, i, out strs, dateTime); if (nums.Count > 0) { for (int j = 0; j < nums.Count; j++) { pid = nums[j].Key; if (string.IsNullOrEmpty(pid)) { pid = pno; } if (j > 0) { nsb.Append(","); } nsb.AppendLine(pno + ":" + i.ToString() + " " + strs[j] + " pid:" + pid + " num:" + nums[j].Value); } } } MessageBox.Show(nsb.ToString());
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通