fix: 修复 SAP 人员同步一致性
This commit is contained in:
@@ -116,7 +116,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
var gainfoSap = await _dbContext.Queryable<GainfoSapEntity>()
|
var gainfoSap = await _dbContext.Queryable<GainfoSapEntity>()
|
||||||
.Where(x => x.ename == userCode)
|
.Where(x => x.ename == userCode)
|
||||||
.Where(x => x.isowner == "F")
|
.Where(x => x.isowner == "F")
|
||||||
.OrderByDescending(x => x.logdate)
|
.OrderByDescending(x => new { x.logdate, x.id })
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
await UpdatePersonAsync(gainfoSap);
|
await UpdatePersonAsync(gainfoSap);
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,6 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
{
|
{
|
||||||
_logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length);
|
_logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length);
|
||||||
var chunkThirdPartPersons = thirdPartPersons.Where(x => searchCodes.Contains(x.ZWORKCODE)).ToList();
|
var chunkThirdPartPersons = thirdPartPersons.Where(x => searchCodes.Contains(x.ZWORKCODE)).ToList();
|
||||||
var currentPersons = GetCurrentPersons(chunkThirdPartPersons);
|
|
||||||
|
|
||||||
var histories = await _dbContext.Queryable<GainfoSapEntity>()
|
var histories = await _dbContext.Queryable<GainfoSapEntity>()
|
||||||
.Where(x => searchCodes.Contains(x.ename))
|
.Where(x => searchCodes.Contains(x.ename))
|
||||||
@@ -146,6 +145,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
|
|
||||||
var latestHistoryPersons = histories
|
var latestHistoryPersons = histories
|
||||||
.OrderByDescending(x => x.logdate)
|
.OrderByDescending(x => x.logdate)
|
||||||
|
.ThenByDescending(x => x.id)
|
||||||
.GroupBy(x => x.ename)
|
.GroupBy(x => x.ename)
|
||||||
.ToDictionary(x => x.Key, x => ToSapPersonItem(x.First()));
|
.ToDictionary(x => x.Key, x => ToSapPersonItem(x.First()));
|
||||||
|
|
||||||
@@ -153,74 +153,62 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (latestHistoryPersons.TryGetValue(person.ZWORKCODE, out var latestHistory) && comparer.Equals(person, latestHistory))
|
await _dbContext.UseTransactionAsync(async () =>
|
||||||
{
|
{
|
||||||
continue;
|
var item = ToGainfoSap(person);
|
||||||
}
|
|
||||||
|
|
||||||
var item = ToGainfoSap(person);
|
if (!latestHistoryPersons.TryGetValue(person.ZWORKCODE, out var latestHistory)
|
||||||
await InsertGainfoSapHistoryAsync(item);
|
|| !comparer.Equals(person, latestHistory))
|
||||||
latestHistoryPersons[person.ZWORKCODE] = ToSapPersonItem(item);
|
{
|
||||||
|
await _dbContext.InsertAsync(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
var no = await _dbContext.Queryable<GainfoEntity>()
|
||||||
|
.Where(x => x.Code == item.ename)
|
||||||
|
.Select(x => x.No)
|
||||||
|
.SingleAsync();
|
||||||
|
|
||||||
|
if (no.IsEmpty())
|
||||||
|
{
|
||||||
|
await InsertCurrentPersonCoreAsync(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await UpdatePersonAsync(item, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "执行历史同步失败:{message}", ex.Message);
|
_logger.LogError(ex, "执行人员同步失败,工号:{workCode},错误:{message}", person.ZWORKCODE, ex.Message);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var person in currentPersons)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var item = ToGainfoSap(person);
|
|
||||||
var no = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == item.ename).Select(x => x.No).SingleAsync();
|
|
||||||
if (no.IsEmpty())
|
|
||||||
{
|
|
||||||
await InsertCurrentPersonAsync(item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await UpdatePersonAsync(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "执行当前人员同步失败:{message}", ex.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InsertGainfoSapHistoryAsync(GainfoSapEntity item)
|
|
||||||
{
|
|
||||||
await _dbContext.InsertAsync(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task InsertCurrentPersonAsync(GainfoSapEntity item)
|
private async Task InsertCurrentPersonCoreAsync(GainfoSapEntity item)
|
||||||
{
|
{
|
||||||
var info = GainfoSapToGainfo(item);
|
var info = GainfoSapToGainfo(item);
|
||||||
//只有身份证号存在才进行新增
|
//只有身份证号存在才进行新增
|
||||||
if (info.IdNo.IsPresent())
|
if (info.IdNo.IsPresent())
|
||||||
{
|
{
|
||||||
await _dbContext.UseTransactionAsync(async () =>
|
if (item.isowner == "T")
|
||||||
{
|
{
|
||||||
if (item.isowner == "T")
|
if (!await _dbContext.Queryable<GainfoEntity>().AnyAsync(x => x.Code == item.ename))
|
||||||
{
|
{
|
||||||
if (!await _dbContext.Queryable<GainfoEntity>().AnyAsync(x => x.Code == item.ename))
|
await _dbContext.InsertAsync(info);
|
||||||
{
|
}
|
||||||
await _dbContext.InsertAsync(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory);
|
await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!await _dbContext.Queryable<GainfoLeaveEntity>().AnyAsync(x => x.Code == item.ename))
|
||||||
{
|
{
|
||||||
if (!await _dbContext.Queryable<GainfoLeaveEntity>().AnyAsync(x => x.Code == item.ename))
|
await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync();
|
||||||
{
|
|
||||||
await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -264,9 +252,13 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdatePersonAsync(GainfoSapEntity item)
|
public async Task UpdatePersonAsync(GainfoSapEntity item, bool useTransaction = true)
|
||||||
{
|
{
|
||||||
await _dbContext.Client.Ado.BeginTranAsync();
|
if (useTransaction)
|
||||||
|
{
|
||||||
|
await _dbContext.Client.Ado.BeginTranAsync();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//获取当前在职人员
|
//获取当前在职人员
|
||||||
@@ -334,46 +326,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
//只有厂区变更才需要处理工作网格
|
//只有厂区变更才需要处理工作网格
|
||||||
if (hasFactoryChange)
|
if (hasFactoryChange)
|
||||||
{
|
{
|
||||||
var workGridUser = await _dbContext.Queryable<WorkGridUserEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
|
await HandleWorkGridChangeAsync(gainfo, DateOnly.FromDateTime(DateTime.Now));
|
||||||
if (workGridUser != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var resignationDate = DateOnly.FromDateTime(DateTime.Now);
|
|
||||||
|
|
||||||
var workGridSchedules = await _dbContext.Queryable<WorkGridScheduleEntity>()
|
|
||||||
.Where(x => x.UserCode == gainfo.Code)
|
|
||||||
.Where(x => x.Date >= resignationDate)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (workGridSchedules.Any())
|
|
||||||
{
|
|
||||||
var dates = workGridSchedules.Select(x => $"{x.Date.ToString("yyyy年-MM月-dd日")}的{x.PeriodType.GetDescription()}").Join(",");
|
|
||||||
var workGrid = await _dbContext.Queryable<WorkGridEntity>()
|
|
||||||
.Where(x => x.Code == workGridUser.WorkGridCode)
|
|
||||||
.Select(x => new
|
|
||||||
{
|
|
||||||
x.LeaderUserCode,
|
|
||||||
x.Name
|
|
||||||
}).SingleAsync();
|
|
||||||
|
|
||||||
var content = $"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
|
|
||||||
|
|
||||||
await _dingTalkApi.SendWorkMessageByWorkGridAsync(new DingTalkWorkMessageRequest
|
|
||||||
{
|
|
||||||
Content = content,
|
|
||||||
WorkCodes = new List<string> { workGrid.LeaderUserCode }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await _dbContext.DeleteAsync(workGridUser);
|
|
||||||
await _dbContext.DeleteAsync(workGridSchedules);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError(e, "网格异动处理异常:{error}", e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,47 +351,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
.Where(x => x.AssignType == AssignTypeEnumType.User && x.AssignValue == gainfo.No)
|
.Where(x => x.AssignType == AssignTypeEnumType.User && x.AssignValue == gainfo.No)
|
||||||
.ExecuteCommandAsync();
|
.ExecuteCommandAsync();
|
||||||
|
|
||||||
var workGridUser = await _dbContext.Queryable<WorkGridUserEntity>()
|
await HandleWorkGridChangeAsync(gainfo, DateOnly.FromDateTime(gainfo.ResignationDate!.Value));
|
||||||
.Where(x => x.UserCode == gainfo.Code)
|
|
||||||
.SingleAsync();
|
|
||||||
if (workGridUser != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var resignationDate = DateOnly.FromDateTime(gainfo.ResignationDate!.Value);
|
|
||||||
|
|
||||||
var workGridSchedules = await _dbContext.Queryable<WorkGridScheduleEntity>()
|
|
||||||
.Where(x => x.UserCode == gainfo.Code)
|
|
||||||
.Where(x => x.Date >= resignationDate)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (workGridSchedules.Any())
|
|
||||||
{
|
|
||||||
var dates = workGridSchedules.Select(x => $"{x.Date.ToString("yyyy年-MM月-dd日")}的{x.PeriodType.GetDescription()}").Join(",");
|
|
||||||
var workGrid = await _dbContext.Queryable<WorkGridEntity>()
|
|
||||||
.Where(x => x.Code == workGridUser.WorkGridCode)
|
|
||||||
.Select(x => new
|
|
||||||
{
|
|
||||||
x.LeaderUserCode,
|
|
||||||
x.Name
|
|
||||||
}).SingleAsync();
|
|
||||||
var content = $"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
|
|
||||||
|
|
||||||
await _dingTalkApi.SendWorkMessageByWorkGridAsync(new DingTalkWorkMessageRequest
|
|
||||||
{
|
|
||||||
Content = content,
|
|
||||||
WorkCodes = new List<string> { workGrid.LeaderUserCode }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await _dbContext.DeleteAsync(workGridUser);
|
|
||||||
await _dbContext.DeleteAsync(workGridSchedules);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError(e, "网格异动处理异常:{error}", e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gainfo.Id = gainfo.IdentityUserId;
|
gainfo.Id = gainfo.IdentityUserId;
|
||||||
await _dbContext.DeleteReallyAsync(gainfo);
|
await _dbContext.DeleteReallyAsync(gainfo);
|
||||||
@@ -446,12 +359,80 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await _dbContext.Client.Ado.CommitTranAsync();
|
if (useTransaction)
|
||||||
|
{
|
||||||
|
await _dbContext.Client.Ado.CommitTranAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _dbContext.Client.Ado.RollbackTranAsync();
|
if (useTransaction)
|
||||||
|
{
|
||||||
|
await _dbContext.Client.Ado.RollbackTranAsync();
|
||||||
|
}
|
||||||
|
|
||||||
_logger.LogError(ex, "更新人员失败:{message}", ex.Message);
|
_logger.LogError(ex, "更新人员失败:{message}", ex.Message);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleWorkGridChangeAsync(GainfoEntity gainfo, DateOnly effectiveDate)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var workGridUser = await _dbContext.Queryable<WorkGridUserEntity>()
|
||||||
|
.Where(x => x.UserCode == gainfo.Code)
|
||||||
|
.SingleAsync();
|
||||||
|
if (workGridUser == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var workGridSchedules = await _dbContext.Queryable<WorkGridScheduleEntity>()
|
||||||
|
.Where(x => x.UserCode == gainfo.Code)
|
||||||
|
.Where(x => x.Date >= effectiveDate)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (workGridSchedules.Any())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var workGrid = await _dbContext.Queryable<WorkGridEntity>()
|
||||||
|
.Where(x => x.Code == workGridUser.WorkGridCode)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.LeaderUserCode,
|
||||||
|
x.Name
|
||||||
|
})
|
||||||
|
.SingleAsync();
|
||||||
|
|
||||||
|
if (workGrid != null)
|
||||||
|
{
|
||||||
|
var dates = workGridSchedules
|
||||||
|
.Select(x => $"{x.Date:yyyy年-MM月-dd日}的{x.PeriodType.GetDescription()}")
|
||||||
|
.Join(",");
|
||||||
|
var content =
|
||||||
|
$"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
|
||||||
|
|
||||||
|
await _dingTalkApi.SendWorkMessageByWorkGridAsync(new DingTalkWorkMessageRequest
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
WorkCodes = new List<string> { workGrid.LeaderUserCode }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "工作网格消息通知失败,工号:{workCode},错误:{error}", gainfo.Code, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _dbContext.DeleteAsync(workGridUser);
|
||||||
|
await _dbContext.DeleteAsync(workGridSchedules);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "网格异动处理异常,工号:{workCode},错误:{error}", gainfo.Code, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,18 +466,23 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
.GroupBy(x => x.ZWORKCODE)
|
.GroupBy(x => x.ZWORKCODE)
|
||||||
.ToDictionary(x => x.Key, x => x.First());
|
.ToDictionary(x => x.Key, x => x.First());
|
||||||
|
|
||||||
var existingCodes = await _dbContext.Queryable<GainfoEntity>().Where(x => workCodes.Contains(x.Code)).Select(x => x.Code).ToListAsync();
|
var existingCodes = await _dbContext.Queryable<GainfoEntity>()
|
||||||
|
.Where(x => workCodes.Contains(x.Code))
|
||||||
|
.Select(x => x.Code)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
var modifiedPersons = new List<SapPersonItem>();
|
var modifiedPersons = new List<SapPersonItem>();
|
||||||
foreach (var person in sapList)
|
foreach (var person in sapList)
|
||||||
{
|
{
|
||||||
if (!existingCodes.Contains(person.ZWORKCODE))
|
if (string.IsNullOrWhiteSpace(person.ZWORKCODE))
|
||||||
{
|
{
|
||||||
modifiedPersons.Add(person);
|
modifiedPersons.Add(person);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(person.ZWORKCODE))
|
var existsInGainfo = existingCodes.Contains(person.ZWORKCODE);
|
||||||
|
var isOwner = int.Parse(person.ZSTATUS) < 5;
|
||||||
|
if ((isOwner && !existsInGainfo) || (!isOwner && existsInGainfo))
|
||||||
{
|
{
|
||||||
modifiedPersons.Add(person);
|
modifiedPersons.Add(person);
|
||||||
continue;
|
continue;
|
||||||
@@ -535,17 +521,6 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
return modifiedPersons;
|
return modifiedPersons;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SapPersonItem> GetCurrentPersons(List<SapPersonItem> sapList)
|
|
||||||
{
|
|
||||||
return sapList
|
|
||||||
.OrderByDescending(x => x.ZSTATUS)
|
|
||||||
.ThenBy(x => x.ZRZRQ)
|
|
||||||
.GroupBy(x => x.ZWORKCODE)
|
|
||||||
.Select(x => x.First())
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task<List<SapPersonItem>> LoadDataAsync(List<string> workCodes)
|
private async Task<List<SapPersonItem>> LoadDataAsync(List<string> workCodes)
|
||||||
{
|
{
|
||||||
var gainfos = new List<GainfoSapEntity>();
|
var gainfos = new List<GainfoSapEntity>();
|
||||||
@@ -557,6 +532,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var latestItems = items
|
var latestItems = items
|
||||||
.OrderByDescending(x => x.logdate)
|
.OrderByDescending(x => x.logdate)
|
||||||
|
.ThenByDescending(x => x.id)
|
||||||
.GroupBy(x => x.ename)
|
.GroupBy(x => x.ename)
|
||||||
.Select(x => x.First())
|
.Select(x => x.First())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|||||||
Reference in New Issue
Block a user