123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654 |
- using DotNetCore.CAP;
- using Hotline.Application.Quality;
- using Hotline.Caching.Interfaces;
- using Hotline.File;
- using Hotline.FlowEngine.Workflows;
- using Hotline.Orders;
- using Hotline.Repository.SqlSugar.Extensions;
- using Hotline.Repository.SqlSugar.Ts;
- using Hotline.Settings.TimeLimits;
- using Hotline.Share.Dtos;
- using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
- using Hotline.Share.Dtos.File;
- using Hotline.Share.Dtos.FlowEngine;
- using Hotline.Share.Dtos.FlowEngine.Workflow;
- using Hotline.Share.Dtos.Order;
- using Hotline.Share.Dtos.Settings;
- using Hotline.Share.Enums.Order;
- using Hotline.Share.Enums.Quality;
- using Hotline.Share.Enums.Settings;
- using Hotline.Share.Requests;
- using Hotline.Tools;
- using MapsterMapper;
- using Microsoft.AspNetCore.Mvc.Formatters;
- using Microsoft.EntityFrameworkCore.Metadata.Internal;
- using Novacode;
- using SqlSugar;
- using System.Data;
- using System.Dynamic;
- using Hotline.Settings;
- using XF.Domain.Authentications;
- using XF.Domain.Constants;
- using XF.Domain.Dependency;
- using XF.Domain.Exceptions;
- using XF.Domain.Repository;
- namespace Hotline.Application.Orders;
- public class OrderApplication : IOrderApplication, IScopeDependency
- {
- private readonly IOrderDomainService _orderDomainService;
- private readonly IWorkflowDomainService _workflowDomainService;
- private readonly IOrderRepository _orderRepository;
- private readonly ITimeLimitDomainService _timeLimitDomainService;
- private readonly IMapper _mapper;
- private readonly ISystemSettingCacheManager _systemSettingCacheManager;
- private readonly IRepository<OrderWord> _orderWrodRepository;
- private readonly IRepositoryTextSearch<OrderTs> _repositoryts;
- private readonly IFileRepository _fileRepository;
- private readonly ISessionContext _sessionContext;
- private readonly IRepository<OrderVisit> _orderVisitRepository;
- private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
- private readonly IQualityApplication _qualityApplication;
- private readonly ICapPublisher _capPublisher;
- public OrderApplication(
- IOrderDomainService orderDomainService,
- IOrderRepository orderRepository,
- IWorkflowDomainService workflowDomainService,
- ITimeLimitDomainService timeLimitDomainService,
- ISystemSettingCacheManager systemSettingCacheManager,
- IMapper mapper,
- IRepository<OrderWord> orderWrodRepository,
- IRepositoryTextSearch<OrderTs> repositoryts,
- IFileRepository fileRepository,
- ISessionContext sessionContext,
- IRepository<OrderVisit> orderVisitRepository,
- IRepository<OrderVisitDetail> orderVisitDetailRepository,
- IQualityApplication qualityApplication,
- ICapPublisher capPublisher
- )
- {
- _orderDomainService = orderDomainService;
- _workflowDomainService = workflowDomainService;
- _orderRepository = orderRepository;
- _timeLimitDomainService = timeLimitDomainService;
- _mapper = mapper;
- _systemSettingCacheManager = systemSettingCacheManager;
- _orderWrodRepository = orderWrodRepository;
- _repositoryts = repositoryts;
- _fileRepository = fileRepository;
- _sessionContext = sessionContext;
- _orderVisitRepository = orderVisitRepository;
- _orderVisitDetailRepository = orderVisitDetailRepository;
- _qualityApplication = qualityApplication;
- _capPublisher = capPublisher;
- }
- /// <summary>
- /// 更新工单办理期满时间(延期调用,其他不调用)
- /// 1.更新工单 2.更新流程 3.推送省平台
- /// </summary>
- /// <returns></returns>
- public async Task DelayOrderExpiredTimeAsync(string orderId, int timeCount, ETimeType timeType, CancellationToken cancellationToken)
- {
- var order = await _orderDomainService.GetOrderAsync(orderId, cancellationToken: cancellationToken);
- var expiredTimeConfig =
- _timeLimitDomainService.CalcEndTime(DateTime.Now, new TimeConfig(timeCount, timeType), order.AcceptTypeCode);
- order.TimeLimit = expiredTimeConfig.TimeText;
- order.TimeLimitCount = expiredTimeConfig.Count;
- order.TimeLimitUnit = expiredTimeConfig.TimeType;
- order.ExpiredTime = expiredTimeConfig.ExpiredTime;
- order.NearlyExpiredTime = expiredTimeConfig.NearlyExpiredTime;
- //if (string.IsNullOrEmpty(order.WorkflowId))
- // throw new UserFriendlyException("该工单流程id异常");
- //var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, cancellationToken: cancellationToken);
- //await _workflowDomainService.UpdateExpiredTimeAsync(workflow, expiredTimeConfig.ExpiredTime,
- // expiredTimeConfig.TimeText, expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
- if (string.IsNullOrEmpty(order.WorkflowId))
- throw new UserFriendlyException("该工单流程id异常");
- await _workflowDomainService.UpdateUnhandleExpiredTimeAsync(order.WorkflowId, expiredTimeConfig.ExpiredTime, cancellationToken);
- await _orderRepository.UpdateAsync(order, cancellationToken);
- }
- /// <summary>
- /// 新增工单办理流程记录
- /// </summary>
- public async Task AddOrderTracesAsync(string orderId, ICollection<WorkflowTraceDto> traces, CancellationToken cancellationToken)
- {
- var order = await _orderRepository.GetAsync(orderId, cancellationToken);
- if (order is null)
- throw new UserFriendlyException("工单不存在");
- if (string.IsNullOrEmpty(order.WorkflowId))
- throw new UserFriendlyException("工单未开启流程");
- await _workflowDomainService.AddTracesAsync(order.WorkflowId, _mapper.Map<List<WorkflowTrace>>(traces),
- cancellationToken);
- }
- /// <summary>
- /// 撤销工单
- /// </summary>
- public async Task CancelOrderAsync(string orderId, string opinion, CancellationToken cancellationToken)
- {
- var order = await _orderRepository.GetAsync(orderId, cancellationToken);
- if (order is null)
- throw new UserFriendlyException("工单不存在");
- if (!string.IsNullOrEmpty(order.WorkflowId))
- {
- //结束流程
- await _workflowDomainService.TerminateAsync(new TerminateDto
- {
- WorkflowId = order.WorkflowId,
- Opinion = opinion
- }, cancellationToken);
- }
- //归档工单
- var now = DateTime.Now;
- var handleDuration = order.StartTime.HasValue
- ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value,
- now, 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;
- order.File(now, handleDuration, fileDuration, allDuration);
- await _orderRepository.UpdateAsync(order, cancellationToken);
- }
- /// <summary>
- /// 即将超期列表
- /// </summary>
- /// <param name="dto"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public ISugarQueryable<Order> GetAboutToExpireAsync(AboutToExpireListDto dto)
- {
- var setting = _systemSettingCacheManager.GetSetting(SettingConstants.OrderAboutToExpire);
- var value = setting?.SettingValue[0];
- value = string.IsNullOrEmpty(value) ? "0" : value;
- DateTime stTime = DateTime.Now.AddDays(int.Parse(value));
- stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
- DateTime stTime2 = _timeLimitDomainService.WorkDay(DateTime.Now);
- return _orderRepository.Queryable(canView: true)
- .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
- .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No!))
- .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title!))
- .WhereIF(dto.Delay.HasValue && dto.Delay == true,d=>d.OrderDelays.Any() == true)
- .WhereIF(dto.Delay.HasValue && dto.Delay == false, d => d.OrderDelays.Any() == false)
- .Where(d => d.ExpiredTime != null &&
- d.Status != EOrderStatus.Filed && d.Status != EOrderStatus.Published && d.Status != EOrderStatus.Visited && stTime >= d.ExpiredTime.Value && stTime2 <= d.ExpiredTime.Value)
- .OrderByDescending(d => d.CreationTime);
- }
- // /// <summary>
- // /// 即将超期节点列表
- // /// </summary>
- // /// <param name="dto"></param>
- // /// <param name="cancellationToken"></param>
- // /// <returns></returns>
- //public async Task<PagedDto<WorkflowOrderDto>> GetAboutToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken)
- //{
- // var setting = _systemSettingCacheManager.GetSetting(SettingConstants.OrderAboutToExpire);
- // var value = setting?.SettingValue[0];
- // value = string.IsNullOrEmpty(value) ? "0" : value;
- // DateTime stTime = DateTime.Now.AddDays(int.Parse(value));
- // stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
- // DateTime stTime2 = _timeLimitDomainService.WorkDay(DateTime.Now);
- // RefAsync<int> total = 0;
- // var items = await Db.Queryable<Workflow>()
- // .LeftJoin<Order>((x, o) => x.ExternalId == o.Id)
- // .Where(x => x.ModuleCode == "OrderHandle")
- // .WhereIF(dto.IsProvince.HasValue, (x, o) => o.IsProvince == dto.IsProvince)
- // .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => o.Title.Contains(dto.Keyword!) || o.No.Contains(dto.Keyword!))
- // .Where((x, o) => (int)x.Status < 20 && stTime >= x.ExpiredTime && stTime2 <= x.ExpiredTime)
- // .Select((x, o) => new WorkflowOrder { Order = o }, true)
- // .OrderByDescending(x => x.CreationTime)
- // .ToPageListAsync(dto.PageIndex, dto.PageSize, total, cancellationToken);
- // return new PagedDto<WorkflowOrderDto>(total, _mapper.Map<IReadOnlyList<WorkflowOrderDto>>(items));
- //}
- /// <summary>
- /// 已超期列表
- /// </summary>
- /// <param name="dto"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public ISugarQueryable<Order> GetToExpireAsync(AboutToExpireListDto dto)
- {
- DateTime stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
- return _orderRepository.Queryable(canView: true)
- .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
- //.WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
- .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No.Contains(dto.No))
- .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Contains(dto.Title!))
- .WhereIF(dto.Delay.HasValue && dto.Delay == true, d => d.OrderDelays.Any() == true)
- .WhereIF(dto.Delay.HasValue && dto.Delay == false, d => d.OrderDelays.Any() == false)
- .Where(d => d.ExpiredTime != null &&
- (((d.Status == EOrderStatus.Filed || d.Status == EOrderStatus.Published || d.Status == EOrderStatus.Visited) && d.FiledTime >= d.ExpiredTime) ||
- ((d.Status != EOrderStatus.Filed && d.Status != EOrderStatus.Published && d.Status != EOrderStatus.Visited) && stTime >= d.ExpiredTime.Value)))
- .OrderByDescending(x => x.CreationTime);
- }
- // /// <summary>
- // /// 已超期节点列表
- // /// </summary>
- // /// <param name="dto"></param>
- // /// <param name="cancellationToken"></param>
- // /// <returns></returns>
- // public async Task<PagedDto<WorkflowOrderDto>> GetToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken)
- // {
- // DateTime stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
- //RefAsync<int> total = 0;
- //var items= await Db.Queryable<Workflow>()
- // .LeftJoin<Order>((x,o)=>x.ExternalId == o.Id)
- // .Where(x => x.ModuleCode == "OrderHandle")
- // .WhereIF(dto.IsProvince.HasValue, (x, o) => o.IsProvince == dto.IsProvince)
- // .WhereIF(!string.IsNullOrEmpty(dto.Keyword), (x, o) => o.Title.Contains(dto.Keyword!) || o.No.Contains(dto.Keyword!))
- // .Where((x,o) => (((int)x.Status >= 20 && x.EndTime >= x.ExpiredTime) || ((int)x.Status < 20 && stTime >= x.ExpiredTime)))
- // .Select((x, o) => new WorkflowOrder { Order = o }, true)
- // .OrderByDescending(x => x.CreationTime)
- // .ToPageListAsync(dto.PageIndex, dto.PageSize, total, cancellationToken);
- // return new PagedDto<WorkflowOrderDto>(total, _mapper.Map<IReadOnlyList<WorkflowOrderDto>>(items));
- // }
- /// <summary>
- /// 工单关键字分词
- /// </summary>
- /// <param name="inputStr"></param>
- /// <returns></returns>
- public async Task OrderParticiple(string inputStr, string orderId, CancellationToken cancellationToken)
- {
- var words = await _orderWrodRepository.Queryable().Where(x => x.IsEnable == 1 && x.Classify.Contains("普通标签")).Select(x => x.Tag).ToListAsync(cancellationToken);
- var res = new List<string>();
- if (words.Any()) res = ParticipleTool.SegMMDouble(inputStr, ref words);
- var participles = await _orderWrodRepository.Queryable().In(x => x.Tag, res).ToListAsync(cancellationToken);
- if (participles.Any())
- {
- //关键词
- var tags = participles.Select(x => x.Tag).ToList();
- var tagsStr = string.Join(",", tags);
- await _orderRepository.Updateable().SetColumns(x => x.TagNames == tagsStr).Where(x => x.Id == orderId).ExecuteCommandAsync(cancellationToken);
- List<string> synonyms = participles.Select(x => x.Synonym).ToList();
- if (synonyms.Any())
- {
- var synonymsStr = string.Join(",", synonyms);
- synonyms = synonymsStr.Split(",").Distinct().ToList();
- tags.AddRange(synonyms);
- }
- var vector = await _orderRepository.Queryable().Where(x => x.Id == orderId).ToListAsync(cancellationToken);
- if (vector.Any()) await _repositoryts.UpdateVectorAsync(orderId, tags, cancellationToken);
- else await _repositoryts.AddVectorAsync(orderId, DateTime.Now, tags, cancellationToken);
- }
- }
- public async Task OrderSensitiveParticiple(string inputStr, string orderId, CancellationToken cancellationToken)
- {
- var words = await _orderWrodRepository.Queryable().Where(x => x.IsEnable == 1 && x.Classify.Contains("敏感标签")).Select(x => x.Tag).ToListAsync(cancellationToken);
- var res = new List<string>();
- if (words.Any()) res = ParticipleTool.SegMMDouble(inputStr, ref words);
- if (res.Any())
- {
- var intersect = words.Intersect(res).ToList();
- await _orderRepository.Updateable().SetColumns(o => new Order() { Sensitive = intersect }).Where(o => o.Id == orderId).ExecuteCommandAsync(cancellationToken);
- }
- }
- /// <summary>
- /// 接收外部平台工单
- /// </summary>
- public Task<AddOrderResponse> ReceiveOrderFromExternalAsync(AddOrderDto dto, ISessionContext current, CancellationToken cancellationToken)
- {
- switch (dto.Source)
- {
- case ESource.ProvinceStraight:
- return ReceiveOrderFromProvinceAsync(dto, dto.Files, current, cancellationToken);
- case ESource.Police110:
- case ESource.CityDataExchangeLz:
- case ESource.CityDataExchangeYB:
- case ESource.CityDataExchangeZG:
- case ESource.CityDataExchangeNJ:
- case ESource.WebPortal:
- case ESource.ConvergenceMedia:
- case ESource.IYIBIN:
- case ESource.ZHYB:
- case ESource.ZZPT:
- case ESource.WLLZ:
- return ReceiveOrderFromOtherPlatformAsync(dto, dto.Files, current, cancellationToken);
- case ESource.Hotline:
- case ESource.HotlineImport:
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
- /// <summary>
- /// 接收外部平台修改工单附件
- /// </summary>
- public async Task UpdateOrderFilesAnonymousAsync(UpdateOrderFilesDto dto, CancellationToken cancellationToken)
- {
- if (string.IsNullOrEmpty(dto.Id) && string.IsNullOrEmpty(dto.OrderNo))
- throw new UserFriendlyException("工单外部编号不能为空");
- var order = await _orderRepository.Queryable()
- .FirstAsync(d => d.Id == dto.Id || d.No == dto.OrderNo, cancellationToken);
- if (order != null && dto.Files != null && dto.Files.Any())
- {
- order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", cancellationToken);
- await _orderRepository.UpdateAsync(order, cancellationToken);
- }
- }
- /// <summary>
- /// 工单回访
- /// </summary>
- /// <param name="dto"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public async Task OrderVisitWeb(OrderVisitWebDto dto, CancellationToken cancellationToken)
- {
- var visit = await _orderVisitRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.OrderVisitDetails)
- .FirstAsync(x => x.Id == dto.Id);
- if (visit != null)
- {
- var first = dto.OrderVisitDetailDto.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org);
- if (first != null)
- {
- visit.NowEvaluate = first.OrgProcessingResults;
- visit.Order.Visited(first.OrgProcessingResults.Key, first.OrgProcessingResults.Value);
- }
- visit.VisitState = EVisitState.Visited;
- visit.VisitTime = dto.VisitTime;
- visit.VisitType = dto.VisitType;
- for (int i = 0; i < visit.OrderVisitDetails.Count; i++)
- {
- var detail = visit.OrderVisitDetails[i];
- var detaildto = dto.OrderVisitDetailDto.FirstOrDefault(x => x.Id == detail.Id);
- if (detaildto != null)
- {
- _mapper.Map(detaildto, visit.OrderVisitDetails[i]);
- }
- }
- await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
- await _orderVisitDetailRepository.UpdateRangeAsync(visit.OrderVisitDetails, cancellationToken);
- await _orderRepository.UpdateAsync(visit.Order, cancellationToken);
- var orderDto = _mapper.Map<OrderDto>(visit.Order);
- if (first != null)
- {
- //推省上
- await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
- new PublishVisitDto()
- {
- Order = orderDto,
- No = visit.No,
- VisitType = visit.VisitType,
- VisitName = visit.CreatorName,
- VisitTime = visit.VisitTime,
- VisitRemark = string.IsNullOrEmpty(first.VisitContent) ? first.OrgProcessingResults?.Value : first.VisitContent,
- AreaCode = visit.Order.AreaCode!,
- SubjectResultSatifyCode = first.OrgProcessingResults.Key,
- FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
- ClientGuid = ""
- }, cancellationToken: cancellationToken);
- }
- //写入质检
- await _qualityApplication.AddQualityAsync(EQualitySource.Visit, orderDto.Id, visit.Id,
- cancellationToken);
- }
- }
- public ISugarQueryable<Order> QueryOrders(QueryOrderDto dto)
- {
- var isCenter = _sessionContext.OrgIsCenter;
- return _orderRepository.Queryable(canView: isCenter ? false : true)
- .Includes(x => x.OrderScreens)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword!)) //标题
- .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), d => d.ProvinceNo.Contains(dto.ProvinceNo)) //省本地编号
- .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No)) //工单编码
- //.WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content!))
- .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptTypeCode)) //受理类型
- .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannelCode)) //来源渠道
- .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId)) //热点类型
- .WhereIF(!string.IsNullOrEmpty(dto.TransferPhone), d => d.TransferPhone.Contains(dto.TransferPhone!)) //转接号码
- //.WhereIF(dto.OrgCodes.Any(), d => d.Workflow.Assigns.Any(s => dto.OrgCodes.Contains(s.OrgCode)))
- .WhereIF(dto.OrgCodes.Any(), d => dto.OrgCodes.Contains(d.ActualHandleOrgCode)) //接办部门
- .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), d => d.AcceptorName.Contains(dto.NameOrNo!) || d.AcceptorStaffNo.Contains(dto.NameOrNo!)) //受理人/坐席
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart) //受理时间开始
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd) //受理时间结束
- .WhereIF(dto.EmergencyLevels.Any(), d => dto.EmergencyLevels.Contains(d.EmergencyLevel)) //紧急程度
- .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.FromPhone.Contains(dto.FromPhone)) //来电号码
- .WhereIF(!string.IsNullOrEmpty(dto.PhoneNo), d => d.Contact.Contains(dto.PhoneNo!)) //联系电话
- .WhereIF(!string.IsNullOrEmpty(dto.PushTypeCode), d => d.PushTypeCode == dto.PushTypeCode) //推送分类
- .WhereIF(dto.ExpiredTimeStart.HasValue, d => d.ExpiredTime >= dto.ExpiredTimeStart) //超期时间开始
- .WhereIF(dto.ExpiredTimeEnd.HasValue, d => d.ExpiredTime <= dto.ExpiredTimeEnd) //超期时间结束
- .WhereIF(dto.Statuses.Any(), d => dto.Statuses.Contains(d.Status)) //工单状态
- .WhereIF(dto.Statuses.Any(d => d == EOrderStatus.SpecialToUnAccept), d => d.Status <= EOrderStatus.SpecialToUnAccept)
- .WhereIF(!string.IsNullOrEmpty(dto.ActualHandlerName), d => d.ActualHandlerName.Contains(dto.ActualHandlerName)) //接办人
- .WhereIF(dto.IsScreen == true, d => d.OrderScreens.Any(x => x.Status != EScreenStatus.Refuse)) //有甄别
- .WhereIF(dto.IsScreen == false, d => !d.OrderScreens.Any(x => x.Status != EScreenStatus.Refuse)) //无甄别
- .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), d => d.ActualHandleStepCode == dto.CurrentStepCode) //当前办理节点
- .WhereIF(dto.ActualHandleTimeStart.HasValue, d => d.ActualHandleTime >= dto.ActualHandleTimeStart) //办结时间开始
- .WhereIF(dto.ActualHandleTimeEnd.HasValue, d => d.ActualHandleTime <= dto.ActualHandleTimeEnd) //办结时间结束
- .WhereIF(dto.IsOverTime == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //是 超期
- .WhereIF(dto.IsOverTime == false, d => (d.ExpiredTime > DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime > d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //否 超期
- .WhereIF(dto.IdentityType != null, d => d.IdentityType == dto.IdentityType) //来电主体
- .WhereIF(!string.IsNullOrEmpty(dto.FromName), d => d.FromName.Contains(dto.FromName)) //来电人姓名
- .WhereIF(dto.AreaCodes.Any(), d => dto.AreaCodes.Contains(d.AreaCode)) //区域
- .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.IsProvince == true)
- .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.IsProvince == false)
- .WhereIF(!string.IsNullOrEmpty(dto.SensitiveWord), x => SqlFunc.JsonArrayAny(x.Sensitive, dto.SensitiveWord))
- .WhereIF(dto.IsSensitiveWord.HasValue && dto.IsSensitiveWord == true, x => x.Sensitive != null && SqlFunc.JsonArrayLength(x.Sensitive) > 0)
- .OrderByDescending(d => d.CreationTime);
- }
- /// <summary>
- /// 未签收统计
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- public ISugarQueryable<Order,WorkflowStep> QueryUnsignedOrders(QueryUnsignedOrdersRequest dto) {
- if (dto.EndTime.HasValue)
- dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
- var IsCenter = _sessionContext.OrgIsCenter;
- return _orderRepository.Queryable()
- .LeftJoin<WorkflowStep>((x,ws)=>x.Id == ws.ExternalId)
- .WhereIF(dto.StartTime.HasValue, (x,ws) => ws.CreationTime >= dto.StartTime)
- .WhereIF(dto.EndTime.HasValue, (x, ws) => ws.CreationTime <= dto.EndTime)
- .WhereIF(dto.Level == 0 && IsCenter == false, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContext.OrgId))
- .WhereIF(dto.Level == 1,(x,ws)=> ws.AcceptorOrgId == _sessionContext.OrgId)
- .WhereIF(dto.Level == 2, (x, ws) => ws.AcceptorOrgId.StartsWith(_sessionContext.OrgId))
- .WhereIF(dto.Signed == 0 ,(x,ws)=>ws.Status == Share.Enums.FlowEngine.EWorkflowStepStatus.WaitForAccept)
- .WhereIF(dto.Signed == 1, (x, ws) => ws.Status == Share.Enums.FlowEngine.EWorkflowStepStatus.WaitForHandle)
- .Where((x,ws)=>ws.CountersignPosition == Share.Enums.FlowEngine.ECountersignPosition.None && x.Status > EOrderStatus.WaitForAccept)
- .OrderByDescending((x,ws) => ws.CreationTime);
- }
- /// <summary>
- /// 信件来源统计
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- public ISugarQueryable<Order> QueryOrderSource(QueryOrderSourceRequest dto)
- {
- if (dto.EndTime.HasValue)
- dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
- return _orderRepository.Queryable()
- .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
- .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
- .WhereIF(dto.IdentityType.HasValue , d=>d.IdentityType == dto.IdentityType)
- .Where(d=> d.SourceChannel != null && d.SourceChannel !="");
- }
- /// <summary>
- /// 信件来源统计列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- public async Task<List<OrderSourceHeaderVo>> QueryOrderSourceList(QueryOrderSourceRequest dto)
- {
- if (dto.EndTime.HasValue)
- dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
- var data = await _orderRepository.Queryable()
- .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
- .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
- .WhereIF(dto.IdentityType.HasValue, d => d.IdentityType == dto.IdentityType)
- .Where(d => d.SourceChannel != null && d.SourceChannel != "")
- .GroupBy(d => new { Time = d.CreationTime.ToString("yyyy-MM-dd"), d.SourceChannel })
- .Select(d => new OrderSourceHeaderVo
- {
- Time = d.CreationTime.ToString("yyyy-MM-dd"),
- Phone = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "RGDH", 1, 0)),
- Web = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YTW", 1, 0)),
- Rests = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "QT", 1, 0)),
- Created = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZJ", 1, 0)),
- WeChat = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "WX", 1, 0)),
- App = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "AP", 1, 0)),
- WisdomYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZHYB", 1, 0)),
- Platform = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZZPT", 1, 0)),
- Platform12328 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12328", 1, 0)),
- MayorAndNetizens = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZYSM", 1, 0)),
- MediaYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBRMT", 1, 0)),
- Platform12345 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12345", 1, 0)),
- Interaction = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZMHD", 1, 0)),
- ServiceYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBS", 1, 0)),
- CityTransfer = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZHZ", 1, 0)),
- Platform110 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YB110", 1, 0)),
- NoService = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SMZXBNCS", 1, 0)),
- Iyb = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "IYB", 1, 0))
- }).ToListAsync() ;
- var totalVo = new OrderSourceHeaderVo()
- {
- Time = "合计",
- Phone = data.Sum(x => x.Phone),
- Web = data.Sum(x => x.Web),
- Rests = data.Sum(x => x.Rests),
- Created = data.Sum(x => x.Created),
- WeChat = data.Sum(x => x.WeChat),
- App = data.Sum(x => x.App),
- WisdomYB = data.Sum(x => x.WisdomYB),
- Platform = data.Sum(x => x.Platform),
- Platform12328 = data.Sum(x => x.Platform12328),
- MayorAndNetizens = data.Sum(x => x.MayorAndNetizens),
- MediaYB = data.Sum(x => x.MediaYB),
- Platform12345 = data.Sum(x => x.Platform12345),
- Interaction = data.Sum(x => x.Interaction),
- ServiceYB = data.Sum(x => x.ServiceYB),
- CityTransfer = data.Sum(x => x.CityTransfer),
- Platform110 = data.Sum(x => x.Platform110),
- NoService = data.Sum(x => x.NoService),
- Iyb = data.Sum(x => x.Iyb)
- };
- data.Add(totalVo);
- return data;
- }
- public ISugarQueryable<Order> QueryOrderSourceDetail(QueryOrderSourceDetailRequest dto) {
-
- return _orderRepository.Queryable()
- .WhereIF(string.IsNullOrEmpty(dto.SourceChannel),d=>d.SourceChannel == dto.SourceChannel)
- .WhereIF(dto.Time.HasValue,d=>d.CreationTime.ToString("yyyy-MM-dd") == dto.Time.Value.ToString("yyyy-MM-dd"))
- .WhereIF(dto.IdentityType.HasValue, d => d.IdentityType == dto.IdentityType)
- .Where(d => d.SourceChannel != null && d.SourceChannel != "");
- }
- #region private
- /// <summary>
- /// 接受外部工单(除省平台)
- /// </summary>
- /// <param name="dto"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- private async Task<AddOrderResponse> ReceiveOrderFromOtherPlatformAsync(AddOrderDto dto, List<FileDto> files,
- ISessionContext current, CancellationToken cancellationToken)
- {
- if (string.IsNullOrEmpty(dto.ExternalId))
- throw new UserFriendlyException("工单外部编号不能为空");
- var order = await _orderRepository.Queryable()
- .FirstAsync(d => d.ExternalId == dto.ExternalId, cancellationToken);
- if (order == null)
- {
- order = _mapper.Map<Order>(dto);
- order.InitId();
- if (files != null && files.Any())
- order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
- await _orderDomainService.AddAsync(order, cancellationToken: cancellationToken);
- }
- else
- {
- _mapper.Map(dto, order);
- if (files != null && files.Any())
- order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
- await _orderRepository.UpdateAsync(order, cancellationToken);
- }
- return _mapper.Map<AddOrderResponse>(order);
- }
- /// <summary>
- /// 接受省平台工单
- /// </summary>
- private async Task<AddOrderResponse> ReceiveOrderFromProvinceAsync(AddOrderDto dto, List<FileDto> files,
- ISessionContext current, CancellationToken cancellationToken)
- {
- if (string.IsNullOrEmpty(dto.ProvinceNo))
- throw new UserFriendlyException("无效省工单编号");
- var orderExtension = await _orderDomainService.GetOrderExtensionsAsync(dto.ProvinceNo, cancellationToken);
- var order = await _orderRepository.GetAsync(d => d.ProvinceNo == dto.ProvinceNo, cancellationToken);
- if (order is null)
- {
- order = _mapper.Map<Order>(dto);
- order.InitId();
- if (files != null && files.Any())
- order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
- await _orderDomainService.AddAsync(order, cancellationToken: cancellationToken);
- if (orderExtension is not null)
- {
- orderExtension.Id = order.Id;
- if (dto.OrderExtension != null)
- _mapper.Map(dto.OrderExtension, orderExtension);
- await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
- }
- }
- else
- {
- _mapper.Map(dto, order);
- if (files != null && files.Any())
- order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
- await _orderRepository.UpdateAsync(order, cancellationToken);
- if (orderExtension is not null)
- {
- orderExtension.Id = order.Id;
- if (dto.OrderExtension != null)
- _mapper.Map(dto.OrderExtension, orderExtension);
- await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
- }
- //特提(撤回至发起)
- if (!string.IsNullOrEmpty(order.WorkflowId))
- await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, "省工单重派", current, cancellationToken);
- }
- return _mapper.Map<AddOrderResponse>(order);
- }
- #endregion
- }
|