BiCallController.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. using Hotline.Application.ExportExcel;
  2. using Hotline.Share.Tools;
  3. using Hotline.Application.StatisticalReport;
  4. using Hotline.Application.Systems;
  5. using Hotline.Caching.Interfaces;
  6. using Hotline.CallCenter.Calls;
  7. using Hotline.CallCenter.Tels;
  8. using Hotline.Share.Dtos;
  9. using Hotline.Share.Dtos.CallCenter;
  10. using Hotline.Share.Dtos.Order;
  11. using Hotline.Share.Dtos.TrCallCenter;
  12. using Hotline.Share.Requests;
  13. using Hotline.Tools;
  14. using Hotline.Users;
  15. using MapsterMapper;
  16. using Microsoft.AspNetCore.Authorization;
  17. using Microsoft.AspNetCore.Mvc;
  18. using SqlSugar;
  19. using System.Data;
  20. using System.Linq.Dynamic.Core;
  21. using XF.Domain.Repository;
  22. using Hotline.Settings;
  23. using XF.Utility.EnumExtensions;
  24. using Hotline.Share.Enums.CallCenter;
  25. using Hotline.Repository.SqlSugar.Extensions;
  26. using Hotline.Api.Filter;
  27. using Hotline.Share.Dtos.Order.Publish;
  28. using Hotline.Application.StatisticalReport.CallReport;
  29. using DocumentFormat.OpenXml.Spreadsheet;
  30. using DocumentFormat.OpenXml.Wordprocessing;
  31. using NPOI.SS.Formula.Functions;
  32. namespace Hotline.Api.Controllers.Bi;
  33. /// <summary>
  34. /// 话务报表
  35. /// </summary>
  36. public class BiCallController : BaseController
  37. {
  38. private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  39. private readonly BaseDataApplication _baseDataApplication;
  40. private readonly IRepository<User> _userRepository;
  41. private readonly IRepository<TelRest> _telRestRepository;
  42. private readonly IMapper _mapper;
  43. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  44. private readonly IRepository<Work> _workRepository;
  45. private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
  46. private readonly ICallReportApplication _callReportApplication;
  47. private readonly IExportApplication _exportApplication;
  48. public BiCallController(
  49. IRepository<TrCallRecord> trCallRecordRepository,
  50. IRepository<User> userRepository,
  51. IRepository<TelRest> telRestRepository,
  52. IMapper mapper,
  53. ISystemSettingCacheManager systemSettingCacheManager,
  54. ISystemDicDataCacheManager sysDicDataCacheManager,
  55. IRepository<Work> workRepository,
  56. ICallReportApplication callReportApplication,
  57. IExportApplication exportApplication,
  58. BaseDataApplication baseDataApplication)
  59. {
  60. _trCallRecordRepository = trCallRecordRepository;
  61. _userRepository = userRepository;
  62. _telRestRepository = telRestRepository;
  63. _mapper = mapper;
  64. _systemSettingCacheManager = systemSettingCacheManager;
  65. _workRepository = workRepository;
  66. _sysDicDataCacheManager = sysDicDataCacheManager;
  67. _callReportApplication = callReportApplication;
  68. _exportApplication = exportApplication;
  69. _baseDataApplication = baseDataApplication;
  70. }
  71. /// <summary>
  72. /// 话务统计分析
  73. /// </summary>
  74. /// <param name="dto"></param>
  75. /// <returns></returns>
  76. [HttpGet("calls")]
  77. [AllowAnonymous]
  78. public async Task<List<BiCallDto>> QueryCallsAsync([FromQuery] BiQueryCallsDto dto)
  79. => await _callReportApplication.QueryCallsAsync(dto, HttpContext.RequestAborted);
  80. /// <summary>
  81. /// 话务统计分析---导出
  82. /// </summary>
  83. /// <param name="dto"></param>
  84. /// <returns></returns>
  85. [HttpPost("calls_export")]
  86. [LogFilterAlpha("导出日志")]
  87. [AllowAnonymous]
  88. public async Task<FileStreamResult> ExportQueryCallsAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
  89. => ExcelStreamResult(
  90. _exportApplication.GetExcelStream(
  91. dto,
  92. await _callReportApplication.QueryCallsAsync(dto.QueryDto, HttpContext.RequestAborted),
  93. list =>
  94. {
  95. return new BiCallDto()
  96. {
  97. HourRange = "合计",
  98. Hour = 13,
  99. Total = list.Sum(p => p.Total),
  100. Answered = list.Sum(p => p.Answered),
  101. Hanguped = list.Sum(p => p.Hanguped)
  102. };
  103. }),
  104. "话务统计分析");
  105. /// <summary>
  106. /// 话务日期统计
  107. /// </summary>
  108. /// <param name="dto"></param>
  109. /// <returns></returns>
  110. [HttpGet("query_calls_statistics")]
  111. public async Task<TotalList<QueryCallsDetailStatistics>> QueryCallsStatisticsAsync([FromQuery] StartEndTimeDto dto)
  112. {
  113. var items = await _callReportApplication.QueryCallsDetailStatisticsAsync(dto, HttpContext.RequestAborted);
  114. var total = new QueryCallsDetailStatistics
  115. {
  116. Date = "合计",
  117. //InTotal = items.Sum(m => m.InTotal),
  118. NotAcceptedHang = items.Sum(m => m.NotAcceptedHang),
  119. InConnectionQuantity = items.Sum(m => m.InConnectionQuantity),
  120. InNotAnswered = items.Sum(m => m.InNotAnswered),
  121. IvrByeCount = items.Sum(m => m.IvrByeCount),
  122. OutConnectionQuantity = items.Sum(m => m.OutConnectionQuantity),
  123. OutNotAnswered = items.Sum(m => m.OutNotAnswered)
  124. };
  125. return new TotalList<QueryCallsDetailStatistics>(items, total);
  126. }
  127. /// <summary>
  128. /// 话务日期统计-导出
  129. /// </summary>
  130. /// <param name="dto"></param>
  131. /// <returns></returns>
  132. [HttpPost("query_calls_statistics_export")]
  133. [LogFilterAlpha("导出日志")]
  134. public async Task<FileStreamResult> QueryCallsStatisticsExportAsync([FromBody] ExportExcelDto<StartEndTimeDto> dto)
  135. {
  136. var items = (await _callReportApplication.QueryCallsDetailStatisticsAsync(dto.QueryDto, HttpContext.RequestAborted));
  137. return _exportApplication.GetExcelFile(dto, items, "话务日期统计", "Date");
  138. }
  139. /// <summary>
  140. /// 话务日期统计详情
  141. /// </summary>
  142. /// <param name="dto"></param>
  143. /// <returns></returns>
  144. [HttpGet("query_calls_statistics_detail")]
  145. public async Task<PagedDto<QueryCallsStatisticsDetailOutDto>> QueryCallsStatisticsDetailAsync([FromQuery] QueryCallsStatisticsDetailInDto dto)
  146. => (await _callReportApplication.QueryCallsStatisticsDetailAsync(dto, HttpContext.RequestAborted))
  147. .ToPaged();
  148. /// <summary>
  149. /// 话务日期统计详情--导出
  150. /// </summary>
  151. /// <param name="dto"></param>
  152. /// <returns></returns>
  153. [HttpPost("query_calls_statistics_detail/export")]
  154. [LogFilterAlpha("导出日志")]
  155. public async Task<FileStreamResult> QueryCallsStatisticsDetailAsync([FromBody] ExportExcelDto<QueryCallsStatisticsDetailInDto> dto)
  156. {
  157. var items = (await _callReportApplication.QueryCallsStatisticsDetailAsync(dto.QueryDto, HttpContext.RequestAborted)).Item2;
  158. return _exportApplication.GetExcelFile(dto, items, "话务日期统计详情", "OrderNo");
  159. }
  160. /// <summary>
  161. /// 话务日期统计详情页面基础数据
  162. /// </summary>
  163. /// <param name="dto"></param>
  164. /// <returns></returns>
  165. [HttpGet("query_calls_statistics_detail/base-data")]
  166. public Dictionary<string, dynamic> QueryCallsStatisticsDetailBaseData()
  167. {
  168. return new Dictionary<string, dynamic>
  169. {
  170. { "endBy", EnumExts.GetDescriptions<EEndBy>() }
  171. };
  172. }
  173. /// <summary>
  174. /// 话务日期明细
  175. /// </summary>
  176. /// <param name="dto"></param>
  177. /// <returns></returns>
  178. [HttpGet("query_calls_detail")]
  179. public async Task<object> QueryCallsDetailAsync([FromQuery] BiQueryCallsDto dto)
  180. {
  181. var items = await _callReportApplication.QueryCallsDetailAsync(dto);
  182. var total = new QueryCallsDetailDto
  183. {
  184. Date = "合计",
  185. Hour = "",
  186. InTotal = items.Sum(p => p.InTotal),
  187. InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
  188. NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
  189. TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
  190. InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
  191. InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
  192. TimeoutConnection = items.Sum(p => p.TimeoutConnection),
  193. TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
  194. QueueByeCount = items.Sum(p => p.QueueByeCount),
  195. IvrByeCount = items.Sum(p => p.IvrByeCount),
  196. OutTotal = items.Sum(p => p.OutTotal),
  197. OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
  198. };
  199. return new { List = items, Total = total };
  200. }
  201. /// <summary>
  202. /// 话务日期明细--导出
  203. /// </summary>
  204. /// <param name="dto"></param>
  205. /// <returns></returns>
  206. [HttpPost("query_calls_detail_export")]
  207. [LogFilterAlpha("导出日志")]
  208. public async Task<FileStreamResult> QueryCallsDetailExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
  209. {
  210. return ExcelStreamResult(
  211. _exportApplication.GetExcelStream(
  212. dto,
  213. await _callReportApplication.QueryCallsDetailAsync(dto.QueryDto),
  214. items =>
  215. {
  216. return new QueryCallsDetailDto
  217. {
  218. Date = "合计",
  219. Hour = "",
  220. InTotal = items.Sum(p => p.InTotal),
  221. InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
  222. NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
  223. TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
  224. InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
  225. InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
  226. TimeoutConnection = items.Sum(p => p.TimeoutConnection),
  227. TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
  228. QueueByeCount = items.Sum(p => p.QueueByeCount),
  229. IvrByeCount = items.Sum(p => p.IvrByeCount),
  230. OutTotal = items.Sum(p => p.OutTotal),
  231. OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
  232. };
  233. })
  234. , "话务日期明细数据");
  235. }
  236. /// <summary>
  237. /// 话务日期明细--呼入明细
  238. /// </summary>
  239. /// <param name="dto"></param>
  240. /// <returns></returns>
  241. [HttpGet("query_incall_calls_list")]
  242. public async Task<PagedDto<CallRecordOutDto>> GetInCallCallListAsync([FromQuery] BiQueryCallsDto dto)
  243. {
  244. var (total, items) = await _callReportApplication.QueryCallsDetailInTotalAsync(dto, false);
  245. return new PagedDto<CallRecordOutDto>(total, items);
  246. }
  247. /// <summary>
  248. /// 话务日期明细----导出
  249. /// </summary>
  250. /// <param name="dto"></param>
  251. /// <returns></returns>
  252. [HttpPost("query_incall_calls_list_export")]
  253. [LogFilterAlpha("导出日志")]
  254. public async Task<FileStreamResult> GetInCallCallListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
  255. {
  256. var (total, data) = await _callReportApplication.QueryCallsDetailInTotalAsync(dto.QueryDto, dto.IsExportAll);
  257. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<CallRecordOutDto>(dto.ColumnInfos);
  258. var dtos = data
  259. .Select(stu => _mapper.Map(stu, typeof(CallRecordOutDto), dynamicClass))
  260. .Cast<object>()
  261. .ToList();
  262. var stream = ExcelHelper.CreateStream(dtos);
  263. return ExcelStreamResult(
  264. _exportApplication.GetExcelStream(
  265. dto,
  266. (await _callReportApplication.QueryCallsDetailInTotalAsync(dto.QueryDto, dto.IsExportAll)).Item2
  267. ),
  268. dto.QueryDto.TypeCode == "2" ? "话务日期-接通明细数据" : "话务日期-总量明细数据");
  269. }
  270. /// <summary>
  271. /// 话务日期明细--时间段
  272. /// </summary>
  273. /// <param name="dto"></param>
  274. /// <returns></returns>
  275. [HttpGet("query_calls_hour_detail_list")]
  276. public async Task<TotalList<QueryCallsDetailDto>> QueryCallsHourDetailListAsync([FromQuery] BiQueryCallsDto dto)
  277. {
  278. var items = await _callReportApplication.QueryCallsHourDetailAsync(dto, HttpContext.RequestAborted);
  279. var total = new QueryCallsDetailDto
  280. {
  281. Date = "",
  282. Hour = "合计",
  283. InTotal = items.Sum(p => p.InTotal),
  284. InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
  285. NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
  286. TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
  287. InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
  288. InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
  289. TimeoutConnection = items.Sum(p => p.TimeoutConnection),
  290. TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
  291. QueueByeCount = items.Sum(p => p.QueueByeCount),
  292. IvrByeCount = items.Sum(p => p.IvrByeCount),
  293. OutTotal = items.Sum(p => p.OutTotal),
  294. OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
  295. };
  296. return new TotalList<QueryCallsDetailDto>(items, total);
  297. }
  298. /// <summary>
  299. /// 话务日期明细--时间段--导出
  300. /// </summary>
  301. /// <param name="dto"></param>
  302. /// <returns></returns>
  303. [HttpPost("query_calls_hour_detail_list_export")]
  304. [LogFilterAlpha("导出日志")]
  305. public async Task<FileStreamResult> QueryCallsHourDetailListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
  306. => ExcelStreamResult(
  307. _exportApplication.GetExcelStream(
  308. dto,
  309. await _callReportApplication.QueryCallsHourDetailAsync(dto.QueryDto, HttpContext.RequestAborted),
  310. items =>
  311. {
  312. return new QueryCallsDetailDto
  313. {
  314. Date = "",
  315. Hour = "合计",
  316. InTotal = items.Sum(p => p.InTotal),
  317. InConnectionQuantity = items.Sum(p => p.InConnectionQuantity),
  318. NotAcceptedHang = items.Sum(p => p.NotAcceptedHang),
  319. TotalDurationIncomingCalls = items.Sum(p => p.TotalDurationIncomingCalls),
  320. InAvailableAnswer = items.Sum(p => p.InAvailableAnswer),
  321. InHangupImmediateWhenAnswered = items.Sum(p => p.InHangupImmediateWhenAnswered),
  322. TimeoutConnection = items.Sum(p => p.TimeoutConnection),
  323. TimeoutSuspension = items.Sum(p => p.TimeoutSuspension),
  324. QueueByeCount = items.Sum(p => p.QueueByeCount),
  325. IvrByeCount = items.Sum(p => p.IvrByeCount),
  326. OutTotal = items.Sum(p => p.OutTotal),
  327. OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
  328. };
  329. })
  330. , "话务日期明细-时间段");
  331. /// <summary>
  332. /// 坐席话务统计分析
  333. /// </summary>
  334. /// <param name="dto"></param>
  335. /// <returns></returns>
  336. [HttpPost("seats/export")]
  337. [LogFilterAlpha("导出日志")]
  338. public async Task<FileStreamResult> ExportSeatss([FromBody] ExportExcelDto<ReportRequiredPagedRequest> dto)
  339. {
  340. return ExcelStreamResult(
  341. _exportApplication.GetExcelStream(
  342. dto,
  343. await _callReportApplication.QuerySeatCallAsync(dto.QueryDto, HttpContext.RequestAborted),
  344. list =>
  345. {
  346. return new BiSeatCallsDto()
  347. {
  348. Name = "合计",
  349. InTotal = list.Sum(p => p.InTotal),
  350. InAnswered = list.Sum(p => p.InAnswered),
  351. InHangupImmediate = list.Sum(p => p.InHangupImmediate),
  352. InHanguped = list.Sum(m => m.InHanguped),
  353. OutDurationAvg = list.Sum(m => m.OutDurationAvg),
  354. InAvailableAnswer = list.Sum(m => m.InAvailableAnswer),
  355. InHangupImmediateWhenAnswered = list.Sum(m => m.InHangupImmediateWhenAnswered),
  356. OutTotal = list.Sum(m => m.OutTotal),
  357. OutAnswered = list.Sum(m => m.OutAnswered),
  358. LoginDuration = list.Sum(m => m.LoginDuration),
  359. RestDuration = list.Sum(m => m.RestDuration),
  360. InDurationAvg = list.Sum(m => m.InDurationAvg)
  361. };
  362. })
  363. , "坐席话务统计分析");
  364. }
  365. /// <summary>
  366. /// 坐席话务统计分析
  367. /// </summary>
  368. /// <param name="dto"></param>
  369. /// <returns></returns>
  370. [HttpGet("seats")]
  371. [AllowAnonymous]
  372. public async Task<TotalList<BiSeatCallsDto>> QuerySeatCallsAsync([FromQuery] ReportRequiredPagedRequest dto)
  373. {
  374. var items = await _callReportApplication.QuerySeatCallAsync(dto, HttpContext.RequestAborted);
  375. var total = new BiSeatCallsDto
  376. {
  377. Name="合计", // 坐席姓名
  378. UserId="", // 用户ID
  379. StaffNo="", // 工号
  380. TelNo="", // 分机号
  381. InTotal = items.Sum(m => m.InTotal), // 呼入总量
  382. OutTotal = items.Sum(m => m.OutTotal), // 呼出总量
  383. InAnswered = items.Sum(m => m.InAnswered), // 呼入接通量
  384. OutAnswered = items.Sum(m => m.OutAnswered), // 呼出接通量
  385. InHangupImmediate = items.Sum(m => m.InHangupImmediate), // 呼入秒挂
  386. InHanguped = items.Sum(m => m.InHanguped), // 呼入未接
  387. InDurationAvg = items.Sum(m => m.InDurationAvg), // 呼入平均时长
  388. OutDurationAvg = items.Sum(m => m.OutDurationAvg), // 呼出平均时长
  389. InAvailableAnswer = items.Sum(m => m.InAvailableAnswer), // 有效接通量
  390. InHangupImmediateWhenAnswered = items.Sum(m => m.InHangupImmediateWhenAnswered), // 呼入接通秒挂
  391. LoginDuration = items.Sum(m => m.LoginDuration), // 登录时长(秒)
  392. RestDuration = items.Sum(m => m.RestDuration), // 小休+摘机时长 (秒)
  393. };
  394. return new TotalList<BiSeatCallsDto>(items, total);
  395. }
  396. /// <summary>
  397. /// 坐席话务统计分析明细
  398. /// </summary>
  399. /// <param name="dto"></param>
  400. /// <returns></returns>
  401. [HttpGet("seats/list")]
  402. public async Task<PagedDto<CallRecordOutDto>> QuerySeatCallsListAsync([FromQuery] BiQueryCallsListDto dto)
  403. {
  404. var (total, items) = await _callReportApplication.QuerySeatCallsListAsync(dto, false);
  405. return new PagedDto<CallRecordOutDto>(total, items);
  406. }
  407. /// <summary>
  408. /// 坐席话务统计分析明细导出
  409. /// </summary>
  410. /// <param name="dto"></param>
  411. /// <returns></returns>
  412. [HttpPost("seats/list/export")]
  413. [LogFilterAlpha("导出日志")]
  414. public async Task<FileStreamResult> QuerySeatCallsListExportAsync([FromBody] ExportExcelDto<BiQueryCallsListDto> dto)
  415. {
  416. var (total, data) = await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll);
  417. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<CallRecordOutDto>(dto.ColumnInfos);
  418. var dtos = data
  419. .Select(stu => _mapper.Map(stu, typeof(CallRecordOutDto), dynamicClass))
  420. .Cast<object>()
  421. .ToList();
  422. var stream = ExcelHelper.CreateStream(dtos);
  423. return ExcelStreamResult(
  424. _exportApplication.GetExcelStream(
  425. dto,
  426. (await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll)).Item2
  427. ),
  428. "坐席话务统计分析明细");
  429. }
  430. /// <summary>
  431. /// 小休统计
  432. /// </summary>
  433. /// <param name="dto"></param>
  434. /// <returns></returns>
  435. [HttpGet("rests")]
  436. [AllowAnonymous]
  437. public async Task<IReadOnlyList<BiSeatRestDto>> QuerySeatRest([FromQuery] QuerySeatRestRequest dto)
  438. {
  439. return await _telRestRepository.Queryable()
  440. .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
  441. .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), x => x.StaffNo.Contains(dto.StaffNo))
  442. .Where(x => x.CreationTime >= dto.StartTime)
  443. .Where(x => x.CreationTime <= dto.EndTime)
  444. .GroupBy(x => new { x.UserId, x.StaffNo, x.UserName })
  445. .Select(x => new BiSeatRestDto
  446. {
  447. UserId = x.UserId,
  448. StaffNo = x.StaffNo,
  449. UserName = x.UserName,
  450. RestCount = SqlFunc.AggregateCount(x.Id),
  451. RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
  452. CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
  453. })
  454. .OrderByIF(dto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
  455. .OrderByIF(dto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
  456. .MergeTable()
  457. .ToListAsync(HttpContext.RequestAborted);
  458. }
  459. /// <summary>
  460. /// 小休统计
  461. /// </summary>
  462. /// <param name="dto"></param>
  463. /// <returns></returns>
  464. [HttpPost("rests/export")]
  465. [LogFilterAlpha("导出日志")]
  466. public async Task<FileStreamResult> QuerySeatRestExport([FromBody] ExportExcelDto<QuerySeatRestRequest> dto)
  467. {
  468. var query = await _telRestRepository.Queryable()
  469. .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.UserName), x => x.UserName.Contains(dto.QueryDto.UserName))
  470. .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.StaffNo), x => x.StaffNo.Contains(dto.QueryDto.StaffNo))
  471. .Where(x => x.CreationTime >= dto.QueryDto.StartTime)
  472. .Where(x => x.CreationTime <= dto.QueryDto.EndTime)
  473. .GroupBy(x => new { x.UserId, x.StaffNo, x.UserName })
  474. .Select(x => new BiSeatRestDto
  475. {
  476. UserId = x.UserId,
  477. StaffNo = x.StaffNo,
  478. UserName = x.UserName,
  479. RestCount = SqlFunc.AggregateCount(x.Id),
  480. RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
  481. CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
  482. })
  483. .OrderByIF(dto.QueryDto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
  484. .OrderByIF(dto.QueryDto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
  485. .MergeTable()
  486. .ToListAsync(HttpContext.RequestAborted);
  487. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatRestDto>(dto.ColumnInfos);
  488. var dtos = _mapper.Map<ICollection<BiSeatRestDto>>(query)
  489. .Select(stu => _mapper.Map(stu, typeof(BiSeatRestDto), dynamicClass))
  490. .Cast<object>()
  491. .ToList();
  492. var stream = ExcelHelper.CreateStream(dtos);
  493. return ExcelStreamResult(stream, "座席小休统计表");
  494. }
  495. /// <summary>
  496. /// 坐席转接统计
  497. /// </summary>
  498. /// <param name="dto"></param>
  499. /// <returns></returns>
  500. [HttpGet("seatswitch")]
  501. [AllowAnonymous]
  502. public async Task<PagedDto<BiSeatSwitchDto>> QuerySeatSwitch([FromQuery] QuerySeatSwitchRequest dto)
  503. {
  504. var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto, false, HttpContext.RequestAborted);
  505. return new PagedDto<BiSeatSwitchDto>(total, items);
  506. }
  507. /// <summary>
  508. /// 坐席转接统计导出
  509. /// </summary>
  510. /// <param name="dto"></param>
  511. /// <returns></returns>
  512. [HttpPost("seatswitch/export")]
  513. [LogFilterAlpha("导出日志")]
  514. public async Task<FileStreamResult> QuerySeatSwitchExport([FromBody] ExportExcelDto<QuerySeatSwitchRequest> dto)
  515. {
  516. var (total, items) = await _callReportApplication.QuerySeatSwitchAsync(dto.QueryDto, dto.IsExportAll, HttpContext.RequestAborted);
  517. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatSwitchDto>(dto.ColumnInfos);
  518. var dtos = _mapper.Map<ICollection<BiSeatSwitchDto>>(items)
  519. .Select(stu => _mapper.Map(stu, typeof(BiSeatSwitchDto), dynamicClass))
  520. .Cast<object>()
  521. .ToList();
  522. var stream = ExcelHelper.CreateStream(dtos);
  523. return ExcelStreamResult(stream, "转外线统计分析");
  524. }
  525. /// <summary>
  526. /// 小时统计
  527. /// </summary>
  528. /// <returns></returns>
  529. [HttpGet("hourcall")]
  530. [AllowAnonymous]
  531. public async Task<List<TrCallHourDto>> QueryHourCall([FromQuery] BiQueryHourCallDto dto)
  532. => await _callReportApplication.GetCallHourListAsync(dto, HttpContext.RequestAborted);
  533. /// <summary>
  534. /// 小时统计--导出
  535. /// </summary>
  536. /// <returns></returns>
  537. [HttpPost("hourcall/export")]
  538. [LogFilterAlpha("导出日志")]
  539. [AllowAnonymous]
  540. public async Task<FileStreamResult> ExportQueryHourCall([FromBody] ExportExcelDto<BiQueryHourCallDto> dto)
  541. => ExcelStreamResult(
  542. _exportApplication.GetExcelStream(
  543. dto,
  544. await _callReportApplication.GetCallHourListAsync(dto.QueryDto, HttpContext.RequestAborted),
  545. list =>
  546. {
  547. return new TrCallHourDto()
  548. {
  549. HourTo = "合计",
  550. EffectiveCount = list.Sum(p => p.EffectiveCount),
  551. ConnectByeCount = list.Sum(p => p.ConnectByeCount),
  552. NoConnectByeCount = list.Sum(p => p.NoConnectByeCount),
  553. QueueByeCount = list.Sum(m => m.QueueByeCount),
  554. IvrByeCount = list.Sum(m => m.IvrByeCount)
  555. };
  556. })
  557. , "通话时段分析");
  558. /// <summary>
  559. /// 通话时段统计明细
  560. /// </summary>
  561. /// <returns></returns>
  562. [HttpGet("hourcall_list")]
  563. public async Task<PagedDto<BiSeatSwitchDto>> QueryCallList([FromQuery] QueryCallListDto dto)
  564. {
  565. var res = await _callReportApplication.GetCallListAsync(dto, HttpContext.RequestAborted);
  566. return new PagedDto<BiSeatSwitchDto>(res.Total, res.Data);
  567. }
  568. /// <summary>
  569. /// 通话时段统计明细 导出
  570. /// </summary>
  571. /// <param name="dto"></param>
  572. /// <returns></returns>
  573. [HttpPost("hourcall_list/export")]
  574. [LogFilterAlpha("导出日志")]
  575. public async Task<FileStreamResult> ExportQueryCallList([FromBody] ExportExcelDto<QueryCallListDto> dto)
  576. {
  577. foreach (var item in dto.ColumnInfos)
  578. {
  579. if (item.Prop == "cpn" || item.Prop == "cdpn")
  580. {
  581. item.Prop = item.Prop.ToUpper();
  582. }
  583. }
  584. return ExcelStreamResult(
  585. _exportApplication.GetExcelStream(
  586. dto,
  587. (await _callReportApplication.GetCallListAsync(dto.QueryDto, HttpContext.RequestAborted)).Data)
  588. , "通话时段分析");
  589. }
  590. /// <summary>
  591. /// 通话时段统计明细获取基本信息
  592. /// </summary>
  593. /// <param name="id"></param>
  594. /// <returns></returns>
  595. [HttpGet("hourcall_list_base")]
  596. public async Task<object> ReTransactBaseData()
  597. {
  598. var rsp = new
  599. {
  600. CallForwardingSource = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingSource),
  601. CallForwardingType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingType),
  602. };
  603. return rsp;
  604. }
  605. /// <summary>
  606. /// 热线号码统计
  607. /// </summary>
  608. /// <param name="StartTime"></param>
  609. /// <param name="EndTime"></param>
  610. /// <returns></returns>
  611. [AllowAnonymous]
  612. [HttpGet("gateway-query")]
  613. public async Task<List<CallHotLineDto>> QueryGateWay([FromQuery] BiQueryGateWayDto dto)
  614. => await _callReportApplication.GetCallHotLineListAsync(dto, HttpContext.RequestAborted);
  615. /// <summary>
  616. /// 热线号码统计导出
  617. /// </summary>
  618. /// <param name="dto"></param>
  619. /// <returns></returns>
  620. [HttpPost("gateway-query/export")]
  621. [LogFilterAlpha("导出日志")]
  622. public async Task<FileStreamResult> ExportQueryGatetWay(ExportExcelDto<BiQueryGateWayDto> dto)
  623. => ExcelStreamResult(
  624. _exportApplication.GetExcelStream(
  625. dto,
  626. await _callReportApplication.GetCallHotLineListAsync(dto.QueryDto, HttpContext.RequestAborted)
  627. )
  628. , "热线号码统计");
  629. #region 宜宾话务表
  630. /// <summary>
  631. /// 话务日期统计明细
  632. /// </summary>
  633. /// <param name="dto"></param>
  634. /// <returns></returns>
  635. [HttpGet("query-calldate-statistics")]
  636. public async Task<object> QueryCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
  637. {
  638. var list = await _callReportApplication.QueryCallDateStatisticsDetail(dto);
  639. var total = new QueryCallDateStatisticsDetailResp()
  640. {
  641. Date = "合计",
  642. IvrCallInTotal = list.Sum(x => x.IvrCallInTotal),
  643. PersonCallInCount = list.Sum(x => x.PersonCallInCount),
  644. EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
  645. GaoXiaoCallInCount = list.Sum(x => x.GaoXiaoCallInCount), //高效办成一件事
  646. AiCallInCount = list.Sum(x => x.AiCallInCount),
  647. PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
  648. EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
  649. GaoXiaoCallInPutthroughCount = list.Sum(x => x.GaoXiaoCallInPutthroughCount),
  650. AiCallInPutthroughCount = list.Sum(x => x.AiCallInPutthroughCount),
  651. PersonRingOffCount = list.Sum(x => x.PersonRingOffCount),//个人服务挂断
  652. EnterpriseRingOffCount = list.Sum(x => x.EnterpriseRingOffCount), //企业挂断
  653. GaoXiaoRingOffCount = list.Sum(x => x.GaoXiaoRingOffCount),
  654. IvrRingOffCount = list.Sum(x => x.IvrRingOffCount), //IVR挂断
  655. };
  656. return new { List = list, Total = total };
  657. }
  658. /// <summary>
  659. /// 话务日期统计明细导出
  660. /// </summary>
  661. /// <param name="dto"></param>
  662. /// <returns></returns>
  663. [HttpPost("query-calldate-statistics/export")]
  664. [LogFilterAlpha("导出日志")]
  665. public async Task<FileStreamResult> QueryCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
  666. =>
  667. _exportApplication.GetExcelFile(
  668. dto,
  669. await _callReportApplication.QueryCallDateStatisticsDetail(dto.QueryDto)
  670. , "话务日期统计明细", "Date");
  671. /// <summary>
  672. /// 个人服务话务明细
  673. /// </summary>
  674. /// <param name="dto"></param>
  675. /// <returns></returns>
  676. [HttpGet("query-person-calldate-statistics")]
  677. public async Task<object> QueryPersonCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
  678. {
  679. var list = await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto);
  680. var total = new QueryPersonCallDateStatisticsDetailResp()
  681. {
  682. Date = "合计",
  683. PersonCallInCount = list.Sum(x => x.PersonCallInCount),
  684. PersonCallInPutthroughCount = list.Sum(x => x.PersonCallInPutthroughCount),
  685. //PersonRingOffCount = list.Sum(x=>x.PersonRingOffCount),//个人服务挂断
  686. PersonQueueOffCount = list.Sum(x => x.PersonQueueOffCount),//个人服务队列挂断
  687. PersonWaitOffCount = list.Sum(x => x.PersonWaitOffCount) //个人服务等待挂断
  688. };
  689. return new { List = list, Total = total };
  690. }
  691. /// <summary>
  692. /// 个人服务话务明细导出
  693. /// </summary>
  694. /// <param name="dto"></param>
  695. /// <returns></returns>
  696. [HttpPost("query-person-calldate-statistics/export")]
  697. [LogFilterAlpha("导出日志")]
  698. public async Task<FileStreamResult> QueryPersonCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
  699. => _exportApplication.GetExcelFile(
  700. dto,
  701. await _callReportApplication.QueryPersonCallDateStatisticsDetail(dto.QueryDto)
  702. , "个人服务话务明细", "Date");
  703. /// <summary>
  704. /// 企业服务话务明细
  705. /// </summary>
  706. /// <param name="dto"></param>
  707. /// <returns></returns>
  708. [HttpGet("query-enterprise-calldate-statistics")]
  709. public async Task<object> QueryEnterpriseCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
  710. {
  711. var list = await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto);
  712. var total = new QueryEnterpriseCallDateStatisticsDetailResp()
  713. {
  714. Date = "合计",
  715. EnterpriseCallInCount = list.Sum(x => x.EnterpriseCallInCount),
  716. EnterpriseCallInPutthroughCount = list.Sum(x => x.EnterpriseCallInPutthroughCount),
  717. //EnterpriseRingOffCount = list.Sum(x=>x.EnterpriseRingOffCount), //企业挂断
  718. EnterpriseQueueOffCount = list.Sum(x => x.EnterpriseQueueOffCount),//个人服务队列挂断
  719. EnterpriseWaitOffCount = list.Sum(x => x.EnterpriseWaitOffCount) //个人服务等待挂断
  720. };
  721. return new { List = list, Total = total };
  722. }
  723. /// <summary>
  724. /// 企业服务话务明细导出
  725. /// </summary>
  726. /// <param name="dto"></param>
  727. /// <returns></returns>
  728. [HttpPost("query-enterprise-calldate-statistics/export")]
  729. [LogFilterAlpha("导出日志")]
  730. public async Task<FileStreamResult> QueryEnterpriseCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
  731. => _exportApplication.GetExcelFile(
  732. dto,
  733. await _callReportApplication.QueryEnterpriseCallDateStatisticsDetail(dto.QueryDto)
  734. , "企业服务话务明细", "Date");
  735. /// <summary>
  736. /// 高效服务话务明细
  737. /// </summary>
  738. /// <param name="dto"></param>
  739. /// <returns></returns>
  740. [HttpGet("query-gaoxiao-calldate-statistics")]
  741. public async Task<object> QueryGaoXiaoCallDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
  742. {
  743. var list = await _callReportApplication.QueryGaoXiaoCallDateStatisticsDetail(dto);
  744. var total = new QueryGaoXiaoCallDateStatisticsDetailResp()
  745. {
  746. Date = "合计",
  747. GaoXiaoCallInCount = list.Sum(x => x.GaoXiaoCallInCount),
  748. GaoXiaoCallInPutthroughCount = list.Sum(x => x.GaoXiaoCallInPutthroughCount),
  749. GaoXiaoQueueOffCount = list.Sum(x => x.GaoXiaoQueueOffCount),//企业服务队列挂断
  750. GaoXiaoWaitOffCount = list.Sum(x => x.GaoXiaoWaitOffCount) //企业服务等待挂断
  751. };
  752. return new { List = list, Total = total };
  753. }
  754. /// <summary>
  755. /// 高效服务话务明细导出
  756. /// </summary>
  757. /// <param name="dto"></param>
  758. /// <returns></returns>
  759. [HttpPost("query-gaoxiao-calldate-statistics/export")]
  760. [LogFilterAlpha("导出日志")]
  761. public async Task<FileStreamResult> QueryGaoXiaoCallDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
  762. => _exportApplication.GetExcelFile(
  763. dto,
  764. await _callReportApplication.QueryGaoXiaoCallDateStatisticsDetail(dto.QueryDto)
  765. , "高效服务话务明细", "Date");
  766. /// <summary>
  767. /// 呼出话务统计明细
  768. /// </summary>
  769. /// <param name="dto"></param>
  770. /// <returns></returns>
  771. [HttpGet("query-callout-date-statistics")]
  772. public async Task<object> QueryCallOutDateStatisticsDetail([FromQuery] QueryCallDateStatisticsDetailDto dto)
  773. {
  774. List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;
  775. var list = await _callReportApplication.QueryCallOutDateStatisticsDetail(dto, enterpriseTels);
  776. var total = new QueryCallOutDateStatisticsDetailResp()
  777. {
  778. Date = "合计",
  779. PersonCallOutCount = list.Sum(x => x.PersonCallOutCount),
  780. EnterpriseCallOutCount = list.Sum(x => x.EnterpriseCallOutCount),
  781. AiVisitCallOutCount = list.Sum(x => x.AiVisitCallOutCount),
  782. AiCallOutCount = list.Sum(x => x.AiCallOutCount),
  783. PersonCallOutPutthroughCount = list.Sum(x => x.PersonCallOutPutthroughCount),
  784. EnterpriseCallOutPutthroughCount = list.Sum(x => x.EnterpriseCallOutPutthroughCount),
  785. AiVisitCallOutPutthroughCount = list.Sum(x => x.AiVisitCallOutPutthroughCount),
  786. AiCallOutPutthroughCount = list.Sum(x => x.AiCallOutPutthroughCount)
  787. };
  788. return new { List = list, Total = total };
  789. }
  790. /// <summary>
  791. /// 呼出话务统计明细
  792. /// </summary>
  793. /// <param name="dto"></param>
  794. /// <returns></returns>
  795. [HttpPost("query-callout-date-statistics/export")]
  796. [LogFilterAlpha("导出日志")]
  797. public async Task<FileStreamResult> QueryCallOutDateStatisticsDetailExport([FromBody] ExportExcelDto<QueryCallDateStatisticsDetailDto> dto)
  798. {
  799. List<string> enterpriseTels = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseTel)?.SettingValue;
  800. return _exportApplication.GetExcelFile(
  801. dto,
  802. await _callReportApplication.QueryCallOutDateStatisticsDetail(dto.QueryDto, enterpriseTels)
  803. , "呼出话务统计明细", "Date");
  804. }
  805. /// <summary>
  806. /// 坐席月接通率统计
  807. /// </summary>
  808. /// <param name="dto"></param>
  809. /// <returns></returns>
  810. [HttpGet("query-seat-monthcall")]
  811. public async Task<object> QuerySeatMonthCall([FromQuery] QuerySeatMonthCallRequest dto)
  812. {
  813. var list = await _callReportApplication.QuerySeatMonthCall(dto);
  814. var total = new QuerySeatMonthCallResp()
  815. {
  816. Name = "合计",
  817. InAnswered = list.Sum(x => x.InAnswered),
  818. InAvailableAnswer = list.Sum(x => x.InAvailableAnswer),
  819. InHangupImmediateWhenAnswered = list.Sum(x => x.InHangupImmediateWhenAnswered),
  820. OverTimeImmediate = list.Sum(x => x.OverTimeImmediate),
  821. InTimeImmediate = list.Sum(x => x.InTimeImmediate),
  822. InHanguped = list.Sum(x => x.InHanguped),
  823. InHangupImmediate = list.Sum(x => x.InHangupImmediate),
  824. OverTimeInHanguped = list.Sum(x => x.OverTimeInHanguped),
  825. };
  826. return new { List = list, Total = total };
  827. }
  828. /// <summary>
  829. /// 坐席月接通率统计基础数据
  830. /// </summary>
  831. /// <returns></returns>
  832. [HttpGet("query-seat-monthcall-basedata")]
  833. public async Task<object> QuerySeatMonthCallBaseData()
  834. {
  835. var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;
  836. return new
  837. {
  838. SeatUser = await _userRepository.Queryable().Includes(d => d.Roles).Where(d => d.Roles.Any(x => setting.Contains(x.Name))).ToListAsync()
  839. };
  840. }
  841. /// <summary>
  842. /// 坐席月接通率统计导出
  843. /// </summary>
  844. /// <param name="dto"></param>
  845. /// <returns></returns>
  846. [HttpPost("query-seat-monthcall/export")]
  847. [LogFilterAlpha("导出日志")]
  848. public async Task<FileStreamResult> QuerySeatMonthCallExport([FromBody] ExportExcelDto<QuerySeatMonthCallRequest> dto)
  849. => _exportApplication.GetExcelFile(
  850. dto,
  851. await _callReportApplication.QuerySeatMonthCall(dto.QueryDto)
  852. , "坐席月接通率统计", "Name");
  853. /// <summary>
  854. /// 坐席月接通明细
  855. /// </summary>
  856. /// <param name="dto"></param>
  857. /// <returns></returns>
  858. [HttpGet("query-seat-monthcall-detail")]
  859. public async Task<PagedDto<QuerySeatMonthCallDetailResp>> QuerySeatMonthCallDetail([FromQuery] QuerySeatMonthCallDetailRequest dto)
  860. {
  861. var query = _callReportApplication.QuerySeatMonthCallDetail(dto);
  862. var (total, items) = await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
  863. return new PagedDto<QuerySeatMonthCallDetailResp>(total, items);
  864. }
  865. /// <summary>
  866. /// 坐席月接通明细导出
  867. /// </summary>
  868. /// <param name="dto"></param>
  869. /// <returns></returns>
  870. [HttpPost("query-seat-monthcall-detail/export")]
  871. [LogFilterAlpha("导出日志")]
  872. public async Task<FileStreamResult> QuerySeatMonthCallDetailExport([FromBody] ExportExcelDto<QuerySeatMonthCallDetailRequest> dto)
  873. {
  874. var query = _callReportApplication.QuerySeatMonthCallDetail(dto.QueryDto);
  875. List<QuerySeatMonthCallDetailResp> data;
  876. if (dto.IsExportAll)
  877. {
  878. data = await query.ToListAsync(HttpContext.RequestAborted);
  879. }
  880. else
  881. {
  882. var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
  883. data = items;
  884. }
  885. var dataDtos = _mapper.Map<ICollection<QuerySeatMonthCallDetailResp>>(data);
  886. dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<QuerySeatMonthCallDetailResp>(dto.ColumnInfos);
  887. var dtos = dataDtos
  888. .Select(stu => _mapper.Map(stu, typeof(QuerySeatMonthCallDetailResp), dynamicClass))
  889. .Cast<object>()
  890. .ToList();
  891. var stream = ExcelHelper.CreateStream(dtos);
  892. return ExcelStreamResult(stream, "坐席月接通明细");
  893. }
  894. #endregion
  895. }