diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln
index 92f4fdf4..3a2f5093 100644
--- a/Dlhis.Jinko.Face.sln
+++ b/Dlhis.Jinko.Face.sln
@@ -29,8 +29,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{48
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Message", "Message", "{65E76F97-E78A-4C95-B788-4091236B1A79}"
@@ -45,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.DataPermission.Model"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.InfoCheck.Api", "Src\Dlhis.InfoCheck.Api\Dlhis.InfoCheck.Api.csproj", "{A501D16E-638F-4156-989C-2BACCC2FAC2B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Jip.Api", "Src\Dlhis.Jip.Api\Dlhis.Jip.Api.csproj", "{841B7B43-5394-413F-9D68-A07EBDD6D4CD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -83,10 +83,6 @@ Global
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.Build.0 = Release|Any CPU
- {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.Build.0 = Release|Any CPU
{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -111,6 +107,10 @@ Global
{A501D16E-638F-4156-989C-2BACCC2FAC2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A501D16E-638F-4156-989C-2BACCC2FAC2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A501D16E-638F-4156-989C-2BACCC2FAC2B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {841B7B43-5394-413F-9D68-A07EBDD6D4CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {841B7B43-5394-413F-9D68-A07EBDD6D4CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {841B7B43-5394-413F-9D68-A07EBDD6D4CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {841B7B43-5394-413F-9D68-A07EBDD6D4CD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -122,11 +122,11 @@ Global
{85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D}
{1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5} = {489252FB-A44B-46EE-B065-21CDCB724441}
- {9EA85FB2-F320-4F97-B278-00652CF35BD8} = {AA987BDF-EF63-467B-AD04-59F9B10D9000}
{A54426E2-1CA0-48AB-BBA6-07CDE2807E35} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B}
{053BF7B2-B1A0-435F-9C77-2EF5622CC5C5} = {65E76F97-E78A-4C95-B788-4091236B1A79}
{4D656761-8CE7-4316-A3DF-8C1722D69CCE} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
{A501D16E-638F-4156-989C-2BACCC2FAC2B} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
+ {841B7B43-5394-413F-9D68-A07EBDD6D4CD} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0}
diff --git a/Src/Dlhis.Basic.Api/ContentHandlers/CodeContentHandler.cs b/Src/Dlhis.Basic.Api/ContentHandlers/CodeContentHandler.cs
new file mode 100644
index 00000000..28d89356
--- /dev/null
+++ b/Src/Dlhis.Basic.Api/ContentHandlers/CodeContentHandler.cs
@@ -0,0 +1,22 @@
+using System.Text;
+using Kurisu.RemoteCall;
+using Kurisu.RemoteCall.Abstractions;
+using Newtonsoft.Json;
+
+namespace Dlhis.Basic.Api.ContentHandlers;
+
+public class CodeContentHandler : IContentHandler
+{
+ ///
+ public HttpContent Create(List values)
+ {
+ var code = values.First(x => x.Parameter.Name == "code").GetValue();
+ var obj = new
+ {
+ code,
+ };
+ var json = JsonConvert.SerializeObject(obj);
+
+ return new StringContent(json, Encoding.UTF8, "application/json");
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj
index 5c849fbb..938a97d6 100644
--- a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj
+++ b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs b/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs
index 36c86c74..10b504b3 100644
--- a/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs
+++ b/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs
@@ -1,13 +1,13 @@
using Dlhis.Basic.Api.Dto;
using Kurisu.RemoteCall.Attributes;
-using Kurisu.RemoteCall.Default;
namespace Dlhis.Basic.Api;
+[RequestResultHandler]
[EnableRemoteClient(Name = "basic-service", BaseUrl = "${InternalRequest:BasicRequestUrl}")]
public interface IBusinessPlacePermissionsApi
{
[Auth]
[Get("/api/businessplacepermissions/my")]
- Task>> GetMyAsync();
+ Task> GetMyAsync();
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic.Api/IGainfoPermissionApi.cs b/Src/Dlhis.Basic.Api/IGainfoPermissionApi.cs
index e3ff75cb..2dee857f 100644
--- a/Src/Dlhis.Basic.Api/IGainfoPermissionApi.cs
+++ b/Src/Dlhis.Basic.Api/IGainfoPermissionApi.cs
@@ -1,16 +1,12 @@
-using Dlhis.Basic.Api.Request;
-using Kurisu.RemoteCall.Attributes;
-using Kurisu.RemoteCall.Default;
+using Kurisu.RemoteCall.Attributes;
namespace Dlhis.Basic.Api;
+[RequestResultHandler]
[EnableRemoteClient(Name = "basic-service", BaseUrl = "${InternalRequest:BasicRequestUrl}")]
public interface IGainfoPermissionApi
{
- [Post("/api/gainfoPermissions/reset")]
- Task ResetAsync(GainfoPermissionResetRequest request);
-
[Auth]
[Get("/api/devicePermissions/userPermissionCodes")]
- Task>> GetPermissionsDeviceCodesAsync(string userCode);
+ Task> GetPermissionsDeviceCodesAsync(string userCode);
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic.Api/ISyncApi.cs b/Src/Dlhis.Basic.Api/ISyncApi.cs
new file mode 100644
index 00000000..e02a8064
--- /dev/null
+++ b/Src/Dlhis.Basic.Api/ISyncApi.cs
@@ -0,0 +1,30 @@
+using Dlhis.Basic.Api.ContentHandlers;
+using Dlhis.Basic.Api.Response;
+using Kurisu.RemoteCall.Attributes;
+
+namespace Dlhis.Basic.Api;
+
+[RequestResultHandler]
+[EnableRemoteClient(Name = "basic-service", BaseUrl = "${InternalRequest:BasicRequestUrl}")]
+public interface ISyncApi
+{
+ [Post("/api/sync/gainfo/werk")]
+ [RequestContentHandler(typeof(CodeContentHandler))]
+ Task SyncGainfoByWerkAsync(string code);
+
+ [Post("/api/sync/gainfo/user")]
+ [RequestContentHandler(typeof(CodeContentHandler))]
+ Task SyncGainfoByUserCodeAsync(string code);
+
+ [Get("/api/sync/orgs")]
+ Task SyncOrganizationsAsync();
+
+
+ [Get("/api/sync/positions")]
+ Task GetPositionsAsync();
+
+
+ [Post("/api/sync/businessTrips")]
+ [RequestContentHandler(typeof(CodeContentHandler))]
+ Task HandlerBusinessTripsAsync(string code);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic.Api/Response/SapOrganization.cs b/Src/Dlhis.Basic.Api/Response/SapOrganization.cs
new file mode 100644
index 00000000..978e37b5
--- /dev/null
+++ b/Src/Dlhis.Basic.Api/Response/SapOrganization.cs
@@ -0,0 +1,15 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Basic.Api.Response;
+
+///
+/// sap机构信息
+///
+public class SapOrganization
+{
+ ///
+ /// 机构项
+ ///
+ [JsonProperty("item")]
+ public List Items { get; set; }
+}
diff --git a/Src/Dlhis.Basic.Api/Response/SapOrganizationItem.cs b/Src/Dlhis.Basic.Api/Response/SapOrganizationItem.cs
new file mode 100644
index 00000000..e26fe528
--- /dev/null
+++ b/Src/Dlhis.Basic.Api/Response/SapOrganizationItem.cs
@@ -0,0 +1,66 @@
+namespace Dlhis.Basic.Api.Response;
+
+public class SapOrganizationItem
+{
+ ///
+ /// 开始日期
+ ///
+ public string BEGDA { get; set; }
+
+ ///
+ /// 结束日期
+ ///
+ public string ENDDA { get; set; }
+
+ ///
+ /// 语言
+ ///
+ public string 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.Basic.Api/Response/SapOrganizationResponse.cs b/Src/Dlhis.Basic.Api/Response/SapOrganizationResponse.cs
new file mode 100644
index 00000000..5aa31c6e
--- /dev/null
+++ b/Src/Dlhis.Basic.Api/Response/SapOrganizationResponse.cs
@@ -0,0 +1,9 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Basic.Api.Response;
+
+public class SapOrganizationResponse
+{
+ [JsonProperty("T_ORG")]
+ public SapOrganization Org { get; set; }
+}
diff --git a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonItem.cs b/Src/Dlhis.Basic.Api/Response/SapPersonItem.cs
similarity index 98%
rename from Src/Dlhis.ScheduledTask/Common/Dto/SapPersonItem.cs
rename to Src/Dlhis.Basic.Api/Response/SapPersonItem.cs
index 262b4ff4..4356ce52 100644
--- a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonItem.cs
+++ b/Src/Dlhis.Basic.Api/Response/SapPersonItem.cs
@@ -1,4 +1,4 @@
-namespace Dlhis.ScheduledTask.Common.Dto;
+namespace Dlhis.Jip.Api.Dto;
public class SapPersonItem
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Dto/SapPosition.cs b/Src/Dlhis.Basic.Api/Response/SapPosition.cs
similarity index 76%
rename from Src/Dlhis.ScheduledTask/Common/Dto/SapPosition.cs
rename to Src/Dlhis.Basic.Api/Response/SapPosition.cs
index 25b47e00..a1427f67 100644
--- a/Src/Dlhis.ScheduledTask/Common/Dto/SapPosition.cs
+++ b/Src/Dlhis.Basic.Api/Response/SapPosition.cs
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
-namespace Dlhis.ScheduledTask.Common.Dto;
+namespace Dlhis.Basic.Api.Response;
public class SapPosition
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Dto/SapPositionItem.cs b/Src/Dlhis.Basic.Api/Response/SapPositionItem.cs
similarity index 94%
rename from Src/Dlhis.ScheduledTask/Common/Dto/SapPositionItem.cs
rename to Src/Dlhis.Basic.Api/Response/SapPositionItem.cs
index 3feaa89e..586b9a57 100644
--- a/Src/Dlhis.ScheduledTask/Common/Dto/SapPositionItem.cs
+++ b/Src/Dlhis.Basic.Api/Response/SapPositionItem.cs
@@ -1,4 +1,4 @@
-namespace Dlhis.ScheduledTask.Common.Dto
+namespace Dlhis.Basic.Api.Response
{
public class SapPositionItem
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Response/SapPositionResponse.cs b/Src/Dlhis.Basic.Api/Response/SapPositionResponse.cs
similarity index 60%
rename from Src/Dlhis.ScheduledTask/Common/Response/SapPositionResponse.cs
rename to Src/Dlhis.Basic.Api/Response/SapPositionResponse.cs
index 76eb0892..6fa49921 100644
--- a/Src/Dlhis.ScheduledTask/Common/Response/SapPositionResponse.cs
+++ b/Src/Dlhis.Basic.Api/Response/SapPositionResponse.cs
@@ -1,7 +1,7 @@
-using Dlhis.ScheduledTask.Common.Dto;
+using Dlhis.Jip.Api.Dto;
using Newtonsoft.Json;
-namespace Dlhis.ScheduledTask.Common.Response;
+namespace Dlhis.Basic.Api.Response;
public class SapPositionResponse
{
diff --git a/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs b/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs
index 00683db3..f25bbf79 100644
--- a/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs
+++ b/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs
@@ -140,8 +140,7 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
};
}
- var tenantResult = await _tenantApi.GetTenantByCodeAsync(place.TenantId);
- var tenantInfo = tenantResult.EnsureSuccessStatusCode();
+ var tenant = await _tenantApi.GetTenantByCodeAsync(place.TenantId);
var relationship = await _dbContext.Queryable().Where(x => x.PlaceCode == place.Code).FirstAsync();
if (relationship == null)
@@ -150,8 +149,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
{
CustomCode = placeCustomCode,
Name = place.Name,
- TenantCode = tenantInfo.Code,
- TenantName = tenantInfo.Name,
+ TenantCode = tenant.Code,
+ TenantName = tenant.Name,
Shifts = new List()
};
}
@@ -181,8 +180,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
{
CustomCode = placeCustomCode,
Name = place.Name,
- TenantCode = tenantInfo.Code,
- TenantName = tenantInfo.Name,
+ TenantCode = tenant.Code,
+ TenantName = tenant.Name,
Shifts = list.OrderBy(x => x.Sequence).ToList()
};
}
diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs
index a18aa97e..1751b19d 100644
--- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs
+++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs
@@ -33,9 +33,9 @@ public class DeviceGroupService : IDeviceGroupService
public async Task> GetTreeAsync(DeviceTypeEnumType type)
{
- var tenantResult = await _tenantApi.GetMyTenantsAsync();
- var tenantIds = tenantResult.Data.Select(x => x.Code).ToList();
- tenantIds.AddRange(tenantResult.Data.Select(x => x.PCode));
+ var tenants = await _tenantApi.GetMyTenantsAsync();
+ var tenantIds = tenants.Select(x => x.Code).ToList();
+ tenantIds.AddRange(tenants.Select(x => x.PCode));
var deviceGroups = await _dbContext.Queryable()
.Where(x => tenantIds.Contains(x.TenantId))
diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
index c9bb65d8..a0dad80a 100644
--- a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
+++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
@@ -379,8 +379,7 @@ public class DevicePermissionService : IDevicePermissionService
.Where(x => x.num == 1)
.ToListAsync();
- var tenantsResult = await _tenantApi.GetTenantsInternalAsync();
- var tenants = tenantsResult.Data;
+ var tenants = await _tenantApi.GetTenantsInternalAsync();
page.Data.ForEach(x =>
{
diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs
index 135ea0a1..10b0a5d4 100644
--- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs
+++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs
@@ -246,8 +246,8 @@ public class DeviceService : IDeviceService
var factory = device.TenantId;
try
{
- var tenantResult = await _tenantApi.GetTenantByCodeAsync(device.TenantId);
- factory = tenantResult?.Data?.Name ?? string.Empty;
+ var tenant = await _tenantApi.GetTenantByCodeAsync(device.TenantId);
+ factory = tenant?.Name ?? string.Empty;
}
catch (Exception)
{
diff --git a/Src/Dlhis.Basic/Dlhis.Basic.csproj b/Src/Dlhis.Basic/Dlhis.Basic.csproj
index cf699d42..5b2a8bb7 100644
--- a/Src/Dlhis.Basic/Dlhis.Basic.csproj
+++ b/Src/Dlhis.Basic/Dlhis.Basic.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs b/Src/Dlhis.Basic/JinkoSapHttpClientPack.cs
similarity index 95%
rename from Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs
rename to Src/Dlhis.Basic/JinkoSapHttpClientPack.cs
index 69c78040..8ef2a9a1 100644
--- a/Src/Dlhis.ScheduledTask/Packs/JinkoSapHttpClientPack.cs
+++ b/Src/Dlhis.Basic/JinkoSapHttpClientPack.cs
@@ -2,7 +2,7 @@
using System.Text;
using Kurisu.AspNetCore.Startup;
-namespace Dlhis.ScheduledTask.Packs;
+namespace Dlhis.Basic;
public class JinkoSapHttpClientPack : BaseAppPack
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Comparers/SapPersonComparer.cs b/Src/Dlhis.Basic/Organization/Comparers/SapPersonComparer.cs
similarity index 95%
rename from Src/Dlhis.ScheduledTask/Common/Comparers/SapPersonComparer.cs
rename to Src/Dlhis.Basic/Organization/Comparers/SapPersonComparer.cs
index 58f8db79..8ef64662 100644
--- a/Src/Dlhis.ScheduledTask/Common/Comparers/SapPersonComparer.cs
+++ b/Src/Dlhis.Basic/Organization/Comparers/SapPersonComparer.cs
@@ -1,7 +1,7 @@
-using Dlhis.ScheduledTask.Common.Dto;
-using System.Text;
+using Dlhis.Basic.Organization.Services.Implements;
+using Dlhis.Jip.Api.Dto;
-namespace Dlhis.ScheduledTask.Common.Comparers;
+namespace Dlhis.Basic.Organization.Comparers;
///
/// 人员信息比较器
diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfoPermissionsController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfoPermissionsController.cs
index 4b135fba..3999dd61 100644
--- a/Src/Dlhis.Basic/Organization/Controllers/GainfoPermissionsController.cs
+++ b/Src/Dlhis.Basic/Organization/Controllers/GainfoPermissionsController.cs
@@ -66,17 +66,4 @@ public class GainfoPermissionsController : ControllerBase
{
return await _gainfoPermissions.GetAssignGroupAsync(userNo);
}
-
- ///
- /// 权限下发重置
- ///
- ///
- ///
- [AllowAnonymous]
- [HttpPost("reset")]
- [IgnoreTenant]
- public async Task ResetPermissionsAsync(GainfoPermissionResetRequest request)
- {
- await _gainfoPermissions.ResetPermissionsAsync(request);
- }
}
diff --git a/Src/Dlhis.Basic/Organization/Controllers/SyncController.cs b/Src/Dlhis.Basic/Organization/Controllers/SyncController.cs
new file mode 100644
index 00000000..14af77d0
--- /dev/null
+++ b/Src/Dlhis.Basic/Organization/Controllers/SyncController.cs
@@ -0,0 +1,55 @@
+using Dlhis.Basic.Organization.Request;
+using Dlhis.Basic.Organization.Services;
+using Dlhis.Jip.Api.Responses;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Dlhis.Basic.Organization.Controllers;
+
+[AllowAnonymous]
+[ApiController]
+[Route("/api/[controller]")]
+public class SyncController : ControllerBase
+{
+ private readonly IGainfoUpdateService _gainfoUpdateService;
+ private readonly IJinkoSapService _jinkoSapService;
+ private readonly ISapBusinessTripService _sapBusinessTripService;
+
+ public SyncController(IGainfoUpdateService gainfoUpdateService, IJinkoSapService jinkoSapService, ISapBusinessTripService sapBusinessTripService)
+ {
+ _gainfoUpdateService = gainfoUpdateService;
+ _jinkoSapService = jinkoSapService;
+ _sapBusinessTripService = sapBusinessTripService;
+ }
+
+ [HttpPost("/api/sync/gainfo/werk")]
+ public async Task TodoByWerkAsync(CodeRequest request)
+ {
+ await _gainfoUpdateService.TodoByWerkAsync(request.Code);
+ }
+
+ [HttpPost("/api/sync/gainfo/user")]
+ public async Task TodoByCodeAsync(CodeRequest request)
+ {
+ await _gainfoUpdateService.TodoByCodeAsync(request.Code);
+ }
+
+
+ [HttpGet("/api/sync/orgs")]
+ public async Task GetOrgsSync()
+ {
+ return await _jinkoSapService.GetSapOrganizationsAsync();
+ }
+
+ [HttpGet("/api/sync/positions")]
+ public async Task GetPositionsAsync()
+ {
+ return await _jinkoSapService.GetPositionsAsync();
+ }
+
+ [HttpPost("/api/sync/businessTrips")]
+ public async Task GetPositionsAsync(CodeRequest request)
+ {
+ await _sapBusinessTripService.HandlerBusinessTripsByFactoryAsync(request.Code);
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Organization/Request/CodeRequest.cs b/Src/Dlhis.Basic/Organization/Request/CodeRequest.cs
new file mode 100644
index 00000000..b29966e9
--- /dev/null
+++ b/Src/Dlhis.Basic/Organization/Request/CodeRequest.cs
@@ -0,0 +1,6 @@
+namespace Dlhis.Basic.Organization.Request;
+
+public class CodeRequest
+{
+ public string Code { get; set; }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoUpdateService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoUpdateService.cs
new file mode 100644
index 00000000..da36df1a
--- /dev/null
+++ b/Src/Dlhis.Basic/Organization/Services/IGainfoUpdateService.cs
@@ -0,0 +1,8 @@
+namespace Dlhis.Basic.Organization.Services;
+
+public interface IGainfoUpdateService : IScopeDependency
+{
+ Task TodoByWerkAsync(string werk);
+
+ Task TodoByCodeAsync(string code);
+}
diff --git a/Src/Dlhis.ScheduledTask/Common/Services/IIdentityUserSyncService.cs b/Src/Dlhis.Basic/Organization/Services/IIdentityUserSyncService.cs
similarity index 76%
rename from Src/Dlhis.ScheduledTask/Common/Services/IIdentityUserSyncService.cs
rename to Src/Dlhis.Basic/Organization/Services/IIdentityUserSyncService.cs
index c5d80dcb..a4a2a58a 100644
--- a/Src/Dlhis.ScheduledTask/Common/Services/IIdentityUserSyncService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/IIdentityUserSyncService.cs
@@ -1,4 +1,4 @@
-namespace Dlhis.ScheduledTask.Common.Services;
+namespace Dlhis.Basic.Organization.Services;
public interface IIdentityUserSyncService : IScopeDependency
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Services/IJinkoSapService.cs b/Src/Dlhis.Basic/Organization/Services/IJinkoSapService.cs
similarity index 76%
rename from Src/Dlhis.ScheduledTask/Common/Services/IJinkoSapService.cs
rename to Src/Dlhis.Basic/Organization/Services/IJinkoSapService.cs
index badd62b3..d78c554c 100644
--- a/Src/Dlhis.ScheduledTask/Common/Services/IJinkoSapService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/IJinkoSapService.cs
@@ -1,6 +1,6 @@
-using Dlhis.ScheduledTask.Common.Response;
+using Dlhis.Jip.Api.Responses;
-namespace Dlhis.ScheduledTask.Common.Services;
+namespace Dlhis.Basic.Organization.Services;
public interface IJinkoSapService : IScopeDependency
{
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/FactorySettingService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/FactorySettingService.cs
index 16ae5b37..7258b54c 100644
--- a/Src/Dlhis.Basic/Organization/Services/Implements/FactorySettingService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/FactorySettingService.cs
@@ -79,8 +79,7 @@ public class FactorySettingService : IFactorySettingService
}
else
{
- var apiResult = await _tenantApi.GetMyTenantsAsync();
- factories = apiResult.Data;
+ factories = await _tenantApi.GetMyTenantsAsync();
}
var factoryCodes = factories.Select(x => x.Code).ToList();
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs
index cc7b59e1..f7fc4a4d 100644
--- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs
@@ -8,8 +8,7 @@ using Dlhis.Entity.Basic.Enums;
using Dlhis.Entity.Device.Enums;
using Dlhis.InfoCheck.Api;
using Dlhis.InfoCheck.Api.Requests;
-using Dlhis.Scheduled.Api;
-using Dlhis.Scheduled.Api.Request;
+using Dlhis.Jip.Api;
using Kurisu.AspNetCore.Authentication.Abstractions;
using Kurisu.AspNetCore.CustomClass;
using Kurisu.AspNetCore.DataAccess.Extensions;
@@ -28,11 +27,11 @@ public class GainfoFaceService : IGainfoFaceService
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
private readonly ICurrentUser _currentUser;
- private readonly IHangfireApi _hangfireApi;
private readonly IDevicePermissionService _devicePermissionService;
private readonly IFactorySettingService _factorySettingService;
private readonly IHainingApi _hainingApi;
private readonly IInfoCheckApi _infoCheckApi;
+ private readonly IJinkoJipApi _jinkoJipApi;
private readonly IDataProtectionProvider _dataProtectionProvider;
public GainfoFaceService(IGainfoStore gainfoStore,
@@ -40,11 +39,11 @@ public class GainfoFaceService : IGainfoFaceService
ILogger logger,
IConfiguration configuration,
ICurrentUser currentUser,
- IHangfireApi hangfireApi,
IDevicePermissionService devicePermissionService,
IFactorySettingService factorySettingService,
IHainingApi hainingApi,
IInfoCheckApi infoCheckApi,
+ IJinkoJipApi jinkoJipApi,
IDataProtectionProvider dataProtectionProvider)
{
_gainfoStore = gainfoStore;
@@ -53,11 +52,11 @@ public class GainfoFaceService : IGainfoFaceService
_logger = logger;
_configuration = configuration;
_currentUser = currentUser;
- _hangfireApi = hangfireApi;
_devicePermissionService = devicePermissionService;
_factorySettingService = factorySettingService;
_hainingApi = hainingApi;
_infoCheckApi = infoCheckApi;
+ _jinkoJipApi = jinkoJipApi;
_dataProtectionProvider = dataProtectionProvider;
}
@@ -109,7 +108,7 @@ public class GainfoFaceService : IGainfoFaceService
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External)
.Where(x => x.IdNo == request.UserNo)
.SingleAsync();
-
+
gainfo ??= await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
.Where(x => x.IdNo == request.UserNo)
.SingleAsync();
@@ -231,11 +230,14 @@ public class GainfoFaceService : IGainfoFaceService
try
{
- await _hangfireApi.SyncFaceToSapAsync(new FaceUploadToSapRequest
+ var r = await _jinkoJipApi.SyncFaceToSapAsync(face.UserCode, face.Face);
+ if (r.OLX == "S")
{
- UserCode = face.UserCode,
- Base64 = face.Face
- });
+ await _faceDbContext.Updateable()
+ .SetColumns(x => x.IsSync == true)
+ .Where(x => x.UserCode == face.UserCode)
+ .ExecuteCommandAsync();
+ }
}
catch (Exception e)
{
@@ -372,7 +374,7 @@ public class GainfoFaceService : IGainfoFaceService
Level = (int)x.Level
}).ToList()
});
- r = result.Data;
+ r = result;
}
catch (Exception ex)
{
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs
index addbeae6..b4446cf2 100644
--- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs
@@ -6,8 +6,6 @@ using Dlhis.Entity.Basic.Enums;
using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Device.Enums;
using Dlhis.Entity.Visitor.Entity;
-using Dlhis.Scheduled.Api;
-using Dlhis.Scheduled.Api.Request;
using Dlhis.Sys.Api;
using Kurisu.AspNetCore.Authentication.Abstractions;
using Kurisu.AspNetCore.DataAccess.Dto;
@@ -26,7 +24,7 @@ public class GainfoService : IGainfoService
private readonly IDataProtectionProvider _dataProtectionProvider;
private readonly ICurrentUser _currentUser;
private readonly ITenantApi _tenantApi;
- private readonly IHangfireApi _hangfireApi;
+ private readonly IJinkoSapService _jinkoSapService;
private readonly IDevicePermissionService _devicePermissionService;
private readonly IGainfoPermissionService _gainfoPermissionService;
private readonly ILogger _logger;
@@ -36,7 +34,7 @@ public class GainfoService : IGainfoService
IDataProtectionProvider dataProtectionProvider,
ICurrentUser currentUser,
ITenantApi tenantApi,
- IHangfireApi hangfireApi,
+ IJinkoSapService jinkoSapService,
IDevicePermissionService devicePermissionService,
IGainfoPermissionService gainfoPermissionService,
ILogger logger)
@@ -46,7 +44,7 @@ public class GainfoService : IGainfoService
_dataProtectionProvider = dataProtectionProvider;
_currentUser = currentUser;
_tenantApi = tenantApi;
- _hangfireApi = hangfireApi;
+ _jinkoSapService = jinkoSapService;
_devicePermissionService = devicePermissionService;
_gainfoPermissionService = gainfoPermissionService;
_logger = logger;
@@ -166,8 +164,7 @@ public class GainfoService : IGainfoService
.Select()
.ToPageListAsync(new PageDto { PageIndex = 1, PageSize = 1 });
- var tenantsResult = await _tenantApi.GetTenantsInternalAsync();
- var tenants = tenantsResult.Data;
+ var tenants = await _tenantApi.GetTenantsInternalAsync();
page.Data.ForEach(x =>
{
@@ -191,8 +188,9 @@ public class GainfoService : IGainfoService
if (gainfo == null)
{
//开启同步处理
- await _hangfireApi.SyncSapPersonAsync(new SapNoRequest { Code = code });
- return null;
+ await _jinkoSapService.GetPersonsByCodeAsync(code);
+ gainfo = await _gainfoStore.Queryable().Where(x => x.Code == code).SingleAsync();
+ if (gainfo == null) return null;
}
var info = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
@@ -217,11 +215,8 @@ public class GainfoService : IGainfoService
{
try
{
- var tenantResult = await _tenantApi.GetTenantByCodeAsync(info.Factory);
- if (tenantResult is { Data: not null })
- {
- info.FactoryName = tenantResult.Data.Name;
- }
+ var tenant = await _tenantApi.GetTenantByCodeAsync(info.Factory);
+ info.FactoryName = tenant?.Name;
}
catch (Exception)
{
@@ -408,8 +403,7 @@ public class GainfoService : IGainfoService
try
{
- var tenantsResult = await _tenantApi.GetTenantsInternalAsync();
- var tenants = tenantsResult.Data;
+ var tenants = await _tenantApi.GetTenantsInternalAsync();
info.Workplace = tenants.FirstOrDefault(x => x.Code == info.Workplace)?.Name;
info.Factory = tenants.FirstOrDefault(x => x.Code == info.Factory)?.Name;
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs
new file mode 100644
index 00000000..5681b72c
--- /dev/null
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs
@@ -0,0 +1,506 @@
+using Dlhis.Basic.Device.Services;
+using Dlhis.Basic.Organization.Comparers;
+using Dlhis.Entity.Basic.Entity;
+using Dlhis.Entity.Basic.Enums;
+using Dlhis.Jip.Api.Dto;
+using Dlhis.Sys.Api;
+using Dlhis.Sys.Api.Response;
+using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
+using Kurisu.AspNetCore.Utils.Extensions;
+
+namespace Dlhis.Basic.Organization.Services.Implements;
+
+public class GainfoUpdateService : IGainfoUpdateService
+{
+ private readonly IDbContext _dbContext;
+ private readonly ILogger _logger;
+ private readonly ITenantApi _tenantApi;
+ private readonly IJinkoSapService _jinkoSapService;
+ private readonly IDevicePermissionService _devicePermissionService;
+ private readonly IIdentityUserSyncService _identityUserSyncService;
+
+ private List _tenants;
+
+ public GainfoUpdateService(IDbContext dbContext,
+ ILogger logger,
+ ITenantApi tenantApi,
+ IJinkoSapService jinkoSapService,
+ IDevicePermissionService devicePermissionService,
+ IIdentityUserSyncService identityUserSyncService)
+ {
+ _dbContext = dbContext;
+ _dbContext.Client.QueryFilter.Clear();
+ _logger = logger;
+ _tenantApi = tenantApi;
+ _jinkoSapService = jinkoSapService;
+ _devicePermissionService = devicePermissionService;
+ _identityUserSyncService = identityUserSyncService;
+ }
+
+
+ public async Task TodoByWerkAsync(string werk)
+ {
+ var werkInfo = await _dbContext.Queryable().Where(x => x.Werk == werk).SingleAsync();
+ werkInfo.LastSyncStartTime = DateTime.Now;
+ werkInfo.HandleMessage = "任务执行中";
+ await _dbContext.UpdateAsync(werkInfo);
+
+ try
+ {
+ var personResp = await _jinkoSapService.GetPersonsByWerkAsync(werk);
+ var persons = personResp.Person.Items;
+
+ werkInfo.HandleMessage = "SAP人员数量" + persons.Count;
+ werkInfo.Total = persons.Count;
+ await _dbContext.UpdateAsync(werkInfo);
+
+ if (persons.Count > 0)
+ {
+ var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
+
+ werkInfo.HandleMessage = "SAP人员差异数量" + modifiedPersons.Count;
+ werkInfo.DiffNumber = modifiedPersons.Count;
+ await _dbContext.UpdateAsync(werkInfo);
+
+ if (modifiedPersons.Count > 0)
+ {
+ await SavePersonAsync(modifiedPersons);
+ }
+ }
+
+ werkInfo.HandleMessage = "同步结束";
+ werkInfo.LastSyncEndTime = DateTime.Now;
+ werkInfo.BackgroundJobKey = string.Empty;
+ await _dbContext.UpdateAsync(werkInfo);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "{werk}同步处理异常:{message}", werk, ex.Message);
+ werkInfo.HandleMessage = ex.Message;
+ werkInfo.LastSyncEndTime = DateTime.Now;
+ werkInfo.BackgroundJobKey = string.Empty;
+ await _dbContext.UpdateAsync(werkInfo);
+ }
+ }
+
+
+ public async Task TodoByCodeAsync(string code)
+ {
+ _logger.LogInformation("SAP根据学工号同步开始:{code}", code);
+
+ var personResp = await _jinkoSapService.GetPersonsByCodeAsync(code);
+ var persons = personResp.Person.Items;
+
+ _logger.LogInformation("获取SAP人员数量为:{count}", persons.Count);
+ if (persons.Count > 0)
+ {
+ var modifiedPersons = await GetModifiedPersonAsync(persons.OrderByDescending(x => x.ZSTATUS).ThenBy(x => x.ZRZRQ).ToList());
+ _logger.LogInformation("SAP人员差异数量为:{count}", modifiedPersons.Count);
+ if (modifiedPersons.Count > 0)
+ {
+ await SavePersonAsync(modifiedPersons);
+ }
+ }
+
+ _logger.LogInformation("SAP根据学工号同步结束:{code}", code);
+ }
+
+
+ private async Task SavePersonAsync(List persons)
+ {
+ _tenants = await _tenantApi.GetTenantsInternalAsync();
+
+ var workCodes = persons.Select(x => x.ZWORKCODE).ToList();
+ var chunks = workCodes.Chunk(4000).ToList();
+
+ foreach (var searchCodes in chunks)
+ {
+ _logger.LogWarning("SAP分批处理Chunk数量:{count}", searchCodes.Length);
+ var existsWorkCodes = await _dbContext.Queryable()
+ .Where(x => searchCodes.Contains(x.ename))
+ .Select(x => x.ename)
+ .ToListAsync();
+
+ var originUpdates = persons.Where(x => existsWorkCodes.Contains(x.ZWORKCODE)).ToList();
+ var existsUpdateWorkCodes = originUpdates.Select(x => x.ZWORKCODE).ToList();
+ var originInserts = persons.Where(x => searchCodes.Contains(x.ZWORKCODE)).Where(x => !existsUpdateWorkCodes.Contains(x.ZWORKCODE)).ToList();
+
+ var updates = ToGainfoSap(originUpdates);
+ var inserts = ToGainfoSap(originInserts);
+
+ foreach (var item in inserts)
+ {
+ try
+ {
+ await InsertPersonAsync(item);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "执行新增失败:{message}", ex.Message);
+ }
+ }
+
+ foreach (var item in updates)
+ {
+ try
+ {
+ var no = await _dbContext.Queryable().Where(x => x.Code == item.ename).Select(x => x.No).SingleAsync();
+ if (no.IsEmpty())
+ {
+ await InsertPersonAsync(item);
+ }
+ else
+ {
+ await UpdatePersonAsync(item);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "执行更新失败:{message}", ex.Message);
+ }
+ }
+ }
+ }
+
+ private async Task InsertPersonAsync(GainfoSapEntity item)
+ {
+ await _dbContext.InsertAsync(item);
+ var info = GainfoSapToGainfo(item);
+
+ if (item.isowner == "T")
+ {
+ await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
+ {
+ await _dbContext.InsertAsync(info);
+ await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory);
+
+ }, new List { info.No });
+ }
+ else
+ {
+ if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename))
+ {
+ await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync();
+ }
+ }
+ }
+
+ private GainfoEntity GainfoSapToGainfo(GainfoSapEntity item)
+ {
+ var info = new GainfoEntity
+ {
+ No = Guid.NewGuid().ToString(),
+ InternalNo = item.PERNR,
+ Type = GainfoUserTypeEnumType.Normal,
+ Name = item.gname,
+ Code = item.ename,
+ CountryNo = item.country,
+ IdClass = item.idcls,
+ IdNo = item.idno,
+ Native = item.native,
+ Gender = item.sex == "F" ? GenderEnumType.Female : GenderEnumType.Male,
+ Birthday = item.birthday,
+ Address = item.address,
+ DepartmentNo = item.appellation,
+ Nation = item.nation,
+ Phone = item.phone,
+ Degree = item.email,
+ Grade = item.ZZ_ZD,
+ Title = item.Z_ZJ,
+ PositionNo = item.STELL,
+ Remark = item.remark,
+ Werks = item.WERKS,
+ CostId = item.KOSTL,
+ EntryDate = item.createdate,
+ ResignationDate = item.ZLZRQ,
+ CardType = SafeParseCardType(item.ZZ_KLX),
+ Workplace = _tenants.LastOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code ?? item.ZZ_GZDJDNM,
+ Factory = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code ?? item.ZZ_GZDCQNM,
+ };
+
+ return info;
+ }
+
+ private async Task UpdatePersonAsync(GainfoSapEntity item)
+ {
+ var info = GainfoSapToGainfo(item);
+ await _dbContext.Updateable().SetColumns(g => new GainfoSapEntity
+ {
+ PERNR = item.PERNR,
+ gname = item.gname,
+ phone = item.phone,
+ appellation = item.appellation,
+ isowner = item.isowner,
+ remark = item.remark,
+ email = item.email,
+ WERKS = item.WERKS,
+ KOSTL = item.KOSTL,
+ STELL = item.STELL,
+ Z_ZJ = item.Z_ZJ,
+ ZZ_ZD = item.ZZ_ZD,
+ MNTXT = item.MNTXT,
+ MASSN = item.MASSN,
+ ZSTATUS = item.ZSTATUS,
+ ZLZRQ = item.ZLZRQ,
+ STELL_NM = item.STELL_NM,
+ ZZ_KLX = item.ZZ_KLX,
+ createdate = item.createdate,
+ ZZ_GZDJDNM = item.ZZ_GZDJDNM,
+ ZZ_GZDCQNM = item.ZZ_GZDCQNM,
+ }).Where(x => x.ename == item.ename).ExecuteCommandAsync();
+
+ //获取当前在职人员
+ var gainfo = await _dbContext.Queryable().Where(x => x.Code == item.ename).SingleAsync();
+
+ var workplace = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code ?? item.ZZ_GZDJDNM;
+ var factory = _tenants.LastOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code ?? item.ZZ_GZDCQNM;
+
+ if (gainfo != null)
+ {
+ if (item.isowner == "T")
+ {
+ await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
+ {
+ await _dbContext.Updateable().SetColumns(g => new GainfoEntity
+ {
+ InternalNo = item.PERNR,
+ Name = item.gname,
+ PositionNo = item.STELL,
+ Grade = item.ZZ_ZD,
+ Title = item.Z_ZJ,
+ Phone = item.phone,
+ DepartmentNo = item.appellation,
+ Remark = item.remark,
+ Degree = item.email,
+ Werks = item.WERKS,
+ CostId = item.KOSTL,
+ EntryDate = item.createdate,
+ ResignationDate = item.ZLZRQ,
+ Workplace = workplace,
+ Factory = factory,
+ CardType = SafeParseCardType(item.ZZ_KLX)
+ }).Where(x => x.Code == item.ename).ExecuteCommandAsync();
+
+ await _identityUserSyncService.SyncAccountAsync(gainfo.Code, gainfo.Name, gainfo.IdNo, factory);
+
+ }, new List { gainfo.No });
+ }
+ else
+ {
+ await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
+ {
+ await _dbContext.Updateable().SetColumns(g => new GainfoEntity
+ {
+ InternalNo = item.PERNR,
+ Name = item.gname,
+ PositionNo = item.STELL,
+ Grade = item.ZZ_ZD,
+ Title = item.Z_ZJ,
+ Phone = item.phone,
+ DepartmentNo = item.appellation,
+ Remark = item.remark,
+ Degree = item.email,
+ Werks = item.WERKS,
+ CostId = item.KOSTL,
+ EntryDate = item.createdate,
+ ResignationDate = item.ZLZRQ,
+ Workplace = workplace,
+ Factory = factory,
+ CardType = SafeParseCardType(item.ZZ_KLX)
+ }).Where(x => x.Code == item.ename).ExecuteCommandAsync();
+
+ await _identityUserSyncService.SyncAccountAsync(gainfo.Code, gainfo.Name, gainfo.IdNo, factory);
+
+ }, new List { gainfo.No });
+
+
+ try
+ {
+ //先写入离职表
+ gainfo.IdentityUserId = (int)gainfo.Id; //记录原始id
+ gainfo.Id = 0;
+ gainfo.ResignationDate = item.ZLZRQ;
+
+ if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename))
+ {
+ await _dbContext.Client.Insertable(gainfo).AS("GainfoLeave").ExecuteCommandAsync();
+ }
+
+ gainfo.Id = gainfo.IdentityUserId;
+ await _dbContext.DeleteReallyAsync(gainfo);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "离职任务生成失败:{message}", ex.Message);
+ }
+ }
+ }
+ else
+ {
+ if (item.isowner == "T")
+ {
+ await _dbContext.InsertAsync(info);
+ await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, factory);
+ }
+ else
+ {
+ if (!await _dbContext.Queryable().AnyAsync(x => x.Code == item.ename))
+ {
+ await _dbContext.Client.Insertable(info).AS("GainfoLeave").ExecuteCommandAsync();
+ }
+ else
+ {
+ await _dbContext.Updateable().SetColumns(g => new GainfoLeaveEntity
+ {
+ InternalNo = item.PERNR,
+ Name = item.gname,
+ PositionNo = item.STELL,
+ Grade = item.ZZ_ZD,
+ Title = item.Z_ZJ,
+ Phone = item.phone,
+ DepartmentNo = item.appellation,
+ Remark = item.remark,
+ Degree = item.email,
+ Werks = item.WERKS,
+ CostId = item.KOSTL,
+ EntryDate = item.createdate,
+ ResignationDate = item.ZLZRQ,
+ Workplace = workplace,
+ Factory = factory,
+ CardType = SafeParseCardType(item.ZZ_KLX)
+ }).Where(x => x.Code == item.ename).ExecuteCommandAsync();
+ }
+ }
+ }
+ }
+
+ private async Task> GetModifiedPersonAsync(List sapList)
+ {
+ var last = await LoadDataAsync();
+ if (last.Count <= 0)
+ {
+ return sapList;
+ }
+
+ var needRemove = sapList.Intersect(last, new SapPersonComparer()).ToList();
+ return sapList.Except(needRemove, new SapPersonComparer()).ToList();
+ }
+
+
+ private async Task> LoadDataAsync()
+ {
+ //var pJson = "{\"id\":0,\"ano\":null,\"class\":\"C\",\"passwd\":null,\"question\":null,\"answer\":null,\"gname\":\"岳文超\",\"ename\":\"098250\",\"country\":null,\"idcls\":\"ID\",\"idno\":\"\\\"140105200112051318\n\",\"native\":\"14010\",\"sex\":\"M\",\"birthday\":\"2001-12-05T00:00:00\",\"address\":\"\",\"postcode\":null,\"occupation\":\"99\",\"appellation\":\"00210591\",\"nation\":\"01\",\"phone\":\"13773151205\",\"fax\":null,\"mobile\":null,\"email\":\"高中/中专【失效】\",\"web\":\"\",\"vip\":null,\"sec\":null,\"cropsno\":null,\"cropname\":null,\"fancy\":null,\"remark\":\"入职时间:2023-05-05 离职时间:2023-10-30 变更原因:自离【失效】\",\"amount\":0,\"days\":0,\"consume01\":0.0000,\"consume02\":0.0000,\"consume03\":0.0000,\"consume04\":0.0000,\"log_id\":\"XX\",\"log_shift\":\"1\",\"log_date\":null,\"log_ip\":\"127.0.0.1\",\"times\":0,\"logmark\":0,\"rmcode\":null,\"mkt\":null,\"src\":null,\"isowner\":\"F\",\"createdate\":\"2023-05-05T00:00:00\",\"PERNR\":\"00281800\",\"WERKS\":\"1560\",\"ZSTATUS\":\"5\",\"KOSTL\":\"156020336\",\"ZZ_ZD\":\"3\",\"Z_ZJ\":\"T0\",\"STELL\":null,\"STELL_NM\":null,\"ZLZRQ\":\"2023-10-30T00:00:00\",\"MASSN\":\"ZD\",\"MNTXT\":\"离职\",\"MASSG\":null,\"MGTXT\":null,\"logdate\":\"2024-03-14T00:02:34\",\"updatelogdate\":null,\"guestno\":null,\"ZZ_KLX\":\"3\",\"DAT01\":null,\"ZZ_COUNNM\":null,\"ZZ_GZDJDNM\":\"海宁基地\",\"ZZ_GZDCQNM\":\"海宁尖山\"}";
+ //var gainfos = new List() { pJson.ToObject() };
+ var gainfos = await _dbContext.Queryable().ToListAsync();
+
+ return gainfos.Select(x => new SapPersonItem
+ {
+ NAME = x.gname,
+ ZWORKCODE = x.ename,
+ ZZ_SFZH = x.idno,
+ GBDAT = x.birthday,
+ ZZ_KLX = x.ZZ_KLX,
+ ZXUELI = x.email,
+ ORGEH = x.appellation,
+ ZMOBILE = x.phone,
+ ZSTATUS = x.ZSTATUS,
+ ZRZRQ = x.createdate,
+ PERNR = x.PERNR,
+ WERKS = x.WERKS,
+ KOSTL = x.KOSTL,
+ ZZ_ZD = x.ZZ_ZD,
+ Z_ZJ = x.Z_ZJ,
+ STELL = x.STELL,
+ STELL_NM = x.STELL_NM,
+ ZLZRQ = x.ZLZRQ,
+ MASSN = x.MASSN,
+ MNTXT = x.MNTXT,
+ ZZ_COUNNM = x.ZZ_COUNNM,
+ ZZ_GZDJDNM = x.ZZ_GZDJDNM,
+ ZZ_GZDCQNM = x.ZZ_GZDCQNM
+ }).ToList();
+ }
+
+
+ private static List ToGainfoSap(List data)
+ {
+ return data.Select(person =>
+ {
+ //var position = _positions.FirstOrDefault(x => x.No == person.PLANS);
+
+ var rzrq = person.ZRZRQ;
+ var lzrq = person.ZLZRQ;
+ var rmk = $"入职时间:{rzrq.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
+
+ if (lzrq != null && lzrq.Value.ToString("yyyy-MM-dd") != "1900-01-01")
+ rmk += $"离职时间:{lzrq.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture)} ";
+
+ if (!string.IsNullOrWhiteSpace(person.MGTXT))
+ rmk += $"变更原因:{person.MGTXT}";
+
+ var native = GetNative(person.ZZ_SFZH);
+ var sex = person.GESCH == "2" ? "F" : "M";
+
+ person.ZZ_SFZH = person.ZZ_SFZH?.TrimStart();
+ GainfoSapEntity o = new()
+ {
+ gname = person.NAME,
+ ename = person.ZWORKCODE,
+ idno = person.ZZ_SFZH,
+ birthday = person.GBDAT,
+ ZZ_KLX = person.ZZ_KLX,
+ email = person.ZXUELI,
+ appellation = person.ORGEH,
+ phone = person.ZMOBILE,
+ ZSTATUS = person.ZSTATUS,
+ createdate = person.ZRZRQ,
+ PERNR = person.PERNR,
+ WERKS = person.WERKS,
+ KOSTL = person.KOSTL,
+ ZZ_ZD = person.ZZ_ZD,
+ Z_ZJ = person.Z_ZJ,
+ STELL = person.STELL,
+ STELL_NM = person.STELL_NM,
+ ZLZRQ = person.ZLZRQ,
+ MASSN = person.MASSN,
+ MNTXT = person.MNTXT,
+ remark = rmk,
+ native = native,
+ sex = sex,
+ logdate = DateTime.Now,
+ isowner = int.Parse(person.ZSTATUS) < 5 ? "T" : "F",
+ @class = "C",
+ country = person.ZZ_COUNNM,
+ log_ip = "127.0.0.1",
+ log_shift = "1",
+ log_id = "XX",
+ address = "",
+ occupation = "99",
+ nation = "01",
+ idcls = "ID",
+ ZZ_COUNNM = person.ZZ_COUNNM,
+ ZZ_GZDJDNM = person.ZZ_GZDJDNM,
+ ZZ_GZDCQNM = person.ZZ_GZDCQNM,
+ };
+
+ return o;
+ }).ToList();
+ }
+
+ private static string GetNative(string idNo)
+ {
+ if (string.IsNullOrWhiteSpace(idNo) || idNo.Length < 6) return null;
+ idNo = idNo.TrimStart();
+ return idNo[..6];
+ }
+
+ private static int? SafeParseCardType(string ZZ_KLX)
+ {
+ if (int.TryParse(ZZ_KLX, out var cardType))
+ {
+ return cardType;
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.ScheduledTask/Common/GetHashCodeExtensions.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GetHashCodeExtensions.cs
similarity index 80%
rename from Src/Dlhis.ScheduledTask/Common/GetHashCodeExtensions.cs
rename to Src/Dlhis.Basic/Organization/Services/Implements/GetHashCodeExtensions.cs
index 99d3fffd..dc1fbfc1 100644
--- a/Src/Dlhis.ScheduledTask/Common/GetHashCodeExtensions.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/GetHashCodeExtensions.cs
@@ -1,4 +1,4 @@
-namespace Dlhis.ScheduledTask.Common;
+namespace Dlhis.Basic.Organization.Services.Implements;
internal static class GetHashCodeExtensions
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/IdentityUserSyncService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/IdentityUserSyncService.cs
similarity index 98%
rename from Src/Dlhis.ScheduledTask/Common/Services/Implements/IdentityUserSyncService.cs
rename to Src/Dlhis.Basic/Organization/Services/Implements/IdentityUserSyncService.cs
index ab488671..2ccbdfb8 100644
--- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/IdentityUserSyncService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/IdentityUserSyncService.cs
@@ -3,7 +3,7 @@ using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
using Kurisu.AspNetCore.Utils.Extensions;
using Microsoft.AspNetCore.Identity;
-namespace Dlhis.ScheduledTask.Common.Services.Implements;
+namespace Dlhis.Basic.Organization.Services.Implements;
public class IdentityUserSyncService : IIdentityUserSyncService
{
diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoSapService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/JinkoSapService.cs
similarity index 97%
rename from Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoSapService.cs
rename to Src/Dlhis.Basic/Organization/Services/Implements/JinkoSapService.cs
index 7cd5d5d9..521c93e8 100644
--- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/JinkoSapService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/JinkoSapService.cs
@@ -1,12 +1,12 @@
using System.Net;
using System.Text;
using Dlhis.Entity.Basic.Entity;
-using Dlhis.ScheduledTask.Common.Dto;
-using Dlhis.ScheduledTask.Common.Response;
+using Dlhis.Jip.Api.Dto;
+using Dlhis.Jip.Api.Responses;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
using Newtonsoft.Json;
-namespace Dlhis.ScheduledTask.Common.Services.Implements;
+namespace Dlhis.Basic.Organization.Services.Implements;
public class JinkoSapService : IJinkoSapService
{
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/SapBusinessTripService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/SapBusinessTripService.cs
index c587e8ac..79381e05 100644
--- a/Src/Dlhis.Basic/Organization/Services/Implements/SapBusinessTripService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/SapBusinessTripService.cs
@@ -1,139 +1,147 @@
-// using Dlhis.Entity.Basic.Entity;
-// using Dlhis.Entity.Device.Entities;
-// using Dlhis.Entity.Device.Enums;
-// using Dlhis.Entity.Sys.Entities;
-// using Dlhis.Entity.Sys.Enums;
-// using Dlhis.Entity.Visitor.Entity;
-// using Dlhis.Entity.Visitor.Enums;
-// using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
-// using SqlSugar;
-//
-// namespace Dlhis.Basic.Organization.Services.Implements;
-//
-// public class SapBusinessTripService : ISapBusinessTripService
-// {
-// private readonly IJinkoJipService _jinkoJipService;
-// private readonly IDbContext _dbContext;
-// private readonly ILogger _logger;
-//
-// public SapBusinessTripService(IJinkoJipService jinkoJipService, IDbContext dbContext , ILogger logger)
-// {
-// _jinkoJipService = jinkoJipService;
-// _dbContext = dbContext;
-// _logger = logger;
-// }
-//
-// ///
-// public async Task HandlerBusinessTripsByFactoryAsync(string factory)
-// {
-// var today = DateTime.Today;
-// var yesterday = today.AddDays(-1);
-//
-// try
-// {
-// var tripResponse = await _jinkoJipService.GetTravelInfosByFactoryAsync(today, today, factory);
-// if (!tripResponse.Items.Any())
-// {
-// return;
-// }
-//
-// foreach (var tripInfoItem in tripResponse.Items.Where(x => x.Destination.IsPresent()))
-// {
-// if (await _dbContext.Queryable().Where(x => x.Code == tripInfoItem.Code
-// && x.BeginDate == tripInfoItem.BeginDate
-// && x.EndDate == tripInfoItem.EndDate
-// && x.Destination == factory).AnyAsync())
-// {
-// continue;
-// }
-//
-// var entity = tripInfoItem.Adapt();
-// entity.Status = BusinessTripStatusEnumType.Wait;
-// await _dbContext.InsertAsync(entity);
-// }
-//
-// //获取今天和昨天的出差数据
-// var tripInfos = await _dbContext.Queryable()
-// .Where(x => (SqlFunc.DateIsSame(x.BeginDate, today) && SqlFunc.DateIsSame(x.BeginDate, today))
-// || (SqlFunc.DateIsSame(x.BeginDate, yesterday) && SqlFunc.DateIsSame(x.BeginDate, yesterday)))
-// .Where(x => !SqlFunc.IsNullOrEmpty(x.Destination))
-// .Where(x => x.Destination == factory)
-// .ToListAsync();
-//
-// //获取分组信息
-// var tripGroup = await _dbContext.Queryable()
-// .Where(x => x.Type == DeviceTypeEnumType.Door)
-// .Where(x => x.TenantId == factory)
-// .Where(x => x.IsBusinessTrip)
-// .SingleAsync();
-//
-// var userCodes = tripInfos.Select(x => x.Code).Distinct().ToList();
-// var gainfos = await _dbContext.Queryable().Where(x => userCodes.Contains(x.Code)).ToListAsync();
-//
-// foreach (var gainfo in gainfos)
-// {
-// try
-// {
-// var myTripInfos = tripInfos.Where(x => x.Code == gainfo.Code).ToList();
-//
-// var yesterdayTripInfo = myTripInfos.FirstOrDefault(x => x.BeginDate == yesterday && x.EndDate == yesterday); //昨天出差数据
-// var todayTripInfo = myTripInfos.FirstOrDefault(x => x.BeginDate == today && x.EndDate == today); //今天出差数据
-//
-// //都为空不处理
-// if (yesterdayTripInfo == null && todayTripInfo == null) continue;
-//
-// //都不为空则更新数据状态
-// if (yesterdayTripInfo != null && todayTripInfo != null)
-// {
-// todayTripInfo.Status = BusinessTripStatusEnumType.Generated;
-// await _dbContext.UpdateAsync(todayTripInfo);
-// continue;
-// }
-//
-// var beforeResult = await _devicePermissionApi.GetPermissionUsersInfoAsync(new List { gainfo.Code });
-//
-// if (yesterdayTripInfo != null)
-// {
-// yesterdayTripInfo.Status = BusinessTripStatusEnumType.Deleted;
-// await _dbContext.Updateable()
-// .SetColumns(x => x.IsDeleted == true)
-// .Where(x => x.AssignType == AssignTypeEnumType.User)
-// .Where(x => x.AssignValue == gainfo.No)
-// .Where(x => x.UniqueType == DeviceAssignmentTypeEnumType.Group)
-// .Where(x => x.UniqueValue == tripGroup.Code)
-// .Where(x => x.Type == tripGroup.Type)
-// .Where(x => x.TenantId == factory)
-// .ExecuteCommandAsync();
-// await _dbContext.UpdateAsync(yesterdayTripInfo);
-// }
-//
-// if (yesterdayTripInfo == null)
-// {
-// todayTripInfo.Status = BusinessTripStatusEnumType.Generated;
-// await _dbContext.InsertAsync(new DevicePermissionEntity
-// {
-// AssignType = AssignTypeEnumType.User,
-// AssignValue = gainfo.No,
-// UniqueType = DeviceAssignmentTypeEnumType.Group,
-// UniqueValue = tripGroup.Code,
-// TenantId = factory,
-// Type = tripGroup.Type,
-// IsDeleted = false
-// });
-// await _dbContext.UpdateAsync(todayTripInfo);
-// }
-//
-// await _devicePermissionApi.RePermissionUsersInfoAsync(beforeResult.Data);
-// }
-// catch (Exception e)
-// {
-// _logger.LogError(e, "出差自动下发任务失败:{message}", e.Message);
-// }
-// }
-// }
-// catch (Exception e)
-// {
-// _logger.LogError(e, "处理{factory}出差数据失败:{message}", factory, e.Message);
-// }
-// }
-// }
\ No newline at end of file
+using Dlhis.Basic.Device.Services;
+using Dlhis.Entity.Basic.Entity;
+using Dlhis.Entity.Device.Entities;
+using Dlhis.Entity.Device.Enums;
+using Dlhis.Entity.Sys.Entities;
+using Dlhis.Entity.Sys.Enums;
+using Dlhis.Entity.Visitor.Entity;
+using Dlhis.Entity.Visitor.Enums;
+using Dlhis.Jip.Api;
+using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
+using Kurisu.AspNetCore.Utils.Extensions;
+using Mapster;
+using SqlSugar;
+
+namespace Dlhis.Basic.Organization.Services.Implements;
+
+public class SapBusinessTripService : ISapBusinessTripService
+{
+ private readonly IJinkoJipApi _jinkoJipApi;
+ private readonly IDbContext _dbContext;
+ private readonly IDevicePermissionService _devicePermissionService;
+ private readonly ILogger _logger;
+
+ public SapBusinessTripService(IJinkoJipApi jinkoJipApi,
+ IDbContext dbContext,
+ IDevicePermissionService devicePermissionService,
+ ILogger logger)
+ {
+ _jinkoJipApi = jinkoJipApi;
+ _dbContext = dbContext;
+ _devicePermissionService = devicePermissionService;
+ _logger = logger;
+ }
+
+ ///
+ public async Task HandlerBusinessTripsByFactoryAsync(string factory)
+ {
+ var today = DateTime.Today;
+ var yesterday = today.AddDays(-1);
+
+ try
+ {
+ var tripResponse = await _jinkoJipApi.GetBusinessTripInfosByFactoryAsync(factory, today, today);
+ if (!tripResponse.Items.Any())
+ {
+ return;
+ }
+
+ foreach (var tripInfoItem in tripResponse.Items.Where(x => x.Destination.IsPresent()))
+ {
+ if (await _dbContext.Queryable().Where(x => x.Code == tripInfoItem.Code
+ && x.BeginDate == tripInfoItem.BeginDate
+ && x.EndDate == tripInfoItem.EndDate
+ && x.Destination == factory).AnyAsync())
+ {
+ continue;
+ }
+
+ var entity = tripInfoItem.Adapt();
+ entity.Status = BusinessTripStatusEnumType.Wait;
+ await _dbContext.InsertAsync(entity);
+ }
+
+ //获取今天和昨天的出差数据
+ var tripInfos = await _dbContext.Queryable()
+ .Where(x => (SqlFunc.DateIsSame(x.BeginDate, today) && SqlFunc.DateIsSame(x.BeginDate, today))
+ || (SqlFunc.DateIsSame(x.BeginDate, yesterday) && SqlFunc.DateIsSame(x.BeginDate, yesterday)))
+ .Where(x => !SqlFunc.IsNullOrEmpty(x.Destination))
+ .Where(x => x.Destination == factory)
+ .ToListAsync();
+
+ //获取分组信息
+ var tripGroup = await _dbContext.Queryable()
+ .Where(x => x.Type == DeviceTypeEnumType.Door)
+ .Where(x => x.TenantId == factory)
+ .Where(x => x.IsBusinessTrip)
+ .SingleAsync();
+
+ var userCodes = tripInfos.Select(x => x.Code).Distinct().ToList();
+ var gainfos = await _dbContext.Queryable().Where(x => userCodes.Contains(x.Code)).Select(x => new { x.No, x.Code }).ToListAsync();
+
+ foreach (var gainfo in gainfos)
+ {
+ try
+ {
+ var myTripInfos = tripInfos.Where(x => x.Code == gainfo.Code).ToList();
+
+ var yesterdayTripInfo = myTripInfos.FirstOrDefault(x => x.BeginDate == yesterday && x.EndDate == yesterday); //昨天出差数据
+ var todayTripInfo = myTripInfos.FirstOrDefault(x => x.BeginDate == today && x.EndDate == today); //今天出差数据
+
+ //都为空不处理
+ if (yesterdayTripInfo == null && todayTripInfo == null) continue;
+
+ //都不为空则更新数据状态
+ if (yesterdayTripInfo != null && todayTripInfo != null)
+ {
+ todayTripInfo.Status = BusinessTripStatusEnumType.Generated;
+ await _dbContext.UpdateAsync(todayTripInfo);
+ continue;
+ }
+
+ await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
+ {
+ if (yesterdayTripInfo != null)
+ {
+ yesterdayTripInfo.Status = BusinessTripStatusEnumType.Deleted;
+ await _dbContext.Updateable()
+ .SetColumns(x => x.IsDeleted == true)
+ .Where(x => x.AssignType == AssignTypeEnumType.User)
+ .Where(x => x.AssignValue == gainfo.No)
+ .Where(x => x.UniqueType == DeviceAssignmentTypeEnumType.Group)
+ .Where(x => x.UniqueValue == tripGroup.Code)
+ .Where(x => x.Type == tripGroup.Type)
+ .Where(x => x.TenantId == factory)
+ .ExecuteCommandAsync();
+ await _dbContext.UpdateAsync(yesterdayTripInfo);
+ }
+
+ if (yesterdayTripInfo == null)
+ {
+ todayTripInfo.Status = BusinessTripStatusEnumType.Generated;
+ await _dbContext.InsertAsync(new DevicePermissionEntity
+ {
+ AssignType = AssignTypeEnumType.User,
+ AssignValue = gainfo.No,
+ UniqueType = DeviceAssignmentTypeEnumType.Group,
+ UniqueValue = tripGroup.Code,
+ TenantId = factory,
+ Type = tripGroup.Type,
+ IsDeleted = false
+ });
+ await _dbContext.UpdateAsync(todayTripInfo);
+ }
+ }, new List { gainfo.No });
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "出差自动下发任务失败:{message}", e.Message);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "处理{factory}出差数据失败:{message}", factory, e.Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs
index 132f2323..356aec3e 100644
--- a/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs
+++ b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs
@@ -35,8 +35,7 @@ public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService
})
.ToPageListAsync(request);
- var usersResult = await _userApi.GetUserByIdsAsync(page.Data.Select(x => x.UserId).Distinct().ToList());
- var users = usersResult.Data;
+ var users = await _userApi.GetUserByIdsAsync(page.Data.Select(x => x.UserId).Distinct().ToList());
page.Data.ForEach(item => { item.UserName = users.FirstOrDefault(x => x.Id == item.UserId)?.UserName; });
@@ -98,9 +97,7 @@ public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService
})
.ToListAsync();
- var userResult = await _userApi.GetUserByIdAsync(id);
- var user = userResult.Data;
-
+ var user = await _userApi.GetUserByIdAsync(id);
infos.ForEach(item => { item.UserName = user?.UserName; });
return infos;
diff --git a/Src/Dlhis.Basic/appsettings.Development.json b/Src/Dlhis.Basic/appsettings.Development.json
index c22992e5..47d1cb6f 100644
--- a/Src/Dlhis.Basic/appsettings.Development.json
+++ b/Src/Dlhis.Basic/appsettings.Development.json
@@ -22,7 +22,7 @@
"Timeout": 30,
"SlowSqlTime": 1,
"EnableSqlLog": true,
- "Generate": true
+ "Generate": false
},
"SwaggerOptions": {
"Enable": true,
diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs
index ddeb8fca..0e2094cf 100644
--- a/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs
+++ b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs
@@ -69,8 +69,7 @@ public class MealSupplementRecordService : IMealSupplementRecordService
var tenants = new List();
try
{
- var tenantsResult = await _tenantApi.GetTenantsInternalAsync();
- tenants = tenantsResult.Data;
+ tenants = await _tenantApi.GetTenantsInternalAsync();
}
catch (Exception)
{
diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
index 4253b7ff..b65df1a1 100644
--- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
+++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
@@ -93,8 +93,7 @@ public class BalanceService : IBalanceService
try
{
- var tenantResult = await _tenantApi.GetTenantsInternalAsync();
- var tenants = tenantResult.Data;
+ var tenants = await _tenantApi.GetTenantsInternalAsync();
page.Data.ForEach(item =>
{
@@ -233,7 +232,7 @@ public class BalanceService : IBalanceService
public async Task RecordPageDetailsAsync(BalanceRecordPageDetailRequest request)
{
- var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Data.Select(x => (Guid?)x.Code).ToList();
+ var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Select(x => (Guid?)x.Code).ToList();
if (request.BusinessplaceCodes.IsPresent())
{
myCodes = myCodes.Where(x => request.BusinessplaceCodes.Contains(x)).ToList();
@@ -272,9 +271,7 @@ public class BalanceService : IBalanceService
try
{
- var tenantResult = await _tenantApi.GetTenantsInternalAsync();
- var tenants = tenantResult.Data;
-
+ var tenants = await _tenantApi.GetTenantsInternalAsync();
page.Data.ForEach(item => { item.Factory = tenants.FirstOrDefault(x => x.Code == item.Factory)?.Name; });
}
catch (Exception)
@@ -538,6 +535,8 @@ public class BalanceService : IBalanceService
Werks = gainfo.Werks,
IsDeleted = false
});
+
+ await _balanceRepository.CalculateBalanceAsync(gainfo.Code);
}
}
diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
index 6ba97b8f..9bb02d33 100644
--- a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
+++ b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
@@ -132,14 +132,10 @@ public class OrderService : IOrderService
private async Task CheckPermissionAsync(string userCode, string deviceUniqueNo)
{
- var r = await _gainfoPermissionApi.GetPermissionsDeviceCodesAsync(userCode);
- if (r.Code != Kurisu.RemoteCall.Default.ApiStateCode.Success)
- {
- true.ThrowIfTrue(r.Msg);
- }
+ var data = await _gainfoPermissionApi.GetPermissionsDeviceCodesAsync(userCode);
var code = await _dbContext.Queryable().Where(x => x.UniqueNo == deviceUniqueNo).Select(x => x.Code).SingleAsync();
- r.Data.Contains(code).ThrowIfFalse("无权消费");
+ data.Contains(code).ThrowIfFalse("无权消费");
}
diff --git a/Src/Dlhis.InfoCheck.Api/Dlhis.InfoCheck.Api.csproj b/Src/Dlhis.InfoCheck.Api/Dlhis.InfoCheck.Api.csproj
index cf75c67b..938a97d6 100644
--- a/Src/Dlhis.InfoCheck.Api/Dlhis.InfoCheck.Api.csproj
+++ b/Src/Dlhis.InfoCheck.Api/Dlhis.InfoCheck.Api.csproj
@@ -3,11 +3,11 @@
net6.0
enable
- enable
+ disable
-
+
diff --git a/Src/Dlhis.InfoCheck.Api/IInfoCheckApi.cs b/Src/Dlhis.InfoCheck.Api/IInfoCheckApi.cs
index 8a015a57..91d853cc 100644
--- a/Src/Dlhis.InfoCheck.Api/IInfoCheckApi.cs
+++ b/Src/Dlhis.InfoCheck.Api/IInfoCheckApi.cs
@@ -1,12 +1,12 @@
using Dlhis.InfoCheck.Api.Requests;
using Kurisu.RemoteCall.Attributes;
-using Kurisu.RemoteCall.Default;
namespace Dlhis.InfoCheck.Api;
///
/// 信息检查
///
+[RequestResultHandler]
[EnableRemoteClient(Name = "infocheck-service", BaseUrl = "${InternalRequest:InfoCheckRequestUrl}")]
public interface IInfoCheckApi
{
@@ -16,5 +16,5 @@ public interface IInfoCheckApi
///
///
[Post("/api/face/detection")]
- Task>> FaceDetectAsync(FaceDetectRequest request);
+ Task> FaceDetectAsync(FaceDetectRequest request);
}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/ClientHandlers/JipClientHandler.cs b/Src/Dlhis.Jip.Api/ClientHandlers/JipClientHandler.cs
new file mode 100644
index 00000000..d445d79d
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/ClientHandlers/JipClientHandler.cs
@@ -0,0 +1,13 @@
+using Kurisu.RemoteCall.Abstractions;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Dlhis.Jip.Api.ClientHandlers;
+
+public class JipClientHandler : IHttpRemoteCallPolicyHandler
+{
+ ///
+ public IHttpClientBuilder ConfigureHttpClient(IHttpClientBuilder builder)
+ {
+ return builder;
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/ClientHandlers/JipTokenHandler.cs b/Src/Dlhis.Jip.Api/ClientHandlers/JipTokenHandler.cs
new file mode 100644
index 00000000..e1a68d48
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/ClientHandlers/JipTokenHandler.cs
@@ -0,0 +1,47 @@
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+using Kurisu.RemoteCall.Abstractions;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.IdentityModel.Tokens;
+
+namespace Dlhis.Jip.Api.ClientHandlers;
+
+public class JipTokenHandler : IAsyncAuthTokenHandler
+{
+ ///
+ public async Task GetTokenAsync(IServiceProvider serviceProvider)
+ {
+ var configuration = serviceProvider.GetService()!;
+
+ var jwtKey = configuration.GetSection("JinkoOptions:Jip:Key").Value;
+ var jwtSecret = configuration.GetSection("JinkoOptions:Jip:Secret").Value;
+ const int min = 5;
+
+ var now = DateTime.Now.AddMinutes(-min);
+ var expires = DateTime.Now.AddMinutes(min);
+
+ var claims = new List
+ {
+ new(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(now).ToUnixTimeSeconds()}"),
+ new(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(expires).ToUnixTimeSeconds()}"),
+ new(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 await Task.FromResult(jwtHandler.WriteToken(securityToken));
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/Dlhis.Jip.Api.csproj b/Src/Dlhis.Jip.Api/Dlhis.Jip.Api.csproj
new file mode 100644
index 00000000..bc9c9c83
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dlhis.Jip.Api.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/Src/Dlhis.Jip.Api/Dto/SapOrganization.cs b/Src/Dlhis.Jip.Api/Dto/SapOrganization.cs
new file mode 100644
index 00000000..d1c7df5c
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapOrganization.cs
@@ -0,0 +1,15 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.Dto;
+
+///
+/// sap机构信息
+///
+public class SapOrganization
+{
+ ///
+ /// 机构项
+ ///
+ [JsonProperty("item")]
+ public List Items { get; set; }
+}
diff --git a/Src/Dlhis.Jip.Api/Dto/SapOrganizationItem.cs b/Src/Dlhis.Jip.Api/Dto/SapOrganizationItem.cs
new file mode 100644
index 00000000..1f8d6ce3
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapOrganizationItem.cs
@@ -0,0 +1,66 @@
+namespace Dlhis.Jip.Api.Dto;
+
+public class SapOrganizationItem
+{
+ ///
+ /// 开始日期
+ ///
+ public string BEGDA { get; set; }
+
+ ///
+ /// 结束日期
+ ///
+ public string ENDDA { get; set; }
+
+ ///
+ /// 语言
+ ///
+ public string 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.Jip.Api/Dto/SapPerson.cs b/Src/Dlhis.Jip.Api/Dto/SapPerson.cs
new file mode 100644
index 00000000..3f7d981a
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapPerson.cs
@@ -0,0 +1,9 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.Dto;
+
+public class SapPerson
+{
+ [JsonProperty("item")]
+ public List Items { get; set; }
+}
diff --git a/Src/Dlhis.Jip.Api/Dto/SapPersonDepartmentStatus.cs b/Src/Dlhis.Jip.Api/Dto/SapPersonDepartmentStatus.cs
new file mode 100644
index 00000000..7e493f9c
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapPersonDepartmentStatus.cs
@@ -0,0 +1,19 @@
+// namespace Dlhis.ScheduledTask.Common.Dto
+// {
+// public class SapPersonDepartmentStatus
+// {
+// public string ZWORKCODE { get; set; }
+//
+// public DateTime BEGDA { get; set; }
+//
+// public DateTime ENDDA { get; set; }
+//
+// public string WERKS { get; set; }
+//
+// ///
+// /// 部门号
+// ///
+// public string ORGEH { get; set; }
+//
+// }
+// }
diff --git a/Src/Dlhis.Jip.Api/Dto/SapPersonItem.cs b/Src/Dlhis.Jip.Api/Dto/SapPersonItem.cs
new file mode 100644
index 00000000..a20b2862
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapPersonItem.cs
@@ -0,0 +1,211 @@
+namespace Dlhis.Jip.Api.Dto;
+
+public class SapPersonItem
+{
+ public string KOSTL { get; set; }
+
+ ///
+ /// 离职日期
+ ///
+ public DateTime? 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 DateTime 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 DateTime 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 string ZZ_COUNNM { get; set; }
+
+ ///
+ /// 基地
+ ///
+ public string ZZ_GZDJDNM { get; set; }
+
+ ///
+ /// 厂区
+ ///
+ public string ZZ_GZDCQNM { get; set; }
+}
diff --git a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonJobStatus.cs b/Src/Dlhis.Jip.Api/Dto/SapPersonJobStatus.cs
similarity index 87%
rename from Src/Dlhis.ScheduledTask/Common/Dto/SapPersonJobStatus.cs
rename to Src/Dlhis.Jip.Api/Dto/SapPersonJobStatus.cs
index 8ec20753..2db345de 100644
--- a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonJobStatus.cs
+++ b/Src/Dlhis.Jip.Api/Dto/SapPersonJobStatus.cs
@@ -1,4 +1,4 @@
-// namespace Dlhis.ScheduledTask.Common.Dto
+// namespace Dlhis.ScheduledTask.Common.Dto
// {
// public class SapPersonJobStatus
// {
diff --git a/Src/Dlhis.Jip.Api/Dto/SapPosition.cs b/Src/Dlhis.Jip.Api/Dto/SapPosition.cs
new file mode 100644
index 00000000..31dadb5f
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapPosition.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.Dto;
+
+public class SapPosition
+{
+
+ [JsonProperty("item")]
+ public List Items { get; set; }
+}
diff --git a/Src/Dlhis.Jip.Api/Dto/SapPositionItem.cs b/Src/Dlhis.Jip.Api/Dto/SapPositionItem.cs
new file mode 100644
index 00000000..c04d44f2
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Dto/SapPositionItem.cs
@@ -0,0 +1,40 @@
+namespace Dlhis.Jip.Api.Dto
+{
+ public class SapPositionItem
+ {
+ ///
+ /// 开始日期
+ ///
+ public string BEGDA { get; set; }
+
+ ///
+ /// 结束日期
+ ///
+ public string ENDDA { get; set; }
+
+ ///
+ /// 语言代码
+ ///
+ public string LANGU { get; set; }
+
+ ///
+ /// 岗位编码
+ ///
+ public string ZJOBID { get; set; }
+
+ ///
+ /// 岗位名称
+ ///
+ public string ZJOBNAME { get; set; }
+
+ ///
+ ///
+ ///
+ public string ZZWID { get; set; }
+
+ ///
+ /// 所属部门ID
+ ///
+ public string ZDEPID { get; set; }
+ }
+}
diff --git a/Src/Dlhis.Jip.Api/IJinkoJipApi.cs b/Src/Dlhis.Jip.Api/IJinkoJipApi.cs
new file mode 100644
index 00000000..0ef5ac07
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/IJinkoJipApi.cs
@@ -0,0 +1,86 @@
+using Dlhis.Jip.Api.ClientHandlers;
+using Dlhis.Jip.Api.Request;
+using Dlhis.Jip.Api.RequestContentHandlers;
+using Dlhis.Jip.Api.Requests;
+using Dlhis.Jip.Api.Responses;
+using Dlhis.Jip.Api.ResultHandlers;
+using Kurisu.RemoteCall.Attributes;
+
+namespace Dlhis.Jip.Api;
+
+///
+/// jinko-jip api https://jip.jinkosolar.com
+///
+[Auth(TokenHandler = typeof(JipTokenHandler))]
+[EnableRemoteClient(Name = "jip-service", BaseUrl = "${JinkoOptions:Jip:BaseUrl}", PolicyHandler = typeof(JipClientHandler))]
+public interface IJinkoJipApi
+{
+ ///
+ /// 上传考勤记录
+ ///
+ ///
+ ///
+ [Post("/JIP/HCM/HCM_SWIPE_DATA_SAVE")]
+ Task UploadAttendancesAsync(UploadAttendanceRequest request);
+
+ ///
+ /// 获取出差信息
+ ///
+ /// 厂区
+ /// 开始时间
+ /// 结束时间
+ ///
+ /// var obj = new
+ /// {
+ /// I_PAGE = 1,
+ /// I_LINE = 500,
+ /// IV_BEGDA = beginDay,
+ /// IV_ENDDA = endDay,
+ /// IT_CCMDD = new List{object}
+ /// {
+ /// new
+ /// {
+ /// IV_CCMDD = factory
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///var obj = new
+ ///{
+ /// IV_BEGDA = beginDay,
+ /// IV_ENDDA = endDay,
+ /// IT_2002GH = new List{object}
+ /// {
+ /// new
+ /// {
+ /// IV_GONGH = userCode
+ /// }
+ /// }
+ ///};
+ ///
+ ///
+ [Post("/JIP/HCM/HCM_TRAVELINFO")]
+ [RequestContentHandler(typeof(BusinessTripContentHandler))]
+ Task GetBusinessTripInfosByFactoryAsync(string factory, DateTime start, DateTime end);
+
+
+ ///
+ /// 同步餐补状态
+ ///
+ ///
+ ///
+ [Post("/JIP/DHR/DHR_DL_CALLBACK")]
+ [RequestResultHandler(typeof(DHRResultHandler))]
+ Task SyncMealSupplementRecordsAsync(List requests);
+
+ ///
+ /// 同步照片到sap
+ ///
+ ///
+ ///
+ ///
+ [Post("/JIP/HCM/HCM_I_PHOTO")]
+ [RequestContentHandler(typeof(SyncFaceContentHandler))]
+ Task SyncFaceToSapAsync(string userCode, string base64);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/RequestContentHandlers/BusinessTripContentHandler.cs b/Src/Dlhis.Jip.Api/RequestContentHandlers/BusinessTripContentHandler.cs
new file mode 100644
index 00000000..92f94fe9
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/RequestContentHandlers/BusinessTripContentHandler.cs
@@ -0,0 +1,36 @@
+using System.Text;
+using Kurisu.RemoteCall;
+using Kurisu.RemoteCall.Abstractions;
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.RequestContentHandlers;
+
+public class BusinessTripContentHandler : IContentHandler
+{
+ ///
+ public HttpContent Create(List values)
+ {
+ var factory = values.First(x => x.Parameter.Name.Equals("factory", StringComparison.OrdinalIgnoreCase)).GetValue();
+ var start = values.First(x => x.Parameter.Name.Equals("start", StringComparison.OrdinalIgnoreCase)).GetValue().ToString("yyyy-MM-dd");
+ var end = values.First(x => x.Parameter.Name.Equals("end", StringComparison.OrdinalIgnoreCase)).GetValue().ToString("yyyy-MM-dd");
+
+ var obj = new
+ {
+ I_PAGE = 1,
+ I_LINE = 500,
+ IV_BEGDA = start,
+ IV_ENDDA = end,
+ IT_CCMDD = new List