using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SA.Entity.zxdcrm_Models; using SA.Core.Init; using SA.Domain.XFYun.XFYunEntity; using System.Collections.Concurrent; using SA.Core.Util; using SA.Domain.XFYun.BaseInfo; using SA.Entity.dbcrm; namespace SA.Domain.XFYun { /// /// 获取订单 /// public class GenOrderCall { private static ConcurrentDictionary wxSzzyorders = new ConcurrentDictionary(); private static ConcurrentDictionary wxSzzyordersChecking = new ConcurrentDictionary(); /// /// 订单查询起始时间 /// public static DateTime? startTime; private static AI_CallTaskConfig genOrderCallConfig = GetConfig(); private static int GetNum = 100; private int times = 0; /// /// 获取订单 /// public void GetOrder() { try { //LogHelper.Info("OrderCallConfig: " + SerializeHelper.ToJson(genOrderCallConfig)); // 一段时间不跑任务 var now = DateTime.Now; if (DateTime.TryParse(genOrderCallConfig.HgrecordStime, out DateTime stime) && DateTime.TryParse(genOrderCallConfig.HgrecordEtime, out DateTime etime)) { if (now.TimeOfDay < stime.TimeOfDay || now.TimeOfDay > etime.TimeOfDay) { LogHelper.Info($"GetOrder Sleep:stime:{stime},etime:{etime},当前:{now.TimeOfDay}"); return; } } times++; List status = new List { 0, 6 }; status.AddRange(genOrderCallConfig.ReCallStatus); if (times % 2 != 1) status = new List { 0 }; var calltime = DateTime.Now.AddDays(-genOrderCallConfig.CallDay); if (!startTime.HasValue) startTime = genOrderCallConfig.StartTime; startTime = startTime < calltime ? calltime : startTime; var orderlist = InitDB.zxdcrmDb.Queryable() // .Select(d=>new WxSzzyorder { Orderid = d.Orderid,Cname=d.Cname,Idcard=d.Idcard,Subproductname=d.Subproductname,Subproductid=d.Subproductid,Arrivalpay=d.Arrivalpay, Opendays=d.Opendays,Giftdays=d.Giftdays,Giftdays2=d.Giftdays2, Resid = d.Resid, Ctime = d.Ctime, Channel = d.Channel, Contractctime = d.Contractctime,AiHgrecordStime=d.AiHgrecordStime,AiHgrecordEtime=d.AiHgrecordEtime }) .Where(d => d.Orderstatus!.Equals("200") && status.Contains(d.AiHgrecordStatus.Value)) .Where(d => d.Contractctime >= startTime) .Where(d => d.Idcard != null) .Where(d => d.Hashgrecord == null || d.Hashgrecord != 1) //判断是否已经进行过合规 //.Where(d=>d.Orderid== 81118603) .OrderBy(d => d.Orderid).Take(GetNum).ToList(); //测试 //orderlist = InitDB.zxdcrmDb.Queryable().Where(n => n.Orderid == 80338991).ToList(); if (orderlist.Count < GetNum) GetNum = GetNum <= 20 ? GetNum : GetNum - 20; if (orderlist.Count >= GetNum) GetNum = GetNum >= 500 ? GetNum : GetNum + 100; var filterCodes = orderlist.Select(n => n.Productcode).Distinct().ToList(); var basProduct = InitDB.dbcrmDb.Queryable().Where(n => filterCodes.Contains(n.id)).ToList(); var basPackage = InitDB.dbcrmDb.Queryable().Where(n => filterCodes.Contains(n.id)).ToList(); var updatenum = 0; foreach (var item in orderlist) { var product = basProduct.FirstOrDefault(n => n.id == item.Productcode); if (product != null) { if (genOrderCallConfig.IgnoreProductType.Contains(product.groupid)) { LogHelper.Info($"IgnoreProductType: 订单【{item.Orderid}】产品类型为{product.groupid}忽略不外呼"); continue; } } else { var package = basPackage.FirstOrDefault(n => n.id == item.Productcode); if (package != null && genOrderCallConfig.IgnoreProductType.Contains(package.groupid)) { LogHelper.Info($"IgnoreProductType: 订单【{item.Orderid}】产品类型为{product.groupid}忽略不外呼"); continue; } } WxSzzyorder wxSzzyorder; if (wxSzzyorders.TryRemove(item.Orderid, out wxSzzyorder)) { wxSzzyorders.TryAdd(item.Orderid, item); updatenum++; } else { //处理时加入处理列表,处理列表有的时候暂不加入待处理列表 if (!wxSzzyordersChecking.ContainsKey(item.Orderid)) { wxSzzyorders.TryAdd(item.Orderid, item); } } } LogHelper.Info($"查询数据times:{times}次,status={SerializeHelper.ToJson(status)}数据:{orderlist.Count},当前待处理列表:{wxSzzyorders.Count},正在处理列表:{wxSzzyordersChecking.Count},更新数据:{updatenum};"); CheckOrderList(); } catch (Exception ex) { LogHelper.Error($"查询数据错误!{ex.Message}"); } } /// /// 检查列表 /// public void CheckOrderList() { var sameuserlist = wxSzzyorders.Values.GroupBy(d => new { d.Resid }, d => d); LogHelper.Info($"检查订单数量:【{wxSzzyorders.Count}】相同用户数量:【{sameuserlist.Count()}】"); foreach (var item in sameuserlist) { var resid = item.Key.Resid!.ToString(); var wxSzzyorderslist = item.ToList(); LogHelper.Info($"开始检查用户:【{resid}】满足条件订单【{string.Join(",", wxSzzyorderslist.Select(n => n.Orderid))}】"); //同人有未完成订单且未超时的不处理 if (CheckOrderSameUserNotFinish(resid, wxSzzyorderslist)) { wxSzzyorderslist.ForEach(d => { WxSzzyorder wxSzzyorder; wxSzzyorders.TryRemove(d.Orderid, out wxSzzyorder); }); continue; } var checklist = new List(); foreach (var wxSzzyorderitem in wxSzzyorderslist) { LogHelper.Info($"开始检查订单:【{wxSzzyorderitem.Orderid}】"); WxSzzyorder wxSzzyorder; //加入正在处理列表 wxSzzyordersChecking.TryAdd(wxSzzyorderitem.Orderid, wxSzzyorderitem); if (wxSzzyorders.TryRemove(wxSzzyorderitem.Orderid, out wxSzzyorder)) { if (CheckOrderFail(wxSzzyorder) && !CheckOrderIgnore(wxSzzyorder)) { //忽略的不处理 checklist.Add(wxSzzyorder); } } } //处理 if (checklist.Count > 0) { CheckOrder(checklist); } //取出正在处理列表 wxSzzyorderslist.ForEach(d => { WxSzzyorder wxSzzyorder; wxSzzyordersChecking.TryRemove(d.Orderid, out wxSzzyorder); }); } } /// /// 检查同人,若同人有一定时间内的未完成订单,将不处理,等待完成。 /// /// /// /// public static bool CheckOrderSameUserNotFinish(string resid, List wxSzzyorders) { var orderlist = wxSzzyorders.Select(d => d.Orderid).ToList(); //四种状态 List status = new List { 0, 6 }; status.AddRange(genOrderCallConfig.ReCallStatus); //查看一下是否有当天已支付 未合规 且未签合同的 其他单 var sevenDay = DateTime.Now.Date.AddDays(-7); var wlist = InitDB.zxdcrmDb.Queryable().Where(d => d.Resid == resid && d.Ctime >= sevenDay) .Where(d => status.Contains(d.AiHgrecordStatus.Value)) .Where(d => d.Hashgrecord == null || d.Hashgrecord != 1) .Where(d => !orderlist.Contains(d.Orderid)).ToList(); //查看一下是否有当天已支付 或者 已提交支付 未签合同的 其他单 List waitStatus = new List { "200", "190" }; var hasPayList = wlist.Where(d => waitStatus.Contains(d.Orderstatus)).ToList(); if (hasPayList.Count > 0) { LogHelper.Info($"检查相同用户:【{resid}】,正在等待已支付单【{string.Join(",", hasPayList.Select(n => n.Orderid).ToList())}】"); return true; } var noPayList = wlist.Where(d => !waitStatus.Contains(d.Orderstatus) && d.Ctime >= DateTime.Now.Date).ToList(); if (noPayList.Count > 0) { var maxTime = wxSzzyorders.Select(d => d.Contractctime).Max(); var timespan = DateTime.Now - maxTime; if (timespan.HasValue && timespan.Value.Minutes < genOrderCallConfig.SameUserCheckTimeSpanMin) { LogHelper.Info($"检查相同用户:{resid},合同最大签订时间:{maxTime},有未支付订单【{string.Join(",", noPayList.Select(n => n.Orderid))}】,需等待时间:{genOrderCallConfig.SameUserCheckTimeSpanMin},已等待【{timespan.Value.Minutes}分钟】"); return true; } } return false; } /// /// 检查订单 /// /// 订单列表 public static void CheckOrder(List wxSzzyorders) { LogHelper.Info($"开始处理:resid:{wxSzzyorders.First().Resid},订单号【{string.Join(",", wxSzzyorders.Select(n => n.Orderid))}】"); var oldTaskList = InitDB.zxdcrmDb.Queryable() .Where(d => wxSzzyorders.Select(n => n.Orderid).ToList().Contains(d.Orderid.Value)).ToList(); try { CsvrAiCalltask csvrAiCalltask = GetCsvrAiCalltaskFromConfig(wxSzzyorders.First()); csvrAiCalltask.Resid = wxSzzyorders.First().Resid; csvrAiCalltask.Props = GetPropos(wxSzzyorders); csvrAiCalltask.Status = 0; csvrAiCalltask.Ctime = DateTime.Now; csvrAiCalltask.AiHgrecordStatus = 1; if (oldTaskList.Count > 0) { csvrAiCalltask.HasCall = 1; } else { //等待重播不需要修改状态为 等待AI外呼 wxSzzyorders.ForEach(d => { d.AiHgrecordStatus = 1; }); } var csvrAiCalltaskOrders = GetCsvrAiCalltaskOrders(wxSzzyorders); LogHelper.Info($"Props:{csvrAiCalltask.Props}"); CreatCsvrAiCalltask(wxSzzyorders, csvrAiCalltask, csvrAiCalltaskOrders); } catch (Exception ex) { LogHelper.Error($"resid:{wxSzzyorders.First().Resid}处理失败,orderid:{SerializeHelper.ToJson(wxSzzyorders.Select(d => d.Orderid).ToList())},{ex.Message}"); } } private static List GetCsvrAiCalltaskOrders(List wxSzzyorders) { List csvrAiCalltaskOrders = new List(); foreach (var item in wxSzzyorders) { LogHelper.Info($"Orderid:{item.Orderid},AiHgrecordStatus:{item.AiHgrecordStatus}"); csvrAiCalltaskOrders.Add(new CsvrAiCalltaskOrders { Orderid = item.Orderid, Subproductname = item.Subproductname, Cname = item.Cname, Idcard = item.Idcard }); } return csvrAiCalltaskOrders; } /// /// 创建任务 /// /// /// /// public static void CreatCsvrAiCalltask(List wxSzzyorders, CsvrAiCalltask csvrAiCalltask, List csvrAiCalltaskOrders) { try { InitDB.zxdcrmDb.Ado.BeginTran(); InitDB.zxdcrmDb.Updateable(wxSzzyorders).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); var id = InitDB.zxdcrmDb.Insertable(csvrAiCalltask).ExecuteReturnIdentity(); foreach (var item in csvrAiCalltaskOrders) { item.Taskid = id; } InitDB.zxdcrmDb.Insertable(csvrAiCalltaskOrders).ExecuteCommand(); InitDB.zxdcrmDb.Ado.CommitTran(); LogHelper.Info($"CreatCsvrAiCalltask:{csvrAiCalltask.Resid},Exetime:{csvrAiCalltask.Exetime}"); } catch (Exception ex) { InitDB.zxdcrmDb.Ado.RollbackTran(); LogHelper.Error($"orderid:{SerializeHelper.ToJson(wxSzzyorders.Select(d => d.Orderid))}", ex); throw; } } /// ///  "姓氏":"郭",   ///   "先生/女士":"先生",   /// "姓名":"郭立兴",  /// "身份证后6位":"310911", /// "产品确认":"智赢系列" /// /// /// public static string GetPropos(List wxSzzyorders) { var wxSzzyorder = wxSzzyorders.First(); Dictionary Proposkv = new Dictionary(); Proposkv.Add("【姓氏】", wxSzzyorder.Cname!.Substring(0, 1)); var cardnum = 1; if (wxSzzyorder.Idcard!.Length == 18) cardnum = int.Parse(wxSzzyorder.Idcard.Substring(16, 1)); Proposkv.Add("【先生/女士】", cardnum % 2 == 1 ? "先生" : "女士"); Proposkv.Add("【姓名】", wxSzzyorder.Cname); Proposkv.Add("【身份证后4位】", wxSzzyorder.Idcard.Substring(wxSzzyorder.Idcard.Length - 4, 4)); var productConfir = ""; if (wxSzzyorders.Count == 1) { var subproductname = genOrderCallConfig.proposProductConfig.Subproductname.Replace("#Subproductname", wxSzzyorder.Subproductname); productConfir = genOrderCallConfig.proposProductConfig.OneTemplate .Replace("@Subproductname", subproductname) .Replace("#Arrivalpay", PriceToCn(wxSzzyorder.Arrivalpay.Value)); var payexp = ""; if (wxSzzyorder.Opendays > 1) { payexp = genOrderCallConfig.proposProductConfig.PayExp.Replace("@Subproductname", "") .Replace("#OpenDays", toHanStr(wxSzzyorder.Opendays.ToString())); var gift = ""; var giftday = 0; if (wxSzzyorder.Giftdays.HasValue) giftday += wxSzzyorder.Giftdays.Value; if (wxSzzyorder.Giftdays2.HasValue) giftday += wxSzzyorder.Giftdays2.Value; if (giftday > 0) { gift = genOrderCallConfig.proposProductConfig.GiftExp.Replace("#GiftDays", toHanStr(giftday.ToString())); gift = gift.Replace("#OpenDays", toHanStr((wxSzzyorder.Opendays + giftday).ToString())); } payexp = payexp.Replace("@GiftExp", gift); } productConfir = productConfir.Replace("@PayExp", payexp); if (payexp.Equals("")) productConfir = productConfir.Replace(",,", ","); } else { var subproductnames = ""; var payexps = ""; foreach (var item in wxSzzyorders.GroupBy(d => d.Subproductname, d => d).ToList()) { var subproductname = genOrderCallConfig.proposProductConfig.Subproductname.Replace("#Subproductname", item.Key); subproductnames += subproductname + "和"; if (item.Sum(d => d.Opendays) == item.Count()) continue; var payexp = genOrderCallConfig.proposProductConfig.PayExp.Replace("@Subproductname", subproductname) .Replace("#OpenDays", toHanStr(item.Sum(d => d.Opendays).ToString())); var gift = ""; var giftday = 0; foreach (var subwxSzzyorderitem in item) { if (subwxSzzyorderitem.Giftdays.HasValue) giftday += subwxSzzyorderitem.Giftdays.Value; if (subwxSzzyorderitem.Giftdays2.HasValue) giftday += subwxSzzyorderitem.Giftdays2.Value; } if (giftday > 0) { gift = genOrderCallConfig.proposProductConfig.GiftExp.Replace("#GiftDays", toHanStr(giftday.ToString())); gift = gift.Replace("#OpenDays", toHanStr((item.Sum(d => d.Opendays) + giftday).ToString())); } payexp = payexp.Replace("@GiftExp", gift); payexps += payexp; } subproductnames = subproductnames.Substring(0, subproductnames.Length - 1); if (payexps.Length > 1) payexps = payexps.Substring(0, payexps.Length - 1); productConfir = genOrderCallConfig.proposProductConfig.MultipleTemplate .Replace("@Subproductname", subproductnames) .Replace("@PayExp", payexps) .Replace("#Arrivalpay", PriceToCn(wxSzzyorders.Sum(d => d.Arrivalpay).Value)); } Proposkv.Add("【产品确认】", productConfir); var result = SerializeHelper.ToJson(Proposkv); return result; } /// /// 金额数字转大写(带小数点) /// public static string PriceToCn(decimal price) { //数字转大写 string[] n = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; string[] d = { "", "分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" }; //不同位置的数字要加单位 List needReplace = new List { "零拾", "零佰", "零仟", "零万", "零亿", "亿万", "零元", "零零", "零角", "零分" }; List afterReplace = new List { "零", "零", "零", "万", "亿", "亿", "元", "零", "零", "" }; string e = price % 1 == 0 ? "整" : ""; //金额是整数,加一个“整”结尾 string re = ""; int a = (int)(price * 100); int k = 1; while (a != 0) { //初步转换大小写 re = n[a % 10] + d[k] + re; a = a / 10; k = k < 11 ? k + 1 : 4; } string need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault(); while (need != null) { int i = needReplace.IndexOf(need); re = re.Replace(needReplace[i], afterReplace[i]); need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault(); }//循环排除特殊情况 // re = re == "" ? "零元" : re + e; re = re == "" ? "零元" : re; return re; } public static string toHanStr(String numStr) { var price = Convert.ToDecimal(numStr); //数字转大写 string[] n = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; string[] d = { "", "分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" }; //不同位置的数字要加单位 List needReplace = new List { "零拾", "零佰", "零仟", "零万", "零亿", "亿万", "零元", "零零", "零角", "零分" }; List afterReplace = new List { "零", "零", "零", "万", "亿", "亿", "元", "零", "零", "" }; string e = price % 1 == 0 ? "整" : ""; //金额是整数,加一个“整”结尾 string re = ""; int a = (int)(price * 100); int k = 1; while (a != 0) { //初步转换大小写 re = n[a % 10] + d[k] + re; a = a / 10; k = k < 11 ? k + 1 : 4; } string need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault(); while (need != null) { int i = needReplace.IndexOf(need); re = re.Replace(needReplace[i], afterReplace[i]); need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault(); }//循环排除特殊情况 // re = re == "" ? "零元" : re + e; re = re == "" ? "零" : re.Replace("元", ""); return re; } /// /// 获取任务 /// /// /// public static CsvrAiCalltask GetCsvrAiCalltaskFromConfig(WxSzzyorder wxSzzyorder) { CsvrAiCalltask csvrAiCalltask = new CsvrAiCalltask(); csvrAiCalltask.Robot = genOrderCallConfig.Robot; csvrAiCalltask.AppId = genOrderCallConfig.AppId; csvrAiCalltask.CallNo = genOrderCallConfig.CallNo; csvrAiCalltask.Sms = genOrderCallConfig.Sms; DateTime now = DateTime.Now; var expmin = genOrderCallConfig.SmsExprieMinCall; csvrAiCalltask.Smstime = now; csvrAiCalltask.Exetime = now.AddMinutes(expmin); //优先级别1-紧急 2-优先 csvrAiCalltask.Priority = genOrderCallConfig.Priority; return csvrAiCalltask; } /// /// 失败订单重试//true 重试 /// /// /// public static bool CheckOrderFail(WxSzzyorder wxSzzyorder) { var aihgrecoedStatus = wxSzzyorder.AiHgrecordStatus!.Value; var now = DateTime.Now; var ReCallMin = genOrderCallConfig.ReCallMins; var ReCallStatus = genOrderCallConfig.ReCallStatus; if (ReCallStatus.Contains(aihgrecoedStatus) || aihgrecoedStatus == 6) { var taskids = InitDB.zxdcrmDb.Queryable().Where(d => d.Orderid == wxSzzyorder.Orderid).OrderByDescending(d => d.Taskid).Select(d => d.Taskid).ToList(); if (taskids == null || taskids.Count == 0) { return true; } var logInfo = $"检查订单重试:【{wxSzzyorder.Orderid}】,状态:【{wxSzzyorder.AiHgrecordStatusname}】任务Id【{SerializeHelper.ToJson(taskids)}】"; LogHelper.Info($"{logInfo}"); var maxid = taskids.Max(d => d.Value); var exectime = InitDB.zxdcrmDb.Queryable().Where(d => d.Id == maxid).OrderByDescending(d => d.Id).Select(d => d.Exetime).First(); var min = 0; if (taskids.Count() > ReCallMin.Count) { LogHelper.Info($"{logInfo}超过最大重试次数【{ReCallMin.Count}】,忽略。"); //wxSzzyorder.AiHgrecordStatus = -2; //InitDB.zxdcrmDb.Updateable(wxSzzyorder).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); return false; } else { min = ReCallMin[taskids.Count() - 1]; } var difmin = now - exectime!.Value; // 如果在固定时间内的话直接重试 DateTime stime; DateTime etime; if (DateTime.TryParse(wxSzzyorder.AiHgrecordStime, out stime) && DateTime.TryParse(wxSzzyorder.AiHgrecordEtime, out etime)) { if (now.TimeOfDay >= stime.TimeOfDay && now.TimeOfDay <= etime.TimeOfDay) { LogHelper.Info($"{logInfo}: 设置间隔【{stime}-{etime}】当前:{now.TimeOfDay},上次执行时间:{exectime!.Value},开始重试!"); return true; } } if (difmin.TotalMinutes > min) { LogHelper.Info($"{logInfo}exectime:{exectime!.Value},开始重试!"); return true; } if (ReCallStatus.Contains(aihgrecoedStatus)) { LogHelper.Info($"{logInfo},修改为等待重拨"); wxSzzyorder.AiHgrecordStatus = 6; InitDB.zxdcrmDb.Updateable(wxSzzyorder).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); } return false; } return true; } /// /// 检查是否忽略,忽略更新Ai_hgrecord_status=4 /// /// /// public bool CheckOrderIgnore(WxSzzyorder wxSzzyorder) { bool Ignore = false; var now = DateTime.Now; //小于最小订单金额 if (wxSzzyorder.Arrivalpay < genOrderCallConfig.MinAmount && !genOrderCallConfig.WhiteList.Contains(wxSzzyorder.Resid)) { LogHelper.Info($"订单【{wxSzzyorder.Orderid}】金额【{wxSzzyorder.Arrivalpay}】小于外呼设置金额【{genOrderCallConfig.MinAmount}】跳过"); Ignore = true; } //忽略本次,不更新字段 DateTime stime; DateTime etime; if (DateTime.TryParse(wxSzzyorder.AiHgrecordStime, out stime) && DateTime.TryParse(wxSzzyorder.AiHgrecordEtime, out etime)) { if (now.TimeOfDay < stime.TimeOfDay || now.TimeOfDay > etime.TimeOfDay) { LogHelper.Info($"订单【{wxSzzyorder.Orderid}回访时间【{wxSzzyorder.AiHgrecordStime}-{wxSzzyorder.AiHgrecordEtime}】不在范围之内当前时间:{now.TimeOfDay}"); return true; } } if (!Ignore) { if (genOrderCallConfig.IgnoreHitConfigs != null) { foreach (var hitConfig in genOrderCallConfig.IgnoreHitConfigs) { //检查渠道 if (HitKey.Channel.ToString().Equals(hitConfig.HitKey)) { //包含 if (hitConfig.Contain != null && hitConfig.Contain.Count > 0) { foreach (var item in hitConfig.Contain) { var channelitem = GetChannelItem(item); if (wxSzzyorder.Channel >= channelitem.Min && wxSzzyorder.Channel <= channelitem.Max) { LogHelper.Info($"Ignore,hitConfig.Contain:Channel:{wxSzzyorder.Channel},Min:{channelitem.Min},Max:{channelitem.Max}"); Ignore = true; } else { Ignore = false; break; } } } //不包含,结果会被不包含覆盖,不包含优先级更高 if (hitConfig.NoContain != null && hitConfig.NoContain.Count > 0) { foreach (var item in hitConfig.NoContain) { var channelitem = GetChannelItem(item); if (wxSzzyorder.Channel < channelitem.Min || wxSzzyorder.Channel > channelitem.Max) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.NoContain:Channel:{wxSzzyorder.Channel},Min:{channelitem.Min},Max:{channelitem.Max}"); Ignore = true; } else { Ignore = false; break; } } } } //检查产品Id if (HitKey.Subproductid.ToString().Equals(hitConfig.HitKey) && !Ignore) { //包含 if (hitConfig.Contain != null && hitConfig.Contain.Count > 0) { if (hitConfig.Contain.Contains(wxSzzyorder.Subproductid!.Value.ToString())) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.Contain:Subproductid:{wxSzzyorder.Subproductid.ToString()}"); Ignore = true; } else { Ignore = false; break; } } //不包含,结果会被不包含覆盖,不包含优先级更高 if (hitConfig.NoContain != null && hitConfig.NoContain.Count > 0) { if (!hitConfig.NoContain.Contains(wxSzzyorder.Subproductid!.Value.ToString())) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.NoContain:Subproductid:{wxSzzyorder.Subproductid.ToString()}"); Ignore = true; } else { Ignore = false; break; } } } //检查Resid if (HitKey.Resid.ToString().Equals(hitConfig.HitKey) && !Ignore) { //包含 if (hitConfig.Contain != null && hitConfig.Contain.Count > 0) { if (hitConfig.Contain.Contains(wxSzzyorder.Resid!.ToString())) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.Contain:Resid:{wxSzzyorder.Resid!.ToString()}"); Ignore = true; } else { Ignore = false; break; } } //不包含,结果会被不包含覆盖,不包含优先级更高 if (hitConfig.NoContain != null && hitConfig.NoContain.Count > 0) { if (!hitConfig.NoContain.Contains(wxSzzyorder.Resid!.ToString())) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.NoContain:Resid:{wxSzzyorder.Resid!.ToString()}"); Ignore = true; } else { Ignore = false; break; } } } } } } if (!Ignore) { //检查产品是否为不需要风控的自动开通产品 var subproduct = InitDB.zxdcrmDb.Queryable().Where(d => d.Subproductid == wxSzzyorder.Subproductid).First(); //如果不需要ai回访 则忽略 if (subproduct.NeedAi == 0) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, NeedAi:subproduct:{wxSzzyorder.Subproductid!.ToString()}"); Ignore = true; } /* if (subproduct != null && subproduct.AutomaticOpen == 1 && subproduct.NeedFK == 0) { LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, NotNeedFK:subproduct:{wxSzzyorder.Subproductid!.ToString()}"); Ignore = true; }*/ } if (Ignore) { wxSzzyorder.AiHgrecordStatus = -1; LogHelper.Info($"Ignore,resid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, -1"); // wxSzzyorder.Ai_hgrecord_statusname = Ai_hgrecord_statusnameKV[wxSzzyorder.Ai_hgrecord_status]; InitDB.zxdcrmDb.Updateable(wxSzzyorder).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); } return Ignore; } /// /// 获取channelItem /// /// /// public static ChannelItem GetChannelItem(string ChannelStr) { ChannelItem channelItem = new ChannelItem { Max = 0, Min = 0 }; try { int min = 0; int max = 0; var c = ChannelStr.Split('|'); int.TryParse(c[0], out min); int.TryParse(c[1], out max); channelItem.Max = max; channelItem.Min = min; } catch (Exception ex) { LogHelper.Error($"ChannelStr:{ChannelStr}格式异常", ex); return channelItem; } return channelItem; } /// /// 获取配置 /// /// /// public static AI_CallTaskConfig GetConfig() { try { var test = new AI_CallTaskConfig(); test.IgnoreHitConfigs.Add(new HitConfig()); var s = SerializeHelper.ToJson(test); InitConfig initConfig = new InitConfig(); genOrderCallConfig = initConfig.Get_CallTaskConfig(); if (string.IsNullOrEmpty(genOrderCallConfig.AppId)) { var errmsg = "获取AI_CallTaskConfig失败:AppId 为空!"; LogHelper.Error(errmsg); throw new Exception(errmsg); } } catch (Exception ex) { LogHelper.Error(ex, "AI_CallTaskConfig,配置出错"); } return genOrderCallConfig; } #region 测试方法 public static AI_CallTaskConfig RefreshConfig() { genOrderCallConfig = GetConfig(); return genOrderCallConfig; } public string BuildProposTest(List orderids) { var orderList = InitDB.zxdcrmDb.Queryable().Where(n => orderids.Contains(n.Orderid)).ToList(); var res = GetPropos(orderList); return res; } #endregion 测试方法 /// /// 人工手动拨打AI回访 /// /// /// public async Task CreatAiOrder(string? resid) { if (resid == null) { return "resid不能为空!"; } LogHelper.Info($"开始处理:resid:{resid}, 人工手动拨打AI回访!"); List status = new List { 0, 6 }; var aiHgrecordStatus = new List { -2, 3, 7 }; status.AddRange(genOrderCallConfig.ReCallStatus); var orderlist = await InitDB.zxdcrmDb.Queryable() .Where(d => d.Resid == resid) // .Select(d=>new WxSzzyorder { Orderid = d.Orderid,Cname=d.Cname,Idcard=d.Idcard,Subproductname=d.Subproductname,Subproductid=d.Subproductid,Arrivalpay=d.Arrivalpay, Opendays=d.Opendays,Giftdays=d.Giftdays,Giftdays2=d.Giftdays2, Resid = d.Resid, Ctime = d.Ctime, Channel = d.Channel, Contractctime = d.Contractctime,AiHgrecordStime=d.AiHgrecordStime,AiHgrecordEtime=d.AiHgrecordEtime }) .Where(d => d.Orderstatus!.Equals("200")) .Where(x => x.AiHgrecordStatus != null && aiHgrecordStatus.Contains(x.AiHgrecordStatus.Value)) .Where(d => d.Contractctime >= startTime) .Where(d => d.Idcard != null) .Where(d => d.Hashgrecord == null || d.Hashgrecord != 1) //判断是否已经进行过合规 //.Where(d=>d.Orderid== 81118603) .OrderBy(d => d.Orderid).ToListAsync(); if (orderlist == null || !orderlist.Any()) { return "无订单可以进行回访!"; } CheckOrder(orderlist); orderlist.ForEach(d => { d.AiHgrecordStatus = 6; }); InitDB.zxdcrmDb.Updateable(orderlist).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); return $"成功发起任务【 {string.Join(",", orderlist.Select(x => x.Orderid).ToList())}】"; } public async Task CreatAiOrders(string? orderids) { if (orderids == null) { return "orderids不能为空!"; } Log.Information($"开始处理:orderids:{orderids}, 人工手动拨打AI回访!"); try { var orderidList = orderids.Split(',').Select(x => int.Parse(x)).ToList(); List status = new List { 0, 6 }; var aiHgrecordStatus = new List { -2, -1, 0, 3, 7 }; status.AddRange(genOrderCallConfig.ReCallStatus); var orderlist = await InitDB.zxdcrmDb.Queryable() .Where(d => orderidList.Contains(d.Orderid)) .Where(x => x.AiHgrecordStatus != null && aiHgrecordStatus.Contains(x.AiHgrecordStatus.Value)) .Where(d => d.Contractctime >= startTime) .Where(d => d.Idcard != null) .Where(d => d.Hashgrecord == null || d.Hashgrecord != 1) .OrderBy(d => d.Orderid).ToListAsync(); if (orderlist == null || !orderlist.Any()) { return "无订单可以进行回访!"; } var sameuserlist = orderlist.GroupBy(d => new { d.Resid }, d => d); foreach (var item in sameuserlist) { var wxSzzyorderslist = item.ToList(); CheckOrder(wxSzzyorderslist); } orderlist.ForEach(d => { d.AiHgrecordStatus = 6; }); InitDB.zxdcrmDb.Updateable(orderlist).UpdateColumns(d => new { d.AiHgrecordStatus, d.AiHgrecordStatusname }).ExecuteCommand(); return $"成功发起任务【 {string.Join(",", orderlist.Select(x => x.Orderid).ToList())}】"; } catch (Exception ex) { Log.Error(ex, "人工手动拨打AI回访"); return ex.Message; } } } }