diff --git a/Src/Dlhis.ScheduledTask/Jobs/AutoConfirmAppointmentJob.cs b/Src/Dlhis.ScheduledTask/Jobs/AutoConfirmAppointmentJob.cs
index 227a4860..b1a0407c 100644
--- a/Src/Dlhis.ScheduledTask/Jobs/AutoConfirmAppointmentJob.cs
+++ b/Src/Dlhis.ScheduledTask/Jobs/AutoConfirmAppointmentJob.cs
@@ -1,5 +1,4 @@
using Dlhis.Entity.Basic.Entity;
-using Dlhis.Entity.Basic.Enums;
using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Device.Enums;
using Dlhis.Entity.Visitor.Entity;
@@ -8,51 +7,70 @@ using Dlhis.ScheduledTask.Attributes;
namespace Dlhis.ScheduledTask.Jobs;
+
///
-/// 访客预约移除
+/// 定时任务:每5分钟执行一次,自动处理访客预约车间相关逻辑。
///
[RecurringJob(nameof(AutoConfirmAppointmentJob), "0 0/5 * * * ?", Name = "访客预约自动处理车间")]
public class AutoConfirmAppointmentJob : BaseJob
{
- ///
+ // 构造函数,注入服务提供者
public AutoConfirmAppointmentJob(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
- ///
+ // 定时任务主逻辑
protected override async Task RunAsync(IServiceProvider serviceProvider)
{
+ // 查询所有需要自动处理的访客预约明细
var details = await DbContext.Queryable()
.Where(x => x.IsEnterDoorArea == false || (x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Arrived))
.Where(x => x.IsEnterWorkplace && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Wait && DateTime.Now >= x.WorkplaceStart)
.ToListAsync();
+ // 获取所有相关证件号
+ var idNos = details.Select(x => x.IdNo).Distinct().ToList();
+ // 查询访客信息
+ var gainfos = await DbContext.Queryable()
+ .Where(x => idNos.Contains(x.IdNo) || idNos.Contains(x.Code))
+ .ToListAsync();
+
+ // 批量获取所有有效区域编码,避免循环中多次查库
+ var allValidAreaCodes = details.SelectMany(GetValidAreaCodes).Distinct().ToList();
+ // 查询所有有效区域编码
+ var allAreaCodes = await DbContext.Queryable()
+ .Where(x => allValidAreaCodes.Contains(x.CustomCode))
+ .Select(x => x.CustomCode)
+ .ToListAsync();
+
+ // 预先缓存每个detail的有效区域编码,减少循环内重复计算
+ var detailsWithValidAreaCodesDict = details.ToDictionary(
+ x => x.Id,
+ x => GetValidAreaCodes(x).Intersect(allAreaCodes).ToList()
+ );
+
+ var deviceTaskList = new List(); // 设备任务列表
+ var updateDetails = new List(); // 需要更新的预约明细
+
foreach (var detail in details)
{
- var gainfo = await DbContext.Queryable().Where(x => x.IdNo == detail.IdNo || x.Code == detail.IdNo).SingleAsync();
- if (gainfo == null)
+ // 查找对应访客信息
+ var gainfo = gainfos.FirstOrDefault(x => x.IdNo == detail.IdNo || x.Code == detail.IdNo);
+ if (gainfo == null) continue;
+
+ // 获取当前明细的有效区域编码
+ var existsAreaCodes = detailsWithValidAreaCodesDict[detail.Id];
+ if (!existsAreaCodes.Any()) continue;
+
+ // 查询区域下的设备信息
+ var deviceInfos = await GetDeviceUniqueNoAndTenantIdAsync(existsAreaCodes);
+ if (deviceInfos?.Any() != true)
{
continue;
}
- var areaCodes = GetValidAreaCodes(detail).ToList();
- if (!areaCodes.Any())
- {
- continue;
- }
-
- var existsAreaCodes = await DbContext.Queryable().Where(x => areaCodes.Contains(x.CustomCode)).Select(x => x.CustomCode).ToListAsync();
-
- //当前分配的设备组code
- var deviceGroupCodes = await DbContext.Queryable()
- .Where(x => existsAreaCodes.Contains(x.CustomCode))
- .Select(x => x.DeviceGroupCode)
- .ToListAsync();
-
- var deviceCodes = await DbContext.Queryable().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
- var deviceUniqueNos = await DbContext.Queryable().Where(x => deviceCodes.Contains(x.Code)).Select(x => new { x.UniqueNo, x.TenantId }).ToListAsync();
-
- await DbContext.InsertAsync(deviceUniqueNos.Select(x => new DeviceTaskEntity
+ // 生成设备任务
+ deviceTaskList.AddRange(deviceInfos.Select(x => new DeviceTaskEntity
{
DeviceType = DeviceTypeEnumType.Door,
DeviceUniqueNo = x.UniqueNo,
@@ -63,20 +81,70 @@ public class AutoConfirmAppointmentJob : BaseJob
TenantId = x.TenantId,
Source = "定时任务判断触发车间下发任务",
Version = 0
- }).ToList());
+ }));
- if (detail.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Wait)
- {
- detail.WorkplaceStatus = VisitorAppointmentDetailStatusEnumType.Arrived;
- }
+ // 更新预约明细状态
+ if (detail.WorkplaceStatus != VisitorAppointmentDetailStatusEnumType.Wait) continue;
- await DbContext.UpdateAsync(detail);
+ detail.WorkplaceStatus = VisitorAppointmentDetailStatusEnumType.Arrived;
+ updateDetails.Add(detail);
+ }
+
+ // 事务提交设备任务和明细状态更新
+ var r = await DbContext.Client.Ado.UseTranAsync(async () =>
+ {
+ if (deviceTaskList.Any())
+ await DbContext.InsertAsync(deviceTaskList);
+ if (updateDetails.Any())
+ await DbContext.UpdateAsync(updateDetails);
+ });
+
+ // 记录失败日志
+ if (!r.IsSuccess)
+ {
+ Logger.LogError(r.ErrorException, "执行访客预约自动处理车间任务失败:{error}", r.ErrorMessage);
}
}
-
- private static IEnumerable GetValidAreaCodes(VisitorAppointmentDetailEntity detail)
+ ///
+ /// 获取预约明细的有效区域编码
+ ///
+ ///
+ ///
+ private static List GetValidAreaCodes(VisitorAppointmentDetailEntity detail)
{
- return detail.ApplyWorkplaceAreas;
+ return detail.ApplyWorkplaceAreas ?? new List();
}
-}
\ No newline at end of file
+
+ ///
+ /// 根据区域编码获取设备唯一编号和租户ID
+ ///
+ ///
+ ///
+ private async Task> GetDeviceUniqueNoAndTenantIdAsync(List existsAreaCodes)
+ {
+ // 当前分配的设备组code
+ var deviceGroupCodes = await DbContext.Queryable()
+ .Where(x => existsAreaCodes.Contains(x.CustomCode))
+ .Select(x => x.DeviceGroupCode)
+ .ToListAsync();
+ if (!deviceGroupCodes.Any()) return null;
+
+ // 查询设备组下的设备编码
+ var deviceCodes = await DbContext.Queryable()
+ .Where(x => deviceGroupCodes.Contains(x.GroupCode))
+ .Select(x => x.DeviceCode)
+ .ToListAsync();
+ if (!deviceCodes.Any()) return null;
+
+ // 查询设备唯一编号和租户ID
+ var deviceUniqueNos = await DbContext.Queryable()
+ .Where(x => deviceCodes.Contains(x.Code))
+ .Select(x => new { x.UniqueNo, x.TenantId })
+ .ToListAsync();
+
+ return !deviceUniqueNos.Any()
+ ? null
+ : deviceUniqueNos.Select(x => (x.UniqueNo, x.TenantId)).ToList();
+ }
+}
diff --git a/Src/Dlhis.ScheduledTask/Properties/launchSettings.json b/Src/Dlhis.ScheduledTask/Properties/launchSettings.json
index 519808b2..d27ea5fb 100644
--- a/Src/Dlhis.ScheduledTask/Properties/launchSettings.json
+++ b/Src/Dlhis.ScheduledTask/Properties/launchSettings.json
@@ -6,7 +6,7 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
- "applicationUrl": "http://localhost:5010;http://*:5010;"
+ "applicationUrl": "http://*:5010;"
}
}
}
\ No newline at end of file
diff --git a/Src/Dlhis.ScheduledTask/appsettings.Development.json b/Src/Dlhis.ScheduledTask/appsettings.Development.json
index d7342833..202ad4b1 100644
--- a/Src/Dlhis.ScheduledTask/appsettings.Development.json
+++ b/Src/Dlhis.ScheduledTask/appsettings.Development.json
@@ -17,9 +17,9 @@
},
"SwaggerOptions": {
"Enable": true,
- "Authority": "https://yikatong.isawesome.cn/oauth2",
- "ClientId": "4fb184324eac4180",
- "ClientSecret": "8ac8f235152f1524",
+ "Authority": "https://park.yaens.com/oauth2",
+ "ClientId": "98958aa485d38412",
+ "ClientSecret": "52589e011f02fe19",
"Scopes": {
"openid": "openid",
"profile": "profile",
@@ -27,7 +27,7 @@
}
},
"IdentityServerOptions": {
- "Authority": "https://yikatong.isawesome.cn/oauth2",
+ "Authority": "https://park.yaens.com/oauth2",
"RequireHttpsMetadata": true,
"Issuer": "identity.isawesome.cn",
"Audience": "",
diff --git a/Src/Dlhis.ScheduledTask/appsettings.json b/Src/Dlhis.ScheduledTask/appsettings.json
index a1b023d2..a37364e7 100644
--- a/Src/Dlhis.ScheduledTask/appsettings.json
+++ b/Src/Dlhis.ScheduledTask/appsettings.json
@@ -6,9 +6,9 @@
}
},
"InternalRequest": {
- "SysRequestUrl": "http://sys",
- "BasicRequestUrl": "http://basic",
- "CanteenRequestUrl": "http://canteen",
+ "SysRequestUrl": "http://192.168.199.124:5003",
+ "BasicRequestUrl": "http://192.168.199.124:5002",
+ "CanteenRequestUrl": "http://192.168.199.124:5008",
"MessageRequestUrl": "http://message"
},
"DataProtectionOptions": {
@@ -26,7 +26,7 @@
"EnableSqlLog": true
},
"FaceUrlOptions": {
- "Url": "https://yikatong.isawesome.cn/api/basic/gainfos/face?token=",
+ "Url": "https://192.168.199.124/api/basic/gainfos/face?token=",
"Limit": 7200
},
"SwaggerOptions": {
@@ -41,7 +41,7 @@
}
},
"IdentityServerOptions": {
- "Authority": "http://identity.oauth.svc.cluster.local",
+ "Authority": "https://192.168.199.124/oauth2",
"RequireHttpsMetadata": false,
"Issuer": "identity.isawesome.cn",
"Audience": "",