瀏覽代碼

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

田爽 9 月之前
父節點
當前提交
ce314a6182

+ 8 - 8
src/Hotline.Api/StartupHelper.cs

@@ -263,14 +263,14 @@ namespace Hotline.Api
                 switch (callCenterConfiguration.CallCenterType)
                 {
                     case AppDefaults.CallCenterType.XingTang:
-                        // var getCallsJobKey = new JobKey(nameof(XingTangCallsSyncJob));
-                        // d.AddJob<XingTangCallsSyncJob>(getCallsJobKey);
-                        // d.AddTrigger(t => t
-                        //     .WithIdentity("get-callsxt-trigger")
-                        //     .ForJob(getCallsJobKey)
-                        //     .StartNow()
-                        //     .WithCronSchedule("0/5 * * * * ?")
-                        // );
+                        var getCallsJobKey = new JobKey(nameof(XingTangCallsSyncJob));
+                        d.AddJob<XingTangCallsSyncJob>(getCallsJobKey);
+                        d.AddTrigger(t => t
+                            .WithIdentity("get-callsxt-trigger")
+                            .ForJob(getCallsJobKey)
+                            .StartNow()
+                            .WithCronSchedule("0/5 * * * * ?")
+                        );
 
                         var getOperationsJobKey = new JobKey(nameof(XingTangTelOperationSyncJob));
                         d.AddJob<XingTangTelOperationSyncJob>(getOperationsJobKey);

+ 2 - 2
src/Hotline.Api/config/appsettings.Development.json

@@ -28,7 +28,7 @@
     }
   },
   "ConnectionStrings": {
-    "Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;"
+    "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;"
     //"Redis": "110.188.24.182:50179",
     //"MongoDB": "mongodb://192.168.100.121:27017",
     //"Wex": "server=222.212.82.225;Port=4509;Database=fs_kft;Uid=root;Pwd=Wex@12345;"
@@ -37,7 +37,7 @@
     "Host": "110.188.24.182",
     "Port": 50179,
     "Password": "fengwo123!$!$",
-    "Database": 3 //release:3, dev:5
+    "Database": 5 //release:3, dev:5
   },
   "Swagger": true,
   "Cors": {

+ 2 - 2
src/Hotline.Api/config/appsettings.json

@@ -28,7 +28,7 @@
     }
   },
   "ConnectionStrings": {
-    "Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;"
+    "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;"
     //"Redis": "110.188.24.182:50179,password=fengwo22@@",
     //"MongoDB": "mongodb://192.168.100.121:27017",
     //"Wex": "server=222.212.82.225;Port=4509;Database=fs_kft;Uid=root;Pwd=Wex@12345;"
@@ -37,7 +37,7 @@
     "Host": "110.188.24.182",
     "Port": 50179,
     "Password": "fengwo123!$!$",
-    "Database": 3
+    "Database": 5 
   },
   "Swagger": true,
   "Cors": {

+ 17 - 33
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -217,7 +217,7 @@ public abstract class DefaultCallApplication : ICallApplication
             .WhereIF(dto.Direction != null, d => d.Direction == dto.Direction)
             .WhereIF(dto.WaitDurationStart != null && dto.WaitDurationStart > 0, d => d.WaitDuration >= dto.WaitDurationStart)
             .WhereIF(dto.WaitDurationEnd != null && dto.WaitDurationEnd > 0, d => d.WaitDuration <= dto.WaitDurationEnd)
-            .OrderByDescending(d=>d.Id)
+            .OrderByDescending(d => d.Id)
             .Select((d, o) => new CallNativeDto
             {
                 OrderId = o.Id,
@@ -237,7 +237,7 @@ public abstract class DefaultCallApplication : ICallApplication
             .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), d => d.StaffNo == dto.StaffNo)
             .WhereIF(!string.IsNullOrEmpty(dto.GroupId), d => d.GroupId == dto.GroupId)
             .WhereIF(dto.OperateState != null, d => d.OperateState == dto.OperateState)
-            .OrderByDescending(d=>d.Id)
+            .OrderByDescending(d => d.Id)
             .ToFixedListAsync(dto, cancellationToken);
     }
 
@@ -261,45 +261,29 @@ public abstract class DefaultCallApplication : ICallApplication
             catch (Exception e)
             {
                 _logger.LogError($"写入callidRelation失败:{e.Message}");
+                return await GetOrSetCallIdAsync(callNo, cancellationToken);
             }
         }
 
         return callOrder.CallId;
     }
 
