|
|
|
|
@@ -16,7 +16,6 @@ using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions;
|
|
|
|
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
|
|
|
|
using Kurisu.AspNetCore.Utils.Extensions;
|
|
|
|
|
using Microsoft.AspNetCore.DataProtection;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
|
|
|
|
|
namespace Dlhis.Basic.Appointment.Services.Implements;
|
|
|
|
|
@@ -97,16 +96,26 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
var detail = await _dbContext.Queryable<VisitorAppointmentDetailEntity>().Where(x => x.Id == request.Id).SingleAsync();
|
|
|
|
|
detail.ThrowIfNull("预约信息不存在");
|
|
|
|
|
|
|
|
|
|
await GenerateTaskAndUpdateFaceAsync(detail.Id, request.Base64Image, DeviceTaskEnumType.Add);
|
|
|
|
|
|
|
|
|
|
if (detail.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
|
|
|
{
|
|
|
|
|
detail.DoorStatus = VisitorAppointmentDetailStatusEnumType.Arrived;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
true.ThrowIfTrue($"数据有误:{detail.DoorStatus.GetDescription()}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detail.ArrivedTime = DateTime.Now;
|
|
|
|
|
await _dbContext.UpdateAsync(detail);
|
|
|
|
|
|
|
|
|
|
await _gainfoFaceService.UploadExternalFaceAsync(new GainfoUploadFaceRequest
|
|
|
|
|
{
|
|
|
|
|
UserNo = detail.IdNo,
|
|
|
|
|
Face = request.Base64Image
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await GenerateDeviceTasksAsync(detail, false, DeviceTaskEnumType.Add);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _dhApi.SendFaceAsync(new FaceRequest
|
|
|
|
|
@@ -121,53 +130,6 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task GenerateTaskAndUpdateFaceAsync(long detailId, string base64, DeviceTaskEnumType deviceTaskType)
|
|
|
|
|
{
|
|
|
|
|
var detail = await _dbContext.Queryable<VisitorAppointmentDetailEntity>().Where(x => x.Id == detailId).SingleAsync();
|
|
|
|
|
detail.ThrowIfNull("预约信息不存在");
|
|
|
|
|
|
|
|
|
|
var areaCodes = GetValidAreaCodes(detail);
|
|
|
|
|
var existsAreaCodes = await _dbContext.Queryable<AppointmentAreaEntity>().Where(x => areaCodes.Contains(x.CustomCode)).Select(x => x.CustomCode).ToListAsync();
|
|
|
|
|
|
|
|
|
|
//当前分配的设备组code
|
|
|
|
|
var deviceGroupCodes = await _dbContext.Queryable<AppointmentAreaAssignmentEntity>()
|
|
|
|
|
.Where(x => existsAreaCodes.Contains(x.CustomCode))
|
|
|
|
|
.Select(x => x.DeviceGroupCode)
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var deviceCodes = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
|
|
|
|
|
var deviceUniqueNos = await _dbContext.Queryable<DeviceEntity>().Where(x => deviceCodes.Contains(x.Code)).Select(x => new { x.UniqueNo, x.TenantId }).ToListAsync();
|
|
|
|
|
|
|
|
|
|
await _dbContext.InsertAsync(deviceUniqueNos.Select(x => new DeviceTaskEntity
|
|
|
|
|
{
|
|
|
|
|
DeviceType = DeviceTypeEnumType.Door,
|
|
|
|
|
DeviceUniqueNo = x.UniqueNo,
|
|
|
|
|
Status = DeviceTaskStatusEnumType.Wait,
|
|
|
|
|
UserNo = detail.UserNo,
|
|
|
|
|
Type = deviceTaskType,
|
|
|
|
|
Priority = 100,
|
|
|
|
|
TenantId = x.TenantId,
|
|
|
|
|
Source = DeviceTaskSourceEnumType.Appointment,
|
|
|
|
|
Version = 0
|
|
|
|
|
}).ToList());
|
|
|
|
|
|
|
|
|
|
await _gainfoFaceService.UploadExternalFaceAsync(new GainfoUploadFaceRequest
|
|
|
|
|
{
|
|
|
|
|
UserNo = detail.IdNo,
|
|
|
|
|
Face = base64
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static IEnumerable<string> GetValidAreaCodes(VisitorAppointmentDetailEntity detail)
|
|
|
|
|
{
|
|
|
|
|
if (detail.IsEnterDoorArea)
|
|
|
|
|
{
|
|
|
|
|
yield return detail.ApplyDoorArea;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<AppointmentDetailResponse> GetTodayByIdNoAsync(string idNo, string factory)
|
|
|
|
|
{
|
|
|
|
|
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
|
|
|
|
|
@@ -185,7 +147,7 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
.LeftJoin<GainfoEntity>((x, ga) => ga.IdNo == x.IdNo)
|
|
|
|
|
.Where((x, ga) => ga.IdNo == idNo)
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && now >= x.DoorStart && now <= x.DoorEnd && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
|
|
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.Factory == factory).Where(p => p.No == x.No).Any())
|
|
|
|
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
|
|
|
|
.Select(x => new AppointmentDetailResponse
|
|
|
|
|
{
|
|
|
|
|
No = x.No,
|
|
|
|
|
@@ -208,7 +170,29 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
.FirstAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Pagination<AppointmentDetailResponse>> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request)
|
|
|
|
|
|
|
|
|
|
public async Task FocusLeaveAsync(long id, string reason)
|
|
|
|
|
{
|
|
|
|
|
var detail = await _dbContext.Queryable<VisitorAppointmentDetailEntity>().Where(x => x.Id == id).SingleAsync();
|
|
|
|
|
detail.ThrowIfNull("数据不存在");
|
|
|
|
|
|
|
|
|
|
if (detail.IsEnterDoorArea && detail.DoorStatus == VisitorAppointmentDetailStatusEnumType.Arrived)
|
|
|
|
|
{
|
|
|
|
|
detail.DoorStatus = VisitorAppointmentDetailStatusEnumType.FocusLeave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (detail.IsEnterWorkplace && detail.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Arrived)
|
|
|
|
|
{
|
|
|
|
|
detail.WorkplaceStatus = VisitorAppointmentDetailStatusEnumType.FocusLeave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detail.FocusLeaveDateTime = DateTime.Now;
|
|
|
|
|
detail.Remark += "强制离场原因:" + reason;
|
|
|
|
|
|
|
|
|
|
await GenerateDeviceTasksAsync(detail, true, DeviceTaskEnumType.Delete);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Pagination<AppointmentDetailResponse>> GetRecordPageByIdNoAsync(AppointmentIdNoPageRequest request)
|
|
|
|
|
{
|
|
|
|
|
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
|
|
|
|
|
try
|
|
|
|
|
@@ -271,12 +255,10 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public async Task<AppointmentSummaryResponse> GetSummaryAsync(string factory, DateTime start, DateTime end)
|
|
|
|
|
{
|
|
|
|
|
var total = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorStart, start))
|
|
|
|
|
//|| (x.IsEnterWorkplace && ((x.WorkplaceStart >= start && x.WorkplaceStart <= end) || (x.WorkplaceEnd >= start && x.WorkplaceEnd <= end)))
|
|
|
|
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
|
|
|
|
.CountAsync();
|
|
|
|
|
|
|
|
|
|
@@ -287,18 +269,13 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
|
|
|
|
|
var notIn = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorStart, start))
|
|
|
|
|
//|| (x.IsEnterWorkplace && ((x.WorkplaceStart >= start && x.WorkplaceStart <= end) || (x.WorkplaceEnd >= start && x.WorkplaceEnd <= end)))
|
|
|
|
|
.Where(x => (x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
|
|
|
//|| (x.IsEnterWorkplace && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
|
|
|
)
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
|
|
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
|
|
|
|
.CountAsync();
|
|
|
|
|
|
|
|
|
|
var leave = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorEnd, start))
|
|
|
|
|
.Where(x => (x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Leave)
|
|
|
|
|
//|| (x.IsEnterWorkplace && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Leave)
|
|
|
|
|
)
|
|
|
|
|
.Where(x => x.IsEnterDoorArea && (x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Leave || x.DoorStatus == VisitorAppointmentDetailStatusEnumType.FocusLeave))
|
|
|
|
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
|
|
|
|
.CountAsync();
|
|
|
|
|
|
|
|
|
|
@@ -316,4 +293,69 @@ public class AppointmentService : IAppointmentService
|
|
|
|
|
NotLeave = notLeave
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public async Task UpdateFaceAsync(long detailId, string base64)
|
|
|
|
|
{
|
|
|
|
|
var detail = await _dbContext.Queryable<VisitorAppointmentDetailEntity>().Where(x => x.Id == detailId).SingleAsync();
|
|
|
|
|
detail.ThrowIfNull("数据不存在");
|
|
|
|
|
|
|
|
|
|
await _gainfoFaceService.UploadExternalFaceAsync(new GainfoUploadFaceRequest
|
|
|
|
|
{
|
|
|
|
|
UserNo = detail.IdNo,
|
|
|
|
|
Face = base64
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await GenerateDeviceTasksAsync(detail, true, DeviceTaskEnumType.Update);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task GenerateDeviceTasksAsync(VisitorAppointmentDetailEntity detail, bool withWorkplace, DeviceTaskEnumType deviceTaskType)
|
|
|
|
|
{
|
|
|
|
|
var areaCodes = GetValidAreaCodes(detail, withWorkplace).ToList();
|
|
|
|
|
if (areaCodes.Any())
|
|
|
|
|
{
|
|
|
|
|
var existsAreaCodes = await _dbContext.Queryable<AppointmentAreaEntity>().Where(x => areaCodes.Contains(x.CustomCode)).Select(x => x.CustomCode).ToListAsync();
|
|
|
|
|
|
|
|
|
|
//当前分配的设备组code
|
|
|
|
|
var deviceGroupCodes = await _dbContext.Queryable<AppointmentAreaAssignmentEntity>()
|
|
|
|
|
.Where(x => existsAreaCodes.Contains(x.CustomCode))
|
|
|
|
|
.Select(x => x.DeviceGroupCode)
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var deviceCodes = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
|
|
|
|
|
var deviceUniqueNos = await _dbContext.Queryable<DeviceEntity>().Where(x => deviceCodes.Contains(x.Code)).Select(x => new { x.UniqueNo, x.TenantId }).ToListAsync();
|
|
|
|
|
|
|
|
|
|
await _dbContext.InsertAsync(deviceUniqueNos.Select(x => new DeviceTaskEntity
|
|
|
|
|
{
|
|
|
|
|
DeviceType = DeviceTypeEnumType.Door,
|
|
|
|
|
DeviceUniqueNo = x.UniqueNo,
|
|
|
|
|
Status = DeviceTaskStatusEnumType.Wait,
|
|
|
|
|
UserNo = detail.UserNo,
|
|
|
|
|
Type = deviceTaskType,
|
|
|
|
|
Priority = 100,
|
|
|
|
|
TenantId = x.TenantId,
|
|
|
|
|
Source = DeviceTaskSourceEnumType.Appointment,
|
|
|
|
|
Version = 0
|
|
|
|
|
}).ToList());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IEnumerable<string> GetValidAreaCodes(VisitorAppointmentDetailEntity detail, bool withWorkplace)
|
|
|
|
|
{
|
|
|
|
|
if (detail.IsEnterDoorArea)
|
|
|
|
|
{
|
|
|
|
|
yield return detail.ApplyDoorArea;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (withWorkplace && detail.IsEnterWorkplace)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in detail.ApplyWorkplaceAreas)
|
|
|
|
|
{
|
|
|
|
|
yield return item;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|