diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs index f9b3a87c..5d66eedb 100644 --- a/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs @@ -12,6 +12,11 @@ public class DishesMenusBookingSettingResponse /// public DateTime Deadline { get; set; } + /// + /// 允许发起订餐 + /// + public bool AbleBooking => Deadline > ServerTime; + /// /// 支付方式 /// diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index ab663500..b669579f 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -752,14 +752,6 @@ public class BalanceService : IBalanceService .Select() .ToPageListAsync(request); - page.Data.Add(new BalanceRecordByUserResponse - { - Amount = 20, - CostDateTime = DateTime.Now.Date, - Remark = "2024-03-21 餐补", - No = "129876578" - }); - return page; } diff --git a/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs b/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs index 4fcde1c1..0c28fe79 100644 --- a/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs +++ b/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs @@ -1,10 +1,9 @@ using Dlhis.Entity.Common; using Kurisu.SqlSugar.Services; -using SqlSugar; namespace Dlhis.ScheduledTask.CommonJobs; - public class DelApiLogTaskJob +public class DelApiLogTaskJob { private readonly IDbContext _dbContext; private readonly Logger _logger; @@ -19,33 +18,14 @@ namespace Dlhis.ScheduledTask.CommonJobs; { try { - DateTime now = DateTime.Now; - DateTime todayStart = now.Date; - DateTime threeDaysAgoStart = todayStart.AddDays(-7); - - var logs = await _dbContext.ChangeDb("log") - .Queryable() - .Where(x => x._ts >= threeDaysAgoStart && x._ts <= now) - .Select(x => x.Id) - .ToListAsync(); - - var lst = new List(); - foreach (var id in logs) - { - var entity = new ApiLogEntity - { - Id = id, - }; - lst.Add(entity); - } - await _dbContext.ChangeDb("log").DeleteReallyAsync(lst); + DateTime before = DateTime.Now.Date.AddDays(-7); + await _dbContext.ChangeDb("log").Client.Deleteable().Where(x => x._ts <= before).ExecuteCommandAsync(); } catch (Exception ex) { _logger.LogError(ex, "删除日志异常:{message}", ex.Message); } - } } - + diff --git a/Src/Dlhis.ScheduledTask/CommonJobs/MealSupplementHandlerJob.cs b/Src/Dlhis.ScheduledTask/CommonJobs/MealSupplementHandlerJob.cs new file mode 100644 index 00000000..6694948f --- /dev/null +++ b/Src/Dlhis.ScheduledTask/CommonJobs/MealSupplementHandlerJob.cs @@ -0,0 +1,143 @@ +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Basic.Enums; +using Dlhis.Entity.Canteen.Entities; +using Dlhis.ScheduledTask.SyncSapInfo; +using Dlhis.ScheduledTask.SyncSapInfo.Services; +using Kurisu.AspNetCore.UnifyResultAndValidation; +using Kurisu.Core.DataAccess.Entity; +using Kurisu.SqlSugar.Services; +using SqlSugar; + +namespace Dlhis.ScheduledTask.CommonJobs; + +public class MealSupplementHandlerJob +{ + private readonly IDbContext _dbContext; + private readonly ILogger _logger; + private readonly IJinkoJIPService _jinkoJIPService; + + public MealSupplementHandlerJob(IDbContext dbContext, ILogger logger, IJinkoJIPService jinkoJIPService) + { + _dbContext = dbContext; + _logger = logger; + _jinkoJIPService = jinkoJIPService; + } + + public async Task RunAsync() + { + _dbContext.Client.QueryFilter.ClearAndBackup(); + try + { + //查询待处理餐补 + var mealSupplements = await _dbContext.Queryable() + .Where(x => (x.Status == MealSupplementStatusEnumtype.Wait || x.Status == MealSupplementStatusEnumtype.Error) && !x.Sync) + .ToListAsync(); + + foreach (var item in mealSupplements) + { + GainfoMealEntity mealUser = null; + var gainfo = await _dbContext.Queryable().Where(x => x.Code == item.Code).SingleAsync(); + //档案不存在 + if (gainfo == null) + { + continue; + } + else + { + mealUser = await _dbContext.Queryable().Where(x => x.UserNo == gainfo.No).SingleAsync(); + if (mealUser == null) + { + mealUser = new GainfoMealEntity + { + Balance = 0, + BalanceOfRecharge = 0, + BalanceOfSubsidies = 0, + UserNo = gainfo.No, + UserCode = gainfo.Code, + Version = 0, + TenantId = gainfo.Factory, + }; + + await _dbContext.InsertAsync(mealUser); + } + } + + await SetMealSupplementAsync(mealUser, item); + } + } + finally + { + _dbContext.Client.QueryFilter.Restore(); + } + } + + private async Task SetMealSupplementAsync(GainfoMealEntity mealUser, MealSupplementRecordEntity mealSupplement) + { + await _dbContext.Client.Ado.BeginTranAsync(); + try + { + await ContinueUpdateAsync(async () => + { + mealUser = await _dbContext.Queryable().Where(x => x.UserCode == mealUser.UserCode).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.Id == mealUser.Id && x.Version == mealUser.Version) + .ExecuteCommandAsync(); + + if (effect <= 0) + { + throw new VersionExceptions("餐补写入错误"); + } + + }, 5); + + mealSupplement.Status = MealSupplementStatusEnumtype.Sucess; + mealSupplement.Sync = true; + await _dbContext.UpdateAsync(mealSupplement); + + //FAIL SUCCESS + await _jinkoJIPService.SyncMealSupplementRecordsAsync(new List + { + new() + { + UniqueId = mealSupplement.UniqueId, + Status = "SUCCESS", + Msg = "操作成功" + } + }); + } + catch (Exception ex) + { + mealSupplement.Status = MealSupplementStatusEnumtype.Error; + mealSupplement.Result = ex.Message; + await _dbContext.UpdateAsync(mealSupplement); + + await _dbContext.Client.Ado.RollbackTranAsync(); + } + } + + private async Task ContinueUpdateAsync(Func func, int retry, string errorMessage = null) + { + for (int i = 0; i < retry; i++) + { + try + { + await func(); + return; + } + catch (Exception ex) when (ex is VersionExceptions) + { + _logger.LogWarning(ex, ex.Message); + } + catch (Exception) + { + throw; + } + } + + throw new UserFriendlyException(errorMessage ?? "操作失败,请重试"); + } +} diff --git a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs index 57729a3d..ca89b3d2 100644 --- a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs +++ b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs @@ -64,10 +64,17 @@ public class JobPack : BaseAppPack { TimeZone = TimeZoneInfo.Local }); + //删除前三天前的日志 RecurringJob.AddOrUpdate("DelApiLogTask", s => s.RunAsync(), "0 0 */7 * *", new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }); + + //处理餐补 + RecurringJob.AddOrUpdate("MealSupplementHandler", s => s.RunAsync(), "0/60 * * * * ?", new RecurringJobOptions + { + TimeZone = TimeZoneInfo.Local + }); } } diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoJIPService.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoJIPService.cs index 847e2635..7991ea97 100644 --- a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoJIPService.cs +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/IJinkoJIPService.cs @@ -1,9 +1,10 @@ using Dlhis.ScheduledTask.SyncSapInfo.Response; -namespace Dlhis.ScheduledTask.SyncSapInfo.Services +namespace Dlhis.ScheduledTask.SyncSapInfo.Services; + +public interface IJinkoJIPService : ISingletonDependency { - public interface IJinkoJIPService : ISingletonDependency - { - Task UploadAttendancesAsync(List requests); - } + Task UploadAttendancesAsync(List requests); + + Task SyncMealSupplementRecordsAsync(List requests); } diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoJIPService.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoJIPService.cs index 28bd30cc..e7db78bc 100644 --- a/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoJIPService.cs +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/Services/Implements/JinkoJIPService.cs @@ -5,6 +5,7 @@ using System.Text; using Dlhis.ScheduledTask.SyncSapInfo.Response; using Kurisu.AspNetCore.Utils.Extensions; using Microsoft.IdentityModel.Tokens; +using Newtonsoft.Json.Linq; namespace Dlhis.ScheduledTask.SyncSapInfo.Services.Implements; @@ -35,6 +36,8 @@ public class JinkoJIPService : IJinkoJIPService public async Task UploadAttendancesAsync(List requests) { + var requestUrl = "/JIP/HCM/HCM_SWIPE_DATA_SAVE"; + var body = new { T_DATA = requests, @@ -45,7 +48,7 @@ public class JinkoJIPService : IJinkoJIPService //_logger.LogInformation("上传考勤记录请求:{json}", json); var content = new StringContent(json, Encoding.UTF8, "application/json"); - var response = await GetHttpClient().PostAsync("/JIP/HCM/HCM_SWIPE_DATA_SAVE", content); + var response = await GetHttpClient().PostAsync(requestUrl, content); var responseJson = await response.Content.ReadAsStringAsync(); _logger.LogInformation("上传考勤记录响应:{json}", responseJson); @@ -55,7 +58,26 @@ public class JinkoJIPService : IJinkoJIPService } - //************************************************************************************************************************************************/ + public async Task SyncMealSupplementRecordsAsync(List requests) + { + var requestUrl = "/JIP/DHR/DHR_DL_CALLBACK"; + + var json = requests.ToJson(); + + var content = new StringContent(json, Encoding.UTF8, "application/json"); + var response = await GetHttpClient().PostAsync(requestUrl, content); + var responseJson = await response.Content.ReadAsStringAsync(); + + var jobj = JObject.Parse(responseJson); + + jobj.ContainsKey("exp").ThrowIfTrue(jobj.GetValue("exp").Value()); + jobj.ContainsKey("message").ThrowIfTrue(jobj.GetValue("message").Value()); + + (jobj.GetValue("code").Value() != 200).ThrowIfTrue(jobj.GetValue("message").Value()); + } + + + //********************************************************************* help methods ***************************************************************************/ private static string IssueJwt(string jwtKey, string jwtSecret, int mins) @@ -65,9 +87,9 @@ public class JinkoJIPService : IJinkoJIPService var claims = new List { - new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(now).ToUnixTimeSeconds()}"), - new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(expires).ToUnixTimeSeconds()}"), - new Claim(JwtRegisteredClaimNames.Iss,jwtKey), + 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)); diff --git a/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncMealSupplementRecordRequest.cs b/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncMealSupplementRecordRequest.cs new file mode 100644 index 00000000..68fa53df --- /dev/null +++ b/Src/Dlhis.ScheduledTask/SyncSapInfo/SyncMealSupplementRecordRequest.cs @@ -0,0 +1,17 @@ +namespace Dlhis.ScheduledTask.SyncSapInfo; + +public class SyncMealSupplementRecordRequest +{ + /// + /// 唯一id + /// + public string UniqueId { get; set; } + + /// + /// FAIL SUCCESS + /// + public string Status { get; set; } + + + public string Msg { get; set; } +}