diff --git a/Src/Dlhis.ScheduledTask/Common/Services/IGainfoUpdateService.cs b/Src/Dlhis.ScheduledTask/Common/Services/IGainfoUpdateService.cs deleted file mode 100644 index fab210dc..00000000 --- a/Src/Dlhis.ScheduledTask/Common/Services/IGainfoUpdateService.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Dlhis.ScheduledTask.Common.Services; - -public interface IGainfoUpdateService : IScopeDependency -{ - Task TodoByWerkAsync(string werk); - - Task TodoByCodeAsync(string code); -} diff --git a/Src/Dlhis.ScheduledTask/Common/Services/IJinkoJIPService.cs b/Src/Dlhis.ScheduledTask/Common/Services/IJinkoJIPService.cs index 6b91adbc..60bca394 100644 --- a/Src/Dlhis.ScheduledTask/Common/Services/IJinkoJIPService.cs +++ b/Src/Dlhis.ScheduledTask/Common/Services/IJinkoJIPService.cs @@ -5,11 +5,13 @@ namespace Dlhis.ScheduledTask.Common.Services; public interface IJinkoJipService : ISingletonDependency { - Task UploadAttendancesAsync(List requests); - + /// + /// 同步餐补处理结果 + /// + /// + /// Task SyncMealSupplementRecordsAsync(List requests); - /// /// 获取出差信息 /// @@ -28,9 +30,14 @@ public interface IJinkoJipService : ISingletonDependency /// Task GetTravelInfosByUserCodeAsync(DateTime begin, DateTime end, string userCode); - + /// + /// 同步人脸数据到SAP + /// + /// + /// + /// Task SyncFaceToSapAsync(string userCode, string base64); - - - string IssueToken(); + + + Task UploadAttendancesAsync(UploadAttendanceRequest request); } \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs deleted file mode 100644 index ebf8428a..00000000 --- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs +++ /dev/null @@ -1,496 +0,0 @@ -using Dlhis.Basic.Api; -using Dlhis.Basic.Api.Dto; -using Dlhis.Entity.Basic.Entity; -using Dlhis.Entity.Basic.Enums; -using Dlhis.Sys.Api; -using Dlhis.Sys.Api.Response; -using Dlhis.ScheduledTask.Common.Dto; -using Dlhis.ScheduledTask.Common.Comparers; -using Kurisu.AspNetCore.Utils.Extensions; -using Dlhis.Basic.Api.Request; -using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; - -namespace Dlhis.ScheduledTask.Common.Services.Implements; - -public class GainfoUpdateService : IGainfoUpdateService -{ - private readonly IDbContext _dbContext; - private readonly ILogger _logger; - private readonly ITenantApi _tenantApi; - private readonly IIdentityUserSyncService _identityUserSyncService; - private readonly IGainfoPermissionApi _gainfoPermissionApi; - private readonly IDevicePermissionApi _devicePermissionApi; - private readonly IJinkoSapService _jinkoSapService; - - private List _tenants; - - public GainfoUpdateService(IDbContext dbContext, - ILogger logger, - ITenantApi tenantApi, - IIdentityUserSyncService identityUserSyncService, - IGainfoPermissionApi gainfoPermissionApi, - IDevicePermissionApi devicePermissionApi, - IJinkoSapService jinkoSapService) - { - _dbContext = dbContext; - _dbContext.Client.QueryFilter.Clear(); - _logger = logger; - _tenantApi = tenantApi; - _identityUserSyncService = identityUserSyncService; - _gainfoPermissionApi = gainfoPermissionApi; - _devicePermissionApi = devicePermissionApi; - _jinkoSapService = jinkoSapService; - } - - - public async Task TodoByWerkAsync(string werk) - { - var werkInfo = await _dbContext.Queryable().Where(x => x.Werk == werk).SingleAsync(); - werkInfo.LastSyncStartTime = DateTime.Now; - werkInfo.HandleMessage = "任务执行中"; - await _dbContext.UpdateAsync(werkInfo); - - try - { - var personResp = await _jinkoSapService.GetPersonsByWerkAsync(werk); - var persons = personResp.Person.Items; - - werkInfo.HandleMessage = "SAP人员数量" + persons.Count; - werkInfo.Total = persons.Count; - await _dbContext.UpdateAsync(werkInfo); - - if (persons.Count > 0) - { - var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList()); - - werkInfo.HandleMessage = "SAP人员差异数量" + modifiedPersons.Count; - werkInfo.DiffNumber = modifiedPersons.Count; - await _dbContext.UpdateAsync(werkInfo); - - if (modifiedPersons.Count > 0) - { - await SavePersonAsync(modifiedPersons); - } - } - - werkInfo.HandleMessage = "同步结束"; - werkInfo.LastSyncEndTime = DateTime.Now; - werkInfo.BackgroundJobKey = string.Empty; - await _dbContext.UpdateAsync(werkInfo); - } - catch (Exception ex) - { - _logger.LogError(ex, "{werk}同步处理异常:{message}", werk, ex.Message); - werkInfo.HandleMessage = ex.Message; - werkInfo.LastSyncEndTime = DateTime.Now; - werkInfo.BackgroundJobKey = string.Empty; - await _dbContext.UpdateAsync(werkInfo); - } - } - - - public async Task TodoByCodeAsync(string code) - { - _logger.LogInformation("SAP根据学工号同步开始:{code}", code); - - var personResp = await _jinkoSapService.GetPersonsByCodeAsync(code); - var persons = personResp.Person.Items; - - _logger.LogInformation("获取SAP人员数量为:{count}", persons.Count); - if (persons.Count > 0) - { - var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList()); - _logger.LogInformation("SAP人员差异数量为:{count}", modifiedPersons.Count); - if (modifiedPersons.Count > 0) - { - await SavePersonAsync(modifiedPersons); - } - } - - _logger.LogInformation("SAP根据学工号同步结束:{code}", code); - } - - - private async Task SavePersonAsync(List persons) - { - var tenantResult = await _tenantApi.GetTenantsInternalAsync(); - _tenants = tenantResult.Data; - - var workCodes = persons.Select(x => x.ZWORKCODE).ToList(); - var chunks = workCodes.Chunk(4000).ToList(); - - foreach (var searchCodes in chunks) - { - _logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length); - var existsWorkCodes = 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 updates = ToGainfoSap(originUpdates); - var inserts = ToGainfoSap(originInserts); - - foreach (var item in inserts) - { - try - { - await InsertPersonAsync(item); - } - catch (Exception ex) - { - _logger.LogError(ex, "执行新增失败:{message}", ex.Message); - } - } - - foreach (var item in updates) - { - try - { - var no = await _dbContext.Queryable().Where(x => x.Code == item.ename).Select(x => x.No).SingleAsync(); - if (no.IsEmpty()) - { - await InsertPersonAsync(item); - } - else - { - await UpdatePersonAsync(item); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "执行更新失败:{message}", ex.Message); - } - } - } - } - - private async Task InsertPersonAsync(GainfoSapEntity item) - { - await _dbContext.InsertAsync(item); - var info = GainfoSapToGainfo(item); - - if (item.isowner == "T") - { - await _dbContext.InsertAsync(info); - await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory); - await _devicePermissionApi.RePermissionUsersInfoAsync(new PermissionUsersInfoDto - { - UserNos = new List { info.No }, - PermissionInfos = new Dictionary> - { - [info.No] = new() - } - }); - } - else - { - if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename)) - { - await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync(); - } - } - } - - private GainfoEntity GainfoSapToGainfo(GainfoSapEntity item) - { - var info = new GainfoEntity - { - No = Guid.NewGuid().ToString(), - InternalNo = item.PERNR, - Type = GainfoUserTypeEnumType.Normal, - 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 = item.birthday, - Address = item.address, - DepartmentNo = item.appellation, - Nation = item.nation, - Phone = item.phone, - Degree = item.email, - Grade = item.ZZ_ZD, - Title = item.Z_ZJ, - PositionNo = item.STELL, - Remark = item.remark, - Werks = item.WERKS, - CostId = item.KOSTL, - EntryDate = item.createdate, - ResignationDate = item.ZLZRQ, - CardType = SafeParseCardType(item.ZZ_KLX), - Workplace = _tenants.LastOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code ?? item.ZZ_GZDJDNM, - Factory = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code ?? item.ZZ_GZDCQNM, - }; - - return info; - } - - private async Task UpdatePersonAsync(GainfoSapEntity item) - { - var info = GainfoSapToGainfo(item); - await _dbContext.Updateable().SetColumns(g => new GainfoSapEntity - { - PERNR = item.PERNR, - gname = item.gname, - 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, - ZZ_KLX = item.ZZ_KLX, - createdate = item.createdate, - ZZ_GZDJDNM = item.ZZ_GZDJDNM, - ZZ_GZDCQNM = item.ZZ_GZDCQNM, - }).Where(x => x.ename == item.ename).ExecuteCommandAsync(); - - //获取当前在职人员 - var gainfo = await _dbContext.Queryable().Where(x => x.Code == item.ename).SingleAsync(); - - var workplace = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code ?? item.ZZ_GZDJDNM; - var factory = _tenants.LastOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code ?? item.ZZ_GZDCQNM; - - if (gainfo != null) - { - if (item.isowner == "T") - { - var dtoResult = await _devicePermissionApi.GetPermissionUsersInfoAsync(new List { gainfo.No }); - var dto = dtoResult.Data; - - await _dbContext.Updateable().SetColumns(g => new GainfoEntity - { - InternalNo = item.PERNR, - Name = item.gname, - PositionNo = item.STELL, - Grade = item.ZZ_ZD, - Title = item.Z_ZJ, - Phone = item.phone, - DepartmentNo = item.appellation, - Remark = item.remark, - Degree = item.email, - Werks = item.WERKS, - CostId = item.KOSTL, - EntryDate = item.createdate, - ResignationDate = item.ZLZRQ, - Workplace = workplace, - Factory = factory, - CardType = SafeParseCardType(item.ZZ_KLX) - }).Where(x => x.Code == item.ename).ExecuteCommandAsync(); - - await _identityUserSyncService.SyncAccountAsync(gainfo.Code, gainfo.Name, gainfo.IdNo, factory); - - await _devicePermissionApi.RePermissionUsersInfoAsync(dto); - } - else - { - try - { - await _gainfoPermissionApi.ResetAsync(new GainfoPermissionResetRequest - { - IsLeave = true, - UserNo = gainfo.No - }); - } - catch (Exception ex) - { - _logger.LogError(ex, "离职任务生成失败:{message}", ex.Message); - } - - //先写入离职表 - gainfo.IdentityUserId = (int)gainfo.Id; //记录原始id - gainfo.Id = 0; - gainfo.ResignationDate = item.ZLZRQ; - - if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename)) - { - await _dbContext.Client.Insertable(gainfo).AS("GainfoLeave").ExecuteCommandAsync(); - } - - gainfo.Id = gainfo.IdentityUserId; - await _dbContext.DeleteReallyAsync(gainfo); - } - } - else - { - if (item.isowner == "T") - { - await _dbContext.InsertAsync(info); - await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, factory); - } - else - { - if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename)) - { - await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync(); - } - else - { - await _dbContext.Updateable().SetColumns(g => new GainfoLeaveEntity - { - InternalNo = item.PERNR, - Name = item.gname, - PositionNo = item.STELL, - Grade = item.ZZ_ZD, - Title = item.Z_ZJ, - Phone = item.phone, - DepartmentNo = item.appellation, - Remark = item.remark, - Degree = item.email, - Werks = item.WERKS, - CostId = item.KOSTL, - EntryDate = item.createdate, - ResignationDate = item.ZLZRQ, - Workplace = workplace, - Factory = factory, - CardType = SafeParseCardType(item.ZZ_KLX) - }).Where(x => x.Code == item.ename).ExecuteCommandAsync(); - } - } - } - } - - private async Task> GetModifiedPersonAsync(List sapList) - { - var last = await LoadDataAsync(); - if (last.Count <= 0) - { - return sapList; - } - - var needRemove = sapList.Intersect(last, new SapPersonComparer()).ToList(); - return sapList.Except(needRemove, new SapPersonComparer()).ToList(); - } - - - private async Task> LoadDataAsync() - { - //var pJson = "{\"id\":0,\"ano\":null,\"class\":\"C\",\"passwd\":null,\"question\":null,\"answer\":null,\"gname\":\"岳文超\",\"ename\":\"098250\",\"country\":null,\"idcls\":\"ID\",\"idno\":\"\\\"140105200112051318\n\",\"native\":\"14010\",\"sex\":\"M\",\"birthday\":\"2001-12-05T00:00:00\",\"address\":\"\",\"postcode\":null,\"occupation\":\"99\",\"appellation\":\"00210591\",\"nation\":\"01\",\"phone\":\"13773151205\",\"fax\":null,\"mobile\":null,\"email\":\"高中/中专【失效】\",\"web\":\"\",\"vip\":null,\"sec\":null,\"cropsno\":null,\"cropname\":null,\"fancy\":null,\"remark\":\"入职时间:2023-05-05 离职时间:2023-10-30 变更原因:自离【失效】\",\"amount\":0,\"days\":0,\"consume01\":0.0000,\"consume02\":0.0000,\"consume03\":0.0000,\"consume04\":0.0000,\"log_id\":\"XX\",\"log_shift\":\"1\",\"log_date\":null,\"log_ip\":\"127.0.0.1\",\"times\":0,\"logmark\":0,\"rmcode\":null,\"mkt\":null,\"src\":null,\"isowner\":\"F\",\"createdate\":\"2023-05-05T00:00:00\",\"PERNR\":\"00281800\",\"WERKS\":\"1560\",\"ZSTATUS\":\"5\",\"KOSTL\":\"156020336\",\"ZZ_ZD\":\"3\",\"Z_ZJ\":\"T0\",\"STELL\":null,\"STELL_NM\":null,\"ZLZRQ\":\"2023-10-30T00:00:00\",\"MASSN\":\"ZD\",\"MNTXT\":\"离职\",\"MASSG\":null,\"MGTXT\":null,\"logdate\":\"2024-03-14T00:02:34\",\"updatelogdate\":null,\"guestno\":null,\"ZZ_KLX\":\"3\",\"DAT01\":null,\"ZZ_COUNNM\":null,\"ZZ_GZDJDNM\":\"海宁基地\",\"ZZ_GZDCQNM\":\"海宁尖山\"}"; - //var gainfos = new List() { pJson.ToObject() }; - var gainfos = await _dbContext.Queryable().ToListAsync(); - - return gainfos.Select(x => new SapPersonItem - { - NAME = x.gname, - ZWORKCODE = x.ename, - ZZ_SFZH = x.idno, - GBDAT = x.birthday, - ZZ_KLX = x.ZZ_KLX, - ZXUELI = x.email, - ORGEH = x.appellation, - ZMOBILE = x.phone, - ZSTATUS = x.ZSTATUS, - ZRZRQ = x.createdate, - 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, - MASSN = x.MASSN, - MNTXT = x.MNTXT, - ZZ_COUNNM = x.ZZ_COUNNM, - ZZ_GZDJDNM = x.ZZ_GZDJDNM, - ZZ_GZDCQNM = x.ZZ_GZDCQNM - }).ToList(); - } - - - private static List ToGainfoSap(List data) - { - return data.Select(person => - { - //var position = _positions.FirstOrDefault(x => x.No == person.PLANS); - - var rzrq = person.ZRZRQ; - var lzrq = person.ZLZRQ; - var rmk = $"入职时间:{rzrq.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} "; - - if (lzrq != null && lzrq.Value.ToString("yyyy-MM-dd") != "1900-01-01") - 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(); - GainfoSapEntity o = new() - { - gname = person.NAME, - ename = person.ZWORKCODE, - idno = person.ZZ_SFZH, - birthday = person.GBDAT, - ZZ_KLX = person.ZZ_KLX, - email = person.ZXUELI, - appellation = person.ORGEH, - phone = person.ZMOBILE, - ZSTATUS = person.ZSTATUS, - createdate = 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 = person.ZLZRQ, - MASSN = person.MASSN, - MNTXT = person.MNTXT, - remark = rmk, - native = native, - sex = sex, - logdate = DateTime.Now, - isowner = int.Parse(person.ZSTATUS) < 5 ? "T" : "F", - @class = "C", - country = person.ZZ_COUNNM, - log_ip = "127.0.0.1", - log_shift = "1", - log_id = "XX", - address = "", - occupation = "99", - nation = "01", - idcls = "ID", - ZZ_COUNNM = person.ZZ_COUNNM, - ZZ_GZDJDNM = person.ZZ_GZDJDNM, - ZZ_GZDCQNM = person.ZZ_GZDCQNM, - }; - - return o; - }).ToList(); - } - - private static string GetNative(string idNo) - { - if (string.IsNullOrWhiteSpace(idNo) || idNo.Length < 6) return null; - idNo = idNo.TrimStart(); - return idNo[..6]; - } - - private static int? SafeParseCardType(string ZZ_KLX) - { - if (int.TryParse(ZZ_KLX, out var cardType)) - { - return cardType; - } - - return null; - } -} \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoJIPService.cs b/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoJIPService.cs index 88d207b2..047f2b94 100644 --- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoJIPService.cs +++ b/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoJIPService.cs @@ -32,16 +32,11 @@ public class JinkoJipService : IJinkoJipService return httpClient; } - public async Task UploadAttendancesAsync(List requests) + public async Task UploadAttendancesAsync(UploadAttendanceRequest request) { var requestUrl = "/JIP/HCM/HCM_SWIPE_DATA_SAVE"; - var body = new - { - T_DATA = requests, - }; - - var json = body.ToJson(); + var json = request.ToJson(); //_logger.LogInformation("上传考勤记录请求:{json}", json);