fix 同步任务调整

This commit is contained in:
2024-03-09 12:13:11 +08:00
parent 07d77f1070
commit bbd7659320
16 changed files with 392 additions and 32 deletions

View File

@@ -93,6 +93,11 @@ public class GainfoSapEntity
public string guestno { get; set; }
public string ZZ_KLX { get; set; }
public DateTime? DAT01 { get; set; }
public string ZZ_COUNNM { get; set; }
public string ZZ_GZDJDNM { get; set; }
public string ZZ_GZDCQNM { get; set; }
}

View File

@@ -0,0 +1,18 @@
using Kurisu.SqlSugar;
using SqlSugar;
namespace Dlhis.Entity.Basic.Entity;
[SugarTable(TableName = "Werk", TableDescription = "人事范围")]
public class WerkEntity : SugarBaseEntity
{
/// <summary>
/// 人事范围
/// </summary>
public string Werk { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
}

View File

@@ -33,7 +33,11 @@ public class SapPersonComparer : IEqualityComparer<SapPersonItem>
&& 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);
&& (x.ZZ_KLX ?? string.Empty) == (y.ZZ_KLX ?? string.Empty)
&& x.ZZ_COUNNM == y.ZZ_COUNNM
&& x.ZZ_GZDJDNM == y.ZZ_GZDJDNM
&& x.ZZ_GZDCQNM == y.ZZ_GZDCQNM
;
}
public int GetHashCode(SapPersonItem obj)
@@ -57,7 +61,11 @@ public class SapPersonComparer : IEqualityComparer<SapPersonItem>
^ obj.MASSN.SafeGetHashCode()
^ obj.MNTXT.SafeGetHashCode()
^ obj.ZXUELI.SafeGetHashCode()
^ (obj.ZZ_KLX ?? "").SafeGetHashCode();
^ (obj.ZZ_KLX ?? "").SafeGetHashCode()
^ obj.ZZ_COUNNM.SafeGetHashCode()
^ obj.ZZ_GZDJDNM.SafeGetHashCode()
^ obj.ZZ_GZDCQNM.SafeGetHashCode()
;
}

View File

@@ -2,11 +2,8 @@
namespace Dlhis.ScheduledTask.SyncSapInfo.Dto;
public class SapPerson
public class SapPerson<T>
{
/// <summary>
///
/// </summary>
[JsonProperty("item")]
public List<SapPersonItem> Items { get; set; }
public List<T> Items { get; set; }
}

View File

@@ -0,0 +1,19 @@
namespace Dlhis.ScheduledTask.SyncSapInfo.Dto
{
public class SapPersonDepartmentStatus
{
public string ZWORKCODE { get; set; }
public DateTime BEGDA { get; set; }
public DateTime ENDDA { get; set; }
public string WERKS { get; set; }
/// <summary>
/// 部门号
/// </summary>
public string ORGEH { get; set; }
}
}

View File

@@ -5,6 +5,7 @@ public class SapPersonItem
public string KOSTL { get; set; }
public string ZLZRQ { get; set; }
public string ZZ_SFZH { get; set; }
public string STELL { get; set; }
@@ -189,4 +190,19 @@ public class SapPersonItem
///
/// </summary>
public string ZZ_ZPQD { get; set; }
/// <summary>
/// 国家
/// </summary>
public string ZZ_COUNNM { get; set; }
/// <summary>
/// 基地
/// </summary>
public string ZZ_GZDJDNM { get; set; }
/// <summary>
/// 厂区
/// </summary>
public string ZZ_GZDCQNM { get; set; }
}

View File

