DatasharingSubscriber.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. using DotNetCore.CAP;
  2. using Hotline.Application.CallCenter;
  3. using Hotline.Application.FlowEngine;
  4. using Hotline.Application.Orders;
  5. using Hotline.Authentications;
  6. using Hotline.Caching.Interfaces;
  7. using Hotline.Configurations;
  8. using Hotline.ContingencyManagement;
  9. using Hotline.File;
  10. using Hotline.FlowEngine.WorkflowModules;
  11. using Hotline.FlowEngine.Workflows;
  12. using Hotline.Orders;
  13. using Hotline.OrderTranspond;
  14. using Hotline.Settings;
  15. using Hotline.Share.Dtos;
  16. using Hotline.Share.Dtos.ContingencyManagement;
  17. using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
  18. using Hotline.Share.Dtos.FlowEngine;
  19. using Hotline.Share.Dtos.FlowEngine.Workflow;
  20. using Hotline.Share.Dtos.Order;
  21. using Hotline.Share.Dtos.OrderTranspond;
  22. using Hotline.Share.Dtos.TrCallCenter;
  23. using Hotline.Share.Enums.FlowEngine;
  24. using Hotline.Share.Enums.Order;
  25. using Hotline.Share.Mq;
  26. using MapsterMapper;
  27. using Microsoft.Extensions.Options;
  28. using XF.Domain.Dependency;
  29. using XF.Domain.Exceptions;
  30. using XF.Domain.Repository;
  31. namespace Hotline.Application.Subscribers
  32. {
  33. /// <summary>
  34. /// 订阅来自DataSharing的消息
  35. /// </summary>
  36. public class DataSharingSubscriber : ICapSubscribe, ITransientDependency
  37. {
  38. private readonly IRepository<OrderVisit> _orderVisitRepository;
  39. private readonly IMapper _mapper;
  40. private readonly IOrderRepository _orderRepository;
  41. private readonly IOrderDomainService _orderDomainService;
  42. private readonly ICapPublisher _capPublisher;
  43. private readonly IRepository<OrderDelay> _orderDelayRepository;
  44. private readonly IRepository<OrderSendBack> _orderSendBackRepository;
  45. private readonly IWorkflowApplication _workflowApplication;
  46. private readonly IWorkflowDomainService _workflowDomainService;
  47. private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
  48. private readonly IFileRepository _fileRepository;
  49. private readonly IRepository<OrderUrge> _orderUrgeRepository;
  50. private readonly IRepository<OrderSupervise> _orderSuperviseRepository;
  51. private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
  52. private readonly IOrderScreenRepository _orderScreenRepository;
  53. private readonly IRepository<OrderExtension> _orderExtensionRepository;
  54. private readonly IRepository<SystemDicData> _systemDicDataRepository;
  55. private readonly ISystemOrganizeRepository _systemOrganizeRepository;
  56. private readonly IRepository<TranspondCityRawData> _transpondCityRawDataRepository;
  57. private readonly IRepository<OrderComplement> _orderComplementRepository;
  58. private readonly IOrderApplication _orderApplication;
  59. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  60. private readonly IRepository<OrderWarning> _orderWarningRepository;
  61. private readonly IRepository<OrderRevoke> _orderRevokeRepository;
  62. private readonly IRepository<ContingencyManagementOrders> _contingencyManagementOrdersRepository;
  63. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  64. private readonly ICallApplication _callApplication;
  65. public DataSharingSubscriber(
  66. IRepository<OrderVisit> orderVisitRepository,
  67. IMapper mapper,
  68. IOrderRepository orderRepository,
  69. IOrderDomainService orderDomainService,
  70. ICapPublisher capPublisher,
  71. IRepository<OrderDelay> orderDelayRepository,
  72. IRepository<OrderSendBack> orderSendBackRepository,
  73. IWorkflowApplication workflowApplication,
  74. IWorkflowDomainService workflowDomainService,
  75. IRepository<WorkflowTrace> workflowTraceRepository,
  76. IRepository<OrderUrge> orderUrgeRepository,
  77. IRepository<OrderSupervise> orderSuperviseRepository,
  78. IRepository<OrderVisitDetail> orderVisitedDetailRepository,
  79. IOrderScreenRepository orderScreenRepository,
  80. IRepository<OrderExtension> orderExtensionRepository,
  81. IFileRepository fileRepository,
  82. IRepository<SystemDicData> systemDicDataRepository,
  83. ISystemOrganizeRepository systemOrganizeRepository,
  84. IRepository<TranspondCityRawData> transpondCityRawDataRepository,
  85. IRepository<OrderComplement> orderComplementRepository,
  86. IOrderApplication orderApplication,
  87. ISystemSettingCacheManager systemSettingCacheManager,
  88. IRepository<OrderWarning> orderWarningRepository,
  89. IRepository<OrderRevoke> orderRevokeRepository,
  90. IRepository<ContingencyManagementOrders> contingencyManagementOrdersRepository,
  91. IOptionsSnapshot<AppConfiguration> appOptions,
  92. ICallApplication callApplication)
  93. {
  94. _orderSendBackRepository = orderSendBackRepository;
  95. _workflowApplication = workflowApplication;
  96. _workflowDomainService = workflowDomainService;
  97. _workflowTraceRepository = workflowTraceRepository;
  98. _orderUrgeRepository = orderUrgeRepository;
  99. _orderSuperviseRepository = orderSuperviseRepository;
  100. _orderScreenRepository = orderScreenRepository;
  101. _orderExtensionRepository = orderExtensionRepository;
  102. _orderVisitedDetailRepository = orderVisitedDetailRepository;
  103. _orderRepository = orderRepository;
  104. _orderDomainService = orderDomainService;
  105. _fileRepository = fileRepository;
  106. _orderVisitRepository = orderVisitRepository;
  107. _mapper = mapper;
  108. _capPublisher = capPublisher;
  109. _orderDelayRepository = orderDelayRepository;
  110. _systemDicDataRepository = systemDicDataRepository;
  111. _systemOrganizeRepository = systemOrganizeRepository;
  112. _transpondCityRawDataRepository = transpondCityRawDataRepository;
  113. _orderComplementRepository = orderComplementRepository;
  114. _orderApplication = orderApplication;
  115. _systemSettingCacheManager = systemSettingCacheManager;
  116. _orderWarningRepository = orderWarningRepository;
  117. _orderRevokeRepository = orderRevokeRepository;
  118. _contingencyManagementOrdersRepository = contingencyManagementOrdersRepository;
  119. _appOptions = appOptions;
  120. _callApplication = callApplication;
  121. }
  122. /// <summary>
  123. /// 接收工单退回结果
  124. /// </summary>
  125. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderReturnFeedback)]
  126. public async Task RecOrderReturnAsync(OrderSendBackResultDto dto, CancellationToken cancellationToken)
  127. {
  128. var sendBack = await _orderSendBackRepository.GetAsync(p => p.Id == dto.Id && p.State == 0, cancellationToken);
  129. if (sendBack != null)
  130. {
  131. sendBack.Result = dto.Result;
  132. sendBack.Reason = dto.Reason;
  133. sendBack.AuditName = dto.AuditName;
  134. sendBack.AuditOrgName = dto.AuditOrgName;
  135. sendBack.AuditTime = dto.AuditTime;
  136. if (dto.Result == 0)
  137. sendBack.State = 2;
  138. else if (dto.Result == 1)
  139. sendBack.State = 1;
  140. if (dto.Files != null && dto.Files.Any())
  141. {
  142. sendBack.FileJson = await _fileRepository.AddFileAsync(dto.Files, sendBack.Id, string.Empty, cancellationToken);
  143. }
  144. var order = await _orderRepository.GetAsync(sendBack.OrderId, cancellationToken);
  145. if (order is null)
  146. throw new UserFriendlyException("无效工单编号");
  147. if (dto.Result is 1)
  148. {
  149. //var now = DateTime.Now;
  150. //var handleDuration = order.StartTime.HasValue
  151. // ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value,
  152. // now, order.ProcessType is EProcessType.Zhiban)
  153. // : 0;
  154. //var fileDuration = order.CenterToOrgTime.HasValue
  155. // ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
  156. // now, order.ProcessType is EProcessType.Zhiban)
  157. // : 0;
  158. //var allDuration = order.StartTime.HasValue
  159. // ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
  160. // order.ProcessType is EProcessType.Zhiban)
  161. // : 0;
  162. //order.File(now, handleDuration, fileDuration, allDuration);
  163. //await _orderRepository.UpdateAsync(order, cancellationToken);
  164. var current = SessionContextCreator.CreateSessionContext(dto.Source);
  165. if (string.IsNullOrEmpty(order.WorkflowId))
  166. {
  167. var startDto = new StartWorkflowDto
  168. {
  169. DefinitionModuleCode = WorkflowModuleConsts.OrderHandle,
  170. Title = order.Title,
  171. Opinion = dto.Reason ?? "省工单同意退回",
  172. };
  173. await _workflowApplication.StartToEndAsync(startDto, current, order.Id, order.ExpiredTime,
  174. cancellationToken);
  175. }
  176. else
  177. {
  178. //await _workflowApplication.HandleToEndAsync(current, order.WorkflowId, "省工单同意退回", null,
  179. // EReviewResult.Approval, cancellationToken);
  180. await _workflowApplication.JumpToEndAsync(current, order.WorkflowId, dto.Reason ?? "省工单同意退回",
  181. null, order.ExpiredTime, cancellationToken: cancellationToken);
  182. }
  183. }
  184. else
  185. {
  186. order.Status = EOrderStatus.WaitForAccept;
  187. await _orderRepository.UpdateAsync(order, cancellationToken);
  188. }
  189. await _orderSendBackRepository.UpdateAsync(sendBack, cancellationToken);
  190. }
  191. }
  192. /// <summary>
  193. /// 服务工单撤单
  194. /// </summary>
  195. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderRevoke)]
  196. public async Task RecCancelOrderAsync(CancelOrderDto dto, CancellationToken cancellationToken)
  197. {
  198. var order = await _orderRepository.GetAsync(p => p.ProvinceNo == dto.ProvinceNo, cancellationToken);
  199. if (order is null)
  200. throw new UserFriendlyException("未查询到工单");
  201. OrderRevoke orderRevoke = new()
  202. {
  203. OrderId = order.Id,
  204. RevokeTime = DateTime.Parse(dto.RevokeTime),
  205. RevokeType = dto.RevokeType,
  206. RevokeName = dto.RevokeName,
  207. RevokeReasion = dto.Opinion,
  208. CliengGuid = dto.CliengGuid,
  209. IsProRevoke = true,
  210. RevokeTypeName = dto.RevokeType switch
  211. {
  212. "1" => "诉求人已私下解决",
  213. "2" => "诉求内容有误",
  214. "3" => "诉求人信息有误",
  215. "other" => "其它",
  216. _ => "其它",
  217. }
  218. };
  219. await _orderRevokeRepository.AddAsync(orderRevoke, cancellationToken);
  220. var current = SessionContextCreator.CreateSessionContext(dto.Source);
  221. if (string.IsNullOrEmpty(order?.WorkflowId))
  222. {
  223. var startDto = new StartWorkflowDto
  224. {
  225. DefinitionModuleCode = WorkflowModuleConsts.OrderHandle,
  226. Title = order.Title,
  227. Opinion = dto.Opinion,
  228. };
  229. await _workflowApplication.StartToEndAsync(startDto, current, order.Id, order.ExpiredTime,
  230. cancellationToken);
  231. }
  232. else
  233. {
  234. //await _workflowApplication.HandleToEndAsync(current, order.WorkflowId, dto.Opinion, null,
  235. // cancellationToken: cancellationToken);
  236. await _workflowApplication.JumpToEndAsync(current, order.WorkflowId, dto.Opinion, null, order.ExpiredTime,
  237. cancellationToken: cancellationToken);
  238. }
  239. }
  240. /// <summary>
  241. /// 服务工单催单
  242. /// </summary>
  243. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderRemind)]
  244. public async Task RecOrderUrgeAsync(ProvinceOrderUrgeDto dto, CancellationToken cancellationToken)
  245. {
  246. var exists = await _orderUrgeRepository.Queryable()
  247. .AnyAsync(d => d.DsBisId == dto.DsBisId, cancellationToken);
  248. if (exists)
  249. throw new UserFriendlyException($"收到重复催办编号: {dto.DsBisId}");
  250. var order = await _orderRepository.Queryable().Where(x => x.ProvinceNo == dto.CaseSerial).FirstAsync(cancellationToken);
  251. var model = new OrderUrge();
  252. model.InitId();
  253. model.State = 0;
  254. model.CreatorOrgName = "省12345";
  255. model.CrUser = dto.RemindName;
  256. model.ApplyContent = dto.RemindReasion;
  257. model.OrderId = order.Id;
  258. model.OrgId = "001";
  259. model.OrgName = "市民热线服务中心";
  260. model.RemindTime = dto.RemindTime;
  261. model.DsBisId = dto.DsBisId;
  262. //if (!string.IsNullOrEmpty(order.WorkflowId))
  263. //{
  264. // var org = await _workflowDomainService.FindActualHandlerAsync(order.WorkflowId, cancellationToken);
  265. // if (org != null)
  266. // {
  267. // model.OrgId = org.Key;
  268. // model.OrgName = org.Value;
  269. // }
  270. //}
  271. if (!string.IsNullOrEmpty(order.CurrentHandleOrgId) && !string.IsNullOrEmpty(order.CurrentHandleOrgName))
  272. {
  273. model.OrgId = order.CurrentHandleOrgId;
  274. model.OrgName = order.CurrentHandleOrgName;
  275. }
  276. if (dto.Files.Any())
  277. model.FileJson =
  278. await _fileRepository.AddFileAsync(dto.Files, model.Id, "", cancellationToken);
  279. await _orderUrgeRepository.AddAsync(model, cancellationToken);
  280. }
  281. /// <summary>
  282. /// 服务工单预警---收到预警给当前办理部门发催办,如果没有办理部门直接催办中心
  283. /// </summary>
  284. /// <param name="dto"></param>
  285. /// <param name="cancellationToken"></param>
  286. /// <returns></returns>
  287. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderWarning)]
  288. public async Task RecWarnInfoAsync(WarningDto dto, CancellationToken cancellationToken)
  289. {
  290. var order = await _orderRepository.Queryable().Where(x => x.ProvinceNo == dto.CaseSerial).FirstAsync(cancellationToken);
  291. if (order != null)
  292. {
  293. var model = new OrderUrge();
  294. model.InitId();
  295. model.State = 0;
  296. model.CreatorOrgName = "省12345";
  297. model.CrUser = "省12345";
  298. model.ApplyContent = dto.WarnRulename + " " + dto.WarnDescribe;
  299. model.OrderId = order.Id;
  300. model.ReplyLimitTime = dto.WarnTimebf;
  301. model.OrgId = "001";
  302. model.OrgName = "市民热线服务中心";
  303. //if (!string.IsNullOrEmpty(order.WorkflowId))
  304. //{
  305. // var org = await _workflowDomainService.FindActualHandlerAsync(order.WorkflowId, cancellationToken);
  306. // if (org != null)
  307. // {
  308. // model.OrgId = org.Key;
  309. // model.OrgName = org.Value;
  310. // }
  311. //}
  312. model.OrgId = order.CurrentHandleOrgId;
  313. model.OrgName = order.CurrentHandleOrgName;
  314. await _orderUrgeRepository.AddAsync(model, cancellationToken);
  315. //写入预警
  316. var warning = new OrderWarning()
  317. {
  318. OrderId = order.Id,
  319. WarnRulename = dto.WarnRulename,
  320. WarnDescribe = dto.WarnDescribe,
  321. WarnTimebf = dto.WarnTimebf,
  322. WarnDegree = dto.WarnDegree,
  323. WarnType = dto.WarnType,
  324. WarnDate = dto.WarnDate,
  325. IsProWarn = true
  326. };
  327. await _orderWarningRepository.AddAsync(warning, cancellationToken);
  328. }
  329. }
  330. /// <summary>
  331. /// 督办工单派发接口
  332. /// </summary>
  333. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderSupervise)]
  334. public async Task RecOrderSuperviseAsync(ProvinceSendOrderSuperviseDto dto, CancellationToken cancellationToken)
  335. {
  336. var exists = await _orderSuperviseRepository.Queryable()
  337. .AnyAsync(d => d.SuperviseSerial == dto.ProvinceOrderSuperviseDto.SuperviseSerial, cancellationToken);
  338. if (exists)
  339. throw new UserFriendlyException($"收到重复督办编号: {dto.ProvinceOrderSuperviseDto.SuperviseSerial}");
  340. var order = await _orderRepository.Queryable().Where(x => x.ProvinceNo == dto.ProvinceOrderSuperviseDto!.CaseSerial).FirstAsync(cancellationToken);
  341. var org = await _systemOrganizeRepository.GetAsync(x => x.Id == order.ActualHandleOrgCode, cancellationToken);
  342. var model = new OrderSupervise();
  343. model.InitId();
  344. model.OrderId = order.Id;
  345. model.ReplyLimitTime = dto.ProvinceOrderSuperviseDto.SuperviseReturnDate;
  346. model.OrgName = org.Name;
  347. model.OrgId = org.Id;
  348. model.LaunchOrgName = dto.ProvinceOrderSuperviseDto.SuperviseSendDept;
  349. model.CrUser = dto.ProvinceOrderSuperviseDto.SupervisePerson;
  350. model.State = 0;
  351. model.Province = true;
  352. model.ApplyContent = dto.ProvinceOrderSuperviseDto.SuperviseContent;
  353. model.SuperviseSerial = dto.ProvinceOrderSuperviseDto.SuperviseSerial;
  354. model.SuperviseTitle = dto.ProvinceOrderSuperviseDto.SuperviseTitle;
  355. model.SuperviseTime = dto.ProvinceOrderSuperviseDto.SuperviseTime;
  356. model.SuperviseType = dto.ProvinceOrderSuperviseDto.SuperviseType;
  357. if (dto.Files.Any())
  358. model.FileJson =
  359. await _fileRepository.AddFileAsync(dto.Files, model.Id, "", cancellationToken);
  360. await _orderSuperviseRepository.AddAsync(model, cancellationToken);
  361. }
  362. /// <summary>
  363. /// 服务工单甄别结果
  364. /// </summary>
  365. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderScreen)]
  366. public async Task RecOrderScreenResultAsync(ProvinceSendScreenResultDto dto, CancellationToken cancellationToken)
  367. {
  368. //var order = await _orderRepository.Queryable()
  369. // .Where(x => x.ProvinceNo == dto.ProvinceScreenResult!.CaseSerial)
  370. // .FirstAsync(cancellationToken);
  371. //var orderScreen = await _orderScreenRepository.Queryable()
  372. // .Where(x => x.OrderId == order.Id && x.Status == Share.Enums.Order.EScreenStatus.Approval)
  373. // .FirstAsync(cancellationToken);
  374. var orderScreen = await _orderScreenRepository.Queryable()
  375. .Where(x => x.Order.ProvinceNo == dto.ProvinceScreenResult.CaseSerial &&
  376. x.Status == EScreenStatus.Approval)
  377. .FirstAsync(cancellationToken);
  378. var current = SessionContextCreator.CreateSessionContext(dto.Source);
  379. await _workflowApplication.HandleToEndAsync(current,
  380. orderScreen.WorkflowId, "省上推送甄别结果", null,
  381. dto.ProvinceScreenResult.AuditResult
  382. ? Share.Enums.FlowEngine.EReviewResult.Approval
  383. : Share.Enums.FlowEngine.EReviewResult.Failed, cancellationToken);
  384. orderScreen.Status = dto.ProvinceScreenResult.AuditResult ? Share.Enums.Order.EScreenStatus.End : Share.Enums.Order.EScreenStatus.Refuse;
  385. //if (orderScreen.Status == Share.Enums.Order.EScreenStatus.End)
  386. //{
  387. // var visitDetail = await _orderVisitedDetailRepository.GetAsync(orderScreen.VisitDetailId, cancellationToken);
  388. // if (visitDetail != null)
  389. // {
  390. // var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
  391. // visitDetail.OrgProcessingResults = screenSatisfy;
  392. // visitDetail.OrgHandledAttitude = screenSatisfy;
  393. // await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
  394. // }
  395. //}
  396. orderScreen.ReplyContent = dto.ProvinceScreenResult.AuditOpinion;
  397. orderScreen.AuditName = dto.ProvinceScreenResult.AuditPerson;
  398. orderScreen.AuditOrgName = dto.ProvinceScreenResult.AuditOuname;
  399. orderScreen.AuditTime = dto.ProvinceScreenResult.AuditTime;
  400. if (dto.Files.Any())
  401. orderScreen.FileJson =
  402. await _fileRepository.AddFileAsync(dto.Files, orderScreen.Id, "", cancellationToken);
  403. await _orderScreenRepository.UpdateAsync(orderScreen, cancellationToken);
  404. }
  405. /// <summary>
  406. /// 更新工单受理附件
  407. /// </summary>
  408. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderUpdataFiles)]
  409. public async Task RecOrderUpdateFilesAsync(OrderUpdataFiles dto, CancellationToken cancellationToken)
  410. {
  411. if (dto == null && dto.Files.Any())
  412. {
  413. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  414. order.FileJson = await _fileRepository.AddFileAsync(dto.Files, dto.OrderId, "", cancellationToken);
  415. }
  416. }
  417. /// <summary>
  418. /// 省下行回访
  419. /// </summary>
  420. /// <param name="dto"></param>
  421. /// <param name="cancellationToken"></param>
  422. /// <returns></returns>
  423. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderEvlResult)]
  424. public async Task OrderVisitProvince(ProvinceOrderVisitDto dto, CancellationToken cancellationToken)
  425. {
  426. var orderVisit = await _orderVisitRepository.Queryable()
  427. .Includes(x => x.Order)
  428. .Includes(x => x.OrderVisitDetails)
  429. .Where(x => x.Order.ProvinceNo == dto.ProvinceNo &&
  430. x.VisitState != Share.Enums.Order.EVisitState.None).FirstAsync(cancellationToken);
  431. if (orderVisit != null)
  432. {
  433. //处理评价结果
  434. var processingResult = dto.OrgProcessingResults;
  435. Kv orgProcessingResults = null;
  436. if (!string.IsNullOrEmpty(processingResult))
  437. {
  438. var dicData = await _systemDicDataRepository.GetAsync(x => x.DicTypeCode == SysDicTypeConsts.VisitSatisfaction &&
  439. x.DicDataValue == processingResult, cancellationToken);
  440. if (dicData != null)
  441. {
  442. orgProcessingResults = new Kv();
  443. orgProcessingResults.Key = dicData.DicDataValue;
  444. orgProcessingResults.Value = dicData.DicDataName;
  445. }
  446. if (orgProcessingResults != null)
  447. {
  448. //主表
  449. orderVisit.VisitState = Share.Enums.Order.EVisitState.Visited;
  450. orderVisit.VisitTime = dto.VisitTime;
  451. orderVisit.VisitType = dto.VisitType;
  452. orderVisit.IsCanHandle = orgProcessingResults.Key == "2";
  453. orderVisit.IsCanAiVisit = false;
  454. orderVisit.NowEvaluate = orgProcessingResults;
  455. await _orderVisitRepository.UpdateAsync(orderVisit, cancellationToken);
  456. //子表
  457. for (int i = 0; i < orderVisit.OrderVisitDetails.Count; i++)
  458. {
  459. if (orderVisit.OrderVisitDetails[i].VisitTarget == EVisitTarget.Seat)
  460. {
  461. orderVisit.OrderVisitDetails[i].VoiceEvaluate = (EVoiceEvaluate)int.Parse(orgProcessingResults.Key);
  462. orderVisit.OrderVisitDetails[i].SeatEvaluate = (ESeatEvaluate)int.Parse(orgProcessingResults.Key);
  463. }
  464. else
  465. {
  466. orderVisit.OrderVisitDetails[i].OrgProcessingResults = orgProcessingResults;
  467. }
  468. orderVisit.OrderVisitDetails[i].VisitContent = dto.VisitContent;
  469. }
  470. await _orderVisitedDetailRepository.UpdateRangeAsync(orderVisit.OrderVisitDetails, cancellationToken);
  471. //工单
  472. orderVisit.Order.Visited(orgProcessingResults.Key, orgProcessingResults.Value);
  473. await _orderRepository.UpdateAsync(orderVisit.Order);
  474. ////处理网站通知差评数据
  475. //if (orderVisit.Order.Source == ESource.Hotline && orderVisit.OrderVisitDetails.Any(x => x.OrgHandledAttitude?.Key == "1" || x.OrgHandledAttitude?.Key == "2" || x.OrgProcessingResults?.Key == "1" || x.OrgProcessingResults?.Key == "2"))
  476. //{
  477. // //包含不满意数据,重新生成新的回访
  478. // var newOrderVisit = _mapper.Map<OrderVisit>(orderVisit);
  479. // newOrderVisit.InitId();
  480. // newOrderVisit.VisitState = EVisitState.NoSatisfiedWaitForVisit;
  481. // newOrderVisit.VisitTime = null;
  482. // newOrderVisit.IsCanHandle = false;
  483. // newOrderVisit.IsCanAiVisit = false;
  484. // newOrderVisit.AiVisitCount = 0;
  485. // await _orderVisitRepository.AddAsync(newOrderVisit, cancellationToken);
  486. // var list = _mapper.Map<List<OrderVisitDetail>>(orderVisit.OrderVisitDetails);
  487. // list.ForEach(x =>
  488. // {
  489. // x.VisitId = newOrderVisit.Id;
  490. // x.VoiceEvaluate = null;
  491. // x.VoiceEvaluate = null;
  492. // x.OrgHandledAttitude = null;
  493. // x.OrgNoSatisfiedReason = null;
  494. // x.OrgProcessingResults = null;
  495. // x.VisitContent = "";
  496. // });
  497. // await _orderVisitedDetailRepository.AddRangeAsync(list, cancellationToken);
  498. //}
  499. }
  500. }
  501. }
  502. }
  503. /// <summary>
  504. /// 工单回访
  505. /// </summary>
  506. /// <param name="dto"></param>
  507. /// <param name="cancellationToken"></param>
  508. /// <returns></returns>
  509. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderVisitAllOther)]
  510. public async Task OrderVisitWeb(OrderVisitWebDto dto, CancellationToken cancellationToken)
  511. {
  512. await _orderApplication.OrderVisitWeb(dto, cancellationToken);
  513. }
  514. /// <summary>
  515. /// 订阅省工单延期消息
  516. /// </summary>
  517. /// <param name="dto"></param>
  518. /// <param name="cancellationToken"></param>
  519. /// <returns></returns>
  520. [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderDelayResult)]
  521. public async Task OrderDelayWeb(ProvinceSendDelayResultDto dto, CancellationToken cancellationToken)
  522. {
  523. var order = await _orderRepository.GetAsync(x => x.ProvinceNo == dto.No, cancellationToken);
  524. if (order != null)
  525. {
  526. //查询延期
  527. var orderDelay = await _orderDelayRepository
  528. .GetAsync(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining, cancellationToken);
  529. if (orderDelay != null)
  530. {
  531. orderDelay.AuditName = dto.AuditName;
  532. orderDelay.AuditOrgName = dto.AuditOrgName;
  533. orderDelay.AuditTime = dto.AuditTime;
  534. orderDelay.AuditOpinion = dto.Opinion;
  535. if (dto.Files != null && dto.Files.Any())
  536. orderDelay.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderDelay.Id, orderDelay.WorkflowId, cancellationToken);
  537. await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
  538. var current = SessionContextCreator.CreateSessionContext(dto.Source);
  539. await _workflowApplication.HandleToEndAsync(current, orderDelay.WorkflowId, dto.Opinion, dto.Files,
  540. dto.IsPass ? EReviewResult.Approval : EReviewResult.Failed, cancellationToken);
  541. }
  542. }
  543. }
  544. /// <summary>
  545. /// 接收工单处理结果
  546. /// </summary>
  547. [CapSubscribe(EventNames.SharingOrderReultSend)]
  548. public async Task RecOrderResultAsync(OrderResultDto dto, CancellationToken cancellationToken)
  549. {
  550. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  551. if (order is null)
  552. throw new UserFriendlyException($"无效工单编号, orderId: {dto.OrderId}");
  553. if (string.IsNullOrEmpty(order.WorkflowId))
  554. throw new UserFriendlyException($"该工单未开启流程,orderId: {dto.OrderId}");
  555. //if (dto.Files != null && dto.Files.Any())
  556. //{
  557. // order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, order.WorkflowId,
  558. // cancellationToken);
  559. // await _orderRepository.FileAsync(order, cancellationToken);
  560. //}
  561. var current = SessionContextCreator.CreateSessionContext(dto.Source);
  562. switch (dto.FinishType)
  563. {
  564. case "0":
  565. //退回:撤回至发起人
  566. await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, dto.Opinion, current, cancellationToken);//todo think是否需要保存附件至省平台办理节点?
  567. break;
  568. case "1":
  569. //办结:归档
  570. await _workflowApplication.HandleToEndAsync(current, order.WorkflowId, dto.Opinion, dto.Files,
  571. cancellationToken: cancellationToken);
  572. break;
  573. }
  574. //var now = DateTime.Now;
  575. //var handleDuration = order.StartTime.HasValue
  576. // ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value,
  577. // now, order.ProcessType is EProcessType.Zhiban)
  578. // : 0;
  579. //var fileDuration = order.CenterToOrgTime.HasValue
  580. // ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
  581. // now, order.ProcessType is EProcessType.Zhiban)
  582. // : 0;
  583. //var allDuration = order.StartTime.HasValue
  584. // ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
  585. // order.ProcessType is EProcessType.Zhiban)
  586. // : 0;
  587. //order.File(now, handleDuration, fileDuration, allDuration);
  588. //await _orderRepository.UpdateAsync(order, cancellationToken);
  589. }
  590. /// <summary>
  591. /// 接收工单扩展信息
  592. /// </summary>
  593. [CapSubscribe(EventNames.SharingOrderExtends)]
  594. public async Task RecOrderExtensionAsync(OrderExtensionDto dto, CancellationToken cancellationToken)
  595. {
  596. var order = await _orderRepository.Queryable()
  597. .FirstAsync(d => d.ProvinceNo == dto.ProvinceNo, cancellationToken);
  598. var orderExtension = await _orderDomainService.GetOrderExtensionsAsync(dto.ProvinceNo, cancellationToken);
  599. if (orderExtension is null)
  600. {
  601. orderExtension = _mapper.Map<OrderExtension>(dto);
  602. if (order != null)
  603. orderExtension.Id = order.Id;
  604. await _orderExtensionRepository.AddAsync(orderExtension, cancellationToken);
  605. }
  606. else
  607. {
  608. _mapper.Map(dto, orderExtension);
  609. if (order != null)
  610. orderExtension.Id = order.Id;
  611. await _orderExtensionRepository.UpdateAsync(orderExtension, cancellationToken);
  612. }
  613. }
  614. /// <summary>
  615. /// 接收工单办理流程
  616. /// </summary>
  617. [CapSubscribe(EventNames.SharingOrderAddTraces)]
  618. public async Task RecOrderTracesAsync(AddOrderTracesDto dto, CancellationToken cancellationToken)
  619. {
  620. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  621. if (order is null)
  622. throw new UserFriendlyException($"未查询到对应工单,orderId: {dto.OrderId}");
  623. if (string.IsNullOrEmpty(order.WorkflowId))
  624. throw new UserFriendlyException($"该工单未开启流程,orderId: {dto.OrderId}");
  625. var traces = dto.Traces.Select(d =>
  626. {
  627. var trace = _mapper.Map<WorkflowTrace>(d);
  628. trace.WorkflowId = order.WorkflowId;
  629. return trace;
  630. }).ToList();
  631. await _workflowDomainService.AddTracesAsync(order.WorkflowId, traces, cancellationToken);
  632. }
  633. /// <summary>
  634. /// 接收工单补充内容
  635. /// </summary>
  636. [CapSubscribe(EventNames.SharingOrderSupplements)]
  637. public async Task RecOrderSupplementsAsync(AddOrderComplementDto dto, CancellationToken cancellationToken)
  638. {
  639. var order = await _orderRepository.GetAsync(d => d.ProvinceNo == dto.CaseSerial, cancellationToken);
  640. if (order is null)
  641. throw new UserFriendlyException("无效省工单编号");
  642. dto.OrderId = order.Id;
  643. await _orderDomainService.AddOrderComplementAsync(dto, cancellationToken);
  644. }
  645. /// <summary>
  646. /// 接收省上上传附件
  647. /// </summary>
  648. /// <param name="dto"></param>
  649. /// <param name="cancellationToken"></param>
  650. /// <returns></returns>
  651. /// <exception cref="UserFriendlyException"></exception>
  652. /// <exception cref="ArgumentOutOfRangeException"></exception>
  653. [CapSubscribe(EventNames.SharingFileInfo)]
  654. public async Task RecFilesAsync(ReceiveFilesFromDsDto dto, CancellationToken cancellationToken)
  655. {
  656. if (dto.Files == null || !dto.Files.Any())
  657. throw new UserFriendlyException("未收到任何附件");
  658. switch (dto.DsBisType)
  659. {
  660. case EDsBisType.AcceptOrder:
  661. var order = await _orderRepository.GetAsync(d => d.ProvinceNo == dto.ProvinceNo, cancellationToken);
  662. if (order is null)
  663. throw new UserFriendlyException("无效省工单编号");
  664. order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, order.WorkflowId ?? string.Empty, cancellationToken);
  665. await _orderRepository.UpdateAsync(order, cancellationToken);
  666. break;
  667. case EDsBisType.OrderPreviousResult:
  668. var sendBack = await _orderSendBackRepository.Queryable()
  669. .Where(d => d.Order.ProvinceNo == dto.ProvinceNo)
  670. .FirstAsync(cancellationToken);
  671. if (sendBack is null)
  672. throw new UserFriendlyException("无效省工单退回编号");
  673. sendBack.FileJson = await _fileRepository.AddFileAsync(dto.Files, sendBack.Id, string.Empty, cancellationToken);
  674. await _orderSendBackRepository.UpdateAsync(sendBack, cancellationToken);
  675. break;
  676. case EDsBisType.SendOrderSupervise:
  677. var orderSupervise = await _orderSuperviseRepository
  678. .GetAsync(d => d.SuperviseSerial == dto.SuperviseId, cancellationToken);
  679. if (orderSupervise is null)
  680. throw new UserFriendlyException("无效省工单督办编号");
  681. orderSupervise.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderSupervise.Id, "", cancellationToken);
  682. await _orderSuperviseRepository.AddAsync(orderSupervise, cancellationToken);
  683. break;
  684. case EDsBisType.SendOrderUrge:
  685. var orderUrge = await _orderUrgeRepository
  686. .GetAsync(d => d.DsBisId == dto.DsBisId, cancellationToken);
  687. if (orderUrge is null)
  688. throw new UserFriendlyException("无效省工单催办业务编号");
  689. orderUrge.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderUrge.Id, "", cancellationToken);
  690. await _orderUrgeRepository.UpdateAsync(orderUrge, cancellationToken);
  691. break;
  692. case EDsBisType.OrderScreenResult:
  693. var orderScreen = await _orderScreenRepository.Queryable()
  694. .Where(x => x.Order.ProvinceNo == dto.ProvinceNo && x.Status == Share.Enums.Order.EScreenStatus.Approval)
  695. .FirstAsync(cancellationToken);
  696. if (orderScreen is null)
  697. throw new UserFriendlyException("未查询到对应省工单甄别数据");
  698. orderScreen.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderScreen.Id, "", cancellationToken);
  699. await _orderScreenRepository.UpdateAsync(orderScreen, cancellationToken);
  700. break;
  701. case EDsBisType.OrderDelayResult:
  702. var orderDelay = await _orderDelayRepository.Queryable()
  703. .Where(d => d.Order.ProvinceNo == dto.ProvinceNo && d.DelayState == EDelayState.Examining)
  704. .FirstAsync(cancellationToken);
  705. if (orderDelay is null)
  706. throw new UserFriendlyException($"未查询到延期数据, ProvinceNo: {dto.ProvinceNo}");
  707. if (dto.Files != null && dto.Files.Any())
  708. orderDelay.FileJson = await _fileRepository.AddFileAsync(dto.Files, orderDelay.Id, orderDelay.WorkflowId, cancellationToken);
  709. await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
  710. break;
  711. case EDsBisType.SendOrderComplement:
  712. var complement = await _orderComplementRepository
  713. .GetAsync(d => d.DsBisId == dto.DsBisId, cancellationToken);
  714. if (complement is null)
  715. throw new UserFriendlyException(
  716. $"未查询到补充信息, ProvinceNo: {dto.ProvinceNo}, DsBisIs: {dto.DsBisId}");
  717. if (dto.Files.Any()) complement.FileJson = await _fileRepository.AddFileAsync(dto.Files, complement.Id, "", cancellationToken);
  718. await _orderComplementRepository.UpdateAsync(complement, cancellationToken);
  719. break;
  720. case EDsBisType.OrderHandleResult:
  721. var order1 = await _orderRepository.GetAsync(d => d.ProvinceNo == dto.ProvinceNo, cancellationToken);
  722. if (order1 is null)
  723. throw new UserFriendlyException($"无效工单编号, ProvinceNo: {dto.ProvinceNo}");
  724. if (string.IsNullOrEmpty(order1.WorkflowId))
  725. throw new UserFriendlyException($"该工单未开启流程,ProvinceNo: {dto.ProvinceNo}");
  726. await _workflowApplication.UpdateProvinceHandleResultFilesAsync(order1.WorkflowId, dto.Files, cancellationToken);
  727. break;
  728. default:
  729. throw new ArgumentOutOfRangeException();
  730. }
  731. }
  732. /// <summary>
  733. /// 接收市州互转返回数据
  734. /// </summary>
  735. [CapSubscribe(EventNames.SharingOrderTranspondCity)]
  736. public async Task RecTranspondCityRawDataAsync(TranspondCityRawDataDto dto, CancellationToken cancellationToken)
  737. {
  738. var data = await _transpondCityRawDataRepository.GetAsync(p => p.OrderCode == dto.OrderCode && p.Direction == ETranspondDirection.Out, cancellationToken);
  739. if (data != null)
  740. {
  741. data.IsSuccess = dto.IsSuccess;
  742. data.SendTimes = dto.SendTimes;
  743. data.Result = dto.Result;
  744. data.NewCode = dto.NewCode;
  745. await _transpondCityRawDataRepository.UpdateAsync(data, cancellationToken);
  746. }
  747. }
  748. /// <summary>
  749. /// 接收市州互转接收原始数据
  750. /// </summary>
  751. [CapSubscribe(EventNames.SharingOrderReceiveTranspondCity)]
  752. public async Task RecTranspondCityReceiveRawDataAsync(TranspondCityRawDataDto dto, CancellationToken cancellationToken)
  753. {
  754. await _transpondCityRawDataRepository.AddAsync(_mapper.Map<TranspondCityRawData>(dto), cancellationToken);
  755. }
  756. /// <summary>
  757. /// 接收市州互转办理结果
  758. /// </summary>
  759. [CapSubscribe(EventNames.SharingOrderReceiveHandleOpinionTranspondCity)]
  760. public async Task RecTranspondCityReceiveResultAsync(TranspondCityOrderResultDto dto, CancellationToken cancellationToken)
  761. {
  762. var cityDataUndertakAdvice = _systemSettingCacheManager.GetSetting(SettingConstants.CityDataUndertakAdvice)?.SettingValue[0];
  763. if (cityDataUndertakAdvice == "true")
  764. {
  765. var order = await _orderRepository.GetAsync(p => p.No == dto.No, cancellationToken);
  766. if (order != null)
  767. {
  768. order.ActualOpinion = dto.Opinion;
  769. await _orderRepository.UpdateAsync(order, cancellationToken);
  770. //后面还需要处理流程中的意见
  771. }
  772. }
  773. //修改推送数据办理结果
  774. var data = await _transpondCityRawDataRepository.GetAsync(p => p.OrderCode == dto.No && p.Direction == ETranspondDirection.Out, cancellationToken);
  775. if (data != null)
  776. {
  777. data.ActualOpinion = dto.Opinion;
  778. await _transpondCityRawDataRepository.UpdateAsync(data, cancellationToken);
  779. }
  780. }
  781. /// <summary>
  782. /// 应急管理局推送回调
  783. /// </summary>
  784. /// <returns></returns>
  785. [CapSubscribe(EventNames.HotlineOrderContingencyManagementState)]
  786. public async Task RecHotlineOrderContingencyManagementState(RecOrderStateDto dto, CancellationToken cancellationToken)
  787. {
  788. var data = await _contingencyManagementOrdersRepository.GetAsync(p => p.Id == dto.Id, cancellationToken);
  789. if (data != null && dto.State != data.PushState)
  790. {
  791. data.PushState = dto.State;
  792. await _contingencyManagementOrdersRepository.UpdateAsync(data, cancellationToken);
  793. }
  794. }
  795. /// <summary>
  796. /// 处理每天办理完成未及时推送办理结果的数据
  797. /// </summary>
  798. /// <param name="provinceNos"></param>
  799. /// <param name="cancellationToken"></param>
  800. /// <returns></returns>
  801. [CapSubscribe(EventNames.HotlineFiledOrdersRepublish)]
  802. public async Task RepublishFiledOrders(List<string> provinceNos, CancellationToken cancellationToken)
  803. {
  804. var unpublishOrders = await _orderRepository.Queryable()
  805. .Where(d => provinceNos.Contains(d.ProvinceNo) &&
  806. !string.IsNullOrEmpty(d.ProvinceNo) &&
  807. d.Status >= EOrderStatus.Filed)
  808. .ToListAsync(cancellationToken);
  809. foreach (var order in unpublishOrders)
  810. {
  811. var trace = await _workflowTraceRepository.Queryable()
  812. .FirstAsync(d => d.WorkflowId == order.WorkflowId && d.StepType == EStepType.End, cancellationToken);
  813. var orderFlowDto = new OrderFlowDto
  814. {
  815. Order = _mapper.Map<OrderDto>(order),
  816. WorkflowTrace = _mapper.Map<WorkflowTraceDto>(trace)
  817. };
  818. if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
  819. !string.IsNullOrEmpty(order.CallId))
  820. {
  821. if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
  822. {
  823. var callRecord = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
  824. if (callRecord != null)
  825. {
  826. orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
  827. }
  828. }
  829. else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
  830. {
  831. var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
  832. if (call is not null)
  833. orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
  834. }
  835. }
  836. //这里需要判断是否是警情退回
  837. orderFlowDto.IsNonPoliceReturn = false;
  838. await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
  839. }
  840. }
  841. /// <summary>
  842. /// 随手拍网格员、回复办理结果
  843. /// </summary>
  844. /// <param name="dto"></param>
  845. /// <param name="cancellationToken"></param>
  846. /// <returns></returns>
  847. [CapSubscribe(EventNames.TianQueReceiverOpinion)]
  848. public async Task TianQueReceiverOpinion(TianQueReceiverOpinionDto dto, CancellationToken cancellationToken)
  849. {
  850. //todo
  851. }
  852. /// <summary>
  853. /// 天阙推送工单,返回信息
  854. /// </summary>
  855. /// <returns></returns>
  856. [CapSubscribe(EventNames.TianQuePushOrderReceiver)]
  857. public async Task TianQuePushOrderReceiver(TianQuePushOrderReceiverDto dto, CancellationToken cancellationToken)
  858. {
  859. //todo
  860. }
  861. }
  862. }