Преглед изворни кода

Merge branch 'release/yibin' of http://git.12345lm.cn/Fengwo/hotline into release/yibin

Dun.Jason пре 10 месеци
родитељ
комит
6d82f3fafa

+ 61 - 39
src/Hotline.Api/Controllers/OrderController.cs

@@ -1348,7 +1348,8 @@ public class OrderController : BaseController
             var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
             startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderDelay;
             startDto.Opinion = model.DelayReason;
-            string workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
+            startDto.Title = "申请延期流程";
+			string workFlowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
                     cancellationToken: HttpContext.RequestAborted);
             //model.WorkflowId = workFlowId;
             //await _orderDelayRepository.UpdateAsync(model, HttpContext.RequestAborted);
@@ -1717,7 +1718,8 @@ public class OrderController : BaseController
             var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
             startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderScreen;
             startDto.Opinion = dto.Data.Content;
-            workflowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
+            startDto.Title = "申请甄别流程";
+		   workflowId = await _workflowApplication.StartWorkflowAsync(startDto, _sessionContext, model.Id,
                     cancellationToken: HttpContext.RequestAborted);
             //var screen = await _orderScreenRepository.GetAsync(model.Id, HttpContext.RequestAborted);
             //if (screen != null)
@@ -3160,9 +3162,8 @@ public class OrderController : BaseController
                 ((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))) &&
-                (((dto.IsHandled.HasValue && dto.IsHandled == false) || step.Status != EWorkflowStepStatus.Handled) ||
-                ((dto.IsHandled.HasValue && dto.IsHandled == true)) || step.Status == EWorkflowStepStatus.Handled)
-                )))
+                 (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled)||
+                ((dto.IsHandled.HasValue && dto.IsHandled == true) && step.Status == EWorkflowStepStatus.Handled)))))
             .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
             .WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
@@ -3196,23 +3197,32 @@ public class OrderController : BaseController
         if (dto.StartTimeEnd.HasValue)
             dto.StartTimeEnd = dto.StartTimeEnd.Value.AddDays(1).AddSeconds(-1);
 
-        var (total, items) = await _orderRepository.Queryable(canView: false)
-            .Where(x => x.Workflow.Steps.Any(s => s.Status < EWorkflowStepStatus.Handled && s.HandlerOrgId == OrgSeedData.CenterId))
-            .Where(x => x.Source < ESource.MLSQ || x.Source > ESource.WZSC)
-            .Where(x => x.Status != EOrderStatus.BackToProvince && x.Status < EOrderStatus.Filed)
-            .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No!.Contains(dto.No!))
-            .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.Title!.Contains(dto.Title!))
-            .WhereIF(dto is { StCreationTime: not null, EndCreationTime: not null }, x => x.CreationTime >= dto.StCreationTime && x.CreationTime <= dto.EndCreationTime)
-            .WhereIF(dto is { StartTimeSt: not null, StartTimeEnd: not null }, x => x.StartTime >= dto.StartTimeSt && x.StartTime <= dto.StartTimeEnd)
-            .WhereIF(!string.IsNullOrEmpty(dto.StepName), x => x.ActualHandleStepName == dto.StepName)
-            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.ActualHandleOrgName!.Contains(dto.ActualHandleOrgName!))
-            .WhereIF(dto.Status.HasValue, x => x.Status == dto.Status)
-            .WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), x => x.AcceptorName!.Contains(dto.AcceptorName!))
-            .WhereIF(dto.ExpiredStatus is EExpiredStatus.Normal, x => DateTime.Now < x.NearlyExpiredTime)
-            .WhereIF(dto.ExpiredStatus is EExpiredStatus.GoingToExpired, x => DateTime.Now > x.NearlyExpiredTime && DateTime.Now < x.ExpiredTime)
-            .WhereIF(dto.ExpiredStatus is EExpiredStatus.Expired, x => DateTime.Now >= x.ExpiredTime)
-            .OrderBy(x => x.Status)
-            .OrderBy(x => x.CreationTime, OrderByType.Desc)
+        var (total, items) = await _orderRepository.Queryable()
+	        .LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
+	        .Where((d, step) =>
+		        ((string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)) ||
+		         (!string.IsNullOrEmpty(d.WorkflowId) &&
+		          ((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.Status != EWorkflowStepStatus.Handled )
+		         )))
+			//.Where(d => d.Workflow.Steps.Any(s => s.Status < EWorkflowStepStatus.Handled && s.HandlerOrgId == OrgSeedData.CenterId))
+            .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+            .Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
+            .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No!.Contains(dto.No!))
+            .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title!.Contains(dto.Title!))
+            .WhereIF(dto is { StCreationTime: not null, EndCreationTime: not null }, d => d.CreationTime >= dto.StCreationTime && d.CreationTime <= dto.EndCreationTime)
+            .WhereIF(dto is { StartTimeSt: not null, StartTimeEnd: not null }, d => d.StartTime >= dto.StartTimeSt && d.StartTime <= dto.StartTimeEnd)
+            .WhereIF(!string.IsNullOrEmpty(dto.StepName), d => d.ActualHandleStepName == dto.StepName)
+            .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.ActualHandleOrgName!.Contains(dto.ActualHandleOrgName!))
+            .WhereIF(dto.Status.HasValue, d => d.Status == dto.Status)
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptorName), d => d.AcceptorName!.Contains(dto.AcceptorName!))
+            .WhereIF(dto.ExpiredStatus is EExpiredStatus.Normal, d => DateTime.Now < d.NearlyExpiredTime)
+            .WhereIF(dto.ExpiredStatus is EExpiredStatus.GoingToExpired, d => DateTime.Now > d.NearlyExpiredTime && DateTime.Now < d.ExpiredTime)
+            .WhereIF(dto.ExpiredStatus is EExpiredStatus.Expired, d => DateTime.Now >= d.ExpiredTime)
+            .OrderBy(d => d.Status)
+            .OrderBy(d => d.CreationTime, OrderByType.Desc)
             .ToPagedListAsync(dto, HttpContext.RequestAborted);
 
         return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
