diff --git a/Src/Dlhis.ScheduledTask/Entities/GainfoSap.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs similarity index 98% rename from Src/Dlhis.ScheduledTask/Entities/GainfoSap.cs rename to Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs index 5a7b95e9..b9081d8e 100644 --- a/Src/Dlhis.ScheduledTask/Entities/GainfoSap.cs +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs @@ -1,6 +1,6 @@ using SqlSugar; -namespace Dlhis.ScheduledTask.Entities; +namespace Dlhis.Entity.Basic.Entity; [SugarTable(TableName = "GainfoSap")] public class GainfoSapEntity diff --git a/Src/Dlhis.Entity/Basic/Entity/PositionEntity.cs b/Src/Dlhis.Entity/Basic/Entity/PositionEntity.cs new file mode 100644 index 00000000..7dfb3d33 --- /dev/null +++ b/Src/Dlhis.Entity/Basic/Entity/PositionEntity.cs @@ -0,0 +1,35 @@ +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Basic.Entity; + +/// +/// 职位表 +/// +[SugarTable(TableName = "Position", TableDescription = "职位表")] +public class PositionEntity : SugarBaseEntity +{ + /// + /// 岗位编码 + /// + [SugarColumn(ColumnDescription = "岗位编码")] + public string No { get; set; } + + /// + /// 岗位名称 + /// + [SugarColumn(ColumnDescription = "岗位名称")] + public string Name { get; set; } + + /// + /// 职等 + /// + [SugarColumn(ColumnDescription = "职等")] + public string Grade { get; set; } + + /// + /// 所属部门ID + /// + [SugarColumn(ColumnDescription = "所属部门ID")] + public string DepartmentNo { get; set; } +} diff --git a/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_01Entity.cs b/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_01Entity.cs deleted file mode 100644 index 7d4f540c..00000000 --- a/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_01Entity.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Dlhis.Entity; -using Kurisu.SqlSugar; -using SqlSugar; - -namespace Dlhis.ScheduledTask.Entities -{ - /// - /// 部门 - /// - [SugarTable(TableName = "T_ORG", TableDescription = "部门表")] - public class ZHRF_SYN_01Entity : SugarBaseEntity - { - /// - /// 开始日期 - /// - [SugarColumn(ColumnDescription = "开始日期")] - public string BEGDA { get; set; } - - /// - /// 结束日期 - /// - [SugarColumn(ColumnDescription = "结束日期")] - public string ENDDA { get; set; } - - /// - /// 语言代码 - /// - [SugarColumn(ColumnDescription = "语言代码")] - public int LANGU { get; set; } - - /// - /// 部门id - /// - [SugarColumn(ColumnDescription = "部门id")] - public int OBJID { get; set; } - - /// - /// 部门名称 - /// - [SugarColumn(ColumnDescription = "部门名称")] - public string STEXT { get; set; } - - /// - /// 上级部门 - /// - [SugarColumn(ColumnDescription = "上级部门")] - public string SOBID { get; set; } - - /// - /// 部门层级 - /// - [SugarColumn(ColumnDescription = "部门层级")] - public string ZZ_BMCJ { get; set; } - - /// - /// 公司 - /// - [SugarColumn(ColumnDescription = "公司")] - public string ORGID01 { get; set; } - - /// - /// 事业部 - /// - [SugarColumn(ColumnDescription = "事业部")] - public string ORGID02 { get; set; } - - /// - /// 一级部门 - /// - [SugarColumn(ColumnDescription = "一级部门")] - public string ORGID03 { get; set; } - - /// - /// 二级部门 - /// - [SugarColumn(ColumnDescription = "二级部门")] - public string ORGID04 { get; set; } - - /// - /// 三级部门 - /// - [SugarColumn(ColumnDescription = "三级部门")] - public string ORGID05 { get; set; } - - /// - /// 四级部门 - /// - [SugarColumn(ColumnDescription = "四级部门")] - - public string ORGID06 { get; set; } - } - - -} diff --git a/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_02Entity.cs b/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_02Entity.cs deleted file mode 100644 index fb39d37d..00000000 --- a/Src/Dlhis.Entity/Basic/Entity/ZHRF_SYN_02Entity.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Dlhis.Entity; -using Kurisu.SqlSugar; -using SqlSugar; - -namespace Dlhis.ScheduledTask.Entities -{ - /// - /// 职位表 - /// - [SugarTable(TableName = "T_POST", TableDescription = "职位表")] - public class ZHRF_SYN_02Entity : SugarBaseEntity - { - /// - /// 开始日期 - /// - [SugarColumn(ColumnDescription = "开始日期")] - public string BEGDA { get; set; } - - /// - /// 结束日期 - /// - [SugarColumn(ColumnDescription = "结束日期")] - public string ENDDA { get; set; } - - /// - /// 语言代码 - /// - [SugarColumn(ColumnDescription = "语言代码")] - public int LANGU { get; set; } - - /// - /// 岗位编码 - /// - [SugarColumn(ColumnDescription = "岗位编码")] - public string ZJOBID { get; set; } - - /// - /// 岗位名称 - /// - [SugarColumn(ColumnDescription = "岗位名称")] - public string ZJOBANME { get; set; } - - /// - /// 职等 - /// - [SugarColumn(ColumnDescription = "职等")] - public string ZJOBACTID { get; set; } - - /// - /// 所属部门ID - /// - [SugarColumn(ColumnDescription = "所属部门ID")] - public string ZDEPID { get; set; } - } -} diff --git a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_ORGComparer.cs b/Src/Dlhis.ScheduledTask/Comparers/ZHRS_ORGComparer.cs deleted file mode 100644 index 6b13097c..00000000 --- a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_ORGComparer.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Dlhis.ScheduledTask.Entities; -using Dlhis.ScheduledTask.Extensions; - -namespace Dlhis.ScheduledTask.Comparers -{ - internal class ZHRS_ORGComparer : IEqualityComparer - { - public bool Equals(ZHRS_ORG x, ZHRS_ORG y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false; - if (x.GetType() != y.GetType()) return false; - - return x.BEGDA == y.BEGDA - && x.ENDDA == y.ENDDA - && x.LANGU == y.LANGU - && x.OBJID == y.OBJID - && x.STEXT == y.STEXT - && x.SOBID == y.SOBID - && x.ORGID01 == y.ORGID01 - && x.ORGID02 == y.ORGID02; - } - - public int GetHashCode(ZHRS_ORG obj) - { - return obj.BEGDA.SafeGetHashCode() ^ obj.ENDDA.SafeGetHashCode() - ^ obj.LANGU.SafeGetHashCode() ^ obj.OBJID.SafeGetHashCode() - ^ obj.STEXT.SafeGetHashCode() ^ obj.SOBID.SafeGetHashCode() - ^ obj.ORGID01.SafeGetHashCode() ^ obj.ORGID02.SafeGetHashCode(); - } - } - -} diff --git a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_PERSONComparer.cs b/Src/Dlhis.ScheduledTask/Comparers/ZHRS_PERSONComparer.cs deleted file mode 100644 index 3ac15c41..00000000 --- a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_PERSONComparer.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Dlhis.ScheduledTask.Dto; -using Dlhis.ScheduledTask.Extensions; -using System.Text; - -namespace Dlhis.ScheduledTask.Comparers -{ - internal class ZHRS_PERSONComparer : IEqualityComparer - { - public bool Equals(PersonDetail x, PersonDetail y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null)) return false; - if (ReferenceEquals(y, null)) return false; - - return x.PERNR == y.PERNR - && x.WERKS == y.WERKS - && SubString(x.ORGEH, 10) == SubString(y.ORGEH, 10) - && SubString(x.NAME, 50) == SubString(y.NAME, 50) - && SafeParseDate(x.GBDAT) == SafeParseDate(y.GBDAT) - && SubString(x.ZZ_SFZH, 18) == SubString(y.ZZ_SFZH, 18) - && SubString(x.ZWORKCODE, 50) == SubString(y.ZWORKCODE, 50) - && SubString(x.ZMOBILE, 20) == SubString(y.ZMOBILE, 20) - && x.ZSTATUS == y.ZSTATUS - && x.KOSTL == y.KOSTL - && x.ZZ_ZD == y.ZZ_ZD - && x.Z_ZJ == y.Z_ZJ - && x.ZRZRQ == y.ZRZRQ - && SafeParseDate(x.ZLZRQ) == SafeParseDate(y.ZLZRQ) - && x.STELL == y.STELL - && x.STELL_NM == y.STELL_NM - && x.MASSN == y.MASSN - && x.MNTXT == y.MNTXT - && (x.ZXUELI ?? string.Empty).Trim() == (y.ZXUELI ?? string.Empty).Trim() - && (x.ZZ_KLX ?? string.Empty) == (y.ZZ_KLX ?? string.Empty); - } - - public int GetHashCode(PersonDetail obj) - { - return obj.PERNR.SafeGetHashCode() - ^ obj.WERKS.SafeGetHashCode() - ^ SubString(obj.ORGEH, 10).SafeGetHashCode() - ^ SubString(obj.NAME, 50).SafeGetHashCode() - ^ SafeParseDate(obj.GBDAT).SafeGetHashCode() - ^ SubString(obj.ZZ_SFZH, 18).SafeGetHashCode() - ^ SubString(obj.ZWORKCODE, 50).SafeGetHashCode() - ^ SubString(obj.ZMOBILE, 20).SafeGetHashCode() - ^ obj.ZSTATUS.SafeGetHashCode() - ^ obj.KOSTL.SafeGetHashCode() - ^ obj.ZZ_ZD.SafeGetHashCode() - ^ obj.Z_ZJ.SafeGetHashCode() - ^ obj.ZRZRQ.SafeGetHashCode() - ^ SafeParseDate(obj.ZLZRQ).SafeGetHashCode() - ^ obj.STELL.SafeGetHashCode() - ^ obj.STELL_NM.SafeGetHashCode() - ^ obj.MASSN.SafeGetHashCode() - ^ obj.MNTXT.SafeGetHashCode() - ^ obj.ZXUELI.SafeGetHashCode() - ^ (obj.ZZ_KLX ?? "").SafeGetHashCode(); - } - - - 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 DateTime? SafeParseDate(string str) - { - if (str == "0000-00-00" || str == "0001-01-01" || str == "1900-01-01") - return null; - - if (DateTime.TryParse(str, out var d)) - { - return d; - } - return null; - } - } -} diff --git a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_POSTComparer.cs b/Src/Dlhis.ScheduledTask/Comparers/ZHRS_POSTComparer.cs deleted file mode 100644 index a52890e3..00000000 --- a/Src/Dlhis.ScheduledTask/Comparers/ZHRS_POSTComparer.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Dlhis.ScheduledTask.Entities; -using Dlhis.ScheduledTask.Extensions; - -namespace Dlhis.ScheduledTask.Comparers -{ - internal class ZHRS_POSTComparer : IEqualityComparer - { - public bool Equals(ZHRS_POST x, ZHRS_POST y) - { - if (ReferenceEquals(x, y)) return true; - if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false; - if (x.GetType() != y.GetType()) return false; - - return x.BEGDA == y.BEGDA - && x.ENDDA == y.ENDDA - && x.LANGU == y.LANGU - && x.ZJOBID == y.ZJOBID - && x.ZJOBANME == y.ZJOBANME - && x.ZZWID == y.ZZWID - && x.ZDEPID == y.ZDEPID; - } - - public int GetHashCode(ZHRS_POST obj) - { - return obj.BEGDA.SafeGetHashCode() ^ obj.ENDDA.SafeGetHashCode() - ^ obj.LANGU.SafeGetHashCode() ^ obj.ZJOBID.SafeGetHashCode() - ^ obj.ZJOBANME.SafeGetHashCode() ^ obj.ZZWID.SafeGetHashCode() - ^ obj.ZDEPID.SafeGetHashCode(); - } - } - -} diff --git a/Src/Dlhis.ScheduledTask/Configurations/ServiceSettings.cs b/Src/Dlhis.ScheduledTask/Configurations/ServiceSettings.cs deleted file mode 100644 index 6e904403..00000000 --- a/Src/Dlhis.ScheduledTask/Configurations/ServiceSettings.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Kurisu.Core.ConfigurableOptions.Attributes; - - -namespace Dlhis.ScheduledTask.Configurations -{ - [Configuration] - public class ServiceSettings - { - public string ServerUrl { get; private set; } - - public string UserName { get; private set; } - - public string Password { get; private set; } - - public string SyncTime { get; private set; } - public int AttendanceUploadInterval { get; private set; } - public string AttendanceUploadUrl { get; private set; } - public string DlhisDatabase { get; private set; } - - public string Werks { get; private set; } - - public DateTime BeginSyncDate { get; private set; } - public int ApiPort { get; private set; } - public string EHRWebServiceUserName { get; set; } - public string EHRWebServicePassword { get; set; } - public string EHRInsertRecordApiUrl { get; set; } - public string EHRDeleteRecordApiUrl { get; set; } - - public string EHRSavePhotoApiUrl { get; set; } - - - /// - /// 获取员工卡片信息RESUT地址 - /// - public string EHR_GET_WORK_CARD_INFOApiUrl { get; set; } - - /// - /// REST账号 - /// - public string RestUserName { get; set; } - - /// - /// REST密码 - /// - public string RestPassword { get; set; } - - - private static int SafeParseInt(string value, int defaultValue = 0) - { - if (int.TryParse(value, out int i)) - { - return i; - } - return defaultValue; - } - - private static bool SafeParseBoolean(string value, bool defaultValue = false) - { - if (bool.TryParse(value, out var b)) - { - return b; - } - return defaultValue; - } - - private static DateTime SafeParseDate(string value, DateTime defaultValue) - { - if (DateTime.TryParse(value, out var b)) - { - return b; - } - return defaultValue; - } - } -} diff --git a/Src/Dlhis.ScheduledTask/ContainerJobActivator.cs b/Src/Dlhis.ScheduledTask/ContainerJobActivator.cs new file mode 100644 index 00000000..e64e06a6 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/ContainerJobActivator.cs @@ -0,0 +1,18 @@ +using Hangfire; + +namespace Dlhis.ScheduledTask; + +public class ContainerJobActivator : JobActivator +{ + private readonly IServiceProvider _serviceProvider; + + public ContainerJobActivator(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public override object ActivateJob(Type job) + { + return _serviceProvider.GetService(job); + } +} \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj b/Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj index 9a01f7a6..6d66acaf 100644 --- a/Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj +++ b/Src/Dlhis.ScheduledTask/Dlhis.ScheduledTask.csproj @@ -26,6 +26,7 @@ + diff --git a/Src/Dlhis.ScheduledTask/Dto/Person.cs b/Src/Dlhis.ScheduledTask/Dto/Person.cs deleted file mode 100644 index 8ee5479f..00000000 --- a/Src/Dlhis.ScheduledTask/Dto/Person.cs +++ /dev/null @@ -1,203 +0,0 @@ -namespace Dlhis.ScheduledTask.Dto -{ - public class PersonDetail - { - public string KOSTL { get; set; } - - public string ZLZRQ { get; set; } - public string ZZ_SFZH { get; set; } - - public string STELL { get; set; } - - public string STELL_NM { get; set; } - - public string ZZ_KLX { get; set; } - - /// - /// - /// - public string PERNR { get; set; } - /// - /// - /// - public string ZWORKCODE { get; set; } - /// - /// - /// - public string MASSN { get; set; } - /// - /// 数据变更 - /// - public string MNTXT { get; set; } - /// - /// - /// - public string MASSG { get; set; } - /// - /// 数据变更 - /// - public string MGTXT { get; set; } - /// - /// - /// - public string ZSTATUS { get; set; } - /// - /// - /// - public string STAT2 { get; set; } - /// - /// - /// - public string BEGDA { get; set; } - /// - /// - /// - public string ENDDA { get; set; } - /// - /// - /// - public string WERKS { get; set; } - /// - /// - /// - public string PERSG { get; set; } - /// - /// - /// - public string PERSK { get; set; } - /// - /// - /// - public string BTRTL { get; set; } - /// - /// - /// - public string ANSVH { get; set; } - /// - /// - /// - public string MOABW { get; set; } - /// - /// - /// - public string ORGEH { get; set; } - /// - /// - /// - public string PLANS { get; set; } - /// - /// - /// - public string ZZ_ZYSF { get; set; } - /// - /// - /// - public string ZZ_AQJB { get; set; } - /// - /// - /// - public string ZZ_ZD { get; set; } - /// - /// - /// - public string ZZ_SJGH { get; set; } - /// - /// - /// - public string ZZ_BGZT { get; set; } - /// - /// - /// - public string Z_ZJ { get; set; } - /// - /// - /// - public string ZZ_XSQY { get; set; } - /// - /// 上海 - /// - public string ZZ_LOC { get; set; } - /// - /// - /// - public string ZZ_COUN { get; set; } - /// - /// - /// - public string ZZ_CITY { get; set; } - /// - /// - /// - public string NACHN { get; set; } - /// - /// - /// - public string VORNA { get; set; } - /// - /// - /// - public string NAME { get; set; } - /// - /// - /// - public string GESCH { get; set; } - /// - /// - /// - public string GBDAT { get; set; } - /// - /// - /// - public string NATIO { get; set; } - /// - /// - /// - public string ZZ_QFRQ { get; set; } - /// - /// - /// - public string ZMOBILE { get; set; } - /// - /// - /// - public string ZEMAIL { get; set; } - /// - /// - /// - public string ZADZH { get; set; } - /// - /// - /// - public string ZRZRQ { get; set; } - /// - /// - /// - public string DAT01 { get; set; } - /// - /// - /// - public string ZCJRQ { get; set; } - /// - /// - /// - public string ZZZRQ { get; set; } - /// - /// 本科 - /// - public string ZXUELI { get; set; } - /// - /// - /// - public string ZZ_ZPQD { get; set; } - } - - public class T_PERSON - { - /// - /// - /// - public List item { get; set; } - } - - -} diff --git a/Src/Dlhis.ScheduledTask/Entities/ZHRS_ORG.cs b/Src/Dlhis.ScheduledTask/Entities/ZHRS_ORG.cs deleted file mode 100644 index 387783d9..00000000 --- a/Src/Dlhis.ScheduledTask/Entities/ZHRS_ORG.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Security.Cryptography; - -namespace Dlhis.ScheduledTask.Entities -{ - public partial class ZHRS_ORG - { - /// - /// 开始日期 - /// - public string BEGDA { get; set; } - - /// - /// 结束日期 - /// - public string ENDDA { get; set; } - - /// - /// 语言 - /// - public int LANGU { get; set; } - - /// - /// 部门id - /// - public int OBJID { get; set; } - - /// - /// 部门名称 - /// - public string STEXT { get; set; } - - /// - /// 上级部门 - /// - public string SOBID { get; set; } - - /// - /// 公司 - /// - public string ORGID01 { get; set; } - - /// - /// 事业部 - /// - public string ORGID02 { get; set; } - } - public partial class ZHRS_ORG : IEquatable - { - public bool Equals(ZHRS_ORG other) - { - if (other is null) - return false; - - return this.BEGDA == other.BEGDA - && this.ENDDA == other.ENDDA - && this.LANGU == other.LANGU - && this.OBJID == other.OBJID - && this.STEXT == other.STEXT - && this.SOBID == other.SOBID - && this.ORGID01 == other.ORGID01 - && this.ORGID02 == other.ORGID02; - } - - public override bool Equals(object obj) => Equals(obj as ZHRS_ORG); - public override int GetHashCode() => (BEGDA, ENDDA, LANGU, OBJID, STEXT, SOBID, ORGID01, ORGID02).GetHashCode(); - } - public class T_ORG - { - public List item { get; set; } - } - - public class ZHRS_ORGResult - { - public T_ORG T_ORG { get; set; } - } -} diff --git a/Src/Dlhis.ScheduledTask/Entities/ZHRS_POST.cs b/Src/Dlhis.ScheduledTask/Entities/ZHRS_POST.cs deleted file mode 100644 index 5788b8fa..00000000 --- a/Src/Dlhis.ScheduledTask/Entities/ZHRS_POST.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Dlhis.ScheduledTask.Entities -{ - public partial class ZHRS_POST - { - /// - /// 开始日期 - /// - public string BEGDA { get; set; } - - /// - /// 结束日期 - /// - public string ENDDA { get; set; } - - /// - /// 语言代码 - /// - public int LANGU { get; set; } - - /// - /// 岗位编码 - /// - public string ZJOBID { get; set; } - - /// - /// 岗位名称 - /// - public string ZJOBANME { get; set; } - - /// - /// - /// - public string ZZWID { get; set; } - - /// - /// 所属部门ID - /// - public string ZDEPID { get; set; } - } - - public partial class ZHRS_POST : IEquatable - { - public bool Equals(ZHRS_POST other) - { - if (other is null) - return false; - - return this.BEGDA == other.BEGDA - && this.ENDDA == other.ENDDA - && this.LANGU == other.LANGU - && this.ZJOBID == other.ZJOBID - && this.ZJOBANME == other.ZJOBANME - && this.ZZWID == other.ZZWID - && this.ZDEPID == other.ZDEPID; - } - - public override bool Equals(object obj) => Equals(obj as ZHRS_POST); - public override int GetHashCode() => (BEGDA, ENDDA, LANGU, ZJOBID, ZJOBANME, ZZWID, ZDEPID).GetHashCode(); - } - public class T_POST - { - public List item { get; set; } - } - - public class ZHRS_POSTResult - { - public T_POST T_POST { get; set; } - } -} diff --git a/Src/Dlhis.ScheduledTask/Extensions/GetHashCodeExtensions.cs b/Src/Dlhis.ScheduledTask/Extensions/GetHashCodeExtensions.cs deleted file mode 100644 index d0db1f4c..00000000 --- a/Src/Dlhis.ScheduledTask/Extensions/GetHashCodeExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Dlhis.ScheduledTask.Extensions -{ - internal static class GetHashCodeExtensions - { - public static int SafeGetHashCode(this object o) - { - if (o == null) return 0; - return o.GetHashCode(); - } - - public static int SafeGetHashCode(this int o) - { - return o.GetHashCode(); - } - } -} diff --git a/Src/Dlhis.ScheduledTask/Job/HangfireActivator.cs b/Src/Dlhis.ScheduledTask/Job/HangfireActivator.cs deleted file mode 100644 index 0ae96316..00000000 --- a/Src/Dlhis.ScheduledTask/Job/HangfireActivator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Hangfire; - -namespace Dlhis.ScheduledTask.Job -{ - public class HangfireActivator : JobActivator - { - private readonly IServiceProvider _serviceProvider; - - public HangfireActivator(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public override object? ActivateJob(Type jobType) - { - return _serviceProvider.GetService(jobType); - } - } -} diff --git a/Src/Dlhis.ScheduledTask/Job/SyncOrgInfoJob.cs b/Src/Dlhis.ScheduledTask/Job/SyncOrgInfoJob.cs deleted file mode 100644 index 3eeb7635..00000000 --- a/Src/Dlhis.ScheduledTask/Job/SyncOrgInfoJob.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Dlhis.ScheduledTask.Comparers; -using Dlhis.ScheduledTask.Entities; -using Kurisu.SqlSugar.Services; -using Mapster; -using System.Net.Http.Headers; -using System.Text; -using System.Text.Json; - -namespace Dlhis.ScheduledTask.Job -{ - /// - /// 部门同步定时任务 - /// - public class SyncOrgInfoJob - { - private List lastUpdatedOrgList = new List(); - private readonly IDbContext _dbContext; - - public SyncOrgInfoJob(IDbContext dbContext) - { - _dbContext = dbContext; - } - - - - public async Task SyncOrgInfo() - { - 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); - - string apiUrl = "http://sappidap.jinkosolar.cn:51000/RESTAdapter/Rest/EHR_ORGANIZATION/"; - - - string requestBody = "{\"I_DATE\":\"2021-01-01\",\"I_DATE_TO\":\"2022-05-29\",\"I_LANGU\":\"1\",\"T_ID\":{\"item\":[{\"OBJID\":\"50007967\"},{\"OBJID\":\"50008308\"}]}}"; - - HttpResponseMessage response = await httpClient.PostAsync(apiUrl, new StringContent(requestBody, Encoding.UTF8, "application/json")); - - if (response.IsSuccessStatusCode) - { - string responseData = await response.Content.ReadAsStringAsync(); - ZHRS_ORGResult orgResult = JsonSerializer.Deserialize(responseData); - - if (orgResult.T_ORG != null && orgResult.T_ORG.item.Count > 0) - { - var modifiedOrgList = GetModifiedOrg(orgResult.T_ORG?.item); - - // 使用 SQLSugar 将新数据同步到数据库 - await SaveOrg(modifiedOrgList); - } - //} - //else - //{ - // Console.WriteLine($"HTTP请求失败,状态码:{response.StatusCode}"); - } - } - - private List GetModifiedOrg(List sapList) - { - if (lastUpdatedOrgList.Count <= 0) - { - return sapList; - } - - var needRemove = sapList.Intersect(lastUpdatedOrgList, new ZHRS_ORGComparer()); - return sapList.Except(needRemove, new ZHRS_ORGComparer()).ToList(); - } - - private async Task SaveOrg(List modifiedOrgList) - { - if (modifiedOrgList == null || modifiedOrgList.Count == 0) return; - - foreach (ZHRS_ORG item in modifiedOrgList) - { - var existingOrgs = await _dbContext.Queryable().Where(x => x.OBJID == item.OBJID).FirstAsync(); - - if (existingOrgs != null) - { - var org = item.Adapt(existingOrgs); - await _dbContext.UpdateAsync(org); - } - else - { - var org = item.Adapt(); - await _dbContext.InsertAsync(org); - } - } - } - } -} diff --git a/Src/Dlhis.ScheduledTask/Job/SyncPersonJob.cs b/Src/Dlhis.ScheduledTask/Job/SyncPersonJob.cs deleted file mode 100644 index 7caca96a..00000000 --- a/Src/Dlhis.ScheduledTask/Job/SyncPersonJob.cs +++ /dev/null @@ -1,452 +0,0 @@ -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.Entity.Basic.Enums; - -namespace Dlhis.ScheduledTask.Job -{ - public class SyncPersonJob - { - - private List lastUpdatedPersonList = new List(); - private List lastUpdatedOrgList = new List(); - private List lastUpdatedPositionList = new List(); - private readonly ServiceSettings serviceSettings; - - private readonly IDbContext _dbContext; - public SyncPersonJob(IDbContext dbContext) - { - _dbContext = dbContext; - } - - public void SyncPersonInfo() - { - try - { - //var personResp = JsonConvert.DeserializeObject(File.ReadAllText("C:\\Users\\79144\\Desktop\\request.json")); // GetPersons(); - var personResp = GetPersons();// JsonConvert.DeserializeObject(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 SavePerson(List 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($"select ename from gainfo_sap where ename in ( {string.Join(",", searchCodes.Select(x => $"'{x}'"))} )") - // .ToList(); - var existsWorkCodes = _dbContext.Queryable() - .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(GainfoSapEntity item) - { - var gainfo = await _dbContext.Queryable().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().Where(x => x.IdNo == item.idno).FirstAsync(); - if (gainfo != null) - { - _dbContext.Updateable().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().Any(g => g.IdNo == item.idno && g.SapNo != item.PERNR && g.Employed == "T") - && !_dbContext.Queryable().Any(g => g.IdNo == item.idno && int.Parse(g.SapNo) > int.Parse(item.PERNR) && g.Employed == item.isowner)); - } - else - { - _dbContext.Updateable().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().Any(g => g.Code == item.ename && g.Employed == "T") - && !_dbContext.Queryable().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 persons = new(); - //foreach (var item in werks) - //{ - // try - // { - // var body = new - // { - // T_WERKS = new - // { - // item = new List - // { - // new - // { - // item.WERKS - // } - // } - // }, - // T_PERSON = Array.Empty(), - // T_PNO = Array.Empty(), - // }; - // 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(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(), - // // T_PNO = Array.Empty(), - // // 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 GetModifiedPerson(List 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 ToGainfoSap(List data) - { - return data.Select(person => - { - GainfoSapEntity 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 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), - 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); - } - } - } - -} \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/Job/SyncPositionJob.cs b/Src/Dlhis.ScheduledTask/Job/SyncPositionJob.cs deleted file mode 100644 index 2ef108bb..00000000 --- a/Src/Dlhis.ScheduledTask/Job/SyncPositionJob.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Dlhis.ScheduledTask.Comparers; -using Dlhis.ScheduledTask.Entities; -using Kurisu.SqlSugar.Services; -using Mapster; -using Newtonsoft.Json; -using System.Net.Http.Headers; -using System.Text; - -namespace Dlhis.ScheduledTask.Job -{ - /// - /// 职位同步定时任务 - /// - public class SyncPositionJob - { - private List lastUpdatedPositionList = new List(); - private readonly IDbContext _dbContext; - - public SyncPositionJob(IDbContext dbContext) - { - _dbContext = dbContext; - } - public async Task SyncPositionInfo() - { - 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); - - string url = "http://sappidap.jinkosolar.cn:51000/RESTAdapter/Rest/EHR_POSITION/"; - - string requestBody = "{\"I_DATE\":\"2022-05-26\",\"I_DATE_TO\":\"2022-05-29\",\"I_LANGU\":\"1\",\"I_ALLINFO\":\"X\"}"; - - StringContent content = new StringContent(requestBody, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await httpClient.PostAsync(url, content); - - if (response.IsSuccessStatusCode) - { - string responseContent = await response.Content.ReadAsStringAsync(); - var postResult = JsonConvert.DeserializeObject(responseContent); - - if (postResult.T_POST != null && postResult.T_POST.item.Count > 0) - { - var modifiedOrgList = GetModifiedPosition(postResult.T_POST.item); - - // 步骤 4:使用 SQLSugar 将新数据同步到数据库 - SaveOrg(modifiedOrgList); - } - } - else - { - Console.WriteLine($"HTTP请求失败,状态码:{response.StatusCode}"); - } - } - - private List GetModifiedPosition(List spaList) - { - if (lastUpdatedPositionList.Count <= 0) - { - return spaList; - } - var needRemove = spaList.Intersect(lastUpdatedPositionList, new ZHRS_POSTComparer()); - return spaList.Except(needRemove, new ZHRS_POSTComparer()).ToList(); - } - private async void SaveOrg(List modifiedPostList) - { - if (modifiedPostList == null || modifiedPostList.Count == 0) return; - - foreach (var item in modifiedPostList) - { - var existingPosts = await _dbContext.Queryable().Where(x =>x.ZJOBID == item.ZJOBID).FirstAsync(); - if (existingPosts != null) - { - var entity = item.Adapt(existingPosts); - await _dbContext.UpdateAsync(entity); - } - else - { - var entity = item.Adapt(); - await _dbContext.InsertAsync(entity); - } - } - - - } - } -} diff --git a/Src/Dlhis.ScheduledTask/Job/UseHangfire.cs b/Src/Dlhis.ScheduledTask/Job/UseHangfire.cs deleted file mode 100644 index a295802f..00000000 --- a/Src/Dlhis.ScheduledTask/Job/UseHangfire.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Hangfire; - -namespace Dlhis.ScheduledTask.Job; - -public static class UseHangfire -{ - public static void UseHangfireto(this IServiceCollection services) - { - GlobalConfiguration.Configuration.UseActivator(new HangfireActivator(services.BuildServiceProvider())); - } -} diff --git a/Src/Dlhis.ScheduledTask/Packs/HangfirePack.cs b/Src/Dlhis.ScheduledTask/Packs/HangfirePack.cs index 7cf91214..81ee379c 100644 --- a/Src/Dlhis.ScheduledTask/Packs/HangfirePack.cs +++ b/Src/Dlhis.ScheduledTask/Packs/HangfirePack.cs @@ -1,5 +1,4 @@ -using Dlhis.ScheduledTask.Configurations; -using Dlhis.ScheduledTask.Job; +using Dlhis.ScheduledTask.SyncSapInfo.Job; using Hangfire; using Hangfire.Dashboard.BasicAuthorization; using Hangfire.MySql; @@ -10,17 +9,17 @@ namespace Dlhis.ScheduledTask.Packs; public class HangfirePack : BaseAppPack { + public override int Order => 999; + public override bool IsBeforeUseRouting { get; } public override void ConfigureServices(IServiceCollection services) { - - services.Configure(Configuration.GetSection("ServiceSettings")); services.AddHangfire(configuration => { var options = new MySqlStorageOptions { - TablesPrefix = "Hangfire" + TablesPrefix = "hangfire" }; configuration.UseSimpleAssemblyNameTypeSerializer() @@ -28,12 +27,13 @@ public class HangfirePack : BaseAppPack .UseStorage(new MySqlStorage(Configuration.GetConnectionString("HangfireConnection"), options)); }); - services.UseHangfireto(); - services.AddHangfireServer(); + + services.AddHangfireServer(); } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + GlobalConfiguration.Configuration.UseActivator(new ContainerJobActivator(app.ApplicationServices)); app.UseHangfireDashboard("/hangfire", new DashboardOptions { @@ -61,13 +61,10 @@ public class HangfirePack : BaseAppPack #region 周期任务 //0:00 - RecurringJob.AddOrUpdate("SyncOrgInfoJob_id", s => s.SyncOrgInfo(), "0 0 16 * * ?"); - - //1:00 - RecurringJob.AddOrUpdate("SyncPositionJob_id", s => s.SyncPositionInfo(), "0 0 17 * * ?"); - - //2:00 - RecurringJob.AddOrUpdate("SyncPersonJob_id", s => s.SyncPersonInfo(), "0 0 18 * * ?"); + RecurringJob.AddOrUpdate("SysSap", s => s.SyncOrgInfo(), "30 * * * * ?", new RecurringJobOptions + { + TimeZone = TimeZoneInfo.Local + }); #endregion } } diff --git a/Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs b/Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs new file mode 100644 index 00000000..3d865cc7 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs @@ -0,0 +1,22 @@ +using System.Net.Http.Headers; +using System.Text; +using Kurisu.AspNetCore.Startup; + +namespace Dlhis.ScheduledTask.Packs; + +public class JinkoSapHttpClientPack : BaseAppPack +{ + public override bool IsBeforeUseRouting { get; } + + public override void ConfigureServices(IServiceCollection services) + { + services.AddHttpClient("jinko:sap", (sp, 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); + }); + } +} diff --git a/Src/Dlhis.ScheduledTask/Response/PersonResult.cs b/Src/Dlhis.ScheduledTask/Response/PersonResult.cs deleted file mode 100644 index 2464d1de..00000000 --- a/Src/Dlhis.ScheduledTask/Response/PersonResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Dlhis.ScheduledTask.Dto; - -namespace Dlhis.ScheduledTask.Response -{ - public class PersonResult - { - /// - /// - /// - public T_PERSON T_PERSON { get; set; } - } -} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapOrgComparer.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapOrgComparer.cs new file mode 100644 index 00000000..da2ef800 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapOrgComparer.cs @@ -0,0 +1,33 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Comparers; + +/// +/// 机构数据比较器 +/// +public class SapOrganizationComparer : IEqualityComparer +{ + public bool Equals(SapOrganizationItem x, SapOrganizationItem y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false; + if (x.GetType() != y.GetType()) return false; + + return x.BEGDA == y.BEGDA + && x.ENDDA == y.ENDDA + && x.LANGU == y.LANGU + && x.OBJID == y.OBJID + && x.STEXT == y.STEXT + && x.SOBID == y.SOBID + && x.ORGID01 == y.ORGID01 + && x.ORGID02 == y.ORGID02; + } + + public int GetHashCode(SapOrganizationItem obj) + { + return obj.BEGDA.SafeGetHashCode() ^ obj.ENDDA.SafeGetHashCode() + ^ obj.LANGU.SafeGetHashCode() ^ obj.OBJID.SafeGetHashCode() + ^ obj.STEXT.SafeGetHashCode() ^ obj.SOBID.SafeGetHashCode() + ^ obj.ORGID01.SafeGetHashCode() ^ obj.ORGID02.SafeGetHashCode(); + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPersonComparer.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPersonComparer.cs new file mode 100644 index 00000000..f0caf571 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPersonComparer.cs @@ -0,0 +1,93 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using System.Text; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Comparers; + +/// +/// 人员信息比较器 +/// +public class SapPersonComparer : IEqualityComparer +{ + public bool Equals(SapPersonItem x, SapPersonItem y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + + return x.PERNR == y.PERNR + && x.WERKS == y.WERKS + && SubString(x.ORGEH, 10) == SubString(y.ORGEH, 10) + && SubString(x.NAME, 50) == SubString(y.NAME, 50) + && SafeParseDate(x.GBDAT) == SafeParseDate(y.GBDAT) + && SubString(x.ZZ_SFZH, 18) == SubString(y.ZZ_SFZH, 18) + && SubString(x.ZWORKCODE, 50) == SubString(y.ZWORKCODE, 50) + && SubString(x.ZMOBILE, 20) == SubString(y.ZMOBILE, 20) + && x.ZSTATUS == y.ZSTATUS + && x.KOSTL == y.KOSTL + && x.ZZ_ZD == y.ZZ_ZD + && x.Z_ZJ == y.Z_ZJ + && x.ZRZRQ == y.ZRZRQ + && SafeParseDate(x.ZLZRQ) == SafeParseDate(y.ZLZRQ) + && x.STELL == y.STELL + && x.STELL_NM == y.STELL_NM + && x.MASSN == y.MASSN + && x.MNTXT == y.MNTXT + && (x.ZXUELI ?? string.Empty).Trim() == (y.ZXUELI ?? string.Empty).Trim() + && (x.ZZ_KLX ?? string.Empty) == (y.ZZ_KLX ?? string.Empty); + } + + public int GetHashCode(SapPersonItem obj) + { + return obj.PERNR.SafeGetHashCode() + ^ obj.WERKS.SafeGetHashCode() + ^ SubString(obj.ORGEH, 10).SafeGetHashCode() + ^ SubString(obj.NAME, 50).SafeGetHashCode() + ^ SafeParseDate(obj.GBDAT).SafeGetHashCode() + ^ SubString(obj.ZZ_SFZH, 18).SafeGetHashCode() + ^ SubString(obj.ZWORKCODE, 50).SafeGetHashCode() + ^ SubString(obj.ZMOBILE, 20).SafeGetHashCode() + ^ obj.ZSTATUS.SafeGetHashCode() + ^ obj.KOSTL.SafeGetHashCode() + ^ obj.ZZ_ZD.SafeGetHashCode() + ^ obj.Z_ZJ.SafeGetHashCode() + ^ obj.ZRZRQ.SafeGetHashCode() + ^ SafeParseDate(obj.ZLZRQ).SafeGetHashCode() + ^ obj.STELL.SafeGetHashCode() + ^ obj.STELL_NM.SafeGetHashCode() + ^ obj.MASSN.SafeGetHashCode() + ^ obj.MNTXT.SafeGetHashCode() + ^ obj.ZXUELI.SafeGetHashCode() + ^ (obj.ZZ_KLX ?? "").SafeGetHashCode(); + } + + + 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 DateTime? SafeParseDate(string str) + { + if (str == "0000-00-00" || str == "0001-01-01" || str == "1900-01-01") + return null; + + if (DateTime.TryParse(str, out var d)) + { + return d; + } + return null; + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPositionComparer.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPositionComparer.cs new file mode 100644 index 00000000..e52b1e77 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Comparers/SapPositionComparer.cs @@ -0,0 +1,32 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Comparers; + +/// +/// 岗位信息比较器 +/// +public class SapPositionComparer : IEqualityComparer +{ + public bool Equals(SapPositionItem x, SapPositionItem y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false; + if (x.GetType() != y.GetType()) return false; + + return x.BEGDA == y.BEGDA + && x.ENDDA == y.ENDDA + && x.LANGU == y.LANGU + && x.ZJOBID == y.ZJOBID + && x.ZJOBANME == y.ZJOBANME + && x.ZZWID == y.ZZWID + && x.ZDEPID == y.ZDEPID; + } + + public int GetHashCode(SapPositionItem obj) + { + return obj.BEGDA.SafeGetHashCode() ^ obj.ENDDA.SafeGetHashCode() + ^ obj.LANGU.SafeGetHashCode() ^ obj.ZJOBID.SafeGetHashCode() + ^ obj.ZJOBANME.SafeGetHashCode() ^ obj.ZZWID.SafeGetHashCode() + ^ obj.ZDEPID.SafeGetHashCode(); + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganization.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganization.cs new file mode 100644 index 00000000..2d10427b --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganization.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto; + +/// +/// sap机构信息 +/// +public class SapOrganization +{ + /// + /// 机构项 + /// + [JsonProperty("item")] + public List Items { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganizationItem.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganizationItem.cs new file mode 100644 index 00000000..8a4691e9 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapOrganizationItem.cs @@ -0,0 +1,66 @@ +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto; + +public class SapOrganizationItem +{ + /// + /// 开始日期 + /// + public string BEGDA { get; set; } + + /// + /// 结束日期 + /// + public string ENDDA { get; set; } + + /// + /// 语言 + /// + public int LANGU { get; set; } + + /// + /// 部门id + /// + public string OBJID { get; set; } + + /// + /// 部门名称 + /// + public string STEXT { get; set; } + + /// + /// 上级部门 + /// + public string SOBID { get; set; } + + /// + /// 公司 + /// + public string ORGID01 { get; set; } + + /// + /// 事业部 + /// + public string ORGID02 { get; set; } +} + + +//public partial class SapOrganizationItem : IEquatable +//{ +// public bool Equals(SapOrganizationItem other) +// { +// if (other is null) +// return false; + +// return this.BEGDA == other.BEGDA +// && this.ENDDA == other.ENDDA +// && this.LANGU == other.LANGU +// && this.OBJID == other.OBJID +// && this.STEXT == other.STEXT +// && this.SOBID == other.SOBID +// && this.ORGID01 == other.ORGID01 +// && this.ORGID02 == other.ORGID02; +// } + +// public override bool Equals(object obj) => Equals(obj as SapOrganizationItem); +// public override int GetHashCode() => (BEGDA, ENDDA, LANGU, OBJID, STEXT, SOBID, ORGID01, ORGID02).GetHashCode(); +//} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPerson.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPerson.cs new file mode 100644 index 00000000..a4a7db3c --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPerson.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto; + +public class SapPerson +{ + /// + /// + /// + [JsonProperty("item")] + public List Items { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPersonItem.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPersonItem.cs new file mode 100644 index 00000000..42561eb9 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPersonItem.cs @@ -0,0 +1,192 @@ +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto; + +public class SapPersonItem +{ + public string KOSTL { get; set; } + + public string ZLZRQ { get; set; } + public string ZZ_SFZH { get; set; } + + public string STELL { get; set; } + + public string STELL_NM { get; set; } + + public string ZZ_KLX { get; set; } + + /// + /// + /// + public string PERNR { get; set; } + /// + /// + /// + public string ZWORKCODE { get; set; } + /// + /// + /// + public string MASSN { get; set; } + /// + /// 数据变更 + /// + public string MNTXT { get; set; } + /// + /// + /// + public string MASSG { get; set; } + /// + /// 数据变更 + /// + public string MGTXT { get; set; } + /// + /// + /// + public string ZSTATUS { get; set; } + /// + /// + /// + public string STAT2 { get; set; } + /// + /// + /// + public string BEGDA { get; set; } + /// + /// + /// + public string ENDDA { get; set; } + /// + /// + /// + public string WERKS { get; set; } + /// + /// + /// + public string PERSG { get; set; } + /// + /// + /// + public string PERSK { get; set; } + /// + /// + /// + public string BTRTL { get; set; } + /// + /// + /// + public string ANSVH { get; set; } + /// + /// + /// + public string MOABW { get; set; } + /// + /// + /// + public string ORGEH { get; set; } + /// + /// + /// + public string PLANS { get; set; } + /// + /// + /// + public string ZZ_ZYSF { get; set; } + /// + /// + /// + public string ZZ_AQJB { get; set; } + /// + /// + /// + public string ZZ_ZD { get; set; } + /// + /// + /// + public string ZZ_SJGH { get; set; } + /// + /// + /// + public string ZZ_BGZT { get; set; } + /// + /// + /// + public string Z_ZJ { get; set; } + /// + /// + /// + public string ZZ_XSQY { get; set; } + /// + /// 上海 + /// + public string ZZ_LOC { get; set; } + /// + /// + /// + public string ZZ_COUN { get; set; } + /// + /// + /// + public string ZZ_CITY { get; set; } + /// + /// + /// + public string NACHN { get; set; } + /// + /// + /// + public string VORNA { get; set; } + /// + /// + /// + public string NAME { get; set; } + /// + /// + /// + public string GESCH { get; set; } + /// + /// + /// + public string GBDAT { get; set; } + /// + /// + /// + public string NATIO { get; set; } + /// + /// + /// + public string ZZ_QFRQ { get; set; } + /// + /// + /// + public string ZMOBILE { get; set; } + /// + /// + /// + public string ZEMAIL { get; set; } + /// + /// + /// + public string ZADZH { get; set; } + /// + /// + /// + public string ZRZRQ { get; set; } + /// + /// + /// + public string DAT01 { get; set; } + /// + /// + /// + public string ZCJRQ { get; set; } + /// + /// + /// + public string ZZZRQ { get; set; } + /// + /// 本科 + /// + public string ZXUELI { get; set; } + /// + /// + /// + public string ZZ_ZPQD { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPosition.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPosition.cs new file mode 100644 index 00000000..d8dbc0fe --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPosition.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto; + +public class SapPosition +{ + + [JsonProperty("item")] + public List Items { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPositionItem.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPositionItem.cs new file mode 100644 index 00000000..a22ed596 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Dto/SapPositionItem.cs @@ -0,0 +1,40 @@ +namespace Dlhis.ScheduledTask.SyncSapInfo.Dto +{ + public class SapPositionItem + { + /// + /// 开始日期 + /// + public string BEGDA { get; set; } + + /// + /// 结束日期 + /// + public string ENDDA { get; set; } + + /// + /// 语言代码 + /// + public int LANGU { get; set; } + + /// + /// 岗位编码 + /// + public string ZJOBID { get; set; } + + /// + /// 岗位名称 + /// + public string ZJOBANME { get; set; } + + /// + /// + /// + public string ZZWID { get; set; } + + /// + /// 所属部门ID + /// + public string ZDEPID { get; set; } + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/GetHashCodeExtensions.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/GetHashCodeExtensions.cs new file mode 100644 index 00000000..c0ffb779 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/GetHashCodeExtensions.cs @@ -0,0 +1,15 @@ +namespace Dlhis.ScheduledTask.SyncSapInfo; + +internal static class GetHashCodeExtensions +{ + public static int SafeGetHashCode(this object o) + { + if (o == null) return 0; + return o.GetHashCode(); + } + + public static int SafeGetHashCode(this int o) + { + return o.GetHashCode(); + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncOrganizationJob.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncOrganizationJob.cs new file mode 100644 index 00000000..593df3bd --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncOrganizationJob.cs @@ -0,0 +1,77 @@ +using Dlhis.Entity.Basic.Entity; +using Dlhis.ScheduledTask.SyncSapInfo.Comparers; +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Dlhis.ScheduledTask.SyncSapInfo.Services; +using Hangfire; +using Kurisu.SqlSugar.Services; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Job; + +/// +/// 部门同步定时任务 +/// +public class SyncOrganizationJob +{ + private List lastUpdatedOrgList = new(); + private readonly IDbContext _dbContext; + private readonly IJinkoSapService _jinkoSapService; + + public SyncOrganizationJob(IDbContext dbContext, IJinkoSapService jinkoSapService) + { + _dbContext = dbContext; + _jinkoSapService = jinkoSapService; + } + + public async Task SyncOrgInfo() + { + var orgResult = await _jinkoSapService.GetSapOrganizationsAsync(); + + if (orgResult.Org != null && orgResult.Org.Items.Count > 0) + { + var modifiedOrgList = GetModifiedOrg(orgResult.Org?.Items); + await SaveOrg(modifiedOrgList); + } + + var syncPositionJob = BackgroundJob.ContinueJobWith("SyncOrganizationJob", job => job.SyncPositionInfo(), JobContinuationOptions.OnlyOnSucceededState); + BackgroundJob.ContinueJobWith(syncPositionJob, job => job.SyncPersonInfo(), JobContinuationOptions.OnlyOnSucceededState); + } + + private List GetModifiedOrg(List sapList) + { + if (lastUpdatedOrgList.Count <= 0) + { + return sapList; + } + + var needRemove = sapList.Intersect(lastUpdatedOrgList, new SapOrganizationComparer()); + return sapList.Except(needRemove, new SapOrganizationComparer()).ToList(); + } + + private async Task SaveOrg(List modifiedOrgList) + { + if (modifiedOrgList == null || modifiedOrgList.Count == 0) return; + + foreach (SapOrganizationItem item in modifiedOrgList) + { + var department = await _dbContext.Queryable().Where(x => x.No == item.OBJID).FirstAsync(); + if (department == null) + { + department = new DepartmentEntity + { + No = item.OBJID, + Name = item.STEXT, + PNo = item.SOBID, + }; + + await _dbContext.InsertAsync(department); + } + else + { + department.PNo = item.SOBID; + department.Name = item.STEXT; + + await _dbContext.UpdateAsync(department); + } + } + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPersonJob.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPersonJob.cs new file mode 100644 index 00000000..0c0819d5 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPersonJob.cs @@ -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 SavePerson(List 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() + .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().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().Where(x => x.IdNo == item.idno).FirstAsync(); + if (gainfo != null) + { + _dbContext.Updateable().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().Any(g => g.IdNo == item.idno && g.SapNo != item.PERNR && g.Employed == "T") + && !_dbContext.Queryable().Any(g => g.IdNo == item.idno && int.Parse(g.SapNo) > int.Parse(item.PERNR) && g.Employed == item.isowner)); + } + else + { + _dbContext.Updateable().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().Any(g => g.Code == item.ename && g.Employed == "T") + && !_dbContext.Queryable().Any(g => g.IdNo == item.idno && int.Parse(g.SapNo) > int.Parse(item.PERNR) && g.Employed == item.isowner)); + } + } + + private async Task> GetModifiedPersonAsync(List 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> LoadDataAsync() + { + var gainfo = await _dbContext.Queryable().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 ToGainfoSap(List 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); + } +} \ No newline at end of file diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPositionJob.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPositionJob.cs new file mode 100644 index 00000000..1dbe1187 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Job/SyncPositionJob.cs @@ -0,0 +1,81 @@ +using Dlhis.Entity.Basic.Entity; +using Dlhis.ScheduledTask.SyncSapInfo.Comparers; +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Dlhis.ScheduledTask.SyncSapInfo.Services; +using Kurisu.SqlSugar.Services; +using Mapster; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Job; + +/// +/// 职位同步定时任务 +/// +public class SyncPositionJob +{ + private List lastUpdatedPositionList = new List(); + private readonly IDbContext _dbContext; + private readonly IJinkoSapService _jinkoSapService; + + public SyncPositionJob(IDbContext dbContext, IJinkoSapService jinkoSapService) + { + _dbContext = dbContext; + _jinkoSapService = jinkoSapService; + } + + public async Task SyncPositionInfo() + { + var positionResult = await _jinkoSapService.GetPositionsAsync(); + + if (positionResult.Position != null && positionResult.Position.Items.Count > 0) + { + var modifiedOrgList = GetModifiedPosition(positionResult.Position.Items); + await SaveOrg(modifiedOrgList); + } + } + + private List GetModifiedPosition(List spaList) + { + if (lastUpdatedPositionList.Count <= 0) + { + return spaList; + } + var needRemove = spaList.Intersect(lastUpdatedPositionList, new SapPositionComparer()); + return spaList.Except(needRemove, new SapPositionComparer()).ToList(); + } + + private async Task SaveOrg(List modifiedPostList) + { + if (modifiedPostList == null || modifiedPostList.Count == 0) return; + + var addItems = new List(); + var updateItems = new List(); + + foreach (var item in modifiedPostList) + { + var position = await _dbContext.Queryable().Where(x => x.No == item.ZJOBID).FirstAsync(); + if (position == null) + { + position = new PositionEntity + { + No = item.ZJOBANME, + Name = item.ZJOBANME, + DepartmentNo = item.ZDEPID, + Grade = item.ZZWID + }; + + addItems.Add(position); + } + else + { + position.Name = item.ZJOBANME; + position.DepartmentNo = item.ZDEPID; + position.Grade = item.ZZWID; + + updateItems.Add(position); + } + } + + await _dbContext.InsertAsync(addItems); + await _dbContext.UpdateAsync(updateItems); + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapOrganizationResponse.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapOrganizationResponse.cs new file mode 100644 index 00000000..9e52dd08 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapOrganizationResponse.cs @@ -0,0 +1,10 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Response; + +public class SapOrganizationResponse +{ + [JsonProperty("T_ORG")] + public SapOrganization Org { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPersonResponse.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPersonResponse.cs new file mode 100644 index 00000000..cc9cbb75 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPersonResponse.cs @@ -0,0 +1,13 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Response; + +public class SapPersonResponse +{ + /// + /// + /// + [JsonProperty("T_PERSON")] + public SapPerson Person { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPositionResponse.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPositionResponse.cs new file mode 100644 index 00000000..ed7be3a7 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Response/SapPositionResponse.cs @@ -0,0 +1,10 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Response; + +public class SapPositionResponse +{ + [JsonProperty("T_POST")] + public SapPosition Position { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoSapService.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoSapService.cs new file mode 100644 index 00000000..bd654f02 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoSapService.cs @@ -0,0 +1,12 @@ +using Dlhis.ScheduledTask.SyncSapInfo.Response; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Services; + +public interface IJinkoSapService : IScopeDependency +{ + Task GetSapOrganizationsAsync(); + + Task GetPositionsAsync(); + + Task GetPersonsAsync(); +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoSapService.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoSapService.cs new file mode 100644 index 00000000..b8aea8d6 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoSapService.cs @@ -0,0 +1,104 @@ +using System.Text; +using Dlhis.ScheduledTask.SyncSapInfo.Dto; +using Dlhis.ScheduledTask.SyncSapInfo.Response; +using Dlhis.User.Api; +using Newtonsoft.Json; + +namespace Dlhis.ScheduledTask.SyncSapInfo.Services.Implements; + +public class JinkoSapService : IJinkoSapService +{ + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + private readonly ITenantApi _tenantApi; + + public JinkoSapService(IHttpClientFactory httpClientFactory, ILogger logger, ITenantApi tenantApi) + { + _httpClient = httpClientFactory.CreateClient("jinko:sap"); + _logger = logger; + _tenantApi = tenantApi; + } + + public async Task GetSapOrganizationsAsync() + { + string apiUrl = "http://sappidap.jinkosolar.cn:51000/RESTAdapter/Rest/EHR_ORGANIZATION/"; + + var response = await _httpClient.PostAsync(apiUrl, new StringContent("{}", Encoding.UTF8, "application/json")); + response.EnsureSuccessStatusCode(); + + string responseJson = await response.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(responseJson); + + return result; + } + + public async Task GetPositionsAsync() + { + string apiUrl = "http://sappidap.jinkosolar.cn:51000/RESTAdapter/Rest/EHR_POSITION/"; + + var response = await _httpClient.PostAsync(apiUrl, new StringContent("{}", Encoding.UTF8, "application/json")); + response.EnsureSuccessStatusCode(); + + string responseJson = await response.Content.ReadAsStringAsync(); + + var result = JsonConvert.DeserializeObject(responseJson); + + return result; + } + + public async Task GetPersonsAsync() + { + var apiUrl = "http://sappipap01.jinkosolar.cn:50100/RESTAdapter/Rest/EHR_PERSONNEL/"; + + var tenantResult = await _tenantApi.GetTenantsInternalAsync(); + var tenants = tenantResult.Data; + + List persons = new(); + foreach (var item in tenants) + { + try + { + var body = new + { + T_WERKS = new + { + item = new List + { + new + { + WERKS = item.Code + } + } + }, + T_PERSON = Array.Empty(), + T_PNO = Array.Empty(), + }; + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + + var response = await _httpClient.PostAsync(apiUrl, content); + response.EnsureSuccessStatusCode(); + + var jsonResponse = await response.Content.ReadAsStringAsync(); + + + var personResp = JsonConvert.DeserializeObject(jsonResponse); + if (personResp?.Person?.Items?.Any() == true) + { + persons.AddRange(personResp.Person.Items); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "获取人事范围{werk}失败:" + ex.Message, item); + } + } + + return new SapPersonResponse() + { + Person = new SapPerson + { + Items = persons + }, + }; + } +} diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncOptions.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncOptions.cs new file mode 100644 index 00000000..6936dd88 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncOptions.cs @@ -0,0 +1,75 @@ +using Kurisu.Core.ConfigurableOptions.Attributes; + + +namespace Dlhis.ScheduledTask.SyncSapInfo; + +[Configuration] +public class SyncOptions +{ + public string ServerUrl { get; private set; } + + public string UserName { get; private set; } + + public string Password { get; private set; } + + public string SyncTime { get; private set; } + + public int AttendanceUploadInterval { get; private set; } + + public string AttendanceUploadUrl { get; private set; } + + public string DlhisDatabase { get; private set; } + + public DateTime BeginSyncDate { get; private set; } + + public string EHRWebServiceUserName { get; set; } + public string EHRWebServicePassword { get; set; } + public string EHRInsertRecordApiUrl { get; set; } + public string EHRDeleteRecordApiUrl { get; set; } + + public string EHRSavePhotoApiUrl { get; set; } + + + /// + /// 获取员工卡片信息RESUT地址 + /// + public string EHR_GET_WORK_CARD_INFOApiUrl { get; set; } + + /// + /// REST账号 + /// + public string RestUserName { get; set; } + + /// + /// REST密码 + /// + public string RestPassword { get; set; } + + + private static int SafeParseInt(string value, int defaultValue = 0) + { + if (int.TryParse(value, out int i)) + { + return i; + } + return defaultValue; + } + + private static bool SafeParseBoolean(string value, bool defaultValue = false) + { + if (bool.TryParse(value, out var b)) + { + return b; + } + return defaultValue; + } + + private static DateTime SafeParseDate(string value, DateTime defaultValue) + { + if (DateTime.TryParse(value, out var b)) + { + return b; + } + return defaultValue; + } +} diff --git a/Src/Dlhis.ScheduledTask/appsettings.json b/Src/Dlhis.ScheduledTask/appsettings.json index ce430ddc..7939768c 100644 --- a/Src/Dlhis.ScheduledTask/appsettings.json +++ b/Src/Dlhis.ScheduledTask/appsettings.json @@ -14,7 +14,7 @@ "EnableSqlLog": true }, "ConnectionStrings": { - "HangfireConnection": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=HangFire;charset=utf8mb4;Allow User Variables=true;" + "HangfireConnection": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=hangfire;charset=utf8mb4;Allow User Variables=true;" }, "FaceUrlOptions": { "Url": "https://yikatong.isawesome.cn/api/basic/gainfos/face?token=", diff --git a/Src/Dlhis.User.Api/ITenantApi.cs b/Src/Dlhis.User.Api/ITenantApi.cs index 3a9422b1..f9515bb1 100644 --- a/Src/Dlhis.User.Api/ITenantApi.cs +++ b/Src/Dlhis.User.Api/ITenantApi.cs @@ -18,6 +18,14 @@ public interface ITenantApi [Get("/api/tenants/list")] Task>> GetTenantsAsync(); + /// + /// 获取所有租户(内部使用) + /// + /// + [Get("/api/tenants/list-internal")] + Task>> GetTenantsInternalAsync(); + + /// /// 根据code获取租户信息 /// diff --git a/Src/Dlhis.User/Identity/Controllers/TenantsController.cs b/Src/Dlhis.User/Identity/Controllers/TenantsController.cs index 7b7c21ff..36862536 100644 --- a/Src/Dlhis.User/Identity/Controllers/TenantsController.cs +++ b/Src/Dlhis.User/Identity/Controllers/TenantsController.cs @@ -40,6 +40,17 @@ public class TenantsController : ControllerBase return await _tenantService.GetListAsync(); } + /// + /// 内部使用接口 + /// + /// + [AllowAnonymous] + [HttpGet("list-internal")] + public async Task> GetListInternalAsync() + { + return await _tenantService.GetListAsync(); + } + /// /// 获取租户 /// @@ -49,5 +60,5 @@ public class TenantsController : ControllerBase { return await _tenantService.GetTenantByCode(code); } - + }