Files
jinko.yikatong/Src/Dlhis.ScheduledTask/Job/SyncPersonJob.cs
2024-01-09 16:28:58 +08:00

445 lines
18 KiB
C#

using Dlhis.ScheduledTask.Comparers;
using Dlhis.ScheduledTask.Dto;
using Dlhis.ScheduledTask.Entities;
using Dlhis.ScheduledTask.Response;
using Newtonsoft.Json;
using System.Data.SqlClient;
using System.Data;
using System.Net.Http.Headers;
using System.Text;
using Dlhis.ScheduledTask.Configurations;
using Kurisu.SqlSugar.Services;
using Dlhis.Entity.Basic.Entity;
using Dlhis.ScheduledTask.Wsproxy.Dlhis.JinkoHr.WsProxy;
using Dlhis.Entity.Basic.Enums;
namespace Dlhis.ScheduledTask.Job
{
public class SyncPersonJob
{
private List<PersonDetail> lastUpdatedPersonList = new List<PersonDetail>();
private List<ZHRS_ORG> lastUpdatedOrgList = new List<ZHRS_ORG>();
private List<ZHRS_POST> lastUpdatedPositionList = new List<ZHRS_POST>();
private readonly ServiceSettings serviceSettings;
private readonly ZHRS_WERKS[] werks;
private readonly IDbContext _dbContext;
public SyncPersonJob(IDbContext dbContext)
{
_dbContext = dbContext;
}
public void SyncPersonInfo()
{
try
{
//var personResp = JsonConvert.DeserializeObject<PersonResult>(File.ReadAllText("C:\\Users\\79144\\Desktop\\request.json")); // GetPersons();
var personResp = GetPersons();// JsonConvert.DeserializeObject<PersonResult>(File.ReadAllText("Cache/request.json")); // GetPersons();
var persons = personResp.T_PERSON.item;
//log.Info("获取人员信息成功,count:" + persons.Count);
File.WriteAllText("Cache/request.json", JsonConvert.SerializeObject(personResp));
//log.Info("请求数据保存到Cache/request.json");
if (persons.Count > 0)
{
var modifiedPersons = GetModifiedPerson(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
//WhyDiff(modifiedPersons.Last());
//log.Info($"同步人员差异数据:{modifiedPersons.Count}");
if (modifiedPersons.Count > 0)
{
var failedRecords = SavePerson(modifiedPersons);
//log.Info($"同步人员数据完成,成功{modifiedPersons.Count - failedRecords}条, 失败:{failedRecords}");
}
else
{
//log.Info($"同步人员数据完成,无数据变更");
}
}
}
catch (Exception ex)
{
//log.Error("同步人员信息失败", ex);
}
}
private async Task<int> SavePerson(List<PersonDetail> persons)
{
var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
var index = 1;
var count = 4000;
var failure = 0;
var total = persons.Count;
// log.Debug($"{i}/{persons.Count}\tName={person.NAME}\tIdNo={person.ZZ_SFZH}\tPERNR={person.PERNR}");
//log.Debug($"一共{persons.Count}条差异数据");
//var conn = OpenDlDbConnection();
var searchCodes = workCodes.Skip((index - 1) * count).Take(count).ToList();
while (searchCodes.Count > 0)
{
//var existsWorkCodes = conn.Query<string>($"select ename from gainfo_sap where ename in ( {string.Join(",", searchCodes.Select(x => $"'{x}'"))} )")
// .ToList();
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 ZHRS_PERSONComparer()).ToList();
int i = 0;
if (originUpdates.Count + originInserts.Count <= count)
{
var currentTotal = originUpdates.Count + originInserts.Count;
//log.Debug($"正在进行第{index}批次,需要处理{currentTotal}条数据");
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(GainfoSap item)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdNo == item.idno).FirstAsync();
if (gainfo != null)
{
gainfo.SapNo = item.PERNR;
gainfo.Name = item.gname;
gainfo.Code = item.ename;
gainfo.Position = item.web;
gainfo.Phone = item.phone;
gainfo.DepartmentNo = item.appellation;
gainfo.Employed = item.isowner;
gainfo.Remark = item.remark;
gainfo.Degree = item.email;
gainfo.Werks = item.WERKS;
await _dbContext.UpdateAsync(gainfo);
}
else
{
var info = new GainfoEntity
{
SapNo = item.ano,
No = item.guestno,
//GType = item.@class,
Name = item.gname,
Code = item.ename,
CountryNo = item.country,
IdClass = item.idcls,
Native = item.native,
Gender = item.sex =="女性"? GenderEnumType.Female: GenderEnumType.Male,
Birthday = (DateTime)item.birthday,
Address = item.address,
//Occuption = item.occuption,
DepartmentNo = item.appellation,
Nation =item.nation,
Phone = item.phone,
Position = item.web,
//Log_id = item.log_id,
//Log_shift = item.log_shift,
//tLog_date = item.log_date,
//Log_ip = item.log_ip,
Employed = item.isowner,
Remark = item.remark,
Degree = item.email,
Werks = item.WERKS
};
await _dbContext.InsertAsync(info);
}
}
private async Task UpdatePerson(GainfoSap 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 PersonResult GetPersons()
{
HttpClient httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMinutes(10);
var credentials = string.Format("{0}:{1}", "EHS_USER", "y3R1hd2h*RICAC");
var headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", headerValue);
List<PersonDetail> persons = new List<PersonDetail>();
foreach (var item in werks)
{
try
{
var body = new
{
T_WERKS = new
{
item = new List<object>
{
new
{
item.WERKS
}
}
},
T_PERSON = Array.Empty<string>(),
T_PNO = Array.Empty<string>(),
};
var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
var response = httpClient.PostAsync("http://sappipap01.jinkosolar.cn:50100/RESTAdapter/Rest/EHR_PERSONNEL/", content).Result;
var jsonResponse = response.Content.ReadAsStringAsync().Result;
if (response.IsSuccessStatusCode)
{
PersonResult personResp = JsonConvert.DeserializeObject<PersonResult>(jsonResponse);
if (personResp?.T_PERSON?.item?.Any() == true)
{
persons.AddRange(personResp.T_PERSON.item);
//log.Info($"人事范围[{item.WERKS}]获取{personResp.T_PERSON.item.Count}条数据");
}
}
else
{
throw new Exception($"请求异常:{response.StatusCode}:" + jsonResponse);
}
// this is webservice call
//var personResp = archivesClient.ZHRF_SYN_03(new ZHRF_SYN_03()
//{
// //I_DATE = Settings.BeginSyncDate.ToString("yyy-MM-dd"),
// T_PERSON = Array.Empty<ZHRS_PERSON>(),
// T_PNO = Array.Empty<ZHRS_PNO>(),
// T_WERKS = new ZHRS_WERKS[] { item },
//});
}
catch (Exception ex)
{
//log.Error($"人事范围[{item.WERKS}]获取失败:{ex.Message}", ex);
}
}
return new PersonResult()
{
T_PERSON = new T_PERSON
{
item = persons
},
};
}
private List<PersonDetail> GetModifiedPerson(List<PersonDetail> sapList)
{
if (lastUpdatedPersonList.Count <= 0)
{
return sapList;
}
var needRemove = sapList.Intersect(lastUpdatedPersonList, new ZHRS_PERSONComparer());
return sapList.Except(needRemove, new ZHRS_PERSONComparer()).ToList();
}
private List<GainfoSap> ToGainfoSap(List<PersonDetail> data)
{
return data.Select(person =>
{
GainfoSap o = null;
try
{
var position = 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 GainfoSap
{
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),
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);
}
private IDbConnection OpenDlDbConnection()
{
try
{
IDbConnection conn = new SqlConnection(serviceSettings.DlhisDatabase);
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
return conn;
}
catch (Exception ex)
{
throw new Exception($"打开迪联数据库错误:{ex.Message}", ex);
}
}
}
}