using System.Linq; using System.Net.Http; using System.Security.Cryptography; using Crm.Core.Domain.Dto.CRM; using Crm.Core.Domain.Dto.Zxd; using Crm.Core.Domain.Impl; using Crm.Core.Entity.Crm; using DG.Core; using static Crm.Core.Domain.Config.SystemEnums; using static DG.Oracle.EntityFramework.Enums; namespace Crm.Core.Domain { public class NotificationDomain : INotificationDomain { private readonly IMapper _mapper; private readonly IRedisManager _redisManager; private readonly IOracleRepository _repository; private readonly IHttpClient _httpClient; private readonly IConfiguration _configuration; private readonly ICacheDomain _cacheDomain; private readonly SystemConfig _systemConfig; private readonly WeworkConfig _weworkConfig; private readonly IServiceProvider _serviceProvider; private readonly NotificationHub _notificationHub; public NotificationDomain(IOracleRepository repository, IRedisManager redisManager, IMapper mapper, IHttpClient httpClient, IConfiguration configuration, ICacheDomain cacheDomain, IServiceProvider serviceProvider, NotificationHub notificationHub) { _repository = repository; _redisManager = redisManager; _mapper = mapper; _httpClient = httpClient; _configuration = configuration; _cacheDomain = cacheDomain; _systemConfig = _configuration.GetSection("SystemConfig").Get(); _weworkConfig = _configuration.GetSection("WeworkConfig").Get(); _serviceProvider = serviceProvider; _notificationHub = notificationHub; } public async Task InsetNotification(OrderUserProtectionDto orderUserProtectionDto, string message) { try { var deptments = await _cacheDomain.GetDeptments(); if (deptments == null || !deptments.Any()) { Log.Error($"无法获取事业部列表!"); return new BAS_NOTIFICATION(); } decimal? repeatDeptid = orderUserProtectionDto.repeat_deptid; if (!repeatDeptid.HasValue || !deptments.Any(x => x.Id == repeatDeptid) || !await _cacheDomain.SetApp(_repository, repeatDeptid.Value)) { Log.Error($"【{orderUserProtectionDto.repeat_deptid}】 非法的deptmentId,无法切换app!"); return new BAS_NOTIFICATION(); } var id = await _repository.GetSeqAsync(PKIDType.LargeTable); decimal eid = orderUserProtectionDto.repeat_eid ?? 0; using (var transaction = await _repository.BeginTransactionAsync()) { try { var notification = new BAS_NOTIFICATION() { ID = id, MESSAGE = message, EID = eid, RESID = orderUserProtectionDto.resid, UMID = orderUserProtectionDto.umid, NOTIFICATIONID = orderUserProtectionDto.id, CTIME = DateTime.Now, READ = 0, NOTIFICATIONTYPE = NotificationType.ReceiveMessage }; await _repository.GetRepository().InsertAsync(notification); // 推送企微消息 var corp = await _repository.GetRepository().Query().FirstOrDefaultAsync(x => x.CORPID == orderUserProtectionDto.repeat_appid); var click = $"点击查看"; await WeworkSend(orderUserProtectionDto.repeat_appid, orderUserProtectionDto.repeat_appuserid, eid, message + click); await transaction.CommitAsync(); return notification; } catch (Exception ex) { await transaction.RollbackAsync(); transaction.Dispose(); Log.Error(ex, "插入消息报错!"); } } return new BAS_NOTIFICATION(); } catch (Exception ex) { Log.Error(ex, $"处理消息报错,data: {JsonSerializer.Serialize(orderUserProtectionDto)}!"); return new BAS_NOTIFICATION(); } } public async Task InsetNotification(SendMessageDto dto) { try { var deptments = await _cacheDomain.GetDeptments(); if (deptments == null || !deptments.Any()) { Log.Error($"无法获取事业部列表!"); return new BAS_NOTIFICATION(); } if (!deptments.Any(x => x.Id == dto.Deptid) || !await _cacheDomain.SetApp(_repository, dto.Deptid ?? 0)) { Log.Error($"【{dto.Deptid}】 非法的deptmentId,无法切换app!"); return new BAS_NOTIFICATION(); } var id = await _repository.GetSeqAsync(PKIDType.LargeTable); var eid = dto.Eid; using (var transaction = await _repository.BeginTransactionAsync()) { try { var notification = new BAS_NOTIFICATION() { ID = id, MESSAGE = dto.Message, EID = eid, RESID = dto.Resid, UMID = dto.Umid, NOTIFICATIONID = Guid.NewGuid().ToString(), CTIME = DateTime.Now, READ = 0, NOTIFICATIONTYPE = dto.Method == NotificationType.HgRefundMessage.ToString() ? NotificationType.HgRefundMessage : dto.Method == NotificationType.ComplaintMessage.ToString() ? NotificationType.ComplaintMessage : string.IsNullOrEmpty(dto.Umid) ? NotificationType.MsgToolMessage : NotificationType.ReceiveMessage }; await _repository.GetRepository().InsertAsync(notification); await transaction.CommitAsync(); return notification; } catch (Exception ex) { await transaction.RollbackAsync(); transaction.Dispose(); Log.Error(ex, "插入消息报错!"); } } return new BAS_NOTIFICATION(); } catch (Exception ex) { Log.Error(ex, $"处理消息报错,data: {JsonSerializer.Serialize(dto)}!"); return new BAS_NOTIFICATION(); } } public async Task InsetNotificationStatistics(OrderUserProtectionDto orderUserProtectionDto) { var deptments = await _cacheDomain.GetDeptments(); if (deptments == null || !deptments.Any()) { Log.Error($"无法获取事业部列表!"); return; } if (!deptments.Any(x => x.Id == orderUserProtectionDto.deptid) || !await _cacheDomain.SetApp(_repository, orderUserProtectionDto.deptid)) { Log.Error($"【{orderUserProtectionDto.deptid}】 非法的deptmentId,无法切换app!"); return; } var statistics = new BAS_NOTIFICATION_STATISTICS() { ID = orderUserProtectionDto.id, DEPTID = orderUserProtectionDto.deptid, CHANNEL = orderUserProtectionDto.channel, DEPTNAME = orderUserProtectionDto.deptname, CROSSDEPT = orderUserProtectionDto.deptid == orderUserProtectionDto.repeat_deptid ? 0 : 1, EID = orderUserProtectionDto.eid ?? 0, ENDTIME = orderUserProtectionDto.end_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.end_time.Value.ToString()), ENAME = orderUserProtectionDto.ename, CTIME = DateTime.Now, REPEATDAYS = orderUserProtectionDto.repeat_days, REPEATSTARTTIME = orderUserProtectionDto.repeat_start_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.repeat_start_time.Value.ToString()), REPEATDEPTID = orderUserProtectionDto.repeat_deptid, REPEATDEPTNAME = orderUserProtectionDto.repeat_deptname, REPEATEID = orderUserProtectionDto.repeat_eid, REPEATENDTIME = orderUserProtectionDto.repeat_end_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.repeat_end_time.Value.ToString()), RESID = orderUserProtectionDto.resid, NAME = orderUserProtectionDto.name, REPEATENAME = orderUserProtectionDto.repeat_ename, REPEATTYPE = orderUserProtectionDto.repeat_type }; await _repository.GetRepository().InsertAsync(statistics); // 切换数据库 decimal? repeatDeptid = orderUserProtectionDto.repeat_deptid; if (!repeatDeptid.HasValue || !deptments.Any(x => x.Id == repeatDeptid) || !await _cacheDomain.SetApp(_repository, repeatDeptid.Value)) { Log.Error($"【{orderUserProtectionDto.repeat_deptid}】 非法的repeat_deptid,无法切换app!"); return; } statistics = new BAS_NOTIFICATION_STATISTICS() { ID = orderUserProtectionDto.id, DEPTID = orderUserProtectionDto.deptid, CHANNEL = orderUserProtectionDto.channel, DEPTNAME = orderUserProtectionDto.deptname, CROSSDEPT = orderUserProtectionDto.deptid == orderUserProtectionDto.repeat_deptid ? 0 : 1, EID = orderUserProtectionDto.eid ?? 0, ENDTIME = orderUserProtectionDto.end_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.end_time.Value.ToString()), ENAME = orderUserProtectionDto.ename, CTIME = DateTime.Now, REPEATDAYS = orderUserProtectionDto.repeat_days, REPEATSTARTTIME = orderUserProtectionDto.repeat_start_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.repeat_start_time.Value.ToString()), REPEATDEPTID = orderUserProtectionDto.repeat_deptid, REPEATDEPTNAME = orderUserProtectionDto.repeat_deptname, REPEATEID = orderUserProtectionDto.repeat_eid, REPEATENDTIME = orderUserProtectionDto.repeat_end_time == null ? default(DateTime?) : Utility.ConvertStringToDateTime(orderUserProtectionDto.repeat_end_time.Value.ToString()), RESID = orderUserProtectionDto.resid, NAME = orderUserProtectionDto.name, REPEATENAME = orderUserProtectionDto.repeat_ename, REPEATTYPE = orderUserProtectionDto.repeat_type }; await _repository.GetRepository().InsertAsync(statistics); } /// /// 推送企微消息 /// /// /// /// /// /// public async Task WeworkSend(string? appid, string? appuserid, decimal eid, string message) { if (string.IsNullOrEmpty(appid) && string.IsNullOrEmpty(appuserid)) return; // 六合投研服务中心或懂牛投研服务中心不发信息 var deptidList = new int[] { 40, 41 }; var url = _systemConfig.GetDeptNameByEid(eid.ToString()); var result = await _httpClient.GetAsync>>(url); if (result.Code == 0) { var deptids = result.Data.Where(x => x.DeptId.HasValue).Select(x => x.DeptId.Value).ToList(); if (deptidList.Intersect(deptids).Any()) { Log.Information($"{eid} 六合投研服务中心或懂牛投研服务中心不发信息"); return; } } var list = await _repository.GetRepository() .QueryIncluding(x => x.WW_CORP_APP) .Where(x => x.EID == eid) .ToListAsync(); var clientid = "UPWEBSITE"; var param = new { Account = "dn.uc", Password = "dn.uc.password", Time = SignHelper.GetTimeStamp() }; foreach (var item in list) { if (item.WW_CORP_APP == null) continue; if (item.WW_CORP_APP.CORPID != appid || item.USERID != appuserid) continue; //if (!_weworkConfig.IsWhite(item.USERID, item.WW_CORP_APP.CORPID)) continue; var content = JsonSerializer.Serialize(new { msgtype = "text", text = new { content = message }, agentid = item.WW_CORP_APP.APPID.ToString(), toparty = "", totag = "", touser = item.USERID, safe = 0 }); var data = new { appid = item.WW_CORP_APP.CORPID, agentid = item.WW_CORP_APP.APPID, data = content }; var response = await _httpClient.PostSecurityAsync>(_systemConfig.WeworkSendUrl, param, data, clientid, _systemConfig.GetAccessKey(clientid)); if (response.ErrCode != 0) { Log.Error($"请求企微推送消息接口报错:{response.RrrMessage}, ex:{JsonSerializer.Serialize(response)}"); } } } public async Task> GetNotificationsByEid(decimal eid, string appid) { if (!await _cacheDomain.SetApp(_repository, appid)) { Log.Error($"【{appid}】 非法的Appid,无法切换app!"); return new List(); } var notifications = new List(); foreach (var type in Enum.GetValues()) { var notification = await _repository.GetRepository().Query() .Where(x => x.EID == eid) .Where(x => x.READ == 0) .Where(x => x.NOTIFICATIONTYPE == type) .OrderByDescending(x => x.CTIME) .FirstOrDefaultAsync(); if (notification != null) notifications.Add(notification); } return _mapper.Map(notifications); } private async Task GetNotificationByEid(decimal eid, string appid, NotificationType notificationType) { if (!await _cacheDomain.SetApp(_repository, appid)) { Log.Error($"【{appid}】 非法的Appid,无法切换app!"); return new BAS_NOTIFICATION(); } var data = await _repository.GetRepository().Query() .Where(x => x.EID == eid) .Where(x => x.READ == 0) .Where(x => x.NOTIFICATIONTYPE == notificationType) .OrderByDescending(x => x.CTIME) .FirstOrDefaultAsync(); if (data == null) { data = await _repository.GetRepository().Query() .Where(x => x.EID == eid) .Where(x => x.NOTIFICATIONTYPE == notificationType) .OrderByDescending(x => x.CTIME) .FirstOrDefaultAsync(); } return data; } public async Task> GetNotificationsPage(NotificationSearchPageDto search) { var excludeEids = await _cacheDomain.GetParameter>(ParameterEnums.CRM_CORE_NOTIFICATION_EXCLUDE); var query = _repository.GetRepository().Query() .Where(x => x.EID == search.Eid) .If(search.Read != null, x => x.Where(y => y.READ == search.Read)) .If(search.TimeFrom != null, x => x.Where(y => y.CTIME >= search.TimeFrom)) .If(search.TimeTo != null, x => x.Where(y => y.CTIME < search.TimeTo.Value.AddDays(1))) .If(excludeEids != null && excludeEids.Any(), x => x.Where(y => !excludeEids.Contains(y.EID.Value))) .If(search.NotificationType != null, x => x.Where(y => y.NOTIFICATIONTYPE == search.NotificationType)) .If(search.ComplaintType.HasValue, x => x.Where(y => y.MESSAGE.Contains(Enum.GetName(typeof(ComplaintType), search.ComplaintType)))) .If(search.ComplaintReason.HasValue, x => x.Where(y => y.MESSAGE.Contains(Enum.Parse(search.ComplaintReason.ToString()).GetDescription()))); var total = await query.CountAsync(); var data = await query .OrderBy(x => x.READ) .ThenByDescending(x => x.CTIME) .Skip((search.PageIndex - 1) * search.PageSize) .Take(search.PageSize) .ToListAsync(); var result = _mapper.Map(data); return new PageResult(search.PageIndex, search.PageSize, total, result); } public async Task Read(List messageIds) { var eid = await _cacheDomain.GetCurrentEid(); var notifications = await _repository.GetRepository().Query() .Where(x => messageIds.Contains(x.ID)) .ToListAsync(); var enabled = await _cacheDomain.GetValueParameter(ParameterEnums.CRM_CORE_NOTIFICATION_ENABLED); if (notifications != null && notifications.Any()) { try { using var transaction = await _repository.BeginTransactionAsync(); foreach (var notification in notifications) { notification.READ = 1; notification.READTIME = DateTime.Now; await _repository.GetRepository().UpdateAsync(notification); } await transaction.CommitAsync(); if (enabled == "1") { foreach (var type in Enum.GetValues()) { var notifi = await GetNotificationByEid(eid, _cacheDomain.GetApp(), type); var data = notifi == null ? notifications.FirstOrDefault() : notifi; await _notificationHub.Send(data); } } } catch (Exception ex) { Log.Error(ex, "更新已读报错!"); return false; } } return true; } public async Task RealAll() { var eid = await _cacheDomain.GetCurrentEid(); var notifications = await _repository.GetRepository().Query() .Where(x => x.EID == eid) .Where(x => x.READ == 0) .ToListAsync(); var enabled = await _cacheDomain.GetValueParameter(ParameterEnums.CRM_CORE_NOTIFICATION_ENABLED); if (notifications != null && notifications.Any()) { try { using var transaction = await _repository.BeginTransactionAsync(); foreach (var notification in notifications) { notification.READ = 1; notification.READTIME = DateTime.Now; await _repository.GetRepository().UpdateAsync(notification); } await transaction.CommitAsync(); if (enabled == "1") { foreach (var type in Enum.GetValues()) { var notifi = await GetNotificationByEid(eid, _cacheDomain.GetApp(), type); var data = notifi == null ? notifications.FirstOrDefault() : notifi; await _notificationHub.Send(data); } } } catch (Exception ex) { Log.Error(ex, "更新已读报错!"); return false; } } return true; } public async Task> GetNotificationStatisticsPage(NotificationStatisticsSearchPageDto dto) { var url = _systemConfig.GetCustomerProtectionsUrl(); var deptmentIds = await _cacheDomain.GetDeptmentIds(); var eid = await _cacheDomain.GetCurrentEid(); if (deptmentIds == null || !deptmentIds.Any()) { return new LivePageDto(); } // 处理筛选的事业部 if (dto.Txt_groupIds != null && dto.Txt_groupIds.HasValue) { var sales = await _cacheDomain.GetSalesDeptList(); if (!sales.Any(x => x.SalesGroupId == dto.Txt_groupIds)) { return new LivePageDto(); } dto.ShowGroupIds = string.Join(",", sales.First(x => x.SalesGroupId == dto.Txt_groupIds).GroupIds); } else if (dto.Txt_deptId != null && dto.Txt_deptId.HasValue) { var sales = await _cacheDomain.GetSalesDeptList(); if (!sales.Any(x => x.SalesGroupId == dto.Txt_deptId)) { return new LivePageDto(); } dto.ShowGroupIds = string.Join(",", sales.First(x => x.SalesGroupId == dto.Txt_deptId).GroupIds); } // 处理筛选员工ID if (dto.Eid != null && dto.UserId != null && (dto.Eid != dto.UserId || dto.RepeatEid != dto.UserId)) { return new LivePageDto(); } if (dto.Eid != null && dto.UserId == null) { var level = await _cacheDomain.LevelSSO(eid); switch (level) { case RoleLevel.Self: if (dto.Eid != eid) return new LivePageDto(); break; case RoleLevel.Dept: var eids = await _cacheDomain.GetSalesDeptsForEid(eid); if (!eids.Contains(dto.Eid.Value)) return new LivePageDto(); break; default: break; } } if (dto.RepeatEid != null && dto.UserId == null) { var level = await _cacheDomain.LevelSSO(eid); switch (level) { case RoleLevel.Self: if (dto.RepeatEid != eid) return new LivePageDto(); break; case RoleLevel.Dept: var eids = await _cacheDomain.GetSalesDeptsForEid(eid); if (!eids.Contains(dto.RepeatEid.Value)) return new LivePageDto(); break; default: break; } } dto.ShowEid = dto.UserId != null ? dto.UserId : null; var excludeEids = await _cacheDomain.GetParameter>(ParameterEnums.CRM_CORE_NOTIFICATION_EXCLUDE); if (excludeEids != null && excludeEids.Any()) { dto.ExcludeRepeatEids = string.Join(",", excludeEids); } dto.SortBy = "cross_dept desc, repeat_end_time desc"; dto.RepeatEndTime = !string.IsNullOrEmpty(dto.RepeatEndTime) ? DateTime.Parse(dto.RepeatEndTime).AddDays(1).ToString("yyyy-MM-dd") : dto.RepeatEndTime; dto.EndTime = !string.IsNullOrEmpty(dto.EndTime) ? DateTime.Parse(dto.EndTime).AddDays(1).ToString("yyyy-MM-dd") : dto.EndTime; dto.ShowDeptids = string.Join(",", deptmentIds); if (dto.DeptId != null && dto.RepeatDeptId != null) { dto.Deptids = dto.DeptId != null ? dto.DeptId.ToString() : ""; dto.RepeatDeptids = dto.RepeatDeptId != null ? dto.RepeatDeptId.ToString() : ""; } if (dto.DeptId != null && dto.RepeatDeptId != null && !deptmentIds.Contains(dto.DeptId.Value) && !deptmentIds.Contains(dto.RepeatDeptId.Value)) { return new LivePageDto(); } Log.Information($"{url} 查询事业部:{dto.Deptids}"); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true }; var dtoStr = JsonSerializer.Serialize(dto, options); var param = JsonSerializer.Deserialize>(dtoStr); try { var response = await _httpClient.GetAsync>>($"{url}", param); if (response.Code == 0) { foreach (var item in response.Data.TableData) { item.RepeatEndTime = item.RepeatDays > 1 ? DateTime.Parse(item.RepeatEndTime).ToString("yyyy-MM-dd") : "--"; item.RepeatStartTime = DateTime.Parse(item.RepeatStartTime).ToString("yyyy-MM-dd"); item.EndTime = DateTime.Parse(item.EndTime).ToString("yyyy-MM-dd"); item.RepeatTypeStr = item.RepeatType == 1 ? "企微联系" : item.RepeatType == 2 ? "电话联系" : "企微和电话联系"; } return response.Data; } } catch (Exception ex) { Log.Error(ex, $"{_systemConfig.GetCustomerProtectionsUrl()} 请求出错,param: {dtoStr}"); throw new ApiException("大数据接口请求报错!"); } return new LivePageDto(); } public async Task GetMessageCount(decimal? eid, NotificationType? notificationType = null, string? connectionId = "") { if (eid == null) return 0; var count = await _repository.GetRepository().Query() .Where(x => x.EID == eid) .Where(x => x.READ == 0) .If(notificationType != null, x => x.Where(x => x.NOTIFICATIONTYPE == notificationType)) .CountAsync(); if (count > 0 && !string.IsNullOrEmpty(connectionId)) { await _notificationHub.SendUserMessage(new OnlineUserInfoDto { Eid = eid.Value, Appid = _cacheDomain.GetApp(), ConnectionId = connectionId }); } return count; } public async Task SendMessage(SendMessageDto dto) { var deptments = await _cacheDomain.GetDeptments(); if (deptments == null || !deptments.Any()) { Log.Error($"无法获取事业部列表!"); throw new ApiException($"无法获取事业部列表!"); } if (dto.Channel != null && dto.Deptid == null) { foreach (var deptment in deptments) { foreach (var deptmentCampain in deptment.DeptmentCampains ?? new List()) { if (dto.Channel >= deptmentCampain.StartCampainId && dto.Channel <= deptmentCampain.EndCampainId) { dto.Deptid = deptment.Id; } } } } if (dto.Deptid == null || dto.Deptid == 0) { throw new ApiException($"无法匹配正确的事业部,请检查请求的渠道号或事业线id!"); } if (dto.IsDepartment) { var eids = await _cacheDomain.GetLeadEid(dto.Deptid ?? 0, dto.Eid); foreach (var eid in eids) { await _notificationHub.SendMessage(new SendMessageDto { Deptid = dto.Deptid, Channel = dto.Channel, Message = dto.Message, Eid = eid, Method = dto.Method, Resid = dto.Resid, Umid = dto.Umid, IsDepartment = dto.IsDepartment, }); } } else { await _notificationHub.SendMessage(dto); } } public async Task GetRepeatDeptments() { var result = new RepeatDeptmentDto(); var deptmentIds = await _cacheDomain.GetDeptmentIds(); if (deptmentIds == null || !deptmentIds.Any()) return result; var show_deptids = string.Join(",", deptmentIds); var url = _systemConfig.GetCustomerProtectionDepts(); var dealDpet = await _httpClient.GetAsync>>($"{url}?repeat=0&show_deptids={show_deptids}"); if (dealDpet.Code == 0 && dealDpet.Data != null) result.DealDepts = dealDpet.Data.Where(x => x.deptid > 0 && !string.IsNullOrWhiteSpace(x.deptname)).ToList(); var repeatDpet = await _httpClient.GetAsync>>($"{url}?repeat=1&show_deptids={show_deptids}"); if (repeatDpet.Code == 0 && dealDpet.Data != null) result.RepeatDepts = repeatDpet.Data.Where(x => x.deptid > 0 && !string.IsNullOrWhiteSpace(x.deptname)).ToList(); return result; } } }