ComplianceServer/oldcode/Core.BLL/Csvr/Csvr_AiCallTask_BL.cs

720 lines
30 KiB
C#

using CRM.Core.BLL.Util;
using CRM.Core.Common.Layui;
using CRM.Core.Model.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Linq.Expressions;
using CRM.Core.Model.Enum;
using Newtonsoft.Json;
using CRM.Core.Common;
using System.Diagnostics;
using System.ComponentModel;
namespace CRM.Core.BLL.Csvr
{
public class Csvr_AiCallTask_BL : DbContextRepository<Csvr_Ai_CallTask>
{
private CACHE_BL cache_BL = new CACHE_BL();
public List<AiCallTask_View> GetList(ref Laypage pager, AiRecordQueryDto dto)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var robotList = cache_BL.GetAiRobotList();
var robotName = robotList.FirstOrDefault()?.RobotName;
var remark = robotList.FirstOrDefault()?.Remark;
using (var db = new zxdContext())
{
var orderQuery = from n in db.Csvr_Ai_CallTask_Orders
group n by n.Taskid into model
select new GroupTask
{
TaskId = model.Key.Value,
LinkOrderId = model.Select(n => n.Orderid.Value).FirstOrDefault()
};
if (dto.orderId.HasValue)
{
orderQuery = from n in db.Csvr_Ai_CallTask_Orders
where n.Orderid == dto.orderId.Value
group n by n.Taskid into model
select new GroupTask
{
TaskId = model.Key.Value,
LinkOrderId = model.Select(n => n.Orderid.Value).FirstOrDefault()
};
}
if (!string.IsNullOrEmpty(dto.channel))
{
var channelQuery = from n in db.Csvr_Ai_CallTask_Orders
join b in db.WX_SZZYORDER
on n.Orderid equals b.ORDERID
select new OrderTaskDto
{
Taskid = n.Taskid.Value,
CHANNEL = b.CHANNEL,
ORDERID = n.Orderid.Value
};
var arr0 = dto.channel.Split('|');
if (arr0.Length > 1)
{
var predicates = new List<Expression<Func<OrderTaskDto, bool>>>();
foreach (var item in arr0)
{
var a = item.Split(',');
var min = Convert.ToInt32(a[0]);
var max = Convert.ToInt32(a[1]);
predicates.Add(m => m.CHANNEL >= min && m.CHANNEL <= max);
}
channelQuery = channelQuery.WhereOR(predicates.ToArray());
}
else
{
var arr = dto.channel.Split(',');
var min = Convert.ToInt32(arr[0]);
var max = Convert.ToInt32(arr[1]);
channelQuery = channelQuery.Where(m => m.CHANNEL >= min && m.CHANNEL <= max);
}
orderQuery = from a in channelQuery
group a by a.Taskid into model
select new GroupTask
{
TaskId = model.Key.Value,
LinkOrderId = model.Select(n => n.ORDERID).FirstOrDefault()
};
}
var queryData =
from o in orderQuery
join b in db.Csvr_Ai_CallTask.AsQueryable() on o.TaskId equals b.Id into bs
from b in bs.DefaultIfEmpty()
join c in db.WX_SZZYORDER on o.LinkOrderId equals c.ORDERID into t1
from c in t1.DefaultIfEmpty()
join d in db.RES_CUSTOMER on c.RESID equals d.RESID into t2
from d in t2.DefaultIfEmpty()
select new AiCallTask_View
{
Robot = b.Robot,
RobotName = robotName,
Remark = remark,
Id = b.Id,
RESID = b.Resid,
UMID= d.UMID,
CallNo = d.LASTNUM3,
CHANNEL = c.CHANNEL,
CNAME = c.CNAME,
AiStatus = b.ai_hgrecord_status,
AiStatusName = b.ai_hgrecord_statusname,
StartTime = b.StartTime,
EndTime = b.EndTime,
Audio = b.Audio,
SvcTime = b.SvcTime,
HasCall= b.hascall,
HasCallName = b.hascall == null || b.hascall == 0?"否":"是",
Ctime = b.Ctime,
Rounds = b.Rounds == null ? 0:b.Rounds.Value
};
if (!string.IsNullOrEmpty(dto.robot)&&dto.robot != "-3")
{
queryData = queryData.Where(n => n.Robot == dto.robot);
}
if(dto.robot == "-3")
{
var containRobot = robotList.Select(n => n.Robot).ToList();
queryData = queryData.Where(n => containRobot.Contains(n.Robot));
}
if (!string.IsNullOrEmpty(dto.robotRemark))
{
queryData = queryData.Where(n => n.Remark == dto.robotRemark);
}
if (!string.IsNullOrEmpty(dto.cname))
{
queryData = queryData.Where(m => m.CNAME == dto.cname);
}
if (dto.xstime.HasValue)
{
queryData = queryData.Where(n => n.Ctime >= dto.xstime);
}
if (dto.xetime.HasValue)
{
dto.xetime = dto.xetime.Value.AddDays(1);
queryData = queryData.Where(n => n.Ctime <= dto.xetime);
}
if (!string.IsNullOrWhiteSpace(dto.resId))
{
queryData = queryData.Where(m => m.RESID == dto.resId);
//where = where.And(m => m.RESID == dto.resId);
}
if (!string.IsNullOrWhiteSpace(dto.UMID))
{
queryData = queryData.Where(m => m.UMID == dto.UMID);
//where = where.And(m => m.RESID == dto.resId);
}
if (dto.aistatus > -3)
{
/*if(dto.aistatus == (int) EnumAiCallState.Ai外呼取消)
{
queryData = queryData.Where(m => m.AiStatus == dto.aistatus || m.AiStatus == (int)EnumAiCallState.人工回访成功);
}
else
{
queryData = queryData.Where(m => m.AiStatus == dto.aistatus);
}*/
queryData = queryData.Where(m => m.AiStatus == dto.aistatus);
}
if (dto.type == -1)
{
List<int> containState = new List<int>() {
(int) EnumAiCallState.AI外呼成功,
(int) EnumAiCallState.AI外呼失败未答完,
(int) EnumAiCallState.AI外呼未接通,
(int) EnumAiCallState.AI外呼失败挂断,
};
queryData = queryData.Where(n => containState.Contains(n.AiStatus.Value));
}
else
{
queryData = queryData.Where(n => n.AiStatus.Value != (int)EnumAiCallState.访);
}
if (!string.IsNullOrWhiteSpace(dto.RobotId))
{
queryData = queryData.Where(n => n.Robot == dto.RobotId);
}
if (dto.hasCall > 0)
{
queryData = queryData.Where(n => n.HasCall == dto.hasCall);
}
queryData = queryData.OrderByDescending(n => n.Ctime);
PagerUtil.SetPager(ref queryData, ref pager);
var list = queryData.ToList();
stopwatch.Stop();
LogHelper.Info($"Ai日志用时 {stopwatch.ElapsedMilliseconds}ms");
stopwatch.Restart();
var taskIds = list.Select(n => n.Id).ToList();
var orderTaskList = db.Csvr_Ai_CallTask_Orders.Where(n => taskIds.Contains(n.Taskid.Value)).ToList();
var orderidList = orderTaskList.Select(x => x.Orderid).ToList();
var orderList = db.WX_SZZYORDER.Where(n => orderidList.Contains(n.ORDERID)).ToList();
var companyList = cache_BL.GetCompanyVirtual();
foreach (var item in list)
{
var childOrder = orderTaskList.Where(n => n.Taskid.Value == item.Id).ToList();
item.ORDERID = string.Join(",", childOrder.Select(n => n.Orderid).ToList());
List<string> channelList = new List<string>();
var orderChannel = orderList.Where(n => childOrder.Select(x => x.Orderid).Contains(n.ORDERID)).Select(n=>n.CHANNEL).Distinct().ToList();
foreach(var channelitem in orderChannel)
{
channelList.Add(ConvertChannelName(companyList, channelitem));
}
item.CHANNELNAME = string.Join(",",channelList);
/*if (item.AiStatus == (int)EnumAiCallState.人工回访成功)
{
item.AiStatusName = EnumAiCallState.Ai外呼取消.ToString();
}*/
}
stopwatch.Stop();
LogHelper.Info($"Ai列表日志用时 {stopwatch.ElapsedMilliseconds}ms");
return list;
}
}
/// <summary>
/// 转换事业部
/// </summary>
/// <param name="channelList"></param>
/// <param name="channel"></param>
/// <returns></returns>
private string ConvertChannelName(List<Bas_CompanyVirtual> channelList, int channel)
{
foreach (var item in channelList)
{
var channelStr = item.Channel.Split('|').ToList();
foreach (var str in channelStr)
{
var a = str.Split(',');
var min = Convert.ToInt32(a[0]);
var max = Convert.ToInt32(a[1]);
if (channel >= min && channel <= max)
{
return item.CompanyName;
}
}
}
return "";
}
public Csvr_Ai_CallTask GetModel(int? id)
{
using (var db = new zxdContext())
{
var res = db.Csvr_Ai_CallTask.FirstOrDefault(n => n.Id == id);
return res;
}
}
public AiRecordDetailDto BuildAudioModel(int? id)
{
using (var db = new zxdContext())
{
var record = db.Csvr_Ai_CallTask.FirstOrDefault(n => n.Id == id);
if (record == null)
{
throw new Exception("找不到对应的数据");
}
var robots = cache_BL.GetAiRobotList().FirstOrDefault(n => n.Robot == record.Robot);
var data = new AiRecordDetailDto
{
robotName = robots?.RobotName,
phoneNo = db.RES_CUSTOMER.FirstOrDefault(n => n.RESID == record.Resid)?.LASTNUM3,
audio = record.Audio,
sessionBeginTime = record.StartTime.Value.ToString("yyyy-MM-dd HH:mm:ss"),
sessionEndTime = record.EndTime.Value.ToString("yyyy-MM-dd HH:mm:ss"),
};
if (!string.IsNullOrWhiteSpace(record.Interact))
{
data.logUserSessionDetailList = JsonConvert.DeserializeObject<List<MsgContent>>(record.Interact);
}
return data;
}
}
public List<AudioRecordView> GetAudioByOrderId(decimal orderId)
{
var robotList = cache_BL.GetAiRobotList();
using (var db = new zxdContext())
{
var robotName = robotList.FirstOrDefault()?.RobotName;
var taskQuery = from n in db.Csvr_Ai_CallTask_Orders
group n by n.Taskid into model
let ids = model.Select(b => b.Orderid).ToList()
select new
{
OrderId = ids,
TaskId = model.Key
};
var res = from b in db.Csvr_Ai_CallTask
join a in taskQuery
on b.Id equals a.TaskId
where a.OrderId.ToList().Contains(orderId)
select new AudioRecordView
{
Type = 2,
RECORDID = b.Id,
FILENAME = b.Audio,
RESID = b.Resid,
TIMELENGTH = b.SvcTime,
SALESEID = b.Robot,
TIMESTART = b.StartTime,
TIMEEND = b.EndTime,
ORDERID = orderId,
CONTENT = b.Labels,
Ctime = b.Ctime
};
return res.ToList();
}
}
public List<AiRecordSumView> GetAiRecordSum(ref Laypage pager, AiRecordQueryDto dto)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var robotList = cache_BL.GetAiRobotList();
using (var db = new zxdContext())
{
var robotName = robotList.FirstOrDefault()?.RobotName;
var remark = robotList.FirstOrDefault()?.Remark;
var sms = robotList.FirstOrDefault()?.SMS;
var orderQuery = db.WX_SZZYORDER.AsQueryable();
List<decimal> orderids = new List<decimal>();
var hasOrderFilter = false;
if (dto.orderId.HasValue)
{
orderQuery = orderQuery.Where(m => m.ORDERID == dto.orderId.Value);
hasOrderFilter = true;
}
if (!string.IsNullOrEmpty(dto.cname))
{
orderQuery = orderQuery.Where(m => m.CNAME == dto.cname);
hasOrderFilter = true;
}
if (!string.IsNullOrEmpty(dto.channel))
{
var arr0 = dto.channel.Split('|');
if (arr0.Length > 1)
{
var predicates = new List<Expression<Func<WX_SZZYORDER, bool>>>();
foreach (var item in arr0)
{
var a = item.Split(',');
var min = Convert.ToInt32(a[0]);
var max = Convert.ToInt32(a[1]);
predicates.Add(m => m.CHANNEL >= min && m.CHANNEL <= max);
}
orderQuery = orderQuery.WhereOR(predicates.ToArray());
}
else
{
var arr = dto.channel.Split(',');
var min = Convert.ToInt32(arr[0]);
var max = Convert.ToInt32(arr[1]);
orderQuery = orderQuery.Where(m => m.CHANNEL >= min && m.CHANNEL <= max);
}
hasOrderFilter = true;
}
if (!string.IsNullOrWhiteSpace(dto.resId))
{
orderQuery = orderQuery.Where(m => m.RESID == dto.resId);
hasOrderFilter = true;
}
List<int> aiExceptState = new List<int>
{
(int)EnumAiCallState.Ai外呼取消,
(int)EnumAiCallState.访
};
//先筛选掉已经拨打的订单
/* var repeatOrder = db.Csvr_Ai_CallTask_Orders.GroupBy(n => n.Orderid).Where(n => n.Count() > 1).ToList();
List<int> exceptTaskId = new List<int>();
foreach(var item in repeatOrder)
{
var maxTaskId = item.Max(n=>n.Taskid);
exceptTaskId.AddRange(item.Where(n => n.Taskid.Value != maxTaskId).Select(n => n.Taskid.Value).ToList());
}*/
if (hasOrderFilter)
{
orderids = orderQuery.Select(n => n.ORDERID).Distinct().ToList();
}
var singleTaskQuery = db.Csvr_Ai_CallTask_Orders.GroupBy(n => n.Orderid).Select(n => n.Max(s => s.Taskid));
if (hasOrderFilter)
{
singleTaskQuery = db.Csvr_Ai_CallTask_Orders.Where(n => orderids.Contains(n.Orderid.Value)).GroupBy(n => n.Orderid).Select(n => n.Max(s => s.Taskid));
}
var orderCountQuery = from n in db.Csvr_Ai_CallTask.AsQueryable()
join b in singleTaskQuery
on n.Id equals b
group b by b into model
select new
{
taskid = model.Key,
count = model.Count()
};
var taskQuery = from n in db.Csvr_Ai_CallTask.AsQueryable()
join b in orderCountQuery
on n.Id equals b.taskid
select new
{
Robot = n.Robot,
Status = n.Status,
ai_hgrecord_status = n.ai_hgrecord_status,
CallRet = n.CallRet,
Labels = n.Labels,
OrderCount = b.count,
Ctime = n.Ctime
};
if (dto.xstime.HasValue)
{
taskQuery = taskQuery.Where(n => n.Ctime >= dto.xstime);
}
if (dto.xetime.HasValue)
{
dto.xetime = dto.xetime.Value.AddDays(1);
taskQuery = taskQuery.Where(n => n.Ctime <= dto.xetime);
}
var query = taskQuery.GroupBy(n => n.Robot).Select(model =>
new AiRecordSumView
{
Robot = model.Key,
RobotName = robotName,
Remark = remark,
Sms = sms == "1" ? "是" : "否",
UnConnectCount = model.Where(n => n.Status == 2 && n.CallRet != "0").Count(),
WaitCount = model.Where(n => n.Status != 2 && !aiExceptState.Contains(n.ai_hgrecord_status)).Count(),
DoneCount = model.Where(n => n.Status == 2).Count(),
CallCount = model.Where(n => n.CallRet == "0").Count(),
SuccessCount = model.Where(n => n.CallRet == "0" && n.Labels.Contains("正常访问")).Count(),
WaitOrder = model.Where(n => n.Status != 2 && !aiExceptState.Contains(n.ai_hgrecord_status)).Sum(n => n.OrderCount),
DoneOrder = model.Where(n => n.Status == 2).Sum(n => n.OrderCount),
CallOrder = model.Where(n => n.CallRet == "0").Sum(n => n.OrderCount),
SuccessOrder = model.Where(n => n.CallRet == "0" && n.Labels.Contains("正常访问")).Sum(n => n.OrderCount),
FailConnectCount = model.Where(n => n.ai_hgrecord_status == (int)EnumAiCallState.AI外呼失败挂断).Count(),
FailCount = model.Where(n => n.ai_hgrecord_status == (int)EnumAiCallState.AI外呼失败未答完).Count()
}
);
if (dto.robot == "-3")
{
var robotIds = robotList.Select(x => x.Robot).ToList();
//var robotFilter = orderQuery.Where(n => robotIds.Contains(n.Robot)).Select(s => s.Robot).ToList();
query = query.Where(n => robotIds.Contains(n.Robot));
}
else
{
var robotFilter = robotList.Where(n => n.Robot ==dto.robot).Select(s => s.Robot).ToList();
query = query.Where(n => robotFilter.Contains(n.Robot));
}
if (!string.IsNullOrWhiteSpace(dto.robotRemark))
{
var remarkFilter = robotList.Where(n => n.Remark == dto.robotRemark).Select(n => n.Robot).ToList();
//var robotFilter = orderQuery.Where(n => remarkFilter.Contains(n.Robot)).Select(s => s.Robot).ToList();
query = query.Where(n => remarkFilter.Contains(n.Robot));
}
PagerUtil.SetPager(ref query, ref pager);
var list = query.ToList();
stopwatch.Stop();
LogHelper.Info($"Ai统计查询耗时{stopwatch.ElapsedMilliseconds}ms]");
foreach (var item in list)
{
item.CallPercent = (item.DoneCount == 0 ? 0 : Math.Round(Convert.ToDecimal(item.CallCount) / item.DoneCount, 2) * 100) + "%";
item.SuccessPercent = (item.CallCount == 0 ? 0 : Math.Round(Convert.ToDecimal(item.SuccessCount) / item.CallCount, 2) * 100) + "%";
item.SuccessOrderPercent = (item.DoneOrder == 0 ? 0 : Math.Round(Convert.ToDecimal(item.SuccessOrder) / item.DoneOrder, 2) * 100) + "%";
item.CallCompletePercent = (item.DoneCount == 0 ? 0 : Math.Round(Convert.ToDecimal(item.SuccessCount) / item.DoneCount, 2) * 100) + "%";
item.OrderCompletePercent = (item.CallOrder == 0 ? 0 : Math.Round(Convert.ToDecimal(item.SuccessOrder) / item.CallOrder, 2) * 100) + "%";
}
return list;
}
}
}
public class AiCallTask_View
{
[DisplayName("任务Id")]
public int Id { get; set; }
public string sid { get; set; }
[DisplayName("机器人Id")]
public string Robot { get; set; }
[DisplayName("AI话术")]
public string RobotName { get; set; }
[DisplayName("任务描述")]
public string Remark { get; set; }
[DisplayName("订单号")]
public string ORDERID { get; set; }
//public string Name { get; set; }
/// <summary>
/// 电话
/// </summary>
[DisplayName("电话号码")]
public string CallNo { get; set; }
[DisplayName("事业部")]
public int CHANNEL { get; set; }
[DisplayName("事业部")]
public string CHANNELNAME { get; set; }
[DisplayName("客户编号")]
public string RESID { get; set; }
[DisplayName("客户新编号")]
public string UMID { get; set; }
[DisplayName("客户姓名")]
public string CNAME { get; set; }
public int? AiStatus { get; set; }
[DisplayName("回访状态")]
public string AiStatusName { get; set; }
[DisplayName("外呼时长(秒)")]
public int? SvcTime { get; set; }
[DisplayName("外呼时间")]
public DateTime? StartTime { get; set; }
[DisplayName("挂机时间")]
public DateTime? EndTime { get; set; }
[DisplayName("录音")]
public string Audio { get; set; }
[DisplayName("是否重拨")]
public int? HasCall { get; set; }
[DisplayName("是否重拨")]
public string HasCallName { get; set; }
public DateTime? Ctime { get; set; }
[DisplayName("轮次")]
public int Rounds { get; set; }
/*public string OrderIdList { get; set; }*/
/* public int? ReTryCount { get; set; }*/
}
public class AiCallTaskExportView:AiCallTaskDetailExportView
{
[DisplayName("AI话术")]
public string RobotName { get; set; }
[DisplayName("任务描述")]
public string Remark { get; set; }
}
public class AiCallTaskDetailExportView
{
/// <summary>
/// 电话
/// </summary>
[DisplayName("用户号码")]
public string CallNo { get; set; }
[DisplayName("事业部")]
public string CHANNELNAME { get; set; }
[DisplayName("客户Id")]
public string RESID { get; set; }
[DisplayName("客户姓名")]
public string CNAME { get; set; }
[DisplayName("订单号")]
public string ORDERID { get; set; }
//public string Name { get; set; }
[DisplayName("AI外呼状态")]
public string AiStatusName { get; set; }
[DisplayName("录音编号")]
public decimal Id { get; set; }
[DisplayName("外呼时长")]
public int? SvcTime { get; set; }
[DisplayName("是否重拨")]
public string HasCallName { get; set; }
[DisplayName("对话轮次")]
public int Rounds { get; set; }
[DisplayName("外呼时间")]
public DateTime? StartTime { get; set; }
[DisplayName("挂机时间")]
public DateTime? EndTime { get; set; }
[DisplayName("录音")]
public string Audio { get; set; }
}
public class AiRecordQueryDto
{
/// <summary>
/// 事业部
/// </summary>
public string channel { get; set; }
/// <summary>
/// 客户id
/// </summary>
public string resId { get; set; }
public string UMID { get; set; }
/// <summary>
/// 订单号
/// </summary>
public decimal? orderId { get; set; }
public string cname { get; set; }
public int aistatus { get; set; } = -3;
/// <summary>
/// 默认全部
/// </summary>
public int type { get; set; } = -3;
public string RobotId { get; set; } = "";
public int hasCall { get; set; } = -3;
public DateTime? xstime { get; set; }
public DateTime? xetime { get; set; }
public string robot { get; set; } = "-3";
public string robotRemark { get; set; }
}
public class AiRecordSumView
{
public string Robot { get; set; }
public string RobotName { get; set; }
public string Remark { get; set; }
public int WaitCount { get; set; }
public int DoneCount { get; set; }
public int UnConnectCount { get; set; }
public int FailCount { get; set; }
public int FailConnectCount { get; set; }
public string CallPercent { get; set; }
public string SuccessPercent { get; set; }
public int SuccessCount { get; set; }
public int CallCount { get; set; }
public string Sms { get; set; }
public int WaitOrder { get; set; }
public int DoneOrder { get; set; }
public int CallOrder { get; set; }
public int SuccessOrder { get; set; }
public string SuccessOrderPercent { get; set; }
/// <summary>
/// 外呼完成率(外呼成功人次/已外呼人次)
/// </summary>
public string CallCompletePercent { get; set; }
/// <summary>
/// 订单成功率(已成功订单数/已接通订单数)
/// </summary>
public string OrderCompletePercent { get; set; }
}
/// <summary>
/// 录音列表
/// </summary>
public class AiRecordDetailDto
{
public string robotId { get; set; }
public string robotName { get; set; }
public string phoneNo { get; set; }
public string audio { get; set; }
public string sessionBeginTime { get; set; }
public string sessionEndTime { get; set; }
public List<MsgContent> logUserSessionDetailList { get; set; }
}
public class MsgContent
{
public DateTime Time { get; set; }
public string Type { get; set; }
public string Content { get; set; }
public string Nodeid { get; set; }
public string Nodename { get; set; }
public string Ugc { get; set; }
}
public class AudioRecordView
{
/// <summary>
/// 默认为普通录音
/// </summary>
public int Type { get; set; } = 1;
public decimal? RECORDID { get; set; }
public string sid { get; set; }
public string FILENAME { get; set; }
public string RESID { get; set; }
public decimal? TIMELENGTH { get; set; }
public string SALESEID { get; set; }
public DateTime? TIMESTART { get; set; }
public DateTime? TIMEEND { get; set; }
public decimal? ORDERID { get; set; }
public string CONTENT { get; set; }
public DateTime? Ctime { get; set; }
public string COMPANYCODE { get; set; }
}
public class OrderTaskDto
{
public string Robot { get; set; }
public decimal ORDERID { get; set; }
public string CNAME { get; set; }
public int CHANNEL { get; set; }
public string RESID { get; set; }
public int? Taskid { get; set; }
}
public class GroupTask
{
public decimal TaskId { get; set; }
public decimal LinkOrderId { get; set; }
}
}