@@ -0,0 +1,16 @@
namespace Dlhis.ScheduledTask.SyncSapInfo.Dto
{
public class SapPersonJobStatus
{
public string ZWORKCODE { get; set; }
public DateTime BEGDA { get; set; }
public DateTime ENDDA { get; set; }
/// <summary>
/// 0离职
/// </summary>
public int STAT2 { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
using Dlhis.ScheduledTask.SyncSapInfo.Services;
namespace Dlhis.ScheduledTask.SyncSapInfo.Job;
public class SyncOriginCardInfoJob
{
private readonly IJinkoJIPService _jinkoJIPService;
public SyncOriginCardInfoJob(IJinkoJIPService jinkoJIPService)
{
_jinkoJIPService = jinkoJIPService;
}
public async Task RunAsync()
{
await _jinkoJIPService.UploadAttendancesAsync(new List<UploadAttendanceRequest>()
{
new UploadAttendanceRequest()
{
RaiseTime = DateTime.Now,
ZWORKCODE = "000001",
ZNOTE = "正门1"
}
});
}
}

View File

@@ -7,6 +7,9 @@ using Dlhis.ScheduledTask.SyncSapInfo.Comparers;
using Dlhis.ScheduledTask.SyncSapInfo.Services;
using Kurisu.AspNetCore.Scope;
using Dlhis.Entity.Basic.Enums;
using Dlhis.Sys.Api;
using Dlhis.Sys.Api.Response;
using SqlSugar;
namespace Dlhis.ScheduledTask.SyncSapInfo.Job;
@@ -14,12 +17,15 @@ public class SyncPersonJob
{
private readonly ILogger _logger;
private readonly IJinkoSapService _jinkoSapService;
private readonly ITenantApi _tenantApi;
private List<PositionEntity> _positions;
private List<TenantResponse> _tenants;
public SyncPersonJob(ILogger<SyncPersonJob> logger, IJinkoSapService jinkoSapService)
public SyncPersonJob(ILogger<SyncPersonJob> logger, IJinkoSapService jinkoSapService, ITenantApi tenantApi)
{
_logger = logger;
_jinkoSapService = jinkoSapService;
_tenantApi = tenantApi;
}
public async Task RunAsync()
@@ -44,8 +50,11 @@ public class SyncPersonJob
}
}
private int SavePerson(List<SapPersonItem> persons)
private async Task<int> SavePerson(List<SapPersonItem> persons)
{
var tenantResult = await _tenantApi.GetTenantsInternalAsync();
_tenants = tenantResult.Data;
var failure = 0;
var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
var chunks = workCodes.Chunk(4000).ToList();
@@ -67,7 +76,6 @@ public class SyncPersonJob
var existsUpdateWorkCodes = originUpdates.Select(x => x.ZWORKCODE).ToList();
var originInserts = persons.Where(x => searchCodes.Contains(x.ZWORKCODE)).Where(x => !existsUpdateWorkCodes.Contains(x.ZWORKCODE)).ToList();
int i = 0;
var currentTotal = originUpdates.Count + originInserts.Count;
@@ -137,6 +145,8 @@ public class SyncPersonJob
Position = item.web,
Remark = item.remark,
Werks = item.WERKS,
Workplace = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code,
Factory = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code,
};
if (item.isowner == "T")
@@ -149,7 +159,7 @@ public class SyncPersonJob
}
}
private void UpdatePerson(IDbContext db, GainfoSapEntity item)
{
var gainfoSap = db.Queryable<GainfoSapEntity>().Where(x => x.ename == item.ename).First();
@@ -163,7 +173,9 @@ public class SyncPersonJob
isowner = item.isowner,
remark = item.remark,
email = item.email,
WERKS = item.WERKS
WERKS = item.WERKS,
ZZ_GZDJDNM = item.ZZ_GZDJDNM,
ZZ_GZDCQNM = item.ZZ_GZDCQNM,
})
.Where(x => x.ename == item.ename)
.ExecuteCommand();
@@ -180,7 +192,9 @@ public class SyncPersonJob
DepartmentNo = item.appellation,
Remark = item.remark,
Degree = item.email,
Werks = item.WERKS
Werks = item.WERKS,
Workplace = item.ZZ_GZDJDNM,
Factory = item.ZZ_GZDCQNM
})
.Where(x => x.Code == item.ename)
.ExecuteCommand();
@@ -288,15 +302,18 @@ public class SyncPersonJob
sex = sex,
web = SubString(position?.Name ?? "", 30),
logdate = DateTime.Now,
isowner = int.Parse(person.ZSTATUS) < 4 ? "T" : "F",
isowner = int.Parse(person.ZSTATUS) < 5 ? "T" : "F",
@class = "C",
country = "CN",
country = person.ZZ_COUNNM,
log_ip = "127.0.0.1",
log_shift = "1",
log_id = "XX",
address = "",
occupation = "99",
nation = "01"
nation = "01",
ZZ_COUNNM = person.ZZ_COUNNM,
ZZ_GZDJDNM = person.ZZ_GZDJDNM,
ZZ_GZDCQNM = person.ZZ_GZDCQNM,
};
return o;