@@ -3275,23 +3285,35 @@ public class OrderController : BaseController
                     : d is EOrderStatus.WaitForAccept or EOrderStatus.BackToUnAccept or EOrderStatus.SpecialToUnAccept)
             .ToArray();
 
-        var (total2, items2) = await _orderRepository.Queryable(canView: false)
-            .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
-            .WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
-            .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.No.Contains(dto.Keyword!) || d.Title.Contains(dto.Keyword!))
-            .Where(d => string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)
-            .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
-            .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => !d.CounterSignType.HasValue)
-            .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
-            .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false, d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now)//即将超期 未办
-            .Where(x => x.Source < ESource.MLSQ || x.Source > ESource.WZSC)
-            .Where(x => x.Status != EOrderStatus.BackToProvince && x.Status < EOrderStatus.Filed)
-            .OrderBy(d => d.Status)
-            .OrderByIF(dto.IsHandled == true, d => d.StartTime, OrderByType.Asc)
-            .OrderByIF(dto.IsHandled == false, d => d.CreationTime, OrderByType.Desc)
-            .ToPagedListAsync(dto, HttpContext.RequestAborted);
-
-        var page2 = new PagedDto<OrderDto>(total2, _mapper.Map<IReadOnlyList<OrderDto>>(items2));
+		var (total2, items2) = await _orderRepository.Queryable()
+		.LeftJoin<WorkflowStep>((d, step) => d.Id == step.ExternalId)
+		.Where((d, step) =>
+			((string.IsNullOrEmpty(d.WorkflowId) && (string.IsNullOrEmpty(d.SignerId) || d.SignerId == _sessionContext.RequiredUserId)) ||
+			(!string.IsNullOrEmpty(d.WorkflowId) &&
+			((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))) &&
+			 (((dto.IsHandled.HasValue && dto.IsHandled == false) && step.Status != EWorkflowStepStatus.Handled) ||
+			((dto.IsHandled.HasValue && dto.IsHandled == true) && step.Status == EWorkflowStepStatus.Handled)))))
+		.WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
+		.WhereIF(dto.IsHandled.HasValue, d => handleStatuses.Contains(d.Status))
+		.WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!))
+		.WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
+		.WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
+		.WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => !d.CounterSignType.HasValue)
+		.WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true, d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) || (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
+		.WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false, d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now)//即将超期 未办
+		.WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
+		.WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
+		.Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+		.Where(d => d.Status != EOrderStatus.BackToProvince && d.Status < EOrderStatus.Filed)
+		.OrderBy(d => d.Status)
+		.OrderByIF(dto.IsHandled == true, d => d.StartTime, OrderByType.Desc)
+		.OrderByIF(dto.IsHandled == false, d => d.CreationTime, OrderByType.Desc)
+		.Select((d, step) => d)
+		.ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+		var page2 = new PagedDto<OrderDto>(total2, _mapper.Map<IReadOnlyList<OrderDto>>(items2));
 
         return new { Waited = page1, Sign = page2 };
     }

+ 4 - 2
src/Hotline.Api/Controllers/PbxController.cs

@@ -288,7 +288,8 @@ namespace Hotline.Api.Controllers
                 var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
                 startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
                 startWorkflowDto.Opinion = dto.Reason;
-                await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, telRest.Id, cancellationToken: HttpContext.RequestAborted);
+                startWorkflowDto.Title = "分机休息申请流程";
+				await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, telRest.Id, cancellationToken: HttpContext.RequestAborted);
             }
         }
 
@@ -323,7 +324,8 @@ namespace Hotline.Api.Controllers
             var startWorkflowDto = _mapper.Map<StartWorkflowDto>(dto);
             startWorkflowDto.DefinitionModuleCode = WorkflowModuleConsts.TelRestApply;
             startWorkflowDto.Opinion = dto.Reason;
-            await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, telRest.Id, cancellationToken: HttpContext.RequestAborted);
+            startWorkflowDto.Title = "分机休息申请流程";
+			await _workflowApplication.StartWorkflowAsync(startWorkflowDto, _sessionContext, telRest.Id, cancellationToken: HttpContext.RequestAborted);
         }
 
 

+ 12 - 0
src/Hotline.Api/Controllers/PushMessageController.cs

@@ -68,6 +68,18 @@ namespace Hotline.Api.Controllers
             return await _messageCodeDomainService.VerifyWhitelistAsync(UserName);
         }
 
+        /// <summary>
+        /// 修改短信状态
+        /// </summary>
+        /// <param name="messageDto"></param>
+        /// <param name="cancellation"></param>
+        /// <returns></returns>
+        [HttpPost("update-send-sms-state")]
+        [AllowAnonymous]
+        public async Task UpdateSendSmsState(PushReceiveMessageDto messageDto, CancellationToken cancellation)
+        {
+            await _pushDomainService.PushMsgUpdateStateNewAsync(messageDto, cancellation);
+        }
 
         //[HttpGet("checkdcode")]
         //public async Task CheckdCode(string UserName, string phoneNum, string Code)

+ 131 - 30
src/Hotline.Api/Controllers/TestController.cs

@@ -7,6 +7,8 @@ using Fw.Utility.Client;
 using Google.Protobuf.WellKnownTypes;
 using Hotline.Ai.Visit;
 using Hotline.Application.ExportExcel;
