using DotNetCore.CAP; using Hotline.Caching.Interfaces; using Hotline.Share.Dtos; using Hotline.Share.Dtos.Order; using Hotline.Share.Dtos.Push; using Hotline.Share.Enums.Order; using Hotline.Share.Tools; using Mapster; using Microsoft.Extensions.Logging; using XF.Domain.Dependency; using XF.Domain.Exceptions; using XF.Domain.Repository; using Hotline.EventBus; using Hotline.Orders.Notifications; using Hotline.Configurations; using Microsoft.Extensions.Options; using Hotline.Settings; using System.Text.RegularExpressions; namespace Hotline.Orders; public class OrderVisitDomainService : IOrderVisitDomainService, IScopeDependency { private readonly IRepository _orderVisitDetailRepository; private readonly ILogger _logger; private readonly IRepository _orderRepository; private readonly ISystemDicDataCacheManager _systemDicDataCacheManager; private readonly IOrderVisitRepository _orderVisitRepository; private readonly ICapPublisher _capPublisher; private readonly Publisher _publisher; private readonly IOptionsSnapshot _appOptions; private readonly ISettingOrderVisitSmsReplyRuleRepository _settingOrderVisitSmsReplyRuleRepository; public OrderVisitDomainService(IRepository orderVisitDetailRepository, ILogger logger, IRepository orderRepository, ISystemDicDataCacheManager systemDicDataCacheManager, IOrderVisitRepository orderVisitRepository, ICapPublisher capPublisher, Publisher publisher, IOptionsSnapshot appOptions, ISettingOrderVisitSmsReplyRuleRepository settingOrderVisitSmsReplyRuleRepository) { _orderVisitDetailRepository = orderVisitDetailRepository; _logger = logger; _orderRepository = orderRepository; _systemDicDataCacheManager = systemDicDataCacheManager; _orderVisitRepository = orderVisitRepository; _capPublisher = capPublisher; _publisher = publisher; _appOptions = appOptions; _settingOrderVisitSmsReplyRuleRepository = settingOrderVisitSmsReplyRuleRepository; } /// /// 用户回访短信回复更新回访状态 /// /// /// /// public async Task UpdateSmsReplyAsync(MessageDto data) { if (data.IsSmsReply == false || data.SmsReplyContent.IsNullOrEmpty()) return; var orderVisits = await _orderVisitRepository.Queryable() .Includes(m => m.Order) .Where(m => m.Order.Contact == data.TelNumber) .Where(m => m.VisitState == EVisitState.SMSVisiting) .ToListAsync(); foreach (var orderVisit in orderVisits) { await UpdateSmsReplyAsync(orderVisit, data.SmsReplyContent!.Trim()); } } /// /// 根据用户短信或电话回复的内容转换成系统中对应的评价 /// /// /// /// /// public SettingOrderVisitSmsReplyRule GetVisitEvaluateByReplyTxt(string replyTxt) { var replyToEnumMap = _settingOrderVisitSmsReplyRuleRepository.GetByAppScope(_appOptions.Value.AppScope); if (replyToEnumMap.IsNullOrEmpty()) throw new UserFriendlyException("系统未配置短信回访规则"); replyTxt = replyTxt.Trim(); return replyToEnumMap.FirstOrDefault(m => new Regex(m.ReplyRegular).IsMatch(replyTxt)) ?? throw new UserFriendlyException($"用户回复内容异常; replyTxt: {replyTxt}"); } /// /// 超过48小时未回复短信,修改短信回访记录为默认满意 /// /// /// public async Task UpdateSmsReplyDefaultAsync(MessageDto dto) { await _orderVisitRepository.Queryable() .Includes(m => m.Order) .Where(m => m.Id == dto.ExternalId) .Where(m => m.VisitState == EVisitState.SMSVisiting) .FirstAsync() .Then(async orderVisit => { // 默认满意 await UpdateSmsReplyAsync(orderVisit, "0"); }); } /// /// 超过48小时未回复短信,修改短信回访记录为默认满意 /// 用户回访短信回复更新回访状态 /// /// /// /// private async Task UpdateSmsReplyAsync(OrderVisit orderVisit, string replyTxt) { orderVisit.Order ??= await _orderRepository.GetAsync(orderVisit.OrderId); orderVisit.VisitType = EVisitType.SmsVisit; if (new string[] { "4", "5", "不满意", "非常不满意" }.Contains(replyTxt)) { // “短信不满意待回访”状态下,由其他方式再次进行回访,回访方式需更新为最新的回访方式 // 故在此置为空 orderVisit.VisitType = null; } var smsReplyRule = GetVisitEvaluateByReplyTxt(replyTxt); var visitSatisfactionKv = smsReplyRule.GetOrgProcessingResults(_systemDicDataCacheManager.VisitSatisfaction); if (smsReplyRule.OrgProcessingResults != null) orderVisit.NowEvaluate = visitSatisfactionKv; orderVisit.VisitTime = DateTime.Now; if (smsReplyRule.VisitState != null) orderVisit.VisitState = smsReplyRule.VisitState.Value; await _orderVisitRepository.UpdateAsync(orderVisit, ignoreNullColumns: false); if (orderVisit.VisitState == EVisitState.Visited) { await _orderRepository.GetAsync(orderVisit.OrderId) .Then(async order => { order!.Visited(visitSatisfactionKv.Key, visitSatisfactionKv.Value); await _orderRepository.UpdateAsync(order); }); } var detailOrg = await _orderVisitDetailRepository.Queryable() .Where(m => m.VisitId == orderVisit.Id && m.VisitTarget == EVisitTarget.Org) .ToListAsync(); foreach (var item in detailOrg) { item.ReplyBackfill(visitSatisfactionKv); if (_appOptions.Value.IsZiGong) item.OrgHandledAttitude = visitSatisfactionKv; } await _orderVisitDetailRepository.UpdateRangeAsync(detailOrg); await _orderVisitDetailRepository.Queryable() .Where(m => m.VisitId == orderVisit.Id && m.VisitTarget == EVisitTarget.Seat) .FirstAsync() .Then(async detailSeat => { if (smsReplyRule.SeatEvaluate != null) { detailSeat.ReplyBackfill(smsReplyRule.SeatEvaluate.Value); await _orderVisitDetailRepository.UpdateAsync(detailSeat); } }); if (orderVisit.VisitState != EVisitState.Visited) return; orderVisit.Order.Visited(visitSatisfactionKv.Key, visitSatisfactionKv.Value); await _orderRepository.UpdateAsync(orderVisit.Order); var orderDto = orderVisit.Order.Adapt(); var first = detailOrg.First(); if (visitSatisfactionKv.Key != null && visitSatisfactionKv.Value != null) { //推省上 await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited, new PublishVisitDto() { Order = orderDto, No = orderVisit.No, VisitType = orderVisit.VisitType, VisitName = orderVisit.CreatorName, VisitTime = orderVisit.VisitTime, VisitRemark = string.IsNullOrEmpty(first.VisitContent) ? first.OrgProcessingResults?.Value : first.VisitContent, AreaCode = orderVisit.Order.AreaCode!, SubjectResultSatifyCode = first.OrgProcessingResults.Key, FirstSatisfactionCode = orderVisit.Order.FirstVisitResultCode!, ClientGuid = "" }, cancellationToken: CancellationToken.None); } } }