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");
}
}
}