+using Hotline.Application.JudicialManagement;
+using Hotline.Application.Quality;
 using Hotline.CallCenter.BlackLists;
 using Hotline.CallCenter.Calls;
 using Hotline.CallCenter.Devices;
@@ -16,17 +18,25 @@ using Hotline.FlowEngine.Workflows;
 using Hotline.Identity.Roles;
 using Hotline.Import;
 using Hotline.Orders;
+using Hotline.Push.Notifies;
 using Hotline.Realtimes;
 using Hotline.Repository.SqlSugar;
+using Hotline.Repository.SqlSugar.CallCenter;
 using Hotline.Repository.SqlSugar.System;
 using Hotline.Repository.SqlSugar.Ts;
 using Hotline.Settings;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.FlowEngine;
+using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Realtime;
+using Hotline.Share.Dtos.SendSms;
+using Hotline.Share.Dtos.TrCallCenter;
 using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Push;
+using Hotline.Share.Enums.Quality;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Mq;
 using Hotline.Tools;
@@ -44,6 +54,7 @@ using NewRock.Sdk;
 using NewRock.Sdk.Security;
 using SqlSugar;
 using SqlSugar.SplitTableExtensions;
+using StackExchange.Redis;
 using Tr.Sdk;
 using XC.RSAUtil;
 using XF.Domain.Authentications;
@@ -55,6 +66,7 @@ using XF.Domain.Locks;
 using XF.Domain.Queues;
 using XF.Domain.Repository;
 using XF.EasyCaching;
+using Order = Hotline.Orders.Order;
 
 namespace Hotline.Api.Controllers;
 
@@ -75,7 +87,7 @@ public class TestController : BaseController
     private readonly IBlacklistDomainService _blacklistDomainService;
     private readonly IIvrDomainService _ivrDomainService;
     private readonly ISugarUnitOfWork<HotlineDbContext> _uow;
-    private readonly IRepository<Role> _roleRepository;
+    private readonly IRepository<Identity.Roles.Role> _roleRepository;
     private readonly IMediator _mediator;
 
     private readonly IDistributedLock _distributedLock;
@@ -93,11 +105,17 @@ public class TestController : BaseController
     private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
 
     private readonly IRepository<WorkflowStep> _workflowStepRepository;
+
+    private readonly IWorkflowRepository _workflowRepository;
     //private readonly IRepository<WorkflowStepHandler> _workflowStepHandleRepository;
 
     private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
     private readonly IOrderRepository _orderRepository;
+    private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+    private readonly IQualityApplication _qualityApplication;
+    private readonly IEnforcementApplication _enforcementApplication;
     private readonly IMapper _mapper;
+    private readonly IOptionsSnapshot<SendSmsConfiguration> _sendSmsConfiguration;
 
 
     //private readonly ITypedCache<List<User>> _cache;
@@ -118,7 +136,7 @@ public class TestController : BaseController
         IBlacklistDomainService blacklistDomainService,
         IIvrDomainService ivrDomainService,
         ISugarUnitOfWork<HotlineDbContext> uow,
-        IRepository<Role> roleRepository,
+        IRepository<Identity.Roles.Role> roleRepository,
         IMediator mediator,
         IDistributedLock distributedLock,
         IRepository<OrderUrge> orderUrgeRepository,
@@ -133,10 +151,17 @@ public class TestController : BaseController
         IAiVisitService aiVisitService,
         IRepository<WorkflowTrace> workflowTraceRepository,
         IRepository<WorkflowStep> workflowStepRepository,
+        IWorkflowRepository workflowRepository,
         //IRepository<WorkflowStepHandler> workflowStepHandleRepository,
         IRepository<SystemOrganize> systemOrganizeRepository,
         IOrderRepository orderRepository,
-        IMapper mapper
+        IRepository<TrCallRecord> trCallRecordRepository,
+        IQualityApplication qualityApplication,
+        IEnforcementApplication enforcementApplication,
+        IMapper mapper,
+
+
+   IOptionsSnapshot<SendSmsConfiguration> sendSmsConfiguration
         )
     {
         _logger = logger;
@@ -164,16 +189,38 @@ public class TestController : BaseController
         _aiVisitService = aiVisitService;
         _workflowTraceRepository = workflowTraceRepository;
         _workflowStepRepository = workflowStepRepository;
+        _workflowRepository = workflowRepository;
         //_workflowStepHandleRepository = workflowStepHandleRepository;
         _systemOrganizeRepository = systemOrganizeRepository;
         _orderRepository = orderRepository;
+        _trCallRecordRepository = trCallRecordRepository;
+        _qualityApplication = qualityApplication;
+        _enforcementApplication = enforcementApplication;
         _orderRepository = orderRepository;
         _mapper = mapper;
+        _sendSmsConfiguration = sendSmsConfiguration;
     }
 
     [HttpGet("testo")]
+    [AllowAnonymous]
     public async Task<OpenResponse> TestOrigin()
     {
+        var messageDto = new Share.Dtos.Push.MessageDto
+        {
+            PushBusiness = EPushBusiness.OrderAccept,
+            ExternalId = "123456789",
+            OrderId = "123456789",
+            PushPlatform = EPushPlatform.Sms,
+            Remark =" order.Title",
+            Name ="张三",
+            TemplateCode = "1005",
+            Params = new List<string>() { "20240610000022", "12345" },
+            TelNumber = "15881689499",
+
+        };
+        await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
+
+        var t = _sendSmsConfiguration.Value.Url;
         var now = DateTime.Now.ToString();
         return OpenResponse.Ok(now);
     }
