Files
jinko.yikatong/Src/Dlhis.ScheduledTask/Job/JinkoHrJob.cs

406 lines
16 KiB
C#

using Dlhis.ScheduledTask.Configurations;
using Dlhis.ScheduledTask.Dto;
using Dlhis.ScheduledTask.Entities;
using Dlhis.ScheduledTask.Response;
using Hangfire.Logging;
using Newtonsoft.Json;
using Serilog;
using System.Net.Http.Headers;
using System.Text;
using Dlhis.ScheduledTask.WsProxy;
using Microsoft.Extensions.Options;
namespace Dlhis.ScheduledTask.Job
{
public class JinkoHrJob
{
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>();
public ServiceSettings Settings { get; }
private readonly ZHRS_WERKS[] werks;
private readonly ILogger<JinkoHrJob> _logger;
private readonly ServiceSettings _serviceSettings;
public JinkoHrJob(ILogger<JinkoHrJob> logger, IOptions<ServiceSettings> options)
{
_logger = logger;
_serviceSettings = options.Value;
}
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 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 = conn.Queryable<GainfoSap>()
.Where(x => searchCodes.Contains(x.Ename))
.Select(x => x.Ename)
.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
{
conn.Execute(SqlGeneration.InsertSql, item);
// 模拟触发器业务逻辑
SimulateTriggerBusinessLogic(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
{
conn.Execute(SqlGeneration.UpdateSql, item);
// 手动执行触发器的业务逻辑
UpdateExecuteTriggerBusinessLogic(originUpdates);
//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;
}
//插入
#region
// 模拟触发器业务逻辑的方法
private void SimulateTriggerBusinessLogic(GainfoSap item)
{
int ret;
string accnt = GetAccnt();
// 判断记录是否存在于 Gainfo 表中
if (db.Queryable<GainfoEntity>().Any(it => it.IdNO == item.idno))
{
// 如果存在,执行更新逻辑
UpdateGainfo(item);
}
else
{
// 如果不存在,执行插入逻辑
InsertGainfo(item);
}
}
// 更新 Gainfo 表的方法
private void UpdateGainfo(GainfoSap item)
{
// 此处需要编写更新 Gainfo 表的具体逻辑
// 根据业务需求更新相应的字段
// 这里仅为演示,需要替换为实际逻辑
db.Updateable<GainfoEntity>().UpdateColumns(it => new GainfoEntity
{
Gname = item.gname,
Ename = item.ename,
Web = item.web,
Phone = item.phone,
Appellation = item.appellation,
Isowner = item.isowner,
Remark = item.remark,
Email = item.email,
})
.Where(it => it.IdNO == item.idno)
.ExecuteCommand();
}
// 插入 Gainfo 表的方法
private void InsertGainfo(GainfoSap item)
{
// 此处需要编写插入 Gainfo 表的具体逻辑
// 根据业务需求插入相应的字段
// 这里仅为演示,需要替换为实际逻辑
var accnt = GetAccnt();
db.Insertable(new GainfoEntity
{
Guestno = accnt,
Ano = item.ano,
Class = item.@class,
Gname = item.gname,
Ename = item.ename,
Country = item.country,
Idcls = item.idcls,
Idno = item.idno,
Native = item.native,
Sex = item.sex,
Birthday = item.birthday,
Address = item.address,
Appellation = item.appellation,
Nation = item.nation,
Web = item.web,
Phone = item.phone,
Log_id = item.log_id,
Log_shift = item.log_shift,
Log_date = item.log_date,
Log_ip = item.log_ip,
Isowner = item.isowner,
Remark = item.remark,
}).ExecuteCommand();
}
// 获取 accnt 的方法
private string GetAccnt()
{
int ret;
string accnt = null;
db.Ado.UseStoredProcedure(() =>
{
db.Ado.RegisterOutParam("ret", out ret);
db.Ado.RegisterOutParam("accnt", out accnt);
db.Ado.ExecuteCommand("p_xx_pub_getno", new SugarParameter("@ret", ParameterDirection.Output), new SugarParameter("@accnt", ParameterDirection.Output));
});
return accnt;
}
#endregion
//修改
#region
private void UpdateExecuteTriggerBusinessLogic(List<GainfoSap> updates)
{
foreach (var item in updates)
{
try
{
ExecuteUpdateLogic(item);
Console.WriteLine($"执行更新逻辑 name:{item.gname}, ename:{item.ename}");
}
catch (Exception ex)
{
Console.WriteLine($"执行更新逻辑失败 name:{item.gname}, ename:{item.ename} \r\n{ex.Message}");
}
}
}
private void ExecuteUpdateLogic(GainfoSap updatedItem)
{
//todo 下发任务
// 获取 accnt
string accnt = GetAccnt();
// 检查是否存在相同 idno 的记录
var existingRecord = db.Queryable<GainfoEntity>().FirstOrDefault(a => a.idno == updatedItem.idno);
if (existingRecord != null)
{
// 更新已存在的记录的字段
db.Updateable<GainfoEntity>()
.SetColumns(it => new { it.ano, it.gname, it.ename, it.web, it.phone, it.appellation, it.isowner, it.remark, it.email, it.createdate, it.werks })
.Where(it => it.idno == updatedItem.idno && !db.Queryable<GainfoSap>().Any(b => b.idno == updatedItem.idno && b.pernr != updatedItem.pernr && b.isowner == "T")
&& !db.Queryable<GainfoSap>().Any(c => c.idno == updatedItem.idno && c.pernr > updatedItem.pernr && c.isowner == updatedItem.isowner))
.ExecuteCommand();
}
else
{
// 不存在相同 idno 的记录,执行插入操作
db.Ado.BeginTran();
try
{
accnt = GetAccnt();
db.Insertable(new GainfoEntity
{
Ano = updatedItem.PERNR,
Guestno = accnt,
Ano = updatedItem.ano,
Class = updatedItem.@class,
Gname = updatedItem.gname,
Ename = updatedItem.ename,
Country = updatedItem.country,
Idcls = updatedItem.idcls,
Idno = updatedItem.idno,
Native = updatedItem.native,
Sex = updatedItem.sex,
Birthday = updatedItem.birthday,
Address = updatedItem.address,
Appellation = updatedItem.appellation,
Nation = updatedItem.nation,
Web = updatedItem.web,
Phone = updatedItem.phone,
Log_id = updatedItem.log_id,
Log_shift = updatedItem.log_shift,
Log_date = updatedItem.log_date,
Log_ip = updatedItem.log_ip,
Isowner = updatedItem.isowner,
Remark = updatedItem.remark,
}).ExecuteCommand();
db.Ado.CommitTran();
}
catch (Exception)
{
db.Ado.RollbackTran();
throw;
}
}
}
#endregion
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.LogInformation("获取人员信息成功,count:" + persons.Count);
File.WriteAllText("Cache/request.json", JsonConvert.SerializeObject(personResp));
log.LogInformation("请求数据保存到Cache/request.json");
if (persons.Count > 0)
{
var modifiedPersons = GetModifiedPerson(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
//WhyDiff(modifiedPersons.Last());
log.LogInformation($"同步人员差异数据:{modifiedPersons.Count}");
if (modifiedPersons.Count > 0)
{
var failedRecords = SavePerson(modifiedPersons);
log.Info($"同步人员数据完成,成功{modifiedPersons.Count - failedRecords}条, 失败:{failedRecords}");
}
else
{
log.LogInformation($"同步人员数据完成,无数据变更");
}
}
}
catch (Exception ex)
{
log.Error("同步人员信息失败", ex);
}
}
}
}