Browse Source

Merge branch 'master' of http://110.188.24.182:10023/Fengwo/hotline

xf 1 năm trước cách đây
mục cha
commit
3f42d62275

+ 13 - 10
src/Hotline.Ai.Jths/AiVisitService.cs

@@ -2,6 +2,7 @@
 using Hotline.Ai.Jths.OrderVisits;
 using Hotline.Ai.Visit;
 using Hotline.Orders;
+using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Order;
 using Microsoft.Extensions.Logging;
 using Newtonsoft.Json;
@@ -85,13 +86,13 @@ namespace Hotline.Ai.Jths
             }
             requestData.TaskDataList = taskDataList;
             var response = await ExecuteAsync<AiVisitServiceRequest, AiVisitServiceResponse>(_baseUrl + "/edas/batchTask",Method.Post, requestData,cancellationToken);
-            if (response.Result.TaskInfoList!=null && !string.IsNullOrEmpty(response.Result.BatchUid))
+            if (response.TaskInfoList!=null && !string.IsNullOrEmpty(response.BatchUid))
             {
                 //拼对象
-                aiOrderVisit.BatchUid = response.Result.BatchUid;
+                aiOrderVisit.BatchUid = response.BatchUid;
                 for (int i = 0; i < aiOrderVisit.AiOrderVisitDetails.Count; i++)
                 {
-                    var taskInfo = response.Result.TaskInfoList.FirstOrDefault(x => x.CalledNumber == aiOrderVisit.AiOrderVisitDetails[i].OuterNo);
+                    var taskInfo = response.TaskInfoList.FirstOrDefault(x => x.CalledNumber == aiOrderVisit.AiOrderVisitDetails[i].OuterNo);
                     if (taskInfo != null)
                     {
                         aiOrderVisit.AiOrderVisitDetails[i].AiOrderVisitState = Share.Enums.Ai.EAiOrderVisitState.NoStarted;
@@ -108,18 +109,19 @@ namespace Hotline.Ai.Jths
         }
 
 
-        public async Task QueryAiVisitTask(AiVisitServiceQueryRequest dto,CancellationToken cancellationToken)
+        public async Task<AiVisitQueryData> QueryAiVisitTask(string batchId, string taskId, CancellationToken cancellationToken)
         {
+            var dto = new AiVisitServiceQueryRequest() { BatchUid = batchId, TaskUid = taskId,PageNo=1, PageSize=100 };
             var response = await ExecuteAsync<AiVisitServiceQueryRequest, AiVisitServiceQueryResponse>(_baseUrl + "/edas/task/status/real", Method.Get, dto, cancellationToken);
-            if (response.Result!=null)
+            if (response!=null && response.Result.Result.Count>0)
             {
-
+                return new AiVisitQueryData() { Uid = response.Result.Result[0].Uid, Status = response.Result.Result[0].Status };
             }
-
+            return null;
         }
 
 
-        public async Task<ApiResponse<TResponse>> ExecuteAsync<TRequest,TResponse>(string path, Method httpMethod, TRequest request,
+        public async Task<TResponse> ExecuteAsync<TRequest,TResponse>(string path, Method httpMethod, TRequest request,
             CancellationToken cancellationToken)
             where TRequest : class
         {
@@ -138,12 +140,13 @@ namespace Hotline.Ai.Jths
             }
             try
             {
-                var response = await _client.ExecuteAsync<ApiResponse<TResponse>>(req, cancellationToken);
+                var response = await _client.ExecuteAsync<TResponse>(req, cancellationToken);
+                var t = JsonConvert.DeserializeObject<TResponse>(response.Content);
                 return response.Data;
             }
             catch (Exception e)
             {
-                throw new HttpRequestException($"智能质检平台错误,Error: {e.Message}");
+                throw new HttpRequestException($"智能回访平台错误,Error: {e.Message}");
             }
         }
     }

+ 14 - 2
src/Hotline.Ai.Jths/OrderVisits/AiVisitServiceQueryResponse.cs

@@ -1,35 +1,47 @@
 
+using System.Text.Json.Serialization;
+
 namespace Hotline.Ai.Jths.OrderVisits
 {
     public class AiVisitServiceQueryResponse
     {
-        public string Code { get; set; }
+        [JsonPropertyName("code")]
+        public int Code { get; set; }
 
+        [JsonPropertyName("msg")]
         public string Msg { get; set; }
 
+        [JsonPropertyName("result")]
         public PageTaskStatus Result { get; set; }
     }
 
     public class PageTaskStatus
     {
+        [JsonPropertyName("pageNo")]
         public int PageNo { get; set; }
 
+        [JsonPropertyName("pageSize")]
         public int PageSize { get; set; }
 
+        [JsonPropertyName("total")]
         public int Total { get; set; }
 
+        [JsonPropertyName("pages")]
         public int Pages { get; set; }
 
-        public object Result { get; set; }
+        [JsonPropertyName("result")]
+        public List<TaskStatus> Result { get; set; }
     }
 
     public class TaskStatus
     {
+        [JsonPropertyName("uid")]
         public string Uid { get; set; }
 
         /// <summary>
         /// 任务状态 实时(1 :待执行、2 :暂停中、3 :执行中、4 :失效、5 :呼叫失败、6:已结束(完成或取消))
         /// </summary>
+        [JsonPropertyName("status")]
         public int Status { get; set; }
     }
 }

+ 5 - 2
src/Hotline.Api/Controllers/AiController.cs

@@ -194,7 +194,7 @@ namespace Hotline.Api.Controllers
                             //处理主表
                             aiOrderVisitDetail.OrderVisit.AiVisitCount++;
                             aiOrderVisitDetail.OrderVisit.VisitTime = DateTime.Now;
-                            aiOrderVisitDetail.OrderVisit.IsPutThrough = false;
+                            aiOrderVisitDetail.OrderVisit.IsPutThrough = true;
                             aiOrderVisitDetail.OrderVisit.VisitType = Share.Enums.Order.EVisitType.ChipVoiceVisit;
                             aiOrderVisitDetail.OrderVisit.AiVisitTime();
                             if (orgProcessingResults != null)
@@ -399,7 +399,10 @@ namespace Hotline.Api.Controllers
             });
             await _aiOrderVisitDetailRepository.AddRangeAsync(detaillist, HttpContext.RequestAborted);
             //修改回访主表