@@ -316,7 +363,7 @@ public class TestController : BaseController
     [HttpGet("pgsql")]
     public async Task<string> Pgsql()
     {
-        var role = new Role
+        var role = new Identity.Roles.Role
         {
             Name = $"test_role_{TimeOnly.FromDateTime(DateTime.Now)}",
             DisplayName = "test_role_display",
@@ -331,7 +378,7 @@ public class TestController : BaseController
 
     [AllowAnonymous]
     [HttpGet("roles")]
-    public async Task<List<Role>> GetRoles()
+    public async Task<List<Identity.Roles.Role>> GetRoles()
     {
         using var lockManager = new LockManager(_distributedLock, $"{nameof(TestController)}.{nameof(GetRoles)}");
         lockManager.InvokeInLock(() => { Console.WriteLine("do something"); }, TimeSpan.FromSeconds(10));
@@ -531,41 +578,95 @@ public class TestController : BaseController
     [HttpPost("t4")]
     public async Task TestExportExcel1()
     {
-        var steps = await _workflowStepRepository.Queryable()
-            .Includes(d => d.WorkflowTrace)
-            .Where(d => SqlFunc.Exists(d.WorkflowTrace.Id) &&
-                        d.Status != EWorkflowStepStatus.Handled &&
-                        d.HandlerId == null &&
-                        d.FlowAssignType != null &&
-                        SqlFunc.JsonArrayLength(d.Handlers) == 1)
+        var orders = await _orderRepository.Queryable()
+            .Includes(d=>d.OrderExtension)
+            .InnerJoin<Workflow>((o, w) => o.WorkflowId == w.Id)
+            .Where((o, w) => o.Status < EOrderStatus.Filed && w.Status == EWorkflowStatus.Completed)
             .ToListAsync(HttpContext.RequestAborted);
+        _logger.LogWarning($"order count: {orders.Count}");
 
-        var list = new List<WorkflowStep>();
-        foreach (var step in steps)
+        var workflowIds = orders.Select(d => d.WorkflowId).ToList();
+        var workflows = await _workflowRepository.Queryable()
+            .Includes(d=>d.Steps)
+            .Includes(d=>d.Traces)
+            .Where(d => workflowIds.Contains(d.Id))
+            .ToListAsync(HttpContext.RequestAborted);
+
+        var updateOrders = new List<Order>();
+        foreach (var order in orders)
         {
-            var handler = step.Handlers.First();
-            if (string.IsNullOrEmpty(handler.Key)) continue;
-            if (step.FlowAssignType == EFlowAssignType.User)
+            var workflow = workflows.First(d => d.Id == order.WorkflowId);
+
+            _mapper.Map(workflow, order);
+            var now = DateTime.Now;
+            var handleDuration = order.StartTime.HasValue
+                ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value,
+                now, order.ProcessType is EProcessType.Zhiban)
+                : 0;
+            var fileDuration = order.CenterToOrgTime.HasValue
+                ? _timeLimitDomainService.CalcWorkTime(order.CenterToOrgTime.Value,
+                    now, order.ProcessType is EProcessType.Zhiban)
+                : 0;
+            var allDuration = order.StartTime.HasValue
+                ? _timeLimitDomainService.CalcWorkTime(order.StartTime.Value, now,
+                order.ProcessType is EProcessType.Zhiban)
+                : 0;
+            order.File(now, handleDuration, fileDuration, allDuration);
+
+            var endTrace = workflow.Traces.FirstOrDefault(d => d.StepType == EStepType.End);
+            if(endTrace is null) continue;
+            var trace = workflow.Traces.FirstOrDefault(d => d.Id == endTrace.PrevStepId);
+            if(trace is null) continue;
+
+            order.FileUserId = trace.HandlerId;
+            order.FileUserName = trace.HandlerName;
+            order.FileUserOrgId = trace.HandlerOrgId;
+            order.FileUserOrgName = trace.HandlerOrgName;
+            order.FileOpinion = trace.Opinion;
+
+            //记录冗余归档数据
+            if (workflow.Steps.Any(x => x.BusinessType == Share.Enums.FlowEngine.EBusinessType.Send))
             {
-                step.HandlerId = handler.Key;
-                step.HandlerName = handler.Value;
-                step.WorkflowTrace.HandlerId = step.HandlerId;
-                step.WorkflowTrace.HandlerName = step.HandlerName;
+                order.FileUserRole = EFileUserType.Dispatch;
             }
             else
             {
-                step.HandlerOrgId = handler.Key;
-                step.HandlerOrgName = handler.Value;
-                step.WorkflowTrace.HandlerOrgId = step.HandlerOrgId;
-                step.WorkflowTrace.HandlerOrgName = step.HandlerOrgName;
+                order.FileUserRole = EFileUserType.Seat;
             }
-            list.Add(step);
+            if (order.ProcessType == EProcessType.Jiaoban)
+            {
+                order.FileUserRole = EFileUserType.Org;
+            }
+
+            //是否已解决
+            order.IsResolved = true;//notification.Dto.External == null ? false : notification.Dto.External.IsResolved;
+
+            //await _orderRepository.UpdateAsync(order, cancellationToken);
+            updateOrders.Add(order);
+
+            //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
+            var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, HttpContext.RequestAborted);
+            var orderFlowDto = new OrderFlowDto
+            {
+                Order = _mapper.Map<OrderDto>(order),
+                WorkflowTrace = _mapper.Map<WorkflowTraceDto>(trace)
+            };
+            if (callRecord != null)
+            {
+                orderFlowDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
+            }
+            //这里需要判断是否是警情退回
+            orderFlowDto.IsNonPoliceReturn = false;//notification.Dto.External == null ? false : notification.Dto.External.IsPoliceReturn;
+            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: HttpContext.RequestAborted);
+            //写入质检  针对受理之后直接结束的工单
+            await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, HttpContext.RequestAborted);
+
+            //司法行政监督管理-工单处理
+            await _enforcementApplication.AddEnforcementOrderAsync(order, HttpContext.RequestAborted);
         }
 
