diff --git a/Src/Dlhis.Basic/Organization/Response/WerkPageResponse.cs b/Src/Dlhis.Basic/Organization/Response/WerkPageResponse.cs index 82105723..5277d6f3 100644 --- a/Src/Dlhis.Basic/Organization/Response/WerkPageResponse.cs +++ b/Src/Dlhis.Basic/Organization/Response/WerkPageResponse.cs @@ -1,4 +1,7 @@ -namespace Dlhis.Basic.Organization.Response; +using Kurisu.AspNetCore.Utils.Extensions; +using Newtonsoft.Json; + +namespace Dlhis.Basic.Organization.Response; public class WerkPageResponse { @@ -43,4 +46,13 @@ public class WerkPageResponse /// 处理消息 /// public string HandleMessage { get; set; } + + + [JsonIgnore] + public string BackgroundJobKey { get; set; } + + /// + /// 是否允许同步 + /// + public bool AbleSync => BackgroundJobKey.IsEmpty(); } diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs index 77e36c61..67ed5c23 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs @@ -22,8 +22,10 @@ namespace Dlhis.Canteen.Order.Services.Implements; public class OrderService : BaseOrderService, IOrderService { - public OrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext, - ICurrentUser currentUser, IDevicePermissionApi devicePermissionApi, + public OrderService(ICanteenSettingService canteenSettingService, + IDbContext dbContext, + ICurrentUser currentUser, + IDevicePermissionApi devicePermissionApi, ILogger logger) : base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger) { diff --git a/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs index e1fbc481..26296b5a 100644 --- a/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs @@ -170,8 +170,21 @@ public class GainfoEntity : SugarBaseEntity /// /// 成本中心 /// + [SugarColumn(ColumnDescription = "成本中心")] public string CostId { get; set; } + /// + /// 入职日期 + /// + [SugarColumn(IsNullable = true, ColumnDescription = "入职日期", ColumnDataType = "date")] + public DateTime? EntryDate { get; set; } + + /// + /// 离职日期 + /// + [SugarColumn(IsNullable = true, ColumnDescription = "离职日期", ColumnDataType = "date")] + public DateTime? ResignationDate { get; set; } + /// /// 身份认证用户Id(如果为空匹配code) /// diff --git a/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs index 710ad6b7..e6a22c77 100644 --- a/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoSap.cs @@ -63,6 +63,10 @@ public class GainfoSapEntity public string mkt { get; set; } public string src { get; set; } public string isowner { get; set; } + + /// + /// 入职日期 + /// public DateTime createdate { get; set; } public string PERNR { get; set; } @@ -81,6 +85,9 @@ public class GainfoSapEntity public string STELL_NM { get; set; } + /// + /// 离职日期 + /// public DateTime? ZLZRQ { get; set; } public string MASSN { get; set; } diff --git a/Src/Dlhis.Entity/Basic/Enums/MealSupplementStatusEnumtype.cs b/Src/Dlhis.Entity/Basic/Enums/MealSupplementStatusEnumtype.cs index 6de28a57..6fb26421 100644 --- a/Src/Dlhis.Entity/Basic/Enums/MealSupplementStatusEnumtype.cs +++ b/Src/Dlhis.Entity/Basic/Enums/MealSupplementStatusEnumtype.cs @@ -14,12 +14,11 @@ public enum MealSupplementStatusEnumtype [Description("待核算")] Wait = 0, - /// /// 成功 /// [Description("成功")] - Sucess = 1, + Success = 1, /// /// 处理异常 diff --git a/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs index 7875ae74..45f29262 100644 --- a/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs @@ -38,6 +38,7 @@ public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity /// /// 状态同步 /// + [SugarColumn(ColumnDataType = "bit")] public bool Sync { get; set; } } diff --git a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonNoRequest.cs b/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonNoRequest.cs deleted file mode 100644 index 1628cac6..00000000 --- a/Src/Dlhis.ScheduledTask/Common/Dto/SapPersonNoRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Dlhis.ScheduledTask.Common.Dto; - -public class SapPersonNoRequest -{ - - [Required] - public string Code { get; set; } -} diff --git a/Src/Dlhis.ScheduledTask/Common/Request/SapPersonNoRequest.cs b/Src/Dlhis.ScheduledTask/Common/Request/SapPersonNoRequest.cs new file mode 100644 index 00000000..218bef09 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/Common/Request/SapPersonNoRequest.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.ScheduledTask.Common.Request; + +public class SapNoRequest +{ + /// + /// Code + /// + [Required(ErrorMessage = "编号不能为空")] + public string Code { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/Common/Services/IHangfireService.cs b/Src/Dlhis.ScheduledTask/Common/Services/IHangfireService.cs index f2b92964..12388cb6 100644 --- a/Src/Dlhis.ScheduledTask/Common/Services/IHangfireService.cs +++ b/Src/Dlhis.ScheduledTask/Common/Services/IHangfireService.cs @@ -1,4 +1,4 @@ -using Dlhis.ScheduledTask.Common.Dto; +using Dlhis.ScheduledTask.Common.Request; namespace Dlhis.ScheduledTask.Common.Services; @@ -12,5 +12,12 @@ public interface IHangfireService : ISingletonDependency /// /// /// - Task CreateSapPersonSyncBackgroundJobAsync(SapPersonNoRequest request); + Task CreateSapPersonSyncBackgroundJobAsync(SapNoRequest request); + + /// + /// 创建sap人事范围同步后台任务 + /// + /// + /// + Task CreateSapWerkSyncBackgroundJobAsync(SapNoRequest request); } diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs index 3dfd86b9..645d439e 100644 --- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs +++ b/Src/Dlhis.ScheduledTask/Common/Services/Implements/GainfoUpdateService.cs @@ -8,7 +8,6 @@ using Dlhis.Sys.Api.Response; using Dlhis.ScheduledTask.Common.Dto; using Dlhis.ScheduledTask.Common.Comparers; using Kurisu.AspNetCore.Utils.Extensions; -using Dlhis.ScheduledTask.Common.Response; using Dlhis.Basic.Api.Dtos; namespace Dlhis.ScheduledTask.Common.Services.Implements; @@ -247,7 +246,7 @@ public class GainfoUpdateService : IGainfoUpdateService IdNo = item.idno, Native = item.native, Gender = item.sex == "F" ? GenderEnumType.Female : GenderEnumType.Male, - Birthday = (DateTime)item.birthday, + Birthday = item.birthday, Address = item.address, DepartmentNo = item.appellation, Nation = item.nation, @@ -259,6 +258,8 @@ public class GainfoUpdateService : IGainfoUpdateService Remark = item.remark, Werks = item.WERKS, CostId = item.KOSTL, + EntryDate = item.createdate, + ResignationDate = item.ZLZRQ, Workplace = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDJDNM)?.Code ?? item.ZZ_GZDJDNM, Factory = _tenants.FirstOrDefault(x => x.Name == item.ZZ_GZDCQNM)?.Code ?? item.ZZ_GZDCQNM, }; @@ -296,6 +297,7 @@ public class GainfoUpdateService : IGainfoUpdateService .Where(x => x.ename == item.ename) .ExecuteCommandAsync(); + //获取当前在职人员 var gainfo = await _dbContext.Queryable().Where(x => x.Code == item.ename).FirstAsync(); if (item.isowner == "T") { @@ -316,6 +318,8 @@ public class GainfoUpdateService : IGainfoUpdateService Degree = item.email, Werks = item.WERKS, CostId = item.KOSTL, + EntryDate = item.createdate, + ResignationDate = item.ZLZRQ, Workplace = workplace, Factory = factory }) @@ -332,9 +336,13 @@ public class GainfoUpdateService : IGainfoUpdateService { if (gainfo != null) { - await _dbContext.DeleteReallyAsync(gainfo); + //先写入离职表 + gainfo.IdentityUserId = (int)gainfo.Id; gainfo.Id = 0; + gainfo.ResignationDate = item.ZLZRQ; + await _dbContext.Client.Insertable(gainfo).AS("GainfoLeave").ExecuteCommandAsync(); + await _dbContext.DeleteReallyAsync(gainfo); } } diff --git a/Src/Dlhis.ScheduledTask/Common/Services/Implements/HangfireService.cs b/Src/Dlhis.ScheduledTask/Common/Services/Implements/HangfireService.cs index 13dfb4b7..ce72897a 100644 --- a/Src/Dlhis.ScheduledTask/Common/Services/Implements/HangfireService.cs +++ b/Src/Dlhis.ScheduledTask/Common/Services/Implements/HangfireService.cs @@ -1,21 +1,26 @@ -using Dlhis.ScheduledTask.Common.Dto; +using Dlhis.Entity.Basic.Entity; +using Dlhis.ScheduledTask.Common.Request; using Hangfire; using Kurisu.AspNetCore.Utils; +using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.SqlSugar.Services; namespace Dlhis.ScheduledTask.Common.Services.Implements; public class HangfireService : IHangfireService { private readonly RedisCache _redisCache; + private readonly IDbContext _dbContext; - public HangfireService(RedisCache redisCache) + public HangfireService(RedisCache redisCache, IDbContext dbContext) { _redisCache = redisCache; + _dbContext = dbContext; } - public async Task CreateSapPersonSyncBackgroundJobAsync(SapPersonNoRequest request) + public async Task CreateSapPersonSyncBackgroundJobAsync(SapNoRequest request) { - var jobKey = $"hangfire:background:{request.Code}"; + var jobKey = $"hangfire:background:person:{request.Code}"; using var handler = await _redisCache.LockAsync(jobKey); if (handler.Acquired) @@ -23,4 +28,20 @@ public class HangfireService : IHangfireService BackgroundJob.Enqueue(x => x.TodoByCodeAsync(request.Code)); } } + + public async Task CreateSapWerkSyncBackgroundJobAsync(SapNoRequest request) + { + var jobKey = $"hangfire:background:werk:{request.Code}"; + + using var handler = await _redisCache.LockAsync(jobKey); + if (handler.Acquired) + { + var werkInfo = await _dbContext.Queryable().Where(x => x.Werk == request.Code).SingleAsync(); + werkInfo.ThrowIfNull("人事范围不存在"); + + werkInfo.BackgroundJobKey.IsPresent().ThrowIfTrue("任务进行中,无法再次发起同步"); + + BackgroundJob.Enqueue(x => x.TodoByWerkAsync(request.Code)); + } + } } diff --git a/Src/Dlhis.ScheduledTask/Jobs/MealSupplementHandlerJob.cs b/Src/Dlhis.ScheduledTask/Jobs/MealSupplementHandlerJob.cs index 460e705b..84a054cc 100644 --- a/Src/Dlhis.ScheduledTask/Jobs/MealSupplementHandlerJob.cs +++ b/Src/Dlhis.ScheduledTask/Jobs/MealSupplementHandlerJob.cs @@ -11,7 +11,7 @@ using Kurisu.AspNetCore.Utils; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Scheduled; using Kurisu.Scheduled.Attributes; -using SqlSugar; +using Kurisu.SqlSugar.Extensions; namespace Dlhis.ScheduledTask.Jobs; @@ -36,7 +36,8 @@ public class MealSupplementHandlerJob : BaseJob { //查询待处理餐补 var mealSupplements = await DbContext.Queryable() - .Where(x => (x.Status == MealSupplementStatusEnumtype.Wait || x.Status == MealSupplementStatusEnumtype.Error) && !x.Sync) + .Where(x => x.Status == MealSupplementStatusEnumtype.Wait || x.Status == MealSupplementStatusEnumtype.Error) + .Where(x => !x.Sync) .ToListAsync(); foreach (var item in mealSupplements) @@ -46,27 +47,32 @@ public class MealSupplementHandlerJob : BaseJob //档案不存在 if (gainfo == null) { - if (await DbContext.Queryable().AS("GainfoLeave").Where(x => x.Code == item.Code).AnyAsync()) + gainfo = await DbContext.Queryable().AS("GainfoLeave").Where(x => x.Code == item.Code).SingleAsync(); + if (gainfo != null) { try { - var r = await _jinkoJIPService.SyncMealSupplementRecordsAsync(new List + //离职数据 + if (gainfo.ResignationDate < item.Date) { - new() + var r = await _jinkoJIPService.SyncMealSupplementRecordsAsync(new List { - UniqueId = item.UniqueId, - Status = "FAIL", - Msg = "人员离职" - } - }); + new() + { + UniqueId = item.UniqueId, + Status = "FAIL", + Msg = "人员离职" + } + }); - await DbContext.Updateable() - .SetColumns(x => x.Result == r) - .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Sucess) - .SetColumns(x => x.Sync == true) - .SetColumns(x => x.ModifiedTime == DateTime.Now) - .Where(x => x.UniqueId == item.UniqueId) - .ExecuteCommandAsync(); + await DbContext.Updateable() + .SetColumns(x => x.Result == r) + .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Success) + .SetColumns(x => x.Sync == true) + .SetColumns(x => x.ModifiedTime == DateTime.Now) + .Where(x => x.UniqueId == item.UniqueId) + .ExecuteCommandAsync(); + } } catch { @@ -131,16 +137,12 @@ public class MealSupplementHandlerJob : BaseJob var mealUser = await DbContext.Queryable().Where(x => x.UserCode == mealSupplement.Code).FirstAsync(); var b = mealUser.Balance += mealSupplement.Amount; - var effect = await DbContext.Updateable() - .SetColumns(x => x.Balance == b) - .SetColumns(x => x.ModifiedTime == DateTime.Now) - .Where(x => x.UserCode == mealUser.UserCode && x.Version == mealUser.Version) - .ExecuteCommandAsync(); + await DbContext.Updateable() + .SetColumns(x => x.Balance == b) + .SetColumns(x => x.ModifiedTime == DateTime.Now) + .Where(x => x.UserCode == mealUser.UserCode && x.Version == mealUser.Version) + .ExecuteCommandThrowVersionAsync(); - if (effect <= 0) - { - throw new VersionExceptions("餐补写入错误"); - } }, 5); var r = await _jinkoJIPService.SyncMealSupplementRecordsAsync(new List @@ -156,7 +158,7 @@ public class MealSupplementHandlerJob : BaseJob //更新餐补信息为成功(同步成功) await DbContext.Updateable() .SetColumns(x => x.Result == r) - .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Sucess) + .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Success) .SetColumns(x => x.Sync == true) .SetColumns(x => x.ModifiedTime == DateTime.Now) .Where(x => x.UniqueId == mealSupplement.UniqueId) @@ -165,7 +167,7 @@ public class MealSupplementHandlerJob : BaseJob await DbContext.InsertAsync(new BalanceRecordEntity { Amount = mealSupplement.Amount, - //ApplicationType = CanteenApplicaitonTypeEnumType. + ApplicationType = CanteenApplicaitonTypeEnumType.MealSupplement, Type = BalanceRecordTypeEnumType.In, BusinessPlaceCode = null, BusinessShiftCode = null, @@ -178,13 +180,12 @@ public class MealSupplementHandlerJob : BaseJob TenantId = mealSupplement.Factory, Status = BalanceRecordStatusEnumType.Valid, Source = BalanceRecordSourceEnumType.LocalTenantSubsidies, - Remark = gainfo.Remark, + Remark = mealSupplement.UniqueId + ":" + mealSupplement.Remark, CostId = gainfo.CostId, SubsidiesFromMonth = mealSupplement.Date.ToString("yyyyMM"), OriginTenantId = gainfo.Factory, Name = gainfo.Name, IsCostCrossTenant = false, - ApplicationType = CanteenApplicaitonTypeEnumType.MealSupplement, DepartmentNo = gainfo.DepartmentNo, DeviceUniqueNo = null, @@ -240,7 +241,7 @@ public class MealSupplementHandlerJob : BaseJob //更新餐补信息为成功(同步成功) await DbContext.Updateable() .SetColumns(x => x.Result == r) - .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Sucess) + .SetColumns(x => x.Status == MealSupplementStatusEnumtype.Success) .SetColumns(x => x.Sync == true) .SetColumns(x => x.ModifiedTime == DateTime.Now) .Where(x => x.UniqueId == mealSupplement.UniqueId) diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/HangfireController.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/HangfireController.cs index 210d9613..edc17a72 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/HangfireController.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/HangfireController.cs @@ -1,10 +1,13 @@ -using Dlhis.ScheduledTask.Common.Dto; +using Dlhis.ScheduledTask.Common.Request; using Dlhis.ScheduledTask.Common.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Dlhis.ScheduledTask.TaskAssignment.Controllers; +/// +/// 调度任务 +/// [Authorize(Roles = "admin")] [Route("api/[controller]")] [ApiController] @@ -23,7 +26,18 @@ public class HangfireController : ControllerBase /// /// [HttpPost("sap/person/no")] - public async Task ManuallySync(SapPersonNoRequest request) + public async Task PersonManuallySync(SapNoRequest request) + { + await _hangfireService.CreateSapPersonSyncBackgroundJobAsync(request); + } + + /// + /// 手动启动人事范围同步 + /// + /// + /// + [HttpPost("sap/werk/no")] + public async Task WerkManuallySync(SapNoRequest request) { await _hangfireService.CreateSapPersonSyncBackgroundJobAsync(request); }