Bläddra i källkod

Merge branch 'release/yibin' of http://110.188.24.182:10023/Fengwo/hotline into release/yibin

xf 10 månader sedan
förälder
incheckning
37ebe73582

+ 74 - 17
src/Hotline.Api/Controllers/AiController.cs

@@ -4,6 +4,7 @@ using DotNetCore.CAP;
 using Hotline.Ai.CallOut;
 using Hotline.Ai.Jths;
 using Hotline.Ai.Visit;
+using Hotline.Application.Orders;
 using Hotline.Application.Quality;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Services;
@@ -17,6 +18,7 @@ using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Ai;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Quality;
+using Hotline.Tools;
 using MapsterMapper;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
@@ -53,8 +55,9 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<CallOutTask> _callOutTaskRepository;
         private readonly IRepository<CallOutTaskDetail> _callOutTaskDetailRepository;
         private readonly ISessionContext _sessionContext;
+        private readonly IAiOrderVisitApplication _aiOrderVisitApplication;
 
-        public AiController(ISystemSettingCacheManager systemSettingCacheManager,IRepository<AiOrderVisit> aiOrderVisitRepository,IRepository<AiOrderVisitDetail>  aiOrderVisitDetailRepository,IRepository<OrderVisit> orderVisitRepository,IRepository<OrderVisitDetail> orderVisitDetailRepository,IMapper mapper, /*IOptionsSnapshot<AiVisitConfig> options,*/IAiVisitService aiVisitService, ILogger<AiController> logger,ICapPublisher capPublisher,IOrderRepository orderRepository,IQualityApplication qualityApplication, ISystemDicDataCacheManager sysDicDataCacheManager,IRepository<CallOutTemplate> callOutTemplateRepository, IRepository<CallOutTask> callOutTaskRepository,IRepository<CallOutTaskDetail> callOutTaskDetailRepository,ISessionContext sessionContext)
+        public AiController(ISystemSettingCacheManager systemSettingCacheManager,IRepository<AiOrderVisit> aiOrderVisitRepository,IRepository<AiOrderVisitDetail>  aiOrderVisitDetailRepository,IRepository<OrderVisit> orderVisitRepository,IRepository<OrderVisitDetail> orderVisitDetailRepository,IMapper mapper, /*IOptionsSnapshot<AiVisitConfig> options,*/IAiVisitService aiVisitService, ILogger<AiController> logger,ICapPublisher capPublisher,IOrderRepository orderRepository,IQualityApplication qualityApplication, ISystemDicDataCacheManager sysDicDataCacheManager,IRepository<CallOutTemplate> callOutTemplateRepository, IRepository<CallOutTask> callOutTaskRepository,IRepository<CallOutTaskDetail> callOutTaskDetailRepository,ISessionContext sessionContext,IAiOrderVisitApplication aiOrderVisitApplication)
         {
            _systemSettingCacheManager = systemSettingCacheManager;
             _aiOrderVisitRepository = aiOrderVisitRepository;
@@ -73,6 +76,7 @@ namespace Hotline.Api.Controllers
             _callOutTaskRepository = callOutTaskRepository;
             _callOutTaskDetailRepository = callOutTaskDetailRepository;
             _sessionContext = sessionContext;
+            _aiOrderVisitApplication = aiOrderVisitApplication;
         }
 
 
@@ -496,7 +500,7 @@ namespace Hotline.Api.Controllers
                         if (!isOk)
                             throw UserFriendlyException.SameMessage("启动失败");
                         //处理业务数据
-                        callOut.AiCallOutTaskState = EAiCallOutTaskState.Pause;
+                        callOut.AiCallOutTaskState = EAiCallOutTaskState.InProgress;
                         await _callOutTaskRepository.UpdateAsync(callOut, HttpContext.RequestAborted);
                     }
                     break;
@@ -902,17 +906,44 @@ namespace Hotline.Api.Controllers
         [HttpGet("aivisit/aivisit-list")]
         public async Task<PagedDto<AiOrderVisitDto>> AiVisitList([FromQuery]AiVisitListDto dto)
         {
-            var (total, items) = await _aiOrderVisitRepository.Queryable()
-                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Name.Contains(dto.Keyword))
-                .WhereIF(dto.AiOrderVisitTaskState != null, x => x.TaskState == dto.AiOrderVisitTaskState)
-                .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
-                .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
-                .OrderByDescending(x => x.CreationTime)
+            var query = _aiOrderVisitApplication.QuerysAiOrderVisit(dto);
+            var (total, items) = await query
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<AiOrderVisitDto>(total, _mapper.Map<IReadOnlyList<AiOrderVisitDto>>(items)); 
         }
 