-        await _workflowStepRepository
-            .UpdateNav(list)
-            .Include(d => d.WorkflowTrace)
-            .ExecuteCommandAsync();
+        _logger.LogWarning($"更新orders:{updateOrders.Count}");
+        await _orderRepository.UpdateRangeAsync(updateOrders, HttpContext.RequestAborted);
     }
 
     [HttpGet("rsa")]

+ 3 - 1
src/Hotline.Api/StartupExtensions.cs

@@ -20,6 +20,7 @@ using XF.Utility.MQ;
 using Hotline.Ai.Jths;
 using Hotline.Api.Sdk;
 using Hotline.YbEnterprise.Sdk;
+using Hotline.Share.Dtos.SendSms;
 
 namespace Hotline.Api;
 
@@ -41,7 +42,8 @@ internal static class StartupExtensions
         services.Configure<IdentityConfiguration>(d => configuration.GetSection(nameof(IdentityConfiguration)).Bind(d));
         services.Configure<CallCenterConfiguration>(d => configuration.GetSection(nameof(CallCenterConfiguration)).Bind(d));
         services.Configure<AiVisitConfig>(d => configuration.GetSection("AiVisit").Bind(d));
-        
+        services.Configure<SendSmsConfiguration>(d => configuration.GetSection("SendSms").Bind(d));
+
         // Add services to the container.
         services
             .BatchInjectServices()

+ 7 - 3
src/Hotline.Api/config/appsettings.Development.json

@@ -29,7 +29,7 @@
   },
   "Swagger": true,
   "Cors": {
-    "Origins": [ "http://localhost:8888", "http://admin.hotline.fw.com", "http://localhost:80","http://localhost:8113" ]
+    "Origins": [ "http://localhost:8888", "http://admin.hotline.fw.com", "http://localhost:80", "http://localhost:8113" ]
   },
   "IdentityConfiguration": {
     "Password": {
@@ -130,7 +130,7 @@
       "AreaCode": "511500"
     },
     "WebPortal": {
-     // "SystemSettingsTheme": "class=gray2",
+      // "SystemSettingsTheme": "class=gray2",
       "SystemSettingsTheme": ""
     },
     //业务系统附件上传配置
@@ -207,7 +207,7 @@
   "AiVisit": {
     "Url": "http://118.122.73.80:19061",
     "Appkey": "MTAwMDAx",
-    "ServiceVersion": "V1.0.0", //接口版本号
+    "ServiceVersion": "V1.0.0" //接口版本号
     //"SceneUid": "MTAwMDAxVW7cUNRwRegsLGqb0pvXCU", //场景ID
     //"RuleUid": "MTAwMDAxUbQsuOcmS5ApRyHGyWQr7g", //现有规则ID
     //"VisitFromNameKey": "OC_SCENE_VAR_FIELD14", //来电名称       //开发环境 :OC_SCENE_VAR_FIELD14  //生产环境:OC_SCENE_VAR_FIELD12
@@ -233,6 +233,10 @@
     "ClientId": "1462598736",
     "ClientSecret": "6nZtVK4rKfnsncGymUHB",
     "TenantId": "000000"
+  },
+
+  "SendSms": {
+    "Url": "http://localhost:50108/api/v1/PushMessage/addwaitmsg"
   }
 
 

+ 4 - 1
src/Hotline.Api/config/appsettings.json

@@ -106,7 +106,7 @@
   "AiVisit": {
     "Url": "http://118.122.73.80:19061",
     "Appkey": "MTAwMDAx",
-    "ServiceVersion": "V1.0.0", //接口版本号
+    "ServiceVersion": "V1.0.0" //接口版本号
     //"SceneUid": "MTAwMDAxVW7cUNRwRegsLGqb0pvXCU", //场景ID
     //"RuleUid": "MTAwMDAxUbQsuOcmS5ApRyHGyWQr7g", //现有规则ID
     //"VisitFromNameKey": "OC_SCENE_VAR_FIELD14", //来电名称       //开发环境 :OC_SCENE_VAR_FIELD14  //生产环境:OC_SCENE_VAR_FIELD12
@@ -128,5 +128,8 @@
     "ClientId": "1476116956",
     "ClientSecret": "6NVnvmsFSC8d3qwgBZmN",
     "TenantId": "000000"
+  },
+  "SendSms": {
+    "Url": "http://110.188.24.28:50108/api/v1/PushMessage/addwaitmsg"
   }
 }

+ 1 - 1
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -331,7 +331,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         //var stepHandlers = await GetNextStepHandlersAsync(workflow, targetStepDefine, dto, cancellationToken);
 
-        await _workflowDomainService.RecallAsync(workflow, dto, targetStepDefine, flowAssignInfo, expiredTime, _sessionContext, cancellationToken);
+        await _workflowDomainService.RecallAsync(workflow, dto, targetStepDefine, flowAssignInfo, expiredTime, cancellationToken);
     }
 
     /// <summary>

+ 0 - 2
src/Hotline.Application/Identity/IdentityAppService.cs

@@ -159,8 +159,6 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
             var scheduling = await _schedulingRepository.Queryable()
                 .Includes(x => x.SchedulingUser)
                 .Where(x => x.SchedulingTime == time &&
-                            x.WorkingTime <= DateTime.Now.TimeOfDay && 
-                            x.OffDutyTime >= DateTime.Now.TimeOfDay && 
                             (x.AtWork == true || x.AtWork == null) && 
                             x.SchedulingUser.UserId == id)
                 .OrderBy(x => x.SendOrderNum).FirstAsync(cancellationToken);

+ 5 - 0
src/Hotline.Share/Dtos/Push/PushReceiveMessageDto.cs

