This commit is contained in:
2026-05-13 15:05:02 +08:00
parent 4ece8fc1e5
commit 2f46d45b98

View File

@@ -114,44 +114,55 @@ public class GainfoUpdateService : IGainfoUpdateService
private async Task SavePersonAsync(List<SapPersonItem> persons)
{
var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
var validPersons = persons.Where(x => !string.IsNullOrWhiteSpace(x.ZWORKCODE)).ToList();
if (validPersons.Count <= 0)
{
return;
}
var workCodes = validPersons.Select(x => x.ZWORKCODE).Distinct().ToList();
var chunks = workCodes.Chunk(4000).ToList();
var comparer = new SapPersonComparer();
foreach (var searchCodes in chunks)
{
_logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length);
var existsWorkCodes = await _dbContext.Queryable<GainfoSapEntity>()
var chunkPersons = validPersons.Where(x => searchCodes.Contains(x.ZWORKCODE)).ToList();
var currentPersons = GetCurrentPersons(chunkPersons);
var histories = await _dbContext.Queryable<GainfoSapEntity>()
.Where(x => searchCodes.Contains(x.ename))
.Select(x => x.ename)
.ToListAsync();
var originUpdates = persons.Where(x => existsWorkCodes.Contains(x.ZWORKCODE)).ToList();
var existsUpdateWorkCodes = originUpdates.Select(x => x.ZWORKCODE).ToList();
var originInserts = persons.Where(x => searchCodes.Contains(x.ZWORKCODE)).Where(x => !existsUpdateWorkCodes.Contains(x.ZWORKCODE)).ToList();
var historyPersons = histories.Select(ToSapPersonItem).ToList();
var updates = ToGainfoSap(originUpdates);
var inserts = ToGainfoSap(originInserts);
foreach (var item in inserts)
foreach (var person in chunkPersons)
{
try
{
await InsertPersonAsync(item);
if (historyPersons.Any(x => comparer.Equals(person, x)))
{
continue;
}
var item = ToGainfoSap(person);
await InsertGainfoSapHistoryAsync(item);
historyPersons.Add(ToSapPersonItem(item));
}
catch (Exception ex)
{
_logger.LogError(ex, "执行新增失败:{message}", ex.Message);
_logger.LogError(ex, "执行历史同步失败:{message}", ex.Message);
}
}
foreach (var item in updates)
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 InsertPersonAsync(item);
await InsertCurrentPersonAsync(item);
}
else
{
@@ -160,13 +171,18 @@ public class GainfoUpdateService : IGainfoUpdateService
}
catch (Exception ex)
{
_logger.LogError(ex, "执行更新失败:{message}", ex.Message);
_logger.LogError(ex, "执行当前人员同步失败:{message}", ex.Message);
}
}
}
}
private async Task InsertPersonAsync(GainfoSapEntity item)
private async Task InsertGainfoSapHistoryAsync(GainfoSapEntity item)
{
await _dbContext.InsertAsync(item);
}
private async Task InsertCurrentPersonAsync(GainfoSapEntity item)
{
var info = GainfoSapToGainfo(item);
//只有身份证号存在才进行新增
@@ -174,8 +190,6 @@ public class GainfoUpdateService : IGainfoUpdateService
{
await _dbContext.UseTransactionAsync(async () =>
{
await _dbContext.InsertAsync(item);
if (item.isowner == "T")
{
if (!await _dbContext.Queryable<GainfoEntity>().AnyAsync(x => x.Code == item.ename))
@@ -241,33 +255,6 @@ public class GainfoUpdateService : IGainfoUpdateService
await _dbContext.Client.Ado.BeginTranAsync();
try
{
await _dbContext.Updateable<GainfoSapEntity>().SetColumns(g => new GainfoSapEntity
{
PERNR = item.PERNR,
gname = item.gname,
gname2 = item.gname2,
idno = item.idno,
birthday = item.birthday,
phone = item.phone,
appellation = item.appellation,
isowner = item.isowner,
remark = item.remark,
email = item.email,
WERKS = item.WERKS,
KOSTL = item.KOSTL,
STELL = item.STELL,
Z_ZJ = item.Z_ZJ,
ZZ_ZD = item.ZZ_ZD,
MNTXT = item.MNTXT,
MASSN = item.MASSN,
ZSTATUS = item.ZSTATUS,
ZLZRQ = item.ZLZRQ,
STELL_NM = item.STELL_NM,
createdate = item.createdate,
ZZ_GZDJD = item.ZZ_GZDJD,
ZZ_GZDCQ = item.ZZ_GZDCQ,
}).Where(x => x.ename == item.ename).ExecuteCommandAsync();
//获取当前在职人员
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == item.ename).SingleAsync();
@@ -461,15 +448,8 @@ public class GainfoUpdateService : IGainfoUpdateService
return new List<SapPersonItem>();
}
var currentPersons = sapList
.OrderByDescending(x => x.ZSTATUS)
.ThenBy(x => x.ZRZRQ)
.GroupBy(x => x.ZWORKCODE)
.Select(x => x.First())
.ToList();
var comparer = new SapPersonComparer();
var workCodes = currentPersons
var workCodes = sapList
.Select(x => x.ZWORKCODE)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Distinct()
@@ -477,24 +457,22 @@ public class GainfoUpdateService : IGainfoUpdateService
if (workCodes.Count <= 0)
{
return currentPersons;
return sapList;
}
var last = await LoadDataAsync(workCodes);
if (last.Count <= 0)
{
return currentPersons;
return sapList;
}
var lastMap = last
.OrderByDescending(x => x.ZSTATUS)
.ThenBy(x => x.ZRZRQ)
.Where(x => !string.IsNullOrWhiteSpace(x.ZWORKCODE))
.GroupBy(x => x.ZWORKCODE)
.ToDictionary(x => x.Key, x => x.First());
.ToDictionary(x => x.Key, x => x.ToList());
var modifiedPersons = new List<SapPersonItem>();
foreach (var person in currentPersons)
foreach (var person in sapList)
{
if (string.IsNullOrWhiteSpace(person.ZWORKCODE))
{
@@ -502,20 +480,33 @@ public class GainfoUpdateService : IGainfoUpdateService
continue;
}
if (!lastMap.TryGetValue(person.ZWORKCODE, out var historyPerson) || !comparer.Equals(person, historyPerson))
if (!lastMap.TryGetValue(person.ZWORKCODE, out var historyPersons) || historyPersons.Count <= 0)
{
modifiedPersons.Add(person);
continue;
}
var exactHistory = historyPersons.FirstOrDefault(x => comparer.Equals(person, x));
if (exactHistory != null)
{
historyPersons.Remove(exactHistory);
continue;
}
modifiedPersons.Add(person);
}
if (modifiedPersons.Count > 0)
{
var first = modifiedPersons[0];
SapPersonItem historyPerson = null;
var hasHistory = !string.IsNullOrWhiteSpace(first.ZWORKCODE) && lastMap.TryGetValue(first.ZWORKCODE, out historyPerson);
var historyCandidates = !string.IsNullOrWhiteSpace(first.ZWORKCODE)
&& lastMap.TryGetValue(first.ZWORKCODE, out var currentHistoryPersons)
? currentHistoryPersons
: new List<SapPersonItem>();
var hasHistory = historyCandidates.Count > 0;
var diffType = hasHistory ? "Update" : "Insert";
var diffMessage = hasHistory
? string.Join("; ", GetFirstDiffFields(first, historyPerson))
? string.Join("; ", GetFirstDiffFields(first, historyCandidates[0]))
: "历史记录不存在";
_logger.LogWarning("SAP首条差异 DiffType:{diffType}, ZWORKCODE:{workCode}, HasHistory:{hasHistory}, Diffs:{diffs}",
diffType, first.ZWORKCODE, hasHistory, diffMessage);
@@ -524,6 +515,16 @@ 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)
{
@@ -537,7 +538,73 @@ public class GainfoUpdateService : IGainfoUpdateService
gainfos.AddRange(items);
}
return gainfos.Select(x => new SapPersonItem
return gainfos.Select(ToSapPersonItem).ToList();
}
private static List<GainfoSapEntity> ToGainfoSap(List<SapPersonItem> data)
{
return data.Select(ToGainfoSap).ToList();
}
private static GainfoSapEntity ToGainfoSap(SapPersonItem person)
{
var entryDate = person.ZRZRQ;
var resignDate = person.ZLZRQ;
var rmk = $"入职时间:{entryDate.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
if (resignDate != null && resignDate.Value.ToString("yyyy-MM-dd") != "1900-01-01")
rmk += $"离职时间:{resignDate.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
if (!string.IsNullOrWhiteSpace(person.MGTXT))
rmk += $"变更原因:{person.MGTXT}";
var native = GetNative(person.ZZ_SFZH);
var gender = person.GESCH == "2" ? "F" : "M";
person.ZZ_SFZH = person.ZZ_SFZH?.TrimStart();
return new GainfoSapEntity
{
gname = person.NAME,
gname2 = person.NAME2,
ename = person.ZWORKCODE,
idno = person.ZZ_SFZH,
birthday = person.GBDAT,
email = person.ZXUELI,
appellation = person.ORGEH,
phone = person.ZMOBILE,
ZSTATUS = person.ZSTATUS,
createdate = person.ZRZRQ,
PERNR = person.PERNR,
WERKS = person.WERKS,
KOSTL = person.KOSTL_XJ,
ZZ_ZD = person.ZZ_ZD,
Z_ZJ = person.Z_ZJ,
STELL = person.PLANS,//person.STELL, 20251129变更
STELL_NM = person.STELL_NM ?? string.Empty,
ZLZRQ = person.ZLZRQ,
MASSN = person.MASSN ?? string.Empty,
MNTXT = person.MNTXT ?? string.Empty,
remark = rmk,
native = native,
sex = gender,
logdate = DateTime.Now,
isowner = int.Parse(person.ZSTATUS) < 5 ? "T" : "F",
country = person.ZZ_COUNNM,
address = "",
occupation = "99",
nation = "01",
idcls = "ID",
ZZ_COUNNM = person.ZZ_COUNNM,
ZZ_GZDJD = person.ZZ_GZDJD,
ZZ_GZDCQ = person.ZZ_GZDCQ
};
}
private static SapPersonItem ToSapPersonItem(GainfoSapEntity x)
{
return new SapPersonItem
{
NAME = x.gname,
NAME2 = x.gname2,
@@ -563,68 +630,7 @@ public class GainfoUpdateService : IGainfoUpdateService
ZZ_COUNNM = x.ZZ_COUNNM,
ZZ_GZDJD = x.ZZ_GZDJD,
ZZ_GZDCQ = x.ZZ_GZDCQ
}).ToList();
}
private static List<GainfoSapEntity> ToGainfoSap(List<SapPersonItem> data)
{
return data.Select(person =>
{
var entryDate = person.ZRZRQ;
var resignDate = person.ZLZRQ;
var rmk = $"入职时间:{entryDate.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
if (resignDate != null && resignDate.Value.ToString("yyyy-MM-dd") != "1900-01-01")
rmk += $"离职时间:{resignDate.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
if (!string.IsNullOrWhiteSpace(person.MGTXT))
rmk += $"变更原因:{person.MGTXT}";
var native = GetNative(person.ZZ_SFZH);
var gender = person.GESCH == "2" ? "F" : "M";
person.ZZ_SFZH = person.ZZ_SFZH.TrimStart();
GainfoSapEntity o = new()
{
gname = person.NAME,
gname2 = person.NAME2,
ename = person.ZWORKCODE,
idno = person.ZZ_SFZH,
birthday = person.GBDAT,
email = person.ZXUELI,
appellation = person.ORGEH,
phone = person.ZMOBILE,
ZSTATUS = person.ZSTATUS,
createdate = person.ZRZRQ,
PERNR = person.PERNR,
WERKS = person.WERKS,
KOSTL = person.KOSTL_XJ,
ZZ_ZD = person.ZZ_ZD,
Z_ZJ = person.Z_ZJ,
STELL = person.PLANS,//person.STELL, 20251129变更
STELL_NM = person.STELL_NM ?? string.Empty,
ZLZRQ = person.ZLZRQ,
MASSN = person.MASSN ?? string.Empty,
MNTXT = person.MNTXT ?? string.Empty,
remark = rmk,
native = native,
sex = gender,
logdate = DateTime.Now,
isowner = int.Parse(person.ZSTATUS) < 5 ? "T" : "F",
country = person.ZZ_COUNNM,
address = "",
occupation = "99",
nation = "01",
idcls = "ID",
ZZ_COUNNM = person.ZZ_COUNNM,
ZZ_GZDJD = person.ZZ_GZDJD,
ZZ_GZDCQ = person.ZZ_GZDCQ
};
return o;
}).ToList();
};
}
private static string GetNative(string idNo)