12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349 |
- using DotNetCore.CAP;
- using Hotline.Application.FlowEngine;
- using Hotline.Application.TimeLimits;
- using Hotline.Caching.Interfaces;
- using Hotline.File;
- using Hotline.FlowEngine.Definitions;
- using Hotline.FlowEngine.WfModules;
- using Hotline.FlowEngine.Workflows;
- using Hotline.Orders;
- using Hotline.Orders.Notifications;
- using Hotline.Permissions;
- 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.Enums.Order;
- using Hotline.Share.Enums.Settings;
- using Hotline.Share.Mq;
- using Hotline.Share.Requests;
- using MapsterMapper;
- using MediatR;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.IdentityModel.Tokens;
- using MongoDB.Driver;
- using SqlSugar;
- using System.Threading;
- using XF.Domain.Authentications;
- using XF.Domain.Constants;
- using XF.Domain.Exceptions;
- using XF.Domain.Repository;
- using XF.Utility.EnumExtensions;
- 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 ISystemDomainService _systemDomainService;
- 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 IRepository<OrderDelay> _orderDelayRepository;
- private readonly ITimeLimitApplication _timeLimitApplication;
- 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 ITimeLimitDomainService _timeLimitDomainService;
- public OrderController(
- IOrderDomainService orderDomainService,
- IOrderRepository orderRepository,
- IWorkflowApplication workflowApplication,
- IWorkflowDomainService workflowDomainService,
- IRepository<Hotspot> hotspotTypeRepository,
- ISystemDomainService systemDomainService,
- ISystemOrganizeRepository organizeRepository,
- IDefinitionDomainService definitionDomainService,
- ISystemDicDataCacheManager sysDicDataCacheManager,
- ISessionContext sessionContext,
- IMapper mapper,
- IMediator mediator,
- IRepository<OrderPublish> orderPublishRepository,
- IRepository<OrderVisit> orderVisitRepository,
- IRepository<OrderVisitDetail> orderVisitedDetailRepository,
- ICapPublisher capPublisher,
- IRepository<OrderDelay> orderDelayRepository,
- ITimeLimitApplication timeLimitApplication,
- ISystemSettingCacheManager systemSettingCacheManager,
- IRepository<OrderRedo> orderRedoRepository,
- IRepository<OrderSupervise> orderSuperviseRepository,
- IRepository<OrderUrge> orderUrgeRepository,
- IFileRepository fileRepository,
- IRepository<OrderScreen> orderScreenRepository,
- IRepository<OrderPublishHistory> orderPublishHistoryRepository,
- IRepositoryTextSearch<OrderTs> repositoryts,
- ITimeLimitDomainService timeLimitDomainService
- )
- {
- _orderDomainService = orderDomainService;
- _orderRepository = orderRepository;
- _workflowApplication = workflowApplication;
- _workflowDomainService = workflowDomainService;
- _hotspotTypeRepository = hotspotTypeRepository;
- _systemDomainService = systemDomainService;
- _organizeRepository = organizeRepository;
- _definitionDomainService = definitionDomainService;
- _sysDicDataCacheManager = sysDicDataCacheManager;
- _sessionContext = sessionContext;
- _mapper = mapper;
- _mediator = mediator;
- _orderPublishRepository = orderPublishRepository;
- _orderVisitRepository = orderVisitRepository;
- _orderVisitedDetailRepository = orderVisitedDetailRepository;
- _capPublisher = capPublisher;
- _orderDelayRepository = orderDelayRepository;
- _timeLimitApplication = timeLimitApplication;
- _systemSettingCacheManager = systemSettingCacheManager;
- _orderRedoRepository = orderRedoRepository;
- _orderSuperviseRepository = orderSuperviseRepository;
- _orderUrgeRepository = orderUrgeRepository;
- _fileRepository = fileRepository;
- _orderScreenRepository = orderScreenRepository;
- _orderPublishHistoryRepository = orderPublishHistoryRepository;
- _repositoryts = repositoryts;
- _timeLimitDomainService = timeLimitDomainService;
- }
- #region 工单发布
- /// <summary>
- /// 查询(工单发布)
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.PublishOrderList)]
- [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);
- var orderVisit = new OrderVisit();
- orderVisit.No = order.No;
- orderVisit.OrderId = order.Id;
- orderVisit.VisitState = EVisitState.WaitForVisit;
- orderVisit.PublishTime = DateTime.Now;
- string visitId = await _orderVisitRepository.AddAsync(orderVisit);
- //新增回访信息
- var visitedDetail = new List<OrderVisitDetail>();
- var seatDetail = new OrderVisitDetail();
- seatDetail.VisitId = visitId;
- seatDetail.VisitTarget = EVisitTarget.Seat;
- visitedDetail.Add(seatDetail);
- foreach (var item in dto.IdNames)
- {
- var orgDetail = new OrderVisitDetail();
- orgDetail.VisitId = visitId;
- orgDetail.VisitOrgCode = item.Id;
- orgDetail.VisitOrgName = item.Name;
- orgDetail.VisitTarget = EVisitTarget.Org;
- visitedDetail.Add(orgDetail);
- }
- await _mediator.Publish(new AddVisitNotify(visitedDetail), HttpContext.RequestAborted);
- //TODO 中国政府网
- if (order.SourceChannel == "ZGZFW")
- {
- }
- //TODO 省政民互动
- if (order.SourceChannel == "ZMHD")
- {
- }
- }
- /// <summary>
- /// 发布页面基础信息
- /// </summary>
- /// <returns></returns>
- [Permission(EPermission.PublishOrderPageBase)]
- [HttpGet("publish-order-pagebase/{id}")]
- public async Task<PublishOrderPageBaseDto> PublishOrderPageBase(string id)
- {
- var order = await _orderRepository.Queryable()
- .Includes(d => d.Acceptor)
- .Includes(d => d.OrderComplain)
- .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<IdName>();
- details.ForEach(f => pubentity.IdNames.Add(new IdName() { Id = f.VisitOrgCode, Name = 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>
- [Permission(EPermission.QueryPublishedHistory)]
- [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>
- [Permission(EPermission.QueryOrderVisitList)]
- [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)
- .WhereIF(dto.VisitState == EVisitStateQuery.Visited, x => x.VisitState == Share.Enums.Order.EVisitState.Visited)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.Contains(dto.Keyword!) || d.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>
- [Permission(EPermission.VisitInfo)]
- [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)
- .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);
- return new { OrderVisitModel = orderVisit, VisitCount = visitCount, AgainCount = againCount, VisitSatisfaction = visitSatisfaction, DissatisfiedReason = dissatisfiedReason, VisitManner = visitManner,ViceEvaluate= voiceEvaluate, SeatEvaluate = seatEvaluate };
- }
- /// <summary>
- /// 回访明细
- /// </summary>
- /// <returns></returns>
- [Permission(EPermission.VisitDetailList)]
- [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);
- //更新主表
- if (dto.IsPutThrough)
- {
- visit.VisitState = Share.Enums.Order.EVisitState.Visited;
- visit.VisitTime = DateTime.Now;
- visit.VisitType = EVisitType.ArtificialVisit;
- }
- visit.IsPutThrough = dto.IsPutThrough;
- visit.AgainState = dto.IsAgain ? EAgainState.NeedAgain : EAgainState.NoAgain;
- visit.EmployeeId = _sessionContext.UserId;
- if (first!=null)
- {
- visit.NowEvaluate = first.OrgProcessingResults;
- }
- //await _orderVisitRepository.UpdateAsync(visit,HttpContext.RequestAborted);
- //update order
- if (dto.IsPutThrough)
- {
- if (first!=null)
- {
- visit.Order.Visited(first.OrgProcessingResults.Id, first.OrgProcessingResults.Name);
- }
- //_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.Id, FirstSatisfactionCode = visit.Order.FirstVisitResultCode!, ClientGuid = "" });
- }
- }
- }
- #endregion
- #region 工单重办
- /// <summary>
- /// 重办查询
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.QueryOrderRedoRecord)]
- [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>
- [Permission(EPermission.OrderRedoRecord)]
- [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.Id;
- redo.RedoOrgCode = handler.Name;
- 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>
- [Permission(EPermission.CanDelayOrderList)]
- [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] ApplyDelayDto dto)
- {
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.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 == dto.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 == dto.OrderId);
- if (count > int.Parse(setting?.SettingValue[0]))
- throw UserFriendlyException.SameMessage("延期申请已超过系统预定设置,不能申请");
- var model = _mapper.Map<OrderDelay>(dto);
- model.EmployeeId = _sessionContext.UserId;
- model.ApplyOrgName = _sessionContext.OrgName;
- model.ApplyOrgCode = _sessionContext.OrgId;
- model.BeforeDelay = order.ExpiredTime;
- model.DelayState = EDelayState.Examining;
- if (model.BeforeDelay != null)
- {
- model.AfterDelay = _timeLimitApplication.CalcEndTime(model.BeforeDelay.Value, dto.DelayUnit, dto.DelayNum)?.EndTime;
- }
- model.ApplyDelayTime = DateTime.Now;
- model.No = order.No;
- await _orderDelayRepository.AddAsync(model, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 延期列表
- /// </summary>
- /// <returns></returns>
- [Permission(EPermission.DelayList)]
- [HttpGet("delay")]
- public async Task<PagedDto<OrderDelay>> DelayList([FromQuery] DelayListDto dto)
- {
- var (total, items) = await _orderDelayRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.IsApply, x => x.DelayState != EDelayState.Examining)
- .WhereIF(!dto.IsApply, x => x.DelayState == EDelayState.Examining)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderDelay>(total, _mapper.Map<IReadOnlyList<OrderDelay>>(items));
- }
- /// <summary>
- /// 延期详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.DelayEntity)]
- [HttpGet("delay/{id}")]
- public async Task<OrderDelay> DelayEntity(string id)
- {
- return await _orderDelayRepository.Queryable()
- .Includes(x => x.Order)
- .Includes(x => x.Employee)
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 工单甄别
- /// <summary>
- /// 工单甄别列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderScreenList)]
- [HttpGet("screen")]
- public async Task<PagedDto<OrderScreen>> ScreenList([FromQuery] ScreenListDto dto)
- {
- var (total, items) = await _orderScreenRepository.Queryable()
- .Includes(x => x.Visit, d => d.Order)
- .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Visit.Order.Title.Contains(dto.Keyword!) || d.Visit.Order.No.Contains(dto.Keyword!))
- .WhereIF(dto.Status == EScreenStatus.Apply || dto.Status == EScreenStatus.Approval || dto.Status == EScreenStatus.End, x => x.Status == dto.Status)
- .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
- .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
- .OrderByDescending(x => x.CreationTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- return new PagedDto<OrderScreen>(total, items);
- }
- /// <summary>
- /// 开始工单甄别流程
- /// </summary>
- [Permission(EPermission.ApplyScreen)]
- [HttpPost("screen/startflow")]
- public async Task StartFlow([FromBody] ScreenStartFlowDto dto)
- {
- 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.Value;
- if (DateTime.Now > endTime)
- throw UserFriendlyException.SameMessage("甄别申请时限已超过系统预定设置,不能申请");
- var model = _mapper.Map<OrderScreen>(dto.Data);
- model.Status = EScreenStatus.Apply;
- model.ApplyEndTime = endTime;
- var id = await _orderScreenRepository.AddAsync(model, HttpContext.RequestAborted);
- if (dto.Data.Files.Any()) await _fileRepository.AddFileAsync(dto.Data.Files, id, HttpContext.RequestAborted);
- try
- {
- var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
- startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderHandle;
- startDto.Title = dto.Data.Content;
- await _workflowApplication.StartWorkflowAsync(startDto, id, HttpContext.RequestAborted);
- }
- catch (Exception e)
- {
- await _orderScreenRepository.RemoveAsync(id);
- throw new UserFriendlyException($"工单开启甄别流程失败!, {e.Message}", "工单开启甄别流程失败");
- }
- }
- /// <summary>
- /// 查询工单甄别流程开启参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("screen/startflow")]
- public async Task<DefinedStepDto> GetScreenFlowStartOptionsAsync()
- {
- return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.OrderScreen, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 列表页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("screen/base")]
- public async Task<object> ScreenBaseData()
- {
- var rsp = new
- {
- ScreenStatus = EnumExts.GetDescriptions<EScreenStatus>(),
- ScreenType = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ScreenType),
- };
- return rsp;
- }
- /// <summary>
- /// 甄别详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.ScreenEntity)]
- [HttpGet("screen/{id}")]
- public async Task<OrderScreen> ScreenEntity(string id)
- {
- return await _orderScreenRepository.Queryable()
- .Includes(x => x.Visit, d => d.Order)
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 工单督办
- /// <summary>
- /// 工单督办列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.SuperviseOrderList)]
- [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)
- .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<string> ApplySupervise([FromBody] ApplyOrderSuperviseDto dto)
- {
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- var model = _mapper.Map<OrderSupervise>(dto);
- model.CreatorOrgName = _sessionContext.OrgName;
- model.CrUser = _sessionContext.UserName;
- model.State = 0;
- var id = await _orderSuperviseRepository.AddAsync(model, HttpContext.RequestAborted);
- if (dto.Files.Any()) await _fileRepository.AddFileAsync(dto.Files, id, HttpContext.RequestAborted);
- if (dto.AcceptSms)
- {
- //TODO 发送短信
- }
- return id;
- }
- /// <summary>
- /// 回复督办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ReplySupervise)]
- [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()) await _fileRepository.AddFileAsync(dto.Files, supervise.Id, HttpContext.RequestAborted);
- await _orderSuperviseRepository.UpdateAsync(supervise, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 签收督办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.SignSupervise)]
- [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.SignTime = DateTime.Now;
- supervise.SignUser = _sessionContext.UserName;
- await _orderSuperviseRepository.UpdateAsync(supervise, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 督办详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.SuperviseEntity)]
- [HttpGet("supervise/{id}")]
- public async Task<OrderSupervise> SuperviseEntity(string id)
- {
- return await _orderSuperviseRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- }
- #endregion
- #region 工单催办
- /// <summary>
- /// 工单催办列表
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.UrgeOrderList)]
- [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.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)
- .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<string> ApplyUrge([FromBody] ApplyOrderUrgeDto dto)
- {
- //验证工单是否可以申请
- var order = await _orderRepository.GetAsync(dto.OrderId, HttpContext.RequestAborted);
- if (order is null)
- throw UserFriendlyException.SameMessage("无效工单");
- var model = _mapper.Map<OrderUrge>(dto);
- model.CreatorOrgName = _sessionContext.OrgName;
- model.CrUser = _sessionContext.UserName;
- model.State = 0;
- var id = await _orderUrgeRepository.AddAsync(model, HttpContext.RequestAborted);
- if (dto.Files.Any()) await _fileRepository.AddFileAsync(dto.Files, id, HttpContext.RequestAborted);
- if (dto.AcceptSms)
- {
- //TODO 发送短信
- }
- return id;
- }
- /// <summary>
- /// 回复催办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.ReplyUrge)]
- [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()) await _fileRepository.AddFileAsync(dto.Files, urge.Id, HttpContext.RequestAborted);
- await _orderUrgeRepository.UpdateAsync(urge, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 签收催办
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.SignUrge)]
- [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.SignUser = _sessionContext.UserName;
- urge.SignTime = DateTime.Now;
- await _orderUrgeRepository.UpdateAsync(urge, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 催办详情
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.UrgeEntity)]
- [HttpGet("urge/{id}")]
- public async Task<OrderUrge> UrgeEntity(string id)
- {
- return await _orderUrgeRepository.Queryable()
- .Includes(x => x.Order)
- .FirstAsync(x => x.Id == id);
- }
- #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()
- .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))
- .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.OrderHistory)]
- [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>
- [Permission(EPermission.GetOrder)]
- [HttpGet("{id}")]
- public async Task<OrderDto> Get(string id)
- {
- var order = await _orderRepository.Queryable()
- .Includes(d => d.Acceptor)
- .Includes(d => d.OrderComplain)
- .Includes(d => d.OrderReport)
- .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, withAssigns: true,
- cancellationToken: HttpContext.RequestAborted);
- order.Workflow = workflow;
- canHandle = handlePermission;
- await _mediator.Publish(new GetOrderDetailNotify(order.Workflow, _sessionContext.RequiredUserId,
- _sessionContext.UserName, _sessionContext.RequiredOrgId, _sessionContext.OrgName));
- }
- var dto = _mapper.Map<OrderDto>(order!);
- if (order?.Workflow != null)
- dto.Workflow.CanHandle = canHandle;
- return dto;
- }
- /// <summary>
- /// 新增工单
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderAdd)]
- [HttpPost]
- public async Task<string> Add([FromBody] AddOrderDto dto)
- {
- var order = _mapper.Map<Order>(dto);
- var orderId = await _orderDomainService.AddAsync(order, HttpContext.RequestAborted);
- if (dto.Tags.Any()) await _repositoryts.AddVectorAsync(orderId, DateTime.Now, dto.Tags, HttpContext.RequestAborted);
- if (dto.Files.Any()) await _fileRepository.AddFileAsync(dto.Files, orderId, HttpContext.RequestAborted);
- return orderId;
- }
- /// <summary>
- /// 删除工单
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [Permission(EPermission.OrderRemove)]
- [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()
- .Includes(d => d.OrderComplain)
- .Includes(d => d.OrderReport)
- .FirstAsync(d => d.Id == dto.Id);
- if (order == null)
- throw UserFriendlyException.SameMessage("无效工单编号");
- if (order.Status != EOrderStatus.WaitForAccept || !string.IsNullOrEmpty(order.WorkflowId))
- throw UserFriendlyException.SameMessage("工单已发起流程");
- if (order?.OrderComplain is not null)
- await _orderRepository.RemoveOrderComplainAsync(order.OrderComplain, HttpContext.RequestAborted);
- if (order?.OrderReport is not null)
- await _orderRepository.RemoveOrderReportAsync(order.OrderReport, HttpContext.RequestAborted);
- if (dto.Tags.Any()) await _repositoryts.UpdateVectorAsync(dto.Id, dto.Tags, HttpContext.RequestAborted);
- _mapper.Map(dto, order);
- await _orderRepository.UpdateOrderNavAsync(order, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 开始流程
- /// </summary>
- /// <param name="id">工单id</param>
- /// <param name="dto">流程开启参数</param>
- /// <returns></returns>
- [HttpPost("{id}/startflow")]
- [Obsolete]
- public async Task StartFlow(string id, [FromBody] StartWorkflowDto dto)
- {
- var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
- if (order == null)
- throw UserFriendlyException.SameMessage("无效工单编号");
- if (order.Status != EOrderStatus.WaitForAccept || !string.IsNullOrEmpty(order.WorkflowId))
- throw UserFriendlyException.SameMessage("工单已发起流程");
- dto.DefinitionModuleCode = WorkflowModuleConsts.OrderHandle;
- dto.Title = order.Title;
- order.StartManageFlow();
- await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
- await _workflowApplication.StartWorkflowAsync(dto, order.Id, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 开始工单办理流程
- /// </summary>
- [HttpPost("startflow")]
- public async Task StartFlow([FromBody] OrderStartFlowDto dto)
- {
- var id = dto.Data.Id;
- if (string.IsNullOrEmpty(dto.Data.Id))
- {
- id = await Add(_mapper.Map<AddOrderDto>(dto.Data));
- }
- else
- {
- await Update(dto.Data);
- }
- try
- {
- var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
- startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderHandle;
- startDto.Title = dto.Data.Title;
- await _workflowApplication.StartWorkflowAsync(startDto, id, HttpContext.RequestAborted);
- }
- catch (Exception e)
- {
- await Remove(id);
- throw new UserFriendlyException($"工单开启流程失败!, {e.Message}", "工单开启流程失败");
- }
- }
- /// <summary>
- /// 查询工单办理流程开启参数
- /// </summary>
- /// <returns></returns>
- [HttpGet("startflow")]
- public async Task<DefinedStepDto> GetFlowStartOptionsAsync()
- {
- return await _workflowApplication.GetStartOptionsAsync(WorkflowModuleConsts.OrderHandle, HttpContext.RequestAborted);
- }
- /// <summary>
- /// 列表页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data")]
- public async Task<object> BaseData()
- {
- var rsp = new
- {
- AcceptTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.AcceptType),//EnumExts.GetDescriptions<EAcceptType>(),
- ChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel),
- OrgsOptions = await _organizeRepository.GetOrgJson(),
- EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
- PushTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(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 = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.AcceptType),
- EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
- PushTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.PushType),
- GenderOptions = EnumExts.GetDescriptions<EGender>(),
- IdentityTypeOptions = EnumExts.GetDescriptions<EIdentityType>(),
- LicenceTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.LicenceType),
- AgeRangeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.AgeRange),
- OrderTypeOptions = EnumExts.GetDescriptions<EOrderType>(),
- };
- return rsp;
- }
- /// <summary>
- /// 扩展信息新增页面基础数据
- /// </summary>
- /// <returns></returns>
- [HttpGet("base-data-ext")]
- public async Task<object> BaseDataExtension()
- {
- var rsp = new
- {
- LicenceTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.LicenceType),
- IdentityTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ProviderIdentityType),
- IdentityOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.Identity),
- NationalityOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.Nationality),
- NationOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.Nation),
- MarketTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.MarketType),
- IndustryClassifyOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.IndustryClassify),
- BrandOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.Brand),
- ObjectClassifyOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ObjectClassify),
- ComplainClassifyOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ComplainClassify),
- ReportClassifyOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ReportClassify),
- SalesModeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.SalesMode),
- ECommercePlatformOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.ECommercePlatform),
- PatentTypeOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.PatentType),
- AffairTargetOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.AffairTarget),
- ComplainTypeOptions = EnumExts.GetDescriptions<EComplainType>().Select(d => new IdName(d.Key.ToString(), d.Value)),
- SalesChannelOptions = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.SalesChannel),
- };
- return rsp;
- }
- #endregion
- #region 工单待办
- /// <summary>
- /// 查询待办工单
- /// </summary>
- /// <param name="dto"></param>
- /// <returns></returns>
- [HttpGet("waited")]
- public async Task<PagedDto<OrderWaitedDto>> QueryWaited([FromQuery] PagedRequest dto)
- {
- if (dto.PageSize > 100)
- dto.PageSize = 100;
- var (total, items) = await _orderRepository.Queryable()
- .OrderBy(d => d.ExpiredTime)
- .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
- var dtos = _mapper.Map<IReadOnlyList<OrderWaitedDto>>(items);
- //calc expired description
- var now = DateTime.Now;
- foreach (var waitedDto in dtos)
- {
- var ts = waitedDto.ExpiredTime - now;
- if (ts.Value.TotalDays <= 0)
- {
- //已超期
- waitedDto.ExpiredDescription = $"已超期{Math.Abs(ts.Value.TotalDays):F1}天";
- }
- else
- {
- //未超期
- waitedDto.ExpiredDescription = $"{ts.Value.TotalDays:F1}天后超期";
- }
- }
- return new PagedDto<OrderWaitedDto>(total, dtos);
- }
- #endregion
- }
|