-    /// <summary>
-    /// 批量获取callId
-    /// </summary>
-    public virtual async Task<List<(string callNo, string callId)>> GetOrSetCallIdRangeAsync(List<string> callNos,
-        CancellationToken cancellationToken)
+    public async Task<CallidRelation> GetRelationAsync(string callNo, CancellationToken cancellation)
     {
-        var relations = await _callIdRelationRepository.Queryable()
-            .Where(d => callNos.Contains(d.Id))
-            .ToListAsync(cancellationToken);
+        return await _callIdRelationRepository.GetAsync(callNo, cancellation);
+    }
 
-        var rsp = new List<(string callNo, string callId)>();
-        var newRelations = new List<CallidRelation>();
-        foreach (var callNo in callNos)
-        {
-            var relation = relations.FirstOrDefault(d => d.Id == callNo);
-            if (relation is null)
-            {
-                relation = new CallidRelation
-                {
-                    Id = callNo,
-                    CallId = Ulid.NewUlid().ToString(),
-                };
-                newRelations.Add(relation);
-                rsp.Add(new(relation.Id, relation.CallId));
-            }
-            else
-            {
-                rsp.Add(new(relation.Id, relation.CallId));
-            }
-        }
+    public async Task AddRelationAsync(CallidRelation relation, CancellationToken cancellation)
+    {
+        await _callIdRelationRepository.AddAsync(relation, cancellation);
+    }
 
-        await _callIdRelationRepository.AddRangeAsync(newRelations, cancellationToken);
-        return rsp;
+    /// <summary>
+    /// 乐观并发更新映射关系
+    /// </summary>
+    public virtual async Task<int> UpdateRelationOptLockAsync(CallidRelation relation, CancellationToken cancellationToken)
+    {
+        return await _callIdRelationRepository.Updateable(relation).ExecuteCommandWithOptLockAsync();
     }
 
     /// <summary>
@@ -352,7 +336,7 @@ public abstract class DefaultCallApplication : ICallApplication
     /// 查询通话记录
     /// </summary>
     public virtual Task<List<TrCallRecord>> QueryTianrunCallsAsync(
-        string? phone = null, 
+        string? phone = null,
         ECallDirection? direction = null,
         DateTime? callStartTimeStart = null,
         DateTime? callStartTimeEnd = null,

+ 7 - 2
src/Hotline.Application/CallCenter/ICallApplication.cs

@@ -77,10 +77,14 @@ namespace Hotline.Application.CallCenter
         /// </summary>
         Task<string> GetOrSetCallIdAsync(string callNo, CancellationToken cancellationToken);
 
+        Task<CallidRelation> GetRelationAsync(string callNo, CancellationToken cancellation);
+
+        Task AddRelationAsync(CallidRelation relation, CancellationToken cancellation);
+
         /// <summary>
-        /// 批量获取callId
+        /// 乐观并发更新映射关系
         /// </summary>
-        Task<List<(string callNo, string callId)>> GetOrSetCallIdRangeAsync(List<string> callNos, CancellationToken cancellationToken);
+        Task<int> UpdateRelationOptLockAsync(CallidRelation relation, CancellationToken cancellationToken);
 
         /// <summary>
         /// 查询通话记录
@@ -123,5 +127,6 @@ namespace Hotline.Application.CallCenter
         /// </summary>
         /// <returns></returns>
         List<Kv> GetTelOperationOptions();
+
     }
 }

+ 30 - 6
src/Hotline.Application/Jobs/XingTangCallsSyncJob.cs