View File

@@ -9,5 +9,18 @@ public class SapPersonResponse
///
/// </summary>
[JsonProperty("T_PERSON")]
public SapPerson Person { get; set; }
public SapPerson<SapPersonItem> Person { get; set; }
/// <summary>
/// 离职状态
/// </summary>
[JsonProperty("T_0000")]
public SapPerson<SapPersonJobStatus> JobStatusInfo { get; set; }
/// <summary>
/// 部门变更信息
/// </summary>
[JsonProperty("T_0001")]
public SapPerson<SapPersonDepartmentStatus> DepartmentInfo { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace Dlhis.ScheduledTask.SyncSapInfo.Response
{
public class UploadAttendanceResponse
{
/// <summary>
/// 0 成功
/// </summary>
public string OLX { get; set; }
public string OMS { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
using Dlhis.ScheduledTask.SyncSapInfo.Response;
namespace Dlhis.ScheduledTask.SyncSapInfo.Services
{
public interface IJinkoJIPService : ISingletonDependency
{
Task<UploadAttendanceResponse> UploadAttendancesAsync(List<UploadAttendanceRequest> requests);
}
}

View File

@@ -0,0 +1,84 @@
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using Dlhis.ScheduledTask.SyncSapInfo.Response;
using Kurisu.AspNetCore.Utils.Extensions;
using Microsoft.IdentityModel.Tokens;
namespace Dlhis.ScheduledTask.SyncSapInfo.Services.Implements;
public class JinkoJIPService : IJinkoJIPService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<JinkoJIPService> _logger;
public JinkoJIPService(IHttpClientFactory httpClientFactory, ILogger<JinkoJIPService> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
}
private HttpClient GetHttpClient()
{
var httpClient = _httpClientFactory.CreateClient();
//httpClient.BaseAddress = new Uri("");
//httpClient.Timeout = TimeSpan.FromMinutes(10);
var key = "FACE-7409WIBX";
var secret = "be0a4b88-cd80-4509-b9b9-865205d0d3d8";
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", IssueJwt(key, secret, 5));
return httpClient;
}
private static string IssueJwt(string jwtKey, string jwtSecret, int mins)
{
var now = DateTime.Now.AddMinutes(-mins);
var expires = DateTime.Now.AddMinutes(mins);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(now).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(expires).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Iss,jwtKey),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret));
var descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Issuer = jwtKey,
IssuedAt = now,
NotBefore = now,
Expires = expires,
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
};
var jwtHandler = new JwtSecurityTokenHandler();
var securityToken = jwtHandler.CreateToken(descriptor);
return jwtHandler.WriteToken(securityToken);
}
public async Task<UploadAttendanceResponse> UploadAttendancesAsync(List<UploadAttendanceRequest> requests)
{
var body = new
{
T_DATA = requests,
};
var json = body.ToJson();
_logger.LogInformation("上传考勤记录请求:{json}", json);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await GetHttpClient().PostAsync("http://172.16.202.34:8000/JIP/HCM/HCM_SWIPE_DATA_SAVE", content);
var responseJson = await response.Content.ReadAsStringAsync();
_logger.LogInformation("上传考勤记录响应:{json}", responseJson);
var r = responseJson.ToObject<UploadAttendanceResponse>();
return r;
}
}

View File

