Kaynağa Gözat

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

田爽 5 ay önce
ebeveyn
işleme
8b69aea74c

+ 3 - 5
src/Hotline.Api/Controllers/OrderController.cs

@@ -288,9 +288,8 @@ public class OrderController : BaseController
     [HttpGet("publish/items")]
     public async Task<IList<PublishDto>> GetPublishOrderListAsync([FromQuery] QueryOrderPublishDto dto)
     { 
-        var fixedQueryCount = _systemSettingCacheManager.FixedQueryCount;
         var query = _orderApplication.GetPublishOrderList(dto);
-        return (await query.ToFixedListAsync(dto.QueryIndex, fixedQueryCount, HttpContext.RequestAborted))
+        return (await query.ToFixedListAsync(dto.QueryIndex, dto.PageSize, HttpContext.RequestAborted))
             .Adapt<List<PublishDto>>();
     }
 
@@ -664,9 +663,8 @@ public class OrderController : BaseController
     [HttpGet("published/items")]
     public async Task<IList<PublishedDto>> GetPublishedOrderListAsync([FromQuery] PublishedPagedRequest dto)
     {
-        var fixedQueryCount = _systemSettingCacheManager.FixedQueryCount;
         var query = _orderApplication.GetPublishedOrder(dto);
-        return (await query.ToFixedListAsync(dto.QueryIndex, fixedQueryCount, HttpContext.RequestAborted))
+        return (await query.ToFixedListAsync(dto.QueryIndex, dto.PageSize, HttpContext.RequestAborted))
             .Adapt<List<PublishedDto>>();
     }
 
@@ -4675,7 +4673,7 @@ public class OrderController : BaseController
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    [Permission(EPermission.OrderPreviousList)]
+    //[Permission(EPermission.OrderPreviousList)]
     [HttpGet("order_previous_list")]
     public async Task<PagedDto<SendBackDto>> AuditList([FromQuery] SendBackListDto dto)
     {

+ 20 - 6
src/Hotline.Application.Tests/Application/ZiGongCallReportApplicationTest.cs

@@ -1,4 +1,5 @@
 using Hotline.Application.StatisticalReport.CallReport;
+using Hotline.Caching.Interfaces;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Requests;
@@ -15,12 +16,12 @@ namespace Hotline.Application.Tests.Application;
 public class ZiGongCallReportApplicationTest
 {
     private readonly ZiGongCallReportApplication _ziGongCallReportApplication;
-    private CancellationToken cancellation;
+    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
 
-    public ZiGongCallReportApplicationTest(ZiGongCallReportApplication ziGongCallReportApplication)
+    public ZiGongCallReportApplicationTest(ZiGongCallReportApplication ziGongCallReportApplication, ISystemDicDataCacheManager systemDicDataCacheManager)
     {
         _ziGongCallReportApplication = ziGongCallReportApplication;
-        cancellation = new CancellationToken();
+        _systemDicDataCacheManager = systemDicDataCacheManager;
     }
 
     [Fact]
@@ -44,7 +45,7 @@ public class ZiGongCallReportApplicationTest
             EndTime = DateTime.Now
         };
 
-        var result = await _ziGongCallReportApplication.QuerySeatCallAsync(inDto, cancellation);
+        var result = await _ziGongCallReportApplication.QuerySeatCallAsync(inDto, CancellationToken.None);
         result.ShouldNotBeNull();
     }
 
@@ -66,7 +67,7 @@ public class ZiGongCallReportApplicationTest
             ToNo = toNo,
             EndBy = endBy?.ToEnum<EEndBy>()
         };
-        var (total, items) = await _ziGongCallReportApplication.QueryCallsStatisticsDetailAsync(inDto, cancellation);
+        var (total, items) = await _ziGongCallReportApplication.QueryCallsStatisticsDetailAsync(inDto, CancellationToken.None);
         total.ShouldNotBe(0);
         items.Any(m => m.OrderNo.NotNullOrEmpty()).ShouldBeTrue();
         items.Any(m => m.OrderTitle.NotNullOrEmpty()).ShouldBeTrue();
