From 160bfad259195adbf79faac0c56d9d7427aa0609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B5=87=E6=96=87=E9=BE=99?= Date: Tue, 5 Nov 2024 17:46:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E5=88=A4=E6=96=ADbug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DS.Module.Quartz/QuartzModuleInstall.cs | 26 ++- .../DS.WMS.Core/Flow/Method/FlowRuntime.cs | 11 +- .../QuarztJobs/BackgroundTaskJob.cs | 150 ++++++++++++++++++ .../TaskInteraction/Dtos/TaskJobContext.cs | 26 +++ .../TaskInteraction/Dtos/TaskRequest.cs | 6 + .../TaskInteraction/Entity/TaskJob.cs | 72 +++++++++ .../TaskInteraction/Interface/ITaskJob.cs | 17 ++ .../Method/FeeBillTaskService.cs | 28 ++-- .../TaskInteraction/Method/TaskService.cs | 22 ++- .../Controllers/FeeAuditController.cs | 29 +++- .../FolderProfile1.pubxml.user | 2 +- 11 files changed, 361 insertions(+), 28 deletions(-) create mode 100644 ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs create mode 100644 ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskJobContext.cs create mode 100644 ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskJob.cs create mode 100644 ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskJob.cs diff --git a/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs b/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs index 5ebddd1a..58f42b17 100644 --- a/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs +++ b/ds-wms-service/DS.Module.Quartz/QuartzModuleInstall.cs @@ -9,6 +9,11 @@ namespace DS.Module.QuartzModuleInstall { public static class QuartzModuleInstall { + /// + /// 添加费用模块定时任务 + /// + /// + /// public static void AddFeeQuartzModuleInstall(this IServiceCollection services, IConfiguration configuration) { //获取进项发票 @@ -62,6 +67,11 @@ namespace DS.Module.QuartzModuleInstall services.AddQuartzServer(q => q.WaitForJobsToComplete = true); } + /// + /// 添加操作模块定时任务 + /// + /// + /// public static void AddOpQuartzModuleInstall(this IServiceCollection services, IConfiguration configuration) { var jobKey1 = new JobKey(nameof(WSLReportJob)); @@ -73,10 +83,24 @@ namespace DS.Module.QuartzModuleInstall .ForJob(jobKey1) .WithIdentity(nameof(WSLReportJob) + "-trigger") .WithCronSchedule(configuration["JobConfig:" + jobKey1.Name]) - //.WithSimpleSchedule(s => s.WithIntervalInMinutes(1).WithRepeatCount(1)) //测试用 ); }); + //var jobKey2 = new JobKey(nameof(BackgroundTaskJob)); + //services.AddQuartz(q => + //{ + // // 配置 Quartz + // q.UseMicrosoftDependencyInjectionJobFactory(); + + // q.AddJob(opts => opts.WithIdentity(jobKey2)); + // q.AddTrigger(opts => opts + // .ForJob(jobKey2) + // .WithIdentity(nameof(BackgroundTaskJob) + "-trigger") + // .WithSimpleSchedule(x => x + // .WithIntervalInMinutes(2) + // .RepeatForever())); + //}); + services.AddQuartzServer(q => q.WaitForJobsToComplete = true); } } diff --git a/ds-wms-service/DS.WMS.Core/Flow/Method/FlowRuntime.cs b/ds-wms-service/DS.WMS.Core/Flow/Method/FlowRuntime.cs index 67f5e825..3016604b 100644 --- a/ds-wms-service/DS.WMS.Core/Flow/Method/FlowRuntime.cs +++ b/ds-wms-service/DS.WMS.Core/Flow/Method/FlowRuntime.cs @@ -266,10 +266,10 @@ public class FlowRuntime if (scalar.ObjToInt() > 0 || scalar.ObjToBool()) { conditionId = conditionNode.Id; - //break; + break; } - else { - + else + { conditionId = conditionNode.Pid; } } @@ -361,14 +361,15 @@ public class FlowRuntime if (nextChild.Type == FlowChild.Exclusive) { var childId = GetNextConditionNodeId(nextChild); - if (childId == null) { + if (childId == null) + { childId = "end"; return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点 } else { return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点 - } + } } //todo:前端组织JSON结构有误,加入临时修复代码,待前端改正后移除 else if (nextChild.Type == null) diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs new file mode 100644 index 00000000..f040071c --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/BackgroundTaskJob.cs @@ -0,0 +1,150 @@ +using DS.Module.Core; +using DS.WMS.Core.TaskInteraction.Dtos; +using DS.WMS.Core.TaskInteraction.Entity; +using DS.WMS.Core.TaskInteraction.Interface; +using Fasterflect; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Quartz; +using SqlSugar; + +namespace DS.WMS.Core.QuarztJobs +{ + /// + /// 定时作业触发 + /// + public sealed class BackgroundTaskJob : IJob + { + IServiceProvider serviceProvider; + ISqlSugarClient? db; + ILogger logger; + + /// + /// 初始化 + /// + /// + public BackgroundTaskJob(IServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + logger = serviceProvider.GetRequiredService>(); + db = serviceProvider.GetRequiredService(); + } + + /// + /// 执行任务 + /// + /// + /// + public async Task Execute(IJobExecutionContext context) + { + var dbLinks = await db.Queryable().ToListAsync(); + SqlSugarClient? tenantDb = null; + try + { + foreach (var dbLink in dbLinks) + { + tenantDb = new SqlSugarClient(new ConnectionConfig + { + ConfigId = dbLink.Id, + ConnectionString = dbLink.Connection, + DbType = dbLink.DbType, + IsAutoCloseConnection = true + }); + tenantDb.QueryFilter.Clear(); + var jobs = await tenantDb.Queryable() + .InnerJoin((x, y) => x.TaskId == y.Id) + .Where((x, y) => y.TaskStatus == TaskStatusEnum.Create && !x.IsExecuted && SqlFunc.GetDate() >= x.NextTriggerTime) + .Select((x, y) => new TaskJob + { + Id = x.Id, + TaskId = x.TaskId, + NextTriggerTime = x.NextTriggerTime, + TypeName = x.TypeName, + BusinessId = y.BusinessId, + BusinessType = y.BusinessType, + }).ToListAsync(); + if (jobs.Count == 0) + return; + + var jobContext = new TaskJobContext + { + AdditionalData = context.MergedJobDataMap! + }; + + foreach (var item in jobs) + { + var type = Type.GetType(item.TypeName, false); + if (type == null) + continue; + + try + { + if (ConstructorExtensions.CreateInstance(type, serviceProvider) is ITaskJob job) + { + jobContext.JobInfo = item; + jobContext.Result = DataResult.Success; + await job.Execute(jobContext); + + if (jobContext.Result.Succeeded) + { + item.IsExecuted = true; + item.NextTriggerTime = null; + } + } + } + catch (Exception ex) + { + item.LastException = $"执行作业({item.Id})时发生错误:" + ex.Message + Environment.NewLine + ex.StackTrace; + } + } + + await tenantDb.Updateable(jobs).UpdateColumns(x => new + { + x.IsExecuted, + x.NextTriggerTime, + x.LastException + }).ExecuteCommandAsync(); + + var finishedJobs = jobs.FindAll(x => x.IsExecuted); + if (finishedJobs.Count > 0) //尝试更新关联任务 + { + List tasks = []; + var ids = finishedJobs.Select(x => x.TaskId).Distinct(); + var list = await tenantDb.Queryable().Where(x => ids.Contains(x.TaskId)) + .Select(x => new + { + x.Id, + x.TaskId, + x.IsExecuted + }).ToListAsync(); + var groups = list.GroupBy(x => x.TaskId); + DateTime dtNow = DateTime.Now; + foreach (var group in groups) + { + if (group.Count() == group.Count(x => x.IsExecuted)) + { + tasks.Add(new BusinessTask + { + Id = group.Key, + TaskStatus = TaskStatusEnum.Complete, + UpdateTime = dtNow + }); + } + } + + await tenantDb.Updateable(tasks).UpdateColumns(x => new + { + x.TaskStatus, + x.UpdateBy, + x.UpdateTime + }).ExecuteCommandAsync(); + } + } + } + catch (Exception ex) + { + logger.LogError(ex, "执行定时作业时发生异常"); + } + } + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskJobContext.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskJobContext.cs new file mode 100644 index 00000000..fa1cf399 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskJobContext.cs @@ -0,0 +1,26 @@ +using DS.Module.Core; +using DS.WMS.Core.TaskInteraction.Entity; + +namespace DS.WMS.Core.TaskInteraction.Dtos +{ + /// + /// 定时任务执行上下文 + /// + public class TaskJobContext + { + /// + /// 任务信息 + /// + public TaskJob JobInfo { get; set; } + + /// + /// 任务参数 + /// + public IDictionary? AdditionalData { get; set; } + + /// + /// 执行结果 + /// + public DataResult Result { get; set; } = DataResult.Success; + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs index 86962496..a58bae8f 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Dtos/TaskRequest.cs @@ -2,6 +2,7 @@ using System.Runtime.Serialization; using DS.Module.Core; using DS.WMS.Core.Op.Entity; +using DS.WMS.Core.TaskInteraction.Entity; using DS.WMS.Core.TaskInteraction.Method; using Masuit.Tools.Systems; @@ -74,6 +75,11 @@ namespace DS.WMS.Core.TaskInteraction.Dtos /// public List? Steps { get; set; } + /// + /// 定时任务 + /// + public List? Jobs { get; set; } + /// /// 确定当前对象是否有效 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskJob.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskJob.cs new file mode 100644 index 00000000..b0ac722a --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Entity/TaskJob.cs @@ -0,0 +1,72 @@ +using DS.WMS.Core.Op.Entity; +using SqlSugar; + +namespace DS.WMS.Core.TaskInteraction.Entity +{ + /// + /// 任务定时作业 + /// + [SugarTable("business_task_job", "任务定时作业")] + public class TaskJob + { + /// + /// ID + /// + [SugarColumn(IsPrimaryKey = true)] + public long Id { get; set; } + + /// + /// 任务ID + /// + [SugarColumn(ColumnDescription = "任务ID")] + public long TaskId { get; set; } + + /// + /// 定时任务类型 + /// + [SugarColumn(ColumnDescription = "定时任务类型", Length = 100, IsNullable = false)] + public string TypeName { get; set; } + + /// + /// 下次触发时间 + /// + [SugarColumn(ColumnDescription = "下次触发时间", IsNullable = true)] + public DateTime? NextTriggerTime { get; set; } + + /// + /// 是否已执行 + /// + [SugarColumn(ColumnDescription = "是否已执行")] + public bool IsExecuted { get; set; } + + /// + /// 上次执行异常信息 + /// + [SugarColumn(ColumnDescription = "上次执行异常信息", IsNullable = true)] + public string? LastException { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnDescription = "创建人", IsNullable = false)] + public long CreateBy { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnDescription = "创建时间", IsNullable = false)] + public DateTime CreateTime { get; set; } + + /// + /// 业务ID + /// + [SugarColumn(IsIgnore = true)] + public long BusinessId { get; set; } + + /// + /// 业务类型 + /// + [SugarColumn(IsIgnore = true)] + public BusinessType? BusinessType { get; set; } + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskJob.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskJob.cs new file mode 100644 index 00000000..0dd614ec --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Interface/ITaskJob.cs @@ -0,0 +1,17 @@ +using DS.WMS.Core.TaskInteraction.Dtos; + +namespace DS.WMS.Core.TaskInteraction.Interface +{ + /// + /// 任务定时服务 + /// + public interface ITaskJob + { + /// + /// 执行 + /// + /// + /// + Task Execute(TaskJobContext context); + } +} diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/FeeBillTaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/FeeBillTaskService.cs index 7e807f3e..1fb1121b 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/FeeBillTaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/FeeBillTaskService.cs @@ -189,22 +189,26 @@ namespace DS.WMS.Core.TaskInteraction.Method logger.LogError($"生成【{TaskBaseTypeEnum.BILL_LOCK_AUDIT.GetDescription()}】任务失败:" + result.Message); } + var req = new TaskCreationRequest + { + BusinessId = biz.BusinessId, + BusinessType = biz.BusinessType, + TaskTypeName = TaskBaseTypeEnum.BILL_SENDING.ToString(), + TaskTitle = $"【{TaskBaseTypeEnum.BILL_SENDING.GetDescription()}】{biz.CustomerNo}", + Jobs = [] + }; + req.Jobs.Add(new TaskJob + { + TypeName = "", + NextTriggerTime = dtNow.AddMinutes(60) + }); //生成账单任务 - + result = await CreateTaskAsync(req); + if (!result.Succeeded) + logger.LogError($"生成【{TaskBaseTypeEnum.BILL_SENDING.GetDescription()}】任务失败:" + result.Message); } } - /// - /// 锁单审核 - /// - /// - /// - public async Task BillLockAuditAsync(TaskAuditRequest request) - { - request.TaskTypeName = TaskBaseTypeEnum.BILL_LOCK_AUDIT.ToString(); - return await AuditAsync(request); - } - /// /// 设置锁定 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs index 015532db..60e9071c 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs @@ -9,7 +9,6 @@ using DS.WMS.Core.Flow.Entity; using DS.WMS.Core.Flow.Interface; using DS.WMS.Core.Flow.Method; using DS.WMS.Core.Info.Interface; -using DS.WMS.Core.Invoice.Dtos; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Op.Interface; @@ -290,6 +289,7 @@ namespace DS.WMS.Core.TaskInteraction.Method task.NextType = await GetNextTypeAsync(task); await TenantDb.Insertable(task).ExecuteCommandAsync(); + if (request.Steps?.Count > 0) { var steps = request.Steps.Select(x => new TaskStep @@ -305,6 +305,15 @@ namespace DS.WMS.Core.TaskInteraction.Method await TenantDb.Insertable(steps).ExecuteCommandAsync(); } + if (request.Jobs?.Count > 0) + { + foreach (var item in request.Jobs) + { + item.TaskId = task.Id; + //item.NextTriggerTime ??= dtNow.AddMinutes(30); + } + await TenantDb.Insertable(request.Jobs).ExecuteCommandAsync(); + } result = await OnTaskCreated(task); if (!result.Succeeded) @@ -648,6 +657,11 @@ namespace DS.WMS.Core.TaskInteraction.Method } } + //public async Task SetJobsAsync(List jobs) + //{ + + //} + /// /// 当任务状态发生变化时调用 /// @@ -1046,13 +1060,17 @@ namespace DS.WMS.Core.TaskInteraction.Method var users = await FillInUserInfoAsync(userId); var dt = DateTime.Now; - await ManagerService.SetTaskUserStatus( + var result = await ManagerService.SetTaskUserStatus( callback.BusinessId, callback.AuditType.GetValueOrDefault(), TaskStatusEnum.Complete, //callback.Status == FlowStatusEnum.Approve ? TaskStatusEnum.Complete : TaskStatusEnum.Pending dt, users); + if (!result.Succeeded) + { + + } //记录日志 await LogService.WriteLogAsync(new BusinessTaskLog diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeAuditController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeAuditController.cs index 49995ab8..f622c4b8 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeAuditController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeAuditController.cs @@ -56,7 +56,7 @@ namespace DS.WMS.FeeApi.Controllers /// 查询条件 /// [HttpPost, Route("GetStat")] - public async Task> GetStatAsync(FeeStatisticsRequestV2 request) + public async Task> GetStatAsync([FromBody] FeeStatisticsRequestV2 request) { return await _auditService.GetStatAsync(request.Id, request.BusinessType, request.FeeId); } @@ -78,7 +78,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("Audit")] - public async Task AuditAsync(AuditRequest request) + public async Task AuditAsync([FromBody] AuditRequest request) { if (request == null || request.Ids.Length == 0 || (request.Result != 1 && request.Result != 2)) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -92,7 +92,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("AuditByBiz")] - public async Task AuditAsync(BizAuditRequest request) + public async Task AuditAsync([FromBody] BizAuditRequest request) { if (request == null || (request.Result != 1 && request.Result != 2) || request.Items == null || request.Items.Count == 0) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -106,7 +106,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("OneClickAudit")] - public async Task OneClickAuditAsync(AuditConditionRequest request) + public async Task OneClickAuditAsync([FromBody] AuditConditionRequest request) { if (request.Result != 1 && request.Result != 2) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -120,7 +120,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("BusinessAudit")] - public async Task AuditBillAsync(TaskAuditRequest request) + public async Task AuditBillAsync([FromBody] TaskAuditRequest request) { if (request == null || (request.Result != 1 && request.Result != 2)) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -128,13 +128,28 @@ namespace DS.WMS.FeeApi.Controllers return await _auditService.AuditBillAsync(request); } + /// + /// 锁单审核 + /// + /// + /// + /// + [HttpPost, Route("BusinessLockAudit")] + public async Task AuditBillLockAsync([FromServices] IFeeBillTaskService service, [FromBody] TaskAuditRequest request) + { + if (request == null || (request.Result != 1 && request.Result != 2)) + return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); + + return await service.AuditAsync(request); + } + /// /// 设置业务锁定状态 /// /// 请求信息 /// [HttpPost, Route("SetLocking")] - public async Task SetLockingAsync(BizOperation operation) + public async Task SetLockingAsync([FromBody] BizOperation operation) { bool? isLocked = null; try @@ -160,7 +175,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("SetFeeStatus")] - public async Task SetFeeStatusAsync(IdModel idModel) + public async Task SetFeeStatusAsync([FromBody] IdModel idModel) { return await _auditService.SetFeeStatusAsync(idModel.Value, idModel.Ids); } diff --git a/ds-wms-service/DS.WMS.FeeApi/Properties/PublishProfiles/FolderProfile1.pubxml.user b/ds-wms-service/DS.WMS.FeeApi/Properties/PublishProfiles/FolderProfile1.pubxml.user index 1f70f192..80d7b48a 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Properties/PublishProfiles/FolderProfile1.pubxml.user +++ b/ds-wms-service/DS.WMS.FeeApi/Properties/PublishProfiles/FolderProfile1.pubxml.user @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. <_PublishTargetUrl>D:\Publish\DS8\FeeApi - True|2024-11-04T09:39:07.1315345Z||;True|2024-11-04T17:32:28.9239052+08:00||;True|2024-11-04T15:49:58.6422421+08:00||;True|2024-11-04T15:39:25.1892907+08:00||;True|2024-11-04T15:21:49.7395112+08:00||;True|2024-11-04T11:26:53.4821041+08:00||;True|2024-11-04T11:19:48.8467193+08:00||;True|2024-11-04T11:01:39.9398452+08:00||;True|2024-11-04T10:30:55.0743204+08:00||;True|2024-11-02T21:17:44.8575190+08:00||;True|2024-11-02T20:54:29.9931812+08:00||;True|2024-11-02T20:39:20.4100370+08:00||;True|2024-11-02T18:33:41.0724285+08:00||;True|2024-11-02T18:21:55.8561639+08:00||;True|2024-11-02T17:36:24.3401782+08:00||;True|2024-11-02T16:38:03.0054105+08:00||;True|2024-11-02T16:26:26.1698304+08:00||;True|2024-11-02T16:15:20.2872358+08:00||;True|2024-11-02T15:19:14.9663838+08:00||;True|2024-11-02T14:39:47.8808708+08:00||;False|2024-11-02T14:22:04.2841792+08:00||;True|2024-11-02T11:50:48.2452805+08:00||;True|2024-10-29T18:52:12.7978878+08:00||;True|2024-10-29T10:27:49.1623527+08:00||;True|2024-10-25T15:09:27.7029075+08:00||;True|2024-10-25T10:29:26.9218878+08:00||;True|2024-10-22T17:58:39.9582805+08:00||;True|2024-10-21T17:57:21.7047579+08:00||;True|2024-10-21T14:30:54.4520206+08:00||;True|2024-10-21T10:19:05.7405749+08:00||;True|2024-10-18T16:11:05.4049685+08:00||;True|2024-10-18T14:59:49.1162741+08:00||;True|2024-10-16T16:29:15.3185348+08:00||;True|2024-10-16T14:12:58.1754214+08:00||;True|2024-10-16T14:08:06.5805581+08:00||;True|2024-10-16T11:55:29.8273176+08:00||;True|2024-10-15T17:39:40.4090324+08:00||;True|2024-10-15T17:06:43.0181578+08:00||;True|2024-10-15T15:07:38.9601925+08:00||;True|2024-10-12T13:33:32.4412583+08:00||;True|2024-10-11T17:00:54.0916209+08:00||;True|2024-10-11T10:54:50.3307087+08:00||;True|2024-10-11T10:45:07.8181500+08:00||;True|2024-10-11T10:40:44.2066046+08:00||;True|2024-10-11T10:21:25.7226983+08:00||;True|2024-10-11T10:09:05.5257478+08:00||;True|2024-10-10T14:58:29.1228618+08:00||;True|2024-10-10T14:05:59.4501659+08:00||;True|2024-10-10T11:08:58.9765455+08:00||;True|2024-10-08T17:59:07.5583287+08:00||;True|2024-09-27T19:01:59.6945760+08:00||;True|2024-09-27T18:45:48.2812860+08:00||;True|2024-09-27T18:10:25.5697467+08:00||;True|2024-09-27T17:39:06.3169139+08:00||;True|2024-09-27T17:30:14.1043193+08:00||;True|2024-09-27T16:02:09.0703159+08:00||;True|2024-09-27T15:53:05.1789245+08:00||;True|2024-09-27T15:32:52.1934490+08:00||;True|2024-09-27T13:51:24.9197626+08:00||;True|2024-09-27T13:48:17.2817346+08:00||;True|2024-09-27T11:51:46.8193040+08:00||;True|2024-09-27T10:58:33.1059648+08:00||;True|2024-09-27T10:37:35.0336563+08:00||;False|2024-09-27T10:31:52.6302264+08:00||;True|2024-09-26T19:50:15.5513195+08:00||;True|2024-09-26T19:47:14.0781788+08:00||;True|2024-09-26T19:01:26.5428388+08:00||;True|2024-09-26T18:35:28.7455319+08:00||;True|2024-09-26T18:24:30.8084807+08:00||;True|2024-09-26T18:20:47.3005460+08:00||;True|2024-09-26T18:04:39.8012913+08:00||;True|2024-09-26T17:48:13.8526872+08:00||;True|2024-09-26T16:08:20.1746970+08:00||;True|2024-09-26T16:01:01.1501975+08:00||;False|2024-09-26T16:00:34.1516745+08:00||;True|2024-09-26T14:33:03.4007570+08:00||;True|2024-09-25T19:14:27.8906774+08:00||;True|2024-09-25T18:57:40.1435131+08:00||;True|2024-09-25T17:38:44.0915841+08:00||;True|2024-09-25T15:33:58.4630618+08:00||;True|2024-09-25T15:10:31.3022063+08:00||;False|2024-09-25T14:14:40.9640545+08:00||;True|2024-09-25T10:09:32.2558600+08:00||;True|2024-09-25T09:59:17.1525160+08:00||;False|2024-09-25T09:57:58.7265103+08:00||;False|2024-09-25T09:53:36.7732713+08:00||;False|2024-09-24T18:40:10.0166224+08:00||;True|2024-09-24T08:59:56.1995425+08:00||;True|2024-09-23T18:07:54.7222163+08:00||;True|2024-09-23T17:23:57.7568406+08:00||;True|2024-09-23T16:28:49.3169826+08:00||;True|2024-09-23T15:57:31.8052490+08:00||;True|2024-09-23T11:47:21.1445419+08:00||;True|2024-09-23T09:24:36.0732229+08:00||;True|2024-09-21T11:59:19.0549926+08:00||;True|2024-09-21T11:24:32.4451752+08:00||;True|2024-09-21T10:39:11.5297411+08:00||;True|2024-09-20T18:24:31.7827684+08:00||;True|2024-09-19T17:55:53.1666689+08:00||;True|2024-09-19T17:42:47.9061485+08:00||; + True|2024-11-05T03:48:07.5089999Z||;True|2024-11-04T17:39:07.1315345+08:00||;True|2024-11-04T17:32:28.9239052+08:00||;True|2024-11-04T15:49:58.6422421+08:00||;True|2024-11-04T15:39:25.1892907+08:00||;True|2024-11-04T15:21:49.7395112+08:00||;True|2024-11-04T11:26:53.4821041+08:00||;True|2024-11-04T11:19:48.8467193+08:00||;True|2024-11-04T11:01:39.9398452+08:00||;True|2024-11-04T10:30:55.0743204+08:00||;True|2024-11-02T21:17:44.8575190+08:00||;True|2024-11-02T20:54:29.9931812+08:00||;True|2024-11-02T20:39:20.4100370+08:00||;True|2024-11-02T18:33:41.0724285+08:00||;True|2024-11-02T18:21:55.8561639+08:00||;True|2024-11-02T17:36:24.3401782+08:00||;True|2024-11-02T16:38:03.0054105+08:00||;True|2024-11-02T16:26:26.1698304+08:00||;True|2024-11-02T16:15:20.2872358+08:00||;True|2024-11-02T15:19:14.9663838+08:00||;True|2024-11-02T14:39:47.8808708+08:00||;False|2024-11-02T14:22:04.2841792+08:00||;True|2024-11-02T11:50:48.2452805+08:00||;True|2024-10-29T18:52:12.7978878+08:00||;True|2024-10-29T10:27:49.1623527+08:00||;True|2024-10-25T15:09:27.7029075+08:00||;True|2024-10-25T10:29:26.9218878+08:00||;True|2024-10-22T17:58:39.9582805+08:00||;True|2024-10-21T17:57:21.7047579+08:00||;True|2024-10-21T14:30:54.4520206+08:00||;True|2024-10-21T10:19:05.7405749+08:00||;True|2024-10-18T16:11:05.4049685+08:00||;True|2024-10-18T14:59:49.1162741+08:00||;True|2024-10-16T16:29:15.3185348+08:00||;True|2024-10-16T14:12:58.1754214+08:00||;True|2024-10-16T14:08:06.5805581+08:00||;True|2024-10-16T11:55:29.8273176+08:00||;True|2024-10-15T17:39:40.4090324+08:00||;True|2024-10-15T17:06:43.0181578+08:00||;True|2024-10-15T15:07:38.9601925+08:00||;True|2024-10-12T13:33:32.4412583+08:00||;True|2024-10-11T17:00:54.0916209+08:00||;True|2024-10-11T10:54:50.3307087+08:00||;True|2024-10-11T10:45:07.8181500+08:00||;True|2024-10-11T10:40:44.2066046+08:00||;True|2024-10-11T10:21:25.7226983+08:00||;True|2024-10-11T10:09:05.5257478+08:00||;True|2024-10-10T14:58:29.1228618+08:00||;True|2024-10-10T14:05:59.4501659+08:00||;True|2024-10-10T11:08:58.9765455+08:00||;True|2024-10-08T17:59:07.5583287+08:00||;True|2024-09-27T19:01:59.6945760+08:00||;True|2024-09-27T18:45:48.2812860+08:00||;True|2024-09-27T18:10:25.5697467+08:00||;True|2024-09-27T17:39:06.3169139+08:00||;True|2024-09-27T17:30:14.1043193+08:00||;True|2024-09-27T16:02:09.0703159+08:00||;True|2024-09-27T15:53:05.1789245+08:00||;True|2024-09-27T15:32:52.1934490+08:00||;True|2024-09-27T13:51:24.9197626+08:00||;True|2024-09-27T13:48:17.2817346+08:00||;True|2024-09-27T11:51:46.8193040+08:00||;True|2024-09-27T10:58:33.1059648+08:00||;True|2024-09-27T10:37:35.0336563+08:00||;False|2024-09-27T10:31:52.6302264+08:00||;True|2024-09-26T19:50:15.5513195+08:00||;True|2024-09-26T19:47:14.0781788+08:00||;True|2024-09-26T19:01:26.5428388+08:00||;True|2024-09-26T18:35:28.7455319+08:00||;True|2024-09-26T18:24:30.8084807+08:00||;True|2024-09-26T18:20:47.3005460+08:00||;True|2024-09-26T18:04:39.8012913+08:00||;True|2024-09-26T17:48:13.8526872+08:00||;True|2024-09-26T16:08:20.1746970+08:00||;True|2024-09-26T16:01:01.1501975+08:00||;False|2024-09-26T16:00:34.1516745+08:00||;True|2024-09-26T14:33:03.4007570+08:00||;True|2024-09-25T19:14:27.8906774+08:00||;True|2024-09-25T18:57:40.1435131+08:00||;True|2024-09-25T17:38:44.0915841+08:00||;True|2024-09-25T15:33:58.4630618+08:00||;True|2024-09-25T15:10:31.3022063+08:00||;False|2024-09-25T14:14:40.9640545+08:00||;True|2024-09-25T10:09:32.2558600+08:00||;True|2024-09-25T09:59:17.1525160+08:00||;False|2024-09-25T09:57:58.7265103+08:00||;False|2024-09-25T09:53:36.7732713+08:00||;False|2024-09-24T18:40:10.0166224+08:00||;True|2024-09-24T08:59:56.1995425+08:00||;True|2024-09-23T18:07:54.7222163+08:00||;True|2024-09-23T17:23:57.7568406+08:00||;True|2024-09-23T16:28:49.3169826+08:00||;True|2024-09-23T15:57:31.8052490+08:00||;True|2024-09-23T11:47:21.1445419+08:00||;True|2024-09-23T09:24:36.0732229+08:00||;True|2024-09-21T11:59:19.0549926+08:00||;True|2024-09-21T11:24:32.4451752+08:00||;True|2024-09-21T10:39:11.5297411+08:00||;True|2024-09-20T18:24:31.7827684+08:00||;True|2024-09-19T17:55:53.1666689+08:00||; \ No newline at end of file