using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DotNetCore.CAP; using Hotline.Application.CallCenter.Calls; using Hotline.Application.Tels; using Hotline.Caching.Interfaces; using Hotline.CallCenter.BlackLists; using Hotline.CallCenter.Calls; using Hotline.CallCenter.Tels; using Hotline.Orders; using Hotline.Settings; using Hotline.Share.Dtos; using Hotline.Share.Dtos.CallCenter; using Hotline.Share.Dtos.Order; using Hotline.Share.Dtos.TrCallCenter; using Hotline.Share.Enums.CallCenter; using Hotline.Share.Enums.Order; using Hotline.Share.Mq; using MapsterMapper; using Microsoft.AspNetCore.Http; using SqlSugar; using XF.Domain.Authentications; using XF.Domain.Exceptions; using XF.Domain.Repository; namespace Hotline.Application.CallCenter { public class TianRunCallApplication : DefaultCallApplication { private readonly ISessionContext _sessionContext; private readonly IRepository _trCallRecordRepository; private readonly ITrApplication _trApplication; private readonly ITelApplication _telApplication; private readonly ISystemSettingCacheManager _systemSettingCacheManager; private readonly IMapper _mapper; private readonly ICapPublisher _capPublisher; private readonly IRepository _trCallEvaluateRepository; private readonly IOrderVisitDomainService _orderVisitDomainService; private readonly IOrderRepository _orderRepository; public TianRunCallApplication( ISessionContext sessionContext, IRepository trCallRecordRepository, ITrApplication trApplication, ITelApplication telApplication, ISystemSettingCacheManager systemSettingCacheManager, IMapper mapper, ICapPublisher capPublisher, IRepository trCallEvaluateRepository, IOrderVisitDomainService orderVisitDomainService, IOrderRepository orderRepository) { _sessionContext = sessionContext; _trCallRecordRepository = trCallRecordRepository; _trApplication = trApplication; _telApplication = telApplication; _systemSettingCacheManager = systemSettingCacheManager; _mapper = mapper; _capPublisher = capPublisher; _trCallEvaluateRepository = trCallEvaluateRepository; _orderVisitDomainService = orderVisitDomainService; _orderRepository = orderRepository; } /// /// 新增黑名单 /// public override async Task AddBlackListAsync(AddBlacklistDto dto, CancellationToken cancellationToken) { throw new NotImplementedException(); } /// /// 删除黑名单 /// public override async Task RemoveBlackListAsync(string id, CancellationToken cancellationToken) { throw new NotImplementedException(); } /// /// 查询黑名单 /// public override async Task> QueryBlackListsAsync(CancellationToken cancellationToken) { throw new NotImplementedException(); } /// /// 签入 /// public override async Task SignInAsync(SignInDto dto, CancellationToken cancellationToken) => await _trApplication.OnSign(_sessionContext.RequiredUserId, dto.TelNo, (ETelModel)dto.TelModelState, cancellationToken); /// /// 签出 /// public override Task SingOutAsync(CancellationToken cancellationToken) => _telApplication.SignOutAsync(_sessionContext.RequiredUserId, cancellationToken); public override Task SingOutAsync(string telNo, CancellationToken cancellationToken) => _telApplication.SignOutByTelNoAsync(telNo, cancellationToken); public override async Task GetOrSetCallIdAsync(string callNo, CancellationToken cancellationToken) { return await Task.FromResult(callNo); } public override async Task PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken) { return; } public override async Task OrderVisitRelevanceCallIdAsync(VisitDto dto, CancellationToken cancellationToken) { return; } /// /// 查询当前用户的分机状态 /// /// /// public override Task GetTelStateAsync(CancellationToken cancellationToken) => _trApplication.TelState(_sessionContext.RequiredUserId, cancellationToken); public override async Task GetTianrunCallAsync(string callId, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(callId)) return null; var callRecord = await _trCallRecordRepository.GetAsync( x => x.OtherAccept == callId && string.IsNullOrEmpty(x.OtherAccept) == false, cancellationToken); return callRecord; } /// /// 根据转写ID获取通话信息 /// /// public override async Task GetTianrunCallTransliterationAsync(string transliterationId, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(transliterationId)) return null; var callRecord = await _trCallRecordRepository.GetAsync( x => x.TransliterationId == transliterationId && string.IsNullOrEmpty(x.OtherAccept) == false, cancellationToken); return callRecord; } /// /// 修改转写状态 /// /// public override async Task EditTransliterationStateAsync(string callId, ECallTransliterationState state, string transliterationId, CancellationToken cancellationToken) { await _trCallRecordRepository.Updateable().SetColumns(o => new TrCallRecord { TransliterationState = state, TransliterationId = transliterationId }) .Where(o => o.Id == callId).ExecuteCommandAsync(cancellationToken); } /// /// 关联通话记录与order(添润) /// public override async Task RelateTianrunCallWithOrderAsync(string callId, string orderId, CancellationToken cancellationToken) { var callRecords = await _trCallRecordRepository.Queryable().Where(p => p.OtherAccept == callId && string.IsNullOrEmpty(p.OtherAccept) == false).ToListAsync(cancellationToken); if (callRecords.Any()) { foreach (var callRecord in callRecords) { if (callRecord != null && string.IsNullOrEmpty(callRecord.ExternalId)) { callRecord.ExternalId = orderId; callRecord.CallOrderType = Share.Enums.CallCenter.ECallOrderType.Order; await _trCallRecordRepository.UpdateAsync(callRecord, cancellationToken); } } } else { //如果没查到通话记录就在2分钟后处理 _capPublisher.PublishDelay(DateTime.Now.AddMinutes(2) - DateTime.Now, EventNames.OrderRelateCall, orderId); } } /// /// 处理工单和通话记录关联问题 /// /// /// /// public override async Task OrderRelateCallHandlerAsync(string orderId, CancellationToken cancellationToken) { var order = await _orderRepository.GetAsync(orderId, cancellationToken); if (order != null) { var callRecords = await _trCallRecordRepository.Queryable().Where(p => p.OtherAccept == order.CallId && string.IsNullOrEmpty(p.OtherAccept) == false).ToListAsync(cancellationToken); if (callRecords.Any()) { foreach (var callRecord in callRecords) { if (callRecord != null && string.IsNullOrEmpty(callRecord.ExternalId)) { callRecord.ExternalId = orderId; callRecord.CallOrderType = Share.Enums.CallCenter.ECallOrderType.Order; await _trCallRecordRepository.UpdateAsync(callRecord, cancellationToken); } } } } return "ok"; } /// /// 查询通话记录 /// public override async Task> QueryTianrunCallsAsync( string? phone = null, ECallDirection? direction = null, DateTime? callStartTimeStart = null, DateTime? callStartTimeEnd = null, CancellationToken cancellationToken = default) { return await _trCallRecordRepository.Queryable() .WhereIF(!string.IsNullOrEmpty(phone), d => d.CPN == phone || d.CDPN == phone) .WhereIF(direction != null, d => d.CallDirection == direction) .WhereIF(callStartTimeStart != null, d => d.BeginIvrTime >= callStartTimeStart) .WhereIF(callStartTimeEnd != null, d => d.BeginIvrTime <= callStartTimeEnd) .OrderBy(x => x.CreatedTime) .ToListAsync(cancellationToken); } /// /// 查询分机操作选项 /// /// public override List GetTelOperationOptions() { throw new NotImplementedException(); } /// /// 查询通话记录 /// public override async Task GetCallAsync(string callId, CancellationToken cancellationToken) { var call = await _trCallRecordRepository.Queryable() .FirstAsync(d => d.OtherAccept == callId, cancellationToken); return _mapper.Map(call); } /// /// 查询通话记录列表 /// /// /// /// public override async Task> GetCallListAsync(string callId, CancellationToken cancellationToken) { var call = await _trCallRecordRepository.Queryable() .Where(d => d.OtherAccept == callId).ToListAsync(cancellationToken); return _mapper.Map>(call); } /// /// 根据 OrderId 返回用户电话评价枚举 /// 默认返回 默认满意 /// /// /// public override async Task GetReplyVoiceOrDefaultByOrderIdAsync(string orderId) { throw new NotImplementedException(); } /// /// 根据 OrderId 返回用户电话评价枚举 /// 默认返回 默认满意 /// /// /// public override async Task GetSeatDefaultByOrderIdAsync(string orderId) { var callRecord = await _trCallRecordRepository.Queryable().Where(x => x.ExternalId == orderId && x.CallOrderType == ECallOrderType.Order).FirstAsync(); if (callRecord is not null) { var callEvaluate = await _trCallEvaluateRepository.Queryable().Where(x => x.CallAccept == callRecord.CallAccept).FirstAsync(); if (callEvaluate is null) return ESeatEvaluate.DefaultSatisfied; try { return (ESeatEvaluate)(Convert.ToInt32(callEvaluate.Dtmf.Trim())); } catch (UserFriendlyException) { return ESeatEvaluate.DefaultSatisfied; } } return ESeatEvaluate.DefaultSatisfied; } } }