@@ -89,7 +90,7 @@ public class ZiGongCallReportApplicationTest
             StartTime = "2024-07-29".ObjToDate(),
             EndTime = "2024-07-29 23:59:59".ObjToDate(),
         };
-        var result = await _ziGongCallReportApplication.QueryCallsDetailStatisticsAsync(inDto, cancellation);
+        var result = await _ziGongCallReportApplication.QueryCallsDetailStatisticsAsync(inDto, CancellationToken.None);
         result.Any(m => m.InConnectionRate.IsNullOrEmpty()).ShouldBeFalse();
         result.ShouldNotBeNull();
     }
@@ -161,4 +162,17 @@ public class ZiGongCallReportApplicationTest
         bhour.Total.ShouldBe(hour.Count, "Count 列表和详情的数量对不上");
 
     }
+
+    [Fact]
+    public async Task GetCallHotLineList_Test()
+    {
+        var dto = new BiQueryGateWayDto
+        {
+            StartTime = DateTime.Now.AddMonths(-1),
+            EndTime = DateTime.Now
+        };
+        var result = await _ziGongCallReportApplication.GetCallHotLineListAsync(dto, CancellationToken.None);
+        var hotlines = _systemDicDataCacheManager.CallForwardingSource.Select(m => m.DicDataValue).ToList();
+        result.Any(m => !hotlines.Contains(m.GateWay)).ShouldBeFalse();
+    }
 }

+ 1 - 0
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -293,6 +293,7 @@ public abstract class DefaultCallApplication : ICallApplication
     public virtual async Task<IReadOnlyList<TelOperation>> QueryTelOperationsAsync(QueryTelOperationsFixedDto dto, CancellationToken cancellationToken)
     {
         return await _telOperationRepository.Queryable()
+            .Where(m => m.OperateStateText != "未知")
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), d => d.UserName == dto.UserName)
             .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), d => d.StaffNo == dto.StaffNo)
             .WhereIF(!string.IsNullOrEmpty(dto.GroupId), d => d.GroupId == dto.GroupId)

+ 33 - 3
src/Hotline.Application/Knowledge/KnowApplication.cs

@@ -166,6 +166,21 @@ namespace Hotline.Application.Knowledge
             return new PagedDto<KnowledgeApplyHandlePageDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApplyHandlePageDto>>(items));
         }
 
+        //public async Task<Dictionary<string, Stream>> KnowledgeInfoListExportAsync(KnowledgeInfoExportInDto dto, CancellationToken cancellationToken)
+        //{
+        //    var streamList = new Dictionary<string, Stream>();
+        //    var knowList = await _knowledgeRepository.Queryable()
+        //        .Where(m => dto.Ids.Contains(m.Id))
+        //        .Select(m => new { m.Title, m.Content })
+        //        .ToListAsync(cancellationToken);
+        //    foreach (var item in knowList)
+        //    {
+        //        Stream stream = item.Content.HtmlToStream(dto.FileType);
+        //        streamList.Add(item.Title + dto.FileType.GetFileExtension(), stream);
+        //    }
+        //    return streamList;
+        //}
+
         public async Task<Dictionary<string, Stream>> KnowledgeInfoListExportAsync(KnowledgeInfoExportInDto dto, CancellationToken cancellationToken)
         {
             var streamList = new Dictionary<string, Stream>();
@@ -173,11 +188,26 @@ namespace Hotline.Application.Knowledge
                 .Where(m => dto.Ids.Contains(m.Id))
                 .Select(m => new { m.Title, m.Content })
                 .ToListAsync(cancellationToken);
-            foreach (var item in knowList)
+
+            var tasks = knowList.Select(async item =>
+            {
+                var stream = await Task.Run(() => item.Content.HtmlToStream(dto.FileType), cancellationToken);
+                return new KeyValuePair<string, Stream>(
+                    item.Title + dto.FileType.GetFileExtension(),
+                    stream
+                );
+            });
+
+            var results = await Task.WhenAll(tasks);
+
+            foreach (var kvp in results)
             {
-                Stream stream = item.Content.HtmlToStream(dto.FileType);
-                streamList.Add(item.Title + dto.FileType.GetFileExtension(), stream);
+                if (!streamList.ContainsKey(kvp.Key))
+                {
+                    streamList.Add(kvp.Key, kvp.Value);
+                }
             }
+
             return streamList;
         }
 

