feat 访客强制离场,更新照片
This commit is contained in:
@@ -61,13 +61,26 @@ public class AppointmentsController : ControllerBase
|
|||||||
await _appointmentService.ConfirmAsync(request);
|
await _appointmentService.ConfirmAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
/// <summary>
|
||||||
|
/// 强制离场
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
[HttpPost("focusleave")]
|
||||||
|
[Transactional]
|
||||||
|
public async Task FocusLeaveAsync(AppointmentFocusLeaveRequest request)
|
||||||
|
{
|
||||||
|
await _appointmentService.FocusLeaveAsync(request.Id, request.Reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 人脸更新
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
[HttpPost("face/update")]
|
[HttpPost("face/update")]
|
||||||
[Transactional]
|
[Transactional]
|
||||||
[IgnoreTenant]
|
public async Task UpdateFaceAsync(AppointmentConfirmRequest request)
|
||||||
public async Task GenerateTaskAndUpdateFaceAsync(AppointmentConfirmRequest request)
|
|
||||||
{
|
{
|
||||||
await _appointmentService.GenerateTaskAndUpdateFaceAsync(request.Id, request.Base64Image, DeviceTaskEnumType.Update);
|
await _appointmentService.UpdateFaceAsync(request.Id, request.Base64Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace Dlhis.Basic.Appointment.Request;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Appointment.Request;
|
||||||
|
|
||||||
public class AppointmentConfirmRequest
|
public class AppointmentConfirmRequest
|
||||||
{
|
{
|
||||||
@@ -10,5 +12,6 @@ public class AppointmentConfirmRequest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// base64 image
|
/// base64 image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Required]
|
||||||
public string Base64Image { get; set; }
|
public string Base64Image { get; set; }
|
||||||
}
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -38,6 +38,14 @@ public interface IAppointmentService : IScopeDependency
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<AppointmentDetailResponse> GetTodayByIdNoAsync(string idNo, string factory);
|
Task<AppointmentDetailResponse> GetTodayByIdNoAsync(string idNo, string factory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 强制离开
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="reason"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task FocusLeaveAsync(long id, string reason);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取记录列表
|
/// 获取记录列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -53,5 +61,5 @@ public interface IAppointmentService : IScopeDependency
|
|||||||
|
|
||||||
Task<AppointmentSummaryResponse> GetSummaryAsync(string factory, DateTime start, DateTime end);
|
Task<AppointmentSummaryResponse> GetSummaryAsync(string factory, DateTime start, DateTime end);
|
||||||
|
|
||||||
Task GenerateTaskAndUpdateFaceAsync(long detailId, string base64, DeviceTaskEnumType deviceTaskType);
|
Task UpdateFaceAsync(long detailId, string base64);
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,6 @@ using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions;
|
|||||||
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Appointment.Services.Implements;
|
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();
|
var detail = await _dbContext.Queryable<VisitorAppointmentDetailEntity>().Where(x => x.Id == request.Id).SingleAsync();
|
||||||
detail.ThrowIfNull("预约信息不存在");
|
detail.ThrowIfNull("预约信息不存在");
|
||||||
|
|
||||||
await GenerateTaskAndUpdateFaceAsync(detail.Id, request.Base64Image, DeviceTaskEnumType.Add);
|
|
||||||
|
|
||||||
if (detail.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
if (detail.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
||||||
{
|
{
|
||||||
detail.DoorStatus = VisitorAppointmentDetailStatusEnumType.Arrived;
|
detail.DoorStatus = VisitorAppointmentDetailStatusEnumType.Arrived;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
true.ThrowIfTrue($"数据有误:{detail.DoorStatus.GetDescription()}");
|
||||||
|
}
|
||||||
|
|
||||||
detail.ArrivedTime = DateTime.Now;
|
detail.ArrivedTime = DateTime.Now;
|
||||||
await _dbContext.UpdateAsync(detail);
|
await _dbContext.UpdateAsync(detail);
|
||||||
|
|
||||||
|
await _gainfoFaceService.UploadExternalFaceAsync(new GainfoUploadFaceRequest
|
||||||
|
{
|
||||||
|
UserNo = detail.IdNo,
|
||||||
|
Face = request.Base64Image
|
||||||
|
});
|
||||||
|
|
||||||
|
await GenerateDeviceTasksAsync(detail, false, DeviceTaskEnumType.Add);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _dhApi.SendFaceAsync(new FaceRequest
|
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)
|
public async Task<AppointmentDetailResponse> GetTodayByIdNoAsync(string idNo, string factory)
|
||||||
{
|
{
|
||||||
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
|
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
|
||||||
@@ -185,7 +147,7 @@ public class AppointmentService : IAppointmentService
|
|||||||
.LeftJoin<GainfoEntity>((x, ga) => ga.IdNo == x.IdNo)
|
.LeftJoin<GainfoEntity>((x, ga) => ga.IdNo == x.IdNo)
|
||||||
.Where((x, ga) => ga.IdNo == idNo)
|
.Where((x, ga) => ga.IdNo == idNo)
|
||||||
.Where(x => x.IsEnterDoorArea && now >= x.DoorStart && now <= x.DoorEnd && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
.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
|
.Select(x => new AppointmentDetailResponse
|
||||||
{
|
{
|
||||||
No = x.No,
|
No = x.No,
|
||||||
@@ -208,7 +170,29 @@ public class AppointmentService : IAppointmentService
|
|||||||
.FirstAsync();
|
.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");
|
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
|
||||||
try
|
try
|
||||||
@@ -271,12 +255,10 @@ public class AppointmentService : IAppointmentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<AppointmentSummaryResponse> GetSummaryAsync(string factory, DateTime start, DateTime end)
|
public async Task<AppointmentSummaryResponse> GetSummaryAsync(string factory, DateTime start, DateTime end)
|
||||||
{
|
{
|
||||||
var total = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
var total = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
||||||
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorStart, start))
|
.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())
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
|
|
||||||
@@ -287,18 +269,13 @@ public class AppointmentService : IAppointmentService
|
|||||||
|
|
||||||
var notIn = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
var notIn = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
||||||
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorStart, start))
|
.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)
|
||||||
.Where(x => (x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
||||||
//|| (x.IsEnterWorkplace && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Wait)
|
|
||||||
)
|
|
||||||
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
|
|
||||||
var leave = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
var leave = await _dbContext.Queryable<VisitorAppointmentDetailEntity>()
|
||||||
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorEnd, start))
|
.Where(x => x.IsEnterDoorArea && SqlFunc.DateIsSame(x.DoorEnd, start))
|
||||||
.Where(x => (x.IsEnterDoorArea && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Leave)
|
.Where(x => x.IsEnterDoorArea && (x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Leave || x.DoorStatus == VisitorAppointmentDetailStatusEnumType.FocusLeave))
|
||||||
//|| (x.IsEnterWorkplace && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Leave)
|
|
||||||
)
|
|
||||||
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
.Where(x => SqlFunc.Subqueryable<VisitorAppointmentEntity>().Where(p => p.No == x.No).Where(p => p.Factory == factory).Any())
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
|
|
||||||
@@ -316,4 +293,69 @@ public class AppointmentService : IAppointmentService
|
|||||||
NotLeave = notLeave
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -117,6 +117,12 @@ public class VisitorAppointmentDetailEntity : SugarBaseEntity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(IsNullable = true)]
|
[SugarColumn(IsNullable = true)]
|
||||||
public DateTime? ArrivedTime { get; set; }
|
public DateTime? ArrivedTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 强制离场时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public DateTime? FocusLeaveDateTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 车间状态
|
/// 车间状态
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public enum VisitorAppointmentDetailStatusEnumType
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("到达")]
|
[Description("到达")]
|
||||||
Arrived = 10,
|
Arrived = 10,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 离开
|
/// 离开
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -33,8 +33,14 @@ public enum VisitorAppointmentDetailStatusEnumType
|
|||||||
Leave = 11,
|
Leave = 11,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 作废
|
/// 强制离场
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("作废")]
|
[Description("强制离场")]
|
||||||
|
FocusLeave = 12,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 未预约
|
||||||
|
/// </summary>
|
||||||
|
[Description("未预约")]
|
||||||
Obsolete = 99
|
Obsolete = 99
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user