using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using Zxd.Core.Domain.Dto.Crm; using Zxd.Core.Domain.Dto.Wework; using Zxd.Entity.Wework; using Zxd.Entity.Zxd; namespace Zxd.Core.Domain { internal class EarlyWarningDomain : IEarlyWarningDomain { private readonly IConfiguration _configuration; private readonly IHttpClient _httpClient; private readonly ICacheDomain _cacheDomain; private readonly SystemConfig _systemConfig; private readonly IBaseRepository _zxdRepository; private readonly IBaseRepository _dncmsRepository; private readonly IRedisManager _redisManager; public EarlyWarningDomain(IConfiguration configuration, IHttpClient httpClient, ICacheDomain cacheDomain, IBaseRepository zxdRepository, IBaseRepository dncmsRepository, IRedisManager redisManager) { _systemConfig = configuration.GetSection("SystemConfig").Get(); _configuration = configuration; _httpClient = httpClient; _cacheDomain = cacheDomain; _zxdRepository = zxdRepository; _dncmsRepository = dncmsRepository; _redisManager = redisManager; } public async Task> GetEarlyWarningLogPage(SearchEarlyWarningLogDto dto, string? sgin) { if (string.IsNullOrEmpty(sgin)) throw new ApiException("签名不能为空!"); if (!await _redisManager.ExistsAsync(sgin)) { throw new ApiException("签名已过期!"); } var deptidValue = await _redisManager.GetAsync(sgin); if (string.IsNullOrEmpty(deptidValue) || !int.TryParse(deptidValue, out int deptid)) { throw new ApiException("签名已过期!"); } var query = _zxdRepository.GetRepository().Query() .Where(x => x.Deptid == deptid) .If(dto.AttainTimeFrom != null, x => x.Where(x => x.CreateTime >= dto.AttainTimeFrom)) .If(dto.AttainTimeTo != null, x => x.Where(x => x.CreateTime < dto.AttainTimeTo.Value.AddDays(1))) .If(dto.Eid != null, x => x.Where(x => x.Eid == dto.Eid)) .If(!string.IsNullOrEmpty(dto.Name), x => x.Where(x => x.Name.Contains(dto.Name))) .If(dto.Status != null, x => x.Where(x => x.Status == dto.Status)); var total = await query.CountAsync(); var data = await query .OrderByDescending(x => x.CreateTime) .Select(x => new EarlyWarningLogDto { Id = x.Id, Distinct = x.Distinct, CreateTime = x.CreateTime, Eid = x.Eid, MaxCount = x.Type == EarlyWarningType.百分比 ? $"到达{x.EarlyWarning}%" : $"到达{x.EarlyWarning}人", MaxResource = x.Resource, Name = x.Name, PeriodFrom = x.PeriodFrom, PeriodTo = x.PeriodTo, Status = x.Status.GetDescription() }) .Skip((dto.PageIndex - 1) * dto.PageSize) .Take(dto.PageSize) .ToListAsync(); return new PageResult(dto.PageIndex, dto.PageSize, total, data); } public async Task GetEarlyWarningDetail(int id) { var detail = await _zxdRepository.GetRepository().Query() .Where(x => x.Id == id) .Select(x => new EarlyWarningDetailDto { Id = x.Id, Distinct = x.Distinct, CreateTime = x.CreateTime, Eid = x.Eid, MaxCount = x.Type == EarlyWarningType.百分比 ? $"到达{x.EarlyWarning}%" : $"到达{x.EarlyWarning}人", MaxResource = x.Resource, Name = x.Name, PeriodFrom = x.PeriodFrom, PeriodTo = x.PeriodTo, Status = x.Status.GetDescription() }) .FirstOrDefaultAsync(); return new EarlyWarningDetailDto(); } public async Task UpdateEarlyWarningStatus(UpdateEarlyWarningStatusDto dto) { var data = await _zxdRepository.GetRepository().Query() .Where(x => x.Id == dto.Id) .FirstOrDefaultAsync(); if (data == null) { throw new ApiException("数据不存在或已删除!"); } if (!dto.Status.HasValue) { throw new ApiException("请选择更变状态!"); } data.Status = dto.Status.Value; await _zxdRepository.GetRepository().UpdateAsync(data); } public async Task EarlyWarningSync() { var time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")); var stime = time; var etime = time.AddDays(1).AddSeconds(-1); var settings = await _zxdRepository.GetRepository().Query() .Include(x => x.EarlyWarningTemplate) .ToListAsync(); var users = await _zxdRepository.GetRepository().Query() .ToListAsync(); var settingEids = settings.Select(x => x.Eid).Distinct().ToList(); //var totals = await _dncmsRepository.GetRepository().Query() // .Where(x => settingEids.Contains(x.Eid)) // .ToListAsync(); var result = false; var logs = new List(); //var wwHhuserEids = new List(); //foreach (var deptid in settings.Select(x => x.Deptid).Distinct()) //{ // var deptSettings = settings.Where(x => x.Deptid == deptid).Select(x => x.Eid).ToList(); // var size = 30; // var maxIndex = (deptSettings.Count / size) + 1; // for (var page = 0; page < maxIndex; page++) // { // var url = $"{_systemConfig.CrmCoreUrl}api/Customer/WwHhuserEids?deptid={deptid}"; // var crmData = await _httpClient.PostAsync>>(url, deptSettings.Skip(page * size).Take(size).ToList()); // if (crmData.Code == 0) // { // wwHhuserEids.AddRange(crmData.Data); // } // } //} //var sql = $@"select * from ww_user_extuser where CONCAT(corpid,userid) // in ('{string.Join("','", wwHhuserEids.Select(m => m.CORPID + m.USERID))}')"; //var extuserList = await _weworkRepository.ExecuteSqlToListAsync(sql); foreach (var setting in settings) { var messages = new List(); var url = ""; var template = setting.EarlyWarningTemplate ?? new EarlyWarningTemplate(); if (template.Id < 1) { continue; } var max = template.Maxnum; // 判断是否接粉周期 if (time < template.PeriodFrom || time > template.PeriodTo.AddDays(1).AddSeconds(-1)) { continue; } int? total = 0; // 在东三等其他坐席,以加微数(部门去重)作为达量通知的标准。六合的坐席,以加微数(工号去重)作为达量通知的标准 if (new int[] { 27, 32, 33, 40 }.Contains(setting.Deptid)) { total = await _dncmsRepository.GetRepository().Query() .Where(x => x.Eid == setting.Eid && x.Ctime >= template.PeriodFrom && x.Ctime <= template.PeriodTo.AddDays(1).AddSeconds(-1)).SumAsync(x => x.Eidrepeattypenew); } else { total = await _dncmsRepository.GetRepository().Query() .Where(x => x.Eid == setting.Eid && x.Ctime >= template.PeriodFrom && x.Ctime <= template.PeriodTo.AddDays(1).AddSeconds(-1)).SumAsync(x => x.Eidrepeattype1deptnew); } //var total = GetTotalByEid(extuserList, wwHhuserEids, template.PeriodFrom, template.PeriodTo, setting.Eid); if (total == 0 || !total.HasValue) continue; var index = 0; if (total >= max) { var templateIndex = max.ToString(); if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == templateIndex)) { continue; } url = await GetCrmUrl(setting.Deptid, setting.Eid); messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量100%,点击查看添加详情:{url}" }); logs.Add(new EarlyWarningLog { Distinct = total.Value, CreateTime = DateTime.Now, EarlyWarning = 100, Eid = setting.Eid, Name = setting.Name, PeriodFrom = template.PeriodFrom, PeriodTo = template.PeriodTo, Resource = max, Status = EarlyWaningLogStatus.未处理, Type = EarlyWarningType.百分比, TemplateId = setting.TemplateId, TemplateIndex = templateIndex, Deptid = setting.Deptid, }); } var isPercent = false; foreach (var prewarning in template.PrewarningValueJson) { if (string.IsNullOrEmpty(prewarning.Guid)) continue; if (prewarning.Type == EarlyWarningType.百分比) { result = total >= max * ((decimal)prewarning.Value / 100); var percent = (decimal)total / max * 100; if (result) { if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == prewarning.Guid && x.Resource >= max)) { continue; } url = await GetCrmUrl(setting.Deptid, setting.Eid); messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量{percent:0.0}%,点击查看添加详情:{url}" }); logs.Add(new EarlyWarningLog { Distinct = total.Value, CreateTime = DateTime.Now, EarlyWarning = prewarning.Value, Eid = setting.Eid, Name = setting.Name, PeriodFrom = template.PeriodFrom, PeriodTo = template.PeriodTo, Resource = max, Status = EarlyWaningLogStatus.未处理, Type = EarlyWarningType.百分比, TemplateId = setting.TemplateId, TemplateIndex = prewarning.Guid, Deptid = setting.Deptid, }); isPercent = true; continue; } } else { result = total >= prewarning.Value; if (result) { if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == prewarning.Guid)) { continue; } url = await GetCrmUrl(setting.Deptid, setting.Eid); messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量{total}人,点击查看添加详情:{url}" }); logs.Add(new EarlyWarningLog { Distinct = total.Value, CreateTime = DateTime.Now, EarlyWarning = prewarning.Value, Eid = setting.Eid, Name = setting.Name, PeriodFrom = template.PeriodFrom, PeriodTo = template.PeriodTo, Resource = max, Status = EarlyWaningLogStatus.未处理, Type = EarlyWarningType.数量, TemplateId = setting.TemplateId, TemplateIndex = prewarning.Guid, Deptid = setting.Deptid, }); continue; } } index++; } foreach (var message in messages) { foreach (var user in users.Where(x => x.ParticipantIds.Contains(message.Eid))) { try { await WeworkSend(user.WxWorkId, user.CropId, user.AppId, message.Message); } catch { } } } if (setting.HasChangeNum == 1 && isPercent) { setting.HasChangeNum = 0; await _zxdRepository.GetRepository().UpdateAsync(setting); } } if (logs.Any()) { await _zxdRepository.GetRepository().BatchInsertAsync(logs); } } /// /// 获取去重加微数 /// /// /// /// /// /// /// private int GetTotalByEid(List extuserList, List wwHhuserEids, DateTime stime, DateTime etime, int eid) { var trueExtuser = new List(); //去重 var extuser_gup_dis = extuserList.GroupBy(m => m.Extuserid); foreach (var item in extuser_gup_dis) { var first = item.ToList().OrderBy(m => m.Ctime).First();//获取最早添加好友的记录 trueExtuser.Add(first); } //统计 时间范围内 去重后加微数 var extuserDis = trueExtuser .Where(m => m.Ctime >= stime && m.Ctime <= etime.AddDays(1).AddSeconds(-1))//时间筛选 .GroupBy(m => m.CORPID + m.USERID).Select(i => new WwUserExtuserIdDto() { CORPID = i.First().CORPID, USERID = i.First().USERID, Count = i.Count() }).ToList(); //匹配eid var gupDis = wwHhuserEids.Join(extuserDis, m => m.CORPID + m.USERID, n => n.CORPID + n.USERID, (m, n) => { return new { eid = m.EID, count = n.Count }; }).GroupBy(m => m.eid).ToDictionary(m => m.Key.ToString(), n => n.Sum(i => i.count)); if (!gupDis.TryGetValue(eid.ToString(), out int total)) { return 0; } return total; } private async Task GetCrmUrl(int deptid, int eid) { var app = _systemConfig.Apps.Where(x => x.Deptids.Contains(deptid)).FirstOrDefault(); var sgin = ResUtil.EncryptMD5($"{deptid}_{eid}"); await _redisManager.SetAsync(sgin, deptid.ToString(), TimeSpan.FromDays(7)); return $"{app?.CrmUrl}MessageCenter/EarlyWarning?sgin={sgin}&createTime={DateTime.Now:yyyy-MM-dd}&eid={eid}"; } /// /// 推送企微消息 /// /// /// /// /// /// public async Task WeworkSend(string? wxworkid, string? corpid, string? appid, string? message) { if(string.IsNullOrEmpty(wxworkid) || string.IsNullOrEmpty(corpid) || string.IsNullOrEmpty(appid) || string.IsNullOrEmpty(message)) { Log.Error($"推送企微消息参数不能为空!"); return; } var clientid = "UPWEBSITE"; var param = new { Account = "dn.uc", Password = "dn.uc.password", Time = SignHelper.GetTimeStamp() }; var content = JsonSerializer.Serialize(new { msgtype = "text", text = new { content = message }, agentid = appid, toparty = "", totag = "", touser = wxworkid, safe = 0 }); var data = new { appid = corpid, agentid = 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> GetExternalUserTotal(SearchExternalUserTotalDto dto) { if(string.IsNullOrEmpty(dto.DateFrom) || !DateTime.TryParse(dto.DateFrom, out DateTime dateFrom)) { throw new ApiException("请输入查询日期!"); } if (string.IsNullOrEmpty(dto.DateTo) || !DateTime.TryParse(dto.DateTo, out DateTime dateTo)) { throw new ApiException("请输入查询日期!"); } if (dto.Eids == null || !dto.Eids.Any()) { throw new ApiException("请输入员工工号!"); } var data = await _dncmsRepository.GetRepository().Query() .Where(x => dto.Eids.Contains(x.Eid) && x.Ctime >= dateFrom && x.Ctime <= dateTo.AddDays(1).AddSeconds(-1)) .GroupBy(x => new { x.Eid }) .Select(x => new ExternalUserTotalDto { Eid = x.Key.Eid, Eidrepeattype1deptnew = x.Sum(y => y.Eidrepeattype1deptnew), Newsubscribe = x.Sum(y => y.Newsubscribe), Total = x.Sum(y => y.Total), Eidrepeattypenew = x.Sum(y => y.Eidrepeattypenew) }).ToListAsync(); return data; } class MessageInfo { public int Eid { get; set; } public string? Message { get; set; } } } }