|
@@ -0,0 +1,252 @@
|
|
|
+using Hotline.Orders;
|
|
|
+using Hotline.Permissions;
|
|
|
+using Hotline.Quality;
|
|
|
+using Hotline.Share.Dtos.Quality;
|
|
|
+using Hotline.Share.Dtos;
|
|
|
+using Microsoft.AspNetCore.Mvc;
|
|
|
+using XF.Domain.Authentications;
|
|
|
+using XF.Domain.Exceptions;
|
|
|
+using XF.Domain.Repository;
|
|
|
+using Hotline.Api.Filter;
|
|
|
+using Hotline.Caching.Services;
|
|
|
+using Hotline.FlowEngine.WorkflowModules;
|
|
|
+using Hotline.Repository.SqlSugar.Orders;
|
|
|
+using Hotline.Settings;
|
|
|
+using Hotline.Share.Dtos.FlowEngine;
|
|
|
+using Hotline.Share.Dtos.Order;
|
|
|
+using Hotline.Share.Enums.FlowEngine;
|
|
|
+using Hotline.Share.Enums.Order;
|
|
|
+using Hotline.Share.Enums.Settings;
|
|
|
+using SqlSugar;
|
|
|
+using XF.Utility.EnumExtensions;
|
|
|
+using MapsterMapper;
|
|
|
+using Hotline.File;
|
|
|
+using Hotline.Application.FlowEngine;
|
|
|
+using Hotline.FlowEngine.Workflows;
|
|
|
+using Hotline.Repository.SqlSugar.Extensions;
|
|
|
+
|
|
|
+namespace Hotline.Api.Controllers
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 终止管理
|
|
|
+ /// </summary>
|
|
|
+ public class OrderTerminateController : BaseController
|
|
|
+ {
|
|
|
+ private readonly ISessionContext _sessionContext;
|
|
|
+ private readonly IMapper _mapper;
|
|
|
+ private readonly IFileRepository _fileRepository;
|
|
|
+ private readonly IWorkflowApplication _workflowApplication;
|
|
|
+ private readonly IRepository<Workflow> _workflowRepository;
|
|
|
+ private readonly IWorkflowDomainService _workflowDomainService;
|
|
|
+ private readonly IOrderRepository _orderRepository;
|
|
|
+ private readonly IOrderDomainService _orderDomainService;
|
|
|
+ private readonly IOrderTerminateRepository _orderTerminateRepository;
|
|
|
+
|
|
|
+ public OrderTerminateController(
|
|
|
+ ISessionContext sessionContext,
|
|
|
+ IMapper mapper,
|
|
|
+ IFileRepository fileRepository,
|
|
|
+ IWorkflowApplication workflowApplication,
|
|
|
+ IRepository<Workflow> workflowRepository,
|
|
|
+ IWorkflowDomainService workflowDomainService,
|
|
|
+ IOrderRepository orderRepository,
|
|
|
+ IOrderDomainService orderDomainService,
|
|
|
+ IOrderTerminateRepository orderTerminateRepository
|
|
|
+ )
|
|
|
+ {
|
|
|
+ _sessionContext = sessionContext;
|
|
|
+ _mapper = mapper;
|
|
|
+ _fileRepository = fileRepository;
|
|
|
+ _workflowApplication = workflowApplication;
|
|
|
+ _workflowRepository = workflowRepository;
|
|
|
+ _workflowDomainService = workflowDomainService;
|
|
|
+ _orderRepository = orderRepository;
|
|
|
+ _orderDomainService = orderDomainService;
|
|
|
+ _orderTerminateRepository = orderTerminateRepository;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 工单终止待申请列表
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [Permission(EPermission.CanOrderScreen)]
|
|
|
+ [HttpGet("may-terminate")]
|
|
|
+ public async Task<PagedDto<OrderDto>> MayScreenList([FromQuery] OrderTerminateListDto dto)
|
|
|
+ {
|
|
|
+ var isAdmin = _orderDomainService.IsCheckAdmin();
|
|
|
+ var (total, items) =await _orderRepository.Queryable(isAdmin:isAdmin)
|
|
|
+ .Includes(d=>d.OrderTerminates)
|
|
|
+ .Where(d=> SqlFunc.Subqueryable<OrderTerminate>().Where(t=>t.Status == ETerminateStatus.End || t.Status == ETerminateStatus.Refuse).NotAny())
|
|
|
+ .Where(d => d.Status >= EOrderStatus.Filed && d.ActualHandleOrgCode.StartsWith(_sessionContext.OrgId))
|
|
|
+ .WhereIF(!string.IsNullOrEmpty(dto.No),d=>d.No!.Contains(dto.No!))
|
|
|
+ .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title!.Contains(dto.Title!))
|
|
|
+ .WhereIF(dto.ApplyStartTime.HasValue && dto.ApplyEndTime.HasValue,
|
|
|
+ d => d.OrderTerminates.Any(t=>t.CreationTime >= dto.ApplyStartTime && t.CreationTime<= dto.ApplyEndTime))
|
|
|
+ .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue,d=>d.StartTime >= dto.StartTime && d.StartTime <= dto.EndTime)
|
|
|
+ .OrderByDescending(d => d.StartTime)
|
|
|
+ .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>
|
|
|
+ [HttpGet]
|
|
|
+ public async Task<PagedDto<OrderTerminateEntityDto>> ScreenList([FromQuery] OrderTerminateListDto dto)
|
|
|
+ {
|
|
|
+ var isAdmin = _orderDomainService.IsCheckAdmin();
|
|
|
+ var (total, items) = await _orderTerminateRepository.Queryable(hasHandled: false, isAdmin: isAdmin)
|
|
|
+ .Includes(d=>d.Order)
|
|
|
+ .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No!.Contains(dto.No!))
|
|
|
+ .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title!.Contains(dto.Title!))
|
|
|
+ .WhereIF(dto.ApplyStartTime.HasValue && dto.ApplyEndTime.HasValue,
|
|
|
+ d => d.CreationTime >= dto.ApplyStartTime && d.CreationTime <= dto.ApplyEndTime)
|
|
|
+ .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, d => d.Order.StartTime >= dto.StartTime && d.Order.StartTime <= dto.EndTime)
|
|
|
+ .OrderByDescending(d => d.CreationTime)
|
|
|
+ .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
|
|
|
+ return new PagedDto<OrderTerminateEntityDto>(total, _mapper.Map<IReadOnlyList<OrderTerminateEntityDto>>(items));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 开始工单终止流程
|
|
|
+ /// </summary>
|
|
|
+ [Permission(EPermission.ApplyTerminate)]
|
|
|
+ [HttpPost("startflow")]
|
|
|
+ [LogFilter("开始工单终止流程")]
|
|
|
+ public async Task StartFlow([FromBody] TerminateStartFlowDto dto)
|
|
|
+ {
|
|
|
+ var screenAny = await _orderTerminateRepository.AnyAsync(x =>
|
|
|
+ x.OrderId == dto.Data.OrderId && x.Status == ETerminateStatus.Approval);
|
|
|
+ if (screenAny)
|
|
|
+ throw UserFriendlyException.SameMessage("该工单已提起终止申请,正在审批过程中,不能申请");
|
|
|
+
|
|
|
+ var isNoPass = await _orderTerminateRepository.AnyAsync(x => x.Status == ETerminateStatus.Refuse && x.OrderId == dto.Data.OrderId);
|
|
|
+ if (isNoPass)
|
|
|
+ throw UserFriendlyException.SameMessage("该工单已被拒绝过甄别申请,不能再次申请");
|
|
|
+
|
|
|
+ var model = _mapper.Map<OrderTerminate>(dto.Data);
|
|
|
+ model.Status = ETerminateStatus.Approval ;
|
|
|
+ model.InitId();
|
|
|
+ if (dto.Data.Files.Any())
|
|
|
+ model.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, model.Id, "", HttpContext.RequestAborted);
|
|
|
+ else
|
|
|
+ model.FileJson = new List<Share.Dtos.File.FileJson>();
|
|
|
+ await _orderTerminateRepository.AddAsync(model, HttpContext.RequestAborted);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
|
|
|
+ startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderTerminate;
|
|
|
+ startDto.Opinion = dto.Data.Content;
|
|
|
+ startDto.Title = "申请终止流程";
|
|
|
+ await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
|
|
|
+ cancellationToken: HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ await _orderTerminateRepository.RemoveAsync(model.Id);
|
|
|
+ model.Id = string.Empty;
|
|
|
+ throw new UserFriendlyException($"工单开启终止流程失败!, {e.Message}", "工单开启终止流程失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 工单终止修改后下一步流程
|
|
|
+ /// </summary>
|
|
|
+ [HttpPost("initial_nextFlow")]
|
|
|
+ [LogFilter("办理工单终止流程")]
|
|
|
+ public async Task InitialNextFlow([FromBody] TerminateNextFlowDto dto)
|
|
|
+ {
|
|
|
+ var model = await _orderTerminateRepository.GetAsync(dto.Data.Id);
|
|
|
+
|
|
|
+ if (dto.Data.Files.Any())
|
|
|
+ model.FileJson = await _fileRepository.AddFileAsync(dto.Data.Files, model.Id, "", HttpContext.RequestAborted);
|
|
|
+ else
|
|
|
+ model.FileJson = new List<Share.Dtos.File.FileJson>();
|
|
|
+
|
|
|
+ model.Content = dto.Data.Content;
|
|
|
+ model.IsRecommit = true;
|
|
|
+ await _orderTerminateRepository.UpdateAsync(model, HttpContext.RequestAborted);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ dto.NextWorkflow.WorkflowId = model.WorkflowId;
|
|
|
+ await _workflowApplication.NextAsync(dto.NextWorkflow, _sessionContext,
|
|
|
+ cancellationToken: HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ throw new UserFriendlyException($"工单终止下一步流程失败!, {e.Message}", "工单终止下一步流程失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 查询工单终止流程开启参数
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("screen/startflow")]
|
|
|
+ public async Task<NextStepsDto> GetTerminateFlowStartOptionsAsync()
|
|
|
+ {
|
|
|
+ return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.OrderTerminate,
|
|
|
+ HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 查询工单终止流程参数
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("workflow/{id}")]
|
|
|
+ public async Task<string> GetTerminateWorkFlowAsync(string id)
|
|
|
+ {
|
|
|
+ var workflow = await _workflowRepository.Queryable().FirstAsync(x => x.ExternalId == id);
|
|
|
+ return workflow.Id;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 甄别查询流程办理下一步可选节点
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="workflowId"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("{workflowId}/nextsteps")]
|
|
|
+ public async Task<NextStepsDto> OrderTerminateNextsteps(string workflowId)
|
|
|
+ {
|
|
|
+ return await _workflowApplication.GetNextStepsAsync(workflowId, HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 终止详情
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="id"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpGet("{id}")]
|
|
|
+ public async Task<OrderTerminateEntityDto> Entity(string id)
|
|
|
+ {
|
|
|
+ var model = await _orderTerminateRepository.Queryable()
|
|
|
+ .Includes(x => x.Order)
|
|
|
+ .Includes(x => x.Workflow, d => d.Steps)
|
|
|
+ .FirstAsync(x => x.Id == id);
|
|
|
+ var rspModel = _mapper.Map<OrderTerminateEntityDto>(model);
|
|
|
+ rspModel.IsCanHandle = model.Workflow?.IsCanHandle(
|
|
|
+ _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles) ?? false;
|
|
|
+ if (model.Status == ETerminateStatus.SendBack)
|
|
|
+ rspModel.IsCanHandle = false;
|
|
|
+ rspModel.Handle = false;
|
|
|
+ if (!string.IsNullOrEmpty(rspModel.WorkflowId))
|
|
|
+ {
|
|
|
+ rspModel.Handle = await _workflowDomainService.CheckCurrentIsStartStepAsync(rspModel.WorkflowId, _sessionContext.RequiredUserId,
|
|
|
+ _sessionContext.RequiredOrgId, HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rspModel.FileJson != null && rspModel.FileJson.Any())
|
|
|
+ {
|
|
|
+ var ids = rspModel.FileJson.Select(x => x.Id).ToList();
|
|
|
+ rspModel.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
|
|
|
+ }
|
|
|
+ return rspModel;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|