@@ -43,7 +43,8 @@ namespace Hotline.Application.Jobs
         {
             var xingtangCalls = await _db.Queryable<XingtangCall>()
                 .Where(d => (d.IsSync == null || !d.IsSync) && (d.Tries == null || d.Tries <= 50))
-                .Take(50)
+                .OrderBy(d => d.Id)
+                .Take(10)
                 .ToListAsync(context.CancellationToken);
 
             var occupyCalls = new List<XingtangCall>();
@@ -67,13 +68,9 @@ namespace Hotline.Application.Jobs
                     .Where(d => staffNos.Contains(d.StaffNo))
                     .ToListAsync(context.CancellationToken);
 
-                var relations = await _callApplication.GetOrSetCallIdRangeAsync(
-                    calls.Select(d => d.CallNo).ToList(),
-                    context.CancellationToken);
-
                 foreach (var call in calls)
                 {
-                    call.Id = relations.First(d => d.callNo == call.CallNo).callId;
+                    call.Id = await GetCallIdAsync(call.CallNo, context.CancellationToken);
                     var user = users.FirstOrDefault(d => d.StaffNo == call.StaffNo);
                     if (user is not null)
                     {
@@ -99,6 +96,33 @@ namespace Hotline.Application.Jobs
             }
         }
 
+        private async Task<string> GetCallIdAsync(string callNo, CancellationToken cancellation)
+        {
+            var relation = await _callApplication.GetRelationAsync(callNo, cancellation);
+            if (relation is null)
+            {
+                relation = new CallidRelation
+                {
+                    Id = callNo,
+                    CallId = Ulid.NewUlid().ToString(),
+                    IsUsed = true
+                };
+                await _callApplication.AddRelationAsync(relation, cancellation);
+                return relation.CallId;
+            }
+
+            if (relation.IsUsed)
+                return Ulid.NewUlid().ToString();
+
+            relation.IsUsed = true;
+            var rows = await _callApplication.UpdateRelationOptLockAsync(relation, cancellation);
+            if (rows > 0)
+                return relation.CallId;
+
+            //重新取relation 重新判断isUsed
+            return await GetCallIdAsync(callNo, cancellation);
+        }
+
         /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
         public void Dispose()
         {

+ 1 - 1
src/Hotline.Application/Orders/OrderApplication.cs

@@ -231,7 +231,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                //&& stTime >= d.ExpiredTime.Value && stTime2 <= d.ExpiredTime.Value
 			//.Where(d => d.ExpiredTime != null &&
    //         d.Status != EOrderStatus.Filed && d.Status != EOrderStatus.Published && d.Status != EOrderStatus.Visited && stTime >= d.ExpiredTime.Value && stTime2 <= d.ExpiredTime.Value)
-            .Where(d=>d.Status < EOrderStatus.Filed && dateTime > d.NearlyExpiredTime && dateTime < d.ExpiredTime)
+            .Where(d=>d.Status < EOrderStatus.Filed && ( dateTime > d.NearlyExpiredTimeOne || dateTime > d.NearlyExpiredTime ) && dateTime < d.ExpiredTime)
             .OrderByDescending(d => d.CreationTime);
     }
 

+ 2 - 2
src/Hotline.Share/Enums/Order/EExpiredStatus.cs

@@ -13,7 +13,7 @@ public enum EExpiredStatus
     /// <summary>
     /// 即将超期
     /// </summary>
-    [Description("即将超期")]
+    [Description("剩余时间小于20%")]
     GoingToExpired = 1,
 
     /// <summary>
@@ -25,6 +25,6 @@ public enum EExpiredStatus
     /// <summary>
     /// 即将超期
     /// </summary>
-    [Description("即将超期")]
+    [Description("剩余时间小于50%")]
     GoingToExpiredOne = 3,
 }

+ 9 - 1
src/Hotline/CallCenter/Calls/CallidRelation.cs

@@ -14,7 +14,15 @@ namespace Hotline.CallCenter.Calls
     /// Id: CallNo
     /// </summary>
     public class CallidRelation : CreationEntity
-    {   
+    {
         public string CallId { get; set; }
+
+        /// <summary>
+        /// 是否被通话记录取用
+        /// </summary>
+        public bool IsUsed { get; set; }
+
+        [SqlSugar.SugarColumn(IsEnableUpdateVersionValidation = true)]
+        public Guid Ver { get; set; }
     }
 }

+ 28 - 0
src/Hotline/Permissions/EPermission.cs

@@ -2280,6 +2280,21 @@ namespace Hotline.Permissions
         /// </summary>
         [Display(GroupName ="数据统计",Name ="区域分时统计",Description ="区域分时统计")]
         AreaTimeStatistics = 110219,
+        /// <summary>
+        /// 受理类型统计
+        /// </summary>
+        [Display(GroupName ="数据统计",Name ="受理类型统计",Description ="受理类型统计")]
+        AcceptTypeStatistics = 110220,
+        /// <summary>
+        /// 下级区域统计
+        /// </summary>
+        [Display(GroupName ="数据统计",Name ="下级区域统计",Description ="下级区域统计")]
+        NextLevelAreaStatistics = 110221,
+        /// <summary>
+        /// 热点区域统计
+        /// </summary>
+        [Display(GroupName ="数据统计",Name ="热点区域统计",Description ="热点区域统计")]
+        HotspotAndAreaStatistics = 110222,
         #endregion
 
         #region 知识库统计(11,03,00)
@@ -2436,6 +2451,19 @@ namespace Hotline.Permissions
         SiFaOrgVisitAndOrgSatisfactionStatistics = 120205,
         #endregion
 
+        #region 自定义工单
+        /// <summary>
+        /// 自定义工单
+        /// </summary>
+        [Display(GroupName ="司法自定义工单",Name ="自定义工单",Description ="自定义工单")]
+        SiFaCustomOrder = 120300,
+        /// <summary>
+        /// 新建工单
+        /// </summary>
+        [Display(GroupName ="司法自定义工单",Name ="新建工单",Description ="新建工单")]
+        SiFaNewOrder = 120301,
+
+        #endregion
 
         #endregion