462 lines
21 KiB
C#
462 lines
21 KiB
C#
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<ZxdDbContext> _zxdRepository;
|
||
private readonly IBaseRepository<DncmsDbContext> _dncmsRepository;
|
||
private readonly IRedisManager _redisManager;
|
||
|
||
public EarlyWarningDomain(IConfiguration configuration,
|
||
IHttpClient httpClient,
|
||
ICacheDomain cacheDomain,
|
||
IBaseRepository<ZxdDbContext> zxdRepository,
|
||
IBaseRepository<DncmsDbContext> dncmsRepository,
|
||
IRedisManager redisManager)
|
||
{
|
||
_systemConfig = configuration.GetSection("SystemConfig").Get<SystemConfig>();
|
||
_configuration = configuration;
|
||
_httpClient = httpClient;
|
||
_cacheDomain = cacheDomain;
|
||
_zxdRepository = zxdRepository;
|
||
_dncmsRepository = dncmsRepository;
|
||
_redisManager = redisManager;
|
||
}
|
||
|
||
public async Task<PageResult<EarlyWarningLogDto>> 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<string>(sgin);
|
||
if (string.IsNullOrEmpty(deptidValue) || !int.TryParse(deptidValue, out int deptid))
|
||
{
|
||
throw new ApiException("签名已过期!");
|
||
}
|
||
var query = _zxdRepository.GetRepository<EarlyWarningLog>().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<EarlyWarningLogDto>(dto.PageIndex, dto.PageSize, total, data);
|
||
}
|
||
|
||
public async Task<EarlyWarningDetailDto> GetEarlyWarningDetail(int id)
|
||
{
|
||
var detail = await _zxdRepository.GetRepository<EarlyWarningLog>().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<EarlyWarningLog>().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<EarlyWarningLog>().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<EarlyWarningSetting>().Query()
|
||
.Include(x => x.EarlyWarningTemplate)
|
||
.ToListAsync();
|
||
var users = await _zxdRepository.GetRepository<EarlyWarningUser>().Query()
|
||
.ToListAsync();
|
||
var settingEids = settings.Select(x => x.Eid).Distinct().ToList();
|
||
//var totals = await _dncmsRepository.GetRepository<WeworkExternalUserTotal>().Query()
|
||
// .Where(x => settingEids.Contains(x.Eid))
|
||
// .ToListAsync();
|
||
var result = false;
|
||
var logs = new List<EarlyWarningLog>();
|
||
//var wwHhuserEids = new List<WwHhuserEidDto>();
|
||
//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<ApiResult<List<WwHhuserEidDto>>>(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<WwUserExtuserDto>(sql);
|
||
|
||
foreach (var setting in settings)
|
||
{
|
||
var messages = new List<MessageInfo>();
|
||
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<WeworkExternalUserTotal>().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<WeworkExternalUserTotal>().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<EarlyWarningLog>().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<EarlyWarningLog>().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<EarlyWarningLog>().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<EarlyWarningSetting>().UpdateAsync(setting);
|
||
}
|
||
}
|
||
if (logs.Any())
|
||
{
|
||
await _zxdRepository.GetRepository<EarlyWarningLog>().BatchInsertAsync(logs);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取去重加微数
|
||
/// </summary>
|
||
/// <param name="extuserList"></param>
|
||
/// <param name="wwHhuserEids"></param>
|
||
/// <param name="stime"></param>
|
||
/// <param name="etime"></param>
|
||
/// <param name="eid"></param>
|
||
/// <returns></returns>
|
||
private int GetTotalByEid(List<WwUserExtuserDto> extuserList, List<WwHhuserEidDto> wwHhuserEids, DateTime stime, DateTime etime, int eid)
|
||
{
|
||
var trueExtuser = new List<WwUserExtuserDto>();
|
||
|
||
//去重
|
||
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<string> 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}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 推送企微消息
|
||
/// </summary>
|
||
/// <param name="wxworkid"></param>
|
||
/// <param name="corpid"></param>
|
||
/// <param name="appid"></param>
|
||
/// <param name="message"></param>
|
||
/// <returns></returns>
|
||
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<WxworkResponse<object?>>(_systemConfig.WeworkSendUrl, param, data, clientid, _systemConfig.GetAccessKey(clientid));
|
||
if (response.ErrCode != 0)
|
||
{
|
||
Log.Error($"请求企微推送消息接口报错:{response.RrrMessage}, ex:{JsonSerializer.Serialize(response)}");
|
||
}
|
||
|
||
}
|
||
|
||
public async Task<List<ExternalUserTotalDto>> 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<WeworkExternalUserTotal>().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; }
|
||
}
|
||
}
|
||
}
|