|
|
|
@ -14,6 +14,7 @@ using Newtonsoft.Json;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using DS.Module.DjyServiceStatus;
|
|
|
|
|
|
|
|
|
|
namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
{
|
|
|
|
@ -680,11 +681,18 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
whereList = tenantDb.Utilities.JsonToConditionalModels(querySearch.QueryCondition);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化参数
|
|
|
|
|
TaskBaseTypeEnum? taskType = null;
|
|
|
|
|
if (Enum.TryParse(typeof(TaskBaseTypeEnum), querySearch.OtherQueryCondition?.TaskType, out object? temp))
|
|
|
|
|
{
|
|
|
|
|
taskType = (TaskBaseTypeEnum)temp;
|
|
|
|
|
};
|
|
|
|
|
TaskStatLevelEnum? taskStatLevel = null;
|
|
|
|
|
if (Enum.TryParse(typeof(TaskStatLevelEnum), querySearch.OtherQueryCondition?.TaskCategory, out object? tempStat))
|
|
|
|
|
{
|
|
|
|
|
taskStatLevel = (TaskStatLevelEnum)tempStat;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var userId = long.Parse(user.UserId);
|
|
|
|
|
DataResult<List<dynamic>> result;
|
|
|
|
@ -696,6 +704,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskBCInfo>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
Id = t.Id.SelectAll(),
|
|
|
|
@ -783,6 +794,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskSiSubmitted>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -836,6 +850,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskPerBillBase>((t, a, bc) => t.Id == bc.TASK_PKID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -859,6 +876,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskTruck>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -923,6 +943,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskCutDateChangeInfo>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -942,6 +965,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskRollingNomination>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -967,6 +993,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskDraftInfo>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -989,6 +1018,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskPodDischargeGateoutFull>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -1007,6 +1039,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskCautionNotice>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -1037,6 +1072,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
.LeftJoin<TaskRouteChangeAdvisory>((t, a, bc) => t.Id == bc.TASK_ID)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>((t, a, bc) => new
|
|
|
|
|
{
|
|
|
|
|
PK_ID = t.Id.SelectAll(),
|
|
|
|
@ -1067,6 +1105,9 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
result = await tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
|
|
|
|
|
.Where(whereList)
|
|
|
|
|
.Where((t, a) => a.UserId == userId || t.CreateBy == userId)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.EXCPTION, (t, a) => t.IS_EXCEPT == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1)
|
|
|
|
|
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
|
|
.Select<dynamic>(t => t)
|
|
|
|
|
.ToQueryPageAsync(querySearch.PageCondition);
|
|
|
|
|
return result;
|
|
|
|
@ -1315,9 +1356,6 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
return DataResult<TaskUserStatResultInfo>.Success(resultInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 私有方法
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -1433,6 +1471,192 @@ namespace DS.WMS.Core.TaskPlat.Method
|
|
|
|
|
return fileType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取消任务(可批量)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ids">任务主键数组</param>
|
|
|
|
|
/// <returns>返回结果</returns>
|
|
|
|
|
public async Task<DataResult<TaskManageOrderResultDto>> CancelTask(long[] ids)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
var userId = long.Parse(user.UserId);
|
|
|
|
|
string batchNo = Guid.NewGuid().ToString();
|
|
|
|
|
|
|
|
|
|
var taskList = await tenantDb.Queryable<TaskBaseInfo>()
|
|
|
|
|
.Where(x => ids.Contains(x.Id)).ToListAsync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<TaskManageOrderResultDto> taskRunList = new List<TaskManageOrderResultDto>();
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 取消任务开始", batchNo, string.Join(",", ids));
|
|
|
|
|
|
|
|
|
|
var noList = ids.Select((a, idx) => new { no = idx + 1, id = a }).ToList();
|
|
|
|
|
|
|
|
|
|
foreach (var bk in taskList)
|
|
|
|
|
{
|
|
|
|
|
var sortNo = noList.FirstOrDefault(a => a.id == bk.Id).no;
|
|
|
|
|
taskRunList.Add(await InnerManualTask(batchNo, bk, TaskOperTypeEnum.CANCEL_TASK, sortNo));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "执行成功";
|
|
|
|
|
|
|
|
|
|
var downResultList = taskRunList.Select(x => x).ToList();
|
|
|
|
|
|
|
|
|
|
if (downResultList.Any(x => !x.succ))
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = "执行失败";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = downResultList.FirstOrDefault().msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.ext = downResultList;
|
|
|
|
|
|
|
|
|
|
var succ = downResultList.Count(x => x.succ);
|
|
|
|
|
var fail = downResultList.Count(x => !x.succ);
|
|
|
|
|
|
|
|
|
|
if (succ > 0)
|
|
|
|
|
{
|
|
|
|
|
result.batchTotal = succ.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result.batchTotal = "- ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fail > 0)
|
|
|
|
|
{
|
|
|
|
|
result.batchTotal += "/" + fail.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result.batchTotal += " -";
|
|
|
|
|
}
|
|
|
|
|
return DataResult<TaskManageOrderResultDto>.Success(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 单票执行任务
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 单票执行任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
|
|
/// <param name="model">任务详情</param>
|
|
|
|
|
/// <param name="taskOperTypeEnum">操作类型</param>
|
|
|
|
|
/// <param name="sortNo">顺序号</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
private async Task<TaskManageOrderResultDto> InnerManualTask(string batchNo, TaskBaseInfo model,
|
|
|
|
|
TaskOperTypeEnum taskOperTypeEnum, int sortNo)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
result.bno = model.TASK_NO;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
var userId = long.Parse(user.UserId);
|
|
|
|
|
|
|
|
|
|
if (taskOperTypeEnum == TaskOperTypeEnum.COMPLETE_TASK)
|
|
|
|
|
{
|
|
|
|
|
if (model.TASK_TYPE == TaskBaseTypeEnum.TRUCK_DISPATCH.ToString())
|
|
|
|
|
{
|
|
|
|
|
if (model.STATUS == TaskStatusEnum.Cancel.ToString())
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskCannotCompleteWhenStatusMismatch)), TaskStatusEnum.Cancel.EnumDescription()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (model.TASK_TYPE == TaskBaseTypeEnum.CANCELLATION.ToString())
|
|
|
|
|
{
|
|
|
|
|
//收到订舱已被取消邮件后生成的任务,如果点击完成,(订舱状态变为【退舱】,注意这里还需要确认)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model.COMPLETE_DATE = DateTime.Now;
|
|
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.EnumDescription();
|
|
|
|
|
model.IS_COMPLETE = 1;
|
|
|
|
|
model.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
|
|
model.STATUS_NAME = TaskStatusEnum.Complete.EnumDescription();
|
|
|
|
|
|
|
|
|
|
await tenantDb.Updateable(model).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.COMPLETE_DATE,
|
|
|
|
|
it.COMPLETE_DEAL,
|
|
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
|
|
it.IS_COMPLETE,
|
|
|
|
|
it.STATUS,
|
|
|
|
|
it.STATUS_NAME,
|
|
|
|
|
it.UpdateBy,
|
|
|
|
|
it.UpdateTime,
|
|
|
|
|
it.UpdateUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else if (taskOperTypeEnum == TaskOperTypeEnum.CANCEL_TASK)
|
|
|
|
|
{
|
|
|
|
|
if (model.TASK_TYPE == TaskBaseTypeEnum.CHANGE_SHIP.ToString())
|
|
|
|
|
{
|
|
|
|
|
model.STATUS = TaskStatusEnum.Cancel.ToString();
|
|
|
|
|
model.STATUS_NAME = TaskStatusEnum.Cancel.EnumDescription();
|
|
|
|
|
|
|
|
|
|
await tenantDb.Updateable(model).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.COMPLETE_DATE,
|
|
|
|
|
it.COMPLETE_DEAL,
|
|
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
|
|
it.IS_COMPLETE,
|
|
|
|
|
it.STATUS,
|
|
|
|
|
it.STATUS_NAME,
|
|
|
|
|
it.UpdateBy,
|
|
|
|
|
it.UpdateTime,
|
|
|
|
|
it.UpdateUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else if (model.TASK_TYPE == TaskBaseTypeEnum.ABORT_CHANGE_SHIP.ToString())
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
1.如果原换船通知已经接受,需要把原船名航次恢复并通知客户取消换船。
|
|
|
|
|
2.如果原换船通知未作处理,点击接受或者结束任务时提示:本票货存在未处理换船通知,请先结束原换船任务然后结束本任务。
|
|
|
|
|
3.如果原换船任务为结束任务,在取消换船任务点接受时,提示未做换船,请点击结束任务。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// 查询同票主单的是否有未处理的换船通知
|
|
|
|
|
// _taskBaseInfoRepository.AsQueryable().Where(t=>t.MBL_NO.Equals(taskBaseInfo.MBL_NO) && )
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
model.STATUS = TaskStatusEnum.Cancel.ToString();
|
|
|
|
|
model.STATUS_NAME = TaskStatusEnum.Cancel.EnumDescription();
|
|
|
|
|
|
|
|
|
|
await tenantDb.Updateable(model).UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.STATUS,
|
|
|
|
|
it.STATUS_NAME,
|
|
|
|
|
it.UpdateBy,
|
|
|
|
|
it.UpdateTime,
|
|
|
|
|
it.UpdateUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "执行成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|