@@ -63,5 +63,10 @@ namespace Hotline.Share.Dtos.Push
         /// 发送短信使用的数量
         /// </summary>
         public int? MsgCount { get; set; }
+
+        /// <summary>
+        /// 发送失败原因等
+        /// </summary>
+        public string? Reason { get; set; }
     }
 }

+ 7 - 0
src/Hotline.Share/Dtos/SendSms/SendSmsConfiguration.cs

@@ -0,0 +1,7 @@
+namespace Hotline.Share.Dtos.SendSms
+{
+    public class SendSmsConfiguration
+    {
+        public string Url { get; set; }
+    }
+}

+ 13 - 0
src/Hotline.Share/Dtos/SendSms/SendSmsReponse.cs

@@ -0,0 +1,13 @@
+namespace Hotline.Share.Dtos.SendSms
+{
+    public class SendSmsReponse
+    {
+        public int code { get; set; }
+
+        public string message { get; set; }
+
+        public string error { get; set; }
+
+        public SendSmsReponse result { get; set; }
+    }
+}

+ 1 - 1
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -67,7 +67,7 @@ namespace Hotline.FlowEngine.Workflows
         /// 撤回(返回到之前任意节点)
         /// </summary>
         Task RecallAsync(Workflow workflow, RecallDto dto, StepDefine targetStepDefine, FlowAssignInfo flowAssignInfo,
-            DateTime? expiredTime, ISessionContext current, CancellationToken cancellationToken);
+            DateTime? expiredTime, CancellationToken cancellationToken);
 
         /// <summary>
         /// 撤回至开始节点

+ 58 - 24
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -1,4 +1,5 @@
-using Hotline.File;
+using Dm;
+using Hotline.File;
 using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.Notifications;
 using Hotline.FlowEngine.WorkflowModules;
@@ -571,11 +572,22 @@ namespace Hotline.FlowEngine.Workflows
             }
 
             //update trace
-            var trace = await PreviousTraceAsync(workflow.Id, dto, currentStep,
-                applicantId, applicantName,
+            //var trace = await PreviousTraceAsync(workflow.Id, dto, currentStep,
+            //    applicantId, applicantName,
+            //    applicantOrgId, applicantOrgName,
+            //    applicantOrgAreaCode, applicantOrgAreaName,
+            //    applicantIsCenter, cancellationToken);
+            var trace = workflow.Traces.First(t => t.StepId == currentStep.Id);
+            _mapper.Map(dto, trace);
+
+            //HandleTrace(trace, dto.Opinion, current);
+
+            trace.Handle(applicantId, applicantName,
                 applicantOrgId, applicantOrgName,
                 applicantOrgAreaCode, applicantOrgAreaName,
-                applicantIsCenter, cancellationToken);
+                applicantIsCenter, dto.Opinion);
+
+            //await _workflowTraceRepository.UpdateAsync(trace, cancellationToken);
 
             //复制上一个节点为待接办
             var newPrevStep = await DuplicateStepWithTraceAsync(workflow, prevStep, EWorkflowTraceType.Previous, cancellationToken);
