using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.DynamicApiController; using Furion.FriendlyException; using Furion.JsonSerialization; using Google.Protobuf.Collections; using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Myshipping.Application.Entity; using Myshipping.Core; using Myshipping.Core.Entity; using NPOI.OpenXmlFormats.Vml; using NPOI.SS.Formula.Functions; using NPOI.SS.Formula.PTG; using Org.BouncyCastle.Asn1.Tsp; using Org.BouncyCastle.Ocsp; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace Myshipping.Application { /// /// 服务流程管理 /// [AllowAnonymous, ApiDescriptionSettings("Application", Name = "ServiceWorkFlowManage", Order = 20)] public class ServiceWorkFlowManageService : IServiceWorkFlowManageService, IDynamicApiController, ITransient { private readonly ILogger _logger; private readonly SqlSugarRepository _serviceWorkFlowBaseRepository; private readonly SqlSugarRepository _serviceWorkFlowActivitiesInfoRepository; private readonly SqlSugarRepository _serviceWorkFlowProjectRelationRepository; private readonly SqlSugarRepository _serviceWorkFlowActivitiesRelationRepository; private readonly SqlSugarRepository _serviceWorkFlowActivitiesSubRelationRepository; private readonly SqlSugarRepository _serviceWorkFlowReleaseInfoRepository; private readonly SqlSugarRepository _serviceWorkFlowRunInfoRepository; private readonly SqlSugarRepository _serviceWorkFlowRunActivitiesInfoRepository; private readonly SqlSugarRepository _statusSkuBaseInfoRepository; private readonly SqlSugarRepository _sysUserRepository; private readonly SqlSugarRepository _serviceProjectBaseInfoRepository; private readonly SqlSugarRepository _serviceWorkFlowRunLogInfoRepository; private readonly ICache _cache; private readonly CacheOptions _cacheOptions; private readonly IServiceWorkFlowBaseService _serviceWorkFlowBaseService; const string CONST_CACHE_ENABLE_PROJECT = "service_project_list_enable"; const string CONST_CACHE_ENABLE_PROJECT_STATUS = "service_project_status_list_enable"; const string CONST_CACHE_ENABLE_STATUS = "service_status_list_enable"; public ServiceWorkFlowManageService(SqlSugarRepository serviceWorkFlowBaseRepository, ILogger logger, SqlSugarRepository serviceWorkFlowActivitiesInfoRepository, SqlSugarRepository serviceWorkFlowProjectRelationRepository, SqlSugarRepository serviceWorkFlowActivitiesRelationRepository, SqlSugarRepository serviceWorkFlowActivitiesSubRelationRepository, SqlSugarRepository serviceWorkFlowReleaseInfoRepository, SqlSugarRepository serviceWorkFlowRunInfoRepository, SqlSugarRepository serviceWorkFlowRunActivitiesInfoRepository, SqlSugarRepository statusSkuBaseInfoRepository, IServiceWorkFlowBaseService serviceWorkFlowBaseService, SqlSugarRepository sysUserRepository, SqlSugarRepository serviceProjectBaseInfoRepository, SqlSugarRepository serviceWorkFlowRunLogInfoRepository, IOptions cacheOptions, Func resolveNamed) { _serviceWorkFlowBaseRepository = serviceWorkFlowBaseRepository; _serviceWorkFlowActivitiesInfoRepository = serviceWorkFlowActivitiesInfoRepository; _serviceWorkFlowProjectRelationRepository = serviceWorkFlowProjectRelationRepository; _serviceWorkFlowActivitiesRelationRepository = serviceWorkFlowActivitiesRelationRepository; _logger = logger; _serviceWorkFlowActivitiesSubRelationRepository = serviceWorkFlowActivitiesSubRelationRepository; _serviceWorkFlowReleaseInfoRepository = serviceWorkFlowReleaseInfoRepository; _serviceWorkFlowRunInfoRepository = serviceWorkFlowRunInfoRepository; _serviceWorkFlowRunActivitiesInfoRepository = serviceWorkFlowRunActivitiesInfoRepository; _statusSkuBaseInfoRepository = statusSkuBaseInfoRepository; _serviceWorkFlowBaseService = serviceWorkFlowBaseService; _sysUserRepository = sysUserRepository; _serviceProjectBaseInfoRepository = serviceProjectBaseInfoRepository; _serviceWorkFlowRunLogInfoRepository = serviceWorkFlowRunLogInfoRepository; _cacheOptions = cacheOptions.Value; _cache = resolveNamed(_cacheOptions.CacheType.ToString(), default) as ICache; } #region 推送状态 /// /// 推送状态 /// /// 服务流程详情 /// 返回回执 [HttpPost("/ServiceWorkFlowManage/PushStatus")] public async Task PushStatus([FromBody] TrackingMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 接收推送状态 msg={msg}", batchNo, JSON.Serialize(info)); try { /* 1、首先判断业务的主键,如果存在则需要提取所有主键下的服务流程活动,来更新。 2、状态可以批量处理。 */ if (info.Main == null) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main不能为空", batchNo); throw Oops.Oh($"报文Main不能为空", typeof(InvalidOperationException)); } if (string.IsNullOrWhiteSpace(info.Main.BusiSystemCode)) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main的业务系统代码不能为空", batchNo); throw Oops.Oh($"报文Main的业务系统代码不能为空", typeof(InvalidOperationException)); } if (string.IsNullOrWhiteSpace(info.Main.BusiId)) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main的业务主键不能为空", batchNo); throw Oops.Oh($"报文Main的业务主键不能为空", typeof(InvalidOperationException)); } var statusList = _serviceWorkFlowBaseService.GetEnableProjectWithStatusList(info.Main.OperTenantId.ToString()).GetAwaiter().GetResult(); var projectList = _cache.Get>($"{CONST_CACHE_ENABLE_PROJECT}_{info.Main.OperTenantId}"); DateTime nowDate = DateTime.Now; if (info.Main.PushType == TrackingPushTypeEnum.Project) { if (info.Main.ProjectList == null || info.Main.ProjectList.Count == 0) { _logger.LogInformation("批次={no} 推送类型是【服务项目】,服务项目列表不能为空", batchNo); throw Oops.Oh($"推送类型是【服务项目】,服务项目列表不能为空", typeof(InvalidOperationException)); } //提取所有已经有run记录的 var runBaseList = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .Where(a => a.BUSI_ID == info.Main.BusiId && a.BUSI_SYSTEM_CODE.Equals(info.Main.BusiSystemCode) && !a.IsDeleted && a.TenantId == info.Main.OperTenantId).ToList(); var needProjectArg = info.Main.ProjectList.Select(a => a.ServiceProjectCode).ToArray(); var needProjectList = statusList.Where(a => needProjectArg.Contains(a.ProjectCode)).ToList(); var tskList = needProjectList.GroupJoin(runBaseList, l => l.WFPKId, r => r.SERVICE_WF_ID, (l, r) => { var currList = r.ToList(); if (currList.Count == 0) { //标识当前服务项目写入运行主表 return new { OperType = "Insert", Info = l, Run = new ServiceWorkFlowRunInfo() }; } return new { OperType = "Update", Info = l, Run = currList.FirstOrDefault() }; }).ToList(); tskList.ForEach(async tsk => { if (tsk.OperType == "Insert") { ServiceWorkFlowRunInfo serviceWorkFlowRunInfo = new ServiceWorkFlowRunInfo { PK_ID = IDGen.NextID().ToString(), SERVICE_WF_ID = tsk.Info.WFPKId, BUSI_SYSTEM_CODE = info.Main.BusiSystemCode.ToUpper(), BUSI_ID = info.Main.BusiId.ToUpper(), MBL_NO = info.Main?.MBlNo.ToUpper(), VESSEL_VOYNO = info.Main?.VesselVoyno.ToUpper(), ORDER_NO = info.Main?.OrderNo, STATUS = TaskStatusEnum.Create.ToString(), RELEASE_VERSION = tsk.Info.ReleaseVersion, ACTIVITIES_NUM = 0, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, SERVICE_PROJECT_CODE = tsk.Info.ProjectCode, SERVICE_PROJECT_NAME = tsk.Info.ProjectName, SERVICE_PROJECT_ID = tsk.Info.ProjectPKId, IS_YIELD = 1, ACT_DATE = nowDate, }; await _serviceWorkFlowRunInfoRepository.InsertAsync(serviceWorkFlowRunInfo); } else if (tsk.OperType == "Update") { var runInfo = _serviceWorkFlowRunInfoRepository.AsQueryable() .First(a => a.PK_ID == tsk.Run.PK_ID); runInfo.IS_YIELD = 1; runInfo.ACT_DATE = nowDate; await _serviceWorkFlowRunInfoRepository.AsUpdateable(runInfo).UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, }).ExecuteCommandAsync(); } }); result.succ = true; result.msg = "推送成功"; return result; } //校验状态代码是否一致,不一致直接返回错误不允许推送 var statusArg = info.Main.StatusList.Select(a => a?.StatusCode.ToUpper()) .Where(a => !string.IsNullOrWhiteSpace(a)).Distinct().ToArray(); if (statusArg.Length == 0) { _logger.LogInformation("批次={no} 服务状态列表不能为空", batchNo); throw Oops.Oh($"服务状态列表不能为空", typeof(InvalidOperationException)); } /* 1、从缓存拉取服务项目和状态详情。 2、检索所有相关状态的服务项目。 3、拉取run表相关的订单记录。 4、如果当前订单没有记录,需要按照服务项目和状态生成run表记录。 5、标记相关状态为完成,并更新时间。 */ statusList = statusList.Where(a => a.StatusList.Any(b => { if (statusArg.Contains(b.StatusSKUCode)) return true; if (b.SubStatusList != null && b.SubStatusList.Any(c => statusArg.Contains(c.StatusSKUCode))) return true; return false; })).ToList(); if (statusList.Count == 0) throw Oops.Oh($"未检索到可用服务项目和状态列表", typeof(InvalidOperationException)); var wfArgs = statusList.Select(a => a.WFPKId).ToArray(); //获取订单下所有Run表记录 var runHisList = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .LeftJoin((main, detail) => main.PK_ID == detail.RUN_ID) .Where((main, detail) => main.BUSI_SYSTEM_CODE == info.Main.BusiSystemCode && main.BUSI_ID == info.Main.BusiId && wfArgs.Contains(main.SERVICE_WF_ID)) .Select((main, detail) => new { Main = main, Detail = detail }).ToList(); /* 1、判断run表有记录的直接标记完成和完成时间。 2、没有run表记录的,根据流程写入run表,并标记完成和完成时间。 */ info.Main.StatusList.ForEach(async st => { var relateList = statusList.Where(a => a.StatusList.Any(b => { if (b.StatusSKUCode.Equals(st.StatusCode, StringComparison.OrdinalIgnoreCase)) return true; if (b.SubStatusList != null && b.SubStatusList.Any(c => c.StatusSKUCode.Equals(st.StatusCode, StringComparison.OrdinalIgnoreCase))) return true; return false; })).ToList(); relateList.ForEach(async rt => { var runList = runHisList.Where(a => a.Main.SERVICE_WF_ID == rt.WFPKId).ToList(); if(runList.Count == 0) { #region 处理run表 //需要生成run表记录包含活动明细 ServiceWorkFlowRunInfo serviceWorkFlowRunInfo = new ServiceWorkFlowRunInfo { PK_ID = IDGen.NextID().ToString(), SERVICE_WF_ID = rt.WFPKId, BUSI_SYSTEM_CODE = info.Main.BusiSystemCode.ToUpper(), BUSI_ID = info.Main.BusiId.ToUpper(), MBL_NO = info.Main?.MBlNo.ToUpper(), VESSEL_VOYNO = info.Main?.VesselVoyno.ToUpper(), ORDER_NO = info.Main?.OrderNo, STATUS = TaskStatusEnum.Create.ToString(), RELEASE_VERSION = rt.ReleaseVersion, ACTIVITIES_NUM = rt.StatusNum, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, SERVICE_PROJECT_CODE = rt.ProjectCode, SERVICE_PROJECT_NAME = rt.ProjectName, SERVICE_PROJECT_ID = rt.ProjectPKId, IS_YIELD = 1, ACT_DATE = nowDate, }; //写入run主表 await _serviceWorkFlowRunInfoRepository.InsertAsync(serviceWorkFlowRunInfo); //获取状态最大数 int endNum = rt.StatusList.Max(sku => sku.ActSortNo); string lastActId = string.Empty; rt.StatusList.ForEach(async sku => { ServiceWorkFlowRunActivitiesInfo activitiesRunInfo = new ServiceWorkFlowRunActivitiesInfo { PK_ID = IDGen.NextID().ToString(), RUN_ID = serviceWorkFlowRunInfo.PK_ID, EXEC_SORT_NO = sku.ActSortNo, IS_START = sku.ActSortNo == 1 ? 1 : 0, IS_END = sku.ActSortNo == endNum ? 1 : 0, ACT_ID = sku.ActPKId, STATUS_SKU_CODE = sku.StatusSKUCode, STATUS_SKU_ID = sku.SkuPKId, SHOW_NAME = sku.ShowName, IS_SUB = 0, IS_SUB_JUST = 0, IS_YIELD = 0, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, IsDeleted = false, SOURCE_TYPE = info.Main.SourceType.ToString() }; if (st.StatusCode.Equals(sku.StatusSKUCode,StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if(!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesRunInfo.ACT_DATE = nowDate; } } activitiesRunInfo.ACT_VAL = st.StatusVal; activitiesRunInfo.ACT_REMARK = st.Remark; } //写入run活动表 await _serviceWorkFlowRunActivitiesInfoRepository.InsertAsync(activitiesRunInfo); if (sku.SubStatusList != null && sku.SubStatusList.Count > 0) { string lastSubActId = string.Empty; sku.SubStatusList.ForEach(async sub => { ServiceWorkFlowRunActivitiesInfo activitiesSubRunInfo = new ServiceWorkFlowRunActivitiesInfo { PK_ID = IDGen.NextID().ToString(), RUN_ID = serviceWorkFlowRunInfo.PK_ID, EXEC_SORT_NO = sub.ActSortNo, IS_START = sub.ActSortNo == 1 ? 1 : 0, IS_END = sub.ActSortNo == endNum ? 1 : 0, ACT_ID = sub.ActPKId, STATUS_SKU_CODE = sub.StatusSKUCode, STATUS_SKU_ID = sub.SkuPKId, SHOW_NAME = sub.ShowName, IS_SUB = 1, IS_SUB_JUST = 1, IS_YIELD = 0, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, IsDeleted = false, SOURCE_TYPE = info.Main.SourceType.ToString(), PARENT_ID = activitiesRunInfo.PK_ID }; if (st.StatusCode.Equals(sub.StatusSKUCode, StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if (!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesSubRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesSubRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesSubRunInfo.ACT_DATE = nowDate; } } activitiesSubRunInfo.ACT_VAL = st.StatusVal; activitiesSubRunInfo.ACT_REMARK = st.Remark; } if (!string.IsNullOrWhiteSpace(lastSubActId)) activitiesSubRunInfo.NEXT_ACT_ID = lastSubActId; await _serviceWorkFlowRunActivitiesInfoRepository.InsertAsync(activitiesSubRunInfo); lastSubActId = activitiesSubRunInfo.PK_ID; }); } }); #endregion } else { if (runList.Any(b => b.Detail == null || (b.Detail != null && string.IsNullOrWhiteSpace(b.Detail.PK_ID)))) { var runMain = runList.FirstOrDefault().Main; //需要补充活动表明细 var runEntity =_serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .First(rn => rn.PK_ID == runMain.PK_ID); if(runEntity != null && runEntity.IS_YIELD == 0) { runEntity.IS_YIELD = 1; runEntity.ACT_DATE = nowDate; runEntity.UpdatedTime = nowDate; runEntity.CreatedUserId = long.Parse(info.Main.OperUserId); runEntity.CreatedUserName = info.Main.OperUserName; await _serviceWorkFlowRunInfoRepository.AsUpdateable(runEntity).UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); } //批量写入活动表 #region 批量写入活动表 //获取状态最大数 int endNum = rt.StatusList.Max(sku => sku.ActSortNo); string lastActId = string.Empty; rt.StatusList.ForEach(async sku => { ServiceWorkFlowRunActivitiesInfo activitiesRunInfo = new ServiceWorkFlowRunActivitiesInfo { PK_ID = IDGen.NextID().ToString(), RUN_ID = runEntity.PK_ID, EXEC_SORT_NO = sku.ActSortNo, IS_START = sku.ActSortNo == 1 ? 1 : 0, IS_END = sku.ActSortNo == endNum ? 1 : 0, ACT_ID = sku.ActPKId, STATUS_SKU_CODE = sku.StatusSKUCode, STATUS_SKU_ID = sku.SkuPKId, SHOW_NAME = sku.ShowName, IS_SUB = 0, IS_SUB_JUST = 0, IS_YIELD = 0, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, IsDeleted = false, SOURCE_TYPE = info.Main.SourceType.ToString(), }; if (st.StatusCode.Equals(sku.StatusSKUCode, StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if (!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesRunInfo.ACT_DATE = nowDate; } } activitiesRunInfo.ACT_VAL = st.StatusVal; activitiesRunInfo.ACT_REMARK = st.Remark; } //写入run活动表 await _serviceWorkFlowRunActivitiesInfoRepository.InsertAsync(activitiesRunInfo); if (sku.SubStatusList != null && sku.SubStatusList.Count > 0) { string lastSubActId = string.Empty; sku.SubStatusList.ForEach(async sub => { ServiceWorkFlowRunActivitiesInfo activitiesSubRunInfo = new ServiceWorkFlowRunActivitiesInfo { PK_ID = IDGen.NextID().ToString(), RUN_ID = runEntity.PK_ID, EXEC_SORT_NO = sub.ActSortNo, IS_START = sub.ActSortNo == 1 ? 1 : 0, IS_END = sub.ActSortNo == endNum ? 1 : 0, ACT_ID = sub.ActPKId, STATUS_SKU_CODE = sub.StatusSKUCode, STATUS_SKU_ID = sub.SkuPKId, SHOW_NAME = sub.ShowName, IS_SUB = 1, IS_SUB_JUST = 1, IS_YIELD = 0, CreatedTime = nowDate, UpdatedTime = nowDate, CreatedUserId = long.Parse(info.Main.OperUserId), CreatedUserName = info.Main.OperUserName, TenantId = info.Main.OperTenantId, TenantName = info.Main.OperTenantName, IsDeleted = false, SOURCE_TYPE = info.Main.SourceType.ToString(), PARENT_ID = activitiesRunInfo.PK_ID }; if (st.StatusCode.Equals(sub.StatusSKUCode, StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if (!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesSubRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesSubRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesSubRunInfo.ACT_DATE = nowDate; } } activitiesSubRunInfo.ACT_VAL = st.StatusVal; activitiesSubRunInfo.ACT_REMARK = st.Remark; } if (!string.IsNullOrWhiteSpace(lastSubActId)) activitiesSubRunInfo.NEXT_ACT_ID = lastSubActId; await _serviceWorkFlowRunActivitiesInfoRepository.InsertAsync(activitiesSubRunInfo); lastSubActId = activitiesSubRunInfo.PK_ID; }); } }); #endregion } else { var runMain = runList.FirstOrDefault().Main; //需要补充活动表明细 var runEntity = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .First(rn => rn.PK_ID == runMain.PK_ID); if (runEntity != null && runEntity.IS_YIELD == 0) { runEntity.IS_YIELD = 1; runEntity.ACT_DATE = nowDate; runEntity.UpdatedTime = nowDate; runEntity.CreatedUserId = long.Parse(info.Main.OperUserId); runEntity.CreatedUserName = info.Main.OperUserName; await _serviceWorkFlowRunInfoRepository.AsUpdateable(runEntity).UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); } //只需要更新完成标记和完成时间 rt.StatusList.ForEach(async sku => { var currRunDetail = runList.FirstOrDefault(p => p.Detail.STATUS_SKU_CODE.Equals(sku.StatusSKUCode)).Detail; var activitiesRunInfo = _serviceWorkFlowRunActivitiesInfoRepository.AsQueryable() .First(p=>p.PK_ID == currRunDetail.PK_ID); if (st.StatusCode.Equals(sku.StatusSKUCode, StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if (!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesRunInfo.ACT_DATE = nowDate; } } activitiesRunInfo.ACT_VAL = st.StatusVal; activitiesRunInfo.ACT_REMARK = st.Remark; activitiesRunInfo.UpdatedTime = nowDate; activitiesRunInfo.CreatedUserId = long.Parse(info.Main.OperUserId); activitiesRunInfo.CreatedUserName = info.Main.OperUserName; await _serviceWorkFlowRunActivitiesInfoRepository.AsUpdateable(activitiesRunInfo) .UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, it.ACT_REMARK, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); } if (sku.SubStatusList != null && sku.SubStatusList.Count > 0) { sku.SubStatusList.ForEach(async sub => { var currRunDetailSub = runList.FirstOrDefault(p => p.Detail.STATUS_SKU_CODE.Equals(sub.StatusSKUCode)).Detail; var activitiesSubRunInfo = _serviceWorkFlowRunActivitiesInfoRepository.AsQueryable() .First(p=> currRunDetailSub.STATUS_SKU_CODE.Equals(sub.StatusSKUCode)); if (st.StatusCode.Equals(sub.StatusSKUCode, StringComparison.OrdinalIgnoreCase)) { bool currIsYield = true; //完成时间为空,备注不为空只保存备注信息,不标记完成 if (!st.StatusDate.HasValue && !string.IsNullOrWhiteSpace(st.Remark)) { currIsYield = false; } if (currIsYield) { activitiesSubRunInfo.IS_YIELD = 1; if (st.StatusDate.HasValue) { activitiesSubRunInfo.ACT_DATE = st.StatusDate.Value; } else { activitiesSubRunInfo.ACT_DATE = nowDate; } } activitiesSubRunInfo.ACT_VAL = st.StatusVal; activitiesSubRunInfo.ACT_REMARK = st.Remark; activitiesSubRunInfo.UpdatedTime = nowDate; activitiesSubRunInfo.CreatedUserId = long.Parse(info.Main.OperUserId); activitiesSubRunInfo.CreatedUserName = info.Main.OperUserName; await _serviceWorkFlowRunActivitiesInfoRepository.AsUpdateable(activitiesSubRunInfo) .UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, it.ACT_REMARK, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); } }); } }); } } }); }); result.succ = true; result.msg = "推送成功"; } catch (Exception ex) { result.succ = false; result.msg = $"推送状态失败,原因:{ex.Message}"; } return result; } #endregion #region 单票单服务项目查询 /// /// 单票单服务项目查询 /// /// 查询服务流程详情 /// 返回回执 [HttpPost("/ServiceWorkFlowManage/QuerySingleBusinessPerServiceProject")] public async Task QuerySingleBusinessPerServiceProject(TrackingQueryMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 单票单服务项目查询 msg={msg}", batchNo, JSON.Serialize(info)); try { result.succ = true; result.ext = InnerGetRunListBySingleBusiness(info); } catch (Exception ex) { result.succ = false; result.msg = $"单票单服务项目查询失败,原因:{ex.Message}"; } return result; } #endregion #region 获取单票业务相关的服务项目运行列表 /// /// 获取单票业务相关的服务项目运行列表 /// /// 查询服务流程详情 /// 返回查询列表 private List InnerGetRunListBySingleBusiness(TrackingQueryMessageInfo info) { var runList = _serviceWorkFlowRunInfoRepository.AsQueryable() .Filter(null, true) .LeftJoin((m, s) => m.PK_ID == s.RUN_ID) .LeftJoin((m, s, rela) => m.SERVICE_WF_ID == rela.SERVICE_WORKFLOW_ID && m.RELEASE_VERSION == rela.WF_VERSION) .InnerJoin((m, s, rela, p) => rela.SERVICE_PROJECT_ID == p.PK_ID) .Where((m, s, rela, p) => m.BUSI_SYSTEM_CODE == info.Main.BusiSystemCode && m.BUSI_ID == info.Main.BusiId && (info.Main.ServiceProjectCodeList == null || info.Main.ServiceProjectCodeList.Contains(p.SERVICE_PROJECT_CODE))) .Select((m, s,rela,p) => new { Run = m, Sub = s }).ToList(); var resultList = runList.GroupBy(a => a.Run.PK_ID) .Select(a => { var currList = a.ToList(); var runInfo = currList.FirstOrDefault().Run; var showModel = new ServiceWorkFlowRunDto(); showModel.PKId = runInfo.PK_ID; showModel.ServiceProjectId = runInfo.SERVICE_PROJECT_ID; showModel.ServiceProjectCode = runInfo.SERVICE_PROJECT_CODE; showModel.ServiceProjectName = runInfo.SERVICE_PROJECT_NAME; showModel.IsYield = runInfo.IS_YIELD; showModel.ActDate = runInfo.ACT_DATE; showModel.WFPKId = runInfo.SERVICE_WF_ID; showModel.ActivitiesList = currList.Where(t => !string.IsNullOrWhiteSpace(t.Sub.PK_ID) && t.Sub.IS_SUB == 0) .Select(t => { var runModel = new ServiceWorkFlowActivitiesRunDto { PKId = t.Sub.PK_ID, ActDate = t.Sub.ACT_DATE, ActId = t.Sub.ACT_ID, ExecSortNo = t.Sub.EXEC_SORT_NO, ActVal = t.Sub.ACT_VAL, IsStart = t.Sub.IS_START, IsEnd = t.Sub.IS_END, IsYield = t.Sub.IS_YIELD, RunId = t.Sub.RUN_ID, ShowName = t.Sub.SHOW_NAME, SourceType = t.Sub.SOURCE_TYPE, StatusSKUCode = t.Sub.STATUS_SKU_CODE, StatusSKUId = t.Sub.STATUS_SKU_ID, ActRemark = t.Sub.ACT_REMARK, }; return runModel; }).ToList(); var subList = currList.Where(t => !string.IsNullOrWhiteSpace(t.Sub.PK_ID) && t.Sub.IS_SUB == 1) .Select(t => t.Sub).ToList(); showModel.ActivitiesList = showModel.ActivitiesList.GroupJoin(subList, l => l.PKId, r => r.PARENT_ID, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { l.SubList = currList.Select(x => { var subModel = new ServiceWorkFlowActivitiesRunSubDto { PKId = x.PK_ID, ActDate = x.ACT_DATE, ActId = x.ACT_ID, ExecSortNo = x.EXEC_SORT_NO, ActVal = x.ACT_VAL, IsStart = x.IS_START, IsEnd = x.IS_END, IsYield = x.IS_YIELD, RunId = x.RUN_ID, ShowName = x.SHOW_NAME, SourceType = x.SOURCE_TYPE, StatusSKUCode = x.STATUS_SKU_CODE, StatusSKUId = x.STATUS_SKU_ID, ActRemark = x.ACT_REMARK }; return subModel; }).OrderBy(x => x.ExecSortNo).ToList(); } return l; }).OrderBy(t => t.ExecSortNo).ToList(); return showModel; }).ToList(); return resultList; } #endregion #region 单票所有相关服务项目查询 /// /// 单票所有相关服务项目查询 /// /// 查询服务流程详情 /// 返回回执 [HttpPost("/ServiceWorkFlowManage/QuerySingleBusinessAll")] public async Task QuerySingleBusinessAll(TrackingQueryMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 单票所有相关服务项目查询 msg={msg}", batchNo, JSON.Serialize(info)); try { var runList = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .LeftJoin((m, s) => m.PK_ID == s.RUN_ID) .Where((m, s) => m.BUSI_SYSTEM_CODE == info.Main.BusiSystemCode && m.BUSI_ID == info.Main.BusiId) .Select((m, s) => new { Run = m, Sub = s }).ToList(); var resultList = runList.GroupBy(a => a.Run.PK_ID) .Select(a => { var currList = a.ToList(); var runInfo = currList.FirstOrDefault().Run; var showModel = new ServiceWorkFlowRunDto(); showModel.PKId = runInfo.PK_ID; showModel.ServiceProjectCode = runInfo.SERVICE_PROJECT_CODE; showModel.ServiceProjectName = runInfo.SERVICE_PROJECT_NAME; showModel.ActivitiesList = currList.Where(t => t.Sub.IS_SUB == 0) .Select(t => { var runModel = new ServiceWorkFlowActivitiesRunDto { PKId = t.Sub.PK_ID, ActDate = t.Sub.ACT_DATE, ActId = t.Sub.ACT_ID, ExecSortNo = t.Sub.EXEC_SORT_NO, ActVal = t.Sub.ACT_VAL, IsStart = t.Sub.IS_START, IsEnd = t.Sub.IS_END, IsYield = t.Sub.IS_YIELD, RunId = t.Sub.RUN_ID, ShowName = t.Sub.SHOW_NAME, SourceType = t.Sub.SOURCE_TYPE, StatusSKUCode = t.Sub.STATUS_SKU_CODE, StatusSKUId = t.Sub.STATUS_SKU_ID }; return runModel; }).ToList(); var subList = currList.Where(t => t.Sub.IS_SUB == 1) .Select(t => t.Sub).ToList(); showModel.ActivitiesList = showModel.ActivitiesList.GroupJoin(subList, l => l.PKId, r => r.PARENT_ID, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { l.SubList = currList.Select(x => { var subModel = new ServiceWorkFlowActivitiesRunSubDto { PKId = x.PK_ID, ActDate = x.ACT_DATE, ActId = x.ACT_ID, ExecSortNo = x.EXEC_SORT_NO, ActVal = x.ACT_VAL, IsStart = x.IS_START, IsEnd = x.IS_END, IsYield = x.IS_YIELD, RunId = x.RUN_ID, ShowName = x.SHOW_NAME, SourceType = x.SOURCE_TYPE, StatusSKUCode = x.STATUS_SKU_CODE, StatusSKUId = x.STATUS_SKU_ID }; return subModel; }).OrderBy(x => x.ExecSortNo).ToList(); } return l; }).OrderBy(t => t.ExecSortNo).ToList(); return showModel; }).ToList(); result.succ = true; result.ext = resultList; } catch (Exception ex) { result.succ = false; result.msg = $"单票所有相关服务项目查询失败,原因:{ex.Message}"; } return result; } #endregion /// /// 取消状态 /// /// 服务流程报文详情 /// 返回回执 [HttpPost("/ServiceWorkFlowManage/CancelStatus")] public async Task CancelStatus(TrackingMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 接收推送状态 msg={msg}", batchNo, JSON.Serialize(info)); try { /* 1、首先判断业务的主键,如果存在则需要提取所有主键下的服务流程活动,来更新。 2、状态可以批量处理。 */ if (info.Main == null) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main不能为空", batchNo); throw Oops.Oh($"报文Main不能为空", typeof(InvalidOperationException)); } if (string.IsNullOrWhiteSpace(info.Main.BusiSystemCode)) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main的业务系统代码不能为空", batchNo); throw Oops.Oh($"报文Main的业务系统代码不能为空", typeof(InvalidOperationException)); } if (string.IsNullOrWhiteSpace(info.Main.BusiId)) { _logger.LogInformation("批次={no} 接收推送状态错误 报文Main的业务主键不能为空", batchNo); throw Oops.Oh($"报文Main的业务主键不能为空", typeof(InvalidOperationException)); } var statusList = _serviceWorkFlowBaseService.GetEnableProjectWithStatusList(info.Main.OperTenantId.ToString()).GetAwaiter().GetResult(); var projectList = _cache.Get>($"{CONST_CACHE_ENABLE_PROJECT}_{info.Main.OperTenantId}"); DateTime nowDate = DateTime.Now; if (info.Main.PushType == TrackingPushTypeEnum.Project) { if (info.Main.ProjectList == null || info.Main.ProjectList.Count == 0) { _logger.LogInformation("批次={no} 推送类型是【服务项目】,服务项目列表不能为空", batchNo); throw Oops.Oh($"推送类型是【服务项目】,服务项目列表不能为空", typeof(InvalidOperationException)); } //提取所有已经有run记录的 var runBaseList = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .Where(a => a.BUSI_ID == info.Main.BusiId && a.BUSI_SYSTEM_CODE.Equals(info.Main.BusiSystemCode) && !a.IsDeleted && a.TenantId == info.Main.OperTenantId).ToList(); var needProjectArg = info.Main.ProjectList.Select(a => a.ServiceProjectCode).ToArray(); var needProjectList = statusList.Where(a => needProjectArg.Contains(a.ProjectCode)).ToList(); var tskList = needProjectList.GroupJoin(runBaseList, l => l.WFPKId, r => r.SERVICE_WF_ID, (l, r) => { var currList = r.ToList(); if (currList.Count == 0) { //标识当前服务项目写入运行主表 return new { OperType = "None", Info = l, Run = new ServiceWorkFlowRunInfo() }; } return new { OperType = "Update", Info = l, Run = currList.FirstOrDefault() }; }).ToList(); tskList.ForEach(async tsk => { if (tsk.OperType == "Update") { var runInfo = _serviceWorkFlowRunInfoRepository.AsQueryable() .First(a => a.PK_ID == tsk.Run.PK_ID); runInfo.IS_YIELD = 0; runInfo.ACT_DATE = null; await _serviceWorkFlowRunInfoRepository.AsUpdateable(runInfo).UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, }).ExecuteCommandAsync(); } }); result.succ = true; result.msg = "取消成功"; return result; } //校验状态代码是否一致,不一致直接返回错误不允许推送 var statusArg = info.Main.StatusList.Select(a => a?.StatusCode.ToUpper()) .Where(a => !string.IsNullOrWhiteSpace(a)).Distinct().ToArray(); if (statusArg.Length == 0) { _logger.LogInformation("批次={no} 报文Main的状态列表至少需要提供一个以上的状态信息", batchNo); throw Oops.Oh($"报文Main的状态列表至少需要提供一个以上的状态信息", typeof(InvalidOperationException)); } //检索状态相关的服务流程 statusList = statusList.Where(a => a.StatusList.Any(b => { if (statusArg.Contains(b.StatusSKUCode)) return true; if (b.SubStatusList != null && b.SubStatusList.Any(c => statusArg.Contains(c.StatusSKUCode))) return true; return false; })).ToList(); if (statusList.Count == 0) throw Oops.Oh($"未检索到可用服务项目和状态列表", typeof(InvalidOperationException)); //提取关联的服务流程主键数组 var wfArgs = statusList.Select(a => a.WFPKId).ToArray(); //获取订单下所有Run表记录 var runHisList = _serviceWorkFlowRunInfoRepository.AsQueryable().Filter(null, true) .LeftJoin((main, detail) => main.PK_ID == detail.RUN_ID) .Where((main, detail) => main.BUSI_SYSTEM_CODE == info.Main.BusiSystemCode && main.BUSI_ID == info.Main.BusiId && wfArgs.Contains(main.SERVICE_WF_ID)) .Select((main, detail) => new { Main = main, Detail = detail }).ToList(); //按照请求的状态列表轮询 info.Main.StatusList.ForEach(async st => { var relateList = statusList.Where(a => a.StatusList.Any(b => { if (b.StatusSKUCode.Equals(st.StatusCode, StringComparison.OrdinalIgnoreCase)) return true; if (b.SubStatusList != null && b.SubStatusList.Any(c => c.StatusSKUCode.Equals(st.StatusCode, StringComparison.OrdinalIgnoreCase))) return true; return false; })).ToList(); relateList.ForEach(async rt => { var runList = runHisList.Where(a => a.Main.SERVICE_WF_ID == rt.WFPKId).ToList(); if(runList.Any(b =>b.Detail.STATUS_SKU_CODE.Equals(st.StatusCode,StringComparison.OrdinalIgnoreCase))) { var detail = runList.FirstOrDefault(b => b.Detail.STATUS_SKU_CODE.Equals(st.StatusCode, StringComparison.OrdinalIgnoreCase)); var activitiesRunInfo = _serviceWorkFlowRunActivitiesInfoRepository .AsQueryable().First(b => b.PK_ID == detail.Detail.PK_ID); activitiesRunInfo.ACT_VAL = null; activitiesRunInfo.ACT_REMARK = null; activitiesRunInfo.ACT_DATE = null; activitiesRunInfo.IS_YIELD = 0; activitiesRunInfo.UpdatedTime = nowDate; activitiesRunInfo.UpdatedUserId = long.Parse(info.Main.OperUserId); activitiesRunInfo.UpdatedUserName = info.Main.OperUserName; await _serviceWorkFlowRunActivitiesInfoRepository.AsUpdateable(activitiesRunInfo) .UpdateColumns(it => new { it.ACT_DATE, it.IS_YIELD, it.ACT_REMARK, it.ACT_VAL, it.UpdatedTime, it.UpdatedUserId, it.UpdatedUserName }).ExecuteCommandAsync(); } }); }); result.succ = true; result.msg = "取消成功"; } catch (Exception ex) { result.succ = false; result.msg = $"取消状态失败,原因:{ex.Message}"; } return result; } #region 查询订舱表查询用户和租户信息 /// /// 查询订舱表查询用户和租户信息 /// /// 大简云用户ID /// 大简云用户邮箱 /// 返回用户和租户信息 private UserTendDto GetUserTendInfoByDJYUserId(string djyUserId, string djyUserEmail) { UserTendDto userTendDto = null; //这里因为接口是不做授权验证的,所以这里直接写的动态sql提取了用户和租户信息 var userTendInfo = _sysUserRepository.EntityContext.Queryable("user").AS("sys_user") .AddJoinInfo("sys_tenant", "ten", "user.TenantId=ten.Id") .Where("user.DjyUserId=@id and user.Email like '%" + djyUserEmail + "%'", new { id = djyUserId }) .Select("user.Id as UserId,user.Name as UserName,ten.Id as TendId,ten.Name as TendName").First(); if (userTendInfo == null || userTendInfo.TendId == null) throw Oops.Oh("当前用户详情获取失败,请确认{0}赋值是否准确", nameof(TaskManageOrderMessageInfo.Main.TaskUserId)); userTendDto = new UserTendDto { userId = long.Parse(userTendInfo.UserId.ToString()), userName = userTendInfo.UserName.ToString(), tendId = long.Parse(userTendInfo.TendId.ToString()), tenantName = userTendInfo.TendName.ToString() }; return userTendDto; } #endregion #region 查询订舱表查询用户和租户信息 /// /// 查询订舱表查询用户和租户信息 /// /// 用户ID /// 返回用户和租户信息 private UserTendDto GetUserTendInfo(string userId) { UserTendDto userTendDto = null; //这里因为接口是不做授权验证的,所以这里直接写的动态sql提取了用户和租户信息 var userTendInfo = _sysUserRepository.EntityContext.Queryable("user").AS("sys_user") .AddJoinInfo("sys_tenant", "ten", "user.TenantId=ten.Id") .Where("user.Id=@id", new { id = long.Parse(userId) }) .Select("user.Id as UserId,user.Name as UserName,ten.Id as TendId,ten.Name as TendName").First(); if (userTendInfo == null || userTendInfo.TendId == null) throw Oops.Oh("当前用户详情获取失败,请确认{0}赋值是否准确", nameof(TaskManageOrderMessageInfo.Main.TaskUserId)); userTendDto = new UserTendDto { userId = long.Parse(userTendInfo.UserId.ToString()), userName = userTendInfo.UserName.ToString(), tendId = long.Parse(userTendInfo.TendId.ToString()), tenantName = userTendInfo.TendName.ToString() }; return userTendDto; } #endregion /// /// 查询当前租户下可用服务项目与状态详情 /// /// 查询服务项目请求报文 /// 返回回执 [HttpPost("/ServiceWorkFlowManage/QueryServiceInfo")] public async Task QueryServiceInfo([FromBody] TrackingQueryMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 查询当前租户下可用服务项目 msg={msg}", batchNo, JSON.Serialize(info)); try { /* 1、检索按照租户检索已经发布的服务流程。 2、根据枚举 info.Main.QueryType来判断返回哪些数据。 3、只返回服务项目。 4、只返回服务项目下的服务状态。 5、优先通过缓存获取结果。 */ if (info.Main.QueryType == TrackingQueryTypeEnum.QUERY_SERVICE_PROJECT) { var projectList = await _serviceWorkFlowBaseService.GetEnableProjectList(info.Main.TenantId); if (info.Main.QueryServiceProjectCode != null && info.Main.QueryServiceProjectCode.Length > 0) { result.ext = projectList.Where(a => info.Main.QueryServiceProjectCode.Contains(a.ServiceProjectCode)) .OrderBy(a => a.SortNo).ToList(); } else { result.ext = projectList; } } else if (info.Main.QueryType == TrackingQueryTypeEnum.QUERY_SERVICE_PROJECT_STATUS) { var statusList = await _serviceWorkFlowBaseService.GetEnableProjectList(info.Main.TenantId); if (info.Main.QueryServiceProjectCode != null && info.Main.QueryServiceProjectCode.Length > 0) { result.ext = statusList.Where(a => info.Main.QueryServiceProjectCode.Contains(a.ServiceProjectCode)) .OrderBy(a => a.SortNo).ToList(); } else { result.ext = statusList; } } result.succ = true; } catch (Exception ex) { result.succ = false; result.msg = $"查询服务项目失败,原因:{ex.Message}"; } return result; } #region 校验取消状态 /// /// 校验取消状态 /// /// 服务流程报文详情 /// 返回回执 public async Task ValidateCancelProject(TrackingMessageInfo info) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); string batchNo = IDGen.NextID().ToString(); _logger.LogInformation("批次={no} 接收推送状态 msg={msg}", batchNo, JSON.Serialize(info)); return result; } #endregion #region 检索已选中并且可用的服务项目列表 /// /// 检索已选中并且可用的服务项目列表 /// /// 查询服务项目和状态详情 /// 返回回执 public async Task GetEnableProjectList(QueryServiceProjectWithStatus model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { //先获取可用的服务项目 var projectList = await _serviceWorkFlowBaseService.GetEnableProjectList(model.TenantId.ToString()); TrackingQueryMessageInfo messageInfo = new TrackingQueryMessageInfo { Head = new TrackingMessageHeadInfo { GID = IDGen.NextID().ToString(), MessageType = "PROJECT", ReceiverId = "ServiceProjectStatus", ReceiverName = "服务项目和状态", SenderId = "BookingOrder", SenderName = "海运订舱", RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Version = "2.0", RequestAction = "AddOrModify", },Main = new TrackingMessageQueryMainInfo { BusiId = model.BookingId.ToString(), BusiSystemCode = "BOOKING_ORDER", TenantId = model.TenantId.ToString(), } }; //在获取运行表已有的记录 var runList = InnerGetRunListBySingleBusiness(messageInfo); var resultList = projectList.GroupJoin(runList, l => l.PKId, r => r.ServiceProjectId, (l, r) => { var currList = r.ToList(); var runInfo = currList.FirstOrDefault(); var dto = new ServiceProjectWithStatusDto { ProjectPKId = l.PKId, ProjectCode = l.ServiceProjectCode, ProjectName = l.ServiceProjectName, SortNo = l.SortNo }; if(runInfo != null) { dto.IsYield = runInfo.IsYield == 1 ? true : false; dto.ActDate = runInfo.ActDate; } return dto; }).ToList(); result.succ = true; result.ext = resultList; } catch (Exception ex) { result.succ = false; result.msg = $"检索已选中并且可用的服务项目列表失败,原因:{ex.Message}"; } return result; } #endregion #region 检索服务项目下的状态列表 /// /// 检索服务项目下的状态列表 /// /// 查询服务项目和状态详情 /// 返回回执 public async Task GetEnableStatusListByProject(QueryServiceProjectWithStatus model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var statuList = await _serviceWorkFlowBaseService.GetEnableProjectWithStatusList(model.TenantId.ToString()); var resultList = statuList.Where(a => model.ProjectCodes.Contains(a.ProjectCode)) .OrderBy(a => a.SortNo) .SelectMany(a => a.StatusList.SelectMany(b => { List currList = new List(); currList.Add(b); if (b.SubStatusList != null && b.SubStatusList.Count > 0) { currList.AddRange(b.SubStatusList.OrderBy(e=>e.ActSortNo)); } return currList; } )).ToList() .ToList(); result.succ = true; result.ext = resultList; } catch (Exception ex) { result.succ = false; result.msg = $"检索服务项目下的状态列表失败,原因:{ex.Message}"; } return result; } #endregion #region 单票检索服务项目下的状态列表 /// /// 单票检索服务项目下的状态列表 /// /// 查询服务项目和状态详情 /// 返回回执 public async Task GetEnableStatusListByBusiness(QueryServiceProjectWithStatus model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var statuList = await _serviceWorkFlowBaseService.GetEnableProjectWithStatusList(model.TenantId.ToString()); TrackingQueryMessageInfo messageInfo = new TrackingQueryMessageInfo { Head = new TrackingMessageHeadInfo { GID = IDGen.NextID().ToString(), MessageType = "PROJECT", ReceiverId = "ServiceProjectStatus", ReceiverName = "服务项目和状态", SenderId = "BookingOrder", SenderName = "海运订舱", RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Version = "2.0", RequestAction = "AddOrModify", }, Main = new TrackingMessageQueryMainInfo { BusiId = model.BookingId.ToString(), BusiSystemCode = "BOOKING_ORDER", TenantId = model.TenantId.ToString(), } }; //在获取运行表已有的记录 var runList = InnerGetRunListBySingleBusiness(messageInfo); var resultList = statuList.Join(runList, l => l.WFPKId, r => r.WFPKId, (l, r) => { var runInfo = r; var rltList = new List(); if (runInfo.IsYield == 1) { if(runInfo.ActivitiesList == null ||(runInfo.ActivitiesList != null && runInfo.ActivitiesList.Count == 0)) { l.StatusList.ForEach(b => { rltList.Add(new ServiceProjectStatusDto { ActPKId = b.ActPKId, ActSortNo = b.ActSortNo, ShowName = b.ShowName, IsYield = false, StatusSKUCode = b.StatusSKUCode, ActRemark = b.ActRemark }); if(b.SubStatusList != null && b.SubStatusList.Count > 0) { rltList.AddRange(b.SubStatusList.Select(c => new ServiceProjectStatusDto { ActPKId = c.ActPKId, ActSortNo = c.ActSortNo, ShowName = c.ShowName, IsYield = false, StatusSKUCode = b.StatusSKUCode, ActRemark = b.ActRemark }).ToList()); } }); } else { rltList = runInfo.ActivitiesList.Select(b => new ServiceProjectStatusDto { ActPKId = b.ActId, ActSortNo = b.ExecSortNo, ShowName = b.ShowName, IsYield = b.IsYield == 1 ? true : false, ActDate = b.ActDate, ActVal = b.ActVal, StatusSKUCode = b.StatusSKUCode, ActRemark = b.ActRemark }).ToList(); } } return rltList; }).SelectMany(b=>b).ToList(); result.succ = true; result.ext = resultList; } catch (Exception ex) { result.succ = false; result.msg = $"检索服务项目下的状态列表失败,原因:{ex.Message}"; } return result; } #endregion } }