+ 5 - 2
src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs

@@ -25,18 +25,20 @@ namespace Hotline.Application.StatisticalReport.CallReport;
 public abstract class CallReportApplicationBase : ICallReportApplication
 {
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
     private readonly ICallNativeRepository _callNativeRepository;
     private readonly IRepository<User> _userRepository;
     private readonly IRepository<Work> _workRepository;
     private readonly IRepository<TelRest> _telRestRepository;
 
-    protected CallReportApplicationBase(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository)
+    protected CallReportApplicationBase(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository, ISystemDicDataCacheManager systemDicDataCacheManager)
     {
         _systemSettingCacheManager = systemSettingCacheManager;
         _callNativeRepository = callNativeRepository;
         _userRepository = userRepository;
         _workRepository = workRepository;
         _telRestRepository = telRestRepository;
+        _systemDicDataCacheManager = systemDicDataCacheManager;
     }
 
     public virtual async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken requestAborted)
@@ -45,7 +47,8 @@ public abstract class CallReportApplicationBase : ICallReportApplication
         int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
         int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
         int ringTimes = _systemSettingCacheManager.RingTimes;
-        return await _callNativeRepository.GetCallHotLineListAsync(dto, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTimes);
+        var hotlines = _systemDicDataCacheManager.CallForwardingSource.Select(m => m.DicDataValue).ToList();
+        return await _callNativeRepository.GetCallHotLineListAsync(dto, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTimes, hotlines);
     }
 
     public virtual async Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken requestAborted)

+ 1 - 1
src/Hotline.Application/StatisticalReport/CallReport/LuZhouCallReportApplication.cs

@@ -11,7 +11,7 @@ namespace Hotline.Application.StatisticalReport.CallReport;
 [Injection(AppScopes = EAppScope.LuZhou)]
 public class LuZhouCallReportApplication : CallReportApplicationBase, ICallReportApplication, IScopeDependency
 {
-    public LuZhouCallReportApplication(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository)
+    public LuZhouCallReportApplication(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository, ISystemDicDataCacheManager systemDicDataCacheManager) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository, systemDicDataCacheManager)
     {
     }
 }

+ 2 - 1
src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs

@@ -41,7 +41,8 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
         IRepository<TelRest> telRestRepository,
         ICallNativeRepository callNativeRepository,
         ITrCallRecordRepository trCallRecordRepositoryEx,
-        IMapper mapper) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository)
+        IMapper mapper,
+        ISystemDicDataCacheManager systemDicDataCacheManager) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository, systemDicDataCacheManager)
     {
         _trCallRecordRepository = trCallRecordRepository;
         _systemSettingCacheManager = systemSettingCacheManager;

+ 1 - 1
src/Hotline.Application/StatisticalReport/CallReport/ZiGongCallReportApplication.cs

@@ -11,7 +11,7 @@ namespace Hotline.Application.StatisticalReport.CallReport;
 [Injection(AppScopes = EAppScope.ZiGong)]
 public class ZiGongCallReportApplication : CallReportApplicationBase, ICallReportApplication, IScopeDependency
 {
-    public ZiGongCallReportApplication(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository)
+    public ZiGongCallReportApplication(ISystemSettingCacheManager systemSettingCacheManager, ICallNativeRepository callNativeRepository, IRepository<User> userRepository, IRepository<Work> workRepository, IRepository<TelRest> telRestRepository, ISystemDicDataCacheManager systemDicDataCacheManager) : base(systemSettingCacheManager, callNativeRepository, userRepository, workRepository, telRestRepository, systemDicDataCacheManager)
     {
     }
 }

+ 2 - 1
src/Hotline.Repository.SqlSugar/CallCenter/CallNativeRepository.cs

@@ -225,10 +225,11 @@ public class CallNativeRepository : BaseRepository<CallNative>, ICallNativeRepos
         return new TotalData<BiSeatSwitchDto>(res, total.Value);
     }
 
