BiOrderController.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. using Hotline.Orders;
  2. using Hotline.Repository.SqlSugar.Extensions;
  3. using Hotline.Settings;
  4. using Hotline.Settings.Hotspots;
  5. using Hotline.Share.Dtos;
  6. using Hotline.Share.Dtos.Order;
  7. using Hotline.Share.Enums.Order;
  8. using Microsoft.AspNetCore.Mvc;
  9. using SqlSugar;
  10. using Hotline.Share.Requests;
  11. using XF.Domain.Repository;
  12. using Hotline.Caching.Interfaces;
  13. using Hotline.FlowEngine.Workflows;
  14. using Hotline.Share.Dtos.CallCenter;
  15. using MapsterMapper;
  16. using XF.Domain.Exceptions;
  17. using Microsoft.AspNetCore.Authorization;
  18. namespace Hotline.Api.Controllers.Bi
  19. {
  20. public class BiOrderController : BaseController
  21. {
  22. private readonly IOrderRepository _orderRepository;
  23. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  24. private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
  25. private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
  26. private readonly IRepository<OrderDelay> _orderDelayRepository;
  27. private readonly IMapper _mapper;
  28. private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
  29. private readonly IRepository<OrderSpecial> _orderSpecialRepository;
  30. private readonly IRepository<OrderVisit> _orderVisitRepository;
  31. public BiOrderController(
  32. IOrderRepository orderRepository,
  33. IRepository<Hotspot> hotspotTypeRepository,
  34. ISystemDicDataCacheManager sysDicDataCacheManager,
  35. IRepository<OrderVisitDetail> orderVisitDetailRepository,
  36. IRepository<OrderDelay> orderDelayRepository,
  37. IRepository<WorkflowCountersign> workflowCountersignRepository,
  38. IRepository<OrderSpecial> orderSpecialRepository,
  39. IMapper mapper,
  40. IRepository<OrderVisit> orderVisitRepository
  41. )
  42. {
  43. _orderRepository = orderRepository;
  44. _hotspotTypeRepository = hotspotTypeRepository;
  45. _sysDicDataCacheManager = sysDicDataCacheManager;
  46. _orderVisitDetailRepository = orderVisitDetailRepository;
  47. _orderDelayRepository = orderDelayRepository;
  48. _workflowCountersignRepository = workflowCountersignRepository;
  49. _orderSpecialRepository = orderSpecialRepository;
  50. _mapper = mapper;
  51. _orderVisitRepository = orderVisitRepository;
  52. }
  53. /// <summary>
  54. /// 部门数据统计
  55. /// </summary>
  56. /// <param name="dto"></param>
  57. /// <returns></returns>
  58. [HttpGet("org_data_list")]
  59. public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
  60. {
  61. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  62. var queryOrder = _orderRepository.Queryable(false, false, false)
  63. .LeftJoin<SystemOrganize>((x, o) => x.ActualHandleOrgCode == o.Id)
  64. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  65. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  66. .GroupBy((x, o) => new { x.ActualHandleOrgCode, o.Name })
  67. .Select((x, o) => new OrderBiOrgDataListVo
  68. {
  69. OrgName = o.Name,
  70. OrgId = x.ActualHandleOrgCode,
  71. HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
  72. NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime < SqlFunc.GetDate(), 1, 0)),
  73. }).MergeTable();
  74. var queryCountersign = _workflowCountersignRepository.Queryable()
  75. .LeftJoin<WorkflowCountersignMember>((x,o)=>x.Id ==o.WorkflowCountersignId)
  76. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  77. .WhereIF(dto.EndTime.HasValue, x=> x.CreationTime <= dto.EndTime)
  78. .GroupBy((x,o)=> o.Key)
  79. .Select((x,o) => new OrderBiOrgDataListVo
  80. {
  81. OrgId = o.Key,
  82. CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled,1,0)),
  83. CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  84. }).MergeTable();
  85. var query = queryOrder.LeftJoin(queryCountersign,(or,co)=>or.OrgId == co.OrgId)
  86. .Select((or,co) => new OrderBiOrgDataListVo {
  87. OrgName = or.OrgName,
  88. OrgId = or.OrgId,
  89. HandlerExtendedNum =or.HandlerExtendedNum,
  90. NoHandlerExtendedNum =or.NoHandlerExtendedNum,
  91. CounterHandlerExtendedNum =co.CounterHandlerExtendedNum,
  92. CounterNoHandlerExtendedNum =co.CounterNoHandlerExtendedNum
  93. }).MergeTable();
  94. query = query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrgName.Contains(dto.Keyword!));
  95. switch (dto.SortField)
  96. {
  97. case "handlerExtendedNum":
  98. query = dto.SortRule == 0 ? query.OrderBy(x => x.HandlerExtendedNum) : query.OrderByDescending(x => x.HandlerExtendedNum);
  99. break;
  100. case "counterHandlerExtendedNum":
  101. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterHandlerExtendedNum) : query.OrderByDescending(x => x.CounterHandlerExtendedNum);
  102. break;
  103. case "noHandlerExtendedNum":
  104. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoHandlerExtendedNum) : query.OrderByDescending(x => x.NoHandlerExtendedNum);
  105. break;
  106. case "counterNoHandlerExtendedNum":
  107. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterNoHandlerExtendedNum) : query.OrderByDescending(x => x.CounterNoHandlerExtendedNum);
  108. break;
  109. }
  110. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  111. return new PagedDto<OrderBiOrgDataListVo>(total, items);
  112. }
  113. /// <summary>
  114. /// 中心统计
  115. /// </summary>
  116. /// <param name="dto"></param>
  117. /// <returns></returns>
  118. [HttpGet("centre_data_list")]
  119. public async Task<PagedDto<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto)
  120. {
  121. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  122. var query = _orderRepository.Queryable(false, false, false)
  123. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  124. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  125. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.AcceptorName.Contains(dto.Keyword!))
  126. .GroupBy(x => new { x.AcceptorId, x.AcceptorName })
  127. .Select(x => new OrderBiCentreDataListVo
  128. {
  129. UserName = x.AcceptorName,
  130. UserId = x.AcceptorId,
  131. CentreArchive = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Zhiban, 1, 0)),
  132. CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Jiaoban, 1, 0)),
  133. //NoCentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
  134. Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(x.AcceptType == "无效", 1, 0)),
  135. Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(x.DuplicateIds != null && SqlFunc.JsonArrayLength(x.DuplicateIds) > 0, 1, 0))
  136. }).MergeTable();
  137. switch (dto.SortField)
  138. {
  139. case "centreArchive":
  140. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreArchive) : query.OrderByDescending(x => x.CentreArchive);
  141. break;
  142. case "centreCareOf":
  143. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreCareOf) : query.OrderByDescending(x => x.CentreCareOf);
  144. break;
  145. case "noCentreCareOf":
  146. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoCentreCareOf) : query.OrderByDescending(x => x.NoCentreCareOf);
  147. break;
  148. case "invalid":
  149. query = dto.SortRule == 0 ? query.OrderBy(x => x.Invalid) : query.OrderByDescending(x => x.Invalid);
  150. break;
  151. case "repeat":
  152. query = dto.SortRule == 0 ? query.OrderBy(x => x.Repeat) : query.OrderByDescending(x => x.Repeat);
  153. break;
  154. }
  155. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  156. return new PagedDto<OrderBiCentreDataListVo>(total, items);
  157. }
  158. /// <summary>
  159. /// 热点数据小计统计
  160. /// </summary>
  161. /// <param name="dto"></param>
  162. /// <returns></returns>
  163. [HttpGet("hotspot_subtotal_data_list")]
  164. public async Task<PagedDto<HotspotDataLsitVo>> HotspotSubtotalDataLsit([FromQuery] HotspotSubtotalReportPagedRequest dto)
  165. {
  166. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  167. var query = _hotspotTypeRepository.Queryable(false, true)
  168. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotFullName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotFullName)) && o.IsDeleted == false)
  169. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
  170. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
  171. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  172. .Where((x, o) => x.ParentId == dto.Id)
  173. .Where((x, o) => x.IsDeleted == false)
  174. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  175. .Select((x, o) => new HotspotDataLsitVo
  176. {
  177. Id = x.Id,
  178. Name = x.HotSpotName,
  179. Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  180. }).MergeTable();
  181. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  182. return new PagedDto<HotspotDataLsitVo>(total, items);
  183. }
  184. /// <summary>
  185. /// 热点数据统计
  186. /// </summary>
  187. /// <param name="dto"></param>
  188. /// <returns></returns>
  189. [HttpGet("hotspot_data_list")]
  190. public async Task<object> HotspotDataLsit([FromQuery] HotspotReportPagedRequest dto)
  191. {
  192. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  193. if (dto.Type == 0 && (!dto.ChainStartTime.HasValue || !dto.ChainEndTime.HasValue)) throw UserFriendlyException.SameMessage("请选择环比时间!");
  194. var items = await _hotspotTypeRepository.Queryable(false, true)
  195. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && 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. Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.HotSpotName != o.HotspotName, 1, 0)) > 0,
  208. }).MergeTable().ToListAsync();
  209. var chainStartTime = dto.StartTime;
  210. var chainEndTime = dto.EndTime;
  211. switch (dto.Type)
  212. {
  213. case 1://日
  214. chainStartTime = dto.StartTime.Value.AddDays(-1);
  215. chainEndTime = dto.EndTime.Value.AddDays(-1);
  216. break;
  217. case 2://月
  218. chainStartTime = dto.StartTime.Value.AddMonths(-1);
  219. chainEndTime = dto.EndTime.Value.AddMonths(-1);
  220. break;
  221. case 3://年
  222. chainStartTime = dto.StartTime.Value.AddYears(-1);
  223. chainEndTime = dto.EndTime.Value.AddYears(-1);
  224. break;
  225. case 0:
  226. chainStartTime = dto.ChainStartTime.Value;
  227. chainEndTime = dto.ChainEndTime.Value;
  228. break;
  229. }
  230. var chainItems = await _hotspotTypeRepository.Queryable(false, true)
  231. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && o.IsDeleted == false)
  232. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= chainStartTime)
  233. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= chainEndTime)
  234. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  235. .Where((x, o) => x.ParentId == dto.Id)
  236. .Where((x, o) => x.IsDeleted == false)
  237. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  238. .Select((x, o) => new
  239. {
  240. Id = x.Id,
  241. ChainNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  242. }).MergeTable().ToListAsync();
  243. var res = (from t1 in items
  244. join t2 in chainItems on t1.Id equals t2.Id into t1_t2
  245. from item in t1_t2.DefaultIfEmpty()
  246. select new
  247. {
  248. Id = t1.Id,
  249. Name = t1.Name,
  250. Num = t1.Num,
  251. Sublevel = t1.Sublevel,
  252. Children = new List<HotspotDataLsitVo>(),
  253. ChainNum = t1_t2.Select(x => x.ChainNum).FirstOrDefault(),
  254. ChainRate = t1_t2.Select(x => x.ChainNum).FirstOrDefault() > 0 ?
  255. ((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%",
  256. }).ToList();
  257. return res;
  258. }
  259. /// <summary>
  260. /// 部门不满意统计
  261. /// </summary>
  262. /// <param name="dto"></param>
  263. /// <returns></returns>
  264. [HttpGet("visit-nosatisfied")]
  265. public async Task<object> QueryVisitNoSatisfied([FromQuery] QueryVisitNoSatiisfiedRequest dto)
  266. {
  267. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  268. var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);
  269. List<dynamic>? list = new List<dynamic>();
  270. //DataTable dt = new DataTable();
  271. foreach (var item in dissatisfiedReason)
  272. {
  273. var table = _orderVisitDetailRepository.Queryable()
  274. .Includes(x => x.OrderVisit)
  275. .Where(x => x.VisitTarget == Share.Enums.Order.EVisitTarget.Org)
  276. .Where(x => x.OrgNoSatisfiedReason != null)
  277. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  278. .Where(x => !string.IsNullOrEmpty(x.VisitOrgName))
  279. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.VisitOrgName.Contains(dto.OrgName))
  280. .WhereIF(dto.StartTime.HasValue, x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  281. .WhereIF(dto.EndTime.HasValue, x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  282. .GroupBy(x => new { x.VisitOrgName, x.VisitOrgCode })
  283. .Select(x => new BiVisitNoSatisfiedDto
  284. {
  285. Count = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", item.DicDataValue), 1, 0)),
  286. Key = item.DicDataValue,
  287. OrgName = x.VisitOrgName,
  288. OrgCode = x.VisitOrgCode
  289. })
  290. .OrderByDescending(x => x.Count)
  291. //.ToPivotTable(x => x.Key, x => x.OrgName, x => x.Sum(x => x.Count));
  292. .ToPivotList(x => x.Key,x=> new { x.OrgCode,x.OrgName }, x => x.Sum(x => x.Count));
  293. list.AddRange(table);
  294. }
  295. return new { DicReason = dissatisfiedReason, Data = list };
  296. }
  297. /// <summary>
  298. /// 部门不满意统计明细
  299. /// </summary>
  300. /// <param name="dto"></param>
  301. /// <returns></returns>
  302. [HttpGet("visit-nosatisfied-detail")]
  303. public async Task<PagedDto<OrderVisitDetailDto>> BiQueryVisitNoSatisfiedDetail([FromQuery]BiQueryVisitNoSatisfiedDetailDto dto)
  304. {
  305. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  306. var (total,items) = await _orderVisitDetailRepository.Queryable()
  307. .Includes(x => x.OrderVisit, d => d.Order)
  308. .Includes(x => x.OrderVisit, d => d.Employee)
  309. .Where(x => x.VisitOrgCode == dto.OrgCode)
  310. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  311. .Where(x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  312. .Where(x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  313. .Where(x => SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", dto.DissatisfiedKey))
  314. .WhereIF(!string.IsNullOrEmpty(dto.Keyword),x=>x.OrderVisit.Order.No.Contains(dto.Keyword) || x.OrderVisit.Order.Title.Contains(dto.Keyword))
  315. .OrderBy(x => x.OrderVisit.VisitTime)
  316. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  317. return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
  318. }
  319. /// <summary>
  320. /// 部门延期统计
  321. /// </summary>
  322. /// <param name="dto"></param>
  323. /// <returns></returns>
  324. [HttpGet("order-delay-data-list")]
  325. public async Task<IReadOnlyList<BiOrderDelayDataDto>> QueryOrderDelayDataList([FromQuery] QueryOrderDelayDataListRequest dto)
  326. {
  327. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  328. var list = await _orderDelayRepository.Queryable()
  329. .LeftJoin<SystemOrganize>((x, o) => x.ApplyOrgCode == o.Id)
  330. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  331. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  332. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.ApplyOrgName.Contains(dto.OrgName))
  333. .GroupBy(x => new { x.ApplyOrgCode, x.ApplyOrgName })
  334. .Select(x => new BiOrderDelayDataDto
  335. {
  336. OrgName = x.ApplyOrgName,
  337. OrgCode = x.ApplyOrgCode,
  338. PassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)),
  339. NoPassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)),
  340. ExaminingTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0)),
  341. 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))
  342. }).ToListAsync();
  343. return list;
  344. }
  345. /// <summary>
  346. /// 特提统计
  347. /// </summary>
  348. /// <param name="dto"></param>
  349. /// <returns></returns>
  350. [HttpGet("special_data_list")]
  351. public async Task<PagedDto<OrderBiSpecialListVo>> SpecialDataList([FromQuery] ReportPagedRequest dto)
  352. {
  353. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  354. var query = _orderSpecialRepository.Queryable()
  355. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  356. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  357. .GroupBy(x => new { x.Cause })
  358. .Select(x => new OrderBiSpecialListVo
  359. {
  360. Cause = x.Cause,
  361. OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  362. MaxSpecialTime = SqlFunc.AggregateMax(x.CreationTime),
  363. }).MergeTable();
  364. switch (dto.SortField)
  365. {
  366. case "cause":
  367. query = dto.SortRule == 0 ? query.OrderBy(x => x.Cause) : query.OrderByDescending(x => x.Cause);
  368. break;
  369. case "orderNum":
  370. query = dto.SortRule == 0 ? query.OrderBy(x => x.OrderNum) : query.OrderByDescending(x => x.OrderNum);
  371. break;
  372. case "maxSpecialTime":
  373. query = dto.SortRule == 0 ? query.OrderBy(x => x.MaxSpecialTime) : query.OrderByDescending(x => x.MaxSpecialTime);
  374. break;
  375. }
  376. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  377. return new PagedDto<OrderBiSpecialListVo>(total, items);
  378. }
  379. /// <summary>
  380. /// 获取工单特提信息列表
  381. /// </summary>
  382. /// <param name="dto"></param>
  383. /// <returns></returns>
  384. [HttpGet("special_data_list/list")]
  385. public async Task<PagedDto<OrderSpecialDto>> List([FromQuery] OrderSpecialListDto dto)
  386. {
  387. if(!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  388. var (total, items) = await _orderSpecialRepository.Queryable()
  389. .Includes(x => x.Order)
  390. .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
  391. x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
  392. .WhereIF(!string.IsNullOrEmpty(dto.Cause),
  393. x => x.Cause != null && x.Cause.Equals(dto.Cause))
  394. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  395. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  396. .WhereIF(dto.State.HasValue, x => x.State == dto.State)
  397. .OrderByDescending(x => x.CreationTime)
  398. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  399. return new PagedDto<OrderSpecialDto>(total, _mapper.Map<IReadOnlyList<OrderSpecialDto>>(items));
  400. }
  401. /// <summary>
  402. /// 受理类型前十
  403. /// </summary>
  404. /// <param name="dto"></param>
  405. /// <returns></returns>
  406. //[HttpGet("accept_type_top10_list")]
  407. //public async Task<object> AcceptTypeTop10List([FromQuery] ReportPagedRequest dto)
  408. // {
  409. // if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  410. // dto.PageIndex = 1;
  411. // dto.PageSize = 10;
  412. // var acceptType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
  413. // List<dynamic> listReturn = new List<dynamic>();
  414. // var validQuery = await _orderRepository.Queryable(false, false, false)
  415. // .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  416. // .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  417. // .Select(x => new
  418. // {
  419. // AcceptType = x.AcceptType,
  420. // OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
  421. // Id = x.Id
  422. // }).MergeTable()
  423. // .GroupBy(x => new { x.OneHotspot })
  424. // .Select(x => new
  425. // {
  426. // Name = x.OneHotspot,
  427. // Id = "0",
  428. // AcceptName = "有效受理量",
  429. // Num = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  430. // }).ToListAsync();
  431. // listReturn.AddRange(validQuery);
  432. // foreach (var item in acceptType)
  433. // {
  434. // var query = await _orderRepository.Queryable(false, false, false)
  435. // .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  436. // .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  437. // .Select(x => new
  438. // {
  439. // AcceptType = x.AcceptType,
  440. // OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
  441. // Id = x.Id
  442. // }).MergeTable()
  443. // .GroupBy(x => new { x.OneHotspot })
  444. // .Select(x => new
  445. // {
  446. // Name = x.OneHotspot,
  447. // Id = item.Id,
  448. // AcceptName = item.DicDataName,
  449. // Num = SqlFunc.AggregateSum(SqlFunc.IIF(item.DicDataName.Equals(x.AcceptType), 1, 0)),
  450. // }).ToListAsync();
  451. // listReturn.AddRange(query);
  452. // }
  453. // // if (!string.IsNullOrEmpty(dto.SortField))
  454. // // {
  455. // // listReturn = dto.SortRule == 0 ? (from items in listReturn orderby items.Num select items).ToList() : (from items in listReturn orderby items.Num descending select items).ToList();
  456. // //}
  457. // // else {
  458. // // listReturn = (from items in listReturn orderby items.Num descending select items).ToList() ;
  459. // //}
  460. // return new { Header= acceptType,Data = listReturn };
  461. //}
  462. /// <summary>
  463. /// 受理类型前十
  464. /// </summary>
  465. /// <param name="dto"></param>
  466. /// <returns></returns>
  467. [HttpGet("accept_type_top10_list")]
  468. public async Task<PagedDto<AcceptTypeTop10Vo>> AcceptTypeTop10List([FromQuery] ReportPagedRequest dto)
  469. {
  470. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  471. dto.PageIndex = 1;
  472. dto.PageSize = 10;
  473. var query = _orderRepository.Queryable(false, false, false)
  474. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  475. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  476. .Select(x => new
  477. {
  478. AcceptType = x.AcceptType,
  479. OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
  480. Id = x.Id
  481. }).MergeTable()
  482. .GroupBy(x => new { x.OneHotspot })
  483. .Select(x => new AcceptTypeTop10Vo
  484. {
  485. Name = x.OneHotspot,
  486. ValidAccept = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  487. Consult = SqlFunc.AggregateSum(SqlFunc.IIF("咨询".Equals(x.AcceptType), 1, 0)),
  488. Report = SqlFunc.AggregateSum(SqlFunc.IIF("举报".Equals(x.AcceptType), 1, 0)),
  489. Complaint = SqlFunc.AggregateSum(SqlFunc.IIF("投诉".Equals(x.AcceptType), 1, 0)),
  490. SeekHelp = SqlFunc.AggregateSum(SqlFunc.IIF("求助".Equals(x.AcceptType), 1, 0)),
  491. Suggest = SqlFunc.AggregateSum(SqlFunc.IIF("建议".Equals(x.AcceptType), 1, 0)),
  492. Opinion = SqlFunc.AggregateSum(SqlFunc.IIF("意见".Equals(x.AcceptType), 1, 0)),
  493. Rests = SqlFunc.AggregateSum(SqlFunc.IIF("其他".Equals(x.AcceptType), 1, 0)),
  494. BenefitThePeople = SqlFunc.AggregateSum(SqlFunc.IIF("惠民帮助".Equals(x.AcceptType), 1, 0)),
  495. Praise = SqlFunc.AggregateSum(SqlFunc.IIF("表扬".Equals(x.AcceptType), 1, 0)),
  496. }).MergeTable();
  497. switch (dto.SortField)
  498. {
  499. case "validAccept":
  500. query = dto.SortRule == 0 ? query.OrderBy(x => x.ValidAccept) : query.OrderByDescending(x => x.ValidAccept);
  501. break;
  502. case "consult":
  503. query = dto.SortRule == 0 ? query.OrderBy(x => x.Consult) : query.OrderByDescending(x => x.Consult);
  504. break;
  505. case "report":
  506. query = dto.SortRule == 0 ? query.OrderBy(x => x.Report) : query.OrderByDescending(x => x.Report);
  507. break;
  508. case "complaint":
  509. query = dto.SortRule == 0 ? query.OrderBy(x => x.Complaint) : query.OrderByDescending(x => x.Complaint);
  510. break;
  511. case "seekHelp":
  512. query = dto.SortRule == 0 ? query.OrderBy(x => x.SeekHelp) : query.OrderByDescending(x => x.SeekHelp);
  513. break;
  514. case "suggest":
  515. query = dto.SortRule == 0 ? query.OrderBy(x => x.Suggest) : query.OrderByDescending(x => x.Suggest);
  516. break;
  517. case "opinion":
  518. query = dto.SortRule == 0 ? query.OrderBy(x => x.Opinion) : query.OrderByDescending(x => x.Opinion);
  519. break;
  520. case "rests":
  521. query = dto.SortRule == 0 ? query.OrderBy(x => x.Rests) : query.OrderByDescending(x => x.Rests);
  522. break;
  523. case "benefitThePeople":
  524. query = dto.SortRule == 0 ? query.OrderBy(x => x.BenefitThePeople) : query.OrderByDescending(x => x.BenefitThePeople);
  525. break;
  526. case "praise":
  527. query = dto.SortRule == 0 ? query.OrderBy(x => x.Praise) : query.OrderByDescending(x => x.Praise);
  528. break;
  529. default:
  530. query = query.OrderByDescending(x => x.ValidAccept);
  531. break;
  532. }
  533. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  534. return new PagedDto<AcceptTypeTop10Vo>(total, items);
  535. }
  536. /// <summary>
  537. /// 热点类型部门统计
  538. /// </summary>
  539. /// <param name="dto"></param>
  540. /// <returns></returns>
  541. [HttpGet("hotport-org-statistics")]
  542. public async Task<object> HotPortJoinOrgStatistics([FromQuery]HotPortJoinOrgStatisticsRequest dto)
  543. {
  544. return await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime, dto.EndTime);
  545. }
  546. /// <summary>
  547. /// 回访量统计
  548. /// </summary>
  549. /// <returns></returns>
  550. [HttpGet("visit-measure-statistics")]
  551. public async Task<List<VisitMeasureStatisticsDto>> VisitMeasureStatistics(DateTime StartDate,DateTime EndDate,string? VisitName)
  552. {
  553. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  554. var list = await _orderVisitRepository.Queryable()
  555. .Includes(x => x.Employee)
  556. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState == EVisitState.Visited)
  557. .WhereIF(!string.IsNullOrEmpty(VisitName),x=>x.Employee.Name.Contains(VisitName))
  558. .GroupBy(x=> new { x.EmployeeId,x.Employee.Name })
  559. .Select(x=> new VisitMeasureStatisticsDto()
  560. {
  561. VisitName = x.Employee.Name,
  562. AiVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType== EVisitType.ChipVoiceVisit,1,0)),
  563. ArtificialVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.ArtificialVisit,1,0)),
  564. SumCount = SqlFunc.AggregateCount(x.EmployeeId)
  565. })
  566. .ToListAsync();
  567. return list;
  568. }
  569. /// <summary>
  570. /// 热点类型小类统计
  571. /// </summary>
  572. /// <param name="StartDate"></param>
  573. /// <param name="EndDate"></param>
  574. /// <param name="TypeId">0:全部 ,1:市民,2:企业</param>
  575. /// <returns></returns>
  576. [HttpGet("hotspot-statistics")]
  577. public async Task<object> HotspotStatistics(DateTime StartDate,DateTime EndDate,int TypeId,string? HotspotCode)
  578. {
  579. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  580. if (string.IsNullOrEmpty(HotspotCode))
  581. {
  582. var list = await _hotspotTypeRepository.Queryable()
  583. .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
  584. .Where((it, o) => o.StartTime >= StartDate && o.StartTime <= EndDate && o.Id!=null)
  585. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")) })
  586. .Select((it, o) => new
  587. {
  588. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")),
  589. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  590. })
  591. .MergeTable()
  592. .LeftJoin<Hotspot>((x,q)=> x.HotspotCode == q.Id)
  593. .Select((x, q) => new {
  594. HotspotCode = x.HotspotCode,
  595. SumCount = x.SumCount,
  596. HotspotName = q.HotSpotName,
  597. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  598. })
  599. .ToListAsync();
  600. return list;
  601. }
  602. else
  603. {
  604. string count = (HotspotCode.Length + 2).ToString();
  605. string countx = HotspotCode.Length.ToString();
  606. var list = await _hotspotTypeRepository.Queryable()
  607. .LeftJoin<Order>((it, o)=> it.Id == o.HotspotId)
  608. .Where((it, o) => o.StartTime >= StartDate && o.StartTime <= EndDate && it.ParentId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(countx)) == HotspotCode)
  609. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)) })
  610. .Select((it, o) => new
  611. {
  612. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)),
  613. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  614. })
  615. .MergeTable()
  616. .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
  617. .Select((x, q) => new
  618. {
  619. HotspotCode = x.HotspotCode,
  620. SumCount = x.SumCount,
  621. HotspotName = q.HotSpotName,
  622. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  623. })
  624. .ToListAsync();
  625. return list;
  626. }
  627. }
  628. /// <summary>
  629. /// 部门满意度统计
  630. /// </summary>
  631. /// <param name="StartDate"></param>
  632. /// <param name="EndDate"></param>
  633. /// <param name="OrgName"></param>
  634. /// <param name="TypeId">1:办件结果 2:办件态度</param>
  635. /// <param name="LineNum"></param>
  636. /// <returns></returns>
  637. // [HttpGet("visit-org-satisfaction-statistics")]
  638. //public async Task VisitAndOrgSatisfactionStatistics(DateTime StartDate,DateTime EndDate,string OrgName,int TypeId,string? LineNum )
  639. //{
  640. // EndDate = EndDate.AddDays(1).AddSeconds(-1);
  641. // var list = await _orderVisitDetailRepository.Queryable()
  642. // .Includes(x => x.OrderVisit)
  643. // .Where(x => x.OrderVisit.VisitTime >= StartDate && x.OrderVisit.VisitTime <= EndDate && x.VisitTarget == EVisitTarget.Org)
  644. // .WhereIF(!string.IsNullOrEmpty(OrgName),x=>x.VisitOrgName.Contains(OrgName))
  645. // .GroupBy(x=> new { x.VisitOrgCode ,x.VisitOrgName })
  646. // .Select(x => new
  647. // {
  648. // OrgName = x.VisitOrgName,
  649. // OrgCode= x.VisitOrgCode,
  650. // })
  651. // .ToListAsync();
  652. // }
  653. }
  654. }