311 lines
10 KiB
C#
311 lines
10 KiB
C#
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;
|
|
private List<PositionEntity> _positions;
|
|
|
|
public SyncPersonJob(IDbContext dbContext, ILogger<SyncPersonJob> logger, IJinkoSapService jinkoSapService)
|
|
{
|
|
_dbContext = dbContext;
|
|
_logger = logger;
|
|
_jinkoSapService = jinkoSapService;
|
|
}
|
|
|
|
public async Task RunAsync()
|
|
{
|
|
var personResp = await _jinkoSapService.GetPersonsAsync();
|
|
var persons = personResp.Person.Items;
|
|
|
|
_logger.LogInformation("获取SAP人员数量为:{count}", persons.Count);
|
|
if (persons.Count > 0)
|
|
{
|
|
_positions = await _dbContext.Queryable<PositionEntity>().ToListAsync();
|
|
var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
|
|
_logger.LogInformation("SAP人员差异数量为:{count}", modifiedPersons.Count);
|
|
if (modifiedPersons.Count > 0)
|
|
{
|
|
var failedRecords = SavePerson(modifiedPersons);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task<int> SavePerson(List<SapPersonItem> persons)
|
|
{
|
|
var failure = 0;
|
|
var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
|
|
|
|
foreach (var searchCodes in workCodes.Chunk(4000))
|
|
{
|
|
var existsWorkCodes = await _dbContext.Queryable<GainfoEntity>()
|
|
.Where(x => searchCodes.Contains(x.Code))
|
|
.Select(x => x.Code)
|
|
.ToListAsync();
|
|
|
|
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;
|
|
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}");
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private async Task SavePerson(GainfoSapEntity item)
|
|
{
|
|
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();
|
|
await _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(x => x.Code == item.ename)
|
|
.ExecuteCommandAsync();
|
|
}
|
|
|
|
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 = _positions.FirstOrDefault(x => x.No == 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?.Name ?? "", 30),
|
|
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);
|
|
}
|
|
} |