-    public async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTims)
+    public async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTims, List<string> hotLines)
     {
         var list = await Db.Queryable<CallNative>()
             .Where(x => x.BeginIvrTime >= dto.StartTime && x.BeginIvrTime <= dto.EndTime && SqlFunc.Length(x.ToNo) > 4 && x.CallState != ECallState.Invalid)
+            .Where(x => hotLines.Contains(x.ToNo))
             .WhereIF(!string.IsNullOrEmpty(dto.Gateway), x => x.ToNo == dto.Gateway)
             .GroupBy(x => x.ToNo)
             .Select(x => new CallHotLineDto()

+ 25 - 2
src/Hotline.Share/Tools/HtmlImageValidator.cs

@@ -6,10 +6,19 @@ using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 
 namespace Hotline.Share.Tools;
+
+/// <summary>
+/// Html 转 Word 时,验证图片是否有效
+/// </summary>
 public class HtmlImageValidator
 {
     private readonly HttpClient _httpClient = new HttpClient();
 
+    /// <summary>
+    /// Html 转 Word 时,验证图片是否有效
+    /// </summary>
+    /// <param name="htmlContent"></param>
+    /// <returns></returns>
     public string ValidateAndReplaceImagesAsync(string htmlContent)
     {
         string pattern = "<img[^>]+src=\"([^\"]+)\"[^>]*>";
@@ -28,12 +37,26 @@ public class HtmlImageValidator
         return htmlContent;
     }
 
+    /// <summary>
+    /// 请求图片链接,判断是否有效
+    /// </summary>
+    /// <param name="url"></param>
+    /// <returns></returns>
     private bool IsImageAccessible(string url)
     {
         try
         {
-            var response = _httpClient.GetAsync(url).GetAwaiter().GetResult();
-            return response.IsSuccessStatusCode;
+            var task = _httpClient.GetAsync(url);
+            var completedTask = Task.WhenAny(task, Task.Delay(3000)).GetAwaiter().GetResult();
+
+            if (completedTask == task && task.Result.IsSuccessStatusCode)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
         }
         catch
         {

+ 2 - 0
src/Hotline/Caching/Interfaces/ISysDicDataCacheManager.cs

@@ -14,5 +14,7 @@ namespace Hotline.Caching.Interfaces
         void RemoveSysDicDataCache(string code);
         IReadOnlyList<SystemDicData> AcceptType { get; }
         IReadOnlyList<SystemDicData> LeaderSMS { get; }
+
+        IReadOnlyList<SystemDicData> CallForwardingSource { get; }
     }
 }

+ 2 - 0
src/Hotline/Caching/Services/SysDicDataCacheManager.cs

@@ -34,6 +34,8 @@ namespace Hotline.Caching.Services
 
         public IReadOnlyList<SystemDicData> LeaderSMS => GetSysDicDataCache(SysDicTypeConsts.LeaderSMS);
 
+        public IReadOnlyList<SystemDicData> CallForwardingSource => GetSysDicDataCache(SysDicTypeConsts.CallForwardingSource);
+
         public void RemoveSysDicDataCache(string code)
         {
             _cacheSysDicData.Remove(code);

+ 1 - 1
src/Hotline/CallCenter/Calls/ICallNativeRepository.cs

@@ -10,5 +10,5 @@ public interface ICallNativeRepository : IRepository<CallNative>
     Task<List<QueryCallsDetailDto>> QueryCallsHourDetail(DateTime beginDate, DateTime endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int CallInOverConnRingTime, int SeatChaoTime, string? Line);
     Task<List<TrCallHourDto>?> GetCallHourList(DateTime beginDate, DateTime? endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, string source);
     Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes,int connectByeTimes);
-    Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTimes);
+    Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTimes, List<string> hotLines);
 }

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