@@ -1,8 +1,9 @@
using System.Net.Http.Headers;
using System.Text;
using Dlhis.Entity.Basic.Entity;
using Dlhis.ScheduledTask.SyncSapInfo.Dto;
using Dlhis.ScheduledTask.SyncSapInfo.Response;
using Dlhis.Sys.Api;
using Kurisu.SqlSugar.Services;
using Newtonsoft.Json;
namespace Dlhis.ScheduledTask.SyncSapInfo.Services.Implements;
@@ -10,14 +11,14 @@ namespace Dlhis.ScheduledTask.SyncSapInfo.Services.Implements;
public class JinkoSapService : IJinkoSapService
{
private readonly ILogger<JinkoSapService> _logger;
private readonly IDbContext _dbContext;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ITenantApi _tenantApi;
public JinkoSapService(IHttpClientFactory httpClientFactory, ILogger<JinkoSapService> logger, ITenantApi tenantApi)
public JinkoSapService(IHttpClientFactory httpClientFactory, ILogger<JinkoSapService> logger, IDbContext dbContext)
{
_logger = logger;
_dbContext = dbContext;
_httpClientFactory = httpClientFactory;
_tenantApi = tenantApi;
}
private HttpClient GetHttpClient()
@@ -64,11 +65,13 @@ public class JinkoSapService : IJinkoSapService
{
var apiUrl = "/RESTAdapter/Rest/EHR_PERSONNEL/";
var tenantResult = await _tenantApi.GetTenantsInternalAsync();
var tenants = tenantResult.Data;
var werks = await _dbContext.Queryable<WerkEntity>().ToListAsync();
List<SapPersonItem> persons = new();
foreach (var item in tenants)
List<SapPersonJobStatus> jobInfos = new();
List<SapPersonDepartmentStatus> departmentInfos = new();
foreach (var item in werks)
{
try
{
@@ -80,7 +83,7 @@ public class JinkoSapService : IJinkoSapService
{
new
{
WERKS = item.Code
WERKS = item.Werk
}
}
},
@@ -99,6 +102,16 @@ public class JinkoSapService : IJinkoSapService
{
persons.AddRange(personResp.Person.Items);
}
if (personResp?.JobStatusInfo?.Items?.Any() == true)
{
jobInfos.AddRange(personResp.JobStatusInfo.Items);
}
if (personResp?.DepartmentInfo?.Items?.Any() == true)
{
departmentInfos.AddRange(personResp.DepartmentInfo.Items);
}
}
catch (Exception ex)
{
@@ -108,10 +121,18 @@ public class JinkoSapService : IJinkoSapService
return new SapPersonResponse()
{
Person = new SapPerson
Person = new SapPerson<SapPersonItem>
{
Items = persons
},
JobStatusInfo = new SapPerson<SapPersonJobStatus>
{
Items = jobInfos,
},
DepartmentInfo = new SapPerson<SapPersonDepartmentStatus>
{
Items = departmentInfos
}
};
}
}

View File

@@ -0,0 +1,27 @@
namespace Dlhis.ScheduledTask.SyncSapInfo
{
public class UploadAttendanceRequest
{
/// <summary>
/// item.CardNo.TrimEnd('\0')
/// </summary>
public string ZWORKCODE { get; set; }
public DateTime RaiseTime { get; set; }
/// <summary>
/// yyyy-MM-dd
/// </summary>
public string ZDATE => RaiseTime.ToString("yyyy-MM-dd");
/// <summary>
/// HH:mm:ss
/// </summary>
public string ZTIME => RaiseTime.ToString("HH:mm:ss");
/// <summary>
/// 设备位置
/// </summary>
public string ZNOTE { get; set; }
}
}

View File

@@ -1,18 +1,90 @@
{
"Routes": [
{
"UpstreamPathTemplate": "/api/basic/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"UpstreamPathTemplate": "/api/oauth2/{url}",
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5002
"Host": "192.168.199.30",
"Port": 31001
}
]
},
{
"UpstreamPathTemplate": "/api/common/{url}",
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31002
}
]
},
{
"UpstreamPathTemplate": "/api/sys/{url}",
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31003
}
]
},
{
"UpstreamPathTemplate": "/api/user/{url}",
"UpstreamHttpMethod": [
"Get",
"Post"
],
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31004
}
]
},
{
"UpstreamPathTemplate": "/api/basic/{url}",
"UpstreamHttpMethod": [
"Get",
"Post"
],
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31005
}
]
},
{
"UpstreamPathTemplate": "/api/scheduled/{url}",
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31006
}
]
},
{
"UpstreamPathTemplate": "/api/canteen/{url}",
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.199.30",
"Port": 31007
}
]
}
],
"GlobalConfiguration": {
}
"GlobalConfiguration": {}
}