|
@@ -1,4 +1,6 @@
|
|
|
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
|
|
+using DocumentFormat.OpenXml.Office.CustomUI;
|
|
|
+using DocumentFormat.OpenXml.Office2010.CustomUI;
|
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
|
|
using DotNetCore.CAP;
|
|
|
using FluentValidation;
|
|
@@ -57,6 +59,7 @@ using PanGu;
|
|
|
using SqlSugar;
|
|
|
using System.Data;
|
|
|
using System.Dynamic;
|
|
|
+using System.Threading;
|
|
|
using XF.Domain.Authentications;
|
|
|
using XF.Domain.Dependency;
|
|
|
using XF.Domain.Exceptions;
|
|
@@ -118,8 +121,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
|
|
|
private readonly ISessionContextManager _sessionContextManager;
|
|
|
private readonly IOrderVisitApplication _orderVisitApplication;
|
|
|
private readonly IRepository<OrderVisitDetailCopy> _orderVisitDetailCopyRepository;
|
|
|
+ private readonly IRepository<OrderDelayAutomatic> _orderDelayAutomaticRepository;
|
|
|
|
|
|
- public OrderApplication(
|
|
|
+ public OrderApplication(
|
|
|
IOrderDomainService orderDomainService,
|
|
|
IOrderRepository orderRepository,
|
|
|
IWorkflowDomainService workflowDomainService,
|
|
@@ -170,8 +174,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
|
|
|
ISessionContextManager sessionContextManager,
|
|
|
IOrderVisitApplication orderVisitApplication,
|
|
|
IRepository<Role> roleRepository,
|
|
|
- IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository
|
|
|
- )
|
|
|
+ IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository,
|
|
|
+ IRepository<OrderDelayAutomatic> orderDelayAutomaticRepository
|
|
|
+ )
|
|
|
{
|
|
|
_orderDomainService = orderDomainService;
|
|
|
_workflowDomainService = workflowDomainService;
|
|
@@ -223,7 +228,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
|
|
|
_orderVisitApplication = orderVisitApplication;
|
|
|
_roleRepository = roleRepository;
|
|
|
_orderVisitDetailCopyRepository = orderVisitDetailCopyRepository;
|
|
|
- }
|
|
|
+ _orderDelayAutomaticRepository = orderDelayAutomaticRepository;
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更新工单办理期满时间(延期调用,其他不调用)
|
|
@@ -6734,5 +6740,222 @@ public class OrderApplication : IOrderApplication, IScopeDependency
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
- #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region 自动延期
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 自动延期记录写入
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task OrderDelayAutomatic()
|
|
|
+ {
|
|
|
+
|
|
|
+ var data = new List<OrderDelayAutomatic>();
|
|
|
+ var automatic = await _orderRepository.Queryable()
|
|
|
+ .Where(x => x.Status < EOrderStatus.Filed && x.ExpiredTime <= DateTime.Now.AddHours(1) && x.ExpiredTime >= DateTime.Now)
|
|
|
+ .Where(x => SqlFunc.Subqueryable<OrderDelay>().Where(od => od.OrderId == x.Id && od.DelayState == EDelayState.Examining).NotAny())
|
|
|
+ .Where(x => SqlFunc.Subqueryable<OrderDelayAutomatic>().Where(oda => oda.OrderId == x.Id && oda.Status == EOrderDelayAutomaticStatus.Pending && oda.Type == EOrderDelayAutomaticType.Automatic).NotAny())
|
|
|
+ .Select(x => new OrderDelayAutomatic
|
|
|
+ {
|
|
|
+ OrderId = x.Id,
|
|
|
+ WorkflowId = x.WorkflowId,
|
|
|
+ Title = x.Title,
|
|
|
+ No = x.No,
|
|
|
+ ExpiredTime = x.ExpiredTime,
|
|
|
+ CenterToOrgTime =x.CenterToOrgTime,
|
|
|
+ AcceptTypeCode =x.AcceptTypeCode,
|
|
|
+ Type = EOrderDelayAutomaticType.Automatic
|
|
|
+ })
|
|
|
+ .ToListAsync();
|
|
|
+ if (automatic.Any())
|
|
|
+ {
|
|
|
+ data.AddRange(automatic);
|
|
|
+ }
|
|
|
+ var automaticSMS = await _orderRepository.Queryable()
|
|
|
+ .Where(x => x.Status < EOrderStatus.Filed && x.ExpiredTime <= DateTime.Now.AddHours(2) && x.ExpiredTime >= DateTime.Now.AddHours(1) && x.ExpiredTime >= DateTime.Now)
|
|
|
+ .Where(x => SqlFunc.Subqueryable<OrderDelay>().Where(od => od.OrderId == x.Id && od.DelayState == EDelayState.Examining).NotAny())
|
|
|
+ .Where(x => SqlFunc.Subqueryable<OrderDelayAutomatic>().Where(oda => oda.OrderId == x.Id && oda.Status == EOrderDelayAutomaticStatus.Pending && oda.Type == EOrderDelayAutomaticType.Sms).NotAny())
|
|
|
+ .Select(x => new OrderDelayAutomatic
|
|
|
+ {
|
|
|
+ OrderId = x.Id,
|
|
|
+ WorkflowId = x.WorkflowId,
|
|
|
+ Title = x.Title,
|
|
|
+ No = x.No,
|
|
|
+ ExpiredTime = x.ExpiredTime,
|
|
|
+ CenterToOrgTime = x.CenterToOrgTime,
|
|
|
+ AcceptTypeCode = x.AcceptTypeCode,
|
|
|
+ Type = EOrderDelayAutomaticType.Sms
|
|
|
+ })
|
|
|
+ .ToListAsync();
|
|
|
+ if (automaticSMS.Any())
|
|
|
+ {
|
|
|
+ data.AddRange(automaticSMS);
|
|
|
+ }
|
|
|
+ if (data.Any())
|
|
|
+ {
|
|
|
+ await _orderDelayAutomaticRepository.AddRangeAsync(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 自动延期处理
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="type"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task OrderDelayAutomaticHandle(EOrderDelayAutomaticType type)
|
|
|
+ {
|
|
|
+ var copy = new List<OrderDelayAutomatic>();
|
|
|
+ var tasks = await _orderDelayAutomaticRepository.Queryable()
|
|
|
+ .Where(x => x.Status == EOrderDelayAutomaticStatus.Pending && x.Type == type)
|
|
|
+ .ToListAsync();
|
|
|
+ foreach (var task in tasks)
|
|
|
+ {
|
|
|
+ task.Status = EOrderDelayAutomaticStatus.BeingProcessed;
|
|
|
+ var row = await _orderDelayAutomaticRepository.Updateable(task).ExecuteCommandWithOptLockAsync();
|
|
|
+ if (row > 0)
|
|
|
+ {
|
|
|
+ copy.Add(task);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type == EOrderDelayAutomaticType.Sms)
|
|
|
+ {
|
|
|
+ if (copy.Any())
|
|
|
+ {
|
|
|
+ foreach (var item in copy)
|
|
|
+ {
|
|
|
+ var workflow = await _workflowDomainService.GetWorkflowAsync(item.WorkflowId, withSteps: true);
|
|
|
+ var steps = workflow.Steps.Where(x => x.Status == EWorkflowStepStatus.WaitForAccept || x.Status == EWorkflowStepStatus.WaitForHandle).ToList();
|
|
|
+ if (steps.Any())
|
|
|
+ {
|
|
|
+ foreach (var step in steps)
|
|
|
+ {
|
|
|
+ var setting = step.HandlerOrgId == OrgSeedData.CenterId ? SettingConstants.AutomaticDelayCenterRoles : SettingConstants.AutomaticDelayDepartmentRoles;
|
|
|
+ var roleIds = _systemSettingCacheManager.GetSetting(setting)?.SettingValue;
|
|
|
+ if (step.HandlerOrgId == OrgSeedData.CenterId && string.IsNullOrEmpty(step.RoleId))
|
|
|
+ {
|
|
|
+ roleIds.Add(step.RoleId);
|
|
|
+ }
|
|
|
+ var userList = await _userRepository.Queryable().Where(x => x.OrgId == step.HandlerOrgId && x.Roles.Any(r => roleIds.Contains(r.Name))).ToListAsync();
|
|
|
+ foreach (var user in userList)
|
|
|
+ {
|
|
|
+ if (!string.IsNullOrEmpty(user.PhoneNo))
|
|
|
+ {
|
|
|
+ //发送短信
|
|
|
+ var messageDto = new Share.Dtos.Push.MessageDto
|
|
|
+ {
|
|
|
+ PushBusiness = EPushBusiness.AutomaticDelay,
|
|
|
+ ExternalId = item.Id,
|
|
|
+ OrderId = item.Id,
|
|
|
+ PushPlatform = EPushPlatform.Sms,
|
|
|
+ Remark = item.Title,
|
|
|
+ Name = user.Name,
|
|
|
+ TemplateCode = "1015",
|
|
|
+ Params = new List<string>() { item.No },
|
|
|
+ TelNumber = user.PhoneNo,
|
|
|
+ };
|
|
|
+ await _mediator.Publish(new PushMessageNotify(messageDto));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await _orderDelayAutomaticRepository.Updateable().SetColumns(x=>x.Status == EOrderDelayAutomaticStatus.Processed).Where(x=>x.Id == item.Id).ExecuteCommandAsync();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type == EOrderDelayAutomaticType.Automatic)
|
|
|
+ {
|
|
|
+ if (copy.Any())
|
|
|
+ {
|
|
|
+ foreach (var item in copy)
|
|
|
+ {
|
|
|
+ var delayAny = await _orderDelayRepository.Queryable().Where(x => x.OrderId == item.OrderId && x.DelayState == EDelayState.Examining).AnyAsync();
|
|
|
+ if (!delayAny)
|
|
|
+ {
|
|
|
+ var delays = await _orderDelayRepository.Queryable().Where(x => x.OrderId == item.OrderId && x.AutomaticDelayNum > 0).ToListAsync();
|
|
|
+ var delay = new OrderDelay();
|
|
|
+ if (delays.Any())
|
|
|
+ {
|
|
|
+ delay = delays.First();
|
|
|
+ var startTime = DateTime.Now;
|
|
|
+ if (item.CenterToOrgTime.HasValue)
|
|
|
+ {
|
|
|
+ startTime = item.CenterToOrgTime.Value;
|
|
|
+ }
|
|
|
+ var beforeDelay = DateTime.Now;
|
|
|
+ if (!_appOptions.Value.IsYiBin)
|
|
|
+ {
|
|
|
+ beforeDelay = item.ExpiredTime.Value;
|
|
|
+ }
|
|
|
+ delay.AfterDelay = (await _expireTime
|
|
|
+ .CalcEndTime(beforeDelay, startTime, delay.DelayUnit, delay.DelayNum, item.AcceptTypeCode))?.EndTime; //todo
|
|
|
+ await _orderDelayRepository.Updateable().SetColumns(x => new OrderDelay() { AutomaticDelayNum = x.AutomaticDelayNum + 1, ApplyDelayTime = DateTime.Now, AfterDelay = delay.AfterDelay })
|
|
|
+ .Where(x => x.Id == delay.Id).ExecuteCommandAsync();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ delay.OrderId = item.OrderId;
|
|
|
+ delay.EmployeeId = "";
|
|
|
+ delay.EmployeeName = "系统自动延期";
|
|
|
+ delay.ApplyOrgName = OrgSeedData.CenterName;
|
|
|
+ delay.ApplyOrgCode = OrgSeedData.CenterId;
|
|
|
+ delay.DelayApplyType = EDelayApplyType.LocalApply;
|
|
|
+ delay.BeforeDelay = item.ExpiredTime;
|
|
|
+ delay.DelayState = EDelayState.Pass;
|
|
|
+ delay.DelayReason = "系统自动延期";
|
|
|
+ delay.ApplyDelayTime = DateTime.Now;
|
|
|
+ delay.No = item.No;
|
|
|
+ delay.AutomaticDelayNum = 1;
|
|
|
+ delay.DelayNum = 1;
|
|
|
+ delay.DelayUnit = Share.Enums.Settings.ETimeType.WorkDay;
|
|
|
+ delay.IsProDelay = false;
|
|
|
+ delay.CreatorOrgId = OrgSeedData.CenterId;
|
|
|
+ delay.CreatorOrgName = OrgSeedData.CenterName;
|
|
|
+ delay.CreatorName = "系统自动延期";
|
|
|
+ var startTime = DateTime.Now;
|
|
|
+ if (item.CenterToOrgTime.HasValue)
|
|
|
+ {
|
|
|
+ startTime = item.CenterToOrgTime.Value;
|
|
|
+ }
|
|
|
+ if (delay.BeforeDelay != null)
|
|
|
+ {
|
|
|
+ delay.AfterDelay = (await _expireTime
|
|
|
+ .CalcEndTime(delay.BeforeDelay.Value, startTime, delay.DelayUnit, delay.DelayNum, item.AcceptTypeCode))?.EndTime; //todo
|
|
|
+ }
|
|
|
+ await _orderDelayRepository.AddAsync(delay, false);
|
|
|
+ }
|
|
|
+ //处理工单延期
|
|
|
+ await DelayOrderExpiredTimeAsync(item.OrderId, delay.DelayNum, delay.DelayUnit, delay.IsProDelay, default);
|
|
|
+ }
|
|
|
+ await _orderDelayAutomaticRepository.Updateable().SetColumns(x => x.Status == EOrderDelayAutomaticStatus.Processed).Where(x => x.Id == item.Id).ExecuteCommandAsync();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 批量发送短信
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <param name="cancellationToken"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task SendLeaderSMS(PublishLeaderSMSDto dto, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ //发送短信
|
|
|
+ var messageDto = new Share.Dtos.Push.MessageDto
|
|
|
+ {
|
|
|
+ PushBusiness = EPushBusiness.OrderSend,
|
|
|
+ ExternalId = dto.OrderId,
|
|
|
+ OrderId = dto.OrderId,
|
|
|
+ PushPlatform = EPushPlatform.Sms,
|
|
|
+ Remark = string.Empty,
|
|
|
+ Name = dto.Name,
|
|
|
+ TemplateCode = "1014",
|
|
|
+ Params = new(),
|
|
|
+ TelNumber = dto.TelNumber,
|
|
|
+ };
|
|
|
+ await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ #endregion
|
|
|
}
|