BiOrderController.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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. using Hotline.CallCenter.Calls;
  19. using Hotline.Share.Enums.CallCenter;
  20. namespace Hotline.Api.Controllers.Bi
  21. {
  22. public class BiOrderController : BaseController
  23. {
  24. private readonly IOrderRepository _orderRepository;
  25. private readonly IRepository<Hotspot> _hotspotTypeRepository;
  26. private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
  27. private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
  28. private readonly IRepository<OrderDelay> _orderDelayRepository;
  29. private readonly IMapper _mapper;
  30. private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
  31. private readonly IRepository<OrderSpecial> _orderSpecialRepository;
  32. private readonly IRepository<OrderVisit> _orderVisitRepository;
  33. private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  34. public BiOrderController(
  35. IOrderRepository orderRepository,
  36. IRepository<Hotspot> hotspotTypeRepository,
  37. ISystemDicDataCacheManager sysDicDataCacheManager,
  38. IRepository<OrderVisitDetail> orderVisitDetailRepository,
  39. IRepository<OrderDelay> orderDelayRepository,
  40. IRepository<WorkflowCountersign> workflowCountersignRepository,
  41. IRepository<OrderSpecial> orderSpecialRepository,
  42. IMapper mapper,
  43. IRepository<OrderVisit> orderVisitRepository,
  44. IRepository<TrCallRecord> trCallRecordRepository
  45. )
  46. {
  47. _orderRepository = orderRepository;
  48. _hotspotTypeRepository = hotspotTypeRepository;
  49. _sysDicDataCacheManager = sysDicDataCacheManager;
  50. _orderVisitDetailRepository = orderVisitDetailRepository;
  51. _orderDelayRepository = orderDelayRepository;
  52. _workflowCountersignRepository = workflowCountersignRepository;
  53. _orderSpecialRepository = orderSpecialRepository;
  54. _mapper = mapper;
  55. _orderVisitRepository = orderVisitRepository;
  56. _trCallRecordRepository = trCallRecordRepository;
  57. }
  58. /// <summary>
  59. /// 部门数据统计
  60. /// </summary>
  61. /// <param name="dto"></param>
  62. /// <returns></returns>
  63. [HttpGet("org_data_list")]
  64. public async Task<PagedDto<OrderBiOrgDataListVo>> OrgDataList([FromQuery] ReportPagedRequest dto)
  65. {
  66. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  67. var queryOrder = _orderRepository.Queryable(false, false, false)
  68. .LeftJoin<SystemOrganize>((x, o) => x.ActualHandleOrgCode == o.Id)
  69. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  70. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  71. .GroupBy((x, o) => new { x.ActualHandleOrgCode, o.Name })
  72. .Select((x, o) => new OrderBiOrgDataListVo
  73. {
  74. OrgName = o.Name,
  75. OrgId = x.ActualHandleOrgCode,
  76. HandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ExpiredTime < x.FiledTime, 1, 0)),
  77. NoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime < SqlFunc.GetDate(), 1, 0)),
  78. }).MergeTable();
  79. var queryCountersign = _workflowCountersignRepository.Queryable()
  80. .LeftJoin<WorkflowCountersignMember>((x, o) => x.Id == o.WorkflowCountersignId)
  81. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  82. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  83. .GroupBy((x, o) => o.Key)
  84. .Select((x, o) => new OrderBiOrgDataListVo
  85. {
  86. OrgId = o.Key,
  87. CounterHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.IsHandled, 1, 0)),
  88. CounterNoHandlerExtendedNum = SqlFunc.AggregateSum(SqlFunc.IIF(!o.IsHandled, 1, 0)),
  89. }).MergeTable();
  90. var query = queryOrder.LeftJoin(queryCountersign, (or, co) => or.OrgId == co.OrgId)
  91. .Select((or, co) => new OrderBiOrgDataListVo
  92. {
  93. OrgName = or.OrgName,
  94. OrgId = or.OrgId,
  95. HandlerExtendedNum = or.HandlerExtendedNum,
  96. NoHandlerExtendedNum = or.NoHandlerExtendedNum,
  97. CounterHandlerExtendedNum = co.CounterHandlerExtendedNum,
  98. CounterNoHandlerExtendedNum = co.CounterNoHandlerExtendedNum
  99. }).MergeTable();
  100. query = query.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrgName.Contains(dto.Keyword!));
  101. switch (dto.SortField)
  102. {
  103. case "handlerExtendedNum":
  104. query = dto.SortRule == 0 ? query.OrderBy(x => x.HandlerExtendedNum) : query.OrderByDescending(x => x.HandlerExtendedNum);
  105. break;
  106. case "counterHandlerExtendedNum":
  107. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterHandlerExtendedNum) : query.OrderByDescending(x => x.CounterHandlerExtendedNum);
  108. break;
  109. case "noHandlerExtendedNum":
  110. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoHandlerExtendedNum) : query.OrderByDescending(x => x.NoHandlerExtendedNum);
  111. break;
  112. case "counterNoHandlerExtendedNum":
  113. query = dto.SortRule == 0 ? query.OrderBy(x => x.CounterNoHandlerExtendedNum) : query.OrderByDescending(x => x.CounterNoHandlerExtendedNum);
  114. break;
  115. }
  116. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  117. return new PagedDto<OrderBiOrgDataListVo>(total, items);
  118. }
  119. /// <summary>
  120. /// 中心统计
  121. /// </summary>
  122. /// <param name="dto"></param>
  123. /// <returns></returns>
  124. [HttpGet("centre_data_list")]
  125. public async Task<PagedDto<OrderBiCentreDataListVo>> CentreDataList([FromQuery] ReportPagedRequest dto)
  126. {
  127. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  128. var query = _orderRepository.Queryable(false, false, false)
  129. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  130. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  131. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.AcceptorName.Contains(dto.Keyword!))
  132. .GroupBy(x => new { x.AcceptorId, x.AcceptorName })
  133. .Select(x => new OrderBiCentreDataListVo
  134. {
  135. UserName = x.AcceptorName,
  136. UserId = x.AcceptorId,
  137. CentreArchive = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Zhiban, 1, 0)),
  138. CentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300 && x.ProcessType == EProcessType.Jiaoban, 1, 0)),
  139. //NoCentreCareOf = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300 && x.ExpiredTime > x.FiledTime, 1, 0)),
  140. Invalid = SqlFunc.AggregateSum(SqlFunc.IIF(x.AcceptType == "无效", 1, 0)),
  141. Repeat = SqlFunc.AggregateSum(SqlFunc.IIF(x.DuplicateIds != null && SqlFunc.JsonArrayLength(x.DuplicateIds) > 0, 1, 0))
  142. }).MergeTable();
  143. switch (dto.SortField)
  144. {
  145. case "centreArchive":
  146. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreArchive) : query.OrderByDescending(x => x.CentreArchive);
  147. break;
  148. case "centreCareOf":
  149. query = dto.SortRule == 0 ? query.OrderBy(x => x.CentreCareOf) : query.OrderByDescending(x => x.CentreCareOf);
  150. break;
  151. case "noCentreCareOf":
  152. query = dto.SortRule == 0 ? query.OrderBy(x => x.NoCentreCareOf) : query.OrderByDescending(x => x.NoCentreCareOf);
  153. break;
  154. case "invalid":
  155. query = dto.SortRule == 0 ? query.OrderBy(x => x.Invalid) : query.OrderByDescending(x => x.Invalid);
  156. break;
  157. case "repeat":
  158. query = dto.SortRule == 0 ? query.OrderBy(x => x.Repeat) : query.OrderByDescending(x => x.Repeat);
  159. break;
  160. }
  161. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  162. return new PagedDto<OrderBiCentreDataListVo>(total, items);
  163. }
  164. /// <summary>
  165. /// 热点数据小计统计
  166. /// </summary>
  167. /// <param name="dto"></param>
  168. /// <returns></returns>
  169. [HttpGet("hotspot_subtotal_data_list")]
  170. public async Task<PagedDto<HotspotDataLsitVo>> HotspotSubtotalDataLsit([FromQuery] HotspotSubtotalReportPagedRequest dto)
  171. {
  172. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  173. var query = _hotspotTypeRepository.Queryable(false, true)
  174. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotFullName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotFullName)) && o.IsDeleted == false)
  175. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
  176. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
  177. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  178. .Where((x, o) => x.ParentId == dto.Id)
  179. .Where((x, o) => x.IsDeleted == false)
  180. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  181. .Select((x, o) => new HotspotDataLsitVo
  182. {
  183. Id = x.Id,
  184. Name = x.HotSpotName,
  185. Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  186. }).MergeTable();
  187. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  188. return new PagedDto<HotspotDataLsitVo>(total, items);
  189. }
  190. /// <summary>
  191. /// 热点数据统计
  192. /// </summary>
  193. /// <param name="dto"></param>
  194. /// <returns></returns>
  195. [HttpGet("hotspot_data_list")]
  196. public async Task<object> HotspotDataLsit([FromQuery] HotspotReportPagedRequest dto)
  197. {
  198. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  199. if (dto.Type == 0 && (!dto.ChainStartTime.HasValue || !dto.ChainEndTime.HasValue)) throw UserFriendlyException.SameMessage("请选择环比时间!");
  200. var items = await _hotspotTypeRepository.Queryable(false, true)
  201. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && o.IsDeleted == false)
  202. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= dto.StartTime)
  203. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= dto.EndTime)
  204. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  205. .Where((x, o) => x.ParentId == dto.Id)
  206. .Where((x, o) => x.IsDeleted == false)
  207. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  208. .Select((x, o) => new HotspotDataLsitVo
  209. {
  210. Id = x.Id,
  211. Name = x.HotSpotName,
  212. Num = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  213. Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.HotSpotName != o.HotspotName, 1, 0)) > 0,
  214. }).MergeTable().ToListAsync();
  215. var chainStartTime = dto.StartTime;
  216. var chainEndTime = dto.EndTime;
  217. switch (dto.Type)
  218. {
  219. case 1://日
  220. chainStartTime = dto.StartTime.Value.AddDays(-1);
  221. chainEndTime = dto.EndTime.Value.AddDays(-1);
  222. break;
  223. case 2://月
  224. chainStartTime = dto.StartTime.Value.AddMonths(-1);
  225. chainEndTime = dto.EndTime.Value.AddMonths(-1);
  226. break;
  227. case 3://年
  228. chainStartTime = dto.StartTime.Value.AddYears(-1);
  229. chainEndTime = dto.EndTime.Value.AddYears(-1);
  230. break;
  231. case 0:
  232. chainStartTime = dto.ChainStartTime.Value;
  233. chainEndTime = dto.ChainEndTime.Value;
  234. break;
  235. }
  236. var chainItems = await _hotspotTypeRepository.Queryable(false, true)
  237. .LeftJoin<Order>((x, o) => o.HotspotSpliceName != null && (x.HotSpotName == o.HotspotSpliceName || o.HotspotSpliceName.Contains(x.HotSpotName)) && o.IsDeleted == false)
  238. .WhereIF(dto.StartTime.HasValue, (x, o) => o.CreationTime >= chainStartTime)
  239. .WhereIF(dto.EndTime.HasValue, (x, o) => o.CreationTime <= chainEndTime)
  240. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => x.HotSpotName.Contains(dto.Keyword!))
  241. .Where((x, o) => x.ParentId == dto.Id)
  242. .Where((x, o) => x.IsDeleted == false)
  243. .GroupBy((x, o) => new { x.Id, x.HotSpotName })
  244. .Select((x, o) => new
  245. {
  246. Id = x.Id,
  247. ChainNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.Id != null, 1, 0)),
  248. }).MergeTable().ToListAsync();
  249. var res = (from t1 in items
  250. join t2 in chainItems on t1.Id equals t2.Id into t1_t2
  251. from item in t1_t2.DefaultIfEmpty()
  252. select new
  253. {
  254. Id = t1.Id,
  255. Name = t1.Name,
  256. Num = t1.Num,
  257. Sublevel = t1.Sublevel,
  258. Children = new List<HotspotDataLsitVo>(),
  259. ChainNum = t1_t2.Select(x => x.ChainNum).FirstOrDefault(),
  260. ChainRate = t1_t2.Select(x => x.ChainNum).FirstOrDefault() > 0 ?
  261. ((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%",
  262. }).ToList();
  263. var total = new
  264. {
  265. Id = "0",
  266. Name = "合计",
  267. Num = res.Sum(x => x.Num),
  268. Sublevel = false,
  269. Children = new List<HotspotDataLsitVo>(),
  270. ChainNum = res.Sum(x => x.ChainNum),
  271. 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%"
  272. };
  273. return new { List = res, Total = total };
  274. }
  275. /// <summary>
  276. /// 部门不满意统计
  277. /// </summary>
  278. /// <param name="dto"></param>
  279. /// <returns></returns>
  280. [HttpGet("visit-nosatisfied")]
  281. public async Task<object> QueryVisitNoSatisfied([FromQuery] QueryVisitNoSatiisfiedRequest dto)
  282. {
  283. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  284. var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);
  285. List<dynamic>? list = new List<dynamic>();
  286. //DataTable dt = new DataTable();
  287. foreach (var item in dissatisfiedReason)
  288. {
  289. var table = _orderVisitDetailRepository.Queryable()
  290. .Includes(x => x.OrderVisit)
  291. .Where(x => x.VisitTarget == Share.Enums.Order.EVisitTarget.Org)
  292. .Where(x => x.OrgNoSatisfiedReason != null)
  293. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  294. .Where(x => !string.IsNullOrEmpty(x.VisitOrgName))
  295. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.VisitOrgName.Contains(dto.OrgName))
  296. .WhereIF(dto.StartTime.HasValue, x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  297. .WhereIF(dto.EndTime.HasValue, x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  298. .GroupBy(x => new { x.VisitOrgName, x.VisitOrgCode })
  299. .Select(x => new BiVisitNoSatisfiedDto
  300. {
  301. Count = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", item.DicDataValue), 1, 0)),
  302. Key = item.DicDataValue,
  303. OrgName = x.VisitOrgName,
  304. OrgCode = x.VisitOrgCode
  305. })
  306. .OrderByDescending(x => x.Count)
  307. //.ToPivotTable(x => x.Key, x => x.OrgName, x => x.Sum(x => x.Count));
  308. .ToPivotList(x => x.Key, x => new { x.OrgCode, x.OrgName }, x => x.Sum(x => x.Count));
  309. list.AddRange(table);
  310. }
  311. return new { DicReason = dissatisfiedReason, Data = list };
  312. }
  313. /// <summary>
  314. /// 部门不满意统计明细
  315. /// </summary>
  316. /// <param name="dto"></param>
  317. /// <returns></returns>
  318. [HttpGet("visit-nosatisfied-detail")]
  319. public async Task<PagedDto<OrderVisitDetailDto>> BiQueryVisitNoSatisfiedDetail([FromQuery] BiQueryVisitNoSatisfiedDetailDto dto)
  320. {
  321. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  322. var (total, items) = await _orderVisitDetailRepository.Queryable()
  323. .Includes(x => x.OrderVisit, d => d.Order)
  324. .Includes(x => x.OrderVisit, d => d.Employee)
  325. .Where(x => x.VisitOrgCode == dto.OrgCode)
  326. .Where(x => x.OrderVisit.VisitState == EVisitState.Visited)
  327. .Where(x => x.OrderVisit.VisitTime >= dto.StartTime.Value)
  328. .Where(x => x.OrderVisit.VisitTime <= dto.EndTime.Value)
  329. .Where(x => SqlFunc.JsonListObjectAny(x.OrgNoSatisfiedReason, "Key", dto.DissatisfiedKey))
  330. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderVisit.Order.No.Contains(dto.Keyword) || x.OrderVisit.Order.Title.Contains(dto.Keyword))
  331. .OrderBy(x => x.OrderVisit.VisitTime)
  332. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  333. return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
  334. }
  335. /// <summary>
  336. /// 部门延期统计
  337. /// </summary>
  338. /// <param name="dto"></param>
  339. /// <returns></returns>
  340. [HttpGet("order-delay-data-list")]
  341. public async Task<IReadOnlyList<BiOrderDelayDataDto>> QueryOrderDelayDataList([FromQuery] QueryOrderDelayDataListRequest dto)
  342. {
  343. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  344. var list = await _orderDelayRepository.Queryable()
  345. .LeftJoin<SystemOrganize>((x, o) => x.ApplyOrgCode == o.Id)
  346. .WhereIF(dto.StartTime.HasValue, (x, o) => x.CreationTime >= dto.StartTime)
  347. .WhereIF(dto.EndTime.HasValue, (x, o) => x.CreationTime <= dto.EndTime)
  348. .WhereIF(!string.IsNullOrEmpty(dto.OrgName), x => x.ApplyOrgName.Contains(dto.OrgName))
  349. .GroupBy(x => new { x.ApplyOrgCode, x.ApplyOrgName })
  350. .Select(x => new BiOrderDelayDataDto
  351. {
  352. OrgName = x.ApplyOrgName,
  353. OrgCode = x.ApplyOrgCode,
  354. PassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)),
  355. NoPassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)),
  356. ExaminingTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0)),
  357. 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))
  358. }).ToListAsync();
  359. return list;
  360. }
  361. /// <summary>
  362. /// 特提统计
  363. /// </summary>
  364. /// <param name="dto"></param>
  365. /// <returns></returns>
  366. [HttpGet("special_data_list")]
  367. public async Task<PagedDto<OrderBiSpecialListVo>> SpecialDataList([FromQuery] ReportPagedRequest dto)
  368. {
  369. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  370. var query = _orderSpecialRepository.Queryable()
  371. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  372. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  373. .GroupBy(x => new { x.Cause })
  374. .Select(x => new OrderBiSpecialListVo
  375. {
  376. Cause = x.Cause,
  377. OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  378. MaxSpecialTime = SqlFunc.AggregateMax(x.CreationTime),
  379. })
  380. .MergeTable();
  381. switch (dto.SortField)
  382. {
  383. case "cause":
  384. query = dto.SortRule == 0 ? query.OrderBy(x => x.Cause) : query.OrderByDescending(x => x.Cause);
  385. break;
  386. case "orderNum":
  387. query = dto.SortRule == 0 ? query.OrderBy(x => x.OrderNum) : query.OrderByDescending(x => x.OrderNum);
  388. break;
  389. case "maxSpecialTime":
  390. query = dto.SortRule == 0 ? query.OrderBy(x => x.MaxSpecialTime) : query.OrderByDescending(x => x.MaxSpecialTime);
  391. break;
  392. }
  393. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  394. return new PagedDto<OrderBiSpecialListVo>(total, items);
  395. }
  396. /// <summary>
  397. /// 获取工单特提信息列表
  398. /// </summary>
  399. /// <param name="dto"></param>
  400. /// <returns></returns>
  401. [HttpGet("special_data_list/list")]
  402. public async Task<PagedDto<OrderSpecialDto>> List([FromQuery] OrderSpecialListDto dto)
  403. {
  404. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  405. var (total, items) = await _orderSpecialRepository.Queryable()
  406. .Includes(x => x.Order)
  407. .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
  408. x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
  409. .WhereIF(!string.IsNullOrEmpty(dto.Cause),
  410. x => x.Cause != null && x.Cause.Equals(dto.Cause))
  411. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  412. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  413. .WhereIF(dto.State.HasValue, x => x.State == dto.State)
  414. .OrderByDescending(x => x.CreationTime)
  415. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  416. return new PagedDto<OrderSpecialDto>(total, _mapper.Map<IReadOnlyList<OrderSpecialDto>>(items));
  417. }
  418. /// <summary>
  419. /// 受理类型前十
  420. /// </summary>
  421. /// <param name="dto"></param>
  422. /// <returns></returns>
  423. [HttpGet("accept_type_top10_list")]
  424. public async Task<PagedDto<AcceptTypeTop10Vo>> AcceptTypeTop10List([FromQuery] ReportPagedRequest dto)
  425. {
  426. if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
  427. dto.PageIndex = 1;
  428. dto.PageSize = 10;
  429. var query = _orderRepository.Queryable(false, false, false)
  430. .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
  431. .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
  432. .Select(x => new
  433. {
  434. AcceptType = x.AcceptType,
  435. OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
  436. Id = x.Id
  437. }).MergeTable()
  438. .GroupBy(x => new { x.OneHotspot })
  439. .Select(x => new AcceptTypeTop10Vo
  440. {
  441. Name = x.OneHotspot,
  442. ValidAccept = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  443. Consult = SqlFunc.AggregateSum(SqlFunc.IIF("咨询".Equals(x.AcceptType), 1, 0)),
  444. Report = SqlFunc.AggregateSum(SqlFunc.IIF("举报".Equals(x.AcceptType), 1, 0)),
  445. Complaint = SqlFunc.AggregateSum(SqlFunc.IIF("投诉".Equals(x.AcceptType), 1, 0)),
  446. SeekHelp = SqlFunc.AggregateSum(SqlFunc.IIF("求助".Equals(x.AcceptType), 1, 0)),
  447. Suggest = SqlFunc.AggregateSum(SqlFunc.IIF("建议".Equals(x.AcceptType), 1, 0)),
  448. Opinion = SqlFunc.AggregateSum(SqlFunc.IIF("意见".Equals(x.AcceptType), 1, 0)),
  449. Rests = SqlFunc.AggregateSum(SqlFunc.IIF("其他".Equals(x.AcceptType), 1, 0)),
  450. BenefitThePeople = SqlFunc.AggregateSum(SqlFunc.IIF("惠民帮助".Equals(x.AcceptType), 1, 0)),
  451. Praise = SqlFunc.AggregateSum(SqlFunc.IIF("表扬".Equals(x.AcceptType), 1, 0)),
  452. }).MergeTable();
  453. switch (dto.SortField)
  454. {
  455. case "validAccept":
  456. query = dto.SortRule == 0 ? query.OrderBy(x => x.ValidAccept) : query.OrderByDescending(x => x.ValidAccept);
  457. break;
  458. case "consult":
  459. query = dto.SortRule == 0 ? query.OrderBy(x => x.Consult) : query.OrderByDescending(x => x.Consult);
  460. break;
  461. case "report":
  462. query = dto.SortRule == 0 ? query.OrderBy(x => x.Report) : query.OrderByDescending(x => x.Report);
  463. break;
  464. case "complaint":
  465. query = dto.SortRule == 0 ? query.OrderBy(x => x.Complaint) : query.OrderByDescending(x => x.Complaint);
  466. break;
  467. case "seekHelp":
  468. query = dto.SortRule == 0 ? query.OrderBy(x => x.SeekHelp) : query.OrderByDescending(x => x.SeekHelp);
  469. break;
  470. case "suggest":
  471. query = dto.SortRule == 0 ? query.OrderBy(x => x.Suggest) : query.OrderByDescending(x => x.Suggest);
  472. break;
  473. case "opinion":
  474. query = dto.SortRule == 0 ? query.OrderBy(x => x.Opinion) : query.OrderByDescending(x => x.Opinion);
  475. break;
  476. case "rests":
  477. query = dto.SortRule == 0 ? query.OrderBy(x => x.Rests) : query.OrderByDescending(x => x.Rests);
  478. break;
  479. case "benefitThePeople":
  480. query = dto.SortRule == 0 ? query.OrderBy(x => x.BenefitThePeople) : query.OrderByDescending(x => x.BenefitThePeople);
  481. break;
  482. case "praise":
  483. query = dto.SortRule == 0 ? query.OrderBy(x => x.Praise) : query.OrderByDescending(x => x.Praise);
  484. break;
  485. default:
  486. query = query.OrderByDescending(x => x.ValidAccept);
  487. break;
  488. }
  489. var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
  490. return new PagedDto<AcceptTypeTop10Vo>(total, items);
  491. }
  492. /// <summary>
  493. /// 热点类型部门统计
  494. /// </summary>
  495. /// <param name="dto"></param>
  496. /// <returns></returns>
  497. [HttpGet("hotport-org-statistics")]
  498. public async Task<object> HotPortJoinOrgStatistics([FromQuery] HotPortJoinOrgStatisticsRequest dto)
  499. {
  500. return await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime, dto.EndTime);
  501. }
  502. /// <summary>
  503. /// 回访量统计
  504. /// </summary>
  505. /// <returns></returns>
  506. [HttpGet("visit-measure-statistics")]
  507. public async Task<List<VisitMeasureStatisticsDto>> VisitMeasureStatistics(DateTime StartDate, DateTime EndDate, string? VisitName)
  508. {
  509. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  510. var list = await _orderVisitRepository.Queryable()
  511. .Includes(x => x.Employee)
  512. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState == EVisitState.Visited)
  513. .WhereIF(!string.IsNullOrEmpty(VisitName), x => x.Employee.Name.Contains(VisitName))
  514. .GroupBy(x => new { x.EmployeeId, x.Employee.Name })
  515. .Select(x => new VisitMeasureStatisticsDto()
  516. {
  517. VisitName = x.Employee.Name,
  518. AiVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.ChipVoiceVisit, 1, 0)),
  519. ArtificialVisitCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitType == EVisitType.ArtificialVisit, 1, 0)),
  520. SumCount = SqlFunc.AggregateCount(x.EmployeeId)
  521. })
  522. .ToListAsync();
  523. return list;
  524. }
  525. /// <summary>
  526. /// 热点类型小类统计
  527. /// </summary>
  528. /// <param name="StartDate"></param>
  529. /// <param name="EndDate"></param>
  530. /// <param name="TypeId">0:全部 ,1:市民,2:企业</param>
  531. /// <returns></returns>
  532. [HttpGet("hotspot-statistics")]
  533. public async Task<object> HotspotStatistics(DateTime StartDate, DateTime EndDate, int TypeId, string? HotspotCode)
  534. {
  535. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  536. if (string.IsNullOrEmpty(HotspotCode))
  537. {
  538. var list = await _hotspotTypeRepository.Queryable()
  539. .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
  540. .Where((it, o) => o.StartTime >= StartDate && o.StartTime <= EndDate && o.Id != null)
  541. .WhereIF(TypeId == 1, (it, o) => o.IdentityType == EIdentityType.Citizen)
  542. .WhereIF(TypeId == 2, (it, o) => o.IdentityType == EIdentityType.Enterprise)
  543. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")) })
  544. .Select((it, o) => new
  545. {
  546. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")),
  547. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  548. })
  549. .MergeTable()
  550. .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
  551. .Select((x, q) => new
  552. {
  553. HotspotCode = x.HotspotCode,
  554. SumCount = x.SumCount,
  555. HotspotName = q.HotSpotName,
  556. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  557. })
  558. .ToListAsync();
  559. return list;
  560. }
  561. else
  562. {
  563. string count = (HotspotCode.Length + 2).ToString();
  564. string countx = HotspotCode.Length.ToString();
  565. var list = await _hotspotTypeRepository.Queryable()
  566. .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
  567. .Where((it, o) => o.StartTime >= StartDate && o.StartTime <= EndDate && it.ParentId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(countx)) == HotspotCode)
  568. .WhereIF(TypeId == 1, (it, o) => o.IdentityType == EIdentityType.Citizen)
  569. .WhereIF(TypeId == 2, (it, o) => o.IdentityType == EIdentityType.Enterprise)
  570. .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)) })
  571. .Select((it, o) => new
  572. {
  573. HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>(count)),
  574. SumCount = SqlFunc.AggregateCount(it.HotSpotName)
  575. })
  576. .MergeTable()
  577. .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
  578. .Select((x, q) => new
  579. {
  580. HotspotCode = x.HotspotCode,
  581. SumCount = x.SumCount,
  582. HotspotName = q.HotSpotName,
  583. HasChild = SqlFunc.Subqueryable<Hotspot>().Where(d => d.ParentId == x.HotspotCode).Any()
  584. })
  585. .ToListAsync();
  586. return list;
  587. }
  588. }
  589. /// <summary>
  590. /// 部门满意度统计
  591. /// </summary>
  592. /// <param name="StartDate"></param>
  593. /// <param name="EndDate"></param>
  594. /// <param name="OrgName"></param>
  595. /// <param name="TypeId">1:办件结果 2:办件态度</param>
  596. /// <param name="LineNum"></param>
  597. /// <returns></returns>
  598. [HttpGet("visit-org-satisfaction-statistics")]
  599. public async Task<List<VisitAndOrgSatisfactionStatisticsDto>> VisitAndOrgSatisfactionStatistics(DateTime StartDate, DateTime EndDate, string OrgName, int TypeId, string? LineNum)
  600. {
  601. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  602. var list = await _orderVisitDetailRepository.Queryable()
  603. .Includes(x => x.OrderVisit)
  604. .Where(x => x.OrderVisit.VisitTime >= StartDate && x.OrderVisit.VisitTime <= EndDate && x.VisitTarget == EVisitTarget.Org && x.OrderVisit.VisitState == EVisitState.Visited)
  605. .WhereIF(!string.IsNullOrEmpty(OrgName), x => x.VisitOrgName.Contains(OrgName))
  606. .GroupBy(x => new { x.VisitOrgCode, x.VisitOrgName })
  607. .Select(x => new VisitAndOrgSatisfactionStatisticsDto()
  608. {
  609. OrgName = x.VisitOrgName,
  610. OrgCode = x.VisitOrgCode,
  611. TotalSumCount = SqlFunc.AggregateCount(x.VisitOrgCode),
  612. VerySatisfiedCount = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(x.OrgProcessingResults, "key", "5"), 1, 0)),//非常满意数
  613. })
  614. .ToListAsync();
  615. return list;
  616. }
  617. /// <summary>
  618. /// 中心报表统计
  619. /// </summary>
  620. /// <param name="StartDate"></param>
  621. /// <param name="EndDate"></param>
  622. /// <returns></returns>
  623. [HttpGet("Center_report_forms_statistics")]
  624. public async Task<CenterReportStatisticsDto> CenterReportFormsStatistics(DateTime StartDate, DateTime EndDate)
  625. {
  626. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  627. CenterReportStatisticsDto centerReportStatisticsDto = new();
  628. //信件总量
  629. int sourceChannelCount = await _orderRepository.Queryable(false, false, false).Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate).CountAsync();
  630. #region 通话记录
  631. //通话记录
  632. var callData = await _trCallRecordRepository.Queryable()
  633. .Where(p => p.CreatedTime >= StartDate && p.CreatedTime <= EndDate)
  634. .Select(o => new CenterReportCallDto
  635. {
  636. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.On, 1, 0)),//有效
  637. InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn && o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue, 1, 0)), //无效(排除队列挂断和IVR挂断)
  638. QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.QueueTims > 0 && o.RingTimes == 0, 1, 0)), //队列挂断
  639. 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挂断
  640. })
  641. .ToListAsync();
  642. if (callData != null && callData.Count > 0)
  643. centerReportStatisticsDto.CenterReportCall = callData[0];
  644. #endregion
  645. #region 工单
  646. //工单
  647. var orderData = await _orderRepository.Queryable(false, false, false)
  648. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  649. .Select(x => new CenterReportOrderDto
  650. {
  651. EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(true, 1, 0)),
  652. InvalidCount = 0,
  653. CompletedCount = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status >= 300, 1, 0)),
  654. InProgressCount = SqlFunc.AggregateSum(SqlFunc.IIF((int)x.Status < 300, 1, 0))
  655. })
  656. .ToListAsync();
  657. if (orderData != null && orderData.Count > 0)
  658. centerReportStatisticsDto.CenterReportOrder = orderData[0];
  659. #endregion
  660. #region 信件来源
  661. //信件来源
  662. var sourceChannelData = await _orderRepository.Queryable(false, false, false)
  663. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  664. .Select(it => new
  665. {
  666. SourceChannelCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.SourceChannelCode), "QT", it.SourceChannelCode)
  667. })
  668. .MergeTable()//将查询出来的结果合并成一个新表
  669. .GroupBy(it => new { it.SourceChannelCode })//对新表进行分组
  670. .Select(it => new CenterReportOrderSourceChannelDto
  671. {
  672. Code = it.SourceChannelCode,
  673. CountNum = SqlFunc.AggregateCount(it.SourceChannelCode)
  674. })
  675. .ToListAsync();
  676. List<CenterReportOrderSourceChannelDto> sourceChannel = new()
  677. {
  678. new CenterReportOrderSourceChannelDto
  679. {
  680. Name = "来源总量",
  681. Code = "All",
  682. CountNum = sourceChannelCount
  683. }
  684. };
  685. var sourceChannelDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SourceChannel);
  686. foreach (var item in sourceChannelDic)
  687. {
  688. sourceChannel.Add(new CenterReportOrderSourceChannelDto
  689. {
  690. Name = item.DicDataName,
  691. Code = item.DicTypeCode,
  692. CountNum = sourceChannelData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
  693. });
  694. }
  695. centerReportStatisticsDto.CenterReportOrderSourceChannels = sourceChannel;
  696. #endregion
  697. #region 信件分类
  698. //信件来源
  699. var acceptTypeData = await _orderRepository.Queryable(false, false, false)
  700. .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate)
  701. .Select(it => new
  702. {
  703. AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode)
  704. })
  705. .MergeTable()//将查询出来的结果合并成一个新表
  706. .GroupBy(it => new { it.AcceptTypeCode })//对新表进行分组
  707. .Select(it => new CenterReportOrderSourceChannelDto
  708. {
  709. Code = it.AcceptTypeCode,
  710. CountNum = SqlFunc.AggregateCount(it.AcceptTypeCode)
  711. })
  712. .ToListAsync();
  713. List<CenterReportOrderSourceChannelDto> acceptType = new();
  714. var acceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
  715. foreach (var item in acceptTypeDic)
  716. {
  717. acceptType.Add(new CenterReportOrderSourceChannelDto
  718. {
  719. AllCountNum = sourceChannelCount,
  720. Name = item.DicDataName,
  721. Code = item.DicTypeCode,
  722. CountNum = acceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
  723. });
  724. }
  725. centerReportStatisticsDto.CenterReportOrderAcceptTypes = acceptType;
  726. #endregion
  727. #region 信件回访量
  728. //信件回访量
  729. CenterReportVisitdDto centerReportVisitd = new()
  730. {
  731. Visitd = await _orderVisitRepository.Queryable()
  732. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState == EVisitState.Visited).CountAsync(),
  733. WaitVisitd = await _orderVisitRepository.Queryable()
  734. .Where(x => x.VisitTime >= StartDate && x.VisitTime <= EndDate && x.VisitState != EVisitState.None && x.VisitState != EVisitState.Visited).CountAsync()
  735. };
  736. //部门
  737. var listOrg = await _orderVisitDetailRepository.Queryable()
  738. .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
  739. .Where((it, o) => it.VisitTarget == EVisitTarget.Org && o.VisitTime >= StartDate && o.VisitTime <= EndDate && o.VisitState == EVisitState.Visited)
  740. .Select((it, o) => new Satisfaction
  741. {
  742. Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
  743. Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 0, 1)),
  744. })
  745. .ToListAsync();
  746. if (centerReportVisitd.Visitd > 0 && listOrg != null && listOrg.Count > 0 && listOrg[0].Satisfied > 0)
  747. centerReportVisitd.OrgRate = Math.Round((listOrg[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
  748. //坐席
  749. var listSet = await _orderVisitDetailRepository.Queryable()
  750. .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
  751. .Where((it, o) => it.VisitTarget == EVisitTarget.Seat && o.VisitTime >= StartDate && o.VisitTime <= EndDate && o.VisitState == EVisitState.Visited)
  752. .Select((it, o) => new Satisfaction
  753. {
  754. Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied || it.SeatEvaluate == ESeatEvaluate.NoSatisfied, 1, 0)),
  755. Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(it.SeatEvaluate != ESeatEvaluate.VeryNoSatisfied && it.SeatEvaluate != ESeatEvaluate.NoSatisfied, 1, 0)),
  756. }).ToListAsync();
  757. if (centerReportVisitd.Visitd > 0 && listSet != null && listSet.Count > 0 && listSet[0].Satisfied > 0)
  758. centerReportVisitd.SeatsRate = Math.Round((listSet[0].Satisfied / (double)centerReportVisitd.Visitd) * 100, 2);
  759. centerReportStatisticsDto.CenterReportVisitd = centerReportVisitd;
  760. #endregion
  761. #region 信件分布情况
  762. //市直部门
  763. var listOrgStatisticsCityAll = await _orderRepository.Queryable()
  764. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  765. .Where((it, o) => (o.OrgType == EOrgType.City || o.OrgType == EOrgType.Province) && it.CreationTime >= StartDate && it.CreationTime <= EndDate)
  766. .GroupBy((it, o) => new
  767. {
  768. it.OrgLevelOneCode,
  769. o.Name
  770. })
  771. .Select((it, o) => new OrgStatistics
  772. {
  773. CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
  774. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
  775. }).ToListAsync();
  776. centerReportStatisticsDto.OrgStatisticsCityAll = new OrgStatisticsAll
  777. {
  778. OrgStatistics = listOrgStatisticsCityAll
  779. };
  780. //区县部门
  781. var listOrgStatisticsAreaAll = await _orderRepository.Queryable()
  782. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  783. .Where((it, o) => o.OrgType == EOrgType.County && it.CreationTime >= StartDate && it.CreationTime <= EndDate)
  784. .GroupBy((it, o) => new
  785. {
  786. it.OrgLevelOneCode,
  787. o.Name
  788. })
  789. .Select((it, o) => new OrgStatistics
  790. {
  791. CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
  792. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
  793. }).ToListAsync();
  794. centerReportStatisticsDto.OrgStatisticsAreaAll = new OrgStatisticsAll
  795. {
  796. OrgStatistics = listOrgStatisticsAreaAll
  797. };
  798. #endregion
  799. return centerReportStatisticsDto;
  800. }
  801. /// <summary>
  802. /// 部门受理类型统计周期
  803. /// </summary>
  804. /// <param name="StartDate"></param>
  805. /// <param name="EndDate"></param>
  806. /// <param name="TypeCode">0:全部,1:中心,2:部门</param>
  807. /// <returns></returns>
  808. [HttpGet("department_acceptance_type_statistics")]
  809. public async Task<List<DepartmentAcceptanceTypeStatisticsDto>> DepartmentAcceptanceTypeStatistics(DateTime StartDate, DateTime EndDate, int TypeCode)
  810. {
  811. EndDate = EndDate.AddDays(1).AddSeconds(-1);
  812. var orderData = await _orderRepository.Queryable()
  813. .LeftJoin<SystemOrganize>((it, o) => it.OrgLevelOneCode == o.Id)
  814. .Where((it, o) => it.CreationTime >= StartDate && it.CreationTime <= EndDate && (int)it.Status >= 300)
  815. .WhereIF(TypeCode == 1, (it, o) => it.OrgLevelOneCode == "001")
  816. .WhereIF(TypeCode == 2, (it, o) => it.OrgLevelOneCode != "001")
  817. .GroupBy((it, o) => new
  818. {
  819. it.OrgLevelOneCode,
  820. o.Name,
  821. o.OrgType
  822. })
  823. .Select((it, o) => new DepartmentAcceptanceTypeStatisticsDto
  824. {
  825. OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name,
  826. OrgCode = it.OrgLevelOneCode,
  827. OrgType = (int)o.OrgType == 2 ? "区县部门" : "市直部门",
  828. ZxAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "10", 1, 0)),
  829. ZxAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "10" && it.AllDuration != null, it.AllDuration, 0)),
  830. JyAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "15", 1, 0)),
  831. JyAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "15" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  832. QzAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "20", 1, 0)),
  833. QzAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "20" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  834. ByAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "25", 1, 0)),
  835. ByAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "25" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  836. JbAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "30", 1, 0)),
  837. JbAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "30" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  838. TsAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "35", 1, 0)),
  839. TsAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "35" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  840. QtAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "40", 1, 0)),
  841. QtAllTimes = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "40" && it.FileDurationWorkday != null, it.FileDurationWorkday, 0)),
  842. })
  843. .ToListAsync();
  844. return orderData;
  845. }
  846. }
  847. }