瀏覽代碼

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

Dun.Jason 9 月之前
父節點
當前提交
f281e386d6

+ 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);

+ 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()
         {

+ 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; }
     }
 }