using Hotline.Application.CallCenter; using Hotline.Share.Tools; using Quartz; using SqlSugar; using Hotline.CallCenter.Calls; using Hotline.Repository.SqlSugar; using Hotline.Users; using MapsterMapper; using Microsoft.Extensions.Logging; using XF.Domain.Repository; using XingTang.Sdk; using DotNetCore.CAP; using Hotline.Share.Dtos.Order; using Hotline.Share.Dtos.TrCallCenter; using Hotline.Share.Enums.CallCenter; using System.Dynamic; using Hotline.Share.Dtos.CallCenter; namespace Hotline.Application.Jobs { /// /// 查询兴唐通话记录 /// public class XingTangCallsSyncJob : IJob, IDisposable { private readonly IRepository _callRepository; private readonly IRepository _userRepository; private readonly ICallApplication _callApplication; private readonly ICapPublisher _capPublisher; private readonly IMapper _mapper; private readonly ILogger _logger; private readonly ISqlSugarClient _db; public XingTangCallsSyncJob( ISugarUnitOfWork uow, IRepository callRepository, IRepository userRepository, ICallApplication callApplication, ICapPublisher capPublisher, IMapper mapper, ILogger logger) { _callRepository = callRepository; _userRepository = userRepository; _callApplication = callApplication; _capPublisher = capPublisher; _mapper = mapper; _logger = logger; _db = uow.Db; } public async Task Execute(IJobExecutionContext context) { var xingtangCalls = await _db.Queryable() .Where(d => !string.IsNullOrEmpty(d.CallGuid) && (d.IsSync == null || !d.IsSync) && (d.Tries == null || d.Tries <= 50)) .OrderBy(d => d.Id) .Take(10) .ToListAsync(context.CancellationToken); if (!xingtangCalls.Any()) return; var occupyCalls = new List(); foreach (var call in xingtangCalls) { call.IsSync = true; call.Tries += 1; var rows = await _db.Updateable(call) .ExecuteCommandWithOptLockAsync(); if (rows > 0) occupyCalls.Add(call); } if (!occupyCalls.Any()) return; try { var calls = _mapper.Map>(occupyCalls); //填充user信息 var staffNos = calls.Select(d => d.StaffNo).ToList(); var users = await _userRepository.Queryable() .Where(d => staffNos.Contains(d.StaffNo) && d.StaffNo != "0") .ToListAsync(context.CancellationToken); foreach (var call in calls) { call.Id = await GetCallIdAsync(call.CallNo, context.CancellationToken); var user = users.FirstOrDefault(d => d.StaffNo == call.StaffNo && d.StaffNo != "0"); if (user is not null) { call.UserId = user.Id; call.UserName = user.Name; } if (call.RingDuration == 0) { if (call.BeginRingTime != null) { if (call.EndRingTime != null) { call.RingDuration = call.BeginRingTime.Value.GetDifferenceSeconds(call.EndRingTime.Value); } else { call.RingDuration = call.BeginRingTime.Value.GetDifferenceSeconds(call.EndTime); } } } if (call.GroupId == "0" && call.CallState != ECallState.IVRNoAccept) { call.CallState = ECallState.Invalid; } } await _callRepository.AddRangeAsync(calls, context.CancellationToken); //推省上 if (calls.Any()) { var callIns = _mapper.Map>(calls); await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineCallAdd, callIns); } ////todo //var callIns = calls.Where(d => d.Direction == ECallDirection.In).ToList(); //if (callIns.Any()) //{ // await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineCallAdd, callIns); //} } catch (Exception e) { //Console.WriteLine(e); _logger.LogError($"获取通话记录异常:{e.Message} \n {e.StackTrace}"); foreach (var occupyCall in occupyCalls) { occupyCall.IsSync = false; } await _db.Updateable(occupyCalls) .UpdateColumns(d => new { d.IsSync }) .ExecuteCommandAsync(context.CancellationToken); } } private async Task GetCallIdAsync(string callNo, CancellationToken cancellation) { if (string.IsNullOrEmpty(callNo)) return string.Empty; 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); } /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() { //_logger.LogInformation($"{nameof(XingTangCallsSyncJob)} disposed"); } } }