-             await _orderVisitRepository.Updateable().SetColumns(x => x.IsCanAiVisit == false).Where(x=> detaillist.Select(s=>s.OrderVisitId).Contains(x.Id)).ExecuteCommandAsync(HttpContext.RequestAborted);
+             await _orderVisitRepository.Updateable()
+                .SetColumns(x => x.IsCanAiVisit == false)
+                .SetColumns(x=> x.VisitState == EVisitState.Visiting)
+                .Where(x=> detaillist.Select(s=>s.OrderVisitId).Contains(x.Id)).ExecuteCommandAsync(HttpContext.RequestAborted);
             //推送任务
             //准备原始数据
             var pushModel = await _aiOrderVisitRepository.Queryable()

+ 7 - 2
src/Hotline.Api/Controllers/OrderController.cs

@@ -1177,6 +1177,7 @@ public class OrderController : BaseController
         model.EmployeeName = _sessionContext.UserName;
         model.ApplyOrgName = _sessionContext.OrgName;
         model.ApplyOrgCode = _sessionContext.RequiredOrgId;
+        model.DelayApplyType = EDelayApplyType.LocalApply;
         model.BeforeDelay = order.ExpiredTime;
         model.DelayState = EDelayState.Examining;
         model.DelayReason = dto.Workflow.Opinion;
