feat 增加券导入,获取设备数据权限的人员
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
using Dlhis.Entity.Basic.Entity;
|
||||
using Dlhis.Entity.Device.Entities;
|
||||
using Dlhis.Entity.Device.Enums;
|
||||
using Dlhis.Entity.Visitor.Entity;
|
||||
using Dlhis.Entity.Visitor.Enums;
|
||||
using Dlhis.ScheduledTask.Attributes;
|
||||
|
||||
namespace Dlhis.ScheduledTask.Jobs.Visitor;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 定时任务:每5分钟执行一次,自动处理访客预约车间相关逻辑。
|
||||
/// </summary>
|
||||
[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<VisitorAppointmentDetailEntity>()
|
||||
.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<GainfoEntity>()
|
||||
.Where(x => idNos.Contains(x.IdNo) || idNos.Contains(x.Code))
|
||||
.ToListAsync();
|
||||
|
||||
// 批量获取所有有效区域编码,避免循环中多次查库
|
||||
var allValidAreaCodes = details.SelectMany(GetValidAreaCodes).Distinct().ToList();
|
||||
// 查询所有有效区域编码
|
||||
var allAreaCodes = await DbContext.Queryable<AppointmentAreaEntity>()
|
||||
.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<DeviceTaskEntity>(); // 设备任务列表
|
||||
var updateDetails = new List<VisitorAppointmentDetailEntity>(); // 需要更新的预约明细
|
||||
|
||||
foreach (var detail in details)
|
||||
{
|
||||
// 查找对应访客信息
|
||||
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;
|
||||
}
|
||||
|
||||
// 生成设备任务
|
||||
deviceTaskList.AddRange(deviceInfos.Select(x => new DeviceTaskEntity
|
||||
{
|
||||
DeviceType = DeviceTypeEnumType.Door,
|
||||
DeviceUniqueNo = x.UniqueNo,
|
||||
Status = DeviceTaskStatusEnumType.Wait,
|
||||
UserNo = gainfo.No,
|
||||
Type = DeviceTaskEnumType.Add,
|
||||
Priority = 100,
|
||||
TenantId = x.TenantId,
|
||||
Source = "定时任务判断触发车间下发任务",
|
||||
Version = 0
|
||||
}));
|
||||
|
||||
// 更新预约明细状态
|
||||
if (detail.WorkplaceStatus != VisitorAppointmentDetailStatusEnumType.Wait) continue;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取预约明细的有效区域编码
|
||||
/// </summary>
|
||||
/// <param name="detail"></param>
|
||||
/// <returns></returns>
|
||||
private static List<string> GetValidAreaCodes(VisitorAppointmentDetailEntity detail)
|
||||
{
|
||||
return detail.ApplyWorkplaceAreas ?? new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据区域编码获取设备唯一编号和租户ID
|
||||
/// </summary>
|
||||
/// <param name="existsAreaCodes"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<List<(string UniqueNo, string TenantId)>> GetDeviceUniqueNoAndTenantIdAsync(List<string> existsAreaCodes)
|
||||
{
|
||||
// 当前分配的设备组code
|
||||
var deviceGroupCodes = await DbContext.Queryable<AppointmentAreaAssignmentEntity>()
|
||||
.Where(x => existsAreaCodes.Contains(x.CustomCode))
|
||||
.Select(x => x.DeviceGroupCode)
|
||||
.ToListAsync();
|
||||
if (!deviceGroupCodes.Any()) return null;
|
||||
|
||||
// 查询设备组下的设备编码
|
||||
var deviceCodes = await DbContext.Queryable<DeviceGroupRelationshipEntity>()
|
||||
.Where(x => deviceGroupCodes.Contains(x.GroupCode))
|
||||
.Select(x => x.DeviceCode)
|
||||
.ToListAsync();
|
||||
if (!deviceCodes.Any()) return null;
|
||||
|
||||
// 查询设备唯一编号和租户ID
|
||||
var deviceUniqueNos = await DbContext.Queryable<DeviceEntity>()
|
||||
.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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user