SACenter/SA.Domain.XFYun/GenOrderCall/GenOrderCall.cs

884 lines
43 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 获取订单
/// </summary>
public class GenOrderCall
{
private static ConcurrentDictionary<int, WxSzzyorder> wxSzzyorders = new ConcurrentDictionary<int, WxSzzyorder>();
private static ConcurrentDictionary<int, WxSzzyorder> wxSzzyordersChecking = new ConcurrentDictionary<int, WxSzzyorder>();
/// <summary>
/// 订单查询起始时间
/// </summary>
public static DateTime? startTime;
private static AI_CallTaskConfig genOrderCallConfig = GetConfig();
private static int GetNum = 100;
private int times = 0;
/// <summary>
/// 获取订单
/// </summary>
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<int> status = new List<int> { 0, 6 };
status.AddRange(genOrderCallConfig.ReCallStatus);
if (times % 2 != 1) status = new List<int> { 0 };
var calltime = DateTime.Now.AddDays(-genOrderCallConfig.CallDay);
if (!startTime.HasValue) startTime = genOrderCallConfig.StartTime;
startTime = startTime < calltime ? calltime : startTime;
var orderlist = InitDB.zxdcrmDb.Queryable<WxSzzyorder>()
// .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<WxSzzyorder>().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<TProduct>().Where(n => filterCodes.Contains(n.id)).ToList();
var basPackage = InitDB.dbcrmDb.Queryable<TPackageProduct>().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}");
}
}
/// <summary>
/// 检查列表
/// </summary>
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<WxSzzyorder>();
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);
});
}
}
/// <summary>
/// 检查同人,若同人有一定时间内的未完成订单,将不处理,等待完成。
/// </summary>
/// <param name="resid"></param>
/// <param name="wxSzzyorders"></param>
/// <returns></returns>
public static bool CheckOrderSameUserNotFinish(string resid, List<WxSzzyorder> wxSzzyorders)
{
var orderlist = wxSzzyorders.Select(d => d.Orderid).ToList();
//四种状态
List<int> status = new List<int> { 0, 6 };
status.AddRange(genOrderCallConfig.ReCallStatus);
//查看一下是否有当天已支付 未合规 且未签合同的 其他单
var sevenDay = DateTime.Now.Date.AddDays(-7);
var wlist = InitDB.zxdcrmDb.Queryable<WxSzzyorder>().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<string> waitStatus = new List<string> { "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;
}
/// <summary>
/// 检查订单
/// </summary>
/// <param name="wxSzzyorders">订单列表</param>
public static void CheckOrder(List<WxSzzyorder> wxSzzyorders)
{
LogHelper.Info($"开始处理resid:{wxSzzyorders.First().Resid},订单号【{string.Join(",", wxSzzyorders.Select(n => n.Orderid))}】");
var oldTaskList = InitDB.zxdcrmDb.Queryable<CsvrAiCalltaskOrders>()
.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<CsvrAiCalltaskOrders> GetCsvrAiCalltaskOrders(List<WxSzzyorder> wxSzzyorders)
{
List<CsvrAiCalltaskOrders> csvrAiCalltaskOrders = new List<CsvrAiCalltaskOrders>();
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;
}
/// <summary>
/// 创建任务
/// </summary>
/// <param name="wxSzzyorders"></param>
/// <param name="csvrAiCalltask"></param>
/// <param name="csvrAiCalltaskOrders"></param>
public static void CreatCsvrAiCalltask(List<WxSzzyorder> wxSzzyorders, CsvrAiCalltask csvrAiCalltask, List<CsvrAiCalltaskOrders> 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;
}
}
/// <summary>
///  "姓氏":"郭",
  ///   "先生/女士":"先生",
  /// "姓名":"郭立兴",
 /// "身份证后6位":"310911",
/// "产品确认":"智赢系列"
/// </summary>
/// <param name="wxSzzyorders"></param>
/// <returns></returns>
public static string GetPropos(List<WxSzzyorder> wxSzzyorders)
{
var wxSzzyorder = wxSzzyorders.First();
Dictionary<string, string> Proposkv = new Dictionary<string, string>();
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;
}
/// <summary>
/// 金额数字转大写(带小数点)
/// </summary>
public static string PriceToCn(decimal price)
{
//数字转大写
string[] n = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
string[] d = { "", "分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" };
//不同位置的数字要加单位
List<string> needReplace = new List<string> { "零拾", "零佰", "零仟", "零万", "零亿", "亿万", "零元", "零零", "零角", "零分" };
List<string> afterReplace = new List<string> { "零", "零", "零", "万", "亿", "亿", "元", "零", "零", "" };
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<string>();
while (need != null)
{
int i = needReplace.IndexOf(need);
re = re.Replace(needReplace[i], afterReplace[i]);
need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault<string>();
}//循环排除特殊情况
// 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<string> needReplace = new List<string> { "零拾", "零佰", "零仟", "零万", "零亿", "亿万", "零元", "零零", "零角", "零分" };
List<string> afterReplace = new List<string> { "零", "零", "零", "万", "亿", "亿", "元", "零", "零", "" };
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<string>();
while (need != null)
{
int i = needReplace.IndexOf(need);
re = re.Replace(needReplace[i], afterReplace[i]);
need = needReplace.Where(tb => re.Contains(tb)).FirstOrDefault<string>();
}//循环排除特殊情况
// re = re == "" ? "零元" : re + e;
re = re == "" ? "零" : re.Replace("元", "");
return re;
}
/// <summary>
/// 获取任务
/// </summary>
/// <param name="wxSzzyorder"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 失败订单重试//true 重试
/// </summary>
/// <param name="wxSzzyorder"></param>
/// <returns></returns>
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<CsvrAiCalltaskOrders>().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<CsvrAiCalltask>().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;
}
/// <summary>
/// 检查是否忽略忽略更新Ai_hgrecord_status=4
/// </summary>
/// <param name="wxSzzyorder"></param>
/// <returns></returns>
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($"IgnorehitConfig.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($"Ignoreresid: {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($"Ignoreresid: {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($"Ignoreresid: {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($"Ignoreresid: {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($"Ignoreresid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, hitConfig.NoContain:Resid{wxSzzyorder.Resid!.ToString()}");
Ignore = true;
}
else
{
Ignore = false;
break;
}
}
}
}
}
}
if (!Ignore)
{
//检查产品是否为不需要风控的自动开通产品
var subproduct = InitDB.zxdcrmDb.Queryable<WxSzzysubproduct>().Where(d => d.Subproductid == wxSzzyorder.Subproductid).First();
//如果不需要ai回访 则忽略
if (subproduct.NeedAi == 0)
{
LogHelper.Info($"Ignoreresid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, NeedAisubproduct{wxSzzyorder.Subproductid!.ToString()}");
Ignore = true;
}
/* if (subproduct != null && subproduct.AutomaticOpen == 1 && subproduct.NeedFK == 0)
{
LogHelper.Info($"Ignoreresid: {wxSzzyorder.Resid}, orderid: {wxSzzyorder.Orderid}, NotNeedFKsubproduct{wxSzzyorder.Subproductid!.ToString()}");
Ignore = true;
}*/
}
if (Ignore)
{
wxSzzyorder.AiHgrecordStatus = -1;
LogHelper.Info($"Ignoreresid: {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;
}
/// <summary>
/// 获取channelItem
/// </summary>
/// <param name="ChannelStr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 获取配置
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
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<decimal> orderids)
{
var orderList = InitDB.zxdcrmDb.Queryable<WxSzzyorder>().Where(n => orderids.Contains(n.Orderid)).ToList();
var res = GetPropos(orderList);
return res;
}
#endregion
/// <summary>
/// 人工手动拨打AI回访
/// </summary>
/// <param name="resid"></param>
/// <returns></returns>
public async Task<string> CreatAiOrder(string? resid)
{
if (resid == null)
{
return "resid不能为空";
}
LogHelper.Info($"开始处理resid:{resid}, 人工手动拨打AI回访");
List<int> status = new List<int> { 0, 6 };
var aiHgrecordStatus = new List<int> { -2, 3, 7 };
status.AddRange(genOrderCallConfig.ReCallStatus);
var orderlist = await InitDB.zxdcrmDb.Queryable<WxSzzyorder>()
.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<string> 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<int> status = new List<int> { 0, 6 };
var aiHgrecordStatus = new List<int> { -2, -1, 0, 3, 7 };
status.AddRange(genOrderCallConfig.ReCallStatus);
var orderlist = await InitDB.zxdcrmDb.Queryable<WxSzzyorder>()
.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;
}
}
}
}