using System; using System.Collections.Generic; using System.Linq; using System.Data; using MySystem.Models.Main; using Library; using System.Threading; using Microsoft.Extensions.Hosting; using System.Threading.Tasks; namespace MySystem { public class ProfitHelper { public readonly static ProfitHelper Instance = new ProfitHelper(); private ProfitHelper() { } #region 消费队列(执行消费退款金额的统计) public void StartListenTrade() { Thread th = new Thread(StartListenTradeDo); th.IsBackground = true; th.Start(); } public void StartListenTradeDo() { while (true) { string orderidstring = RedisDbconn.Instance.RPop("ConsumerOrders:Divi:1:List"); if (!string.IsNullOrEmpty(orderidstring)) { ReturnStat(orderidstring, 1); } else { Thread.Sleep(60000); } } } public void StartListenWxTrade() { Thread th = new Thread(StartListenWxTradeDo); th.IsBackground = true; th.Start(); } public void StartListenWxTradeDo() { while (true) { string orderidstring = RedisDbconn.Instance.RPop("ConsumerOrders:Divi:2:List"); if (!string.IsNullOrEmpty(orderidstring)) { ReturnStat(orderidstring, 2); } else { Thread.Sleep(10000); } } } public void ReturnStat(string orderidstring, int PayMode) { int OrderId = int.Parse(function.CheckInt(orderidstring)); WebCMSEntities db = new WebCMSEntities(); using (var tran = db.Database.BeginTransaction()) { try { ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.Id == OrderId); if (order != null) { decimal PayMoney = order.PayMoney; int MerchantId = order.MerchantId; MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == MerchantId); if (merchant != null) { int UserId = merchant.UserId; List customTagSets = db.CustomTagSet.ToList(); //获取公用配置参数集和 //获取参数 CustomTagSet profitPercentSet = customTagSets.FirstOrDefault(m => m.Tags == "CusumerProfitPercent") ?? new CustomTagSet(); decimal profitPercent = decimal.Parse(function.CheckNum(profitPercentSet.Contents)); //基于收款金额的总分润比例; CustomTagSet cusumerFeePercentSet = customTagSets.FirstOrDefault(m => m.Tags == "CusumerFeePercent") ?? new CustomTagSet(); decimal cusumerFeePercent = decimal.Parse(function.CheckNum(cusumerFeePercentSet.Contents)); //费率; CustomTagSet minProfitSet = customTagSets.FirstOrDefault(m => m.Tags == "MinProfit") ?? new CustomTagSet(); decimal minProfit = decimal.Parse(function.CheckNum(minProfitSet.Contents)); //最小分润值; MerchantParamSet set = Newtonsoft.Json.JsonConvert.DeserializeObject(order.SeoDescription); int DiviPersons = set.DiviPersons; //单笔订单分红人数 decimal DiviPercent = set.DiviPercent; //单人最大分红比例 int ProfitDays = set.ProfitDays; //分红期限(天) decimal GetPercent = set.GetPercent / 100; //商家实收比例 decimal MinPayMoney = set.MinPayMoney; //订单参与门槛 int IsAll = set.IsAll; //是否收全额 // decimal TotalActual = 0; if (IsAll == 0 && PayMoney >= MinPayMoney && GetPercent < 1) { decimal DiviMoney = PayMoney * (1 - GetPercent - cusumerFeePercent - profitPercent); if (DiviMoney > 0) { RedisDbconn.Instance.AddRightList("ConsumerOrders:Divi:" + PayMode + ":" + order.MerchantId, order); DiviMoney = DiviMoney / DiviPersons; List deletes = new List(); long CurDiviPersons = DiviPersons; long QueueCount = RedisDbconn.Instance.Count("ConsumerOrders:Divi:" + PayMode + ":" + MerchantId); long CurQueueCount = QueueCount; // int CheckNum = 0; //判断活动人数是否大于当前队列订单数来确认while循环的数量,如果是就少循环一次,判处自己的订单名额 if (CurDiviPersons >= CurQueueCount) { CurDiviPersons = CurQueueCount; } if (DiviPersons < QueueCount) { QueueCount = DiviPersons; } decimal OtherMoney = 0; // 退款金额>最大退款金额-当前退款金额,次金额应归还给商户 // List orders = RedisDbconn.Instance.GetList("ConsumerOrders:Divi:" + PayMode + ":" + MerchantId); // foreach(ConsumerOrders sub in orders) // { // function.WriteLog(sub.Id.ToString(), "返现队列"); // } // function.WriteLog("\n\n", "返现队列"); // 减去自己付的订单 // CurDiviPersons = CurDiviPersons - 1; int OutCount = 0; // 出局人数 while (CurDiviPersons > 0) { ConsumerOrders suborder = RedisDbconn.Instance.RPop("ConsumerOrders:Divi:" + PayMode + ":" + MerchantId); if (suborder != null) { MerchantParamSet subset = Newtonsoft.Json.JsonConvert.DeserializeObject(order.SeoDescription); int subProfitDays = subset.ProfitDays; //分红期限(天) bool IsOut = suborder.UpdateDate.Value.AddDays(subProfitDays) < DateTime.Now ? true : false; if (suborder.CurDivi < suborder.MaxDivi && !IsOut) { //如果没过期并且当前退款金额没超过最大退款金额,就执行 decimal GetMoney = suborder.MaxDivi - suborder.CurDivi; decimal DiffMoney = 0; if (GetMoney >= DiviMoney) { GetMoney = DiviMoney; } else { DiffMoney = DiviMoney - GetMoney; } if (GetMoney > minProfit) { suborder.CurDivi += GetMoney; if (DiffMoney > 0) { OtherMoney += DiffMoney; } ConsumerProfit cprofit = db.ConsumerProfit.Add(new ConsumerProfit() { CreateDate = DateTime.Now, ConsumerId = suborder.ConsumerId, MerchantId = suborder.MerchantId, OrderId = suborder.Id, GetMoney = GetMoney, QueryCount = PayMode, Sort = OrderId, SeoTitle = suborder.OrderNo, SeoKeyword = suborder.PayMoney.ToString(), }).Entity; db.SaveChanges(); MerchantAddInfo merchantAdd = db.MerchantAddInfo.FirstOrDefault(m => m.Id == suborder.MerchantId) ?? new MerchantAddInfo(); // if(order.PayMode == 1) // { // AlipayFunction.Instance.Refund(suborder.SeoTitle, GetMoney.ToString("f2"), "门店分红", merchantAdd.AlipayAuthToken); // } // else // { // Dictionary dic = WeChatFunction.Instance.Refund(merchantAdd.SubMchid, GetMoney, suborder.PayMoney, suborder.OrderNo, DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8), "门店分红"); // } var info = HaoDaHelper.Instance.AggregatedPayRefund(merchantAdd.SubMchid, merchantAdd.AlipayPid, "HDTK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8), merchantAdd.AlipayAuthToken, GetMoney.ToString()); if (suborder.CurDivi < suborder.MaxDivi) { RedisDbconn.Instance.AddList("ConsumerOrders:Divi:" + PayMode + ":" + MerchantId, suborder); } else { OutCount += 1; } } } else { //否者计算人数不计入退款名额 CurDiviPersons += 1; } } CurDiviPersons -= 1; QueueCount = RedisDbconn.Instance.Count("ConsumerOrders:Divi:" + PayMode + ":" + MerchantId); if (QueueCount == 0) { CurDiviPersons = 0; } } // long DoCount = DiviPersons > (QueueCount + OutCount) ? DiviPersons - QueueCount : 0; // decimal MerchantGetMoney = PayMoney * GetPercent; // decimal DoMoney = DoCount * DiviMoney; // TotalActual = PayMoney * GetPercent + DoCount * DiviMoney + OtherMoney; // function.WriteLog("返现金额:" + DiviMoney + ";返现人数:" + DiviPersons + ";返现商户:" + TotalActual + ";返现溢出:" + OtherMoney + ";商户应得金额:" + MerchantGetMoney + ";返现差额:" + DoMoney + ";", "消费者返现日志"); //代理商分润 // AgentProfit(db, order); } } } } tran.Commit(); } catch (Exception ex) { function.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + ex.ToString(), "自定义分润程序监听队列异常"); tran.Rollback(); } } db.Dispose(); } #endregion } }