123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- using DotNetCore.CAP;
- using Hotline.Application.CallCenter;
- using Hotline.Application.JudicialManagement;
- using Hotline.Application.Orders;
- using Hotline.Caching.Interfaces;
- using Hotline.CallCenter.Tels;
- using Hotline.Configurations;
- using Hotline.EventBus;
- using Hotline.FlowEngine.Notifications;
- using Hotline.FlowEngine.WorkflowModules;
- using Hotline.JudicialManagement.Notifies;
- using Hotline.KnowledgeBase;
- using Hotline.Orders;
- using Hotline.Settings;
- using Hotline.Settings.TimeLimits;
- using Hotline.Share.Dtos.FlowEngine.Workflow;
- using Hotline.Share.Dtos.Order;
- using Hotline.Share.Dtos.TrCallCenter;
- using Hotline.Share.Enums.Order;
- using MapsterMapper;
- using MediatR;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using XF.Domain.Repository;
- namespace Hotline.Application.Handlers.FlowEngine;
- public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
- {
- private readonly IKnowledgeDomainService _knowledgeDomainService;
- private readonly IOrderDomainService _orderDomainService;
- private readonly IOrderApplication _orderApplication;
- private readonly ITelDomainService _telDomainService;
- private readonly IOrderRepository _orderRepository;
- private readonly ICapPublisher _capPublisher;
- private readonly IMapper _mapper;
- private readonly IRepository<OrderDelay> _orderDelayRepository;
- private readonly ITimeLimitDomainService _timeLimitDomainService;
- private readonly ILogger<WorkflowEndHandler> _logger;
- private readonly IKnowledgeRepository _knowledgeRepository;
- private readonly ICallApplication _callApplication;
- private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
- private readonly ISystemSettingCacheManager _systemSettingCacheManager;
- private readonly Publisher _publisher;
- public WorkflowEndHandler(
- IMapper mapper,
- IKnowledgeDomainService knowledgeDomainService,
- IOrderDomainService orderDomainService,
- IOrderApplication orderApplication,
- ITelDomainService telDomainService,
- IOrderRepository orderRepository,
- IKnowledgeRepository knowledgeRepository,
- IRepository<OrderDelay> orderDelayRepository,
- ICapPublisher capPublisher,
- ITimeLimitDomainService timeLimitDomainService,
- ICallApplication callApplication,
- IOptionsSnapshot<AppConfiguration> appOptions,
- ISystemSettingCacheManager systemSettingCacheManager,
- Publisher publisher,
- ILogger<WorkflowEndHandler> logger
- )
- {
- _mapper = mapper;
- _knowledgeDomainService = knowledgeDomainService;
- _orderDomainService = orderDomainService;
- _orderApplication = orderApplication;
- _telDomainService = telDomainService;
- _orderRepository = orderRepository;
- _knowledgeRepository = knowledgeRepository;
- _orderDelayRepository = orderDelayRepository;
- _capPublisher = capPublisher;
- _timeLimitDomainService = timeLimitDomainService;
- _callApplication = callApplication;
- _appOptions = appOptions;
- _systemSettingCacheManager = systemSettingCacheManager;
- _publisher = publisher;
- _logger = logger;
- }
- /// <summary>Handles a notification</summary>
- /// <param name="notification">The notification</param>
- /// <param name="cancellationToken">Cancellation token</param>
- public async Task Handle(EndWorkflowNotify notification, CancellationToken cancellationToken)
- {
- try
- {
- var workflow = notification.Workflow;
- //审批是否通过
- var isReviewPass = workflow.IsReviewPass();
- switch (workflow.ModuleCode)
- {
- case WorkflowModuleConsts.KnowledgeAdd://新增知识库
- case WorkflowModuleConsts.KnowledgeUpdate://修改知识库
- case WorkflowModuleConsts.KnowledgeDelete://删除知识库
- //var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
- var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
- knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
- await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
- if (isReviewPass)
- {
- await _knowledgeDomainService.EndWorkKnowledge(workflow, cancellationToken);
- }
- else
- {
- await _knowledgeDomainService.TerminateWorkKnowledge(workflow, cancellationToken);
- }
- break;
- case WorkflowModuleConsts.TelRestApply:
- await _telDomainService.TelRestApplyPassAsync(workflow.ExternalId, cancellationToken);
- break;
- case WorkflowModuleConsts.OrderHandle:
- var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId,
- withExtension: true, cancellationToken: cancellationToken);
- //order.CheckIfFiled();
- order.UpdateHandlingStatus(workflow.IsInCountersign);
- _mapper.Map(workflow, order);
- var now = DateTime.Now;
- var handleDuration = order.CenterToOrgTime.HasValue && order.ActualHandleTime.HasValue
- ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
- order.ActualHandleTime.Value, order.ProcessType is EProcessType.Zhiban)
- : 0;
- var fileDuration = order.CenterToOrgTime.HasValue
- ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
- now, order.ProcessType is EProcessType.Zhiban)
- : 0;
- var allDuration = order.StartTime.HasValue
- ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
- order.ProcessType is EProcessType.Zhiban)
- : 0;
- var creationTimeHandleDurationWorkday = order.ActualHandleTime.HasValue
- ? _timeLimitDomainService.CalcWorkTimeEx(order.CreationTime, now,
- order.ProcessType is EProcessType.Zhiban)
- : 0;
- var centerToOrgHandleDurationWorkday = order.ActualHandleTime.HasValue && order.CenterToOrgTime.HasValue
- ? _timeLimitDomainService.CalcWorkTimeEx(order.CenterToOrgTime.Value, now,
- order.ProcessType is EProcessType.Zhiban)
- : 0;
- order.File(now, handleDuration, fileDuration, allDuration, creationTimeHandleDurationWorkday, centerToOrgHandleDurationWorkday);
- order.FileUserId = notification.Trace.HandlerId;
- order.FileUserName = notification.Trace.HandlerName;
- order.FileUserOrgId = notification.Trace.HandlerOrgId;
- order.FileUserOrgName = notification.Trace.HandlerOrgName;
- order.FileOrgIsCenter = notification.Trace.HandlerOrgIsCenter;
- order.FileOpinion = notification.Dto.Opinion;
- //记录冗余归档数据
- if (notification.Workflow.Steps.Any(x => x.BusinessType == Share.Enums.FlowEngine.EBusinessType.Send))
- {
- order.FileUserRole = EFileUserType.Dispatch;
- }
- else
- {
- order.FileUserRole = EFileUserType.Seat;
- }
- if (order.ProcessType == EProcessType.Jiaoban)
- {
- order.FileUserRole = EFileUserType.Org;
- }
- //是否已解决
- order.IsResolved = notification.Dto.External == null ? false : notification.Dto.External.IsResolved;
- await _orderRepository.UpdateAsync(order, cancellationToken);
- //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
- //var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
- var orderFlowDto = new OrderFlowDto
- {
- Order = _mapper.Map<OrderDto>(order),
- WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace)
- };
- // if (callRecord != null)
- // {
- // orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
- // }
- if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
- !string.IsNullOrEmpty(order.CallId))
- {
- if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.TianRun)
- {
- // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
- var callRecord = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
- if (callRecord != null)
- {
- orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
- }
- }
- else if (_appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XingTang)
- {
- var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
- if (call is not null)
- orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
- }
- }
- //这里需要判断是否是警情退回
- orderFlowDto.IsNonPoliceReturn = notification.Dto.External == null ? false : notification.Dto.External.IsPoliceReturn;
- await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
- //try
- //{
- // //写入质检 针对受理之后直接结束的工单
- // await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
- //}
- //catch (Exception e)
- //{
- // _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
- //}
- //司法行政监督管理-工单处理
- //如果没开启则不处理
- var isOpenJudicialManagement = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenJudicialManagement)?.SettingValue[0];
- if (isOpenJudicialManagement == "true")
- await _publisher.PublishAsync(new JudicialManagementOrderNotify(order), PublishStrategy.ParallelWhenAll, cancellationToken);
- //推诿工单
- // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
- break;
- //case WorkflowModuleConsts.OrderScreen:
- // var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
- // if (screen != null)
- // {
- // screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
- // if (isReviewPass)
- // {
- // screen.Status = EScreenStatus.End;
- // screen.ReplyContent = workflow.ActualOpinion;
- // await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
- // var visitDetail =
- // await _orderVisitedDetailRepository.GetAsync(screen.VisitDetailId, cancellationToken);
- // if (visitDetail != null)
- // {
- // var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
- // visitDetail.OrgProcessingResults = screenSatisfy;
- // //visitDetail.OrgHandledAttitude = screenSatisfy;
- // await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
- // // 修改主表当前评价结果
- // await _orderVisitRepository.Updateable().SetColumns(v => new OrderVisit() { NowEvaluate = screenSatisfy }).Where(v => v.Id == visitDetail.VisitId).ExecuteCommandAsync(cancellationToken);
- // //获取回访信息
- // var visit = await _orderVisitRepository.Queryable().Includes(x => x.Order)
- // .Includes(x => x.OrderVisitDetails)
- // .Where(x => x.Id == screen.VisitId).FirstAsync(cancellationToken);
- // if (visit != null)
- // {
- // //获取回访明细
- // var visitDe = visit.OrderVisitDetails.First(x => x.Id == screen.VisitDetailId);
- // //推省上
- // await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderScreenApplyed,
- // new PublishVisitDto()
- // {
- // Order = _mapper.Map<OrderDto>(visit.Order),
- // No = visit.No,
- // VisitType = visit.VisitType,
- // VisitName = visit.CreatorName,
- // VisitTime = visit.VisitTime,
- // VisitRemark = string.IsNullOrEmpty(visitDe.VisitContent) ? screenSatisfy.Value : visitDe.VisitContent,
- // AreaCode = visit.Order.AreaCode!,
- // SubjectResultSatifyCode = visitDe.OrgProcessingResults?.Key,
- // FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
- // ClientGuid = ""
- // });
- // //推门户
- // await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
- // {
- // Id = visit.Id,
- // Order = _mapper.Map<OrderDto>(visit.Order),
- // OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
- // VisitName = visit.CreatorName,
- // VisitTime = visit.VisitTime,
- // VisitType = visit.VisitType,
- // VisitState = visit.VisitState,
- // PublishTime = visit.PublishTime,
- // }, cancellationToken: cancellationToken);
- // }
- // }
- // }
- // else
- // {
- // await _orderRepository.OrderScreenRevisionVisit(screen.VisitId, true, cancellationToken);
- // screen.Status = EScreenStatus.Refuse;
- // screen.ReplyContent = workflow.ActualOpinion;
- // }
- // screen.NewestAuditTime = DateTime.Now;
- //await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
- //OrderScreenDetail detail = new OrderScreenDetail
- //{
- // ScreenId = screen.Id
- //};
- //detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
- // await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
- // }
- // break;
- case WorkflowModuleConsts.OrderDelay:
- var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
- if (delay != null)
- {
- delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
- if (isReviewPass)
- {
- delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
- await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
- //处理工单延期
- await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
- delay.DelayUnit, delay.IsProDelay, cancellationToken);
- }
- else
- {
- delay.DelayState = EDelayState.NoPass;
- await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
- }
- }
- break;
- }
- }
- catch (Exception e)
- {
- _logger.LogError($"{nameof(WorkflowEndHandler)}异常,{e}");
- throw;
- }
- }
- }
|