买赠活动配置与解析<二>

解析:

        /// <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());
posted @ 2012-08-26 09:18  z.seven  阅读(310)  评论(0编辑  收藏  举报