TrCallRecordRepository.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using Hotline.CallCenter.Calls;
  2. using Hotline.Orders;
  3. using Hotline.Repository.SqlSugar.DataPermissions;
  4. using Hotline.Settings;
  5. using Hotline.Share.Dtos.CallCenter;
  6. using Hotline.Share.Dtos.TrCallCenter;
  7. using Hotline.Share.Enums.CallCenter;
  8. using SqlSugar;
  9. using XF.Domain.Dependency;
  10. using static System.Runtime.InteropServices.JavaScript.JSType;
  11. namespace Hotline.Repository.SqlSugar.CallCenter
  12. {
  13. public class TrCallRecordRepository : BaseRepository<TrCallRecord>, ITrCallRecordRepository, IScopeDependency
  14. {
  15. public TrCallRecordRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider) : base(uow, dataPermissionFilterBuilder, serviceProvider)
  16. {
  17. }
  18. public async Task<List<BiCallDto>> GetQueryCalls(DateTime beginDate, DateTime endDate, string? Line)
  19. {
  20. List<int> dts = new List<int>();
  21. for (int i = 0; i < 24; i++)
  22. {
  23. dts.Add(i);
  24. }
  25. var listHour = Db.Reportable(dts).ToQueryable<int>();
  26. var list = Db.Queryable<TrCallRecord>()
  27. .Where(p => p.CreatedTime >= beginDate && p.CreatedTime <= endDate && p.CallDirection == ECallDirection.In)
  28. .WhereIF(!string.IsNullOrEmpty(Line), p => p.Gateway == Line)
  29. .GroupBy(p => p.CreatedTime.Hour)
  30. .Select(p => new
  31. {
  32. Hour = p.CreatedTime.Hour, //小时段
  33. Total = SqlFunc.AggregateCount(p.Id),
  34. Answered = SqlFunc.AggregateSum(SqlFunc.IIF(p.AnsweredTime != null, 1, 0)), //应答数
  35. Hanguped = SqlFunc.AggregateSum(SqlFunc.IIF(p.AnsweredTime == null && p.EndBy != null && p.EndBy.Value == EEndBy.To, 1, 0)),//挂断数
  36. })
  37. // .GroupBy(p => p.Hour)
  38. .MergeTable();
  39. var listCall = await listHour.LeftJoin(list, (x, p) => x.ColumnName == p.Hour)
  40. .OrderBy(x => x.ColumnName)
  41. .Select((x, p) => new BiCallDto()
  42. {
  43. Hour = x.ColumnName,
  44. Total = p.Total,
  45. Answered = p.Answered,
  46. Hanguped = p.Hanguped,
  47. })
  48. .ToListAsync();
  49. foreach (var call in listCall)
  50. {
  51. call.HourRange = call.Hour.ToString().PadLeft(2, '0') + ":00 - " + (call.Hour + 1).ToString().PadLeft(2, '0') + ":00";
  52. }
  53. return listCall;
  54. }
  55. /// <summary>
  56. ///
  57. /// </summary>
  58. /// <param name="beginDate"></param>
  59. /// <param name="endDate"></param>
  60. /// <param name="noConnectByeTimes"></param>
  61. /// <param name="effectiveTimes"></param>
  62. /// <param name="connectByeTimes"></param>
  63. /// <param name="CallInOverConnRingTime"></param>
  64. /// <param name="SeatChaoTime"></param>
  65. /// <param name="Line"></param>
  66. /// <returns></returns>
  67. public async Task<List<QueryCallsDetailDto>> QueryCallsHourDetail(DateTime beginDate, DateTime endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int CallInOverConnRingTime, int SeatChaoTime, string? Line)
  68. {
  69. List<int> dts = new List<int>();
  70. for (int i = 0; i < 24; i++)
  71. {
  72. dts.Add(i);
  73. }
  74. var listHour = Db.Reportable(dts).ToQueryable<int>();
  75. var list = Db.Queryable<TrCallRecord>()
  76. .Where(p => p.CreatedTime >= beginDate && p.CreatedTime <= endDate)
  77. // .Where(p => p.Gateway != "82826886" && SqlFunc.Length(p.Gateway) != 4)
  78. .WhereIF(!string.IsNullOrEmpty(Line), p => p.Gateway == Line)
  79. .GroupBy(p => p.CreatedTime.Hour)
  80. .Select(p => new
  81. {
  82. Hour = p.CreatedTime.Hour, //小时段
  83. InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
  84. InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null, 1, 0)),//呼入接通量
  85. NotAcceptedHang = SqlFunc.AggregateSum(SqlFunc.IIF(p.Duration == 0 && p.RingTimes <= noConnectByeTimes && p.RingTimes > 0, 1, 0)), //未接通秒挂
  86. TotalDurationIncomingCalls = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.OnState == EOnState.On, p.Duration, 0)), //呼入总时长
  87. InAvailableAnswer = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes, 1, 0)),//有效接通量
  88. InHangupImmediateWhenAnswered = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.Duration > 0 && p.Duration <= connectByeTimes, 1, 0)), //呼入接通秒挂
  89. TimeoutConnection = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.RingTimes >= CallInOverConnRingTime, 1, 0)),//超时接通量
  90. TimeoutSuspension = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= SeatChaoTime, 1, 0)),//超时挂断量
  91. QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.QueueTims > 0 && p.RingTimes == 0 && p.OnState == EOnState.NoOn, 1, 0)), //队列挂断
  92. IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.In && p.BeginIvrTime.HasValue && !p.BeginQueueTime.HasValue && !p.BeginRingTime.HasValue && p.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
  93. OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(p.CallDirection == ECallDirection.Out, 1, 0)),//呼出总量
  94. OutConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(p.OnState == EOnState.On && p.CallDirection == ECallDirection.Out && p.AnsweredTime != null, 1, 0))
  95. })
  96. .MergeTable();
  97. var listCall = await listHour.LeftJoin(list, (x, p) => x.ColumnName == p.Hour)
  98. .OrderBy(x => x.ColumnName)
  99. .Select((x, p) => new QueryCallsDetailDto()
  100. {
  101. Hour = x.ColumnName.ToString() + ":00 - " + x.ColumnName.ToString() + ":59",
  102. InTotal = p.InTotal,
  103. InConnectionQuantity = p.InConnectionQuantity,
  104. NotAcceptedHang = p.NotAcceptedHang,
  105. TotalDurationIncomingCalls = p.TotalDurationIncomingCalls,
  106. InAvailableAnswer = p.InAvailableAnswer,
  107. InHangupImmediateWhenAnswered = p.InHangupImmediateWhenAnswered,
  108. TimeoutConnection = p.TimeoutConnection,
  109. TimeoutSuspension = p.TimeoutSuspension,
  110. QueueByeCount = p.QueueByeCount,
  111. IvrByeCount = p.IvrByeCount,
  112. OutTotal = p.OutTotal,
  113. OutConnectionQuantity = p.OutConnectionQuantity
  114. })
  115. .ToListAsync();
  116. return listCall;
  117. }
  118. public async Task<List<TrCallHourDto>?> GetCallHourList(DateTime beginDate, DateTime? endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, string source)
  119. {
  120. TimeSpan timeDifference = endDate.Value.Subtract(beginDate).Duration();
  121. int hourDiff = (int)(timeDifference.TotalHours);
  122. //计算时间差
  123. int hour = Convert.ToInt32((endDate - beginDate).Value.TotalHours);
  124. List<DateTime> dts = new List<DateTime>() { beginDate };
  125. for (int i = 0; i < hour - 1; i++)
  126. {
  127. dts.Add(dts.Last().AddHours(1));
  128. }
  129. var list = await Db.Reportable(dts).ToQueryable<DateTime>()
  130. .LeftJoin<TrCallRecord>((it, o) => o.CreatedTime >= it.ColumnName && o.CreatedTime < it.ColumnName.AddHours(1) && o.CallDirection == ECallDirection.In)
  131. //.Where((it, o) => o.CallDirection == ECallDirection.In)
  132. .WhereIF(!string.IsNullOrEmpty(source), (it, o) => o.CDPN == source)
  133. .GroupBy((it, o) => it.ColumnName)
  134. .Select((it, o) => new TrCallHourDto()
  135. {
  136. DateTimeTo = it.ColumnName,
  137. Hour = it.ColumnName.Hour, //小时段
  138. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration >= effectiveTimes, 1, 0)),//有效接通
  139. ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration > 0 && o.Duration <= connectByeTimes, 1, 0)), //接通秒挂
  140. NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration == 0 && o.RingTimes <= noConnectByeTimes && o.RingTimes > 0, 1, 0)), //未接通秒挂
  141. QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.QueueTims > 0 && o.RingTimes == 0 && o.OnState == EOnState.NoOn, 1, 0)), //队列挂断
  142. IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
  143. })
  144. .MergeTable()
  145. .OrderBy(x => x.Hour)
  146. .ToListAsync();
  147. var resultList = list.GroupBy(x => x.Hour)
  148. .Select(x => new TrCallHourDto()
  149. {
  150. Hour = x.Key,
  151. HourTo = x.Key.ToString().PadLeft(2, '0') + ":00 - " + (x.Key).ToString().PadLeft(2, '0') + ":59",
  152. StartHourTo = x.Key.ToString().PadLeft(2, '0') + ":00",
  153. EndHourTo = x.Key.ToString().PadLeft(2, '0') + ":59",
  154. EffectiveCount = x.Sum(d => d.EffectiveCount),
  155. ConnectByeCount = x.Sum(d => d.ConnectByeCount),
  156. NoConnectByeCount = x.Sum(d => d.NoConnectByeCount),
  157. QueueByeCount = x.Sum(d => d.QueueByeCount),
  158. IvrByeCount = x.Sum(d => d.IvrByeCount),
  159. }).OrderBy(x => hour).ToList();
  160. return resultList;
  161. }
  162. /// <summary>
  163. /// 通话时段统计明细
  164. /// </summary>
  165. /// <returns></returns>
  166. public async Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes)
  167. {
  168. TimeSpan endHourTo = DateTime.Now.TimeOfDay;
  169. if (dto.StartHourTo.HasValue)
  170. {
  171. endHourTo = dto.StartHourTo.Value.Add(new TimeSpan(1, 0, 0));
  172. }
  173. RefAsync<int> total = 0;
  174. var res = await Db.Queryable<TrCallRecord>()
  175. .Where(x => x.CreatedTime >= dto.StartTime && x.CreatedTime <= dto.EndTime)
  176. .Where(x => x.CallDirection == ECallDirection.In)
  177. .WhereIF(!string.IsNullOrEmpty(dto.Source), x => x.CDPN == dto.Source)
  178. .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("QueueBye".Equals(dto.Type) || "queueByeCount".Equals(dto.Type)), x => x.QueueTims > 0 && x.RingTimes == 0) //队列挂断
  179. .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("IvrBye".Equals(dto.Type) || "ivrByeCount".Equals(dto.Type)), x => x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn)//IVR挂断
  180. .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("Effective".Equals(dto.Type) || "effectiveCount".Equals(dto.Type)), x => x.Duration >= effectiveTimes) //有效接通
  181. .WhereIF(!string.IsNullOrEmpty(dto.Type) && "Invalid".Equals(dto.Type), x => x.Duration > 0 && x.Duration < effectiveTimes)//无效接通
  182. .WhereIF(!string.IsNullOrEmpty(dto.Type) && "connectByeCount".Equals(dto.Type), x => x.Duration > 0 && x.Duration <= connectByeTimes) //接通秒挂
  183. .WhereIF(!string.IsNullOrEmpty(dto.Type) && "noConnectByeCount".Equals(dto.Type), x => x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0) //未接通秒挂
  184. .WhereIF(!string.IsNullOrEmpty(dto.Type) && "count".Equals(dto.Type), x =>
  185. (x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0) //未接通秒挂
  186. || (x.Duration > 0 && x.Duration <= connectByeTimes) //接通秒挂
  187. || (x.Duration >= effectiveTimes)//有效接通
  188. || (x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn) //IVR挂断
  189. || (x.QueueTims > 0 && x.RingTimes == 0))//队列挂断
  190. .WhereIF(dto.StartHourTo.HasValue, x => SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) >= dto.StartHourTo.Value && SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) < endHourTo)
  191. .Select(x => new BiSeatSwitchDto
  192. {
  193. CPN = x.CPN,
  194. CDPN = x.CDPN,
  195. CreatedTime = x.CreatedTime
  196. })
  197. .OrderByIF(dto is { SortRule: 0, SortField: "createdTime" }, x => x.CreatedTime, OrderByType.Asc)
  198. .OrderByIF(dto is { SortRule: 1, SortField: "createdTime" }, x => x.CreatedTime, OrderByType.Desc)
  199. .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
  200. return new TotalData<BiSeatSwitchDto>(res, total.Value);
  201. }
  202. public async Task<List<CallHotLineDto>> GetCallHotLineList(DateTime beginDate, DateTime endDate, string lineNum, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTims)
  203. {
  204. var list = await Db.Queryable<TrCallRecord>()
  205. .Where(x => x.CreatedTime >= beginDate && x.CreatedTime <= endDate && SqlFunc.Length(x.Gateway)>4)
  206. .WhereIF(!string.IsNullOrEmpty(lineNum), x => x.Gateway == lineNum)
  207. .GroupBy(x => x.Gateway)
  208. .Select(x => new CallHotLineDto()
  209. {
  210. GateWay = x.Gateway,
  211. CallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In, 1, 0)),//接通
  212. ConnectCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.OnState == EOnState.On, 1, 0)),//接通
  213. NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0, 1, 0)), //未接通秒挂
  214. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.Duration >= effectiveTimes, 1, 0)),//有效接通
  215. DurationSum = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.OnState == EOnState.On, x.Duration, 0)),//通话总时长
  216. ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.Duration > 0 && x.Duration <= connectByeTimes, 1, 0)), //接通秒挂
  217. TimelyAnswerCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.CallDirection == ECallDirection.In && x.OnState == EOnState.On && x.RingTimes <= ringTims, 1, 0))//及时应答
  218. }).ToListAsync();
  219. return list;
  220. }
  221. public ISugarQueryable<TrCallRecord> GetCallList(GetCallListDto dto)
  222. {
  223. return Db.Queryable<TrCallRecord>()
  224. .Includes(x => x.Order)
  225. .WhereIF(!string.IsNullOrEmpty(dto.CPN), x => x.CPN.Contains(dto.CPN))
  226. .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.CDPN.Contains(dto.CDPN))
  227. .WhereIF(!string.IsNullOrEmpty(dto.TelNo), x => x.TelNo.Contains(dto.TelNo))
  228. .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
  229. .WhereIF(dto.CallDirection != null, x => x.CallDirection == dto.CallDirection)
  230. .WhereIF(dto.OnState != null, x => x.OnState == dto.OnState)
  231. .WhereIF(dto.EndBy != null, x => x.EndBy == dto.EndBy)
  232. .WhereIF(dto.BeginIvrTimeStart.HasValue, x => x.BeginIvrTime >= dto.BeginIvrTimeStart)
  233. .WhereIF(dto.BeginIvrTimeEnd.HasValue, x => x.BeginIvrTime <= dto.BeginIvrTimeEnd)
  234. .WhereIF(dto.EndIvrTimeStart.HasValue, x => x.EndIvrTime >= dto.EndIvrTimeStart)
  235. .WhereIF(dto.EndIvrTimeEnd.HasValue, x => x.EndIvrTime <= dto.EndIvrTimeEnd)
  236. .WhereIF(dto.BeginQueueTimeStart.HasValue, x => x.BeginQueueTime >= dto.BeginQueueTimeEnd)
  237. .WhereIF(dto.BeginQueueTimeEnd.HasValue, x => x.BeginQueueTime <= dto.BeginQueueTimeEnd)
  238. .WhereIF(dto.EndQueueTimeStart.HasValue, x => x.EndQueueTime >= dto.EndQueueTimeStart)
  239. .WhereIF(dto.EndQueueTimeEnd.HasValue, x => x.EndQueueTime <= dto.EndQueueTimeEnd)
  240. .WhereIF(dto.AnsweredTimeStart.HasValue, x => x.AnsweredTime >= dto.AnsweredTimeStart)
  241. .WhereIF(dto.AnsweredTimeEnd.HasValue, x => x.AnsweredTime <= dto.AnsweredTimeEnd)
  242. .WhereIF(dto.OverTimeStart.HasValue, x => x.OverTime >= dto.OverTimeStart)
  243. .WhereIF(dto.OverTimeEnd.HasValue, x => x.OverTime <= dto.OverTimeEnd)
  244. .WhereIF(dto.BeginRingTimeStart.HasValue, x => x.BeginRingTime >= dto.BeginRingTimeStart)
  245. .WhereIF(dto.BeginRingTimeEnd.HasValue, x => x.BeginRingTime <= dto.BeginRingTimeEnd)
  246. .WhereIF(dto.EndRingTimeStart.HasValue, x => x.EndRingTimg >= dto.EndRingTimeStart)
  247. .WhereIF(dto.EndRingTimeEnd.HasValue, x => x.EndRingTimg <= dto.EndRingTimeEnd)
  248. .WhereIF(dto.CallTimeStart.HasValue, x => x.CreatedTime >= dto.CallTimeStart)
  249. .WhereIF(dto.CallTimeEnd.HasValue, x => x.CreatedTime <= dto.CallTimeEnd)
  250. .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.Order.No.Contains(dto.OrderNo))
  251. .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title))
  252. .WhereIF(!string.IsNullOrEmpty(dto.Gateway), x => x.Gateway.Contains(dto.Gateway))
  253. .WhereIF(dto.IsSensitiveWord.HasValue && dto.IsSensitiveWord == true, d => d.Sensitive != null && SqlFunc.JsonArrayLength(d.Sensitive) > 0)
  254. .WhereIF(!string.IsNullOrEmpty(dto.SensitiveWord), d => SqlFunc.JsonArrayAny(d.Sensitive, dto.SensitiveWord))
  255. .WhereIF(dto.IsAiAnswered == true, x => string.IsNullOrEmpty(x.UserId) == true && x.BeginIvrTime.HasValue && x.EndIvrTime.HasValue)
  256. .WhereIF(dto.PhoneTypes != null, x => x.PhoneTypes == dto.PhoneTypes)
  257. .OrderByDescending(x => x.CreatedTime);
  258. }
  259. public async Task<List<QueryCallDateStatisticsDetailResp>> QueryCallDateStatisticsDetail(DateTime startTime, DateTime endTime)
  260. {
  261. var query = Db.Queryable<TrCallRecord>()
  262. .Where(x => x.CreatedTime >= startTime && x.CreatedTime <= endTime && SqlFunc.Length(x.Gateway) > 4 && x.CallDirection == ECallDirection.In)
  263. .GroupBy(x => x.CreatedTime.ToString("yyyy-MM-dd"))
  264. .Select(x => new QueryCallDateStatisticsDetailResp()
  265. {
  266. Date = x.CreatedTime.ToString("yyyy-MM-dd"),
  267. IvrCallInTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
  268. PersonCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1", 1, 0)),
  269. EnterpriseCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2", 1, 0)),
  270. GaoXiaoCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "3", 1, 0)),
  271. AiCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Gateway == "82826886", 1, 0)),
  272. PersonCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1" && x.OnState == EOnState.On, 1, 0)),
  273. EnterpriseCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.OnState == EOnState.On, 1, 0)),
  274. GaoXiaoCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "3" && x.OnState == EOnState.On, 1, 0)),
  275. AiCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Gateway == "82826886", 1, 0)),
  276. PersonRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1" && x.QueueTims > 0 && x.OnState == EOnState.NoOn, 1, 0)),//个人服务挂断
  277. EnterpriseRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.QueueTims > 0 && x.OnState == EOnState.NoOn, 1, 0)), //企业挂断
  278. GaoXiaoRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "3" && x.QueueTims > 0 && x.OnState == EOnState.NoOn, 1, 0)), //高效办成一件事挂断
  279. IvrRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
  280. })
  281. .OrderBy(x => x.Date);
  282. return await query.ToListAsync();
  283. }
  284. public async Task<List<QueryPersonCallDateStatisticsDetailResp>> QueryPersonCallDateStatisticsDetail(DateTime startTime, DateTime endTime)
  285. {
  286. var query = Db.Queryable<TrCallRecord>()
  287. .Where(x => x.CreatedTime >= startTime && x.CreatedTime <= endTime && SqlFunc.Length(x.Gateway) > 4 && x.CallDirection == ECallDirection.In)
  288. .GroupBy(x => x.CreatedTime.ToString("yyyy-MM-dd"))
  289. .Select(x => new QueryPersonCallDateStatisticsDetailResp()
  290. {
  291. Date = x.CreatedTime.ToString("yyyy-MM-dd"),
  292. PersonCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1", 1, 0)),
  293. PersonCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1" && x.OnState == EOnState.On, 1, 0)),
  294. //PersonRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1" && x.OnState == EOnState.NoOn, 1, 0)),//个人服务挂断
  295. PersonQueueOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "1" && x.QueueTims > 0 && x.RingTimes == 0 && x.OnState == EOnState.NoOn, 1, 0)),//个人服务队列挂断
  296. PersonWaitOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length -1,1) =="1" && x.RingTimes>0 && x.OnState == EOnState.NoOn,1,0)) //个人服务等待挂断
  297. })
  298. .OrderBy(x => x.Date);
  299. return await query.ToListAsync();
  300. }
  301. public async Task<List<QueryEnterpriseCallDateStatisticsDetailResp>> QueryEnterpriseCallDateStatisticsDetail(DateTime startTime,DateTime endTime)
  302. {
  303. var query = Db.Queryable<TrCallRecord>()
  304. .Where(x => x.CreatedTime >= startTime && x.CreatedTime <= endTime && SqlFunc.Length(x.Gateway) > 4 && x.CallDirection == ECallDirection.In)
  305. .GroupBy(x => x.CreatedTime.ToString("yyyy-MM-dd"))
  306. .Select(x => new QueryEnterpriseCallDateStatisticsDetailResp()
  307. {
  308. Date = x.CreatedTime.ToString("yyyy-MM-dd"),
  309. EnterpriseCallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2", 1, 0)),
  310. EnterpriseCallInPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.OnState == EOnState.On, 1, 0)),
  311. //EnterpriseRingOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.QueueTims > 0 && x.RingTimes == 0 && x.OnState == EOnState.NoOn, 1, 0)), //企业挂断
  312. EnterpriseQueueOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.QueueTims > 0 && x.RingTimes == 0 && x.OnState == EOnState.NoOn, 1, 0)),//企业服务队列挂断
  313. EnterpriseWaitOffCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.IvrDtmf.Substring(x.IvrDtmf.Length - 1, 1) == "2" && x.RingTimes > 0 && x.OnState == EOnState.NoOn, 1, 0)) //企业服务等待挂断
  314. })
  315. .OrderBy(x => x.Date);
  316. return await query.ToListAsync();
  317. }
  318. public async Task<List<QueryCallOutDateStatisticsDetailResp>> QueryCallOutDateStatisticsDetail(DateTime startTime,DateTime endTime,List<string> enterpriseTels)
  319. {
  320. var callTable = Db.Queryable<TrCallRecord>()
  321. .Where(x => x.CreatedTime >= startTime && x.CreatedTime <= endTime && SqlFunc.Length(x.Gateway) > 4 && x.CallDirection == ECallDirection.Out && SqlFunc.Length(x.TelNo)==4)
  322. .GroupBy(x => x.CreatedTime.ToString("yyyy-MM-dd"))
  323. .Select(x => new QueryCallOutDateStatisticsDetailResp()
  324. {
  325. Date = x.CreatedTime.ToString("yyyy-MM-dd"),
  326. PersonCallOutCount = SqlFunc.AggregateSum(SqlFunc.IIF(1 == 1 && !enterpriseTels.Contains(x.TelNo),1,0)),
  327. EnterpriseCallOutCount = SqlFunc.AggregateSum(SqlFunc.IIF(1== 1 && enterpriseTels.Contains(x.TelNo),1,0)),
  328. PersonCallOutPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(!enterpriseTels.Contains(x.TelNo) && x.OnState == EOnState.On, 1, 0)),
  329. EnterpriseCallOutPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(enterpriseTels.Contains(x.TelNo) && x.OnState == EOnState.On, 1, 0)),
  330. }).MergeTable();
  331. var aiVisitCallTable = Db.Queryable<AiOrderVisitDetail>()
  332. .Where(x => x.CallTime >= startTime && x.CallTime <= endTime)
  333. .GroupBy(x => x.CallTime.Value.ToString("yyyy-MM-dd"))
  334. .Select(x => new QueryCallOutDateStatisticsDetailResp()
  335. {
  336. Date = x.CallTime.Value.ToString("yyyy-MM-dd"),
  337. AiVisitCallOutCount = SqlFunc.AggregateCount(x.Id),
  338. AiVisitCallOutPutthroughCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.AiIsContact!=null || x.AiVolved!=null || x.AiOrgProcessingResults != null ,1,0))
  339. }).MergeTable();
  340. var list = await callTable.LeftJoin(aiVisitCallTable, (a, b) => a.Date == b.Date)
  341. .Select((a, b) => new QueryCallOutDateStatisticsDetailResp()
  342. {
  343. Date = a.Date,
  344. PersonCallOutCount = a.PersonCallOutCount,
  345. EnterpriseCallOutCount = a.EnterpriseCallOutCount,
  346. AiVisitCallOutCount = b.AiVisitCallOutCount,
  347. AiCallOutCount = 0,
  348. PersonCallOutPutthroughCount= a.PersonCallOutPutthroughCount,
  349. EnterpriseCallOutPutthroughCount = a.EnterpriseCallOutPutthroughCount,
  350. AiVisitCallOutPutthroughCount = b.AiVisitCallOutPutthroughCount,
  351. AiCallOutPutthroughCount = 0,
  352. }).OrderBy(a=>a.Date).ToListAsync();
  353. return list;
  354. }
  355. }
  356. }