fix 重构数据同步
This commit is contained in:
370
Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPersonJob.cs
Normal file
370
Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPersonJob.cs
Normal file
@@ -0,0 +1,370 @@
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using Kurisu.SqlSugar.Services;
|
||||
using Dlhis.Entity.Basic.Entity;
|
||||
using Dlhis.Entity.Basic.Enums;
|
||||
using Dlhis.ScheduledTask.SyncSapInfo.Dto;
|
||||
using Dlhis.ScheduledTask.SyncSapInfo.Comparers;
|
||||
using Dlhis.ScheduledTask.SyncSapInfo.Services;
|
||||
|
||||
namespace Dlhis.ScheduledTask.SyncSapInfo.Job;
|
||||
|
||||
public class SyncPersonJob
|
||||
{
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IJinkoSapService _jinkoSapService;
|
||||
|
||||
public SyncPersonJob(IDbContext dbContext, ILogger logger, IJinkoSapService jinkoSapService)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
_jinkoSapService = jinkoSapService;
|
||||
}
|
||||
|
||||
public async Task SyncPersonInfo()
|
||||
{
|
||||
var personResp = await _jinkoSapService.GetPersonsAsync();
|
||||
var persons = personResp.Person.Items;
|
||||
|
||||
if (persons.Count > 0)
|
||||
{
|
||||
var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
|
||||
if (modifiedPersons.Count > 0)
|
||||
{
|
||||
var failedRecords = SavePerson(modifiedPersons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<int> SavePerson(List<SapPersonItem> persons)
|
||||
{
|
||||
|
||||
var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
|
||||
|
||||
var index = 1;
|
||||
var count = 4000;
|
||||
var failure = 0;
|
||||
var total = persons.Count;
|
||||
|
||||
var searchCodes = workCodes.Skip((index - 1) * count).Take(count).ToList();
|
||||
while (searchCodes.Count > 0)
|
||||
{
|
||||
var existsWorkCodes = _dbContext.Queryable<GainfoEntity>()
|
||||
.Where(x => searchCodes.Contains(x.Code))
|
||||
.Select(x => x.Code)
|
||||
.ToList();
|
||||
|
||||
var originUpdates = persons.Where(x => existsWorkCodes.Contains(x.ZWORKCODE)).ToList();
|
||||
var originInserts = persons.Where(x => searchCodes.Contains(x.ZWORKCODE)).Except(originUpdates, new SapPersonComparer()).ToList();
|
||||
|
||||
int i = 0;
|
||||
if (originUpdates.Count + originInserts.Count <= count)
|
||||
{
|
||||
var currentTotal = originUpdates.Count + originInserts.Count;
|
||||
|
||||
var updates = ToGainfoSap(originUpdates);
|
||||
var inserts = ToGainfoSap(originInserts);
|
||||
|
||||
foreach (var item in inserts)
|
||||
{
|
||||
i++;
|
||||
try
|
||||
{
|
||||
await SavePerson(item);
|
||||
//conn.Execute(SqlGeneration.InsertSql, item);
|
||||
//log.Debug($"执行新增{i}/{currentTotal} name:{item.gname},ename:{item.ename}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failure++;
|
||||
//log.Error($"执行新增{i}/{currentTotal} name:{item.gname},ename:{item.ename}失败 \r\n{ex.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var item in updates)
|
||||
{
|
||||
i++;
|
||||
try
|
||||
{
|
||||
await UpdatePerson(item);
|
||||
//conn.Execute(SqlGeneration.UpdateSql, item);
|
||||
//log.Debug($"执行更新{i}/{currentTotal} name:{item.gname},ename:{item.ename}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failure++;
|
||||
//log.Error($"执行更新{i}/{currentTotal} name:{item.gname},ename:{item.ename}失败 \r\n{ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
persons = persons.Except(originUpdates).Except(originUpdates).ToList();
|
||||
searchCodes = workCodes.Skip((index - 1) * count).Take(count).ToList();
|
||||
}
|
||||
|
||||
return failure;
|
||||
}
|
||||
|
||||
private async Task SavePerson(GainfoSapEntity item)
|
||||
{
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdNo == item.idno).FirstAsync();
|
||||
if (gainfo != null)
|
||||
{
|
||||
gainfo.No = item.guestno;
|
||||
gainfo.SapNo = item.ano;
|
||||
gainfo.Type = item.@class;
|
||||
gainfo.Name = item.gname;
|
||||
gainfo.Code = item.ename;
|
||||
gainfo.CountryNo = item.country;
|
||||
gainfo.IdClass = item.idcls;
|
||||
gainfo.Native = item.native;
|
||||
gainfo.Gender = item.sex == "F" ? GenderEnumType.Female : GenderEnumType.Male;
|
||||
gainfo.Birthday = (DateTime)item.birthday;
|
||||
gainfo.Address = item.address;
|
||||
gainfo.DepartmentNo = item.appellation;
|
||||
gainfo.Nation = item.nation;
|
||||
gainfo.Phone = item.phone;
|
||||
gainfo.Degree = item.email;
|
||||
gainfo.Position = item.web;
|
||||
gainfo.Remark = item.remark;
|
||||
gainfo.Werks = item.WERKS;
|
||||
gainfo.Employed = item.isowner; //int.Parse(person.ZSTATUS) < 4 ? "T" : "F", 是否离职
|
||||
await _dbContext.UpdateAsync(gainfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
var info = new GainfoEntity
|
||||
{
|
||||
No = item.guestno,
|
||||
SapNo = item.ano,
|
||||
Type = item.@class,
|
||||
Name = item.gname,
|
||||
Code = item.ename,
|
||||
CountryNo = item.country,
|
||||
IdClass = item.idcls,
|
||||
IdNo = item.idno,
|
||||
Native = item.native,
|
||||
Gender = item.sex == "F" ? GenderEnumType.Female : GenderEnumType.Male,
|
||||
Birthday = (DateTime)item.birthday,
|
||||
Address = item.address,
|
||||
//Marital 已婚未婚
|
||||
//Occuption = item.occuption,
|
||||
DepartmentNo = item.appellation,
|
||||
Nation = item.nation,
|
||||
Phone = item.phone,
|
||||
Degree = item.email,
|
||||
Position = item.web,
|
||||
//CarNo
|
||||
Remark = item.remark,
|
||||
Werks = item.WERKS,
|
||||
Employed = item.isowner,
|
||||
};
|
||||
await _dbContext.InsertAsync(info);
|
||||
}
|
||||
}
|
||||
private async Task UpdatePerson(GainfoSapEntity item)
|
||||
{
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdNo == item.idno).FirstAsync();
|
||||
if (gainfo != null)
|
||||
{
|
||||
_dbContext.Updateable<GainfoEntity>().SetColumns(g => new GainfoEntity
|
||||
{
|
||||
SapNo = item.PERNR,
|
||||
Name = item.gname,
|
||||
Code = item.ename,
|
||||
Position = item.web,
|
||||
Phone = item.phone,
|
||||
DepartmentNo = item.appellation,
|
||||
Employed = item.isowner,
|
||||
Remark = item.remark,
|
||||
Degree = item.email,
|
||||
Werks = item.WERKS
|
||||
})
|
||||
.Where(g => g.IdNo == item.idno
|
||||
&& !_dbContext.Queryable<GainfoEntity>().Any(g => g.IdNo == item.idno && g.SapNo != item.PERNR && g.Employed == "T")
|
||||
&& !_dbContext.Queryable<GainfoEntity>().Any(g => g.IdNo == item.idno && int.Parse(g.SapNo) > int.Parse(item.PERNR) && g.Employed == item.isowner));
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbContext.Updateable<GainfoEntity>().SetColumns(g => new GainfoEntity
|
||||
{
|
||||
SapNo = item.PERNR,
|
||||
Name = item.gname,
|
||||
Code = item.ename,
|
||||
Position = item.web,
|
||||
Phone = item.phone,
|
||||
DepartmentNo = item.appellation,
|
||||
Employed = item.isowner,
|
||||
Remark = item.remark,
|
||||
Degree = item.email,
|
||||
Werks = item.WERKS
|
||||
})
|
||||
.Where(g => g.SapNo == item.PERNR
|
||||
&& !_dbContext.Queryable<GainfoEntity>().Any(g => g.Code == item.ename && g.Employed == "T")
|
||||
&& !_dbContext.Queryable<GainfoEntity>().Any(g => g.IdNo == item.idno && int.Parse(g.SapNo) > int.Parse(item.PERNR) && g.Employed == item.isowner));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<SapPersonItem>> GetModifiedPersonAsync(List<SapPersonItem> sapList)
|
||||
{
|
||||
var last = await LoadDataAsync();
|
||||
if (last.Count <= 0)
|
||||
{
|
||||
return sapList;
|
||||
}
|
||||
|
||||
var needRemove = sapList.Intersect(last, new SapPersonComparer());
|
||||
return sapList.Except(needRemove, new SapPersonComparer()).ToList();
|
||||
}
|
||||
|
||||
|
||||
private async Task<List<SapPersonItem>> LoadDataAsync()
|
||||
{
|
||||
var gainfo = await _dbContext.Queryable<GainfoSapEntity>().ToListAsync();
|
||||
|
||||
return gainfo.Select(x => new SapPersonItem
|
||||
{
|
||||
NAME = x.gname,
|
||||
ZWORKCODE = x.ename,
|
||||
ZZ_SFZH = x.idno,
|
||||
GBDAT = x.birthday?.ToString("yyyy-MM-dd") ?? "0000-00-00",
|
||||
ZZ_KLX = x.ZZ_KLX,
|
||||
ZXUELI = x.email?.Trim() ?? string.Empty,
|
||||
ORGEH = x.appellation,
|
||||
ZMOBILE = x.phone,
|
||||
ZSTATUS = x.ZSTATUS,
|
||||
ZRZRQ = x.createdate?.ToString("yyyy-MM-dd"),
|
||||
PERNR = x.PERNR,
|
||||
WERKS = x.WERKS,
|
||||
KOSTL = x.KOSTL,
|
||||
ZZ_ZD = x.ZZ_ZD,
|
||||
Z_ZJ = x.Z_ZJ,
|
||||
STELL = x.STELL,
|
||||
STELL_NM = x.STELL_NM,
|
||||
ZLZRQ = x.ZLZRQ?.ToString("yyyy-MM-dd"),
|
||||
MASSN = x.MASSN,
|
||||
MNTXT = x.MNTXT,
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
private List<GainfoSapEntity> ToGainfoSap(List<SapPersonItem> data)
|
||||
{
|
||||
return data.Select(person =>
|
||||
{
|
||||
GainfoSapEntity o = null;
|
||||
try
|
||||
{
|
||||
var position = string.Empty; //lastUpdatedPositionList.FirstOrDefault(x => x.ZJOBID == person.PLANS);
|
||||
|
||||
var rzrq = SafeParseDate(person.ZRZRQ);
|
||||
var lzrq = SafeParseDate(person.ZLZRQ);
|
||||
var rmk = "";
|
||||
if (rzrq != null)
|
||||
rmk = $"入职时间:{rzrq.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
|
||||
|
||||
if (lzrq != null)
|
||||
rmk += $"离职时间:{lzrq.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(person.MGTXT))
|
||||
rmk += $"离职原因:{person.MGTXT}";
|
||||
|
||||
var native = GetNative(person.ZZ_SFZH);
|
||||
var sex = person.GESCH == "2" ? "F" : "M";
|
||||
|
||||
person.ZZ_SFZH = person.ZZ_SFZH?.TrimStart();
|
||||
o = new GainfoSapEntity
|
||||
{
|
||||
gname = person.NAME,
|
||||
ename = person.ZWORKCODE,
|
||||
idno = SubString(person.ZZ_SFZH, 18),
|
||||
birthday = SafeParseDate(person.GBDAT).Value,
|
||||
ZZ_KLX = person.ZZ_KLX,
|
||||
email = person.ZXUELI,
|
||||
appellation = person.ORGEH,
|
||||
phone = person.ZMOBILE,
|
||||
ZSTATUS = person.ZSTATUS,
|
||||
createdate = Convert.ToDateTime(person.ZRZRQ),
|
||||
PERNR = person.PERNR,
|
||||
WERKS = person.WERKS,
|
||||
KOSTL = person.KOSTL,
|
||||
ZZ_ZD = person.ZZ_ZD,
|
||||
Z_ZJ = person.Z_ZJ,
|
||||
STELL = person.STELL,
|
||||
STELL_NM = person.STELL_NM,
|
||||
ZLZRQ = SafeParseDate(person.ZLZRQ).Value,
|
||||
MASSN = person.MASSN,
|
||||
MNTXT = person.MNTXT,
|
||||
remark = rmk,
|
||||
native = native,
|
||||
sex = sex,
|
||||
//web = SubString(position?.ZJOBANME, 30), todo
|
||||
logdate = DateTime.Now,
|
||||
isowner = int.Parse(person.ZSTATUS) < 4 ? "T" : "F",
|
||||
@class = "C",
|
||||
country = "CN",
|
||||
log_ip = "127.0.0.1",
|
||||
log_shift = "1",
|
||||
log_id = "XX",
|
||||
address = "",
|
||||
occupation = "99",
|
||||
nation = "01"
|
||||
};
|
||||
|
||||
return o;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private string GetNative(string idno)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(idno) || idno.Length < 6) return null;
|
||||
idno = idno.TrimStart();
|
||||
return idno.Substring(0, 6);
|
||||
}
|
||||
|
||||
private DateTime? SafeParseDate(string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
{
|
||||
str = "1900-01-01";
|
||||
}
|
||||
|
||||
if ("0000-00-00".Equals(str))
|
||||
{
|
||||
str = "1900-01-01";
|
||||
}
|
||||
|
||||
if (DateTime.TryParse(str, out var d))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string SubString(string s, int len)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
return s?.Trim() ?? "";
|
||||
}
|
||||
s = s.Trim();
|
||||
var bs = Encoding.UTF8.GetBytes(s);
|
||||
if (bs.Length <= len)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
var bytes = new byte[len];
|
||||
Buffer.BlockCopy(bs, 0, bytes, 0, len);
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user