diff --git a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs index 65a96af4..923c10da 100644 --- a/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskInteraction/Method/TaskService.cs @@ -565,7 +565,7 @@ namespace DS.WMS.Core.TaskInteraction.Method DataResult result; if (!FeeTypes.Contains(request.TaskType)) { - result = await ManagerService.SetTaskStatusWithBsno(request.BusinessId, request.TaskType, request.TaskStatus, DateTime.Now, request.TaskDesc); + result = await ManagerService.SetTaskStatusWithBsno(request.BusinessId, request.TaskType, request.TaskStatus, DateTime.Now, false, request.TaskDesc); if (!result.Succeeded) return DataResult.Failed(result.Message, result.MultiCode); @@ -830,7 +830,7 @@ namespace DS.WMS.Core.TaskInteraction.Method } else { - result = await ManagerService.SetTaskStatusWithBsno(request.BusinessId, request.TaskType, TaskStatusEnum.Cancel, dt); + result = await ManagerService.SetTaskStatusWithBsno(request.BusinessId, request.TaskType, TaskStatusEnum.Cancel, dt, false); if (!result.Succeeded) return result; } @@ -966,7 +966,7 @@ namespace DS.WMS.Core.TaskInteraction.Method if (relativeTasks.All(x => x.TaskStatus == TaskStatusEnum.Complete)) { var userIdList = tasks.Where(x => relativeFeeIds.Contains(x.BusinessId)).SelectMany(x => x.RecvUserIdArray).Distinct().ToList(); - result = await ManagerService.SetTaskStatusWithBsno(biz.Key.BusinessId, request.TaskType, TaskStatusEnum.Complete, DateTime.Now, userIdList: userIdList); + result = await ManagerService.SetTaskStatusWithBsno(biz.Key.BusinessId, request.TaskType, TaskStatusEnum.Complete, DateTime.Now, false, userIdList: userIdList); if (!result.Succeeded) return result; } @@ -1282,7 +1282,7 @@ namespace DS.WMS.Core.TaskInteraction.Method /// 描述信息 public async Task SetTaskBaseDescription(long id, TaskBaseTypeEnum taskType, string description) { - await ManagerService.SetTaskBaseInfoPropertyWithBsno(id, taskType, x => x.TASK_DESP == description); + await ManagerService.SetTaskBaseInfoPropertyWithBsno(id, taskType, null, null, x => x.TASK_DESP == description); } } diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageHeadInfo.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageHeadInfo.cs index b0e8dda4..e6c79db2 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageHeadInfo.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageHeadInfo.cs @@ -18,6 +18,16 @@ namespace DS.WMS.Core.TaskPlat.Dtos /// public long? BSNO { get; set; } + /// + /// 子业务主键(用于创建子任务) + /// + public long ChildBSNO { get; set; } + + /// + /// 是否创建为子任务 + /// + public bool IsChild { get; set; } + /// /// 报文类型 TASK-任务 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageMainInfo.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageMainInfo.cs index 79a7ba4e..20427a59 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageMainInfo.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Dtos/TaskManageOrderMessageMainInfo.cs @@ -14,6 +14,11 @@ namespace DS.WMS.Core.TaskPlat.Dtos /// public TaskBaseTypeEnum TaskType { get; set; } + /// + /// 子任务类型 + /// + public TaskBaseTypeEnum ChildTaskType { get; set; } + /// /// 校验任务重复时是否判断任务类型 /// diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Entity/TaskBaseInfo.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Entity/TaskBaseInfo.cs index e5a95538..ed27adf0 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Entity/TaskBaseInfo.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Entity/TaskBaseInfo.cs @@ -34,6 +34,18 @@ namespace DS.WMS.Core.TaskPlat.Entity [SugarColumn(ColumnDescription = "任务类型名称", IsNullable = true, Length = 255)] public string? TASK_TYPE_NAME { get; set; } + /// + /// 是否为子任务 + /// + [SugarColumn(ColumnDescription = "是否为子任务", IsNullable = false, DefaultValue = "0")] + public bool IsChild { get; set; } + + /// + /// 父任务主键 + /// + [SugarColumn(ColumnDescription = "父任务主键", IsNullable = false, DefaultValue = "0")] + public long ParentTaskId { get; set; } + /// /// 任务来源 /// @@ -88,6 +100,12 @@ namespace DS.WMS.Core.TaskPlat.Entity [SugarColumn(ColumnDescription = "外业务主键", IsNullable = true)] public long? OUT_BS_NO { get; set; } + /// + /// 子任务外业务主键 + /// + [SugarColumn(ColumnDescription = "外业务主键", IsNullable = true)] + public long? CHILD_OUT_BS_NO { get; set; } + ///// ///// 基础业务类型 ///// diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskAllocationService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskAllocationService.cs index 79cebb92..08be8664 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskAllocationService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskAllocationService.cs @@ -2,6 +2,7 @@ using DS.Module.Core.Data; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; +using SqlSugar; namespace DS.WMS.Core.TaskPlat.Interface { @@ -45,5 +46,6 @@ namespace DS.WMS.Core.TaskPlat.Interface /// 数据上下文(规则匹配时用到的数据来源) /// 指定任务类型对应的任务接收人列表 Task>>> GetAllotUserBySeaExportId(List taskTypeList, long seaExportId, TaskFlowDataContext? dataContext = null); + Task> GetAllotUserList(SqlSugarScopeProvider tenantDb, long taskId); } } diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs index b95282c6..0f1ed072 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Interface/ITaskManageService.cs @@ -47,12 +47,17 @@ namespace DS.WMS.Core.TaskPlat.Interface /// /// 工作流设置任务在个人下的状态 /// - /// 业务主键 - /// 业务类型 + /// 主业务主键 + /// 主业务类型 /// 业务状态 /// 状态发生时间 /// 要设置任务状态的人员列表 - Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, List userInfos); + /// 子业务主键[可选,当不为空时表示设置子任务的个人状态] + /// 子业务类型 + Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, List userInfos, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null); + + /// /// 工作流设置任务状态 /// @@ -60,22 +65,31 @@ namespace DS.WMS.Core.TaskPlat.Interface /// 业务类型 /// 业务状态 /// 状态发生时间 + /// 完成任务前是否检查所有子任务是否完成 /// 任务描述 - /// 用户Id列表,用于筛选指定用户下的任务 - Task SetTaskStatusWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, string? taskDesc = null, List? userIdList = null); + /// 用户Id列表,用于筛选指定用户下的任务[可选,当不为空时会设置此用户列表涉及到的相关任务的状态] + /// 子业务主键[可选,当不为空时表示设置子任务的状态] + /// 子业务类型 + Task SetTaskStatusWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime,bool isCheckAllChildTaskComplete, string? taskDesc = null, List? userIdList = null, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null); /// /// 工作流任务转交 /// /// 业务主键 /// 业务类型 /// 要转交的人员信息列表 - Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos, SqlSugarScopeProvider? tenantDb = null); + /// 子业务主键[可选,当不为空时表示设置子任务的状态] + /// 子业务类型 + Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos, SqlSugarScopeProvider? tenantDb = null, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null); /// /// 工作流设置任务对象属性 /// - Task SetTaskBaseInfoPropertyWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, params Expression>[] columns); + Task SetTaskBaseInfoPropertyWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null, + params Expression>[] columns); /// /// 测试用 @@ -86,5 +100,10 @@ namespace DS.WMS.Core.TaskPlat.Interface /// 领取任务到当前登陆人(可批量) /// Task PullTask(long[] ids); + + /// + /// 任务台台账子任务列表查询 + /// + Task>> GetChildTaskList(long taskId); } } diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskAllocationService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskAllocationService.cs index fc701524..935c8a8d 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskAllocationService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskAllocationService.cs @@ -498,5 +498,21 @@ namespace DS.WMS.Core.TaskPlat.Method return DataResult>>.Success($"查询成功", result, MultiLanguageConst.OperationSuccess); } + + + /// + /// 获取任务接收人列表 + /// + /// + /// + /// + public async Task> GetAllotUserList(SqlSugarScopeProvider tenantDb, long taskId) + { + var allotUserList = await tenantDb.Queryable() + .Where(x => x.TaskId == taskId) + .Select(x => new { x.UserId, x.UserName }) + .ToListAsync(); + return allotUserList.Select(x => (x.UserId, x.UserName)).ToList(); + } } } diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs index c4c8d9d2..3bb1c1d1 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBCService.cs @@ -3101,7 +3101,7 @@ namespace DS.WMS.Core.TaskPlat.Method return DataResult.Failed("未获取到BC任务对象TaskBaseInfo"); } - await SetTaskStatus(taskBaseInfo, TaskStatusEnum.Complete, DateTime.Now); + await SetTaskStatus(taskBaseInfo, TaskStatusEnum.Complete, DateTime.Now, false); if (taskBaseInfo.OUT_BS_NO is null or 0) { diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs index 2922de6c..1d51f8fb 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageBaseService.cs @@ -47,6 +47,10 @@ namespace DS.WMS.Core.TaskPlat.Method protected Lazy seaExportCommonService; protected Lazy djyServiceStatusService; + protected static readonly string createStatusStr = TaskStatusEnum.Create.ToString(); + protected static readonly string pendingStatusStr = TaskStatusEnum.Pending.ToString(); + protected static readonly string completeStatusStr = TaskStatusEnum.Complete.ToString(); + public TaskManageBaseService(IUser user, ILogger logger, ISaasDbService saasDbService, @@ -583,18 +587,19 @@ namespace DS.WMS.Core.TaskPlat.Method .Where(t => t.Id == taskBaseId) .FirstAsync(); - return await SetTaskStatus(taskInfo, taskStatusEnum, statusTime, bsno); + return await SetTaskStatus(taskInfo, taskStatusEnum, statusTime, false, bsno); } /// - /// 通过任务主表对象设置任务状态() + /// 通过任务主表对象设置任务状态(通用) /// /// 任务主表对象 /// 业务状态 /// 状态发生时间 + /// 完成任务前是否检查所有子任务是否完成 /// 业务主键 /// 任务描述 - public async Task SetTaskStatus(TaskBaseInfo taskInfo, TaskStatusEnum taskStatusEnum, DateTime? statusTime, long? bsno = null, string? taskDesc = null) + public async Task SetTaskStatus(TaskBaseInfo taskInfo, TaskStatusEnum taskStatusEnum, DateTime? statusTime, bool isCheckAllChildTaskComplete, long? bsno = null, string? taskDesc = null) { if (taskInfo is null) { @@ -603,9 +608,22 @@ namespace DS.WMS.Core.TaskPlat.Method SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); + if (!taskInfo.IsChild && isCheckAllChildTaskComplete && taskStatusEnum == TaskStatusEnum.Complete) + { + if (await tenantDb.Queryable() + .Where(x => x.IsChild == true && x.ParentTaskId == taskInfo.Id && (x.STATUS == createStatusStr || x.STATUS == pendingStatusStr)) + .AnyAsync()) + { + return DataResult.Failed("任务设置完成前,需要所有子任务非待处理中或挂起中"); + } + } + // 修改任务的状态 - taskInfo.STATUS = taskStatusEnum.ToString(); - taskInfo.STATUS_NAME = taskStatusEnum.EnumDescription(); + string taskStatusStr = taskStatusEnum.ToString(); + string taskStatusNameStr = taskStatusEnum.EnumDescription(); + + taskInfo.STATUS = taskStatusStr; + taskInfo.STATUS_NAME = taskStatusNameStr; taskInfo.RealUserId = long.Parse(user.UserId); taskInfo.RealUserName = user.UserName; @@ -621,8 +639,10 @@ namespace DS.WMS.Core.TaskPlat.Method } - // 任务状态为“完成”且来源为工作流时要做的工作: - if (taskStatusEnum == TaskStatusEnum.Complete && taskInfo.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString()) + // 任务状态为“完成” && 来源为工作流 && 非子任务 时要做的工作: + if (taskStatusEnum == TaskStatusEnum.Complete + && taskInfo.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() + && !taskInfo.IsChild) { long? orderId = bsno; if (orderId == null || orderId == 0) @@ -669,8 +689,20 @@ namespace DS.WMS.Core.TaskPlat.Method try { + var taskBaseAllocationList = await tenantDb.Queryable().Where(x => x.TaskId == taskInfo.Id && x.Status != taskStatusStr).ToListAsync(); + + List waitUpdateChildTaskIdList = []; + if (!taskInfo.IsChild) + { + waitUpdateChildTaskIdList = await tenantDb.Queryable() + .Where(x => x.IsChild == true && x.ParentTaskId == taskInfo.Id && x.STATUS != taskStatusStr) + .Select(x => x.Id) + .ToListAsync(); + } + await tenantDb.Ado.BeginTranAsync(); + // 更新主任务的状态 await tenantDb.Updateable(taskInfo).UpdateColumns(x => new { x.UpdateBy, @@ -687,15 +719,13 @@ namespace DS.WMS.Core.TaskPlat.Method x.TASK_DESP }).ExecuteCommandAsync(); - //var taskBaseAllocationList = await tenantDb.Queryable().Where(x => x.TaskId == taskInfo.Id).ToListAsync(); - // 取出所有状态与目标状态不一致的关系数据,进行更新 - var taskBaseAllocationList = await tenantDb.Queryable().Where(x => x.TaskId == taskInfo.Id && x.Status != taskStatusEnum.ToString()).ToListAsync(); + // 更新主任务的任务接收人下的状态 if (taskBaseAllocationList.Count != 0) { taskBaseAllocationList.ForEach(x => { - x.Status = taskStatusEnum.ToString(); - x.StatusName = taskStatusEnum.EnumDescription(); + x.Status = taskStatusStr; + x.StatusName = taskStatusNameStr; x.StatusTime = statusTime; }); @@ -709,6 +739,41 @@ namespace DS.WMS.Core.TaskPlat.Method x.StatusTime }).ExecuteCommandAsync(); } + + if (!taskInfo.IsChild && waitUpdateChildTaskIdList.Count > 0) + { + // 更新子任务的状态 + await tenantDb.Updateable() + .SetColumns(x => new TaskBaseInfo() + { + UpdateBy = long.Parse(user.UserId), + UpdateTime = DateTime.Now, + UpdateUserName = user.UserName, + IS_COMPLETE = taskInfo.IS_COMPLETE, + COMPLETE_DATE = taskInfo.COMPLETE_DATE, + STATUS = taskInfo.STATUS, + STATUS_NAME = taskInfo.STATUS_NAME, + RealUserId = taskInfo.RealUserId, + RealUserName = taskInfo.RealUserName, + }) + .Where(x => waitUpdateChildTaskIdList.Contains(x.Id) && x.STATUS != taskStatusStr) + .ExecuteCommandAsync(); + + // 更新子任务的任务接收人下的状态 + await tenantDb.Updateable() + .SetColumns(x => new TaskBaseAllocation() + { + UpdateBy = long.Parse(user.UserId), + UpdateTime = DateTime.Now, + UpdateUserName = user.UserName, + Status = taskInfo.STATUS, + StatusName = taskInfo.STATUS_NAME, + StatusTime = statusTime, + }) + .Where(x => waitUpdateChildTaskIdList.Contains(x.TaskId) && x.Status != taskStatusStr) + .ExecuteCommandAsync(); + } + await tenantDb.Ado.CommitTranAsync(); } catch (Exception) diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs index e61d12f1..ba3240be 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs @@ -87,30 +87,57 @@ namespace DS.WMS.Core.TaskPlat.Method /// /// 工作流设置任务在个人下的状态 /// - /// 业务主键 - /// 业务类型 + /// 主业务主键 + /// 主业务类型 /// 业务状态 /// 状态发生时间 /// 要设置任务状态的人员列表 - public async Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, List userInfos) + /// 子业务主键[可选,当不为空时表示设置子任务的个人状态] + /// 子业务类型 + public async Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, List userInfos, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { + logger.LogInformation("接收到任务个人状态修改报文 bsno={bsno} 状态设置={status} 人员列表={userList} childBsno={childBsno} childTaskBaseTypeEnum={childTaskBaseTypeEnum}", bsno, taskStatusEnum.ToString(), JsonConvert.SerializeObject(userInfos), childBsno, childTaskBaseTypeEnum); + SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); - TaskBaseInfo taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + var taskTypeStr = taskBaseTypeEnum.ToString(); + + var taskId = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) .OrderByDescending(a => a.Id) - .FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString()); + .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr) + .Select(t => new { t.Id }) + .FirstAsync(); - if (taskInfo == null) + if (taskId == null) { - logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskBaseTypeEnum}】未查询到任务"); + logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskTypeStr}】未查询到任务"); return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); } - logger.LogInformation("接收到任务个人状态修改报文 任务主键={id} 状态设置={status} 人员列表={userList}", taskInfo.Id, taskStatusEnum.ToString(), JsonConvert.SerializeObject(userInfos)); + long waitSetTaskId = taskId.Id; + + if (childBsno != null) + { + var childTypeStr = childTaskBaseTypeEnum.ToString(); + var childTaskId = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .OrderByDescending(a => a.Id) + .Where(t => t.CHILD_OUT_BS_NO == childBsno && t.TASK_TYPE == childTypeStr && t.ParentTaskId == taskId.Id) + .Select(t => new { t.Id }) + .FirstAsync(); + if (childTaskId == null) + { + logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskBaseTypeEnum:【{childTypeStr}】未查询到任务"); + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + + waitSetTaskId = childTaskId.Id; + } + var userIdList = userInfos.Select(x => x.RecvUserId).ToList(); var taskBaseAllocationList = await tenantDb.Queryable() - .Where(x => x.TaskId == taskInfo.Id && userIdList.Contains(x.UserId)) + .Where(x => x.TaskId == waitSetTaskId && userIdList.Contains(x.UserId)) .ToListAsync(); if (taskBaseAllocationList.Any()) { @@ -142,53 +169,103 @@ namespace DS.WMS.Core.TaskPlat.Method /// 业务类型 /// 业务状态 /// 状态发生时间 + /// 完成任务前是否检查所有子任务是否完成 /// 任务描述 - /// 用户Id列表,用于筛选指定用户下的任务 - public async Task SetTaskStatusWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, string? taskDesc = null, List? userIdList = null) + /// 用户Id列表,用于筛选指定用户下的任务[可选,当不为空时会设置此用户列表涉及到的相关任务的状态] + /// 子业务主键[可选,当不为空时表示设置子任务的状态] + /// 子业务类型 + public async Task SetTaskStatusWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, bool isCheckAllChildTaskComplete, string? taskDesc = null, List? userIdList = null, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); - if (userIdList == null || userIdList.Count() == 0) - { - TaskBaseInfo taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .OrderByDescending(a => a.Id) - .FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString()); - if (taskInfo == null) - { - logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskBaseTypeEnum}】未查询到任务"); - return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); - } - return await SetTaskStatus(taskInfo, taskStatusEnum, statusTime, bsno, taskDesc); - } - else + var taskTypeStr = taskBaseTypeEnum.ToString(); + + // 表示修改子任务的状态 + if (childBsno != null) { - var taskIdList = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .OrderByDescending(a => a.Id) - .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString()) - .Select(x => x.Id) - .ToListAsync(); - if (taskIdList.Count() == 0) + var taskId = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr) + .OrderByDescending(a => a.Id) + .Select(t => new { t.Id }) + .FirstAsync(); + if (taskId == null) { + var log = $"设置子任务状态时未查询到父任务(父任务BSNO:{bsno},父任务TaskBaseTypeEnum:{taskBaseTypeEnum}"; + logger.LogInformation(log); return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); } - var waitSetStatusTaskIdList = await tenantDb.Queryable().Where(x => taskIdList.Contains(x.TaskId) && userIdList.Contains(x.UserId)).Select(x => x.TaskId).Distinct().ToListAsync(); - - var taskInfoList = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)).Where(x => waitSetStatusTaskIdList.Contains(x.Id)).ToListAsync(); + var childTaskTypeStr = childTaskBaseTypeEnum.ToString(); - var resultList = new List(); - foreach (var item in taskInfoList) + var childTask = await tenantDb.Queryable() + .Where(x => x.IsChild == true + && x.TASK_TYPE == childTaskTypeStr + && x.CHILD_OUT_BS_NO == childBsno) + .FirstAsync(); + if (childTask == null) { - var itemResult = await SetTaskStatus(item, taskStatusEnum, statusTime, bsno, taskDesc); - resultList.Add(itemResult.Succeeded); + var log = $"设置子任务状态时未查询到子任务(父任务BSNO:{bsno},父任务TaskBaseTypeEnum:{taskBaseTypeEnum},子任务childBsno:{childBsno},子任务childTaskBaseTypeEnum:{childTaskBaseTypeEnum}"; + logger.LogInformation(log); + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); } - if (resultList.Any(x => !x)) + + return await SetTaskStatus(childTask, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc); + } + // 表示修改主任务的状态 + else + { + // 表示修改主任务的状态 + if (userIdList == null || userIdList.Count() == 0) { - return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + TaskBaseInfo taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .OrderByDescending(t => t.Id) + .FirstAsync(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr); + if (taskInfo == null) + { + logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskBaseTypeEnum}】未查询到任务"); + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + return await SetTaskStatus(taskInfo, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc); } + // 表示修改主任务的状态,但是通过用户列表做进一步筛选 else { - return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess))); + var taskIdList = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .OrderByDescending(t => t.Id) + .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr) + .Select(x => x.Id) + .ToListAsync(); + if (taskIdList.Count() == 0) + { + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + + var waitSetStatusTaskIdList = await tenantDb.Queryable() + .Where(x => taskIdList.Contains(x.TaskId) && userIdList.Contains(x.UserId)) + .Select(x => x.TaskId) + .Distinct() + .ToListAsync(); + + var taskInfoList = await tenantDb.Queryable() + .ClearFilter(typeof(IOrgId)) + .Where(x => waitSetStatusTaskIdList.Contains(x.Id)) + .ToListAsync(); + + var resultList = new List(); + foreach (var item in taskInfoList) + { + var itemResult = await SetTaskStatus(item, taskStatusEnum, statusTime, isCheckAllChildTaskComplete, bsno, taskDesc); + resultList.Add(itemResult.Succeeded); + } + if (resultList.Any(x => !x)) + { + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + else + { + return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess))); + } } } } @@ -199,29 +276,60 @@ namespace DS.WMS.Core.TaskPlat.Method /// 业务主键 /// 业务类型 /// 要转交的人员信息列表 - public async Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos, SqlSugarScopeProvider? tenantDb = null) + /// 子业务主键[可选,当不为空时表示设置子任务的状态] + /// 子业务类型 + public async Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos, SqlSugarScopeProvider? tenantDb = null, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { tenantDb ??= saasDbService.GetBizDbScopeById(user.TenantId); + + logger.LogInformation("接收到任务转交报文 bsno={bsno} taskBaseTypeEnum={taskBaseTypeEnum} 转交人员列表={userinfo} childBsno={childBsno} childTaskBaseTypeEnum={childTaskBaseTypeEnum}", + bsno, + taskBaseTypeEnum, + JsonConvert.SerializeObject(userInfos), + childBsno, + childTaskBaseTypeEnum); + try { + var taskTypeStr = taskBaseTypeEnum.ToString(); + var childTaskTypeStr = childTaskBaseTypeEnum.ToString(); var task = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString()) + .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr) .OrderByDescending(a => a.Id) .Select(t => new { t.Id, t.IS_PUBLIC }) .FirstAsync(); if (task == null) { - logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskBaseTypeEnum}】未查询到任务"); + logger.LogInformation($"根据bsno:【{bsno}】,TaskBaseTypeEnum:【{taskBaseTypeEnum}】未查询到父任务"); return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); } - - logger.LogInformation("接收到任务转交报文 任务主键={id} 转交人员列表={userinfo}", task.Id, JsonConvert.SerializeObject(userInfos)); - - var completedBusinessStatusCode = await tenantDb.Queryable() - .Where(x => x.ModuleType == 2 && x.TaskType == taskBaseTypeEnum.ToString()) + string? completedBusinessStatusCode = ""; + if (childBsno != null) + { + var childTask = await tenantDb.Queryable() + .Where(x => x.IsChild == true + && x.TASK_TYPE == childTaskTypeStr + && x.CHILD_OUT_BS_NO == childBsno) + .Select(t => new { t.Id, t.IS_PUBLIC }) + .FirstAsync(); + + if (childTask == null) + { + logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskTypeStr:【{childTaskTypeStr}】未查询到子任务"); + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + task = childTask; + } + else + { + completedBusinessStatusCode = await tenantDb.Queryable() + .Where(x => x.ModuleType == 2 && x.TaskType == taskTypeStr) .Select(x => x.CompletedBusinessStatusCode) .FirstAsync(); + } + await tenantDb.Ado.BeginTranAsync(); @@ -277,13 +385,19 @@ namespace DS.WMS.Core.TaskPlat.Method /// /// 工作流设置任务对象属性 /// - public async Task SetTaskBaseInfoPropertyWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, params Expression>[] columns) + public async Task SetTaskBaseInfoPropertyWithBsno(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, + long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null, + params Expression>[] columns) { SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); + + var taskTypeStr = taskBaseTypeEnum.ToString(); + var childTaskTypeStr = childTaskBaseTypeEnum.ToString(); + long? taskInfoId = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) .OrderByDescending(a => a.Id) - .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskBaseTypeEnum.ToString()) + .Where(t => t.OUT_BS_NO == bsno && t.TASK_TYPE == taskTypeStr) .Select(t => t.Id) .FirstAsync(); if (taskInfoId == null || taskInfoId == 0) @@ -295,6 +409,24 @@ namespace DS.WMS.Core.TaskPlat.Method { logger.LogInformation($"根据bsno:【{bsno}】,查询出taskInfoId=【{taskInfoId}】"); } + + if (childBsno != null) + { + long? childTaskId = await tenantDb.Queryable() + .Where(x => x.IsChild == true + && x.TASK_TYPE == childTaskTypeStr + && x.CHILD_OUT_BS_NO == childBsno) + .Select(t => t.Id) + .FirstAsync(); + + if (childTaskId == null || childTaskId == 0) + { + logger.LogInformation($"根据childBsno:【{childBsno}】,childTaskTypeStr:【{childTaskTypeStr}】未查询到子任务"); + return DataResult.Failed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataQueryNoData))); + } + taskInfoId = childTaskId; + } + var updateable = tenantDb.Updateable(); foreach (var item in columns) { @@ -311,6 +443,10 @@ namespace DS.WMS.Core.TaskPlat.Method } #endregion + + + + private static object ImportLockObj = new object(); /// /// 创建任务公共方法 @@ -327,6 +463,11 @@ namespace DS.WMS.Core.TaskPlat.Method //Monitor.Enter(ImportLockObj); logger.LogInformation("批次={no} 接收到创建任务报文 报文={msg}", batchNo, JsonConvert.SerializeObject(info)); + if (info.Head.IsChild && info.Head.ChildBSNO == 0) + { + throw new Exception("创建子任务需要指定子任务的业务主键[info.Head.ChildBSNO]"); + } + SqlSugarScopeProvider tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); // 人员信息测试用 @@ -340,70 +481,106 @@ namespace DS.WMS.Core.TaskPlat.Method TaskBaseInfo taskInfo = null; var taskTypeStr = info.Main.TaskType.ToString(); + var childTaskTypeStr = info.Main.ChildTaskType.ToString(); var createStatusStr = TaskStatusEnum.Create.ToString(); var pendingStatusStr = TaskStatusEnum.Pending.ToString(); - // 特殊处理:费用审核、修改、删除(明细)相关的审核,同一单子可以有多条费用审核及特殊费用审核任务,所属人 - if ((info.Main.TaskType - is TaskBaseTypeEnum.FEE_AUDIT - or TaskBaseTypeEnum.FEE_REJECTED - or TaskBaseTypeEnum.FEE_MODIFY_AUDIT - or TaskBaseTypeEnum.FEE_MODIFY_REJECTED - or TaskBaseTypeEnum.FEE_DELETE_AUDIT - or TaskBaseTypeEnum.FEE_DELETE_REJECTED) - && info.Main.RecvUserInfoList?.Count > 0) - { - // 先查此订单在任务台账是否有指定类型的待处理的任务,如果有,查这些任务的归属人里是否已经包含了任务接收人 - var existsTaskList = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .Where(t => t.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() - && t.OUT_BS_NO == info.Head.BSNO - && t.TASK_TYPE == taskTypeStr - && (t.STATUS == createStatusStr || t.STATUS == pendingStatusStr)) - .Select(x => new { x.Id, x.TASK_NO }) - .ToListAsync(); - - if (existsTaskList.Count > 0) + long parentTaskId = 0; + if (info.Head.IsChild) + { + // 根据BSNO查现有任务的主键 + var parentTask = await tenantDb.Queryable() + .Where(x => x.OUT_BS_NO == info.Head.BSNO && x.TASK_TYPE == taskTypeStr && x.IsChild == false) + .OrderByDescending(x => x.Id) + .Select(x => new { x.Id }) + .FirstAsync(); + if (parentTask == null) { - var existsTaskIdList = existsTaskList.Select(x => x.Id); - var recvUser = info.Main.RecvUserInfoList.First(); - var existsRecvUser = await tenantDb.Queryable().Where(x => existsTaskIdList.Contains(x.TaskId) && x.UserId == recvUser.RecvUserId).AnyAsync(); - if (existsRecvUser) - { - string log = $"订单Id:{info.Head.BSNO}业务类型:{taskTypeStr}已有接收人:{recvUser.RecvUserId}/{recvUser.RecvUserName},跳过创建"; - // 回写任务号 - return await Task.FromResult(new DataResult(ResultCode.Success, log, data: existsTaskList.Select(x => x.TASK_NO))); - } + throw new Exception($"创建子任务时根据未查询到父任务(父任务BSNO:{info.Head.BSNO},父任务TaskBaseTypeEnum:{taskTypeStr}"); + } + parentTaskId = parentTask.Id; + + // 判断子任务是否重复 + var existsChildTask = await tenantDb.Queryable() + .Where(x => x.IsChild == true + //&& x.ParentTaskId == parentTask.Id + && x.TASK_TYPE == childTaskTypeStr + && x.CHILD_OUT_BS_NO == info.Head.ChildBSNO + && (x.STATUS == createStatusStr || x.STATUS == pendingStatusStr)) + .Select(x => new { x.Id, x.TASK_NO }) + .FirstAsync(); + if (existsChildTask != null) + { + var allotUserList = await allocationService.Value.GetAllotUserList(tenantDb, existsChildTask.Id); + var allotUserName = allotUserList.Select(x => x.userName); + var log = $"同一业务下已存在同任务类型的指定状态(待处理或挂起中)的子任务,不能重复创建(任务流水号:{existsChildTask.TASK_NO},接收人:{string.Join("、", allotUserName)})"; + throw new Exception(log); } } else { - // 如果业务主键不为空,则通过业务主键进行重复判断 - if (info.Head.BSNO is not (null or 0)) + // 特殊处理:费用审核、修改、删除(明细)相关的审核,同一单子可以有多条费用审核及特殊费用审核任务,所属人 + if ((info.Main.TaskType + is TaskBaseTypeEnum.FEE_AUDIT + or TaskBaseTypeEnum.FEE_REJECTED + or TaskBaseTypeEnum.FEE_MODIFY_AUDIT + or TaskBaseTypeEnum.FEE_MODIFY_REJECTED + or TaskBaseTypeEnum.FEE_DELETE_AUDIT + or TaskBaseTypeEnum.FEE_DELETE_REJECTED) + && info.Main.RecvUserInfoList?.Count > 0) { - taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .Where(t => t.OUT_BS_NO == info.Head.BSNO) - .WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr) - .OrderByDescending(a => a.Id) - .Select(x => new TaskBaseInfo() - { - Id = x.Id, - STATUS = x.STATUS - }) - .FirstAsync(); + // 先查此订单在任务台账是否有指定类型的待处理的任务,如果有,查这些任务的归属人里是否已经包含了任务接收人 + var existsTaskList = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .Where(t => t.TASK_SOURCE == TaskSourceEnum.WORK_FLOW.ToString() + && t.OUT_BS_NO == info.Head.BSNO + && t.TASK_TYPE == taskTypeStr + && (t.STATUS == createStatusStr || t.STATUS == pendingStatusStr)) + .Select(x => new { x.Id, x.TASK_NO }) + .ToListAsync(); + + if (existsTaskList.Count > 0) + { + var existsTaskIdList = existsTaskList.Select(x => x.Id); + var recvUser = info.Main.RecvUserInfoList.First(); + var existsRecvUser = await tenantDb.Queryable().Where(x => existsTaskIdList.Contains(x.TaskId) && x.UserId == recvUser.RecvUserId).AnyAsync(); + if (existsRecvUser) + { + string log = $"订单Id:{info.Head.BSNO}业务类型:{taskTypeStr}已有接收人:{recvUser.RecvUserId}/{recvUser.RecvUserName},跳过创建"; + // 回写任务号 + return await Task.FromResult(new DataResult(ResultCode.Success, log, data: existsTaskList.Select(x => x.TASK_NO))); + } + } } - // 否则通过Head.GID进行判断 else { - taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) - .Where(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}") - .WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr) - .OrderByDescending(a => a.Id) - .Select(x => new TaskBaseInfo() - { - Id = x.Id, - STATUS = x.STATUS - }) - .FirstAsync(); + // 如果业务主键不为空,则通过业务主键进行重复判断 + if (info.Head.BSNO is not (null or 0)) + { + taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .Where(t => t.OUT_BS_NO == info.Head.BSNO) + .WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr) + .OrderByDescending(a => a.Id) + .Select(x => new TaskBaseInfo() + { + Id = x.Id, + STATUS = x.STATUS + }) + .FirstAsync(); + } + // 否则通过Head.GID进行判断 + else + { + taskInfo = await tenantDb.Queryable().ClearFilter(typeof(IOrgId)) + .Where(t => t.OUT_BUSI_NO == $"{info.Head.SenderId}_{info.Head.GID}") + .WhereIF(info.Main.IsCheckExistsByTaskType, t => t.TASK_TYPE == taskTypeStr) + .OrderByDescending(a => a.Id) + .Select(x => new TaskBaseInfo() + { + Id = x.Id, + STATUS = x.STATUS + }) + .FirstAsync(); + } } } @@ -412,8 +589,11 @@ namespace DS.WMS.Core.TaskPlat.Method && taskInfo.STATUS != TaskStatusEnum.Cancel.ToString() && taskInfo.STATUS != TaskStatusEnum.Complete.ToString()) { - logger.LogInformation("批次={no} 状态已存在,不能重复创建任务 status={status}", batchNo, taskInfo.STATUS); - throw new Exception($"状态已存在,不能重复创建任务"); + var allotUserList = await allocationService.Value.GetAllotUserList(tenantDb, taskInfo.Id); + var allotUserName = allotUserList.Select(x => x.userName); + + var log = $"同一业务下已存在同任务类型的指定状态(待处理或挂起中)的任务,不能重复创建(任务流水号:{taskInfo.TASK_NO},接收人:{string.Join("、", allotUserName)})"; + throw new Exception(log); } logger.LogInformation("批次={no} 接收到创建任务报文 结束查询任务 {msg}", batchNo, taskInfo == null ? "不存在" : "存在"); @@ -493,9 +673,12 @@ namespace DS.WMS.Core.TaskPlat.Method CreateTime = DateTime.Now, }; - if (info.Main.ExtData != null) + if (info.Head.IsChild) { - taskInfo.ExtData = info.Main.ExtData.ToJson(); + taskInfo.IsChild = true; + taskInfo.ParentTaskId = parentTaskId; + taskInfo.CHILD_OUT_BS_NO = info.Head.ChildBSNO; + taskInfo.TASK_TYPE = childTaskTypeStr; } if (Enum.TryParse(typeof(TaskBaseTypeEnum), taskInfo.TASK_TYPE, out object? taskTypeTemp)) @@ -503,6 +686,11 @@ namespace DS.WMS.Core.TaskPlat.Method taskInfo.TASK_TYPE_NAME = ((TaskBaseTypeEnum)taskTypeTemp).EnumDescription(); } + if (info.Main.ExtData != null) + { + taskInfo.ExtData = info.Main.ExtData.ToJson(); + } + // 如果船公司主键不为空,则直接保存船公司主键、Code、Name等信息(如果Name为空,查询一下再赋值) if (taskInfo.CARRIER_ID != null) { @@ -601,7 +789,7 @@ namespace DS.WMS.Core.TaskPlat.Method catch (Exception ex) { logger.LogError(ex, "任务创建时,设置订单业务状态的过程中发生异常,orderId={0},taskType={1}", (long)info.Head.BSNO, taskInfo.TASK_TYPE); - throw; + //throw; } try @@ -617,7 +805,7 @@ namespace DS.WMS.Core.TaskPlat.Method catch (Exception ex) { logger.LogError(ex, "任务创建时,设置订单的货物状态时发生异常,orderId={0},taskType={1}", (long)info.Head.BSNO, taskInfo.TASK_TYPE); - throw; + //throw; } } @@ -644,7 +832,7 @@ namespace DS.WMS.Core.TaskPlat.Method Status = TaskStatusEnum.Create.ToString(), StatusName = TaskStatusEnum.Create.EnumDescription(), StatusTime = DateTime.Now, - BusinessId = taskInfo.OUT_BS_NO, + BusinessId = info.Head.IsChild ? taskInfo.CHILD_OUT_BS_NO : taskInfo.OUT_BS_NO, GoodStatusCode = completedBusinessStatusCode, OrgId = userWithOrgMap.FirstOrDefault(m => m.Id == x.RecvUserId)?.DefaultOrgId ?? 0 }; @@ -1900,6 +2088,7 @@ namespace DS.WMS.Core.TaskPlat.Method } + /// /// 任务台台账列表查询 /// @@ -2676,7 +2865,7 @@ namespace DS.WMS.Core.TaskPlat.Method item.RecvUserList = recvUserList; } - // 2.部分字段值覆盖:提单号、ETD、船公司(如果订单的号码不为空则采用订单的号码) + // 2.部分字段值覆盖:提单号、ETD、船公司、委托编号(如果订单的号码不为空则采用订单的号码) if (!string.IsNullOrEmpty(item.orderMBLNO)) { item.MBL_NO = item.orderMBLNO; @@ -2691,6 +2880,10 @@ namespace DS.WMS.Core.TaskPlat.Method item.CARRIER_ID = item.orderCarrierId; item.CARRIER_NAME = null; } + if (!string.IsNullOrEmpty(item.customerNo)) + { + item.customeR_NO = item.customerNo; + } // 3.ExtData字段从Data转为对象 if (!string.IsNullOrEmpty(item.ExtData)) @@ -3327,6 +3520,133 @@ namespace DS.WMS.Core.TaskPlat.Method } + /// + /// 任务台台账子任务列表查询 + /// + public async Task>> GetChildTaskList(long taskId) + { + var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); + tenantDb.QueryFilter.Clear(); + + var userId = long.Parse(user.UserId); + + var queryable = tenantDb.Queryable() + .LeftJoin((t, a) => t.Id == a.TaskId && a.Deleted == false) + .LeftJoin((t, a, s) => t.OUT_BS_NO == s.Id) + .Where(t => t.IsChild == true && t.ParentTaskId == taskId); + + ISugarQueryable queryableTemp = queryable.Select((t, a, s) => new + { + PK_ID = t.Id.SelectAll(), + + orderMBLNO = s.MBLNO, + orderETD = s.ETD, + orderCarrier = s.Carrier, + orderCarrierId = s.CarrierId, + + s.CustomerNo, + s.CustomerNum, + s.BookingNo, + s.HBLNO, + + s.CustomerName, + s.Sale, + s.CustomerServiceName, + s.OperatorName, + + s.LoadPortCode, + s.LoadPort, + s.DischargePortCode, + s.DischargePort, + + s.CntrTotal, + }).Distinct(); + + List data = await queryableTemp.ToListAsync(); + var result = DataResult>.Success(data); + + if (result.Data?.Count > 0) + { + // 查询任务接收人列表 + var taskIdList = result.Data.Select(x => (long)x.Id).ToList(); + + var allRecvUserList = await tenantDb.Queryable() + .Where(x => taskIdList.Contains(x.TaskId)) + .Select(x => new RecvUserInfo() + { + TaskId = x.TaskId, + RecvUserId = x.UserId, + RecvUserName = x.UserName, + RecvUserStatus = x.Status, + RecvUserStatusName = x.StatusName, + RecvUserStatusTime = x.StatusTime + }).ToListAsync(); + + // 一些特殊处理 + foreach (var item in result.Data) + { + // 1.任务接收人赋值 + if (allRecvUserList.Count > 0) + { + var recvUserList = allRecvUserList.Where(x => x.TaskId == item.Id).ToList(); + + var currentUserStatus = recvUserList.FirstOrDefault(x => x.RecvUserId == userId); + if (currentUserStatus != null) + { + var n = recvUserList.IndexOf(currentUserStatus); + if (n != 0) + { + recvUserList.RemoveAt(n); + recvUserList.Insert(0, currentUserStatus); + } + + item.TASK_USER_STATUS = currentUserStatus.RecvUserStatus; + item.TASK_USER_STATUS_NAME = currentUserStatus.RecvUserStatusName; + item.TASK_USER_STATUS_TIME = currentUserStatus.RecvUserStatusTime; + } + + item.RecvUserList = recvUserList; + } + + // 2.部分字段值覆盖:提单号、ETD、船公司、委托编号(如果订单的号码不为空则采用订单的号码) + if (!string.IsNullOrEmpty(item.orderMBLNO)) + { + item.MBL_NO = item.orderMBLNO; + } + if (item.orderETD != null) + { + item.ETD = item.orderETD; + } + if (!string.IsNullOrEmpty(item.orderCarrier)) + { + item.CARRIER_CODE = item.orderCarrier; + item.CARRIER_ID = item.orderCarrierId; + item.CARRIER_NAME = null; + } + if (!string.IsNullOrEmpty(item.CustomerNo)) + { + item.CUSTOMER_NO = item.CustomerNo; + } + + // 3.ExtData字段从Data转为对象 + if (!string.IsNullOrEmpty(item.ExtData)) + { + try + { + item.ExtData = JObject.Parse(item.ExtData); + } + catch + { + item.ExtData = new { ParseError = true, ParseMessage = "ExtData为非标准Json,导致解析异常" }; + } + } + } + } + + return result; + } + + /// /// 完成任务(可批量) /// diff --git a/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs b/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs index 52279a56..dfdfa4f0 100644 --- a/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs +++ b/ds-wms-service/DS.WMS.TaskApi/Controllers/TaskManageController.cs @@ -65,9 +65,9 @@ public class TaskManageController : ApiController /// [HttpPost("SetTaskUserStatus")] [ApiUser(ApiCode = "BCTaskManage"), AllowAnonymous] - public async Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, [FromBody] List userInfos) + public async Task SetTaskUserStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, [FromBody] List userInfos, long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { - var result = await taskManageService.SetTaskUserStatus(bsno, taskBaseTypeEnum, taskStatusEnum, statusTime, userInfos); + var result = await taskManageService.SetTaskUserStatus(bsno, taskBaseTypeEnum, taskStatusEnum, statusTime, userInfos, childBsno, childTaskBaseTypeEnum); return result; } /// @@ -75,9 +75,9 @@ public class TaskManageController : ApiController /// [HttpPost("SetTaskStatus")] [ApiUser(ApiCode = "BCTaskManage"), AllowAnonymous] - public async Task SetTaskStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime) + public async Task SetTaskStatus(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, TaskStatusEnum taskStatusEnum, DateTime? statusTime, long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { - var result = await taskManageService.SetTaskStatusWithBsno(bsno, taskBaseTypeEnum, taskStatusEnum, statusTime); + var result = await taskManageService.SetTaskStatusWithBsno(bsno, taskBaseTypeEnum, taskStatusEnum, statusTime, true, null, null, childBsno, childTaskBaseTypeEnum); return result; } /// @@ -85,9 +85,9 @@ public class TaskManageController : ApiController /// [HttpPost("TransferTask")] [ApiUser(ApiCode = "BCTaskManage"), AllowAnonymous] - public async Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos) + public async Task TransferTask(long bsno, TaskBaseTypeEnum taskBaseTypeEnum, List userInfos, long? childBsno = null, TaskBaseTypeEnum? childTaskBaseTypeEnum = null) { - var result = await taskManageService.TransferTask(bsno, taskBaseTypeEnum, userInfos); + var result = await taskManageService.TransferTask(bsno, taskBaseTypeEnum, userInfos, null, childBsno, childTaskBaseTypeEnum); return result; } @@ -113,6 +113,17 @@ public class TaskManageController : ApiController return result; } + + /// + /// 任务台台账子任务列表查询 + /// + [HttpGet("GetChildTaskList")] + public async Task>> GetChildTaskList(long taskId) + { + var result = await taskManageService.GetChildTaskList(taskId); + return result; + } + /// /// 完成任务(可批量) /// diff --git a/ds-wms-service/DS.WMS.Test/SaasTest.cs b/ds-wms-service/DS.WMS.Test/SaasTest.cs index 77664245..933fd276 100644 --- a/ds-wms-service/DS.WMS.Test/SaasTest.cs +++ b/ds-wms-service/DS.WMS.Test/SaasTest.cs @@ -242,14 +242,14 @@ public class SaasTest [Fact] public void InitTableTestZXF() { - var tenantDb = saasService.GetBizDbScopeById("1750335377144680448"); + var tenantDb = saasService.GetBizDbScopeById("1819549542425694208"); StaticConfig.CodeFirst_MySqlCollate = "utf8mb4_0900_ai_ci";//较高版本支持 //var ass = Assembly.Load("DS.WMS.Core"); //var types = ass.GetTypes().Where(it => it.FullName?.Contains("DS.WMS.Core.TaskPlat.Entity") == true).ToArray(); //tenantDb.CodeFirst.InitTables(types); - tenantDb.CodeFirst.InitTables(typeof(TaskBCInfo)); + tenantDb.CodeFirst.InitTables(typeof(TaskBaseInfo)); //tenantDb.CodeFirst.InitTables(typeof(TaskFlowLogDetail)); Assert.True(true); }