@@ -959,14 +971,14 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         public async Task RecallAsync(Workflow workflow, RecallDto dto, StepDefine targetStepDefine,
             FlowAssignInfo flowAssignInfo, DateTime? expiredTime,
-            ISessionContext current, CancellationToken cancellationToken)
+            CancellationToken cancellationToken)
         {
             var targetStep = workflow.Steps.FirstOrDefault(d => d.Code == dto.NextStepCode && d.IsOrigin);
             if (targetStep is null)
                 throw UserFriendlyException.SameMessage("该流程尚未流转至该节点");
 
             //update uncompleted traces
-            await RecallTraceAsync(workflow.Id, dto.Opinion, current, cancellationToken);
+            //await RecallTraceAsync(workflow.Traces, dto.Opinion, _sessionContext, cancellationToken);
 
             var isOrgToCenter = await RecallAsync(workflow, dto, flowAssignInfo, targetStepDefine, targetStep,
                 EWorkflowTraceType.Recall, expiredTime, cancellationToken);
@@ -982,10 +994,10 @@ namespace Hotline.FlowEngine.Workflows
         public async Task RecallToStartStepAsync(string workflowId, string opinion, ISessionContext current, CancellationToken cancellationToken)
         {
             //todo 1.当前待办节点删掉 2.当前待办trace更新(status, opinion) 3.复制startStep为待办 4.更新workflow(status, csStatus, handlers) 5.publish event
-            var workflow = await GetWorkflowAsync(workflowId, withDefine: true, withSteps: true,
+            var workflow = await GetWorkflowAsync(workflowId, withDefine: true, withSteps: true, withTraces: true,
                 cancellationToken: cancellationToken);
             //update uncompleted traces
-            await RecallTraceAsync(workflow.Id, opinion, current, cancellationToken);
+            await RecallTraceAsync(workflow.Traces, opinion, current, cancellationToken);
 
             var startStep = workflow.Steps.First(d => d.StepType == EStepType.Start);
             workflow.Steps.RemoveAll(d => true);
@@ -1886,27 +1898,24 @@ namespace Hotline.FlowEngine.Workflows
         //    await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
         //}
 
-        private void HandleTrace(WorkflowTrace trace, string opinion, ISessionContext current)
-        {
-            trace.Handle(
-                current.RequiredUserId, current.UserName,
-                current.RequiredOrgId, current.OrgName,
-                current.OrgAreaCode, current.OrgAreaName,
-                current.OrgIsCenter, opinion);
-        }
-
-        private async Task RecallTraceAsync(string workflowId, string opinion, ISessionContext current, CancellationToken cancellationToken)
+        private async Task RecallTraceAsync(List<WorkflowTrace> traces, string opinion, ISessionContext current, CancellationToken cancellationToken)
         {
             //未办理的traces
-            var uncompleteTraces =
-                await _workflowTraceRepository.QueryAsync(d =>
-                    d.WorkflowId == workflowId && string.IsNullOrEmpty(d.HandlerId));
+            //var uncompleteTraces =
+            //    await _workflowTraceRepository.QueryAsync(d =>
+            //        d.WorkflowId == workflowId && string.IsNullOrEmpty(d.HandlerId));
+
+            var uncompleteTraces = traces.Where(d => d.Status != EWorkflowStepStatus.Handled).ToList();
 
             if (uncompleteTraces.Any())
             {
                 foreach (var trace in uncompleteTraces)
                 {
-                    HandleTrace(trace, opinion, current);
+                    trace.Handle(
+                        current.RequiredUserId, current.UserName,
+                        current.RequiredOrgId, current.OrgName,
+                        current.OrgAreaCode, current.OrgAreaName,
+                        current.OrgIsCenter, opinion);
                 }
 
                 await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
@@ -2021,6 +2030,24 @@ namespace Hotline.FlowEngine.Workflows
             DateTime? expiredTime, CancellationToken cancellationToken)
         {
             var targetIsStartStep = targetStepDefine.StepType is EStepType.Start;
+            var updateTraces = new List<WorkflowTrace>();
+
+            //update uncomplete traces
+            var uncompleteTraces = workflow.Traces.Where(d => d.Status != EWorkflowStepStatus.Handled).ToList();
+            if (uncompleteTraces.Any())
+            {
+                foreach (var trace in uncompleteTraces)
+                {
+                    trace.Handle(
+                        _sessionContext.RequiredUserId, _sessionContext.UserName,
+                        _sessionContext.RequiredOrgId, _sessionContext.OrgName,
+                        _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
+                        _sessionContext.OrgIsCenter, dto.Opinion);
+                }
+
+                //await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
+                updateTraces.AddRange(uncompleteTraces);
+            }
 
             //get targetStep's previous
             WorkflowStep? targetPrevStep = null;
@@ -2043,10 +2070,17 @@ namespace Hotline.FlowEngine.Workflows
 
                 //更新快照对应节点状态
                 var stepIds = removeSteps.Select(d => d.Id).ToList();
-                var updateTraces = workflow.Traces.Where(d => stepIds.Contains(d.StepId)).ToList();
-                await UpdateTracesStateAsync(updateTraces, EWorkflowTraceState.StepRemoveByRecall, cancellationToken);
+                var traces = workflow.Traces.Where(d => stepIds.Contains(d.StepId)).ToList();
+                //await UpdateTracesStateAsync(updateTraces, EWorkflowTraceState.StepRemoveByRecall, cancellationToken);
+                foreach (var trace in traces)
+                {
+                    trace.TraceState = EWorkflowTraceState.StepRemoveByRecall;
+                }
+                updateTraces.AddRange(traces);
             }
 
+            await _workflowTraceRepository.UpdateRangeAsync(updateTraces, cancellationToken);
+
             workflow.EndCountersign();
             workflow.ResetOption();
             if (workflow.Status is EWorkflowStatus.Completed)

+ 1 - 1
src/Hotline/Orders/OrderDomainService.cs

@@ -234,7 +234,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
             .FirstAsync(d => d.Id == userId, cancellationToken);
         var time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
         var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
-            .Where(x => x.SchedulingTime == time && x.WorkingTime <= DateTime.Now.TimeOfDay && x.OffDutyTime >= DateTime.Now.TimeOfDay).CountAsync(cancellationToken);
+            .Where(x => x.SchedulingTime == time).CountAsync(cancellationToken);
         if (schedulings > 0)
         {
             var sendNum = steps.Count / schedulings;

+ 7 - 1
src/Hotline/Push/FWMessage/IPushDomainService.cs

@@ -20,6 +20,12 @@ namespace Hotline.Push.FWMessage
         /// <returns></returns>
         Task PushMsgUpdateStateAsync(PushReceiveMessageDto dto, CancellationToken cancellation);
 
-
+        /// <summary>
+        /// 修改短信推送状态
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <param name="cancellation"></param>
+        /// <returns></returns>
+        Task PushMsgUpdateStateNewAsync(PushReceiveMessageDto dto, CancellationToken cancellation);
     }
 }

+ 115 - 3
src/Hotline/Push/FWMessage/PushDomainService.cs

@@ -1,9 +1,16 @@
 using DotNetCore.CAP;
 using Hotline.Share.Dtos.Push;
+using Hotline.Share.Dtos.SendSms;
 using Hotline.Share.Enums.Push;
 using MapsterMapper;
 using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System.Net;
+using System.Net.Http.Json;
 using System.Text.RegularExpressions;
+using System.Xml;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -21,6 +28,9 @@ public class PushDomainService : IPushDomainService, IScopeDependency
     private readonly IMediator _mediator;
     private readonly IRepository<MessageTemplate> _messageTemplateRepository;
     private readonly ICapPublisher _capPublisher;
+    private readonly IHttpClientFactory _httpClientFactory;
+    private readonly ILogger<PushDomainService> _logger;
+    private readonly IOptionsSnapshot<SendSmsConfiguration> _sendSmsConfiguration;
 
     /// <summary>
     /// 
@@ -30,17 +40,27 @@ public class PushDomainService : IPushDomainService, IScopeDependency
     /// <param name="mediator"></param>
     /// <param name="messageTemplateRepository"></param>
     /// <param name="capPublisher"></param>
+    /// <param name="httpClientFactory"></param>
+    /// <param name="logger"></param>
+    /// <param name="sendSmsConfiguration"></param>
     public PushDomainService(IRepository<Message> messageRepository,
         IMapper mapper,
         IMediator mediator,
         IRepository<MessageTemplate> messageTemplateRepository,
-        ICapPublisher capPublisher)
+        ICapPublisher capPublisher,
+        IHttpClientFactory httpClientFactory,
+        ILogger<PushDomainService> logger,
+     IOptionsSnapshot<SendSmsConfiguration> sendSmsConfiguration
+        )
     {
         _messageRepository = messageRepository;
         _mapper = mapper;
         _mediator = mediator;
         _messageTemplateRepository = messageTemplateRepository;
         _capPublisher = capPublisher;
+        _httpClientFactory = httpClientFactory;
+        _logger = logger;
+        _sendSmsConfiguration = sendSmsConfiguration;
     }
     #endregion
 
@@ -88,7 +108,7 @@ public class PushDomainService : IPushDomainService, IScopeDependency
         }
         #endregion
         var message = _mapper.Map<Message>(messageDto);
-        var id = await _messageRepository.AddAsync(message);//写入本地数据库
+        var id = await _messageRepository.AddAsync(message, cancellation);//写入本地数据库
 
         PushMessageDto pushMessage = new()
         {
@@ -99,8 +119,17 @@ public class PushDomainService : IPushDomainService, IScopeDependency
             Name = message.Name,
             TelNumber = message.TelNumber
         };
+        //消息队列
+         await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SendSms, pushMessage, cancellationToken: cancellation);
 
