123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- 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<TrCallRecord> _trCallRecordRepository;
- private readonly ITrApplication _trApplication;
- private readonly ITelApplication _telApplication;
- private readonly ISystemSettingCacheManager _systemSettingCacheManager;
- private readonly IMapper _mapper;
- private readonly ICapPublisher _capPublisher;
- private readonly IRepository<TrCallEvaluate> _trCallEvaluateRepository;
- private readonly IOrderVisitDomainService _orderVisitDomainService;
- private readonly IOrderRepository _orderRepository;
- public TianRunCallApplication(
- ISessionContext sessionContext,
- IRepository<TrCallRecord> trCallRecordRepository,
- ITrApplication trApplication,
- ITelApplication telApplication,
- ISystemSettingCacheManager systemSettingCacheManager,
- IMapper mapper,
- ICapPublisher capPublisher,
- IRepository<TrCallEvaluate> 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;
- }
- /// <summary>
- /// 新增黑名单
- /// </summary>
- public override async Task<string> AddBlackListAsync(AddBlacklistDto dto, CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// 删除黑名单
- /// </summary>
- public override async Task RemoveBlackListAsync(string id, CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// 查询黑名单
- /// </summary>
- public override async Task<List<Blacklist>> QueryBlackListsAsync(CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// 签入
- /// </summary>
- public override async Task<TrOnDutyResponseDto> SignInAsync(SignInDto dto, CancellationToken cancellationToken) =>
- await _trApplication.OnSign(_sessionContext.RequiredUserId, dto.TelNo, (ETelModel)dto.TelModelState, cancellationToken);
- /// <summary>
- /// 签出
- /// </summary>
- 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<string> 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;
- }
- /// <summary>
- /// 查询当前用户的分机状态
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public override Task<TrOnDutyResponseDto> GetTelStateAsync(CancellationToken cancellationToken) =>
- _trApplication.TelState(_sessionContext.RequiredUserId, cancellationToken);
- public override async Task<TrCallRecord?> 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;
- }
- /// <summary>
- /// 根据转写ID获取通话信息
- /// </summary>
- /// <returns></returns>
- public override async Task<TrCallRecord?> 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;
- }
- /// <summary>
- /// 修改转写状态
- /// </summary>
- /// <returns></returns>
- 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);
- }
- /// <summary>
- /// 关联通话记录与order(添润)
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// 处理工单和通话记录关联问题
- /// </summary>
- /// <param name="orderId"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public override async Task<string> 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";
- }
- /// <summary>
- /// 查询通话记录
- /// </summary>
- public override async Task<List<TrCallRecord>> 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);
- }
- /// <summary>
- /// 查询分机操作选项
- /// </summary>
- /// <returns></returns>
- public override List<Kv> GetTelOperationOptions()
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// 查询通话记录
- /// </summary>
- public override async Task<CallNative?> GetCallAsync(string callId, CancellationToken cancellationToken)
- {
- var call = await _trCallRecordRepository.Queryable()
- .FirstAsync(d => d.OtherAccept == callId, cancellationToken);
- return _mapper.Map<CallNative?>(call);
- }
- /// <summary>
- /// 查询通话记录列表
- /// </summary>
- /// <param name="callId"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public override async Task<List<CallNative>> GetCallListAsync(string callId, CancellationToken cancellationToken)
- {
- var call = await _trCallRecordRepository.Queryable()
- .Where(d => d.OtherAccept == callId).ToListAsync(cancellationToken);
- return _mapper.Map<List<CallNative>>(call);
- }
- /// <summary>
- /// 根据 OrderId 返回用户电话评价枚举
- /// 默认返回 默认满意
- /// </summary>
- /// <param name="orderId"></param>
- /// <returns></returns>
- public override async Task<EVoiceEvaluate> GetReplyVoiceOrDefaultByOrderIdAsync(string orderId)
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// 根据 OrderId 返回用户电话评价枚举
- /// 默认返回 默认满意
- /// </summary>
- /// <param name="orderId"></param>
- /// <returns></returns>
- public override async Task<ESeatEvaluate> 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;
- }
- }
- }
|