diff --git a/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs b/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs
index bd78cd22..3d6c1a5d 100644
--- a/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs
+++ b/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs
@@ -61,13 +61,26 @@ public class AppointmentsController : ControllerBase
await _appointmentService.ConfirmAsync(request);
}
- [AllowAnonymous]
+ ///
+ /// 强制离场
+ ///
+ ///
+ [HttpPost("focusleave")]
+ [Transactional]
+ public async Task FocusLeaveAsync(AppointmentFocusLeaveRequest request)
+ {
+ await _appointmentService.FocusLeaveAsync(request.Id, request.Reason);
+ }
+
+ ///
+ /// 人脸更新
+ ///
+ ///
[HttpPost("face/update")]
[Transactional]
- [IgnoreTenant]
- public async Task GenerateTaskAndUpdateFaceAsync(AppointmentConfirmRequest request)
+ public async Task UpdateFaceAsync(AppointmentConfirmRequest request)
{
- await _appointmentService.GenerateTaskAndUpdateFaceAsync(request.Id, request.Base64Image, DeviceTaskEnumType.Update);
+ await _appointmentService.UpdateFaceAsync(request.Id, request.Base64Image);
}
///
diff --git a/Src/Dlhis.Basic/Appointment/Request/AppointmentConfirmRequest.cs b/Src/Dlhis.Basic/Appointment/Request/AppointmentConfirmRequest.cs
index 8c3c207a..d8ae9054 100644
--- a/Src/Dlhis.Basic/Appointment/Request/AppointmentConfirmRequest.cs
+++ b/Src/Dlhis.Basic/Appointment/Request/AppointmentConfirmRequest.cs
@@ -1,4 +1,6 @@
-namespace Dlhis.Basic.Appointment.Request;
+using System.ComponentModel.DataAnnotations;
+
+namespace Dlhis.Basic.Appointment.Request;
public class AppointmentConfirmRequest
{
@@ -10,5 +12,6 @@ public class AppointmentConfirmRequest
///
/// base64 image
///
+ [Required]
public string Base64Image { get; set; }
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Appointment/Request/AppointmentFocusLeaveRequest.cs b/Src/Dlhis.Basic/Appointment/Request/AppointmentFocusLeaveRequest.cs
new file mode 100644
index 00000000..b367bba7
--- /dev/null
+++ b/Src/Dlhis.Basic/Appointment/Request/AppointmentFocusLeaveRequest.cs
@@ -0,0 +1,11 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Dlhis.Basic.Appointment.Request;
+
+public class AppointmentFocusLeaveRequest
+{
+ public long Id { get; set; }
+
+ [Required(ErrorMessage = "原因不可为空")]
+ public string Reason { get; set; }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Appointment/Services/IAppointmentService.cs b/Src/Dlhis.Basic/Appointment/Services/IAppointmentService.cs
index 11780c93..7c037ee7 100644
--- a/Src/Dlhis.Basic/Appointment/Services/IAppointmentService.cs
+++ b/Src/Dlhis.Basic/Appointment/Services/IAppointmentService.cs
@@ -38,6 +38,14 @@ public interface IAppointmentService : IScopeDependency
///
Task GetTodayByIdNoAsync(string idNo, string factory);
+ ///
+ /// 强制离开
+ ///
+ ///
+ ///
+ ///
+ Task FocusLeaveAsync(long id, string reason);
+
///
/// 获取记录列表
///
@@ -53,5 +61,5 @@ public interface IAppointmentService : IScopeDependency
Task GetSummaryAsync(string factory, DateTime start, DateTime end);
- Task GenerateTaskAndUpdateFaceAsync(long detailId, string base64, DeviceTaskEnumType deviceTaskType);
+ Task UpdateFaceAsync(long detailId, string base64);
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Appointment/Services/Implements/AppointmentService.cs b/Src/Dlhis.Basic/Appointment/Services/Implements/AppointmentService.cs
index 3ab01224..171d178f 100644
--- a/Src/Dlhis.Basic/Appointment/Services/Implements/AppointmentService.cs
+++ b/Src/Dlhis.Basic/Appointment/Services/Implements/AppointmentService.cs
@@ -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().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().Where(x => x.Id == detailId).SingleAsync();
- detail.ThrowIfNull("预约信息不存在");
-
- var areaCodes = GetValidAreaCodes(detail);
- 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
- {
- 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 GetValidAreaCodes(VisitorAppointmentDetailEntity detail)
- {
- if (detail.IsEnterDoorArea)
- {
- yield return detail.ApplyDoorArea;
- }
- }
-
-
public async Task GetTodayByIdNoAsync(string idNo, string factory)
{
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
@@ -185,7 +147,7 @@ public class AppointmentService : IAppointmentService
.LeftJoin((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().Where(p => p.Factory == factory).Where(p => p.No == x.No).Any())
+ .Where(x => SqlFunc.Subqueryable().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> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request)
+
+ public async Task FocusLeaveAsync(long id, string reason)
+ {
+ var detail = await _dbContext.Queryable().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> GetRecordPageByIdNoAsync(AppointmentIdNoPageRequest request)
{
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
try
@@ -271,12 +255,10 @@ public class AppointmentService : IAppointmentService
}
- ///
public async Task GetSummaryAsync(string factory, DateTime start, DateTime end)
{
var total = await _dbContext.Queryable()
.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().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()
.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().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
.CountAsync();
var leave = await _dbContext.Queryable()
.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().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().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().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
+ {
+ 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 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;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs
index ff797d36..bf94af3f 100644
--- a/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs
+++ b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs
@@ -117,6 +117,12 @@ public class VisitorAppointmentDetailEntity : SugarBaseEntity
///
[SugarColumn(IsNullable = true)]
public DateTime? ArrivedTime { get; set; }
+
+ ///
+ /// 强制离场时间
+ ///
+ [SugarColumn(IsNullable = true)]
+ public DateTime? FocusLeaveDateTime { get; set; }
///
/// 车间状态
diff --git a/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailStatusEnumType.cs b/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailStatusEnumType.cs
index d89e45e1..46202b22 100644
--- a/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailStatusEnumType.cs
+++ b/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailStatusEnumType.cs
@@ -25,7 +25,7 @@ public enum VisitorAppointmentDetailStatusEnumType
///
[Description("到达")]
Arrived = 10,
-
+
///
/// 离开
///
@@ -33,8 +33,14 @@ public enum VisitorAppointmentDetailStatusEnumType
Leave = 11,
///
- /// 作废
+ /// 强制离场
///
- [Description("作废")]
+ [Description("强制离场")]
+ FocusLeave = 12,
+
+ ///
+ /// 未预约
+ ///
+ [Description("未预约")]
Obsolete = 99
-}
+}
\ No newline at end of file