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; using Hotline.Application.Orders; using Hotline.Share.Requests; using Hotline.Tools; namespace Hotline.Api.Controllers { /// /// 终止管理 /// public class OrderTerminateController : BaseController { private readonly ISessionContext _sessionContext; private readonly IMapper _mapper; private readonly IFileRepository _fileRepository; private readonly IWorkflowApplication _workflowApplication; private readonly IRepository _workflowRepository; private readonly IWorkflowDomainService _workflowDomainService; private readonly IOrderRepository _orderRepository; private readonly IOrderDomainService _orderDomainService; private readonly IOrderTerminateRepository _orderTerminateRepository; private readonly IOrderApplication _orderApplication; public OrderTerminateController( ISessionContext sessionContext, IMapper mapper, IFileRepository fileRepository, IWorkflowApplication workflowApplication, IRepository workflowRepository, IWorkflowDomainService workflowDomainService, IOrderRepository orderRepository, IOrderDomainService orderDomainService, IOrderTerminateRepository orderTerminateRepository, IOrderApplication orderApplication ) { _sessionContext = sessionContext; _mapper = mapper; _fileRepository = fileRepository; _workflowApplication = workflowApplication; _workflowRepository = workflowRepository; _workflowDomainService = workflowDomainService; _orderRepository = orderRepository; _orderDomainService = orderDomainService; _orderTerminateRepository = orderTerminateRepository; _orderApplication= orderApplication; } /// /// 工单终止待申请列表 /// /// /// [HttpGet("may-terminate")] public async Task> MayOrderTerminateList([FromQuery] OrderTerminateListDto dto) { var isAdmin = _orderDomainService.IsCheckAdmin(); var (total, items) =await _orderRepository.Queryable(isAdmin:isAdmin) .Includes(d=>d.OrderTerminates) .Where(d=> SqlFunc.Subqueryable().Where(t=> t.OrderId == d.Id && t.Status != ETerminateStatus.SendBackStart).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(total, _mapper.Map>(items)); } /// /// 工单终止列表 /// /// /// [HttpGet] public async Task> OrderTerminateList([FromQuery] OrderTerminateListDto dto) { var (total, items) = await _orderApplication.OrderTerminateList(dto) .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted); return new PagedDto(total, _mapper.Map>(items)); } /// /// 工单终止列表导出 /// /// /// [HttpPost("export")] public async Task OrderTerminateListExport([FromBody] ExportExcelDto dto) { var query = _orderApplication.OrderTerminateList(dto.QueryDto); List data; if (dto.IsExportAll) { data = await query.ToListAsync(HttpContext.RequestAborted); } else { var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted); data = items; } var dataDtos = _mapper.Map>(data); dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos); var dtos = dataDtos .Select(stu => _mapper.Map(stu, typeof(OrderTerminateEntityDto), dynamicClass)) .Cast() .ToList(); var stream = ExcelHelper.CreateStream(dtos); return ExcelStreamResult(stream, "工单终止列表"); } /// /// 开始工单终止流程 /// [HttpPost("startflow")] [LogFilter("开始工单终止流程")] public async Task StartFlow([FromBody] StartWorkflowDto 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(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(); await _orderTerminateRepository.AddAsync(model, HttpContext.RequestAborted); try { var startDto = _mapper.Map(dto.Workflow); startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderTerminate; startDto.Opinion = dto.Data.Content; startDto.Title = "申请终止流程"; await _workflowApplication.StartWorkflowAsync(startDto, model.Id, cancellationToken: HttpContext.RequestAborted); } catch (Exception e) { await _orderTerminateRepository.RemoveAsync(model.Id); model.Id = string.Empty; throw new UserFriendlyException($"工单开启终止流程失败!, {e.Message}", "工单开启终止流程失败"); } } /// /// 工单终止修改后下一步流程 /// [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(); model.Content = dto.Data.Content; model.IsRecommit = true; await _orderTerminateRepository.UpdateAsync(model, HttpContext.RequestAborted); try { dto.NextWorkflow.WorkflowId = model.WorkflowId; await _workflowDomainService.NextAsync(_sessionContext, dto.NextWorkflow, cancellationToken: HttpContext.RequestAborted); } catch (Exception e) { throw new UserFriendlyException($"工单终止下一步流程失败!, {e.Message}", "工单终止下一步流程失败"); } } /// /// 查询工单终止流程开启参数 /// /// [HttpGet("screen/startflow")] public async Task GetTerminateFlowStartOptionsAsync() { return await _workflowApplication.GetStartStepsAsync(WorkflowModuleConsts.OrderTerminate, HttpContext.RequestAborted); } /// /// 查询工单终止流程参数 /// /// [HttpGet("workflow/{id}")] public async Task GetTerminateWorkFlowAsync(string id) { var workflow = await _workflowRepository.Queryable().FirstAsync(x => x.ExternalId == id); return workflow.Id; } /// /// 甄别查询流程办理下一步可选节点 /// /// /// [HttpGet("{workflowId}/nextsteps")] public async Task OrderTerminateNextsteps(string workflowId) { return await _workflowApplication.GetNextStepsAsync(workflowId, HttpContext.RequestAborted); } /// /// 终止详情 /// /// /// [HttpGet("{id}")] public async Task 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(model); rspModel.IsCanHandle = model.Workflow?.IsCanHandle( _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles) ?? false; if (model.Status == ETerminateStatus.SendBackStart) 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; } /// /// 列表页面基础数据 /// /// [HttpGet("base")] public async Task BaseData() { var rsp = new { Status = EnumExts.GetDescriptions(), }; return rsp; } /// /// 终止修改理由 /// /// /// [HttpPut("update_content")] [LogFilter("终止修改理由")] public async Task Update([FromBody] OrderTerminateContentDto dto) { await _orderTerminateRepository.Updateable().SetColumns(x => new OrderTerminate { Content = dto.Content }).Where(x => x.Id == dto.Id).ExecuteCommandAsync(); } } }