diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs index 2d659763..6a1b11bc 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs @@ -114,44 +114,55 @@ public class GainfoUpdateService : IGainfoUpdateService private async Task SavePersonAsync(List 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() + var chunkPersons = validPersons.Where(x => searchCodes.Contains(x.ZWORKCODE)).ToList(); + var currentPersons = GetCurrentPersons(chunkPersons); + var histories = await _dbContext.Queryable() .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().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().AnyAsync(x => x.Code == item.ename)) @@ -241,33 +255,6 @@ public class GainfoUpdateService : IGainfoUpdateService await _dbContext.Client.Ado.BeginTranAsync(); try { - await _dbContext.Updateable().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().Where(x => x.Code == item.ename).SingleAsync(); @@ -461,15 +448,8 @@ public class GainfoUpdateService : IGainfoUpdateService return new List(); } - 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(); - 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(); + 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 GetCurrentPersons(List sapList) + { + return sapList + .OrderByDescending(x => x.ZSTATUS) + .ThenBy(x => x.ZRZRQ) + .GroupBy(x => x.ZWORKCODE) + .Select(x => x.First()) + .ToList(); + } + private async Task> LoadDataAsync(List 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 ToGainfoSap(List 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 ToGainfoSap(List 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)