BiOrderController.cs 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. using Hotline.Caching.Interfaces;
  2. using Hotline.CallCenter.Calls;
  3. using Hotline.FlowEngine.Workflows;
  4. using Hotline.Orders;
  5. using Hotline.Repository.SqlSugar.Extensions;
  6. using Hotline.Settings;
  7. using Hotline.Settings.Hotspots;
  8. using Hotline.Share.Dtos;
  9. using Hotline.Share.Dtos.Bi;
  10. using Hotline.Share.Dtos.Bigscreen;
  11. using Hotline.Share.Dtos.CallCenter;
  12. using Hotline.Share.Dtos.Order;
  13. using Hotline.Share.Enums.CallCenter;
  14. using Hotline.Share.Enums.Order;
  15. using Hotline.Share.Requests;
  16. using MapsterMapper;
  17. using Microsoft.AspNetCore.Authorization;
  18. using Microsoft.AspNetCore.Mvc;
  19. using SqlSugar;
  20. using XF.Domain.Authentications;
  21. using XF.Domain.Constants;
  22. using XF.Domain.Exceptions;
  23. using XF.Domain.Repository;
  24. namespace Hotline.Api.Controllers.Bi
  25. {
  26. public class BiOrderController : BaseController
  27. {
  28. private readonly IOrderRepository _orderRepository;
  29. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  30. private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
  31. private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
  32. private readonly IRepository<OrderDelay> _orderDelayRepository;
  33. private readonly IMapper _mapper;
  34. private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
  35. private readonly IRepository<OrderSpecial> _orderSpecialRepository;
  36. private readonly IRepository<OrderVisit> _orderVisitRepository;
  37. private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  38. private readonly IRepository<OrderPublish> _orderPublishRepository;
  39. private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
  40. private readonly IRepository<AiOrderVisitDetail> _aiOrderVisitDetailRepository;
  41. private readonly ISessionContext _sessionContext;
  42. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  43. public BiOrderController(
  44. IOrderRepository orderRepository,
  45. IRepository<Hotspot> hotspotTypeRepository,
  46. ISystemDicDataCacheManager sysDicDataCacheManager,
  47. IRepository<OrderVisitDetail> orderVisitDetailRepository,
  48. IRepository<OrderDelay> orderDelayRepository,
  49. IRepository<WorkflowCountersign> workflowCountersignRepository,
  50. IRepository<OrderSpecial> orderSpecialRepository,
  51. IMapper mapper,
  52. IRepository<OrderVisit> orderVisitRepository,
  53. IRepository<TrCallRecord> trCallRecordRepository,
  54. IRepository<OrderPublish> orderPublishRepository,
  55. IRepository<SystemOrganize> systemOrganizeRepository,
  56. IRepository<AiOrderVisitDetail> aiOrderVisitDetailRepository,
  57. ISessionContext sessionContext,
  58. ISystemSettingCacheManager systemSettingCacheManager
  59. )
  60. {
  61. _orderRepository = orderRepository;
  62. _hotspotTypeRepository = hotspotTypeRepository;
  63. _sysDicDataCacheManager = sysDicDataCacheManager;
  64. _orderVisitDetailRepository = orderVisitDetailRepository;
  65. _orderDelayRepository = orderDelayRepository;
  66. _workflowCountersignRepository = workflowCountersignRepository;
  67. _orderSpecialRepository = orderSpecialRepository;
  68. _mapper = mapper;
  69. _orderVisitRepository = orderVisitRepository;
  70. _trCallRecordRepository = trCallRecordRepository;
  71. _orderPublishRepository = orderPublishRepository;
  72. _systemOrganizeRepository = systemOrganizeRepository;
  73. _aiOrderVisitDetailRepository = aiOrderVisitDetailRepository;
  74. _sessionContext = sessionContext;
  75. _systemSettingCacheManager = systemSettingCacheManager;
  76. }
  77. /// <summary>
  78. /// 部门数据统计
  79. /// </summary>
  80. /// <param name="dto"></param>
  81. /// <returns></returns>
  82. [HttpGet("org_data_list")]
  83. public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
  84. {
  85. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  86. var queryOrder = _orderRepository.Queryable(false, false, false)
  87. .LeftJoin<SystemOrganize>((x, o) => x.ActualHandleOrgCode == o.Id)
  88. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  89. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  90. .GroupBy((x, o) => new { x.ActualHandleOrgCode, o.Name })
  91. .Select((x, o) => new OrderBiOrgDataListVo
  92. {
  93. OrgName = o.Name,
  94. OrgId = x.ActualHandleOrgCode,
  95. HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ExpiredTime < x.FiledTime, 1, 0)),
  96. NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime < SqlFunc.GetDate(), 1, 0)),
  97. }).MergeTable();
  98. var queryCountersign = _workflowCountersignRepository.Queryable()
  99. .LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
  100. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  101. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  102. .GroupBy((x, o) => o.Key)
  103. .Select((x, o) => new OrderBiOrgDataListVo
  104. {
  105. OrgId = o.Key,
  106. CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled, 1, 0)),
  107. CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  108. }).MergeTable();
  109. var query = queryOrder.LeftJoin(queryCountersign, (or, co) => or.OrgId == co.OrgId)
  110. .Select((or, co) => new OrderBiOrgDataListVo
  111. {
  112. OrgName = or.OrgName,
  113. OrgId = or.OrgId,
  114. HandlerExtendedNum = or.HandlerExtendedNum,
  115. NoHandlerExtendedNum = or.NoHandlerExtendedNum,
  116. CounterHandlerExtendedNum = co.CounterHandlerExtendedNum,
  117. CounterNoHandlerExtendedNum = co.CounterNoHandlerExtendedNum
  118. }).MergeTable();
  119. query = query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrgName.Contains(dto.Keyword!));
  120. switch (dto.SortField)
  121. {
  122. case "handlerExtendedNum":
  123. query = dto.SortRule == 0 ? query.OrderBy(x => x.HandlerExtendedNum) : query.OrderByDescending(x => x.HandlerExtendedNum);
  124. break;
  125. case "counterHandlerExtendedNum":
  126. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterHandlerExtendedNum) : query.OrderByDescending(x => x.CounterHandlerExtendedNum);
  127. break;
  128. case "noHandlerExtendedNum":
  129. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoHandlerExtendedNum) : query.OrderByDescending(x => x.NoHandlerExtendedNum);
  130. break;
  131. case "counterNoHandlerExtendedNum":
  132. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterNoHandlerExtendedNum) : query.OrderByDescending(x => x.CounterNoHandlerExtendedNum);
  133. break;
  134. }
  135. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  136. return new PagedDto<OrderBiOrgDataListVo>(total, items);
  137. }
  138. /// <summary>
  139. /// 话务员办件统计
  140. /// </summary>
  141. /// <param name="dto"></param>
  142. /// <returns></returns>
  143. [HttpGet("centre_data_list")]
  144. public async Task<PagedDto<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto)
  145. {
  146. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  147. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  148. var query = _orderRepository.Queryable(false, false, false)
  149. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  150. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  151. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.AcceptorName.Contains(dto.Keyword!))
  152. .GroupBy(x => new { x.AcceptorId, x.AcceptorName })
  153. .Select(x => new OrderBiCentreDataListVo
  154. {
  155. UserName = x.AcceptorName,
  156. UserId = x.AcceptorId,
  157. CentreArchive = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Zhiban, 1, 0)),
  158. CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Jiaoban, 1, 0)),
  159. //NoCentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
  160. Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(x.AcceptType == "无效", 1, 0)),
  161. Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(x.DuplicateIds != null && SqlFunc.JsonArrayLength(x.DuplicateIds) > 0, 1, 0))
  162. }).MergeTable();
  163. switch (dto.SortField)
  164. {
  165. case "centreArchive":
  166. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreArchive) : query.OrderByDescending(x => x.CentreArchive);
  167. break;
  168. case "centreCareOf":
  169. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreCareOf) : query.OrderByDescending(x => x.CentreCareOf);
  170. break;
  171. case "noCentreCareOf":
  172. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoCentreCareOf) : query.OrderByDescending(x => x.NoCentreCareOf);
  173. break;
  174. case "invalid":
  175. query = dto.SortRule == 0 ? query.OrderBy(x => x.Invalid) : query.OrderByDescending(x => x.Invalid);
  176. break;
  177. case "repeat":
  178. query = dto.SortRule == 0 ? query.OrderBy(x => x.Repeat) : query.OrderByDescending(x => x.Repeat);
  179. break;
  180. }
  181. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  182. return new PagedDto<OrderBiCentreDataListVo>(total, items);
  183. }
  184. /// <summary>
  185. /// 热点数据小计统计
  186. /// </summary>
  187. /// <param name="dto"></param>
  188. /// <returns></returns>
  189. [HttpGet("hotspot_subtotal_data_list")]
  190. public async Task<PagedDto<HotspotDataLsitVo>> HotspotSubtotalDataLsit([FromQuery] HotspotSubtotalReportPagedRequest dto)
  191. {
  192. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  193. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  194. var query = _hotspotTypeRepository.Queryable(false, true)
  195. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotFullName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotFullName)) && o.IsDeleted == false)
  196. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
  197. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
  198. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  199. .Where((x, o) => x.ParentId == dto.Id)
  200. .Where((x, o) => x.IsDeleted == false)
  201. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  202. .Select((x, o) => new HotspotDataLsitVo
  203. {
  204. Id = x.Id,
  205. Name = x.HotSpotName,
  206. Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  207. }).MergeTable();
  208. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  209. return new PagedDto<HotspotDataLsitVo>(total, items);
  210. }
  211. /// <summary>
  212. /// 热点数据统计
  213. /// </summary>
  214. /// <param name="dto"></param>
  215. /// <returns></returns>
  216. [HttpGet("hotspot_data_list")]
  217. public async Task<object> HotspotDataLsit([FromQuery] HotspotReportPagedRequest dto)
  218. {
  219. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  220. if (dto.Type == 0 && (!dto.ChainStartTime.HasValue || !dto.ChainEndTime.HasValue)) throw UserFriendlyException.SameMessage("请选择环比时间!");
  221. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  222. if (dto.Type == 0)
  223. {
  224. dto.ChainEndTime = dto.ChainEndTime.Value.AddDays(1).AddSeconds(-1);
  225. }
  226. var items = await _hotspotTypeRepository.Queryable(false, true)
  227. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && o.IsDeleted == false)
  228. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
  229. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
  230. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  231. .Where((x, o) => x.ParentId == dto.Id)
  232. .Where((x, o) => x.IsDeleted == false)
  233. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  234. .Select((x, o) => new HotspotDataLsitVo
  235. {
  236. Id = x.Id,
  237. Name = x.HotSpotName,
  238. Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  239. Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.HotSpotName != o.HotspotName, 1, 0)) > 0,
  240. }).MergeTable().ToListAsync();
  241. var chainStartTime = dto.StartTime;
  242. var chainEndTime = dto.EndTime;
  243. switch (dto.Type)
  244. {
  245. case 1://日
  246. chainStartTime = dto.StartTime.Value.AddDays(-1);
  247. chainEndTime = dto.EndTime.Value.AddDays(-1);
  248. break;
  249. case 2://月
  250. chainStartTime = dto.StartTime.Value.AddMonths(-1);
  251. chainEndTime = dto.EndTime.Value.AddMonths(-1);
  252. break;
  253. case 3://年
  254. chainStartTime = dto.StartTime.Value.AddYears(-1);
  255. chainEndTime = dto.EndTime.Value.AddYears(-1);
  256. break;
  257. case 0:
  258. chainStartTime = dto.ChainStartTime.Value;
  259. chainEndTime = dto.ChainEndTime.Value;
  260. break;
  261. }
  262. var chainItems = await _hotspotTypeRepository.Queryable(false, true)
  263. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && o.IsDeleted == false)
  264. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= chainStartTime)
  265. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= chainEndTime)
  266. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  267. .Where((x, o) => x.ParentId == dto.Id)
  268. .Where((x, o) => x.IsDeleted == false)
  269. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  270. .Select((x, o) => new
  271. {
  272. Id = x.Id,
  273. ChainNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  274. }).MergeTable().ToListAsync();
  275. var res = (from t1 in items
  276. join t2 in chainItems on t1.Id equals t2.Id into t1_t2
  277. from item in t1_t2.DefaultIfEmpty()
  278. select new
  279. {
  280. Id = t1.Id,
  281. Name = t1.Name,
  282. Num = t1.Num,
  283. Sublevel = t1.Sublevel,
  284. Children = new List<HotspotDataLsitVo>(),
  285. ChainNum = t1_t2.Select(x => x.ChainNum).FirstOrDefault(),
  286. ChainRate = t1_t2.Select(x => x.ChainNum).FirstOrDefault() > 0 ?
  287. ((double.Parse(t1.Num.ToString()) - double.Parse(t1_t2.Select(x => x.ChainNum).FirstOrDefault().ToString())) / double.Parse(t1_t2.Select(x => x.ChainNum).FirstOrDefault().ToString()) * 100).ToString("F2") + "%" : "100.00%",
  288. }).ToList();
  289. var total = new
  290. {
  291. Id = "0",
  292. Name = "合计",
  293. Num = res.Sum(x => x.Num),
  294. Sublevel = false,
  295. Children = new List<HotspotDataLsitVo>(),
  296. ChainNum = res.Sum(x => x.ChainNum),
  297. ChainRate = res.Sum(x => x.ChainNum) > 0 ? ((double.Parse(res.Sum(x => x.Num).ToString()) - double.Parse(res.Sum(x => x.ChainNum).ToString())) / double.Parse(res.Sum(x => x.ChainNum).ToString()) * 100).ToString("F2") + "%" : "100.00%"
  298. };
  299. return new { List = res, Total = total };
  300. }
  301. /// <summary>
  302. /// 部门不满意统计
  303. /// 已加验证部门
  304. /// </summary>
  305. /// <param name="dto"></param>
  306. /// <returns></returns>
  307. [HttpGet("visit-nosatisfied")]
  308. public async Task<object> QueryVisitNoSatisfied([FromQuery] QueryVisitNoSatiisfiedRequest dto)
  309. {
  310. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  311. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  312. var IsCenter = _sessionContext.OrgIsCenter;
  313. var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);
  314. List<dynamic>? list = new List<dynamic>();
  315. //DataTable dt = new DataTable();
  316. foreach (var item in dissatisfiedReason)
  317. {
  318. var table = _orderVisitDetailRepository.Queryable()
  319. .Includes(x => x.OrderVisit)
  320. .Where(x => x.VisitTarget == Share.Enums.Order.EVisitTarget.Org)
  321. .Where(x => x.OrgNoSatisfiedReason != null)
  322. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  323. .Where(x => !string.IsNullOrEmpty(x.VisitOrgName))
  324. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.VisitOrgName.Contains(dto.OrgName))
  325. .WhereIF(dto.StartTime.HasValue, x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  326. .WhereIF(dto.EndTime.HasValue, x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  327. .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.RequiredOrgId))
  328. .GroupBy(x => new { x.VisitOrgName, x.VisitOrgCode })
  329. .Select(x => new BiVisitNoSatisfiedDto
  330. {
  331. Count = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", item.DicDataValue), 1, 0)),
  332. Key = item.DicDataValue,
  333. OrgName = x.VisitOrgName,
  334. OrgCode = x.VisitOrgCode
  335. })
  336. .OrderByDescending(x => x.Count)
  337. //.ToPivotTable(x => x.Key, x => x.OrgName, x => x.Sum(x => x.Count));
  338. .ToPivotList(x => x.Key, x => new { x.OrgCode, x.OrgName }, x => x.Sum(x => x.Count));
  339. list.AddRange(table);
  340. }
  341. return new { DicReason = dissatisfiedReason, Data = list };
  342. }
  343. /// <summary>
  344. /// 部门不满意统计明细
  345. /// </summary>
  346. /// <param name="dto"></param>
  347. /// <returns></returns>
  348. [HttpGet("visit-nosatisfied-detail")]
  349. public async Task<PagedDto<OrderVisitDetailDto>> BiQueryVisitNoSatisfiedDetail([FromQuery] BiQueryVisitNoSatisfiedDetailDto dto)
  350. {
  351. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  352. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  353. var IsCenter = _sessionContext.OrgIsCenter;
  354. var (total, items) = await _orderVisitDetailRepository.Queryable()
  355. .Includes(x => x.OrderVisit, d => d.Order)
  356. .Includes(x => x.OrderVisit, d => d.Employee)
  357. .Where(x => x.VisitOrgCode == dto.OrgCode)
  358. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  359. .Where(x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  360. .Where(x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  361. .Where(x => SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", dto.DissatisfiedKey))
  362. .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.RequiredOrgId))
  363. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderVisit.Order.No.Contains(dto.Keyword) || x.OrderVisit.Order.Title.Contains(dto.Keyword))
  364. .OrderBy(x => x.OrderVisit.VisitTime)
  365. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  366. return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
  367. }
  368. /// <summary>
  369. /// 部门延期统计
  370. /// </summary>
  371. /// <param name="dto"></param>
  372. /// <returns></returns>
  373. [HttpGet("order-delay-data-list")]
  374. public async Task<IReadOnlyList<BiOrderDelayDataDto>> QueryOrderDelayDataList([FromQuery] QueryOrderDelayDataListRequest dto)
  375. {
  376. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  377. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  378. var IsCenter = _sessionContext.OrgIsCenter;
  379. var list = await _orderDelayRepository.Queryable()
  380. .LeftJoin<SystemOrganize>((x, o) => x.ApplyOrgCode == o.Id)
  381. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  382. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  383. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.ApplyOrgName.Contains(dto.OrgName))
  384. .WhereIF(IsCenter == false, x => x.ApplyOrgCode.StartsWith(_sessionContext.RequiredOrgId))
  385. .GroupBy(x => new { x.ApplyOrgCode, x.ApplyOrgName })
  386. .Select(x => new BiOrderDelayDataDto
  387. {
  388. OrgName = x.ApplyOrgName,
  389. OrgCode = x.ApplyOrgCode,
  390. PassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)),
  391. NoPassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)),
  392. ExaminingTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0)),
  393. AllTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0))
  394. }).ToListAsync();
  395. return list;
  396. }
  397. /// <summary>
  398. /// 特提统计
  399. /// </summary>
  400. /// <param name="dto"></param>
  401. /// <returns></returns>
  402. [HttpGet("special_data_list")]
  403. public async Task<PagedDto<OrderBiSpecialListVo>> SpecialDataList([FromQuery] ReportPagedRequest dto)
  404. {
  405. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  406. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  407. var IsCenter = _sessionContext.OrgIsCenter;
  408. var query = _orderSpecialRepository.Queryable()
  409. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  410. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  411. .WhereIF(IsCenter == false, x => x.OrgId.StartsWith(_sessionContext.RequiredOrgId))
  412. .GroupBy(x => new { x.Cause })
  413. .Select(x => new OrderBiSpecialListVo
  414. {
  415. Cause = x.Cause,
  416. OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  417. MaxSpecialTime = SqlFunc.AggregateMax(x.CreationTime),
  418. })
  419. .MergeTable();
  420. switch (dto.SortField)
  421. {
  422. case "cause":
  423. query = dto.SortRule == 0 ? query.OrderBy(x => x.Cause) : query.OrderByDescending(x => x.Cause);
  424. break;
  425. case "orderNum":
  426. query = dto.SortRule == 0 ? query.OrderBy(x => x.OrderNum) : query.OrderByDescending(x => x.OrderNum);
  427. break;
  428. case "maxSpecialTime":
  429. query = dto.SortRule == 0 ? query.OrderBy(x => x.MaxSpecialTime) : query.OrderByDescending(x => x.MaxSpecialTime);
  430. break;
  431. }
  432. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  433. return new PagedDto<OrderBiSpecialListVo>(total, items);
  434. }
  435. /// <summary>
  436. /// 获取工单特提信息列表
  437. /// </summary>
  438. /// <param name="dto"></param>
  439. /// <returns></returns>
  440. [HttpGet("special_data_list/list")]
  441. public async Task<PagedDto<OrderSpecialDto>> List([FromQuery] OrderSpecialListDto dto)
  442. {
  443. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  444. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  445. var IsCenter = _sessionContext.OrgIsCenter;
  446. var (total, items) = await _orderSpecialRepository.Queryable()
  447. .Includes(x => x.Order)
  448. .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
  449. x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
  450. .WhereIF(!string.IsNullOrEmpty(dto.Cause),
  451. x => x.Cause != null && x.Cause.Equals(dto.Cause))
  452. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  453. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  454. .WhereIF(dto.State.HasValue, x => x.State == dto.State)
  455. .WhereIF(IsCenter == false, x => x.OrgId.StartsWith(_sessionContext.OrgId))
  456. .OrderByDescending(x => x.CreationTime)
  457. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  458. return new PagedDto<OrderSpecialDto>(total, _mapper.Map<IReadOnlyList<OrderSpecialDto>>(items));
  459. }
  460. /// <summary>
  461. /// 受理类型前十
  462. /// </summary>
  463. /// <param name="dto"></param>
  464. /// <returns></returns>
  465. [HttpGet("accept_type_top10_list")]
  466. public async Task<PagedDto<AcceptTypeTop10Vo>> AcceptTypeTop10List([FromQuery] ReportPagedRequest dto)
  467. {
  468. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  469. dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
  470. dto.PageIndex = 1;
  471. dto.PageSize = 10;
  472. var query = _orderRepository.Queryable(false, false, false)
  473. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  474. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  475. .Select(x => new
  476. {
  477. AcceptType = x.AcceptType,
  478. OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
  479. Id = x.Id
  480. }).MergeTable()
  481. .GroupBy(x => new { x.OneHotspot })
  482. .Select(x => new AcceptTypeTop10Vo
  483. {
  484. Name = x.OneHotspot,
  485. ValidAccept = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  486. Consult = SqlFunc.AggregateSum(SqlFunc.IIF("咨询".Equals(x.AcceptType), 1, 0)),
  487. Report = SqlFunc.AggregateSum(SqlFunc.IIF("举报".Equals(x.AcceptType), 1, 0)),
  488. Complaint = SqlFunc.AggregateSum(SqlFunc.IIF("投诉".Equals(x.AcceptType), 1, 0)),
  489. SeekHelp = SqlFunc.AggregateSum(SqlFunc.IIF("求助".Equals(x.AcceptType), 1, 0)),
  490. Suggest = SqlFunc.AggregateSum(SqlFunc.IIF("建议".Equals(x.AcceptType), 1, 0)),
  491. Opinion = SqlFunc.AggregateSum(SqlFunc.IIF("意见".Equals(x.AcceptType), 1, 0)),
  492. Rests = SqlFunc.AggregateSum(SqlFunc.IIF("其他".Equals(x.AcceptType), 1, 0)),
  493. BenefitThePeople = SqlFunc.AggregateSum(SqlFunc.IIF("惠民帮助".Equals(x.AcceptType), 1, 0)),
  494. Praise = SqlFunc.AggregateSum(SqlFunc.IIF("表扬".Equals(x.AcceptType), 1, 0)),
  495. }).MergeTable();
  496. switch (dto.SortField)
  497. {
  498. case "validAccept":
  499. query = dto.SortRule == 0 ? query.OrderBy(x => x.ValidAccept) : query.OrderByDescending(x => x.ValidAccept);
  500. break;
  501. case "consult":
  502. query = dto.SortRule == 0 ? query.OrderBy(x => x.Consult) : query.OrderByDescending(x => x.Consult);
  503. break;
  504. case "report":
  505. query = dto.SortRule == 0 ? query.OrderBy(x => x.Report) : query.OrderByDescending(x => x.Report);
  506. break;
  507. case "complaint":
  508. query = dto.SortRule == 0 ? query.OrderBy(x => x.Complaint) : query.OrderByDescending(x => x.Complaint);
  509. break;
  510. case "seekHelp":
  511. query = dto.SortRule == 0 ? query.OrderBy(x => x.SeekHelp) : query.OrderByDescending(x => x.SeekHelp);
  512. break;
  513. case "suggest":
  514. query = dto.SortRule == 0 ? query.OrderBy(x => x.Suggest) : query.OrderByDescending(x => x.Suggest);
  515. break;
  516. case "opinion":
  517. query = dto.SortRule == 0 ? query.OrderBy(x => x.Opinion) : query.OrderByDescending(x => x.Opinion);
  518. break;
  519. case "rests":
  520. query = dto.SortRule == 0 ? query.OrderBy(x => x.Rests) : query.OrderByDescending(x => x.Rests);
  521. break;
  522. case "benefitThePeople":
  523. query = dto.SortRule == 0 ? query.OrderBy(x => x.BenefitThePeople) : query.OrderByDescending(x => x.BenefitThePeople);
  524. break;
  525. case "praise":
  526. query = dto.SortRule == 0 ? query.OrderBy(x => x.Praise) : query.OrderByDescending(x => x.Praise);
  527. break;
  528. default:
  529. query = query.OrderByDescending(x => x.ValidAccept);
  530. break;
  531. }
  532. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  533. return new PagedDto<AcceptTypeTop10Vo>(total, items);
  534. }
  535. /// <summary>
  536. /// 热点类型部门统计
  537. /// </summary>
  538. /// <param name="dto"></param>
  539. /// <returns></returns>
  540. [HttpGet("hotport-org-statistics")]
  541. public async Task<object> HotPortJoinOrgStatistics([FromQuery] HotPortJoinOrgStatisticsRequest dto)
  542. {
  543. dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
  544. var IsCenter = _sessionContext.OrgIsCenter;
  545. return await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime, dto.EndTime, IsCenter, _sessionContext.OrgId);
  546. }
  547. /// <summary>
  548. /// 回访量统计
  549. /// </summary>
  550. /// <returns></returns>
  551. [HttpGet("visit-measure-statistics")]
  552. public async Task<VisitMeasureStatisticsDto> VisitMeasureStatistics(DateTime StartDate, DateTime EndDate, string? VisitName)
  553. {
  554. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  555. var list = await _orderVisitRepository.Queryable()
  556. .Includes(x => x.Employee)
  557. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState == EVisitState.Visited)
  558. .WhereIF(!string.IsNullOrEmpty(VisitName), x => x.Employee.Name.Contains(VisitName))
  559. .GroupBy(x => new { x.EmployeeId, x.Employee.Name })
  560. .Select(x => new VisitMeasureStatisticsModelDto()
  561. {
  562. VisitName = x.Employee.Name,
  563. CallVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.CallVisit, 1, 0)),
  564. ArtificialVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType != EVisitType.CallVisit, 1, 0)),
  565. SumCount = SqlFunc.AggregateCount(x.EmployeeId)
  566. })
  567. .ToListAsync();
  568. var returnModel = new VisitMeasureStatisticsDto();
  569. returnModel.VisitMeasureStatisticsModelList = list;
  570. //查询AIVisit
  571. returnModel.AiVisitCount = await _aiOrderVisitDetailRepository.Queryable()
  572. .Where(x => x.AiVisitTime >= StartDate && x.AiVisitTime <= EndDate && x.IsSuccess != null).CountAsync();
  573. returnModel.AiVisitSatisfiedCount = await _aiOrderVisitDetailRepository.Queryable()
  574. .Includes(x => x.OrderVisit)
  575. .Where(x => x.AiVisitTime >= StartDate && x.AiVisitTime <= EndDate && x.IsSuccess == true && SqlFunc.JsonField(x.OrderVisit.NowEvaluate, "Key") != "1" && SqlFunc.JsonField(x.OrderVisit.NowEvaluate, "Key") != "2").CountAsync();
  576. returnModel.AiVisitNoSatisfiedCount = await _aiOrderVisitDetailRepository.Queryable()
  577. .Includes(x => x.OrderVisit)
  578. .Where(x => x.AiVisitTime >= StartDate && x.AiVisitTime <= EndDate && x.IsSuccess == true && SqlFunc.JsonField(x.OrderVisit.NowEvaluate, "Key") == "1" && SqlFunc.JsonField(x.OrderVisit.NowEvaluate, "Key") == "2").CountAsync();
  579. returnModel.AIVisitFailCount = await _aiOrderVisitDetailRepository.Queryable()
  580. .Where(x => x.AiVisitTime >= StartDate && x.AiVisitTime <= EndDate && x.IsSuccess == false).CountAsync();
  581. return returnModel;
  582. }
  583. /// <summary>
  584. /// 热点类型小类统计
  585. /// </summary>
  586. /// <param name="StartDate"></param>
  587. /// <param name="EndDate"></param>
  588. /// <param name="TypeId">0:全部 ,1:市民,2:企业</param>
  589. /// <returns></returns>
  590. [HttpGet("hotspot-statistics")]
  591. public async Task<object> HotspotStatistics(DateTime StartDate, DateTime EndDate, int TypeId, string? HotspotCode)
  592. {
  593. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  594. if (string.IsNullOrEmpty(HotspotCode))
  595. {
  596. var list = await _hotspotTypeRepository.Queryable()
  597. .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
  598. .Where((it, o) => o.CreationTime >= StartDate && o.CreationTime <= EndDate && o.Id != null)
  599. .WhereIF(TypeId == 1, (it, o) => o.IdentityType == EIdentityType.Citizen)
  600. .WhereIF(TypeId == 2, (it, o) => o.IdentityType == EIdentityType.Enterprise)
  601. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")) })
  602. .Select((it, o) => new
  603. {
  604. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")),
  605. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  606. })
  607. .MergeTable()
  608. .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
  609. .Select((x, q) => new
  610. {
  611. HotspotCode = x.HotspotCode,
  612. SumCount = x.SumCount,
  613. HotspotName = q.HotSpotName,
  614. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  615. })
  616. .ToListAsync();
  617. return list;
  618. }
  619. else
  620. {
  621. string count = (HotspotCode.Length + 2).ToString();
  622. string countx = HotspotCode.Length.ToString();
  623. var list = await _hotspotTypeRepository.Queryable()
  624. .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
  625. .Where((it, o) => o.CreationTime >= StartDate && o.CreationTime <= EndDate && it.ParentId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(countx)) == HotspotCode)
  626. .WhereIF(TypeId == 1, (it, o) => o.IdentityType == EIdentityType.Citizen)
  627. .WhereIF(TypeId == 2, (it, o) => o.IdentityType == EIdentityType.Enterprise)
  628. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)) })
  629. .Select((it, o) => new
  630. {
  631. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)),
  632. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  633. })
  634. .MergeTable()
  635. .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
  636. .Select((x, q) => new
  637. {
  638. HotspotCode = x.HotspotCode,
  639. SumCount = x.SumCount,
  640. HotspotName = q.HotSpotName,
  641. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  642. })
  643. .ToListAsync();
  644. return list;
  645. }
  646. }
  647. /// <summary>
  648. /// 部门满意度统计
  649. /// </summary>
  650. /// <param name="StartDate"></param>
  651. /// <param name="EndDate"></param>
  652. /// <param name="OrgName"></param>
  653. /// <param name="TypeId">1:办件结果 2:办件态度</param>
  654. /// <param name="LineNum"></param>
  655. /// <returns></returns>
  656. [HttpGet("visit-org-satisfaction-statistics")]
  657. public async Task<VisitAndOrgSatisfactionStatisticsResultDto> VisitAndOrgSatisfactionStatistics(DateTime StartDate, DateTime EndDate, string OrgName, int TypeId, string? LineNum)
  658. {
  659. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  660. bool IsCenter = _sessionContext.OrgIsCenter;
  661. var list = await _orderVisitDetailRepository.Queryable()
  662. .Where(x => x.OrderVisit.VisitTime >= StartDate && x.OrderVisit.VisitTime <= EndDate && x.VisitTarget == EVisitTarget.Org && x.OrderVisit.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(x.VisitOrgCode))
  663. .WhereIF(!string.IsNullOrEmpty(OrgName), x => x.VisitOrgName.Contains(OrgName))
  664. .WhereIF(!string.IsNullOrEmpty(LineNum), x => x.OrderVisit.Order.CallRecord.Gateway.Contains(LineNum))
  665. .WhereIF(IsCenter == false, x => x.VisitOrgCode.StartsWith(_sessionContext.OrgId))
  666. .GroupBy(x => new
  667. {
  668. VisitOrgCode = x.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))
  669. })
  670. .Select(x => new VisitAndOrgSatisfactionStatisticsDto()
  671. {
  672. OrgCode = x.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
  673. TotalSumCount = SqlFunc.AggregateCount(x.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))),
  674. VerySatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "5", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "5", 1, 0))),//非常满意数
  675. SatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "4", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "4", 1, 0))), //满意数
  676. RegardedAsSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "-1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "-1", 1, 0))),//视为满意
  677. DefaultSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "0", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "0", 1, 0))),//默认满意
  678. NoSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2", 1, 0))),//不满意
  679. NoEvaluateCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "7", 1, 0))),//未做评价
  680. NoPutThroughCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "6", 1, 0))),//未接通
  681. })
  682. .MergeTable()
  683. .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
  684. .Select((it, o) => new VisitAndOrgSatisfactionStatisticsDto()
  685. {
  686. OrgName = o.Name,
  687. OrgCode = it.OrgCode,
  688. OrgType = o.OrgType,
  689. TotalSumCount = it.TotalSumCount,
  690. VerySatisfiedCount = it.VerySatisfiedCount,//非常满意数
  691. SatisfiedCount = it.SatisfiedCount, //满意数
  692. RegardedAsSatisfiedCount = it.RegardedAsSatisfiedCount,//视为满意
  693. DefaultSatisfiedCount = it.DefaultSatisfiedCount,//默认满意
  694. NoSatisfiedCount = it.NoSatisfiedCount,//不满意
  695. NoEvaluateCount = it.NoEvaluateCount,//未做评价
  696. NoPutThroughCount = it.NoPutThroughCount,//未接通
  697. })
  698. .ToListAsync();
  699. var countySumModel = new VisitAndOrgSatisfactionStatisticsDto()
  700. {
  701. OrgName = "区县合计",
  702. TotalSumCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.TotalSumCount),
  703. VerySatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VerySatisfiedCount),
  704. SatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.SatisfiedCount),
  705. RegardedAsSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.RegardedAsSatisfiedCount),
  706. DefaultSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.DefaultSatisfiedCount),
  707. NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
  708. NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
  709. NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
  710. };
  711. var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
  712. {
  713. OrgName = "市直合计",
  714. TotalSumCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.TotalSumCount),
  715. VerySatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.VerySatisfiedCount),
  716. SatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.SatisfiedCount),
  717. RegardedAsSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.RegardedAsSatisfiedCount),
  718. DefaultSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.DefaultSatisfiedCount),
  719. NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoSatisfiedCount),
  720. NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoEvaluateCount),
  721. NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoPutThroughCount),
  722. };
  723. var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
  724. {
  725. OrgName = "总计",
  726. TotalSumCount = list.Sum(x => x.TotalSumCount),
  727. VerySatisfiedCount = list.Sum(x => x.VerySatisfiedCount),
  728. SatisfiedCount = list.Sum(x => x.SatisfiedCount),
  729. RegardedAsSatisfiedCount = list.Sum(x => x.RegardedAsSatisfiedCount),
  730. DefaultSatisfiedCount = list.Sum(x => x.DefaultSatisfiedCount),
  731. NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
  732. NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
  733. NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
  734. };
  735. return new VisitAndOrgSatisfactionStatisticsResultDto { DataList = list, CountySumModel = countySumModel, CitySumModel = citySumModel, SumModel = sumModel };
  736. }
  737. /// <summary>
  738. /// 子部门满意度明细
  739. /// </summary>
  740. /// <param name="StartDate"></param>
  741. /// <param name="EndDate"></param>
  742. /// <param name="OrgCode"></param>
  743. /// <param name="TypeId"></param>
  744. /// <param name="LineNum"></param>
  745. /// <returns></returns>
  746. [HttpGet("visit-org-statisfaction-org-detail")]
  747. public async Task<VisitAndOrgSatisfactionStatisticsResultDto> VisitAndOrgStatisfactionOrgDetail(DateTime StartDate, DateTime EndDate, string OrgCode, int TypeId, string? LineNum)
  748. {
  749. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  750. bool IsCenter = _sessionContext.OrgIsCenter;
  751. var list = await _systemOrganizeRepository.Queryable().Where(x => x.Id.StartsWith(OrgCode))
  752. .LeftJoin<OrderVisitDetail>((x, it) => x.Id == it.VisitOrgCode)
  753. .Where((x, it) => it.OrderVisit.VisitTime >= StartDate && it.OrderVisit.VisitTime <= EndDate && it.VisitTarget == EVisitTarget.Org && it.OrderVisit.VisitState == EVisitState.Visited)
  754. .WhereIF(!string.IsNullOrEmpty(LineNum), (x, it) => it.OrderVisit.Order.CallRecord.Gateway.Contains(LineNum))
  755. .WhereIF(IsCenter == false, (x, it) => it.VisitOrgCode.StartsWith(_sessionContext.OrgId))
  756. .GroupBy((x, it) => new
  757. {
  758. VisitOrgCode = it.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9"))
  759. })
  760. .Select((x, it) => new VisitAndOrgSatisfactionStatisticsDto()
  761. {
  762. OrgCode = it.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9")),
  763. TotalSumCount = SqlFunc.AggregateCount(it.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9"))),
  764. VerySatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "5", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "5", 1, 0))),//非常满意数
  765. SatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "4", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "4", 1, 0))), //满意数
  766. RegardedAsSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "-1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "-1", 1, 0))),//视为满意
  767. DefaultSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "0", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "0", 1, 0))),//默认满意
  768. NoSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "2", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "2", 1, 0))),//不满意
  769. NoEvaluateCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "7", 1, 0))),//未做评价
  770. NoPutThroughCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgHandledAttitude, "Key") == "6", 1, 0)))//未接通
  771. })
  772. .MergeTable()
  773. .LeftJoin<SystemOrganize>((x, it) => x.OrgCode == it.Id)
  774. .Select((x, it) => new VisitAndOrgSatisfactionStatisticsDto()
  775. {
  776. OrgName = it.Name,
  777. OrgCode = x.OrgCode,
  778. OrgType = it.OrgType,
  779. TotalSumCount = x.TotalSumCount,
  780. VerySatisfiedCount = x.VerySatisfiedCount,//非常满意数
  781. SatisfiedCount = x.SatisfiedCount, //满意数
  782. RegardedAsSatisfiedCount = x.RegardedAsSatisfiedCount,//视为满意
  783. DefaultSatisfiedCount = x.DefaultSatisfiedCount,//默认满意
  784. NoSatisfiedCount = x.NoSatisfiedCount,//不满意
  785. NoEvaluateCount = x.NoEvaluateCount,//未做评价
  786. NoPutThroughCount = x.NoPutThroughCount,//未接通
  787. })
  788. .ToListAsync();
  789. var countySumModel = new VisitAndOrgSatisfactionStatisticsDto()
  790. {
  791. OrgName = "区县合计",
  792. TotalSumCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.TotalSumCount),
  793. VerySatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.VerySatisfiedCount),
  794. SatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.SatisfiedCount),
  795. RegardedAsSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.RegardedAsSatisfiedCount),
  796. DefaultSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.DefaultSatisfiedCount),
  797. NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoSatisfiedCount),
  798. NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoEvaluateCount),
  799. NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.County).Sum(x => x.NoPutThroughCount),
  800. };
  801. var citySumModel = new VisitAndOrgSatisfactionStatisticsDto()
  802. {
  803. OrgName = "市直合计",
  804. TotalSumCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.TotalSumCount),
  805. VerySatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.VerySatisfiedCount),
  806. SatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.SatisfiedCount),
  807. RegardedAsSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.RegardedAsSatisfiedCount),
  808. DefaultSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.DefaultSatisfiedCount),
  809. NoSatisfiedCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoSatisfiedCount),
  810. NoEvaluateCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoEvaluateCount),
  811. NoPutThroughCount = list.Where(x => x.OrgType == EOrgType.City).Sum(x => x.NoPutThroughCount),
  812. };
  813. var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
  814. {
  815. OrgName = "总计",
  816. TotalSumCount = list.Sum(x => x.TotalSumCount),
  817. VerySatisfiedCount = list.Sum(x => x.VerySatisfiedCount),
  818. SatisfiedCount = list.Sum(x => x.SatisfiedCount),
  819. RegardedAsSatisfiedCount = list.Sum(x => x.RegardedAsSatisfiedCount),
  820. DefaultSatisfiedCount = list.Sum(x => x.DefaultSatisfiedCount),
  821. NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
  822. NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
  823. NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
  824. };
  825. return new VisitAndOrgSatisfactionStatisticsResultDto { DataList = list, CountySumModel = countySumModel, CitySumModel = citySumModel, SumModel = sumModel };
  826. }
  827. /// <summary>
  828. /// 部门满意度明细
  829. /// </summary>
  830. /// <param name="StartDate"></param>
  831. /// <param name="EndDate"></param>
  832. /// <param name="OrgCode"></param>
  833. /// <param name="TypeId"></param>
  834. /// <param name="LineNum"></param>
  835. /// <returns></returns>
  836. [HttpGet("visit-org-satisfaction-detail")]
  837. public async Task<PagedDto<OrderVisitDetailDto>> VisitAndOrgSatisfactionDetail([FromQuery] VisitAndOrgSatisfactionDetailDto dto)
  838. {
  839. dto.EndDate = dto.EndDate.AddDays(1).AddSeconds(-1);
  840. var (total, items) = await _orderVisitDetailRepository.Queryable()
  841. .Includes(x => x.OrderVisit, o => o.Order, d => d.CallRecord)
  842. .Where(x => x.OrderVisit.VisitTime >= dto.StartDate && x.OrderVisit.VisitTime <= dto.EndDate && x.VisitTarget == EVisitTarget.Org && x.OrderVisit.VisitState == EVisitState.Visited)
  843. .WhereIF(dto.OrgCode == "001", x => x.VisitOrgCode == dto.OrgCode)
  844. .WhereIF(dto.OrgCode != "001", x => x.VisitOrgCode.StartsWith(dto.OrgCode))
  845. .WhereIF(dto.TypeId == 1, x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.DateValue)
  846. .WhereIF(dto.TypeId == 2, x => SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == dto.DateValue)
  847. .WhereIF(!string.IsNullOrEmpty(dto.LineNum), x => x.OrderVisit.Order.CallRecord.Gateway == dto.LineNum)
  848. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  849. return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
  850. }
  851. /// <summary>
  852. /// 中心报表统计
  853. /// </summary>
  854. /// <param name="StartDate"></param>
  855. /// <param name="EndDate"></param>
  856. /// <returns></returns>
  857. [HttpGet("center_report_forms_statistics")]
  858. public async Task<CenterReportStatisticsDto> CenterReportFormsStatistics(DateTime StartDate, DateTime EndDate)
  859. {
  860. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  861. CenterReportStatisticsDto centerReportStatisticsDto = new();
  862. //信件总量
  863. int sourceChannelCount = await _orderRepository.Queryable().Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate).CountAsync();
  864. #region 通话记录
  865. //通话记录
  866. var callData = await _trCallRecordRepository.Queryable()
  867. .Where(p => p.CreatedTime >= StartDate && p.CreatedTime <= EndDate)
  868. .Select(o => new CenterReportCallDto
  869. {
  870. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.On, 1, 0)),//有效
  871. InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn && o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue, 1, 0)), //无效(排除队列挂断和IVR挂断)
  872. QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.QueueTims > 0 && o.RingTimes == 0, 1, 0)), //队列挂断
  873. IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
  874. })
  875. .ToListAsync();
  876. if (callData != null && callData.Count > 0)
  877. centerReportStatisticsDto.CenterReportCall = callData[0];
  878. #endregion
  879. #region 工单
  880. //工单
  881. var orderData = await _orderRepository.Queryable()
  882. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  883. .Select(x => new CenterReportOrderDto
  884. {
  885. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  886. InvalidCount = 0,
  887. CompletedCount = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300, 1, 0)),
  888. InProgressCount = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300, 1, 0))
  889. })
  890. .ToListAsync();
  891. if (orderData != null && orderData.Count > 0)
  892. centerReportStatisticsDto.CenterReportOrder = orderData[0];
  893. #endregion
  894. #region 信件来源
  895. //信件来源
  896. var sourceChannelData = await _orderRepository.Queryable()
  897. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  898. .Select(it => new
  899. {
  900. SourceChannelCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.SourceChannelCode), "QT", it.SourceChannelCode)
  901. })
  902. .MergeTable()//将查询出来的结果合并成一个新表
  903. .GroupBy(it => new { it.SourceChannelCode })//对新表进行分组
  904. .Select(it => new CenterReportOrderSourceChannelDto
  905. {
  906. Code = it.SourceChannelCode,
  907. CountNum = SqlFunc.AggregateCount(it.SourceChannelCode)
  908. })
  909. .ToListAsync();
  910. List<CenterReportOrderSourceChannelDto> sourceChannel = new()
  911. {
  912. new CenterReportOrderSourceChannelDto
  913. {
  914. Name = "来源总量",
  915. Code = "All",
  916. CountNum = sourceChannelCount
  917. }
  918. };
  919. var sourceChannelDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SourceChannel);
  920. foreach (var item in sourceChannelDic)
  921. {
  922. sourceChannel.Add(new CenterReportOrderSourceChannelDto
  923. {
  924. Name = item.DicDataName,
  925. Code = item.DicTypeCode,
  926. CountNum = sourceChannelData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
  927. });
  928. }
  929. centerReportStatisticsDto.CenterReportOrderSourceChannels = sourceChannel;
  930. #endregion
  931. #region 信件分类
  932. //信件来源
  933. var acceptTypeData = await _orderRepository.Queryable(false, false, false)
  934. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  935. .Select(it => new
  936. {
  937. AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode)
  938. })
  939. .MergeTable()//将查询出来的结果合并成一个新表
  940. .GroupBy(it => new { it.AcceptTypeCode })//对新表进行分组
  941. .Select(it => new CenterReportOrderSourceChannelDto
  942. {
  943. Code = it.AcceptTypeCode,
  944. CountNum = SqlFunc.AggregateCount(it.AcceptTypeCode)
  945. })
  946. .ToListAsync();
  947. List<CenterReportOrderSourceChannelDto> acceptType = new();
  948. var acceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
  949. foreach (var item in acceptTypeDic)
  950. {
  951. acceptType.Add(new CenterReportOrderSourceChannelDto
  952. {
  953. AllCountNum = sourceChannelCount,
  954. Name = item.DicDataName,
  955. Code = item.DicTypeCode,
  956. CountNum = acceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
  957. });
  958. }
  959. centerReportStatisticsDto.CenterReportOrderAcceptTypes = acceptType;
  960. #endregion
  961. #region 信件回访量
  962. //信件回访量
  963. CenterReportVisitdDto centerReportVisitd = new()
  964. {
  965. Visitd = await _orderVisitRepository.Queryable()
  966. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState == EVisitState.Visited).CountAsync(),
  967. WaitVisitd = await _orderVisitRepository.Queryable()
  968. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState != EVisitState.None && x.VisitState != EVisitState.Visited).CountAsync()
  969. };
  970. //部门
  971. var listOrg = await _orderVisitDetailRepository.Queryable()
  972. .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
  973. .Where((it, o) => it.VisitTarget == EVisitTarget.Org && o.VisitTime >= StartDate && o.VisitTime <= EndDate && o.VisitState == EVisitState.Visited)
  974. .Select((it, o) => new Satisfaction
  975. {
  976. Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
  977. Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 0, 1)),
  978. })
  979. .ToListAsync();
  980. if (listOrg != null && listOrg.Count > 0)
  981. {
  982. var SatisfiedCount = listOrg[0].Satisfied + listOrg[0].Satisfied;
  983. if (SatisfiedCount > 0 && listOrg[0].Satisfied > 0)
  984. centerReportVisitd.OrgRate = Math.Round((listOrg[0].Satisfied / (double)SatisfiedCount) * 100, 2);
  985. }
  986. //if (centerReportVisitd.Visitd > 0 && listOrg != null && listOrg.Count > 0 && listOrg[0].Satisfied > 0)
  987. //centerReportVisitd.OrgRate = Math.Round((listOrg[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
  988. //坐席
  989. var listSet = await _orderVisitDetailRepository.Queryable()
  990. .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
  991. .Where((it, o) => it.VisitTarget == EVisitTarget.Seat && o.VisitTime >= StartDate && o.VisitTime <= EndDate && o.VisitState == EVisitState.Visited)
  992. .Select((it, o) => new Satisfaction
  993. {
  994. Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied || it.SeatEvaluate == ESeatEvaluate.NoSatisfied, 1, 0)),
  995. Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate != ESeatEvaluate.VeryNoSatisfied && it.SeatEvaluate != ESeatEvaluate.NoSatisfied, 1, 0)),
  996. }).ToListAsync();
  997. if (listSet != null && listSet.Count > 0)
  998. {
  999. var SatisfiedCount = listSet[0].Satisfied + listSet[0].Satisfied;
  1000. if (SatisfiedCount > 0 && listSet[0].Satisfied > 0)
  1001. centerReportVisitd.OrgRate = Math.Round((listSet[0].Satisfied / (double)SatisfiedCount) * 100, 2);
  1002. }
  1003. //if (centerReportVisitd.Visitd > 0 && listSet != null && listSet.Count > 0 && listSet[0].Satisfied > 0)
  1004. // centerReportVisitd.SeatsRate = Math.Round((listSet[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
  1005. centerReportStatisticsDto.CenterReportVisitd = centerReportVisitd;
  1006. #endregion
  1007. #region 信件分布情况
  1008. //市直部门
  1009. var listOrgStatisticsCityAll = await _orderRepository.Queryable()
  1010. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  1011. .Where((it, o) => (o.OrgType == EOrgType.City || o.OrgType == EOrgType.Province) && it.CreationTime >= StartDate && it.CreationTime <= EndDate)
  1012. .GroupBy((it, o) => new
  1013. {
  1014. it.OrgLevelOneCode,
  1015. o.Name
  1016. })
  1017. .Select((it, o) => new OrgStatistics
  1018. {
  1019. CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
  1020. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
  1021. }).ToListAsync();
  1022. centerReportStatisticsDto.OrgStatisticsCityAll = new OrgStatisticsAll
  1023. {
  1024. OrgStatistics = listOrgStatisticsCityAll
  1025. };
  1026. //区县部门
  1027. var listOrgStatisticsAreaAll = await _orderRepository.Queryable()
  1028. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  1029. .Where((it, o) => o.OrgType == EOrgType.County && it.CreationTime >= StartDate && it.CreationTime <= EndDate)
  1030. .GroupBy((it, o) => new
  1031. {
  1032. it.OrgLevelOneCode,
  1033. o.Name
  1034. })
  1035. .Select((it, o) => new OrgStatistics
  1036. {
  1037. CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
  1038. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
  1039. }).ToListAsync();
  1040. centerReportStatisticsDto.OrgStatisticsAreaAll = new OrgStatisticsAll
  1041. {
  1042. OrgStatistics = listOrgStatisticsAreaAll
  1043. };
  1044. #endregion
  1045. return centerReportStatisticsDto;
  1046. }
  1047. /// <summary>
  1048. /// 部门受理类型统计周期
  1049. /// </summary>
  1050. /// <param name="StartDate"></param>
  1051. /// <param name="EndDate"></param>
  1052. /// <param name="TypeCode">0:全部,1:中心,2:部门</param>
  1053. /// <returns></returns>
  1054. [HttpGet("department_acceptance_type_statistics")]
  1055. public async Task<List<DepartmentAcceptanceTypeStatisticsDto>> DepartmentAcceptanceTypeStatistics(DateTime StartDate, DateTime EndDate, int TypeCode)
  1056. {
  1057. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  1058. var IsCenter = _sessionContext.OrgIsCenter;
  1059. var orderData = await _orderRepository.Queryable()
  1060. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  1061. .Where((it, o) => it.CreationTime >= StartDate && it.CreationTime <= EndDate && (int)it.Status >= 300)
  1062. .WhereIF(TypeCode == 1, (it, o) => it.OrgLevelOneCode == "001")
  1063. .WhereIF(TypeCode == 2, (it, o) => it.OrgLevelOneCode != "001")
  1064. .WhereIF(IsCenter == false, (it, o) => it.OrgLevelOneCode.StartsWith(_sessionContext.RequiredOrgId))
  1065. .GroupBy((it, o) => new
  1066. {
  1067. it.OrgLevelOneCode,
  1068. o.Name,
  1069. o.OrgType
  1070. })
  1071. .Select((it, o) => new DepartmentAcceptanceTypeStatisticsDto
  1072. {
  1073. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name,
  1074. OrgCode = it.OrgLevelOneCode,
  1075. OrgType = (int)o.OrgType == 2 ? "区县部门" : "市直部门",
  1076. ZxAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "10", 1, 0)),
  1077. ZxAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "10" && it.AllDuration != null, it.AllDuration, 0)),
  1078. ZxAcceptanceTypeCode = "10",
  1079. JyAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "15", 1, 0)),
  1080. JyAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "15" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1081. JyAcceptanceTypeCode = "15",
  1082. QzAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "20", 1, 0)),
  1083. QzAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "20" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1084. QzAcceptanceTypeCode = "20",
  1085. ByAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "25", 1, 0)),
  1086. ByAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "25" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1087. ByAcceptanceTypeCode = "25",
  1088. JbAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "30", 1, 0)),
  1089. JbAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "30" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1090. JbAcceptanceTypeCode = "30",
  1091. TsAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "35", 1, 0)),
  1092. TsAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "35" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1093. TsAcceptanceTypeCode = "35",
  1094. QtAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "40", 1, 0)),
  1095. QtAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "40" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  1096. QtAcceptanceTypeCode = "40"
  1097. })
  1098. .ToListAsync();
  1099. return orderData;
  1100. }
  1101. /// <summary>
  1102. /// 部门受理类型统计周期--明细列表
  1103. /// </summary>
  1104. /// <param name="dto"></param>
  1105. /// <returns></returns>
  1106. [HttpGet("department_acceptance_type_order_list")]
  1107. public async Task<PagedDto<OrderDto>> DepartmentAcceptanceTypeOrderList([FromQuery] DepartmentKeyWordRequest dto)
  1108. {
  1109. dto.EndDate = dto.EndDate.AddDays(1).AddSeconds(-1);
  1110. var (total, items) = await _orderRepository.Queryable()
  1111. .Where(p => p.CreationTime >= dto.StartDate && p.CreationTime <= dto.EndDate && (int)p.Status >= 300)
  1112. .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneCode), p => p.OrgLevelOneCode == dto.OrgLevelOneCode)
  1113. .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), p => p.AcceptTypeCode == dto.AcceptTypeCode)
  1114. .OrderByDescending(d => d.CreationTime)
  1115. .ToPagedListAsync(dto, HttpContext.RequestAborted);
  1116. return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
  1117. }
  1118. /// <summary>
  1119. /// 部门办件统计表-----未完成
  1120. /// </summary>
  1121. /// <param name="StartDate"></param>
  1122. /// <param name="EndDate"></param>
  1123. /// <param name="OrgCode"></param>
  1124. /// <param name="OrgName"></param>
  1125. /// <returns></returns>
  1126. [HttpGet("departmental_processing_statistics")]
  1127. [AllowAnonymous]
  1128. public async Task<object> DepartmentalProcessingStatistics(DateTime StartDate, DateTime EndDate, string? OrgCode, string? OrgName)
  1129. {
  1130. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  1131. var handeOrgDownNum = 0;
  1132. if (!string.IsNullOrEmpty(OrgCode) && OrgCode != "001")
  1133. {
  1134. handeOrgDownNum = OrgCode.Length + 3;
  1135. }
  1136. //工单
  1137. var query = _orderRepository.Queryable()
  1138. .Where(it => it.CreationTime >= StartDate && it.CreationTime <= EndDate)
  1139. .Select(it => new
  1140. {
  1141. it.Id,
  1142. OrgLevelOneCode = SqlFunc.IIF(it.ActualHandleOrgCode != "001", SqlFunc.Substring(it.ActualHandleOrgCode, 0, 6), it.ActualHandleOrgCode),
  1143. OrgLevelDownCode = SqlFunc.IIF(!string.IsNullOrEmpty(OrgCode) && OrgCode != "001" && it.ActualHandleOrgCode.Length >= handeOrgDownNum
  1144. , SqlFunc.Substring(it.ActualHandleOrgCode, 0, handeOrgDownNum), it.ActualHandleOrgCode),
  1145. it.ActualHandleOrgCode,
  1146. it.Status,//工单状态
  1147. it.ExpiredTime,//期满时间
  1148. it.ActualHandleTime,//办理时间
  1149. it.CounterSignType,//会签
  1150. }).MergeTable()
  1151. .WhereIF(!string.IsNullOrEmpty(OrgCode) && OrgCode == "001", it => it.OrgLevelOneCode == OrgCode)
  1152. .WhereIF(!string.IsNullOrEmpty(OrgCode) && OrgCode != "001", it => it.OrgLevelDownCode.Contains(OrgCode))
  1153. .MergeTable()
  1154. .Select(it => new DepartmentalProcessingStatisticsDto
  1155. {
  1156. Id = it.Id,
  1157. OrgCode = SqlFunc.IIF(!string.IsNullOrEmpty(OrgCode), it.OrgLevelDownCode, it.OrgLevelOneCode),
  1158. ActualHandleOrgCode = it.ActualHandleOrgCode,
  1159. Status = it.Status,//工单状态
  1160. ExpiredTime = it.ExpiredTime,//期满时间
  1161. ActualHandleTime = it.ActualHandleTime,//办理时间
  1162. CounterSignType = it.CounterSignType,//会签
  1163. }).MergeTable();
  1164. //发布
  1165. var queryPublish = _orderPublishRepository.Queryable()
  1166. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  1167. .GroupBy(it => new
  1168. {
  1169. it.OrderId,
  1170. it.PublishState
  1171. })
  1172. .Select(it => new DepartmentalProcessingStatisticsDto
  1173. {
  1174. Id = it.OrderId,
  1175. PublishState = it.PublishState
  1176. });
  1177. //会签
  1178. var queryCountersign = _workflowCountersignRepository.Queryable()
  1179. .LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
  1180. .Where(x => x.CreationTime >= StartDate && x.CreationTime <= EndDate)
  1181. .GroupBy((x, o) => o.Key)
  1182. .Select((x, o) => new DepartmentalProcessingStatisticsDataDto
  1183. {
  1184. OrgCode = o.Key,
  1185. HQYBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled, 1, 0)),
  1186. HQZBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  1187. DelayEnd = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  1188. DelayWait = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  1189. }).MergeTable();
  1190. var queryPush = query.LeftJoin(queryPublish, (it, o) => it.Id == o.Id).Where(it => it.OrgCode != null);
  1191. return await queryPush.GroupBy((it, o) => new
  1192. {
  1193. it.OrgCode
  1194. })
  1195. .Select((it, o) => new
  1196. {
  1197. //办件信息完整
  1198. OrgCode = it.OrgCode,
  1199. OrderCountNum = SqlFunc.AggregateCount(it.OrgCode),//总量
  1200. YBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 300, 1, 0)),//已办
  1201. ZBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status < 300, 1, 0)),//在办
  1202. YBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 300 && it.ActualHandleTime > it.ExpiredTime, 1, 0)),//已办超期
  1203. ZBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status < 300 && it.ExpiredTime < SqlFunc.GetDate(), 1, 0)),//待办超期
  1204. HQYBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 300 && it.CounterSignType != null && it.ActualHandleTime > it.ExpiredTime, 1, 0)),//会签已办超期
  1205. HQZBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status < 300 && it.CounterSignType != null && it.ExpiredTime < SqlFunc.GetDate(), 1, 0)),//会签待办超期
  1206. //归档完整
  1207. Archived = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 300, 1, 0)),//已归档
  1208. ToBeArchived = 0,//待归档
  1209. //发布完整
  1210. WaitPublished = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status == 300, 1, 0)),//待发布 --已归档的就是待发布
  1211. PublishedOpen = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 400 && o.PublishState, 1, 0)),//已发布公开
  1212. PublishedNoOpen = SqlFunc.AggregateSum(SqlFunc.IIF((int)it.Status >= 400 && !o.PublishState, 1, 0)),//已发布不公开
  1213. }).ToListAsync();
  1214. }
  1215. /// <summary>
  1216. /// 高频来电统计
  1217. /// </summary>
  1218. /// <param name="dto"></param>
  1219. /// <returns></returns>
  1220. [HttpGet("high_frequency_call_statistics")]
  1221. public async Task<PagedDto<HighFrequencyCallStatisticsDto>> HighFrequencyCallStatistics([FromQuery] HighFrequencyCallStatisticsRequest dto)
  1222. {
  1223. if (!dto.StartDate.HasValue || !dto.EndDate.HasValue)
  1224. throw UserFriendlyException.SameMessage("请选择时间!");
  1225. dto.EndDate = dto.EndDate.Value.AddDays(1).AddSeconds(-1);
  1226. int CallCount = 2;
  1227. var HighFrequencyCallStatistics = _systemSettingCacheManager.GetSetting(SettingConstants.HighFrequencyCallStatistics)?.SettingValue[0];
  1228. if (HighFrequencyCallStatistics != null)
  1229. CallCount = int.Parse(HighFrequencyCallStatistics);
  1230. var (total, items) = await _trCallRecordRepository.Queryable()
  1231. .LeftJoin<Order>((p, o) => p.ExternalId == o.Id)
  1232. .Where((p, o) => p.OverTime >= dto.StartDate && p.OverTime <= dto.EndDate)
  1233. .Where((p, o) => p.CallOrderType == ECallOrderType.Order)
  1234. .Where((p, o) => p.ExternalId != null && o.Id != null)
  1235. .WhereIF(!string.IsNullOrEmpty(dto.PhoneNum), (p, o) => p.CPN == dto.PhoneNum)
  1236. .Select((p, o) => new
  1237. {
  1238. p.CPN,
  1239. p.ExternalId
  1240. })
  1241. .MergeTable()
  1242. .GroupBy(p => p.CPN)
  1243. .Select(p => new HighFrequencyCallStatisticsDto
  1244. {
  1245. Callnum = p.CPN,
  1246. OrderCountNum = SqlFunc.AggregateCount(p.CPN),//总量
  1247. })
  1248. .MergeTable()
  1249. .Where(p => p.OrderCountNum >= CallCount)
  1250. .OrderByDescending(p => p.OrderCountNum)
  1251. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1252. return new PagedDto<HighFrequencyCallStatisticsDto>(total, _mapper.Map<IReadOnlyList<HighFrequencyCallStatisticsDto>>(items));
  1253. }
  1254. /// <summary>
  1255. /// 高频来电统计列表详情
  1256. /// </summary>
  1257. /// <param name="dto"></param>
  1258. /// <returns></returns>
  1259. [HttpGet("high_frequency_call_statistics_order_list")]
  1260. public async Task<PagedDto<OrderDto>> HighFrequencyCallStatisticsOrderList([FromQuery] HighFrequencyCallStatisticsListRequest dto)
  1261. {
  1262. if (!dto.StartDate.HasValue || !dto.EndDate.HasValue)
  1263. throw UserFriendlyException.SameMessage("请选择时间!");
  1264. if (string.IsNullOrEmpty(dto.FromPhone))
  1265. throw UserFriendlyException.SameMessage("号码不能为空!");
  1266. dto.EndDate = dto.EndDate.Value.AddDays(1).AddSeconds(-1);
  1267. var data = await _trCallRecordRepository.Queryable()
  1268. .LeftJoin<Order>((p, o) => p.ExternalId == o.Id)
  1269. .Where((p, o) => p.OverTime >= dto.StartDate && p.OverTime <= dto.EndDate)
  1270. .Where((p, o) => p.CallOrderType == ECallOrderType.Order)
  1271. .Where((p, o) => p.ExternalId != null && o.Id != null)
  1272. .Where((p, o) => p.CPN == dto.FromPhone)
  1273. .Select((p, o) =>
  1274. p.ExternalId
  1275. )
  1276. .ToListAsync();
  1277. var (total, items) = await _orderRepository.Queryable()
  1278. .Includes(x => x.OrderScreens)
  1279. .Where(p => data.Contains(p.Id))
  1280. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword!)) //标题
  1281. .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), d => d.ProvinceNo.Contains(dto.ProvinceNo)) //省本地编号
  1282. .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No)) //工单编码
  1283. .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptTypeCode)) //受理类型
  1284. .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannelCode)) //来源渠道
  1285. .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId)) //热点类型
  1286. .WhereIF(!string.IsNullOrEmpty(dto.TransferPhone), d => d.TransferPhone.Contains(dto.TransferPhone!)) //转接号码
  1287. .WhereIF(dto.OrgCodes.Any(), d => dto.OrgCodes.Contains(d.ActualHandleOrgCode)) //接办部门
  1288. .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), d => d.AcceptorName.Contains(dto.NameOrNo!) || d.AcceptorStaffNo.Contains(dto.NameOrNo!)) //受理人/坐席
  1289. .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart) //受理时间开始
  1290. .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd) //受理时间结束
  1291. .WhereIF(dto.EmergencyLevels.Any(), d => dto.EmergencyLevels.Contains(d.EmergencyLevel)) //紧急程度
  1292. // .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.FromPhone.Contains(dto.FromPhone)) //来电号码
  1293. .WhereIF(!string.IsNullOrEmpty(dto.PhoneNo), d => d.Contact.Contains(dto.PhoneNo!)) //联系电话
  1294. .WhereIF(!string.IsNullOrEmpty(dto.PushTypeCode), d => d.PushTypeCode == dto.PushTypeCode) //推送分类
  1295. .WhereIF(dto.ExpiredTimeStart.HasValue, d => d.ExpiredTime >= dto.ExpiredTimeStart) //超期时间开始
  1296. .WhereIF(dto.ExpiredTimeEnd.HasValue, d => d.ExpiredTime <= dto.ExpiredTimeEnd) //超期时间结束
  1297. .WhereIF(dto.Statuses.Any(), d => dto.Statuses.Contains(d.Status)) //工单状态
  1298. .WhereIF(dto.Statuses.Any(d => d == EOrderStatus.SpecialToUnAccept), d => d.Status <= EOrderStatus.SpecialToUnAccept)
  1299. .WhereIF(!string.IsNullOrEmpty(dto.ActualHandlerName), d => d.ActualHandlerName.Contains(dto.ActualHandlerName)) //接办人
  1300. .WhereIF(dto.IsScreen == true, d => d.OrderScreens.Any(x => x.Status != EScreenStatus.Refuse)) //有甄别
  1301. .WhereIF(dto.IsScreen == false, d => !d.OrderScreens.Any(x => x.Status != EScreenStatus.Refuse)) //无甄别
  1302. .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), d => d.ActualHandleStepCode == dto.CurrentStepCode) //当前办理节点
  1303. .WhereIF(dto.ActualHandleTimeStart.HasValue, d => d.ActualHandleTime >= dto.ActualHandleTimeStart) //办结时间开始
  1304. .WhereIF(dto.ActualHandleTimeEnd.HasValue, d => d.ActualHandleTime <= dto.ActualHandleTimeEnd) //办结时间结束
  1305. .WhereIF(dto.IsOverTime == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //是 超期
  1306. .WhereIF(dto.IsOverTime == false, d => (d.ExpiredTime > DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime > d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //否 超期
  1307. .WhereIF(dto.IdentityType != null, d => d.IdentityType == dto.IdentityType) //来电主体
  1308. .WhereIF(!string.IsNullOrEmpty(dto.FromName), d => d.FromName.Contains(dto.FromName)) //来电人姓名
  1309. .WhereIF(dto.AreaCodes.Any(), d => dto.AreaCodes.Contains(d.AreaCode)) //区域
  1310. .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.IsProvince == true)
  1311. .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.IsProvince == false)
  1312. .OrderByDescending(d => d.CreationTime)
  1313. .ToPagedListAsync(dto, HttpContext.RequestAborted);
  1314. return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
  1315. }
  1316. /// <summary>
  1317. /// 高频事项预警
  1318. /// </summary>
  1319. /// <param name="dto"></param>
  1320. /// <returns></returns>
  1321. [HttpGet("highmatter-warning")]
  1322. public async Task<PagedDto<HighMatterWarningDto>> HighMatterWarning([FromQuery] HighMatterWarningRequest dto)
  1323. {
  1324. var (total, items) = await _orderRepository.Queryable(false, false, false)
  1325. .Where(x => x.CreationTime >= dto.StartDate && x.CreationTime <= dto.EndDate)
  1326. .LeftJoin<SystemArea>((it, o) => it.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == o.Id)
  1327. .WhereIF(dto.AreaCodes.Any(), (it, o) => dto.AreaCodes.Contains(it.AreaCode)) //区域
  1328. .WhereIF(dto.HotspotIds.Any(), (it, o) => dto.HotspotIds.Contains(it.HotspotId)) //热点类型
  1329. .WhereIF(dto.AcceptTypeCodes.Any(), (it, o) => dto.AcceptTypeCodes.Contains(it.AcceptTypeCode)) //受理类型
  1330. .GroupBy((it, o) => new
  1331. {
  1332. it.AcceptTypeCode,
  1333. it.AcceptType,
  1334. it.HotspotId,
  1335. it.HotspotName,
  1336. AreaCode = it.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
  1337. o.AreaName,
  1338. o.Id,
  1339. })
  1340. .Having((it, o) => SqlFunc.AggregateCount(it.HotspotName) >= 5)
  1341. .Select((it, o) => new HighMatterWarningDto()
  1342. {
  1343. AcceptTypeCode = it.AcceptTypeCode,
  1344. AcceptType = it.AcceptType,
  1345. AreaName = o.AreaName,
  1346. HotspotName = it.HotspotName,
  1347. HotspotId = it.HotspotId,
  1348. SumCount = SqlFunc.AggregateCount(it.HotspotName),
  1349. Id = SqlFunc.AggregateMin(it.Id),
  1350. AreaCode = o.Id
  1351. })
  1352. .MergeTable()
  1353. .LeftJoin<Order>((x, d) => x.Id == d.Id)
  1354. .Select((x, d) => new HighMatterWarningDto()
  1355. {
  1356. AreaName = x.AreaName,
  1357. HotspotName = x.HotspotName,
  1358. HotspotId = x.HotspotId,
  1359. Title = d.Title,
  1360. SumCount = x.SumCount,
  1361. Id = d.Id,
  1362. AcceptTypeCode = x.AcceptTypeCode,
  1363. AcceptType = x.AcceptType,
  1364. AreaCode = x.AreaCode
  1365. })
  1366. .MergeTable()
  1367. .OrderByDescending(d => d.SumCount).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  1368. return new PagedDto<HighMatterWarningDto>(total, _mapper.Map<IReadOnlyList<HighMatterWarningDto>>(items));
  1369. }
  1370. /// <summary>
  1371. /// 高频事项预警明细
  1372. /// </summary>
  1373. /// <param name="dto"></param>
  1374. /// <returns></returns>
  1375. [HttpGet("highmatter-warning-detail")]
  1376. public async Task<PagedDto<OrderDto>> HighMatterWarningDetail([FromQuery] HighMatterWarningDetailRequest dto)
  1377. {
  1378. var (total, items) = await _orderRepository.Queryable(viewFilter: true)
  1379. .Includes(x => x.OrderScreens)
  1380. .Where(d => d.AcceptTypeCode == dto.AcceptTypeCode) //受理类型
  1381. .Where(d => d.HotspotId == dto.HotspotId) //热点类型
  1382. .Where(d => d.CreationTime >= dto.StartDate) //受理时间开始
  1383. .Where(d => d.CreationTime <= dto.EndDate) //受理时间结束
  1384. .Where(d => d.AreaCode == dto.AreaCode) //区域
  1385. .OrderByDescending(d => d.CreationTime)
  1386. .ToPagedListAsync(dto, HttpContext.RequestAborted);
  1387. return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
  1388. }
  1389. }
  1390. }