@@ -1247,6 +1248,10 @@ public class OrderController : BaseController
         var orderDelay = await _orderDelayRepository.GetAsync(x => x.OrderId == dto.Id && x.DelayState == EDelayState.Examining, HttpContext.RequestAborted);
         if (orderDelay != null)
         {
+            if (orderDelay.DelayApplyType == EDelayApplyType.ProvinceApply)
+            {
+                throw UserFriendlyException.SameMessage("当前处于【省平台】审批,无法取消");
+            }
             await _workflowDomainService.TerminateAsync(new TerminateDto() { WorkflowId = orderDelay.WorkflowId, Opinion = "" }, HttpContext.RequestAborted);
             orderDelay.DelayState = EDelayState.Withdraw;
             await _orderDelayRepository.UpdateAsync(orderDelay, HttpContext.RequestAborted);
@@ -2338,7 +2343,7 @@ public class OrderController : BaseController
     public async Task StartFlow([FromBody] OrderStartFlowDto dto)
     {
         ExpiredTimeWithConfig expiredTimeConfig;
-        if (dto.Workflow.NextHandlers.Any(d => d.Key == "001170" || d.Key == "001177"))
+        if (dto.Workflow.NextHandlers.Any(d => d.Key == "001171" || d.Key == "001178"))
         {
             var timeResult = _timeLimitDomainService.CalcEndTime(DateTime.Now, ETimeType.WorkDay, 45, 80);
             expiredTimeConfig = new ExpiredTimeWithConfig
@@ -2416,7 +2421,7 @@ public class OrderController : BaseController
         }
 
         ExpiredTimeWithConfig? expiredTimeConfig = null;
-        if (dto.NextHandlers.Any(d => d.Key == "001170" || d.Key == "001177"))
+        if (dto.NextHandlers.Any(d => d.Key == "001171" || d.Key == "001178"))
         {
             var timeResult = _timeLimitDomainService.CalcEndTime(DateTime.Now, ETimeType.WorkDay, 45, 80);
             expiredTimeConfig = new ExpiredTimeWithConfig

+ 8 - 3
src/Hotline.Api/Controllers/TestController.cs

@@ -4,6 +4,7 @@ using System.IO;
 using DotNetCore.CAP;
 using Fw.Utility.Client;
 using Google.Protobuf.WellKnownTypes;
+using Hotline.Ai.Visit;
 using Hotline.Application.ExportExcel;
 using Hotline.CallCenter.BlackLists;
 using Hotline.CallCenter.Devices;
@@ -75,6 +76,7 @@ public class TestController : BaseController
     private readonly ICapPublisher _capPublisher;
     private readonly IQueue _queue;
     private readonly IExportApplication _exportApplication;
+    private readonly IAiVisitService _aiVisitService;
 
 
     //private readonly ITypedCache<List<User>> _cache;
@@ -106,7 +108,8 @@ public class TestController : BaseController
         ITrClient trClient,
         ICapPublisher capPublisher,
         IQueue queue,
-        IExportApplication exportApplication
+        IExportApplication exportApplication,
+        IAiVisitService aiVisitService
     )
     {
         _logger = logger;
@@ -131,6 +134,7 @@ public class TestController : BaseController
         _capPublisher = capPublisher;
         _queue = queue;
         _exportApplication = exportApplication;
+        _aiVisitService = aiVisitService;
     }
 
     [HttpGet("testo")]
@@ -181,7 +185,7 @@ public class TestController : BaseController
 
     [HttpGet("time")]
     [AllowAnonymous]
-    public async Task<OpenResponse> GetTime()
+    public async Task<OpenResponse> GetTime(string batchId,string taskId)
     {
         //await _repositoryts.AddVectorAsync("f595e730-909a-45e4-9138-a84bf15f4662", DateTime.Now,
         //    new List<string> { "xx", "bb" }, HttpContext.RequestAborted);
@@ -209,7 +213,8 @@ public class TestController : BaseController
         //await _daySettingRepository.IsWorkDay(DateTime.Now);
 
         //var r = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2024-3-22 05:00:00"), DateTime.Parse("2024-3-22 06:00:00"), false);
-        var r = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2024-3-24 17:20:00"), DateTime.Parse("2024-3-24 17:21:00"), false);
+        //var r = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2024-3-24 17:20:00"), DateTime.Parse("2024-3-24 17:21:00"), false);
+        await _aiVisitService.QueryAiVisitTask(batchId, taskId, HttpContext.RequestAborted);
 
         return OpenResponse.Ok(DateTime.Now.ToString("F"));
     }

+ 2 - 0
src/Hotline.Application/Handlers/FlowEngine/WorkflowNextHandler.cs

@@ -224,6 +224,8 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                             {
                                 if (orderDelay != null)
                                 {
+                                    orderDelay.DelayApplyType = EDelayApplyType.ProvinceApply;
+                                    await _orderDelayRepository.UpdateAsync(orderDelay);
                                     //推送
                                     var publishOrderDelay = _mapper.Map<PublishOrderDelayDto>(orderDelay);
                                     await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay, cancellationToken: cancellationToken);

+ 71 - 0
src/Hotline.Application/Visit/AiOrderVisitService.cs

@@ -0,0 +1,71 @@
+
+using Hotline.Ai.Visit;
+using Hotline.Orders;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Org.BouncyCastle.Utilities;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Visit
+{
+    public class AiOrderVisitService : BackgroundService
+    {
+        private readonly IServiceScopeFactory _serviceScopeFactory;
+
+        public AiOrderVisitService(IServiceScopeFactory serviceScopeFactory)
+        {
+            _serviceScopeFactory = serviceScopeFactory;
+        }
+
+        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+        {
+            using var scope = _serviceScopeFactory.CreateScope();
+            var _aivisitService = scope.ServiceProvider.GetRequiredService<IAiVisitService>();
+            var _aivisitRepository = scope.ServiceProvider.GetRequiredService<IRepository<AiOrderVisit>>();
+            var _aiVisitDetailRepository = scope.ServiceProvider.GetRequiredService<IRepository<AiOrderVisitDetail>>();
+            var _orderVisitRepository = scope.ServiceProvider.GetRequiredService<IRepository<OrderVisit>>();
+
+            int times = 300000;
+            while (!stoppingToken.IsCancellationRequested)
+            {
+                try
+                {
+                    var aivisitList = await _aivisitRepository.Queryable()
+                    .Includes(x => x.AiOrderVisitDetails,d=>d.OrderVisit).Where(x=>x.TaskState == Share.Enums.Ai.EAiOrderVisitTaskState.InProgress).ToListAsync();
+                    if (aivisitList != null)
+                    {
+                        foreach (var aivisit in aivisitList)
+                        {
+                            foreach (var aivisitDetail in aivisit.AiOrderVisitDetails)
+                            {
+                                if (!string.IsNullOrEmpty(aivisit.BatchUid) && !string.IsNullOrEmpty(aivisitDetail.TaskUid))
+                                {
+                                    var res = await _aivisitService.QueryAiVisitTask(aivisit.BatchUid, aivisitDetail.TaskUid, stoppingToken);
+                                    if(res!=null  && res.Status == 4)
+                                    {
+                                        aivisitDetail.AiOrderVisitState = Share.Enums.Ai.EAiOrderVisitState.LoseEfficacy;
+                                        await _aiVisitDetailRepository.UpdateAsync(aivisitDetail,stoppingToken);
+                                        aivisitDetail.OrderVisit.VisitState = Share.Enums.Order.EVisitState.WaitForVisit;
+                                        aivisitDetail.OrderVisit.IsCanAiVisit = true;
+                                        await _orderVisitRepository.UpdateAsync(aivisitDetail.OrderVisit,stoppingToken);
+                                        aivisit.VisitedFailCount++;
+                                        if ((aivisit.VisitedFailCount + aivisit.VisitedCount) == aivisit.HasVisitCount)
+                                        {
+                                            aivisit.TaskState = Share.Enums.Ai.EAiOrderVisitTaskState.Ended;
+                                        }
+                                        await _aivisitRepository.UpdateAsync(aivisit,stoppingToken);
+                                    }
+                                }
+
+                            }
+                        }
+                    }
+                    
+                }
+                catch{}
+                await Task.Delay(times);
+            }
+           
+        }
+    }
+}

+ 9 - 0
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -135,6 +135,15 @@ namespace Hotline.Share.Dtos.Order
 
     }
 
+
+    public class AiVisitQueryData
+    {
+        public string Uid { get; set; }
+
+        public int Status { get; set; }
+    }
+
+
     public class AddVisitApplyDto
     {
         public string OrderNo { get; set; }

+ 10 - 6
src/Hotline.Share/Enums/Order/EDelayState.cs

@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
 
 namespace Hotline.Share.Enums.Order
 {
@@ -33,4 +28,13 @@ namespace Hotline.Share.Enums.Order
         [Description("撤销")]
         Withdraw = 3,
     }
+
+    public enum EDelayApplyType
+    {
+        [Description("本地审批")]
+        LocalApply = 0,
+
+        [Description("省审批")]
+        ProvinceApply = 1,
+    }
 }

+ 3 - 0
src/Hotline/Ai/Visit/IAiVisitService.cs

@@ -1,10 +1,13 @@
 
 using Hotline.Orders;
+using Hotline.Share.Dtos.Order;
 
 namespace Hotline.Ai.Visit
 {
     public interface IAiVisitService
     {
         Task<AiOrderVisit> CreateAiOrderVisitTask(AiOrderVisit aiOrderVisit, CancellationToken cancellationToken);
+
+        Task<AiVisitQueryData> QueryAiVisitTask(string batchId,string taskId, CancellationToken cancellationToken);
     }
 }

+ 5 - 0
src/Hotline/Orders/OrderDelay.cs

@@ -92,6 +92,11 @@ namespace Hotline.Orders
         /// </summary>
         public EDelayState DelayState { get; set; }
 
+        /// <summary>
+        /// 审批类型
+        /// </summary>
+        public EDelayApplyType? DelayApplyType { get; set; }
+
         /// <summary>
         /// 附件
         /// </summary>