fix: 修复 SAP 人员同步一致性

This commit is contained in:
2026-07-27 15:19:53 +08:00
parent e0a2a9ea0d
commit 66e1ad5a19

View File

@@ -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,56 +153,45 @@ public class GainfoUpdateService : IGainfoUpdateService
{
try
{
if (latestHistoryPersons.TryGetValue(person.ZWORKCODE, out var latestHistory) && comparer.Equals(person, latestHistory))
{
continue;
}
var item = ToGainfoSap(person);
await InsertGainfoSapHistoryAsync(item);
latestHistoryPersons[person.ZWORKCODE] = ToSapPersonItem(item);
}
catch (Exception ex)
{
_logger.LogError(ex, "执行历史同步失败:{message}", ex.Message);
}
}
foreach (var person in currentPersons)
{
try
await _dbContext.UseTransactionAsync(async () =>
{
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)
if (!latestHistoryPersons.TryGetValue(person.ZWORKCODE, out var latestHistory)
|| !comparer.Equals(person, latestHistory))
{
await _dbContext.InsertAsync(item);
}
private async Task InsertCurrentPersonAsync(GainfoSapEntity 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, "执行人员同步失败,工号:{workCode},错误:{message}", person.ZWORKCODE, ex.Message);
}
}
}
}
private async Task InsertCurrentPersonCoreAsync(GainfoSapEntity item)
{
var info = GainfoSapToGainfo(item);
//只有身份证号存在才进行新增
if (info.IdNo.IsPresent())
{
await _dbContext.UseTransactionAsync(async () =>
{
if (item.isowner == "T")
{
@@ -220,7 +209,6 @@ public class GainfoUpdateService : IGainfoUpdateService
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)
{
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
}
}
if (useTransaction)
{
await _dbContext.Client.Ado.CommitTranAsync();
}
}
catch (Exception ex)
{
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();