12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002 |
- using DotNetCore.CAP;
- using Hotline.Application.FlowEngine;
- using Hotline.Caching.Interfaces;
- using Hotline.File;
- using Hotline.FlowEngine.Definitions;
- using Hotline.FlowEngine.Workflows;
- using Hotline.Orders;
- using Hotline.Orders.Notifications;
- using Hotline.Permissions;
- using Hotline.Quality;
- using Hotline.Repository.SqlSugar.Extensions;
- using Hotline.Repository.SqlSugar.Ts;
- using Hotline.Settings;
- using Hotline.Settings.Hotspots;
- using Hotline.Settings.TimeLimits;
- using Hotline.Share.Dtos;
- using Hotline.Share.Dtos.FlowEngine;
- 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.Mq;
- using Hotline.Share.Requests;
- using MapsterMapper;
- using MediatR;
- using Microsoft.AspNetCore.Mvc;
- using SqlSugar;
- using Hotline.FlowEngine.WorkflowModules;
- using Hotline.Share.Enums.FlowEngine;
- using XF.Domain.Authentications;
- using XF.Domain.Constants;
- using XF.Domain.Exceptions;
- using XF.Domain.Repository;
- using XF.Utility.EnumExtensions;
- using Hotline.CallCenter.Calls;
- using Hotline.DataSharing.Province.Services;
- using Hotline.Share.Dtos.File;
- namespace Hotline.Api.Controllers;
- /// <summary>
- /// 工单
- /// </summary>
- public class OrderController : BaseController
- {
- private readonly IOrderDomainService _orderDomainService;
- private readonly IOrderRepository _orderRepository;
- private readonly IWorkflowApplication _workflowApplication;
- private readonly IWorkflowDomainService _workflowDomainService;
- private readonly IRepository<Hotspot> _hotspotTypeRepository;
- private readonly ISystemOrganizeRepository _organizeRepository;
- private readonly IDefinitionDomainService _definitionDomainService;
- private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
- private readonly ISessionContext _sessionContext;
- private readonly IMapper _mapper;
- private readonly IMediator _mediator;
- private readonly IRepository<OrderPublish> _orderPublishRepository;
- private readonly IRepository<OrderVisit> _orderVisitRepository;
- private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
- private readonly ICapPublisher _capPublisher;
- private readonly IProvinceService _provinceService;
- private readonly IRepository<OrderDelay> _orderDelayRepository;
- private readonly ITimeLimitDomainService _timeLimitDomainService;
- private readonly ISystemSettingCacheManager _systemSettingCacheManager;
- private readonly IRepository<OrderRedo> _orderRedoRepository;
- private readonly IRepository<OrderSupervise> _orderSuperviseRepository;
- private readonly IRepository<OrderUrge> _orderUrgeRepository;
- private readonly IFileRepository _fileRepository;
- private readonly IRepository<OrderScreen> _orderScreenRepository;
- private readonly IRepository<OrderPublishHistory> _orderPublishHistoryRepository;
- private readonly IRepositoryTextSearch<OrderTs> _repositoryts;
- private readonly IQualityRepository _qualityRepository;
- private readonly IRepository<Workflow> _workflowRepository;
- private readonly IRepository<WorkflowStep> _workflowStepRepository;
- private readonly ICitizenRepository _citizenRepository;
- private readonly IRepository<CitizenLabelDetail> _labelDetailRepository;
- private readonly IRepository<RepeatableEvent> _repeatableEventRepository;
- private readonly IRepeatableEventDetailRepository _repeatableEventDetailRepository;
- private readonly IRepository<OrderWord> _orderWrodRepository;
- private readonly IRepository<OrderObserve> _orderObserveRepository;
- private readonly IRepository<OrderVisitApply> _orderVisitApplyRepository;
- private readonly IRepository<OrderFinality> _orderFinalityRepository;
- private readonly IRepository<OrderSendBack> _orderSendBackRepository;
- private readonly IRepository<OrderSpecial> _orderSpecialRepository;
- private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
- private readonly IRepository<TrCallRecord> _trCallRecordRepository;
- private readonly ILogger<OrderController> _logger;
- public OrderController(
- IOrderDomainService orderDomainService,
- IOrderRepository orderRepository,
- IWorkflowApplication workflowApplication,
- IWorkflowDomainService workflowDomainService,
- IRepository<Hotspot> hotspotTypeRepository,
- ISystemOrganizeRepository organizeRepository,
- IDefinitionDomainService definitionDomainService,
- ISystemDicDataCacheManager sysDicDataCacheManager,
- ISessionContext sessionContext,
- IMapper mapper,
- IMediator mediator,
- IRepository<OrderPublish> orderPublishRepository,
- IRepository<OrderVisit> orderVisitRepository,
- IRepository<OrderVisitDetail> orderVisitedDetailRepository,
- ICapPublisher capPublisher,
- IProvinceService provinceService,
- IRepository<OrderDelay> orderDelayRepository,
- ITimeLimitDomainService timeLimitDomainService,
- ISystemSettingCacheManager systemSettingCacheManager,
- IRepository<OrderRedo> orderRedoRepository,
- IRepository<OrderSupervise> orderSuperviseRepository,
- IRepository<OrderUrge> orderUrgeRepository,
- IFileRepository fileRepository,
- IRepository<OrderScreen> orderScreenRepository,
- IRepository<OrderPublishHistory> orderPublishHistoryRepository,
- IRepositoryTextSearch<OrderTs> repositoryts,
- IQualityRepository qualityRepository,
- IRepository<Workflow> workflowRepository,
- IRepository<WorkflowStep> workflowStepRepository,
- ICitizenRepository citizenRepository,
- IRepository<CitizenLabelDetail> labelDetailRepository,
- IRepository<RepeatableEvent> repeatableEventRepository,
- IRepeatableEventDetailRepository repeatableEventDetailRepository,
- IRepository<OrderWord> orderWrodRepository,
- IRepository<OrderObserve> orderObserveRepository,
- IRepository<OrderFinality> orderFinalityRepository,
- IRepository<OrderVisitApply> orderVisitApplyRepository,
- IRepository<OrderSendBack> orderSendBackRepository,
- IRepository<OrderSpecial> orderSpecialRepository,
- IRepository<WorkflowTrace> workflowTraceRepository,
- IRepository<TrCallRecord> trCallRecordRepository,
- ILogger<OrderController> logger)
- {
- _orderDomainService = orderDomainService;
- _orderRepository = orderRepository;
- _workflowApplication = workflowApplication;
- _workflowDomainService = workflowDomainService;
- _hotspotTypeRepository = hotspotTypeRepository;
- _organizeRepository = organizeRepository;
- _definitionDomainService = definitionDomainService;
- _sysDicDataCacheManager = sysDicDataCacheManager;
- _sessionContext = sessionContext;
- _mapper = mapper;
- _mediator = mediator;
- _orderPublishRepository = orderPublishRepository;
- _orderVisitRepository = orderVisitRepository;
- _orderVisitedDetailRepository = orderVisitedDetailRepository;
- _capPublisher = capPublisher;
- _provinceService = provinceService;
- _orderDelayRepository = orderDelayRepository;
- _timeLimitDomainService = timeLimitDomainService;
- _systemSettingCacheManager = systemSettingCacheManager;
- _orderRedoRepository = orderRedoRepository;
- _orderSuperviseRepository = orderSuperviseRepository;
- _orderUrgeRepository = orderUrgeRepository;
- _fileRepository = fileRepository;
- _orderScreenRepository = orderScreenRepository;
- _orderPublishHistoryRepository = orderPublishHistoryRepository;
- _repositoryts = repositoryts;
- _qualityRepository = qualityRepository;
- _workflowRepository = workflowRepository;
- _workflowStepRepository = workflowStepRepository;
- _citizenRepository = citizenRepository;
- _labelDetailRepository = labelDetailRepository;
- _repeatableEventRepository = repeatableEventRepository;
- _repeatableEventDetailRepository = repeatableEventDetailRepository;
- _orderWrodRepository = orderWrodRepository;
- _orderObserveRepository = orderObserveRepository;
- _orderFinalityRepository = orderFinalityRepository;
- _orderVisitApplyRepository = orderVisitApplyRepository;
- _orderSendBackRepository = orderSendBackRepository;
- _orderSpecialRepository = orderSpecialRepository;
- _workflowTraceRepository = workflowTraceRepository;
- _trCallRecordRepository = trCallRecordRepository;
- _logger = logger;
- }
- #region 工单发布
- /// <summary>
- /// 查询(工单发布)
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("publish")]
- public async Task<PagedDto<PublishDto>> PublishOrderList([FromQuery] QueryOrderPublishDto dto)
- {
- var (total, items) = await _orderRepository.Queryable()
- .Includes(d => d.OrderPublish)
- .Where(x => x.Status == EOrderStatus.Filed)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
- .WhereIF(dto.PubState == EPubState.Pub, d => d.Status >= EOrderStatus.Published)
- .WhereIF(dto.PubState == EPubState.NoPub, d => d.Status < EOrderStatus.Published)
- .WhereIF(!string.IsNullOrEmpty(dto.PubMan),
- d => d.Acceptor.Name.Contains(dto.PubMan!) || d.Acceptor.StaffNo.Contains(dto.PubMan!))
- .WhereIF(dto.PubRange == EPublicState.Pub, d => d.OrderPublish.PublishState)
- .WhereIF(dto.PubRange == EPublicState.NoPub, d => !d.OrderPublish.PublishState)
- .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptType))
- .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId))
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .WhereIF(dto.FiledTimeStart.HasValue, d => d.OrderPublish.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.FiledTimeEnd.HasValue, d => d.OrderPublish.CreationTime <= dto.CreationTimeEnd)
- .OrderBy(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<PublishDto>(total, _mapper.Map<IReadOnlyList<PublishDto>>(items));
- }
- /// <summary>
- /// 发布工单
- /// </summary>
- /// <returns></returns>
- [Permission(EPermission.PublishOrder)]
- [HttpPost("publish")]
- public async Task PublishOrder([FromBody] PublishOrderDto dto)
- {
- //验证订单
- var order = await _orderRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("未找到工单,无法发布");
- //新增发布工单
- OrderPublish orderPublish = new OrderPublish();
- orderPublish.OrderId = order.Id;
- orderPublish.No = order.No;
- orderPublish.PublishState = dto.PublishState;
- orderPublish.ArrangeTitle = dto.ArrangeTitle;
- orderPublish.ArrangeContent = dto.ArrangeContent;
- orderPublish.ArrangeOpinion = dto.ArrangeOpinion;
- orderPublish.ProPublishState = dto.ProPublishState;
- orderPublish.FeedBackPhone = dto.FeedBackPhone;
- orderPublish.NoPubReason = dto.NoPubReason;
- orderPublish.CreatorName = _sessionContext.UserName;
- string id = await _orderPublishRepository.AddAsync(orderPublish);
- order.Publish(orderPublish.PublishState);
- await _orderRepository.UpdateAsync(order);
- //TODO 推省上
- try
- {
- var publishPublishOrder = _mapper.Map<PublishPublishOrderDto>(orderPublish);
- publishPublishOrder.Order = _mapper.Map<OrderDto>(order);
- }
- catch {}
- var orderVisit = new OrderVisit();
- orderVisit.No = order.No;
- orderVisit.OrderId = order.Id;
- orderVisit.VisitState = EVisitState.WaitForVisit;
- orderVisit.PublishTime = DateTime.Now;
- orderVisit.IsCanHandle = true;
- if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null })
- {
- orderVisit.VisitState = EVisitState.Visited;
- }
- string visitId = await _orderVisitRepository.AddAsync(orderVisit);
- //新增回访信息
- var visitedDetail = new List<OrderVisitDetail>();
- var seatDetail = new OrderVisitDetail();
- seatDetail.VisitId = visitId;
- seatDetail.VisitTarget = EVisitTarget.Seat;
- foreach (var item in dto.IdNames)
- {
- var orgDetail = new OrderVisitDetail();
- orgDetail.VisitId = visitId;
- orgDetail.VisitOrgCode = item.Key;
- orgDetail.VisitOrgName = item.Value;
- orgDetail.VisitTarget = EVisitTarget.Org;
- if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null })
- {
- var satisfy = new Kv() { Key = "4", Value = "满意" };
- orgDetail.OrgProcessingResults = satisfy;
- orgDetail.OrgHandledAttitude = satisfy;
- }
- visitedDetail.Add(orgDetail);
- }
- if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null })
- {
- seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
- seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
- order.Visited("4", "满意");
- order.Status = EOrderStatus.Visited;
- await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
- }
- visitedDetail.Add(seatDetail);
- await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, HttpContext.RequestAborted);
-
- }
- /// <summary>
- /// 发布页面基础信息
- /// </summary>
- /// <returns></returns>
- [HttpGet("publish-order-pagebase/{id}")]
- public async Task<PublishOrderPageBaseDto> PublishOrderPageBase(string id)
- {
- var order = await _orderRepository.Queryable()
- .Includes(d => d.Acceptor)
- .Includes(d => d.OrderExtension)
- .FirstAsync(d => d.Id == id);
- if (order is null)
- throw UserFriendlyException.SameMessage("未知工单,无法发布");
- var res = new PublishOrderPageBaseDto()
- {
- SourceChannel = order.SourceChannel,
- OrderTitle = order.Title,
- Content = order.Content,
- ActualOpinion = order.ActualOpinion
- };
- var (idName, idNames) =
- await _workflowDomainService.GetUnvisitOrgsAsync(order.WorkflowId, HttpContext.RequestAborted);
- res.ActualHandleOrgName = idName;
- res.idNames = idNames.ToList();
- return res;
- }
- /// <summary>
- /// 已发布列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.PublishedOrderList)]
- [HttpGet("published")]
- public async Task<PagedDto<PublishedDto>> PublishedOrderList([FromQuery] PagedKeywordRequest dto)
- {
- var (total, items) = await _orderPublishRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .OrderBy(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<PublishedDto>(total, _mapper.Map<IReadOnlyList<PublishedDto>>(items));
- }
- /// <summary>
- /// 发布详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.PublishedOrder)]
- [HttpGet("published-order/{id}")]
- public async Task<PublishedEntityDto> PublishedOrder(string id)
- {
- var publishedOrder = await _orderPublishRepository.GetAsync(id, HttpContext.RequestAborted);
- if (publishedOrder is null)
- {
- throw UserFriendlyException.SameMessage("未知数据!");
- }
- var pubentity = _mapper.Map<PublishedEntityDto>(publishedOrder);
- var visit = await _orderVisitRepository.Queryable().Includes(x => x.OrderVisitDetails)
- .OrderByDescending(x => x.CreationTime)
- .FirstAsync(x => x.OrderId == publishedOrder.OrderId, HttpContext.RequestAborted);
- if (visit != null)
- {
- var details = visit.OrderVisitDetails.Where(x => x.VisitTarget == EVisitTarget.Org).ToList();
- if (details != null && details.Count > 0)
- {
- pubentity.IdNames = new List<Kv>();
- details.ForEach(f => pubentity.IdNames.Add(new Kv() { Key = f.VisitOrgCode, Value = f.VisitOrgName }));
- }
- }
- return pubentity;
- }
- /// <summary>
- /// 修改发布内容
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.PublishedModify)]
- [HttpPost("published-order-modify")]
- public async Task PublishedModify([FromBody] PublishOrderModifyDto dto)
- {
- var publishOrder = await _orderPublishRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (publishOrder is null)
- {
- throw UserFriendlyException.SameMessage("无效数据");
- }
- var history = new OrderPublishHistory();
- history.ArrangeTitleBefor = publishOrder.ArrangeTitle;
- history.ArrangeTitleAfter = dto.ArrangeTitle;
- history.ArrangeContentBefor = publishOrder.ArrangeContent;
- history.ArrangeContentAfter = dto.ArrangeContent;
- history.ArrangeOpinionBefor = publishOrder.ArrangeOpinion;
- history.ArrangeOpinionAfter = dto.ArrangeOpinion;
- history.No = publishOrder.No;
- history.OrderId = publishOrder.OrderId;
- history.OrderPublishId = publishOrder.Id;
- publishOrder.ArrangeTitle = dto.ArrangeTitle;
- publishOrder.ArrangeContent = dto.ArrangeContent;
- publishOrder.ArrangeOpinion = dto.ArrangeOpinion;
- await _orderPublishRepository.UpdateAsync(publishOrder, HttpContext.RequestAborted);
- await _orderPublishHistoryRepository.AddAsync(history, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 发布修改记录
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("published-history-list/{id}")]
- public async Task<List<OrderPublishHistory>> QueryPublishedHistory(string id)
- {
- return await _orderPublishHistoryRepository.Queryable().Where(x => x.OrderPublishId == id)
- .OrderByDescending(x => x.CreationTime).ToListAsync(HttpContext.RequestAborted);
- }
- #endregion
- #region 工单回访
- /// <summary>
- /// 回访列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("visit")]
- public async Task<PagedDto<OrderVisitDto>> QueryOrderVisitList([FromQuery] QueryOrderVisitDto dto)
- {
- var (total, items) = await _orderVisitRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .Includes(x => x.OrderVisitDetails)
- .WhereIF(dto.VisitState == EVisitStateQuery.NoVisit,
- x => (x.VisitState == Share.Enums.Order.EVisitState.WaitForVisit ||
- x.VisitState == Share.Enums.Order.EVisitState.NoSatisfiedWaitForVisit) && x.Order.IsProvince == false)
- .WhereIF(dto.VisitState == EVisitStateQuery.Visited,
- x => x.VisitState == Share.Enums.Order.EVisitState.Visited)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.Order.Title.Contains(dto.Keyword!) || x.Order.No.Contains(dto.Keyword!))
- .OrderBy(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderVisitDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDto>>(items));
- }
- /// <summary>
- /// 回访详情
- /// </summary>
- /// <returns></returns>
- [HttpGet("visit/{id}")]
- public async Task<object> VisitInfo(string id)
- {
- var orderVisit = await _orderVisitRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .Includes(x => x.OrderVisitDetails.OrderBy(d=>d.VisitTarget).ToList())
- .FirstAsync(x => x.Id == id, HttpContext.RequestAborted);
- if (orderVisit is null)
- {
- throw UserFriendlyException.SameMessage("未知工单回访");
- }
- int visitCount = await _orderVisitRepository.CountAsync(
- x => x.OrderId == orderVisit.OrderId && x.VisitState == Share.Enums.Order.EVisitState.Visited,
- HttpContext.RequestAborted);
- //int againCount = await _orderVisitRepository.CountAsync(
- // x => x.OrderId == orderVisit.OrderId && x.AgainState == EAgainState.DoAgain, HttpContext.RequestAborted);
- var voiceEvaluate = EnumExts.GetDescriptions<EVoiceEvaluate>();
- var seatEvaluate = EnumExts.GetDescriptions<ESeatEvaluate>();
- var visitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction);
- var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);
- var visitManner = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitManner);
- var callRecord = await _trCallRecordRepository.GetAsync(x => x.CallAccept == orderVisit.Order.CallId);
- var recordingFileUrl = "";
- if (callRecord!= null)
- {
- recordingFileUrl = callRecord.RecordingFileUrl;
- }
-
- return new
- {
- OrderVisitModel = _mapper.Map<OrderVisitDto>(orderVisit),
- VisitCount = visitCount,
- //AgainCount = againCount,
- VisitSatisfaction = visitSatisfaction,
- DissatisfiedReason = dissatisfiedReason,
- VisitManner = visitManner,
- ViceEvaluate = voiceEvaluate,
- SeatEvaluate = seatEvaluate,
- RecordingFileUrl = recordingFileUrl
- };
- }
- /// <summary>
- /// 回访明细
- /// </summary>
- /// <returns></returns>
- [HttpGet("visit/detail")]
- public async Task<PagedDto<OrderVisitDetailDto>> VisitDetailList([FromQuery] VisitDetailListDto dto)
- {
- var (total, items) = await _orderVisitedDetailRepository.Queryable()
- .Includes(x => x.OrderVisit, s => s.Order)
- .WhereIF(dto.VisitState == EVisitStateQuery.NoVisit,
- x => x.OrderVisit.VisitState == Share.Enums.Order.EVisitState.WaitForVisit || x.OrderVisit.VisitState ==
- Share.Enums.Order.EVisitState.NoSatisfiedWaitForVisit)
- .WhereIF(dto.VisitState == EVisitStateQuery.Visited,
- x => x.OrderVisit.VisitState == Share.Enums.Order.EVisitState.Visited)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.OrderVisit.Order.Title.Contains(dto.Keyword!) || d.OrderVisit.Order.No.Contains(dto.Keyword!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
- }
- /// <summary>
- /// 回访保存
- /// </summary>
- /// <returns></returns>
- [Permission(EPermission.Visit)]
- [HttpPost("visit")]
- public async Task Visit([FromBody] VisitDto dto)
- {
- //var visit = await _orderVisitRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- var visit = await _orderVisitRepository.Queryable()
- .Includes(d => d.Order)
- .Includes(d => d.OrderVisitDetails)
- .FirstAsync(d => d.Id == dto.Id, HttpContext.RequestAborted);
- if (visit is null)
- throw UserFriendlyException.SameMessage("未知回访信息");
- if (visit.VisitState == EVisitState.Visited)
- throw UserFriendlyException.SameMessage("已回访,不能重复回访");
- var first = dto.VisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org);
- visit.IsPutThrough = dto.IsPutThrough;
- visit.AgainState = dto.IsAgain ? EAgainState.NeedAgain : EAgainState.NoAgain;
- visit.EmployeeId = _sessionContext.UserId;
- if (first != null)
- {
- visit.NowEvaluate = first.OrgProcessingResults;
- }
- //update order
- if (dto.IsPutThrough)
- {
- visit.VisitState = Share.Enums.Order.EVisitState.Visited;
- visit.VisitTime = DateTime.Now;
- visit.VisitType = EVisitType.ArtificialVisit;
- if (first != null)
- {
- visit.Order.Visited(first.OrgProcessingResults.Key, first.OrgProcessingResults.Value);
- }
- //_mapper.Map(dto.VisitDetails,visit.OrderVisitDetails);
- for (int i = 0; i < visit.OrderVisitDetails.Count; i++)
- {
- var detail = visit.OrderVisitDetails[i];
- var detaildto = dto.VisitDetails.FirstOrDefault(x => x.Id == detail.Id);
- if (detaildto != null)
- {
- _mapper.Map(detaildto, visit.OrderVisitDetails[i]);
- }
- }
- await _orderVisitRepository.UpdateAsync(visit, HttpContext.RequestAborted);
- await _orderVisitedDetailRepository.UpdateRangeAsync(visit.OrderVisitDetails, HttpContext.RequestAborted);
- await _orderRepository.UpdateAsync(visit.Order, HttpContext.RequestAborted);
- var orderDto = _mapper.Map<OrderDto>(visit.Order);
- if (first != null)
- {
- //推省上
- //_capPublisher.Publish(EventNames.HotlineOrderVisited,
- // new PublishVisitDto()
- // {
- // Order = orderDto,
- // No = visit.No,
- // VisitType = visit.VisitType,
- // VisitName = visit.CreatorName,
- // VisitTime = visit.VisitTime,
- // VisitRemark = first.VisitContent,
- // AreaCode = visit.Order.AreaCode!,
- // SubjectResultSatifyCode = first.OrgProcessingResults.Key,
- // FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
- // ClientGuid = ""
- // });
- try
- {
- await _provinceService.SubmitVisitInfo(new PublishVisitDto()
- {
- Order = orderDto,
- No = visit.No,
- VisitType = visit.VisitType,
- VisitName = visit.CreatorName,
- VisitTime = visit.VisitTime,
- VisitRemark = first.VisitContent,
- AreaCode = visit.Order.AreaCode!,
- SubjectResultSatifyCode = first.OrgProcessingResults.Key,
- FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
- ClientGuid = ""
- }, HttpContext.RequestAborted);
- }
- catch (Exception e)
- {
- _logger.LogError("_provinceService.SubmitVisitInfo throw exception: {ex}", e.Message);
- }
- }
- if (first != null)
- {
- //写入质检
- await _qualityRepository.AddQualityAsync(EQualitySource.Visit, visit.Order.Id, visit.Id,
- HttpContext.RequestAborted);
- }
- }
- else { await _orderVisitRepository.UpdateAsync(visit, HttpContext.RequestAborted); }
- }
- /// <summary>
- /// 批量分配回访人员
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("visit/distribution")]
- public async Task<DistributionVisitRspDto> DistributionVisit([FromBody] DistributionVisitDto dto)
- {
- int error = 0;
- foreach (var id in dto.Ids)
- {
- var visit = await _orderVisitRepository.Queryable().FirstAsync(d => d.Id == id, HttpContext.RequestAborted);
- if (visit != null && visit.VisitState != EVisitState.WaitForVisit)
- {
- visit.EmployeeId = dto.EmployeeId;
- await _orderVisitRepository.UpdateAsync(visit, HttpContext.RequestAborted);
- }
- else
- {
- error++;
- }
- }
- return new DistributionVisitRspDto() { ErrorCount = error, SuccessCount = dto.Ids.Count - error };
- }
- #endregion
- #region 二次回访申请
- /// <summary>
- /// 可二次回访申请列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderVisitAgainList)]
- [HttpGet("visitapply/visitagainlist")]
- public async Task<PagedDto<OrderCanVisitAgainDto>> OrderVisitAgainList([FromQuery] OrderVisitAgainListDto dto)
- {
- var (total, items) = await _orderVisitedDetailRepository.Queryable()
- .Includes(x => x.OrderVisit, x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderVisit.Order.No.Contains(dto.Keyword))
- .Where(x => x.OrderVisit.VisitState == EVisitState.Visited &&
- (x.OrderVisit.VisitType == EVisitType.SmsVisit ||
- x.OrderVisit.VisitType == EVisitType.ChipVoiceVisit))
- .Where(x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
- SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2")
- .Where(x => x.OrderVisit.IsCanHandle)
- .Where(x => x.VisitTarget == EVisitTarget.Org)
- .OrderByDescending(x => x.OrderVisit.VisitTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderCanVisitAgainDto>(total, _mapper.Map<IReadOnlyList<OrderCanVisitAgainDto>>(items));
- }
- /// <summary>
- /// 二次回访申请
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- /// <exception cref="UserFriendlyException"></exception>
- [Permission(EPermission.ApplyOrderVisit)]
- [HttpPost("visitapply/add")]
- public async Task ApplyOrderVisit([FromBody] AddVisitApplyDto dto)
- {
- var orderVisitApply = _mapper.Map<OrderVisitApply>(dto);
- //验证是否可以申请二次回访
- var isAny = await _orderVisitApplyRepository.AnyAsync(
- x => x.OrderId == orderVisitApply.OrderId && x.VisitApplyState != EVisitApplyState.NoPass,
- HttpContext.RequestAborted);
- if (isAny)
- throw UserFriendlyException.SameMessage("当前状态不能申请二次回访");
- var orderModel =
- await _orderRepository.GetAsync(x => x.Id == orderVisitApply.OrderId, HttpContext.RequestAborted);
- if (orderModel?.CounterSignType != null)
- throw UserFriendlyException.SameMessage("会签件不能申请二次回访");
- var orderVisitModel = await _orderVisitRepository.GetAsync(x => x.Id == dto.OrderVisitId && x.IsCanHandle,
- HttpContext.RequestAborted);
- if (orderVisitModel == null)
- throw UserFriendlyException.SameMessage("当前状态不能进行二次回访");
- orderVisitModel.IsCanHandle = false;
- await _orderVisitRepository.UpdateAsync(orderVisitModel, HttpContext.RequestAborted);
- orderVisitApply.EmployeeId = _sessionContext.RequiredUserId;
- orderVisitApply.VisitApplyState = EVisitApplyState.Examining;
- await _orderVisitApplyRepository.AddAsync(orderVisitApply, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 二次回访审核
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ExaminOrderVisit)]
- [HttpPost("visitapply/examin")]
- public async Task ExaminOrderVisit([FromBody] ExaminOrderVisitDto dto)
- {
- //获取二次回访申请
- var visitApplyModel = await _orderVisitApplyRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (visitApplyModel == null)
- throw UserFriendlyException.SameMessage("无效申请");
- if (visitApplyModel.VisitApplyState != EVisitApplyState.Examining)
- throw UserFriendlyException.SameMessage("当前状态不能审核");
- if (dto.IsPass)
- visitApplyModel.VisitApplyState = EVisitApplyState.Pass;
- else
- visitApplyModel.VisitApplyState = EVisitApplyState.NoPass;
- visitApplyModel.ExaminOpinion = dto.ExaminOpinion;
- visitApplyModel.ExaminManId = _sessionContext.RequiredUserId;
- visitApplyModel.ExaminTime = DateTime.Now;
- await _orderVisitApplyRepository.UpdateAsync(visitApplyModel, HttpContext.RequestAborted);
- //TODO 处理通过后的业务
- if (dto.IsPass)
- {
- //处理申请单
- visitApplyModel.VisitApplyState = EVisitApplyState.Pass;
- await _orderVisitApplyRepository.UpdateAsync(visitApplyModel, HttpContext.RequestAborted);
- //处理原回访数据
- var visitModel =
- await _orderVisitRepository.GetAsync(visitApplyModel.OrderVisitId, HttpContext.RequestAborted);
- if (visitModel != null)
- {
- visitModel.VisitState = EVisitState.None;
- await _orderVisitRepository.UpdateAsync(visitModel, HttpContext.RequestAborted);
- //处理新回访数据
- //查询原回访数据子表
- var visitModelNew = _mapper.Map<OrderVisit>(visitModel);
- visitModelNew.InitId();
- visitModelNew.CreationTime = DateTime.Now;
- visitModelNew.CreatorId = string.Empty;
- visitModelNew.CreatorName = string.Empty;
- visitModelNew.CreatorOrgId = string.Empty;
- visitModelNew.CreatorOrgName = string.Empty;
- visitModelNew.CreatorOrgLevel = 0;
- visitModelNew.AreaId = string.Empty;
- visitModelNew.VisitState = EVisitState.WaitForVisit;
- visitModelNew.IsCanHandle = false;
- var id = await _orderVisitRepository.AddAsync(visitModelNew, HttpContext.RequestAborted);
- var visitModelDetail = await _orderVisitedDetailRepository.Queryable()
- .Where(x => x.VisitId == visitModel.Id).ToListAsync(HttpContext.RequestAborted);
- var visitDetailListNew = new List<OrderVisitDetail>();
- foreach (var item in visitModelDetail)
- {
- var visitDetail = new OrderVisitDetail();
- visitDetail.VisitId = id;
- visitDetail.VisitOrgCode = item.VisitOrgCode;
- visitDetail.VisitOrgName = item.VisitOrgName;
- visitDetail.VisitTarget = item.VisitTarget;
- visitDetailListNew.Add(visitDetail);
- }
- await _orderVisitedDetailRepository.AddRangeAsync(visitDetailListNew, HttpContext.RequestAborted);
- }
- }
- else
- {
- //处理申请单
- visitApplyModel.VisitApplyState = EVisitApplyState.NoPass;
- visitApplyModel.ExaminManId = _sessionContext.RequiredUserId;
- visitApplyModel.ExaminOpinion = dto.ExaminOpinion;
- visitApplyModel.ExaminTime = DateTime.Now;
- await _orderVisitApplyRepository.UpdateAsync(visitApplyModel, HttpContext.RequestAborted);
- var visitModel =
- await _orderVisitRepository.GetAsync(visitApplyModel.OrderVisitId, HttpContext.RequestAborted);
- if (visitModel != null)
- {
- visitModel.IsCanHandle = true;
- await _orderVisitRepository.UpdateAsync(visitModel, HttpContext.RequestAborted);
- }
- }
- }
- /// <summary>
- /// 二次回访申请列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.VisitApplyList)]
- [HttpGet("visitapply/list")]
- public async Task<PagedDto<VisitApplyDto>> VisitApplyList([FromQuery] VisitApplyListDto dto)
- {
- var (total, items) = await _orderVisitApplyRepository.Queryable()
- .Includes(d => d.Order)
- .Includes(d => d.OrderVisit, d => d.OrderVisitDetails.Where(x => x.VisitTarget == EVisitTarget.Org).ToList())
- .Includes(d => d.OrderVisit, d => d.Employee)
- .Includes(d => d.Employee)
- .WhereIF(dto.VisitApplyState != null, x => x.VisitApplyState == dto.VisitApplyState)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.OrderNo.Contains(dto.Keyword))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<VisitApplyDto>(total, _mapper.Map<IReadOnlyList<VisitApplyDto>>(items));
- }
- /// <summary>
- /// 获取二次回访申请
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("visitapply/{id}")]
- public async Task<VisitApplyDto> VisitApplyEntity(string id)
- {
- var model = await _orderVisitApplyRepository.GetExtAsync(x => x.Id == id, x => x.Includes(d => d.Order));
- return _mapper.Map<VisitApplyDto>(model);
- }
- /// <summary>
- /// 页面基础信息
- /// </summary>
- /// <returns></returns>
- [HttpGet("visitapply/basedata")]
- public async Task<object> VisitApplyBaseData()
- {
- var rsp = new
- {
- VisitApplyState = EnumExts.GetDescriptions<EVisitApplyState>()
- };
- return rsp;
- }
- #endregion
- #region 工单重办
- /// <summary>
- /// 重办查询
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("redo")]
- public async Task<PagedDto<OrderRedo>> QueryOrderRedo([FromQuery] QueryOrderRedoRecordDto dto)
- {
- var (total, items) = await _orderRedoRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderRedo>(total, items);
- }
- /// <summary>
- /// 重办详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("redo/{id}")]
- public async Task<OrderRedo> GetOrderRedo(string id)
- {
- return await _orderRedoRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- }
- /// <summary>
- /// 发起重办
- /// </summary>
- [HttpPost("redo")]
- public async Task<string> AddRedo([FromBody] OrderRedoStartFlowDto dto)
- {
- var redo = _mapper.Map<OrderRedo>(dto.Data);
- redo.CreatorName = _sessionContext.UserName ?? string.Empty;
- redo.CreatorOrgName = _sessionContext.OrgName ?? string.Empty;
- //redo.TimeLimitCount = dto.Workflow.Extension.TimeLimitCount;
- //redo.TimeLimitUnit = dto.Workflow.Extension.TimeLimitUnit;
- //todo
- var handler = dto.Workflow.NextHandlers.First();
- redo.RedoOrgCode = handler.Key;
- redo.RedoOrgCode = handler.Value;
- var id = await _orderRedoRepository.AddAsync(redo, HttpContext.RequestAborted);
- try
- {
- var order = await _orderRepository.GetAsync(dto.Data.OrderId, HttpContext.RequestAborted);
- if (order == null)
- throw UserFriendlyException.SameMessage("无效工单编号");
- if (string.IsNullOrEmpty(order.WorkflowId))
- throw UserFriendlyException.SameMessage("无效工单流程编号");
- var redoFlowDto = _mapper.Map<RecallDto>(dto.Workflow);
- redoFlowDto.WorkflowId = order.WorkflowId;
- await _workflowApplication.RedoAsync(redoFlowDto, HttpContext.RequestAborted);
- return id;
- }
- catch (Exception e)
- {
- await _orderRedoRepository.RemoveAsync(id, cancellationToken: HttpContext.RequestAborted);
- throw new UserFriendlyException($"发起重办失败,{e.Message}");
- }
- }
- /// <summary>
- /// 重办基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data-redo")]
- public async Task<dynamic> BaseDataRedo()
- {
- var rsp = new
- {
- OrderRedoReasonOptions = EnumExts.GetDescriptions<EOrderRedoReason>(),
- };
- return rsp;
- }
- #endregion
- #region 工单延期
- /// <summary>
- /// 可申请延期工单
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("candelay")]
- public async Task<PagedDto<OrderDto>> CanDelayOrderList([FromQuery] CanDelayOrderListDto dto)
- {
- var (total, items) = await _orderRepository.Queryable()
- .Includes(d => d.Acceptor)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
- .Where(d => d.Status != EOrderStatus.WaitForAccept && d.Status != EOrderStatus.Filed &&
- SqlFunc.Subqueryable<OrderDelay>()
- .Where(s => s.OrderId == d.Id && s.DelayState == EDelayState.Examining).NotAny())
- .OrderByDescending(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 申请延期
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- //[Permission(EPermission.ApplyDelay)]
- [HttpPost("delay")]
- public async Task ApplyDelay([FromBody] DelayStartFlowDto dto)
- {
- var delaydto = dto.Data;
- if (string.IsNullOrEmpty(dto.Workflow.Opinion))
- throw UserFriendlyException.SameMessage("办理意见不能为空!");
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(delaydto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- //验证工单是否在办理中
- if (order.Status == EOrderStatus.WaitForAccept || order.Status == EOrderStatus.Filed)
- throw UserFriendlyException.SameMessage("当前工单状态不能申请延期");
- bool IsHas = await _orderDelayRepository.AnyAsync(
- x => x.OrderId == delaydto.OrderId && x.DelayState == EDelayState.Examining, HttpContext.RequestAborted);
- if (IsHas)
- throw UserFriendlyException.SameMessage("该存在延期申请正在审核");
- //验证延期次数
- var setting = _systemSettingCacheManager.GetSetting(SettingConstants.DelayNum);
- int count = await _orderDelayRepository.CountAsync(x => x.OrderId == delaydto.OrderId);
- if (count > int.Parse(setting?.SettingValue[0]))
- throw UserFriendlyException.SameMessage("延期申请已超过系统预定设置,不能申请");
- var model = _mapper.Map<OrderDelay>(delaydto);
- model.EmployeeId = _sessionContext.UserId;
- model.ApplyOrgName = _sessionContext.OrgName;
- model.ApplyOrgCode = _sessionContext.OrgId;
- model.BeforeDelay = order.ExpiredTime;
- model.DelayState = EDelayState.Examining;
- model.DelayReason = dto.Workflow.Opinion;
- if (model.BeforeDelay != null)
- {
- model.AfterDelay = _timeLimitDomainService
- .CalcEndTime(model.BeforeDelay.Value, delaydto.DelayUnit, delaydto.DelayNum, false)?.EndTime; //todo
- }
- model.ApplyDelayTime = DateTime.Now;
- model.No = order.No;
- model.InitId();
- if (dto.Data.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderDelayRepository.AddAsync(model, HttpContext.RequestAborted);
- try
- {
- var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
- startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderDelay;
- startDto.Title = model.DelayReason;
- string workFlowId =
- await _workflowApplication.StartWorkflowAsync(startDto, model.Id,
- cancellationToken: HttpContext.RequestAborted);
- model.WorkflowId = workFlowId;
- await _orderDelayRepository.UpdateAsync(model, HttpContext.RequestAborted);
- }
- catch (Exception ex)
- {
- await _orderDelayRepository.RemoveAsync(model.Id, false, HttpContext.RequestAborted);
- throw new UserFriendlyException($"工单延期流程失败!, {ex.Message}", "工单延期流程失败");
- }
- }
- /// <summary>
- /// 延期列表
- /// </summary>
- /// <returns></returns>
- //[Permission(EPermission.DelayList)]
- [HttpGet("delay")]
- public async Task<PagedDto<OrderDelayDto>> DelayList([FromQuery] DelayListDto dto)
- {
- var (total, items) = await _orderDelayRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .Includes(x => x.Workflow)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.IsApply==true, x => x.DelayState != EDelayState.Examining)
- .WhereIF(dto.IsApply==false, x => x.DelayState == EDelayState.Examining)
- .WhereIF(dto.DelayState != null, x => x.DelayState == dto.DelayState)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDelayDto>(total, _mapper.Map<IReadOnlyList<OrderDelayDto>>(items));
- }
- /// <summary>
- /// 延期详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- //[Permission(EPermission.DelayEntity)]
- [HttpGet("delay/{id}")]
- public async Task<OrderDelayDto> DelayEntity(string id)
- {
- var model = await _orderDelayRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .Includes(x => x.Workflow)
- .FirstAsync(x => x.Id == id);
- var rspModel = _mapper.Map<OrderDelayDto>(model);
- rspModel.IsCanHandle = model.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
- var files = await _fileRepository.Queryable().Where(x => x.Key == rspModel.Id && string.IsNullOrEmpty(x.FlowKey)).ToListAsync();
- if (files.Any()) rspModel.Files = _mapper.Map<List<FileDto>>(files);
- return rspModel;
- }
- /// <summary>
- /// 计算期满时间
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("delay/calc-endtime")]
- public async Task<TimeResult?> DelayCalcEndTime([FromBody] DelayCalcEndTimeDto dto)
- {
- return _timeLimitDomainService.CalcEndTime(dto.BeginTime, dto.DelayUnit, dto.DelayNum, false);
- }
- /// <summary>
- /// 查询工单延期流程开启参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("delay/startflow")]
- public async Task<NextStepsDto> GetDelayFlowStartOptions()
- {
- return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.OrderDelay,
- HttpContext.RequestAborted);
- }
- /// <summary>
- /// 延期页面基础信息
- /// </summary>
- /// <returns></returns>
- [HttpGet("delay/basedata")]
- public async Task<object> DelayBaseData()
- {
- var rsp = new
- {
- DelayState = EnumExts.GetDescriptions<EDelayState>(),
- TimeType = EnumExts.GetDescriptions<ETimeType>()
- };
- return rsp;
- }
- #endregion
- #region 工单甄别
- /// <summary>
- /// 工单甄别待申请列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.MayOrderScreenList)]
- [HttpGet("mayscreen")]
- public async Task<PagedDto<OrderVisitDetailDto>> MayScreenList([FromQuery] MayScreenListDto dto)
- {
- var query = _orderVisitedDetailRepository.Queryable()
- .Includes(x => x.OrderVisit)
- .Includes(x => x.OrderVisit, y => y.Order)
- .Includes(x => x.OrderVisit, y => y.Employee)
- .Where(x => x.OrderVisit.VisitState != EVisitState.None && x.OrderVisit.IsCanHandle);
- if (_sessionContext.OrgId != null && !_sessionContext.OrgIsCenter)
- {
- query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
- x.OrderVisit.Order.No.Contains(dto.Keyword!))
- .Where(x => x.VisitTarget == EVisitTarget.Org && x.VisitOrgCode.StartsWith(_sessionContext.OrgId) && (
- SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
- SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
- SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
- SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
- ));
- }
- else
- {
- query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
- x.OrderVisit.Order.No.Contains(dto.Keyword!))
- .Where(x => x.VisitTarget == EVisitTarget.Org && (
- SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
- SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
- SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
- SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
- ));
- }
- var (total, items) = await query
- .OrderBy(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
- }
- /// <summary>
- /// 工单甄别列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("screen")]
- public async Task<PagedDto<OrderScreenListDto>> ScreenList([FromQuery] ScreenListDto dto)
- {
- var query = _orderScreenRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.VisitDetail)
- .Includes(x => x.Visit, d => d.Order)
- .Includes(x => x.Workflow)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Visit.Order.Title.Contains(dto.Keyword!) || d.Visit.Order.No.Contains(dto.Keyword!));
- if (dto.Status is EScreenStatus.Apply)
- {
- query.Where(x => (x.Status == EScreenStatus.Apply || x.Status == EScreenStatus.Approval)
- && SqlFunc.JsonListObjectAny(x.Workflow.HandlerUsers, "Key", _sessionContext.RequiredUserId));
- }
- var (total, items) = await query
- .WhereIF(dto.Status.HasValue && dto.Status == EScreenStatus.MyHandle,
- x => x.Status != EScreenStatus.Apply && x.CreatorId == _sessionContext.UserId)
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .WhereIF(!string.IsNullOrEmpty(dto.OrderId), x => x.OrderId == dto.OrderId)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderScreenListDto>(total, _mapper.Map<IReadOnlyList<OrderScreenListDto>>(items));
- }
- /// <summary>
- /// 开始工单甄别流程
- /// </summary>
- [Permission(EPermission.ApplyScreen)]
- [HttpPost("screen/startflow")]
- public async Task StartFlow([FromBody] ScreenStartFlowDto dto)
- {
- var screenAny = await _orderScreenRepository.AnyAsync(x =>
- x.VisitDetailId == dto.Data.VisitDetailId &&
- (x.Status == EScreenStatus.Apply || x.Status == EScreenStatus.Approval));
- if (screenAny)
- throw UserFriendlyException.SameMessage("该工单已提起甄别申请,正在审批过程中,不能申请");
- var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ScreenApplyNum);
- int count = await _orderScreenRepository.CountAsync(x =>
- x.OrderId == dto.Data.OrderId && x.Status == EScreenStatus.Refuse);
- if (count > int.Parse(setting?.SettingValue[0]))
- throw UserFriendlyException.SameMessage("甄别申请已超过系统预定设置,不能申请");
- var visit = await _orderVisitRepository.GetAsync(dto.Data.VisitId, HttpContext.RequestAborted);
- setting = _systemSettingCacheManager.GetSetting(SettingConstants.ScreenApplyEndTime);
- var endTime = _timeLimitDomainService
- .CalcEndTime(visit.VisitTime.Value, ETimeType.WorkDay, int.Parse(setting?.SettingValue[0]), false).EndTime;
- if (DateTime.Now > endTime)
- throw UserFriendlyException.SameMessage("甄别申请时限已超过系统预定设置,不能申请");
- var model = _mapper.Map<OrderScreen>(dto.Data);
- model.Status = EScreenStatus.Apply;
- model.ApplyEndTime = endTime;
- model.InitId();
- if (dto.Data.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderScreenRepository.AddAsync(model, HttpContext.RequestAborted);
-
- var workflowId = string.Empty;
- try
- {
- await _orderRepository.OrderScreenRevisionVisit(visit.Id, false, HttpContext.RequestAborted);
- var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
- startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderScreen;
- startDto.Title = dto.Data.Content;
- workflowId =
- await _workflowApplication.StartWorkflowAsync(startDto, model.Id,
- cancellationToken: HttpContext.RequestAborted);
- var screen = await _orderScreenRepository.GetAsync(model.Id, HttpContext.RequestAborted);
- if (screen != null)
- {
- screen.WorkflowId = workflowId;
- await _orderScreenRepository.UpdateAsync(screen, HttpContext.RequestAborted);
- }
- }
- catch (Exception e)
- {
- await _orderScreenRepository.RemoveAsync(model.Id);
- model.Id = string.Empty;
- throw new UserFriendlyException($"工单开启甄别流程失败!, {e.Message}", "工单开启甄别流程失败");
- }
- }
- /// <summary>
- /// 查询工单甄别流程开启参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("screen/startflow")]
- public async Task<NextStepsDto> GetScreenFlowStartOptionsAsync()
- {
- //return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.OrderScreen,
- // HttpContext.RequestAborted);
- return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.OrderScreen,
- HttpContext.RequestAborted);
- }
- /// <summary>
- /// 查询工单甄别流程参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("screen/workflow/{id}")]
- public async Task<string> GetScreenWorkFlowAsync(string id)
- {
- var workflow = await _workflowRepository.Queryable().FirstAsync(x => x.ExternalId == id);
- return workflow.Id;
- }
- /// <summary>
- /// 列表页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("screen/base")]
- public async Task<object> ScreenBaseData()
- {
- var rsp = new
- {
- ScreenStatus = EnumExts.GetDescriptions<EScreenStatus>(),
- ScreenType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ScreenType),
- };
- return rsp;
- }
- /// <summary>
- /// 甄别详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("screen/{id}")]
- public async Task<OrderScreenListDto> ScreenEntity(string id)
- {
- var model = await _orderScreenRepository.Queryable()
- .Includes(x => x.Workflow)
- .Includes(x => x.Visit, d => d.Order)
- .FirstAsync(x => x.Id == id);
- var rspModel = _mapper.Map<OrderScreenListDto>(model);
- rspModel.IsCanHandle = model.Workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
- var files = await _fileRepository.Queryable().Where(x => x.Key == rspModel.Id && string.IsNullOrEmpty(x.FlowKey)).ToListAsync();
- if (files.Any()) rspModel.Files = _mapper.Map<List<FileDto>>(files);
- return rspModel;
- }
- #endregion
- #region 工单督办
- /// <summary>
- /// 工单督办列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("supervise")]
- public async Task<PagedDto<SuperviseOrderDto>> SuperviseList([FromQuery] SuperviseListDto dto)
- {
- var (total, items) = await _orderSuperviseRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.SuperviseState > -1, x => x.State == dto.SuperviseState)
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .Where(x => x.OrgId == _sessionContext.OrgId)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<SuperviseOrderDto>(total, _mapper.Map<IReadOnlyList<SuperviseOrderDto>>(items));
- }
- /// <summary>
- /// 申请督办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ApplySupervise)]
- [HttpPost("supervise/apply")]
- public async Task ApplySupervise([FromBody] ApplyOrderSuperviseDto dto)
- {
- if (!dto.SuperviseOrgDtos.Any())
- throw UserFriendlyException.SameMessage("请选择被督办部门");
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- foreach (var item in dto.SuperviseOrgDtos)
- {
- var model = _mapper.Map<OrderSupervise>(dto);
- model.OrgId = item.OrgId;
- model.OrgName = item.OrgName;
- model.LaunchOrgName = _sessionContext.OrgName;
- model.CrUser = _sessionContext.UserName;
- model.State = 0;
- model.InitId();
- if (dto.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderSuperviseRepository.AddAsync(model, HttpContext.RequestAborted);
-
- if (dto.AcceptSms)
- {
- //TODO 发送短信
- }
- //推省上
- if (!string.IsNullOrEmpty(model.Id) && order.Source == ESource.ProvinceStraight)
- {
- var orderDto = _mapper.Map<OrderDto>(order);
- var supervise = await _orderSuperviseRepository.GetAsync(x => x.Id == model.Id);
- if (supervise != null)
- {
- var superviseDto = _mapper.Map<SuperviseOrderDto>(supervise);
- //_capPublisher.Publish(EventNames.HotlineOrderSuperviseCourse, new PublishSuperviseDto()
- //{
- // Order = orderDto,
- // Supervise = superviseDto,
- // ClientGuid = ""
- //});
- try
- {
- await _provinceService.SendSuperviseProcessInfo(new PublishSuperviseDto()
- {
- Order = orderDto,
- Supervise = superviseDto,
- ClientGuid = ""
- }, HttpContext.RequestAborted);
- }
- catch (Exception e)
- {
- _logger.LogError("_provinceService.SendSuperviseProcessInfo throw exception: {ex}", e.Message);
- }
- }
- }
- }
- }
- /// <summary>
- /// 回复督办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("supervise/reply")]
- public async Task ReplySupervise([FromBody] ReplyOrderSuperviseDto dto)
- {
- //验证是否存在督办
- var supervise = await _orderSuperviseRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (supervise is null)
- throw UserFriendlyException.SameMessage("无效督办");
- if (supervise.State > 0)
- throw UserFriendlyException.SameMessage("督办已回复,请勿重复回复");
- _mapper.Map(dto, supervise);
- supervise.ReplyId = _sessionContext.UserId;
- supervise.ReUser = _sessionContext.UserName;
- supervise.ReplyTime = DateTime.Now;
- supervise.State = 1;
- if (dto.Files.Any()) supervise.ReplyFileJson = await _fileRepository.AddFileAsync(dto.Files, supervise.Id, "", HttpContext.RequestAborted);
- await _orderSuperviseRepository.UpdateAsync(supervise, HttpContext.RequestAborted);
- var order = await _orderRepository.GetAsync(supervise.OrderId, HttpContext.RequestAborted);
- //推省上
- if (order != null && order.Source == ESource.ProvinceStraight)
- {
- var orderDto = _mapper.Map<OrderDto>(order);
- var superviseDto = _mapper.Map<SuperviseOrderDto>(supervise);
- //_capPublisher.Publish(EventNames.HotlineOrderSuperviseCourse, new PublishSuperviseDto()
- //{
- // Order = orderDto,
- // Supervise = superviseDto,
- // ClientGuid = ""
- //});
- await _provinceService.SendSuperviseProcessInfo(new PublishSuperviseDto()
- {
- Order = orderDto,
- Supervise = superviseDto,
- ClientGuid = ""
- }, HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 签收督办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("supervise/sign")]
- public async Task SignSupervise([FromBody] SignOrderSuperviseDto dto)
- {
- //验证是否存在督办
- var supervise = await _orderSuperviseRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (supervise is null)
- throw UserFriendlyException.SameMessage("无效督办");
- //supervise.State = 2;
- supervise.SignTime = DateTime.Now;
- supervise.SignUser = _sessionContext.UserName;
- await _orderSuperviseRepository.UpdateAsync(supervise, HttpContext.RequestAborted);
- var order = await _orderRepository.GetAsync(supervise.OrderId, HttpContext.RequestAborted);
- //推省上
- if (order != null && order.Source == ESource.ProvinceStraight)
- {
- var orderDto = _mapper.Map<OrderDto>(order);
- var superviseDto = _mapper.Map<SuperviseOrderDto>(supervise);
- //_capPublisher.Publish(EventNames.HotlineOrderSuperviseCourse, new PublishSuperviseDto()
- //{
- // Order = orderDto,
- // Supervise = superviseDto,
- // ClientGuid = ""
- //});
- await _provinceService.SendSuperviseProcessInfo(new PublishSuperviseDto()
- {
- Order = orderDto,
- Supervise = superviseDto,
- ClientGuid = ""
- }, HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 督办详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("supervise/{id}")]
- public async Task<OrderSuperviseDto> SuperviseEntity(string id)
- {
- var orderSupervise = await _orderSuperviseRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- var orderSuperviseDto = new OrderSuperviseDto();
- if (orderSupervise != null)
- {
- orderSuperviseDto = _mapper.Map<OrderSuperviseDto>(orderSupervise);
- var files = await _fileRepository.Queryable().Where(x => x.Key == orderSupervise.Id).ToListAsync();
- if (files.Any())
- {
- var applyFiles = files.Where(x => x.Classify == "督办申请").ToList();
- if (applyFiles.Any()) orderSuperviseDto.Files = _mapper.Map<List<FileDto>>(applyFiles);
- var replyFiles = files.Where(x => x.Classify == "督办回复").ToList();
- if (replyFiles.Any()) orderSuperviseDto.ReplyFiles = _mapper.Map<List<FileDto>>(replyFiles);
- }
- }
- return orderSuperviseDto;
- }
- #endregion
- #region 工单催办
- /// <summary>
- /// 工单催办列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("urge")]
- public async Task<PagedDto<UrgeOrderDto>> UrgeList([FromQuery] UrgeListDto dto)
- {
- var (total, items) = await _orderUrgeRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.UrgeState > -1, x => x.State == dto.UrgeState)
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .Where(x => x.OrgId == _sessionContext.OrgId)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<UrgeOrderDto>(total, _mapper.Map<IReadOnlyList<UrgeOrderDto>>(items));
- }
- /// <summary>
- /// 申请催办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ApplyUrge)]
- [HttpPost("urge/apply")]
- public async Task ApplyUrge([FromBody] ApplyOrderUrgeDto dto)
- {
- if (!dto.UrgeOrgDtos.Any())
- throw UserFriendlyException.SameMessage("请选择被催办部门");
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- foreach (var item in dto.UrgeOrgDtos)
- {
- var model = _mapper.Map<OrderUrge>(dto);
- model.OrgId = item.OrgId;
- model.OrgName = item.OrgName;
- model.CreatorOrgName = _sessionContext.OrgName;
- model.CrUser = _sessionContext.UserName;
- model.State = 0;
- model.InitId();
- if (dto.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderUrgeRepository.AddAsync(model, HttpContext.RequestAborted);
- if (dto.AcceptSms)
- {
- //TODO 发送短信
- }
- //推省上
- if (!string.IsNullOrEmpty(model.Id) && order.Source == ESource.ProvinceStraight)
- {
- var orderDto = _mapper.Map<OrderDto>(order);
- var urge = await _orderUrgeRepository.GetAsync(x => x.Id == model.Id);
- if (urge != null)
- {
- var urgeDto = _mapper.Map<UrgeOrderDto>(urge);
- //_capPublisher.Publish(EventNames.HotlineOrderSuperviseCourse, new PublishUrgeDto()
- //{
- // Order = orderDto,
- // Urge = urgeDto,
- // ClientGuid = ""
- //});
- }
- }
- }
- }
- /// <summary>
- /// 回复催办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("urge/reply")]
- public async Task ReplyUrge([FromBody] ReplyOrderUrgeDto dto)
- {
- //验证是否存在催办
- var urge = await _orderUrgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (urge is null)
- throw UserFriendlyException.SameMessage("无效催办");
- if (urge.State > 0)
- throw UserFriendlyException.SameMessage("督办已回复,请勿重复回复");
- _mapper.Map(dto, urge);
- urge.ReplyId = _sessionContext.UserId;
- urge.ReUser = _sessionContext.UserName;
- urge.ReplyContent = dto.ReplyContent;
- urge.ReplyTime = DateTime.Now;
- urge.State = 1;
- if (dto.Files.Any()) urge.ReplyFileJson = await _fileRepository.AddFileAsync(dto.Files, urge.Id, "", HttpContext.RequestAborted);
- await _orderUrgeRepository.UpdateAsync(urge, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 签收催办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPost("urge/sign")]
- public async Task SignUrge([FromBody] SignOrderUrgeDto dto)
- {
- //验证是否存在催办
- var urge = await _orderUrgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (urge is null)
- throw UserFriendlyException.SameMessage("无效催办");
- urge.State = 2;
- urge.SignUser = _sessionContext.UserName;
- urge.SignTime = DateTime.Now;
- await _orderUrgeRepository.UpdateAsync(urge, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 催办详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("urge/{id}")]
- public async Task<OrderUrgeDto> UrgeEntity(string id)
- {
- var orderUrge = await _orderUrgeRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- var orderUrgeDto = new OrderUrgeDto();
- if (orderUrge != null)
- {
- orderUrgeDto = _mapper.Map<OrderUrgeDto>(orderUrge);
- var files = await _fileRepository.Queryable().Where(x => x.Key == orderUrge.Id).ToListAsync();
- if (files.Any()) orderUrgeDto.Files = _mapper.Map<List<FileDto>>(files);
- }
- return orderUrgeDto;
- }
- #endregion
- #region 工单办理
- /// <summary>
- /// 工单列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderQuery)]
- [HttpGet]
- public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderDto dto)
- {
- var (total, items) = await _orderRepository.Queryable(workflowFilter: false)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
- .WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content!))
- .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptType))
- .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannel))
- .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.Workflow.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.PhoneNo),
- d => d.FromPhone.Contains(dto.PhoneNo!) || 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.BackToUnAccept),
- d => d.Status <= EOrderStatus.BackToUnAccept)
- .OrderByDescending(d => d.CreationTime)
- .ToPagedListAsync(dto, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 历史工单
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("history")]
- public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderHistoryDto dto)
- {
- var (total, items) = await _orderRepository.Queryable()
- .Where(d => d.FromPhone == dto.PhoneNo)
- .WhereIF(!string.IsNullOrEmpty(dto.OrderId), d => d.Id != dto.OrderId)
- .OrderByDescending(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 查询重复工单
- /// </summary>
- [HttpGet("duplicate")]
- public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderDuplicateDto dto)
- {
- if (!dto.OrderIds.Any())
- return new PagedDto<OrderDto>(0, new List<OrderDto>());
- var (total, items) = await _orderRepository.Queryable()
- .Where(d => dto.OrderIds.Contains(d.Id))
- .OrderByDescending(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 查询工单详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("{id}")]
- public async Task<OrderDto> Get(string id)
- {
- var order = await _orderRepository.Queryable(workflowFilter: false)
- .Includes(d => d.Acceptor)
- .Includes(d => d.OrderExtension)
- .Includes(d => d.OrderDelays)
- .Includes(d => d.OrderScreens)
- .Includes(d => d.OrderVisits, x => x.OrderVisitDetails)
- .FirstAsync(d => d.Id == id);
- if (order == null)
- return new();
- var canHandle = false;
- if (!string.IsNullOrEmpty(order?.WorkflowId))
- {
- var (workflow, handlePermission) = await _workflowDomainService.GetWorkflowHandlePermissionAsync(
- order.WorkflowId, _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
- withSteps: true, withSupplements: true,
- cancellationToken: HttpContext.RequestAborted);
- order.Workflow = workflow;
- canHandle = handlePermission;
- await _mediator.Publish(new GetOrderDetailNotify(order.Workflow,
- _sessionContext.RequiredUserId, _sessionContext.UserName,
- _sessionContext.RequiredOrgId, _sessionContext.OrgName,
- _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName));
- }
- var dto = _mapper.Map<OrderDto>(order!);
- var files = await _fileRepository.Queryable().Where(x => x.Key == dto.Id && x.Classify == "受理上传" && string.IsNullOrEmpty(x.FlowKey)).ToListAsync();
- dto.Files = _mapper.Map<List<FileDto>>(files);
- var call = await _trCallRecordRepository.Queryable().Where(x => x.CallAccept == order.CallId).FirstAsync();
- if (call != null) dto.RecordingFileUrl = call.RecordingFileUrl;
- if (order?.Workflow != null)
- dto.Workflow.CanHandle = canHandle;
- var repeatablesMap = await _repeatableEventDetailRepository.Queryable()
- .Includes(x => x.Order)
- .Where(x => x.OrderId == id).Distinct().ToListAsync();
- var repeatables = _mapper.Map<List<RepeatableEventDetailOpDto>>(repeatablesMap);
- dto.RepeatableEventDetails = repeatables;
- return dto;
- }
- /// <summary>
- /// 新增工单
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderAdd)]
- [HttpPost]
- public async Task<string> Add([FromBody] AddOrderDto dto)
- {
- //todo dto validation
- var order = _mapper.Map<Order>(dto);
- order.SignerId = _sessionContext.UserId;
- order.SignerName = _sessionContext.UserName;
- order.InitId();
- if (dto.Files.Any()) order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", HttpContext.RequestAborted);
- await _orderDomainService.AddAsync(order, HttpContext.RequestAborted);
- //if (dto.Tags.Any()) await _repositoryts.AddVectorAsync(orderId, DateTime.Now, dto.Tags, HttpContext.RequestAborted);
- if (dto.RepeatableEventDetails?.Any() ?? false)
- {
- dto.RepeatableEventDetails.ForEach(x => x.OrderId = order.Id);
- List<RepeatableEventDetail> repeatables =
- _mapper.Map<List<RepeatableEventDetail>>(dto.RepeatableEventDetails);
- await _repeatableEventDetailRepository.AddRangeAsync(repeatables, HttpContext.RequestAborted);
- }
- //内容分词
- await _orderRepository.OrderParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
- return order.Id;
- }
- /// <summary>
- /// 删除工单
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpDelete("{id}")]
- public async Task Remove(string id)
- {
- var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
- if (order == null) return;
- if (order.Status != EOrderStatus.WaitForAccept)
- throw UserFriendlyException.SameMessage("非草稿工单不可删除");
- await _orderRepository.RemoveAsync(order);
- }
- /// <summary>
- /// 更新工单信息
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderUpdate)]
- [HttpPut]
- public async Task Update([FromBody] UpdateOrderDto dto)
- {
- var order = await _orderRepository.Queryable()
- .FirstAsync(d => d.Id == dto.Id);
- if (order == null)
- throw UserFriendlyException.SameMessage("无效工单编号");
- if (order.Status > EOrderStatus.BackToUnAccept)
- throw UserFriendlyException.SameMessage("工单已发起流程");
- if (order.Content != dto.Content)
- await _orderRepository.OrderParticiple(dto.Content, dto.Id, HttpContext.RequestAborted);
- if (dto.RepeatableEventDetails?.Any() ?? false)
- {
- var reAdds = dto.RepeatableEventDetails.Where(x => string.IsNullOrEmpty(x.OrderId) && !x.IsDeleted)
- .ToList();
- var reDeletes = dto.RepeatableEventDetails.Where(x => !string.IsNullOrEmpty(x.OrderId) && x.IsDeleted)
- .ToList();
- reAdds.ForEach(x => x.OrderId = dto.Id);
- List<RepeatableEventDetail> repeatables = _mapper.Map<List<RepeatableEventDetail>>(reAdds);
- await _repeatableEventDetailRepository.AddRangeAsync(repeatables, HttpContext.RequestAborted);
- if (reDeletes?.Any() ?? false)
- {
- await _repeatableEventDetailRepository.DeleteAsync(reDeletes, HttpContext.RequestAborted);
- }
- }
- _mapper.Map(dto, order);
- if (dto.Files.Any()) order.FileJson = await _fileRepository.AddFileAsync(dto.Files, order.Id, "", HttpContext.RequestAborted);
- await _orderRepository.UpdateNav(order).Include(d => d.OrderExtension).ExecuteCommandAsync();
- }
- /// <summary>
- /// 开始工单办理流程
- /// </summary>
- [HttpPost("startflow")]
- public async Task StartFlow([FromBody] OrderStartFlowDto dto)
- {
- var id = dto.Data.Id;
- var isAdd = string.IsNullOrEmpty(dto.Data.Id);
- if (isAdd)
- {
- id = await Add(dto.Data);
- }
- else
- {
- await Update(dto.Data);
- }
- try
- {
- //期满时间
- var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now, ETimeType.Day, 1, true);
- var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
- startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderHandle;
- startDto.Title = dto.Data.Title;
- await _workflowApplication.StartWorkflowAsync(startDto, id, expiredTime, HttpContext.RequestAborted);
- }
- catch (Exception e)
- {
- if (isAdd)
- await Remove(id);
- throw new UserFriendlyException($"工单开启流程失败!, {e.Message}", "工单开启流程失败");
- }
- }
- /// <summary>
- /// 查询工单办理流程开启参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("startflow")]
- public async Task<NextStepsDto> GetFlowStartOptions()
- {
- //return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.OrderHandle,
- // HttpContext.RequestAborted);
- return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.OrderHandle,
- HttpContext.RequestAborted);
- }
- /// <summary>
- /// 查询工单办理的期满时间配置
- /// </summary>
- [HttpGet("time-config")]
- public async Task<TimeConfig> GetOrderHandleTimeConfig(EFlowDirection flowDirection, string? acceptType)
- {
- switch (flowDirection)
- {
- case EFlowDirection.CenterToOrg:
- return new TimeConfig { Count = 3, TimeType = ETimeType.Day };
- case EFlowDirection.OrgToCenter:
- return new TimeConfig { Count = 1, TimeType = ETimeType.Day };
- default:
- throw new ArgumentOutOfRangeException(nameof(flowDirection), flowDirection, null);
- }
- }
- /// <summary>
- /// 列表页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data")]
- public async Task<object> BaseData()
- {
- var rsp = new
- {
- AcceptTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType),
- ChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel),
- OrgsOptions = await _organizeRepository.GetOrgJson(),
- EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
- PushTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.PushType),
- OrderStatusOptions = EnumExts.GetDescriptions<EOrderStatus>(),
- };
- return rsp;
- }
- /// <summary>
- /// 新增页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data-add")]
- public async Task<object> BaseDataAdd()
- {
- var rsp = new
- {
- ChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel),
- AcceptTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType),
- EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
- PushTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.PushType),
- GenderOptions = EnumExts.GetDescriptions<EGender>(),
- IdentityTypeOptions = EnumExts.GetDescriptions<EIdentityType>(),
- LicenceTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.LicenceType),
- AgeRangeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AgeRange),
- OrderTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.OrderType),
- };
- return rsp;
- }
- /// <summary>
- /// 扩展信息新增页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data-ext")]
- public async Task<object> BaseDataExtension()
- {
- var rsp = new
- {
- LicenceTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.LicenceType),
- IdentityTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ProviderIdentityType),
- IdentityOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.Identity),
- NationalityOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.Nationality),
- NationOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.Nation),
- MarketTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.MarketType),
- IndustryClassifyOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.IndustryClassify),
- BrandOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.Brand),
- ObjectClassifyOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ObjectClassify),
- ComplainClassifyOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ComplainClassify),
- ReportClassifyOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ReportClassify),
- SalesModeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SalesMode),
- ECommercePlatformOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.ECommercePlatform),
- PatentTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.PatentType),
- AffairTargetOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AffairTarget),
- ComplainTypeOptions =
- EnumExts.GetDescriptions<EComplainType>().Select(d => new Kv(d.Key.ToString(), d.Value)),
- SalesChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SalesChannel),
- };
- return rsp;
- }
- /// <summary>
- /// 扩展信息新增页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpPost("order_repeatable_event")]
- public async Task<bool> RepeatableEvent(QueryRepeatableEventDto dto)
- {
- var exp = Expressionable.Create<Order>()
- .OrIF(!string.IsNullOrEmpty(dto.HotspotSpliceName),
- x => x.HotspotSpliceName.EndsWith(dto.HotspotSpliceName!))
- .OrIF(!string.IsNullOrEmpty(dto.Address), x => x.Address != null && x.Address.EndsWith(dto.Address!));
- var count = await _orderRepository.Queryable()
- .Where(exp.ToExpression())
- .Where(d => d.CreationTime.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd"))
- .CountAsync();
- var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RepeatableEventNum);
- return count >= int.Parse(setting?.SettingValue[0] ?? "0");
- }
- #endregion
- #region 工单待办
- /// <summary>
- /// 查询待办工单
- /// </summary>
- [HttpGet("waited")]
- public async Task<PagedDto<OrderDto>> QueryWaited([FromQuery] QueryOrderWaitedDto dto)
- {
- EWorkflowStepStatus[] handleStatuses = Array.Empty<EWorkflowStepStatus>();
- if (dto.IsHandled.HasValue)
- handleStatuses = dto.IsHandled.Value
- ? new[] { EWorkflowStepStatus.Handled }
- : new[] { EWorkflowStepStatus.WaitForAccept, EWorkflowStepStatus.WaitForHandle };
- var (total, items) = await _orderRepository.Queryable(workflowFilter: false)
- .Includes(d => d.Workflow, x => x.Steps)
- .Where(d => SqlFunc.JsonListObjectAny(d.Workflow.HandlerUsers, "Key", _sessionContext.RequiredUserId) ||
- SqlFunc.JsonListObjectAny(d.Workflow.HandlerOrgs, "Key", _sessionContext.RequiredOrgId))
- .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
- .WhereIF(dto.IsHandled.HasValue, d => d.Workflow.Steps.Any(x => handleStatuses.Contains(x.Status)))
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.No.Contains(dto.Keyword) || d.Title.Contains(dto.Keyword))
- .OrderByDescending(d => d.ExpiredTime)
- .ToPagedListAsync(dto, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 查询坐席待办
- /// </summary>
- [HttpGet("waited/sign")]
- public async Task<PagedDto<OrderDto>> QueryWaitedForSeat([FromQuery] QueryOrderWaitedDto dto)
- {
- EOrderStatus[] handleStatuses = EnumExts.GetFields<EOrderStatus>().Select(d => (EOrderStatus)d.Key).ToArray();
- handleStatuses = handleStatuses.WhereIF(dto.IsHandled.HasValue,
- d => dto.IsHandled!.Value
- ? d is not EOrderStatus.WaitForAccept and not EOrderStatus.BackToUnAccept
- : d is EOrderStatus.WaitForAccept or EOrderStatus.BackToUnAccept)
- .ToArray();
- var (total, items) = await _orderRepository.Queryable(workflowFilter: false)
- .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
- .WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.No.Contains(dto.Keyword!) || d.Title.Contains(dto.Keyword!))
- .Where(d => string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)
- .OrderByDescending(d => d.ExpiredTime)
- .ToPagedListAsync(dto, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- #endregion
- #region 工单退回
- /// <summary>
- /// 工单退回列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.SendBackOrderList)]
- [HttpGet("send_back")]
- public async Task<PagedDto<OrderSendBackDto>> UrgeList([FromQuery] OrderSendBackListDto dto)
- {
- var (total, items) = await _orderSendBackRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .WhereIF(dto.State is > 0, d => d.State > 0)
- .WhereIF(dto.State is 0, d => d.State == 0)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderSendBackDto>(total, _mapper.Map<IReadOnlyList<OrderSendBackDto>>(items));
- }
- /// <summary>
- /// 退回申请
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ApplySendBack)]
- [HttpPost("send_back/apply")]
- public async Task ApplyUrge([FromBody] OrderSendBackAddDto dto)
- {
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- if ((int)order.Status > 1)
- throw UserFriendlyException.SameMessage("工单状态无效,请确认当前工单状态");
- if ((int)order.Source <= 1)
- throw UserFriendlyException.SameMessage("工单来源无效,请确认当前工单来源");
- var model = _mapper.Map<OrderSendBack>(dto);
- model.InitId();
- if (dto.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderSendBackRepository.AddAsync(model, HttpContext.RequestAborted);
-
- if (!string.IsNullOrEmpty(model.Id))
- {
- order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- order.Status = EOrderStatus.BackToProvince;
- await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 退回审核
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.AuditSendBack)]
- [HttpPost("send_back/audit")]
- public async Task ReplyUrge([FromBody] AuditOrderSendBackDto dto)
- {
- //验证是否存在退回
- var sendBack = await _orderSendBackRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (sendBack is null)
- throw UserFriendlyException.SameMessage("无效退回");
- if (sendBack.State > 0)
- throw UserFriendlyException.SameMessage("退回已审核,请勿重复审核");
- _mapper.Map(dto, sendBack);
- sendBack.AuditName = _sessionContext.UserName;
- sendBack.AuditTime = DateTime.Now;
- await _orderSendBackRepository.UpdateAsync(sendBack, HttpContext.RequestAborted);
- //推省上
- if (sendBack.State == 1)
- {
- var order = await _orderRepository.GetAsync(sendBack.OrderId);
- var sendBackDto = _mapper.Map<OrderSendBackDto>(sendBack);
- var OrderDto = _mapper.Map<OrderDto>(order);
- //_capPublisher.Publish(EventNames.HotlineOrderSendBackApplyed,
- // new PublishOrderSendBackDto() { Order = OrderDto, SendBack = sendBackDto, ClientGuid = "" });
- await _provinceService.GetCaseBackApply(
- new PublishOrderSendBackDto { Order = OrderDto, SendBack = sendBackDto, ClientGuid = "" },
- HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 退回详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("send_back/{id}")]
- public async Task<OrderSendBack> SendBackEntity(string id)
- {
- return await _orderSendBackRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 工单特提
- /// <summary>
- /// 工单特提信息
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [Permission(EPermission.ApplySpecial)]
- [HttpPost("special")]
- public async Task Add([FromBody] OrderSpecialAddDto dto)
- {
- var specialAny = await _orderSpecialRepository.Queryable().Where(x => x.OrderId == dto.OrderId && x.State == 0)
- .AnyAsync();
- if (specialAny) throw UserFriendlyException.SameMessage("工单已存在待审批特提信息!");
- var model = _mapper.Map<OrderSpecial>(dto);
- model.OrgId = _sessionContext.OrgId;
- model.OrgName = _sessionContext.OrgName;
- if (!dto.Audit) model.State = 1;
- model.InitId();
- if (dto.Files.Any()) model.FileJson = await _fileRepository.AddFileAsync(dto.Files, model.Id, "", HttpContext.RequestAborted);
- await _orderSpecialRepository.AddAsync(model, HttpContext.RequestAborted);
- if (model.State == 1)
- {
- var recall = new RecallDto
- {
- WorkflowId = dto.WorkflowId!,
- NextStepCode = dto.NextStepCode,
- NextStepName = dto.NextStepName,
- NextHandlers = dto.NextHandlers,
- Opinion = dto.Cause
- };
- if (dto.AlterTime) recall.External = new External { TimeLimit = dto.TimeLimit, TimeLimitUnit = dto.TimeLimitUnit };
- //if (dto.Files.Any()) recall.Files = dto.Files;
- await _workflowApplication.RecallAsync(recall, HttpContext.RequestAborted);
- var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == dto.OrderId) ;
- if (publish != null)
- {
- var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
- await _orderPublishHistoryRepository.AddAsync(publishHistory, HttpContext.RequestAborted);
- await _orderPublishRepository.RemoveAsync(publish,false, HttpContext.RequestAborted);
- }
- var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == dto.OrderId);
- if (visit != null) {
- visit.VisitState = EVisitState.None;
- await _orderVisitRepository.UpdateAsync(visit, HttpContext.RequestAborted);
- }
- var order = await _orderRepository.GetAsync(x => x.Id == model.OrderId);
- if (order != null && ("001170".Equals(order.CurrentHandleOrgCode) || "001180".Equals(order.CurrentHandleOrgCode)))
- await _provinceService.RevokeOrder(new PublishSpecialDto { Order = _mapper.Map<OrderDto>(order), Special = _mapper.Map<OrderSpecialDto>(model) }, HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 审批工单特提信息
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.AuditSpecial)]
- [HttpPut("special")]
- public async Task Update([FromBody] AuditOrderSpecialDto dto)
- {
- var special = await _orderSpecialRepository.GetAsync(dto.Id);
- if (special is null) throw UserFriendlyException.SameMessage("无效特提审批信息!");
- if (special.State != 0) throw UserFriendlyException.SameMessage("无效特提审批信息,特提审批信息错误,该信息已审核!");
- _mapper.Map(dto, special);
- if (dto.Files.Any()) special.ReplyFileJson = await _fileRepository.AddFileAsync(dto.Files, special.Id, "", HttpContext.RequestAborted);
- await _orderSpecialRepository.UpdateAsync(special, HttpContext.RequestAborted);
- if (special.State == 1)
- {
- var recall = new RecallDto
- {
- WorkflowId = dto.WorkflowId!,
- NextStepCode = dto.NextStepCode,
- NextStepName = dto.NextStepName,
- NextHandlers = dto.NextHandlers,
- Opinion = dto.Opinion
- };
- if (dto.AlterTime) recall.External = new External { TimeLimit = dto.TimeLimit, TimeLimitUnit = dto.TimeLimitUnit };
- //if (dto.Files.Any()) recall.Files = dto.Files;
- await _workflowApplication.RecallAsync(recall, HttpContext.RequestAborted);
- var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == special.OrderId);
- if (publish != null)
- {
- var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
- await _orderPublishHistoryRepository.AddAsync(publishHistory, HttpContext.RequestAborted);
- await _orderPublishRepository.RemoveAsync(publish, false, HttpContext.RequestAborted);
- }
- var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == special.OrderId);
- if (visit != null)
- {
- visit.VisitState = EVisitState.None;
- await _orderVisitRepository.UpdateAsync(visit, HttpContext.RequestAborted);
- }
- var order = await _orderRepository.GetAsync(x => x.Id == special.OrderId);
- if (order != null && ("001170".Equals(order.CurrentHandleOrgCode) || "001180".Equals(order.CurrentHandleOrgCode)))
- await _provinceService.RevokeOrder(new PublishSpecialDto { Order = _mapper.Map<OrderDto>(order), Special = _mapper.Map<OrderSpecialDto>(special) }, HttpContext.RequestAborted);
- }
- }
- /// <summary>
- /// 获取工单特提信息列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.SpecialOrderList)]
- [HttpGet("special/list")]
- public async Task<PagedDto<OrderSpecialDto>> List([FromQuery] OrderSpecialListDto dto)
- {
- var (total, items) = await _orderSpecialRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
- .WhereIF(dto.State.HasValue, x => x.State == dto.State)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderSpecialDto>(total, _mapper.Map<IReadOnlyList<OrderSpecialDto>>(items));
- }
- /// <summary>
- /// 工单列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ApplySpecialOrderList)]
- [HttpGet("special/apply_list")]
- public async Task<PagedDto<OrderDto>> SpecialList([FromQuery] QueryOrderDto dto)
- {
- var query = _orderRepository.Queryable()
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
- .WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content!))
- .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptType))
- .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannel))
- .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 => dto.OrgCodes.Contains(d.Workflow.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.PhoneNo),
- d => d.FromPhone.Contains(dto.PhoneNo!) || 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.BackToUnAccept),
- d => d.Status <= EOrderStatus.BackToUnAccept);
- if (!_sessionContext.OrgIsCenter && _sessionContext.OrgId.Length >= 6)
- {
- var oneCode = _sessionContext.OrgId.Substring(0, 6);
- query = query.Where(x =>
- x.AcceptorOrgCode.StartsWith(oneCode) && !x.AcceptorOrgCode.StartsWith(_sessionContext.OrgId));
- }
- var (total, items) = await query
- .OrderByDescending(d => d.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
- }
- /// <summary>
- /// 获取工单特提信息
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("special/{id}")]
- public async Task<OrderSpecialDto> SpecialEntity(string id)
- {
- var item = await _orderSpecialRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- var itemDto = new OrderSpecialDto();
- if (item != null)
- {
- itemDto = _mapper.Map<OrderSpecialDto>(item);
- var files = await _fileRepository.Queryable().Where(x => x.Key == item.Id).ToListAsync();
- if (files.Any()) itemDto.Files = _mapper.Map<List<FileDto>>(files);
- }
- return itemDto;
- }
- /// <summary>
- /// 列表页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("special/base/{id}")]
- public async Task<object> SpecialBaseData(string id)
- {
- var rsp = new
- {
- SpecialTimeType = EnumExts.GetDescriptions<ETimeType>(),
- SpecialReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SpecialReason),
- Step = await _workflowApplication.GetRecallStepsAsync(id, HttpContext.RequestAborted)
- };
- return rsp;
- }
- /// <summary>
- /// 获取办理时限
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("special/handle_time")]
- public async Task<int> SpecialHandleTime([FromQuery] OrderSpecialHandleTime dto)
- {
- var order = await _orderRepository.GetAsync(dto.OrderId);
- if (dto.FlowDirection != null && dto.FlowDirection == EFlowDirection.OrgToCenter)
- return _timeLimitDomainService.GetOrderTimeLimitConfig(string.Empty);
- return _timeLimitDomainService.GetOrderTimeLimitConfig(order.AcceptTypeCode);
- }
- #endregion
- #region 市民信息
- /// <summary>
- /// 新增市民信息
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [HttpPost("citizen")]
- public async Task Add([FromBody] CitizenAddDto dto)
- {
- var citizen =
- await _citizenRepository.CountAsync(x => x.PhoneNumber == dto.PhoneNumber, HttpContext.RequestAborted);
- if (citizen > 0)
- throw UserFriendlyException.SameMessage("市民联系电话信息重复");
- await _citizenRepository.AddAsync(dto, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除市民信息
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.DeleteCitizen)]
- [HttpDelete("citizen")]
- public async Task Delete([FromBody] CitizenDeleteDto dto)
- {
- await _citizenRepository.RemoveAsync(x => x.Id == dto.Id);
- }
- /// <summary>
- /// 更新市民信息
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.UpdateCitizen)]
- [HttpPut("citizen")]
- public async Task Update([FromBody] CitizenUpdateDto dto)
- {
- var citizen = await _citizenRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (citizen is null)
- throw UserFriendlyException.SameMessage("无效市民信息");
- _mapper.Map(dto, citizen);
- citizen.LastModificationName = _sessionContext.UserName;
- await _citizenRepository.UpdateAsync(citizen, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取市民信息列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.CitizenList)]
- [HttpGet("citizen/list")]
- public async Task<PagedDto<CitizenDto>> List([FromQuery] CitizenListDto dto)
- {
- var (total, items) = await _citizenRepository.Queryable()
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<CitizenDto>(total, _mapper.Map<IReadOnlyList<CitizenDto>>(items));
- }
- /// <summary>
- /// 获取市民信息
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("citizen/{id}")]
- public async Task<Citizen> CitizenEntity(string id)
- {
- return await _citizenRepository.Queryable()
- .Includes(x => x.labelDetails)
- .FirstAsync(x => x.Id == id);
- }
- /// <summary>
- /// 获取市民信息
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("citizen_phone/{phone}")]
- public async Task<object> Citizen(string phone)
- {
- //市民基本信息
- var citizen = await _citizenRepository.Queryable()
- .Includes(x => x.labelDetails)
- .FirstAsync(x => x.PhoneNumber == phone);
- //工单历史
- var oders = await _orderRepository.Queryable().Where(x => x.Contact == phone)
- .OrderBy(x => x.CreationTime, OrderByType.Desc).ToListAsync();
- var allOrderNum = oders.Count;
- var endOrderNum = oders.Count(x =>
- x.Status == EOrderStatus.Published || x.Status == EOrderStatus.Visited || x.Status == EOrderStatus.Filed);
- var handOrderNum =
- oders.Count(x => x.Status == EOrderStatus.Handling || x.Status == EOrderStatus.Countersigning);
- var DissatisfactionNum = await _orderVisitedDetailRepository.Queryable()
- .Includes(x => x.OrderVisit)
- .Where(x => SqlFunc.JsonField(x.OrgProcessingResults, "Value") == "不满意" ||
- SqlFunc.JsonField(x.OrgProcessingResults, "Value") == "非常不满意")
- .Distinct().Select(s => new { s.OrderVisit.OrderId }).CountAsync();
- //来电历史
- //TODO 等待通讯对接完成 还缺少 上次来电时间
- //关注诉求
- var hotspotNames = string.Join(",", oders.Select(x => x.HotspotName).Distinct().Take(5).ToList());
- var rsp = new
- {
- Citizen = citizen,
- LastCallTime = DateTime.Now,
- Order = new
- {
- allOrderNum = allOrderNum,
- endOrderNum = endOrderNum,
- handOrderNum = handOrderNum,
- DissatisfactionNum = DissatisfactionNum
- },
- CallHistory = new { AllCallNum = 0, ConnectNum = 0, CallBackNum = 0 },
- HotspotNames = hotspotNames,
- };
- return rsp;
- }
- /// <summary>
- /// 新增市民标签信息
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [HttpPost("citizen_label")]
- public async Task Add([FromBody] LabelDetailAddDto dto)
- {
- var label = await _labelDetailRepository.CountAsync(x => x.CitizenId == dto.CitizenId && x.Label == dto.Label,
- HttpContext.RequestAborted);
- if (label > 0)
- throw UserFriendlyException.SameMessage("市民联系标签信息重复");
- await _citizenRepository.LabelAddAsync(dto, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除市民标签信息
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpDelete("citizen_label")]
- public async Task Delete([FromBody] LabelDetailDeleteDto dto)
- {
- var label = await _labelDetailRepository.GetAsync(x => x.Id == dto.Id, HttpContext.RequestAborted);
- if (label == null || (label.CreatorName != _sessionContext.UserName))
- throw UserFriendlyException.SameMessage("市民联系标签信息错误");
- await _citizenRepository.LabelDeleteAsync(label, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取市民标签信息列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("citizen_label/list")]
- public async Task<PagedDto<LabelDetailDto>> List([FromQuery] CitizenQueryDto dto)
- {
- var (total, items) = await _labelDetailRepository.Queryable()
- .Includes(x => x.Citizen)
- .WhereIF(!string.IsNullOrEmpty(dto.Label), x => x.Label.Contains(dto.Label!))
- .WhereIF(!string.IsNullOrEmpty(dto.CreatorName),
- x => x.CreatorName != null && x.CreatorName.Contains(dto.CreatorName!))
- .Where(x => x.CitizenId == dto.CitizenId)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<LabelDetailDto>(total, _mapper.Map<IReadOnlyList<LabelDetailDto>>(items));
- }
- #endregion
- #region 重复性事件
- /// <summary>
- /// 新增重复性事件
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [HttpPost("repeatable_event")]
- public async Task Add([FromBody] RepeatableEventAddDto dto)
- {
- var repeatable = _mapper.Map<RepeatableEvent>(dto);
- var repeatableId = await _repeatableEventRepository.AddAsync(repeatable, HttpContext.RequestAborted);
- List<RepeatableEventDetail> detail;
- if (!string.IsNullOrEmpty(repeatableId) && dto.Details.Any())
- dto.Details.ForEach(x => x.RepeatableId = repeatableId);
- detail = _mapper.Map<List<RepeatableEventDetail>>(dto.Details);
- if (detail.Any())
- await _repeatableEventDetailRepository.AddRangeAsync(detail, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除重复性事件
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpDelete("repeatable_event")]
- public async Task Delete([FromBody] RepeatableEventDeleteDto dto)
- {
- await _repeatableEventRepository.RemoveAsync(x => x.Id == dto.Id);
- await _repeatableEventDetailRepository.RemoveAsync(x => x.RepeatableId == dto.Id);
- }
- /// <summary>
- /// 删除重复性事件明细
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpDelete("repeatable_event_detail/{id}")]
- public async Task Delete([FromBody] string id)
- {
- await _repeatableEventDetailRepository.RemoveAsync(x => x.Id == id);
- }
- /// <summary>
- /// 更新重复性事件
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.UpdateRepeatableEvent)]
- [HttpPut("repeatable_event")]
- public async Task Update([FromBody] RepeatableEventUpdateDto dto)
- {
- var repeatable = await _repeatableEventRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (repeatable is null)
- throw UserFriendlyException.SameMessage("无效重复性事件");
- _mapper.Map(dto, repeatable);
- repeatable.LastModificationName = _sessionContext.UserName;
- await _repeatableEventRepository.UpdateAsync(repeatable, HttpContext.RequestAborted);
- List<RepeatableEventDetail> detail;
- if (dto.Details.Any())
- dto.Details.ForEach(x => x.RepeatableId = dto.Id);
- await _repeatableEventDetailRepository.DeleteAsync(dto.Id, HttpContext.RequestAborted);
- detail = _mapper.Map<List<RepeatableEventDetail>>(dto.Details);
- if (detail.Any())
- await _repeatableEventDetailRepository.AddRangeAsync(detail, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取重复性事件列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("repeatable_event/list")]
- public async Task<PagedDto<RepeatableEventDto>> List([FromQuery] RepeatableEventListDto dto)
- {
- var (total, items) = await _repeatableEventRepository.Queryable()
- .Includes(x => x.Details)
- .Includes(x => x.Details, y => y.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- d => d.Title.Contains(dto.Keyword!) || (d.KeyWords != null && d.KeyWords.Contains(dto.Keyword!)))
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .WhereIF(!string.IsNullOrEmpty(dto.Code), x => x.Code != null && x.Code.Contains(dto.Code!))
- .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title.Contains(dto.Title!))
- .WhereIF(!string.IsNullOrEmpty(dto.KeyWords), x => x.KeyWords != null && x.KeyWords.Contains(dto.KeyWords!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<RepeatableEventDto>(total, _mapper.Map<IReadOnlyList<RepeatableEventDto>>(items));
- }
- /// <summary>
- /// 获取重复性事件
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("repeatable_event")]
- public async Task<RepeatableEvent> CitizenEntity([FromQuery] RepeatableEventEntityDto dto)
- {
- return await _repeatableEventRepository.Queryable()
- .Includes(x =>
- x.Details.WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.Title.Contains(dto.Keyword!))
- .ToList())
- .Includes(x => x.Details, y => y.Order)
- .FirstAsync(x => x.Id == dto.Id);
- }
- #endregion
- #region 工单词库
- /// <summary>
- /// 新增工单词库
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [Permission(EPermission.AddOrderWord)]
- [HttpPost("order_word")]
- public async Task Add([FromBody] OrderWordAddDto dto)
- {
- var word = _mapper.Map<OrderWord>(dto);
- await _orderWrodRepository.AddAsync(word, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除工单词库
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.DeleteOrderWord)]
- [HttpDelete("order_word")]
- public async Task Delete([FromBody] OrderWordDeleteDto dto)
- {
- await _orderRepository.RemoveOrderWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 更新工单词库
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.UpdateOrderWord)]
- [HttpPut("order_word")]
- public async Task Update([FromBody] OrderWordUpdateDto dto)
- {
- var word = await _orderWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (word is null)
- throw UserFriendlyException.SameMessage("无效工单词库");
- _mapper.Map(dto, word);
- word.LastModificationName = _sessionContext.UserName;
- await _orderWrodRepository.UpdateAsync(word, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取工单词库列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderWordList)]
- [HttpGet("order_word/list")]
- public async Task<PagedDto<OrderWordDto>> List([FromQuery] OrderWordListDto dto)
- {
- var (total, items) = await _orderWrodRepository.Queryable()
- .WhereIF(!string.IsNullOrEmpty(dto.Tag), x => x.Tag == dto.Tag!)
- .WhereIF(!string.IsNullOrEmpty(dto.Classify), x => x.Classify.Contains(dto.Classify!))
- .WhereIF(!string.IsNullOrEmpty(dto.Synonym), x => x.Synonym != null && x.Synonym.Contains(dto.Synonym!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderWordDto>(total, _mapper.Map<IReadOnlyList<OrderWordDto>>(items));
- }
- /// <summary>
- /// 获取工单词库
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("order_word/{id}")]
- public async Task<OrderWord> OrderWordEntity(string id)
- {
- return await _orderWrodRepository.Queryable()
- .FirstAsync(x => x.Id == id);
- }
- /// <summary>
- /// 获取工单词库基本信息
- /// </summary>
- /// <returns></returns>
- [HttpGet("order_word/base")]
- public async Task<object> Base()
- {
- var rsp = new
- {
- OrderWordClassify = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.OrderWordClassify),
- };
- return rsp;
- }
- #endregion
- #region 工单观察
- /// <summary>
- /// 新增工单观察
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [Permission(EPermission.AddOrderObserve)]
- [HttpPost("order_observe")]
- public async Task Add([FromBody] OrderObserveAddDto dto)
- {
- var ids = dto.OrderIds.Select(x => x.OrderId).ToList();
- var list = await _orderObserveRepository.Queryable().In(x => x.OrderId, ids).Select(x => x.OrderId)
- .ToListAsync();
- if (list.Any())
- dto.OrderIds = ids.Except(list).Select(x => new OrdersObserveAddDto { OrderId = x }).ToList();
- if (!dto.OrderIds.Any())
- throw UserFriendlyException.SameMessage("无效工单观察,当前所选工单都已观察");
- var observe = _mapper.Map<List<OrderObserve>>(dto.OrderIds);
- await _orderObserveRepository.AddRangeAsync(observe, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除工单观察
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpDelete("order_observe")]
- public async Task Delete([FromBody] OrderObserveDeleteDto dto)
- {
- await _orderRepository.RemoveOrderObserveBatchAsync(dto.Ids, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 更新工单观察
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPut("order_observe")]
- public async Task Update([FromBody] OrderObserveUpdateDto dto)
- {
- var word = await _orderObserveRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (word is null)
- throw UserFriendlyException.SameMessage("无效工单观察");
- _mapper.Map(dto, word);
- await _orderObserveRepository.UpdateAsync(word, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取工单观察列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("order_observe/list")]
- public async Task<PagedDto<OrderObserveDto>> List([FromQuery] OrderObserveListDto dto)
- {
- var (total, items) = await _orderObserveRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(dto.IsProvince.HasValue, x => x.Order.IsProvince == dto.IsProvince)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
- //.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title!))
- //.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderObserveDto>(total, _mapper.Map<IReadOnlyList<OrderObserveDto>>(items));
- }
- /// <summary>
- /// 获取工单观察
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("order_observe/{id}")]
- public async Task<OrderObserve> OrderObserveEntity(string id)
- {
- return await _orderObserveRepository.Queryable()
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 工单终结
- /// <summary>
- /// 新增工单终结
- /// </summary>
- /// <param name="dtos"></param>
- /// <returns></returns>
- [Permission(EPermission.AddOrderFinality)]
- [HttpPost("order_finality")]
- public async Task Add([FromBody] OrderFinalityAddDto dto)
- {
- var ids = dto.OrderIds.Select(x => x.OrderId).ToList();
- var list = await _orderFinalityRepository.Queryable().In(x => x.OrderId, ids).Select(x => x.OrderId)
- .ToListAsync();
- if (list.Any())
- dto.OrderIds = ids.Except(list).Select(x => new OrdersFinalityAddDto { OrderId = x }).ToList();
- if (!dto.OrderIds.Any())
- throw UserFriendlyException.SameMessage("无效工单终结,当前所选工单都已终结");
- var observe = _mapper.Map<List<OrderFinality>>(dto.OrderIds);
- await _orderFinalityRepository.AddRangeAsync(observe, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 删除工单终结
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpDelete("order_finality")]
- public async Task Delete([FromBody] OrderFinalityDeleteDto dto)
- {
- await _orderRepository.RemoveOrderFinalityBatchAsync(dto.Ids, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 更新工单终结
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpPut("order_finality")]
- public async Task Update([FromBody] OrderFinalityUpdateDto dto)
- {
- var word = await _orderFinalityRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
- if (word is null)
- throw UserFriendlyException.SameMessage("无效工单观察");
- _mapper.Map(dto, word);
- await _orderFinalityRepository.UpdateAsync(word, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 获取工单终结列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("order_finality/list")]
- public async Task<PagedDto<OrderFinalityDto>> List([FromQuery] OrderFinalityListDto dto)
- {
- var (total, items) = await _orderFinalityRepository.Queryable()
- .Includes(x => x.Order)
- .WhereIF(dto.IsProvince.HasValue, x => x.Order.IsProvince == dto.IsProvince)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
- x => x.Order.No.Contains(dto.Keyword!) || x.Order.Title.Contains(dto.Keyword!))
- //.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Order.Title.Contains(dto.Title!))
- //.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.Order.No.Contains(dto.No!))
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderFinalityDto>(total, _mapper.Map<IReadOnlyList<OrderFinalityDto>>(items));
- }
- /// <summary>
- /// 获取工单终结
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("order_finality/{id}")]
- public async Task<OrderFinality> OrderFinalityEntity(string id)
- {
- return await _orderFinalityRepository.Queryable()
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 超期查询
- /// <summary>
- /// 工单即将超期列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("order/about_expire/list")]
- public async Task<PagedDto<OrderDto>> AboutList([FromQuery] AboutToExpireListDto dto)
- {
- return await _orderRepository.GetAboutToExpireAsync(dto, HttpContext.RequestAborted);
- }
- ///// <summary>
- ///// 工单即将超期节点列表
- ///// </summary>
- ///// <param name="dto"></param>
- ///// <returns></returns>
- //[HttpGet("order/about_expire_node/list")]
- //public async Task<PagedDto<WorkflowOrderDto>> AboutNodeList([FromQuery] AboutToExpireListDto dto)
- //{
- // return await _orderRepository.GetAboutToExpireNodeAsync(dto, HttpContext.RequestAborted);
- //}
- /// <summary>
- /// 工单超期列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("order/expire/list")]
- public async Task<PagedDto<OrderDto>> List([FromQuery] AboutToExpireListDto dto)
- {
- return await _orderRepository.GetToExpireAsync(dto, HttpContext.RequestAborted);
- }
- ///// <summary>
- ///// 工单超期节点列表
- ///// </summary>
- ///// <param name="dto"></param>
- ///// <returns></returns>
- //[HttpGet("order/expire_node/list")]
- //public async Task<PagedDto<WorkflowOrderDto>> NodeList([FromQuery] AboutToExpireListDto dto)
- //{
- // return await _orderRepository.GetToExpireNodeAsync(dto, HttpContext.RequestAborted);
- //}
- #endregion
- #region 工单签收
- /// <summary>
- /// 工单签收
- /// </summary>
- [HttpPost("sign/{orderId}")]
- public async Task Sign(string orderId)
- {
- var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
- if (order == null)
- throw new UserFriendlyException($"无效工单编号, orderId: {orderId}", "无效工单编号");
- if (order.IsSigned())
- throw new UserFriendlyException("该工单已被签收");
- order.Sign(_sessionContext.RequiredUserId, _sessionContext.UserName);
- await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
- }
- #endregion
- }
|