From 8d36b4b65d8d40d61b6c3d939ed63bb9a33ebca3 Mon Sep 17 00:00:00 2001 From: jianghaiqing Date: Tue, 19 Nov 2024 16:47:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=8D=E5=8A=A1=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9A=84=E6=B5=81=E7=A8=8B=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Constants/MultiLanguageConst.cs | 37 ++ .../IServiceWorkFlowBaseService.cs | 4 +- .../ServiceWorkFlowBaseService.cs | 445 +++++++++++++++++- 3 files changed, 474 insertions(+), 12 deletions(-) diff --git a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs index 9e3350a2..5421d368 100644 --- a/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs +++ b/ds-wms-service/DS.Module.Core/Constants/MultiLanguageConst.cs @@ -1953,6 +1953,43 @@ public static class MultiLanguageConst /// [Description("服务流程未修改,不需要重复发布")] public const string ServiceWorkFlowBasePublishFailNoChange = "ServiceWorkFlowBase_PublishFailNoChange"; + + /// + /// 状态信息不能为空 + /// + [Description("状态信息不能为空")] + public const string ServiceWorkFlowBaseStatusNotNull = "ServiceWorkFlowBase_StatusNotNull"; + + /// + /// 状态显示名称不能为空,并且不能少于2个字符 + /// + [Description("状态显示名称不能为空,并且不能少于2个字符")] + public const string ServiceWorkFlowBaseActNameLessTwoChar = "ServiceWorkFlowBase_ActNameLessTwoChar"; + + /// + /// 已存在相同的状态设置,不能保存 + /// + [Description("已存在相同的状态设置,不能保存")] + public const string ServiceWorkFlowBaseActStatusSame = "ServiceWorkFlowBase_ActStatusSame"; + + /// + /// 当前状态已关联发布流程,不能保存 + /// + [Description("当前状态已关联发布流程,不能保存")] + public const string ServiceWorkFlowBaseActStatusExists = "ServiceWorkFlowBase_ActStatusExists"; + + /// + /// 未检索到有效服务流程 + /// + [Description("未检索到有效服务流程")] + public const string ServiceWorkFlowBaseNotAvailableWFlow = "ServiceWorkFlowBase_NotAvailableWFlow"; + + /// + /// 租户ID不能为空 + /// + [Description("租户ID不能为空")] + public const string ServiceWorkFlowBaseTenantIdNotNull = "ServiceWorkFlowBase_TenantIdNotNull"; + #endregion } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Op/Interface/ServiceProject/IServiceWorkFlowBaseService.cs b/ds-wms-service/DS.WMS.Core/Op/Interface/ServiceProject/IServiceWorkFlowBaseService.cs index 7f7a2f63..27af027e 100644 --- a/ds-wms-service/DS.WMS.Core/Op/Interface/ServiceProject/IServiceWorkFlowBaseService.cs +++ b/ds-wms-service/DS.WMS.Core/Op/Interface/ServiceProject/IServiceWorkFlowBaseService.cs @@ -99,7 +99,7 @@ namespace DS.WMS.Core.Op.Interface /// /// 服务活动主键数组 /// 返回回执 - Task>> GetServiceWorkFlowListByActivities(string[] activitiesArgs); + Task>> GetServiceWorkFlowListByActivities(string[] activitiesArgs); /// /// 检索服务流程活动列表 @@ -107,7 +107,7 @@ namespace DS.WMS.Core.Op.Interface /// 检索值 /// 最大返回行数(默认15) /// 返回回执 - Task>> QueryActivitiesList(string queryItem, int topNum = 15); + Task>> QueryActivitiesList(string queryItem, int topNum = 15); /// /// 检索可用的服务项目列表 diff --git a/ds-wms-service/DS.WMS.Core/Op/Method/ServiceProject/ServiceWorkFlowBaseService.cs b/ds-wms-service/DS.WMS.Core/Op/Method/ServiceProject/ServiceWorkFlowBaseService.cs index 3e6ca35e..ee325f07 100644 --- a/ds-wms-service/DS.WMS.Core/Op/Method/ServiceProject/ServiceWorkFlowBaseService.cs +++ b/ds-wms-service/DS.WMS.Core/Op/Method/ServiceProject/ServiceWorkFlowBaseService.cs @@ -29,6 +29,7 @@ using Masuit.Tools.Systems; using Amazon.Runtime.Internal.Util; using DS.Module.RedisModule; using Fasterflect; +using AngleSharp.Dom; namespace DS.WMS.Core.Op.Method @@ -1617,7 +1618,84 @@ namespace DS.WMS.Core.Op.Method /// 返回回执 public async Task> GetShowTimeLine(string id) { - return null; + var showModel = new ServiceWorkFlowRunDto(); + + /* + 根据已保存的服务流程生成测试数据 + */ + var model = InnerGetShowInfo(id); + + if (model != null) + { + showModel.PKId = id; + + if (model.ServiceProject != null) + { + showModel.ServiceProjectName = model.ServiceProject.ServiceProjectName; + showModel.ServiceProjectCode = model.ServiceProject.ServiceProjectCode; + } + + if (model.StatusSkuList != null && model.StatusSkuList.Count > 0) + { + int endSortNo = model.StatusSkuList.Max(a => a.SortNo); + + DateTime startDate = DateTime.Now.AddDays(-(endSortNo + 1)); + + showModel.ActivitiesList = model.StatusSkuList.Select(a => { + + var runModel = new ServiceWorkFlowActivitiesRunDto + { + PKId = Guid.NewGuid().ToString(), + ActDate = startDate.AddDays(a.SortNo), + ActId = a.PKId, + ExecSortNo = a.SortNo, + ActVal = string.Empty, + IsStart = (a.SortNo == 1) ? 1 : 0, + IsEnd = (a.SortNo == endSortNo) ? 1 : 0, + IsYield = 1, + RunId = Guid.NewGuid().ToString(), + ShowName = a.ShowName, + SourceType = "AUTO", + StatusSKUCode = a.statusSkuBase.StatusSKUCode, + StatusSKUId = a.StatusSKUId + }; + + if (a.IsContainsSub == 1) + { + int endSubSortNo = a.SubList.Max(a => a.SortNo); + + DateTime startSubDate = DateTime.Now.AddDays(-(endSubSortNo + 1)); + + runModel.SubList = a.SubList.Select(b => { + var subModel = new ServiceWorkFlowActivitiesRunSubDto + { + PKId = Guid.NewGuid().ToString(), + ActDate = startSubDate.AddDays(b.SortNo), + ActId = b.PKId, + ExecSortNo = b.SortNo, + ActVal = string.Empty, + IsStart = (b.SortNo == 1) ? 1 : 0, + IsEnd = (b.SortNo == endSortNo) ? 1 : 0, + IsYield = 1, + RunId = Guid.NewGuid().ToString(), + ShowName = b.ShowName, + SourceType = "AUTO", + StatusSKUCode = b.statusSkuBase.StatusSKUCode, + StatusSKUId = b.StatusSKUId + }; + + return subModel; + }).ToList(); + } + + return runModel; + + }).ToList(); + } + } + + + return DataResult.Success(showModel); } #endregion @@ -1629,7 +1707,88 @@ namespace DS.WMS.Core.Op.Method /// 返回回执 public async Task> SaveWFActivities(ServiceWorkFlowActivitiesDto info) { - return null; + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + try + { + /* + 1、状态有记录。 + 2、同一状态不能有相同的显示名称 + 3、已经关联服务流程的,并且已经发布的不能修改内容。(只可以新增) + */ + var entity = info.Adapt(); + + if (string.IsNullOrWhiteSpace(entity.STATUS_SKU_ID)) + { + //状态信息不能为空 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseStatusNotNull))); + } + + if (string.IsNullOrWhiteSpace(entity.SHOW_NAME) || entity.SHOW_NAME.Length < 2) + { + //状态显示名称不能为空,并且不能少于2个字符 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseActNameLessTwoChar))); + } + + //同一状态不能有相同的显示名称 + var checkList = tenantDb.Queryable() + .Where(a => a.STATUS_SKU_ID == entity.STATUS_SKU_ID + && a.SHOW_NAME == entity.SHOW_NAME && a.PK_ID != entity.PK_ID).ToList(); + + if (checkList.Count > 0) + { + //已存在相同的状态设置,不能保存 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseActStatusSame))); + } + + //_logger.LogInformation($"服务项目保存 JSON={JSON.Serialize(entity)} user={UserManager.UserId}"); + + if (string.IsNullOrWhiteSpace(entity.PK_ID)) + { + entity.PK_ID = SnowFlakeSingle.Instance.NextId().ToString(); + + tenantDb.Insertable(entity).ExecuteCommand(); + } + else + { + //已经关联服务流程的,并且已经发布的不能修改内容。(只可以新增) + var wfRelation = tenantDb.Queryable() + .Where(a => a.SERVICE_ACTIVITIES_ID == entity.PK_ID) + .ToList(); + + if (wfRelation.Count > 0) + { + var currArg = wfRelation.Select(a => a.SERVICE_WORKFLOW_ID).Distinct().ToList(); + + if (tenantDb.Queryable().Any(a => currArg.Any(b => b == a.PK_ID) + && (!string.IsNullOrWhiteSpace(a.RELEASE_VERSION) || a.IS_LOCK == 1))) + { + //当前状态已关联发布流程,不能保存 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseActStatusExists))); + } + } + + entity.UpdateTime = DateTime.Now; + entity.UpdateBy = long.Parse(user.UserId); + entity.UpdateUserName = user.UserName; + + await tenantDb.Updateable(entity).IgnoreColumns(it => new + { + it.CreateTime, + it.CreateBy, + it.CreateUserName, + it.Deleted, + }).ExecuteCommandAsync(); + } + + return DataResult.Success(entity.PK_ID); + } + catch (Exception ex) + { + Logger.Log(NLog.LogLevel.Info, $"保存服务流程活动异常,原因:{ex.Message}"); + + return DataResult.Failed($"保存服务流程活动异常,原因:{ex.Message}"); + } } #endregion @@ -1639,22 +1798,190 @@ namespace DS.WMS.Core.Op.Method /// /// 服务活动主键数组 /// 返回回执 - public async Task>> GetServiceWorkFlowListByActivities(string[] activitiesArgs) + public async Task>> GetServiceWorkFlowListByActivities(string[] activitiesArgs) { - return null; + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + try + { + /* + 1、通过服务活动ID获取所有关联的服务流程详情列表 + 2、轮询服务流程列表,组织详细的服务流程列表 + */ + var activitiesList = tenantDb.Queryable().Filter(null, true) + .LeftJoin((rela, wf) => rela.SERVICE_WORKFLOW_ID == wf.PK_ID + && rela.WF_VERSION == wf.RELEASE_VERSION) + .Where((rela, wf) => activitiesArgs.Contains(rela.SERVICE_ACTIVITIES_ID) + && !wf.Deleted == false && wf.IS_ENABLE == 1) + .Select((rela, wf) => wf).Distinct().ToList(); + + var subActList = tenantDb.Queryable().Filter(null, true) + .LeftJoin((rela, wf) => rela.SERVICE_WORKFLOW_ID == wf.PK_ID + && rela.WF_VERSION == wf.RELEASE_VERSION) + .Where((rela, wf) => activitiesArgs.Contains(rela.SUB_SERVICE_ACTIVITIES_ID) + && !wf.Deleted == false && wf.IS_ENABLE == 1) + .Select((rela, wf) => wf).Distinct().ToList(); + + if (subActList.Count > 0) + { + activitiesList.AddRange(subActList); + //去重 + activitiesList = activitiesList.Distinct().ToList(); + } + + if (activitiesList.Count == 0) + { + Logger.Log(NLog.LogLevel.Info, $"{JsonConvert.SerializeObject(activitiesArgs)} 未检索到有效服务流程"); + //未检索到有效服务流程 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseNotAvailableWFlow))); + } + + var wfArg = activitiesList.Select(a => a.PK_ID).ToArray(); + + var mergeList = + tenantDb.Queryable().Filter(null, true) + .LeftJoin((wf, rela) => wf.PK_ID == rela.SERVICE_WORKFLOW_ID + && wf.RELEASE_VERSION == rela.WF_VERSION) + .LeftJoin((wf, rela, act) => + rela.SERVICE_ACTIVITIES_ID == act.PK_ID && wf.RELEASE_VERSION == rela.WF_VERSION) + .LeftJoin((wf, rela, act, sku) => + act.STATUS_SKU_ID == sku.PK_ID) + .Where((wf) => wfArg.Contains(wf.PK_ID)) + .Select((wf, rela, act, sku) => + new { WF = wf, Act = act, Sku = sku, SortNo = rela.SORT_NO, IsSub = rela.IS_CONTAINS_SUB, ValType = rela.VAL_TYPE }) + .ToList(); + + + var mergeSubList = + tenantDb.Queryable().Filter(null, true) + .LeftJoin((wf, rela) => wf.PK_ID == rela.SERVICE_WORKFLOW_ID + && wf.RELEASE_VERSION == rela.WF_VERSION) + .LeftJoin((wf, rela, act) => + rela.SUB_SERVICE_ACTIVITIES_ID == act.PK_ID && wf.RELEASE_VERSION == rela.WF_VERSION) + .LeftJoin((wf, rela, act, sku) => + act.STATUS_SKU_ID == sku.PK_ID) + .Where((wf) => wfArg.Contains(wf.PK_ID)) + .Select((wf, rela, act, sku) => + new { WF = wf, Act = act, Sku = sku, SortNo = rela.SORT_NO, ParentId = rela.SERVICE_ACTIVITIES_ID, ValType = rela.VAL_TYPE }) + .ToList(); + + + var prjectList = + tenantDb.Queryable().Filter(null, true) + .LeftJoin((wf, rela) => wf.PK_ID == rela.SERVICE_WORKFLOW_ID + && wf.RELEASE_VERSION == rela.WF_VERSION) + .LeftJoin((wf, rela, prj) => + rela.SERVICE_PROJECT_ID == prj.PK_ID) + .Where((wf) => wfArg.Contains(wf.PK_ID)) + .Select((wf, rela, prj) => new { WF = wf, Rela = rela, Prj = prj }).ToList(); + + + var list = mergeList.GroupBy(a => a.WF.PK_ID) + .Select(a => + { + var model = a.FirstOrDefault().WF; + + var showModel = model.Adapt(); + + showModel.StatusSkuList = a.ToList().OrderBy(a => a.SortNo) + .Select(a => + { + var actModel = a.Act.Adapt(); + + actModel.SortNo = a.SortNo; + actModel.IsContainsSub = a.IsSub; + actModel.ValType = a.ValType; + actModel.statusSkuBase = a.Sku.Adapt(); + + if (a.IsSub == 1) + { + actModel.SubList = mergeSubList.Where( + b => + b.WF.PK_ID == a.WF.PK_ID && b.ParentId == a.Act.PK_ID) + .OrderBy(b => b.SortNo) + .Select(b => + { + + var actModel = b.Act.Adapt(); + + actModel.SortNo = b.SortNo; + actModel.statusSkuBase = b.Sku.Adapt(); + + return actModel; + }).ToList(); + } + + return actModel; + }).ToList(); + + return showModel; + }).ToList(); + + list = list.GroupJoin(prjectList, l => l.PKId, + r => r.WF.PK_ID, + (l, r) => + { + var currList = r.ToList(); + + l.ServiceProject = currList.FirstOrDefault().Prj.Adapt(); + + return l; + }).ToList(); + + + return DataResult>.Success(list); + } + catch (Exception ex) + { + Logger.Log(NLog.LogLevel.Info, $"获取所有相关服务流程列表异常,原因:{ex.Message}"); + + return DataResult>.Failed($"获取所有相关服务流程列表异常,原因:{ex.Message}"); + } } #endregion + #region 检索服务流程活动列表 /// /// 检索服务流程活动列表 /// /// 检索值 /// 最大返回行数(默认15) /// 返回回执 - public async Task>> QueryActivitiesList(string queryItem, int topNum = 15) + public async Task>> QueryActivitiesList(string queryItem, int topNum = 15) { - return null; + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + try + { + + var list = await tenantDb.Queryable() + .LeftJoin((act, sku) => act.STATUS_SKU_ID == sku.PK_ID) + .Where((act, sku) => act.Deleted == false && (string.IsNullOrWhiteSpace(queryItem) || act.SHOW_NAME.Contains(queryItem))) + .Take(topNum).Select((act, sku) => new { Act = act, SKU = sku }).ToListAsync(); + + List resultList = new List(); + + if (list.Count > 0) + { + resultList = list.Select(a => { + var info = a.Act.Adapt(); + + info.statusSkuBase = a.SKU.Adapt(); + + return info; + }).ToList(); + } + + return DataResult>.Success(resultList); + + } + catch (Exception ex) + { + Logger.Log(NLog.LogLevel.Info, $"检索服务流程活动列表异常,原因:{ex.Message}"); + + return DataResult>.Failed($"检索服务流程活动列表异常,原因:{ex.Message}"); + } } + #endregion /// /// 检索可用的服务项目列表 @@ -1664,9 +1991,27 @@ namespace DS.WMS.Core.Op.Method /// 返回回执 public async Task>> GetEnableProjectList(string tenantId, bool isAvoidCache = false) { - return null; + List projectList = _redisService.GetEntity>($"{CONST_CACHE_ENABLE_PROJECT}_{tenantId}"); + + if (isAvoidCache || projectList == null || projectList.Count == 0) + { + var statusList = ReloadServiceProjectCacheInfo(tenantId); + + projectList = statusList.Select(a => new ServiceProjectBaseDto + { + PKId = a.ProjectPKId, + ServiceProjectCode = a.ProjectCode, + ServiceProjectName = a.ProjectName, + SortNo = a.SortNo + }).OrderBy(a => a.SortNo).ToList(); + + _redisService.SetValue($"{CONST_CACHE_ENABLE_PROJECT}_{tenantId}", JsonConvert.SerializeObject(projectList), TimeSpan.FromHours(8).Seconds); + } + + return DataResult>.Success(projectList); } + #region 检索可用的服务项目和状态列表 /// /// 检索可用的服务项目和状态列表 /// @@ -1675,9 +2020,26 @@ namespace DS.WMS.Core.Op.Method /// 返回回执 public async Task>> GetEnableProjectWithStatusList(string tenantId, bool isAvoidCache = false) { - return null; + if (string.IsNullOrWhiteSpace(tenantId)) + { + //租户ID不能为空 + throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.ServiceWorkFlowBaseTenantIdNotNull))); + } + + List statusList = _redisService.GetEntity>($"{CONST_CACHE_ENABLE_PROJECT_STATUS}_{tenantId}"); + + if (isAvoidCache || statusList == null || statusList.Count == 0) + { + statusList = ReloadServiceProjectCacheInfo(tenantId); + + _redisService.SetValue($"{CONST_CACHE_ENABLE_PROJECT_STATUS}_{tenantId}", JsonConvert.SerializeObject(statusList), TimeSpan.FromHours(8).Seconds); + } + + return DataResult>.Success(statusList); } + #endregion + #region 获取可用的服务项目字典列表 /// /// 获取可用的服务项目字典列表 /// @@ -1685,9 +2047,32 @@ namespace DS.WMS.Core.Op.Method /// public async Task>> GetEnableProjectDictTreeList(bool isAvoidCache = false) { - return null; + List resultList = new List(); + + var listRlt = await GetEnableProjectList(user.TenantId, isAvoidCache); + + if (listRlt.Succeeded && listRlt.Data.Count > 0) + { + var list = listRlt.Data; + + resultList.Add(new DictTreeOutput + { + Code = "booking_service_item", + Name = "订舱服务项目", + Children = list.OrderBy(a => a.SortNo).Select(a => new DictTreeOutput + { + Code = a.ServiceProjectCode, + Name = a.ServiceProjectName + }).ToList() + }); + + } + + return DataResult>.Success(resultList); } + #endregion + #region 获取可用的服务状态字典列表 /// /// 获取可用的服务状态字典列表 /// @@ -1695,7 +2080,47 @@ namespace DS.WMS.Core.Op.Method /// public async Task>> GetEnableStatusDictTreeList(bool isAvoidCache = false) { - return null; + List resultList = new List(); + + var listRlt = await GetEnableProjectWithStatusList(user.TenantId, isAvoidCache); + + if (listRlt.Succeeded && listRlt.Data.Count > 0) + { + var list = listRlt.Data; + resultList.Add(new DictTreeOutput + { + Code = "booking_goods_status", + Name = "订舱货物状态", + Children = list.OrderBy(a => a.SortNo).SelectMany(a => { + var rltList = new List(); + a.StatusList.ForEach(b => + { + rltList.Add(new DictTreeOutput + { + Code = b.StatusSKUCode, + Name = b.StatusSKUName, + Remark = b.BackgroundColor + }); + + if (b.SubStatusList != null && b.SubStatusList.Count > 0) + { + rltList.AddRange(b.SubStatusList.Select(c => new DictTreeOutput + { + Code = c.StatusSKUCode, + Name = c.StatusSKUName, + Remark = c.BackgroundColor + }).ToList()); + } + }); + + return rltList; + }).ToList() + }); + + } + + return DataResult>.Success(resultList); } + #endregion } }