+        /// <summary>
+        /// 智能回访任务导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("aivisit/taskexport")]
+        public async Task<FileStreamResult> ExportAiOrderVisit([FromBody]ExportExcelDto<AiVisitListDto> dto)
+        {
+            var query = _aiOrderVisitApplication.QuerysAiOrderVisit(dto.QueryDto);
+            List<AiOrderVisit> aiOrderVisits;
+            if (dto.IsExportAll)
+            {
+                aiOrderVisits = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                aiOrderVisits = items;
+            }
+
+            var aiOrderVisitDtos = _mapper.Map<ICollection<AiOrderVisitDto>>(aiOrderVisits);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
 
+            var dtos = aiOrderVisitDtos
+                .Select(stu => _mapper.Map(stu, typeof(AiOrderVisitDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "智能回访任务");
+        }
         /// <summary>
         /// 智能回访明细
         /// </summary>
@@ -921,18 +952,44 @@ namespace Hotline.Api.Controllers
         [HttpGet("aivisit/aivisitdetail-list")]
         public async Task<PagedDto<AiOrderVisitDetailDto>> AiVisitDetailList([FromQuery]AiVisitDetailListDto dto)
         {
-            var (total, items) = await _aiOrderVisitDetailRepository.Queryable()
-                .Includes(x=>x.OrderVisit,x=>x.OrderVisitDetails)
-                .Includes(x=>x.Order)
-                .Where(x => x.AiOrderVisitId == dto.Id)
-                .WhereIF(dto.AiOrderVisitState.HasValue,x=>x.AiOrderVisitState == dto.AiOrderVisitState)
-                .WhereIF(!string.IsNullOrEmpty(dto.Keyword),x=>x.Order.No.Contains(dto.Keyword) || x.Order.Title.Contains(dto.Keyword))
-                .OrderByDescending(x => x.CreationTime)
-                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-
+            var query = _aiOrderVisitApplication.QueryAiOrderVisitDetail(dto);
+            var (total,items) =await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
             return new PagedDto<AiOrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<AiOrderVisitDetailDto>>(items));
         }
 
+        /// <summary>
+        /// 智能回访明细导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("aivisit/taskdetailexport")]
+        public async Task<FileStreamResult> ExportAiOrderVisitDetail([FromBody]ExportExcelDto<AiVisitDetailListDto> dto)
+        {
+            var query = _aiOrderVisitApplication.QueryAiOrderVisitDetail(dto.QueryDto);
+            List<AiOrderVisitDetail> aiOrderVisits;
+            if (dto.IsExportAll)
+            {
+                aiOrderVisits = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                aiOrderVisits = items;
+            }
+
+            var aiOrderVisitDetailDtos = _mapper.Map<ICollection<AiOrderVisitDetailDto>>(aiOrderVisits);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = aiOrderVisitDetailDtos
+                .Select(stu => _mapper.Map(stu, typeof(AiOrderVisitDetailDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "智能回访明细");
+        }
+
         /// <summary>
         /// 可进行智能回访记录
         /// </summary>

+ 48 - 0
src/Hotline.Application/Orders/AiOrderVisitApplication.cs

@@ -0,0 +1,48 @@
+using Hotline.Orders;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Ai;
+using Microsoft.AspNetCore.Http;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Orders
+{
+    public class AiOrderVisitApplication : IAiOrderVisitApplication, IScopeDependency
+    {
+        private readonly IRepository<AiOrderVisit> _aiOrderVisitRepository;
+        private readonly IRepository<AiOrderVisitDetail> _aiOrderVisitDetailRepository;
+
+        public AiOrderVisitApplication(IRepository<AiOrderVisit> aiOrderVisitRepository, IRepository<AiOrderVisitDetail> aiOrderVisitDetailRepository)
+        {
+            _aiOrderVisitRepository = aiOrderVisitRepository;
+            _aiOrderVisitDetailRepository = aiOrderVisitDetailRepository;
+
+        }
+        public ISugarQueryable<AiOrderVisit> QuerysAiOrderVisit(AiVisitListDto dto)
+        {
+            return _aiOrderVisitRepository.Queryable()
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Name.Contains(dto.Keyword))
+                .WhereIF(dto.AiOrderVisitTaskState != null, x => x.TaskState == dto.AiOrderVisitTaskState)
+                .WhereIF(dto.StartTime.HasValue, x => x.CreationTime >= dto.StartTime)
+                .WhereIF(dto.EndTime.HasValue, x => x.CreationTime <= dto.EndTime)
+                .OrderByDescending(x => x.CreationTime);
+        }
+
+        public ISugarQueryable<AiOrderVisitDetail> QueryAiOrderVisitDetail(AiVisitDetailListDto dto)
+        {
+            return _aiOrderVisitDetailRepository.Queryable()
+                .Includes(x => x.OrderVisit, x => x.OrderVisitDetails)
+                .Includes(x => x.Order)
+                .Where(x => x.AiOrderVisitId == dto.Id)
+                .WhereIF(dto.AiOrderVisitState.HasValue, x => x.AiOrderVisitState == dto.AiOrderVisitState)
+                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), x => x.Order.No.Contains(dto.Keyword) || x.Order.Title.Contains(dto.Keyword))
+                .OrderByDescending(x => x.CreationTime);
+        }
+    }
+}

+ 18 - 0
src/Hotline.Application/Orders/IAiOrderVisitApplication.cs

@@ -0,0 +1,18 @@
+using Hotline.Orders;
+using Hotline.Share.Dtos.Ai;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Application.Orders
+{
+    public interface IAiOrderVisitApplication
+    {
+        ISugarQueryable<AiOrderVisit> QuerysAiOrderVisit(AiVisitListDto dto);
+
+        ISugarQueryable<AiOrderVisitDetail> QueryAiOrderVisitDetail(AiVisitDetailListDto dto);
+    }
+}