-        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SendSms, pushMessage, cancellationToken: cancellation);
+        ////http请求
+        //var result = await ExecuteAsync<PushMessageDto, SendSmsReponse>(_sendSmsConfiguration.Value.Url, pushMessage, cancellationToken: cancellation);
+        //if (result != null && result.code == 0)
+        //{
+        //    message.Status = EPushStatus.Success;
+        //    message.SendState = ESendState.Sending;
+        //    await _messageRepository.UpdateAsync(message, cancellation);
+        //}
     }
 
     /// <summary>
@@ -137,12 +166,95 @@ public class PushDomainService : IPushDomainService, IScopeDependency
                 data.IsSmsReply = dto.IsSmsReply;
                 data.SmsReplyTime = Convert.ToDateTime(dto.SmsReplyTime);
                 data.SmsReplyContent = dto.SmsReplyContent;
+                
             }
+            data.Reason = dto.Reason;
+            await _messageRepository.UpdateAsync(data, cancellation);
+        }
+    }
 
+    /// <summary>
+    /// 修改短信推送状态
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <param name="cancellation"></param>
+    /// <returns></returns>
+    public async Task PushMsgUpdateStateNewAsync(PushReceiveMessageDto dto, CancellationToken cancellation)
+    {
+        var data = await _messageRepository.GetAsync(p => p.Id == dto.ExternalId, cancellation);
+        if (data != null)
+        {
+            data.SmsWaitSendingId = dto.SmsWaitSendingId;
+            data.Status = EPushStatus.Success;
+            data.SendTime = Convert.ToDateTime(dto.SendTime);
+            data.SendState = dto.SendState;
+            data.MsgCount = dto.MsgCount;
+            data.SmsSendingCompletedId = dto.SmsSendingCompletedId;
+            data.IsSmsReply = dto.IsSmsReply;
+            data.SmsReplyTime = Convert.ToDateTime(dto.SmsReplyTime);
+            data.SmsReplyContent = dto.SmsReplyContent;
+            data.Reason = dto.Reason;
             await _messageRepository.UpdateAsync(data, cancellation);
         }
     }
 
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <typeparam name="TRequest"></typeparam>
+    /// <typeparam name="TResponse"></typeparam>
+    /// <param name="path"></param>
+    /// <param name="request"></param>
+    /// <param name="clientInitialize"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    private async Task<TResponse?> ExecuteAsync<TRequest, TResponse>(string path, TRequest request,
+            Action<HttpClient>? clientInitialize = null, CancellationToken cancellationToken = default)
+    {
+        var client = _httpClientFactory.CreateClient("sendwaitsms");
+        clientInitialize?.Invoke(client);
+
+        using var responseMessage = await client.PostAsJsonAsync(path, request, cancellationToken);
+        responseMessage.EnsureSuccessStatusCode();
+        var result = await responseMessage.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
+        return result;
+    }
+
 
+    #region http请求
+
+    /// <summary>
+    /// 封装使用HttpClient调用WebService
+    /// </summary>
+    /// <param name="url">URL地址</param>
+    /// <param name="content">参数</param>
+    /// <returns></returns>
+    private async Task<string> PostHelper(string url, HttpContent content)
+    {
+        _logger.LogInformation($"准备推送短信, {nameof(PostHelper)}");
+        var result = string.Empty;
+        try
+        {
+            using var client = _httpClientFactory.CreateClient();
+            using (var response = await client.PostAsync(url, content))
+            {
+                if (response.StatusCode == HttpStatusCode.OK)
+                {
+                    result = await response.Content.ReadAsStringAsync();
+                    XmlDocument doc = new XmlDocument();
+                    doc.LoadXml(result);
+                    result = doc.InnerText;
+                }
+            }
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex.InnerException?.Message);
+            result = ex.Message;
+        }
+        _logger.LogInformation($"推送响应:{result}");
+        return result;
+    }
 
+    #endregion
 }

+ 1 - 1
src/XF.EasyCaching/XF.EasyCaching.csproj

@@ -5,7 +5,7 @@
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-    <Version>1.0.4</Version>
+    <Version>1.0.6</Version>
     <Authors>xf</Authors>
     <Title>TypedCache implementation with easycaching</Title>
   </PropertyGroup>