fix: 修复 SAP 人员同步一致性
This commit is contained in:
@@ -116,7 +116,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
var gainfoSap = await _dbContext.Queryable<GainfoSapEntity>()
|
||||
.Where(x => x.ename == userCode)
|
||||
.Where(x => x.isowner == "F")
|
||||
.OrderByDescending(x => x.logdate)
|
||||
.OrderByDescending(x => new { x.logdate, x.id })
|
||||
.FirstAsync();
|
||||
await UpdatePersonAsync(gainfoSap);
|
||||
}
|
||||
@@ -138,7 +138,6 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
{
|
||||
_logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length);
|
||||
var chunkThirdPartPersons = thirdPartPersons.Where(x => searchCodes.Contains(x.ZWORKCODE)).ToList();
|
||||
var currentPersons = GetCurrentPersons(chunkThirdPartPersons);
|
||||
|
||||
var histories = await _dbContext.Queryable<GainfoSapEntity>()
|
||||
.Where(x => searchCodes.Contains(x.ename))
|
||||
@@ -146,6 +145,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
|
||||
var latestHistoryPersons = histories
|
||||
.OrderByDescending(x => x.logdate)
|
||||
.ThenByDescending(x => x.id)
|
||||
.GroupBy(x => x.ename)
|
||||
.ToDictionary(x => x.Key, x => ToSapPersonItem(x.First()));
|
||||
|
||||
@@ -153,74 +153,62 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
{
|
||||
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);
|
||||
await InsertGainfoSapHistoryAsync(item);
|
||||
latestHistoryPersons[person.ZWORKCODE] = ToSapPersonItem(item);
|
||||
if (!latestHistoryPersons.TryGetValue(person.ZWORKCODE, out var latestHistory)
|
||||
|| !comparer.Equals(person, latestHistory))
|
||||
{
|
||||
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)
|
||||
{
|
||||
_logger.LogError(ex, "执行历史同步失败:{message}", 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);
|
||||
_logger.LogError(ex, "执行人员同步失败,工号:{workCode},错误:{message}", person.ZWORKCODE, 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);
|
||||
//只有身份证号存在才进行新增
|
||||
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);
|
||||
}
|
||||
else
|
||||
await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory);
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -264,9 +252,13 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
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
|
||||
{
|
||||
//获取当前在职人员
|
||||
@@ -334,46 +326,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
//只有厂区变更才需要处理工作网格
|
||||
if (hasFactoryChange)
|
||||
{
|
||||
var workGridUser = await _dbContext.Queryable<WorkGridUserEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
|
||||
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);
|
||||
}
|
||||
}
|
||||
await HandleWorkGridChangeAsync(gainfo, DateOnly.FromDateTime(DateTime.Now));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,47 +351,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
.Where(x => x.AssignType == AssignTypeEnumType.User && x.AssignValue == gainfo.No)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var workGridUser = await _dbContext.Queryable<WorkGridUserEntity>()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
await HandleWorkGridChangeAsync(gainfo, DateOnly.FromDateTime(gainfo.ResignationDate!.Value));
|
||||
|
||||
gainfo.Id = gainfo.IdentityUserId;
|
||||
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)
|
||||
{
|
||||
await _dbContext.Client.Ado.RollbackTranAsync();
|
||||
if (useTransaction)
|
||||
{
|
||||
await _dbContext.Client.Ado.RollbackTranAsync();
|
||||
}
|
||||
|
||||
_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)
|
||||
.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>();
|
||||
foreach (var person in sapList)
|
||||
{
|
||||
if (!existingCodes.Contains(person.ZWORKCODE))
|
||||
if (string.IsNullOrWhiteSpace(person.ZWORKCODE))
|
||||
{
|
||||
modifiedPersons.Add(person);
|
||||
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);
|
||||
continue;
|
||||
@@ -535,17 +521,6 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
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)
|
||||
{
|
||||
var gainfos = new List<GainfoSapEntity>();
|
||||
@@ -557,6 +532,7 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
.ToListAsync();
|
||||
var latestItems = items
|
||||
.OrderByDescending(x => x.logdate)
|
||||
.ThenByDescending(x => x.id)
|
||||
.GroupBy(x => x.ename)
|
||||
.Select(x => x.First())
|
||||
.ToList();
|
||||
@@ -708,4 +684,4 @@ public class GainfoUpdateService : IGainfoUpdateService
|
||||
private static string FormatDate(DateTime? value) => value?.ToString("yyyy-MM-dd HH:mm:ss") ?? string.Empty;
|
||||
|
||||
private static string FormatDate(DateTime value) => value.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user