using Hotline.FlowEngine.Workflows;
using Hotline.Share.Dtos.FlowEngine;
using Hotline.Share.Dtos.FlowEngine.Workflow;
using Hotline.Share.Dtos.Order.OrderDelay;
using Hotline.Share.Enums.FlowEngine;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using System.Threading;
using Hotline.Authentications;
using Hotline.BatchTask;
using Hotline.Orders;
using Hotline.Share.Dtos.BatchTask;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.BatchTask;
using Hotline.Share.Enums.Order;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Dependency;
using XF.Domain.Entities;
using XF.Domain.Exceptions;
namespace Hotline.Application.OrderApp.OrderDelayApp;
public class OrderDelayApplication : IOrderDelayApplication, IScopeDependency
{
private readonly IOrderDomainService _orderDomainService;
private readonly IOrderDelayRepository _orderDelayRepository;
private readonly IWorkflowDomainService _workflowDomainService;
private readonly IApptaskDomainService _apptaskDomainService;
private readonly ISessionContext _sessionContext;
private readonly IMapper _mapper;
public OrderDelayApplication(
IOrderDomainService orderDomainService,
IOrderDelayRepository orderDelayRepository,
IWorkflowDomainService workflowDomainService,
IApptaskDomainService apptaskDomainService,
ISessionContext sessionContext,
IMapper mapper)
{
_orderDomainService = orderDomainService;
_orderDelayRepository = orderDelayRepository;
_workflowDomainService = workflowDomainService;
_apptaskDomainService = apptaskDomainService;
_sessionContext = sessionContext;
_mapper = mapper;
}
///
/// 查询延期待审批列表
///
///
public ISugarQueryable QueryWaited(DelayListDto dto)
{
var isAdmin = _orderDomainService.IsCheckAdmin();
var hasHandled = dto.IsApply.HasValue && dto.IsApply.Value;
var query = _orderDelayRepository.Queryable()
.Includes(d => d.WorkflowSteps.Where(step =>
((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
step.HandlerId == _sessionContext.RequiredUserId) ||
(step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
(step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)) ||
(step.FlowAssignType == EFlowAssignType.OrgAndRole && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)
&& !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId)))
.OrderByDescending(step => step.CreationTime)
.Take(1)
.ToList()
);
if (!isAdmin)
{
if (hasHandled)
{
query.Where(d => d.WorkflowSteps
.Any(step =>
((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
step.HandlerId == _sessionContext.RequiredUserId) ||
(step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
(step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)) ||
(step.FlowAssignType == EFlowAssignType.OrgAndRole && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)
&& !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId))
&& step.Status == EWorkflowStepStatus.Handled));
}
else
{
query.Where(d => d.WorkflowSteps
.Any(step =>
((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
step.HandlerId == _sessionContext.RequiredUserId) ||
(step.FlowAssignType == EFlowAssignType.Org && !string.IsNullOrEmpty(step.HandlerOrgId) &&
step.HandlerOrgId == _sessionContext.RequiredOrgId) ||
(step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)) ||
(step.FlowAssignType == EFlowAssignType.OrgAndRole && !string.IsNullOrEmpty(step.RoleId) &&
_sessionContext.Roles.Contains(step.RoleId)
&& !string.IsNullOrEmpty(step.HandlerOrgId) && step.HandlerOrgId == _sessionContext.RequiredOrgId))
&& step.Status < EWorkflowStepStatus.Handled));
}
}
query.Includes(d => d.Order)
.WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
.WhereIF(dto.IsApply == false, d => d.DelayState == EDelayState.Examining)
.WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No.Contains(dto.No)) //工单编号
.WhereIF(dto.IsProvince.HasValue && dto.IsProvince == true, d => d.Order.IsProvince == true) //是否省工单
.WhereIF(dto.IsProvince.HasValue && dto.IsProvince == false, d => d.Order.IsProvince == false)
.WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title.Contains(dto.Title)) //工单标题
.WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.Order.SourceChannelCode == dto.Channel) //来源渠道
.WhereIF(dto.CreationTimeStart.HasValue, d => d.Order.CreationTime >= dto.CreationTimeStart) //受理时间Start
.WhereIF(dto.CreationTimeEnd.HasValue, d => d.Order.CreationTime <= dto.CreationTimeEnd) //受理时间End
.WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), d => d.Order.AcceptorName == dto.AcceptorName!) //受理人
.WhereIF(!string.IsNullOrEmpty(dto.Hotspot),
d => d.Order.HotspotSpliceName != null && d.Order.HotspotSpliceName.Contains(dto.Hotspot)) //热点
.WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.Order.AcceptTypeCode == dto.AcceptTypeCode) //受理类型
.WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.Order.OrgLevelOneName.Contains(dto.OrgLevelOneName)) //一级部门
.WhereIF(!string.IsNullOrEmpty(dto.CurrentHandleOrgName), d => d.Order.CurrentHandleOrgName.Contains(dto.CurrentHandleOrgName)) //接办部门
.WhereIF(dto.CurrentHandleTimeStart.HasValue, d => d.Order.CurrentHandleTime >= dto.CurrentHandleTimeStart) //接办时间Start
.WhereIF(dto.CurrentHandleTimeEnd.HasValue, d => d.Order.CurrentHandleTime <= dto.CurrentHandleTimeEnd) //接办时间End
.WhereIF(dto.ApplyTimeStart.HasValue, d => d.CreationTime >= dto.ApplyTimeStart) //延期申请时间Start
.WhereIF(dto.ApplyTimeEnd.HasValue, d => d.CreationTime <= dto.ApplyTimeEnd) //延期申请时间End
.WhereIF(!string.IsNullOrEmpty(dto.ApplyName), d => d.CreatorName.Contains(dto.ApplyName)) //延期申请人
.WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), d => d.CreatorOrgName.Contains(dto.ApplyOrgName)) //延期申请部门
.WhereIF(dto.DelayNum.HasValue, d => d.DelayNum == dto.DelayNum) //延期申请时限
.WhereIF(dto.DelayUnit.HasValue, d => d.DelayUnit == dto.DelayUnit) //延期申请单位
.WhereIF(!string.IsNullOrEmpty(dto.DelayReason), d => d.DelayReason.Contains(dto.DelayReason)) //申请理由
.WhereIF(dto.BeforeDelayStart.HasValue, d => d.BeforeDelay >= dto.BeforeDelayStart) //申请前期满时间Start
.WhereIF(dto.BeforeDelayEnd.HasValue, d => d.BeforeDelay <= dto.BeforeDelayEnd) //申请前期满时间End
.OrderByDescending(d => d.ApplyDelayTime)
;
return query;
}
///
/// 延期审核
///
///
///
///
public async Task ReviewAsync(OrderDelayReviewRequest request, CancellationToken cancellation)
{
/*
* 查询delay
* 查询workflow
* 查询当前节点(待受理or待办理)
* 查询nextStep(_workflowApplication.GetNextStepsAsync)
* 非省工单删除省审批节点
*!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审"删除中心终审
* 从nextStep中查找与dto传入的nextStepName相同的节点,workflow.NextStepCode = step.Key;workflow.NextStepName = step.Value;
* 通过:nextAsync,不同意:rejectAsync
* endhandler:
* 1.更新orderDelay.DelayState
* 2.审批通过:
* a.更新工单办理期满时间(_orderApplication.DelayOrderExpiredTimeAsync)
* b.更新工单未办理节点的期满时间(_workflowDomainService.UpdateUnhandleExpiredTimeAsync)
* c.cap publish EventNames.HotlineOrderExpiredTimeUpdate
*/
request.NextWorkflow.ReviewResult = request.IsPass ? EReviewResult.Approval : EReviewResult.Failed;
if (request.IsPass)
{
await _workflowDomainService.NextAsync(request.NextWorkflow, cancellationToken: cancellation);
}
else
{
var reject = _mapper.Map(request.NextWorkflow);
await _workflowDomainService.RejectAsync(reject, cancellation);
}
}
///
/// 延期批量审核
///
///
public async Task BatchReviewAsync(BatchOrderDelayReviewRequest request, CancellationToken cancellation)
{
//var delayIds = request.DelayWithStepIds.Select(d => d.DelayId).Distinct().ToList();
//var delays = await _orderDelayRepository.Queryable()
// .Where(d => delayIds.Contains(d.Id))
// .ToListAsync(cancellation);
var apptaskItems = new List();
var req = new OrderDelayReviewWithSessionRequest
{
SessionContext = CreateFakeSessionContext(_sessionContext),//(FakeSessionContext)_sessionContext,
IsPass = request.IsPass,
NextWorkflow = request.NextWorkflow
};
foreach (var delay in request.DelayWithStepIds)
{
req.NextWorkflow.WorkflowId = delay.WorkflowId;
req.NextWorkflow.StepId = delay.StepId;//request.DelayWithStepIds.First(d => d.DelayId == delay.Id).StepId;
apptaskItems.Add(new AddApptaskItemRequest
{
BusinessId = delay.DelayId,
TaskParams = req
});
}
var taskId = await _apptaskDomainService.AddAsync(new AddApptaskRequest
{
TaskType = ETaskType.OrderDelay,
Priority = 0,
ApptaskItems = apptaskItems
}, cancellation);
if (!string.IsNullOrEmpty(taskId))
{
//foreach (var orderDelay in delays)
//{
// orderDelay.DelayState = EDelayState.BatchProcessing;
//}
//await _orderDelayRepository.Updateable(delays)
// .UpdateColumns(d => new { d.DelayState })
// .ExecuteCommandAsync(cancellation);
var delayIds = request.DelayWithStepIds.Select(d => d.DelayId).ToList();
await _orderDelayRepository.Updateable()
.SetColumns(d => d.DelayState == EDelayState.BatchProcessing)
.Where(d => delayIds.Contains(d.Id))
.ExecuteCommandAsync(cancellation);
}
}
private FakeSessionContext CreateFakeSessionContext(ISessionContext sessionContext)
{
return new FakeSessionContext
{
UserId = sessionContext.UserId,
UserName = sessionContext.UserName,
Phone = sessionContext.Phone,
Roles = sessionContext.Roles,
OrgId = sessionContext.OrgId,
OrgName = sessionContext.OrgName,
OrgLevel = sessionContext.OrgLevel,
OrgAreaCode = sessionContext.OrgAreaCode,
OrgIsCenter = sessionContext.OrgIsCenter,
OrgAreaName = sessionContext.OrgAreaName,
AreaId = sessionContext.AreaId,
ClientId = sessionContext.ClientId,
StaffNo = sessionContext.StaffNo,
OpenId = sessionContext.OpenId
};
}
}