@@ -335,7 +335,7 @@ public abstract class StepBasicEntity : CreationEntity
     /// <summary>
     /// 办理意见
     /// </summary>
-    [SugarColumn(Length = 8000)]
+    [SugarColumn(ColumnDataType = "text")]
     public string? Opinion { get; set; }
 
     /// <summary>

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

@@ -126,7 +126,7 @@ public partial class Workflow : CreationEntity
     /// <summary>
     /// 实际办理意见(办理中...or 最终办理意见)
     /// </summary>
-    [SugarColumn(Length = 8000)]
+    [SugarColumn(ColumnDataType = "text")]
     public string ActualOpinion { get; set; } = "办理中...";
 
     ///// <summary>

+ 3 - 3
src/Hotline/Orders/Order.cs

@@ -384,7 +384,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 交办意见
         /// </summary>
-        [SugarColumn(Length = 8000, ColumnDescription = "交办意见")]
+        [SugarColumn(ColumnDataType = "text", ColumnDescription = "交办意见")]
         public string? CenterToOrgOpinion { get; set; }
 
         /// <summary>
@@ -558,7 +558,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 实际办理意见(办理中...or 最终办理意见)
         /// </summary>
-        [SugarColumn(Length = 8000, ColumnDescription = "实际办理意见")]
+        [SugarColumn(ColumnDataType = "text", ColumnDescription = "实际办理意见")]
         public string ActualOpinion { get; set; } = "办理中...";
 
         /// <summary>
@@ -835,7 +835,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 归档意见
         /// </summary>
-        [SugarColumn(ColumnDataType = "varchar(8000)", ColumnDescription = "归档意见")]
+        [SugarColumn(ColumnDataType = "text", ColumnDescription = "归档意见")]
         public string? FileOpinion { get; set; }
 
         #endregion

+ 3 - 3
src/Hotline/Orders/OrderPublish.cs

@@ -34,13 +34,13 @@ public class OrderPublish : FullStateEntity
     /// <summary>
     /// 整理内容
     /// </summary>
-    [SugarColumn(ColumnDataType = "varchar(8000)")]
+    [SugarColumn(ColumnDataType = "text")]
     public string ArrangeContent { get; set; }
 
     /// <summary>
     /// 整理结果
     /// </summary>
-    [SugarColumn(ColumnDataType = "varchar(8000)")]
+    [SugarColumn(ColumnDataType = "text")]
     public string ArrangeOpinion { get; set; }
 
     /// <summary>
@@ -97,7 +97,7 @@ public class OrderPublish : FullStateEntity
     /// <summary>
     /// 答复口径
     /// </summary>
-    [SugarColumn(ColumnDataType = "varchar(8000)", IsNullable = true)]
+    [SugarColumn(ColumnDataType = "text", IsNullable = true)]
     public string? AnswerContent { get; set; }
     #endregion
 

+ 4 - 4
src/Hotline/Orders/OrderPublishHistory.cs

@@ -39,25 +39,25 @@ namespace Hotline.Orders
         /// <summary>
         /// 整理内容修改前
         /// </summary>
-        [SugarColumn(ColumnDataType = "varchar(8000)")]
+        [SugarColumn(ColumnDataType = "text")]
         public string ArrangeContentBefor { get; set; }
 
         /// <summary>
         /// 整理内容修改后
         /// </summary>
-        [SugarColumn(ColumnDataType = "varchar(8000)")]
+        [SugarColumn(ColumnDataType = "text")]
         public string ArrangeContentAfter { get; set; }
 
         /// <summary>
         /// 整理结果修改前
         /// </summary>
-        [SugarColumn(ColumnDataType = "varchar(8000)")]
+        [SugarColumn(ColumnDataType = "text")]
         public string ArrangeOpinionBefor { get; set; }
 
         /// <summary>
         /// 整理结果修改后
         /// </summary>
-        [SugarColumn(ColumnDataType = "varchar(8000)")]
+        [SugarColumn(ColumnDataType = "text")]
         public string ArrangeOpinionAfter { get; set; }
 
         /// <summary>