using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.WorkPlan; using CMS.Plugin.PipeLineLems.Application.Contracts.Services; using CMS.Plugin.PipeLineLems.Domain.Shared; using CmsQueryExtensions; using CMS.Plugin.PipeLineLems.Domain.WorkPlan; using CmsQueryExtensions.Extension; using System.Linq.Expressions; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Data; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; namespace CMS.Plugin.PipeLineLems.Application.Implements; /// /// 作业计划表应用服务 /// public class WorkPlanAppService : CMSPluginAppService, IWorkPlanAppService { private readonly IWorkPlanRepository workPlanRepository; /// /// Initializes a new instance of the class. /// /// The task job repository. public WorkPlanAppService(IWorkPlanRepository _WorkPlanRepository) { workPlanRepository = _WorkPlanRepository; } /// /// 获取指定作业计划表 /// /// /// public virtual async Task GetAsync(Guid id) { return ObjectMapper.Map(await workPlanRepository.GetAsync(id)); } /// /// 分页获取作业计划表 /// /// /// public virtual async Task> GetListAsync(GetWorkPlanInput input) { Check.NotNull(input, nameof(input)); if (input.Sorting.IsNullOrWhiteSpace()) { input.Sorting = nameof(WorkPlan.Sort); } #region 动态构造查询条件 //动态构造查询条件 var whereConditions = DynamicGetQueryParams(input); #endregion var count = await workPlanRepository.GetCountAsync(whereConditions); var list = await workPlanRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount); return new PagedResultDto(count, ObjectMapper.Map, List>(list)); } /// /// 动态构造查询条件 /// /// 输入参数 /// private FunReturnResultModel>> DynamicGetQueryParams(GetWorkPlanInput input) { //动态构造查询条件 var whereConditions = WhereConditionsExtensions.GetWhereConditions(input); if (!whereConditions.IsSuccess) { throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg); } //也可再次自定义构建查询条件 Expression> extendExpression = a => a.IsDeleted == false; // 使用 System.Linq.PredicateBuilder 的 And var pres = (System.Linq.Expressions.Expression>)(whereConditions.data); whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression); return whereConditions; } /// /// 新建作业计划表 /// /// /// /// public virtual async Task CreateAsync(WorkPlanCreateDto input) { await CheckCreateOrUpdateDtoAsync(input); var exist = await workPlanRepository.NameExistAsync(input.TaskCode); if (exist) { throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.TaskCode]); } var maxSort = await workPlanRepository.GetMaxSortAsync(); var sort = input.Sort ?? maxSort; var insertObj = ObjectMapper.Map(input); insertObj.Sort = sort; input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None); await workPlanRepository.InsertAsync(insertObj); //if (input.Sort.HasValue && insertObj.Sort != maxSort) //{ // await AdjustSortAsync(insertObj.Id, insertObj.Sort); //} return ObjectMapper.Map(insertObj); } /// /// 更新作业计划表 /// /// /// /// /// public virtual async Task UpdateAsync(Guid id, WorkPlanUpdateDto input) { await CheckCreateOrUpdateDtoAsync(input); var updateObj = await workPlanRepository.GetAsync(id); var exist = await workPlanRepository.NameExistAsync(input.TaskCode, updateObj.Id); if (exist) { throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.TaskCode]); } updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None); updateObj.TaskCode = input.TaskCode; updateObj.OrgMaterialCode = input.OrgMaterialCode; updateObj.FactoryCode = input.FactoryCode; updateObj.ProductCode = input.ProductCode; updateObj.WorkstationCode = input.WorkstationCode; updateObj.EquipmentCode = input.EquipmentCode; updateObj.WorkpieceName = input.WorkpieceName; updateObj.ProcessName = input.ProcessName; updateObj.PipeFittingCode = input.PipeFittingCode; updateObj.PreSerialNumber = input.PreSerialNumber; updateObj.DataIdentifier = input.DataIdentifier; updateObj.PipeSpecCode = input.PipeSpecCode; updateObj.PipeSectionName = input.PipeSectionName; updateObj.OuterDiameter = input.OuterDiameter; updateObj.Bevel = input.Bevel; updateObj.Material = input.Material; updateObj.Length = input.Length; updateObj.DrillingPosition = input.DrillingPosition; updateObj.Intersecting = input.Intersecting; updateObj.InterfaceRequirement = input.InterfaceRequirement; updateObj.HasMainSignature = input.HasMainSignature; updateObj.Quantity = input.Quantity; updateObj.MarkingContent = input.MarkingContent; updateObj.CuttingFile = input.CuttingFile; updateObj.BranchOuterDiameter = input.BranchOuterDiameter; updateObj.BranchWallThickness = input.BranchWallThickness; updateObj.BranchMaterial = input.BranchMaterial; updateObj.BranchPortRadius = input.BranchPortRadius; updateObj.BranchPortAngle = input.BranchPortAngle; updateObj.BranchPortRequirement = input.BranchPortRequirement; updateObj.IntersectingLineType = input.IntersectingLineType; updateObj.IntersectingLineCategory = input.IntersectingLineCategory; updateObj.FinishedProductScale = input.FinishedProductScale; updateObj.FlangeThickness = input.FlangeThickness; updateObj.FlangeInnerDiameter = input.FlangeInnerDiameter; updateObj.WeldingHeatInput = input.WeldingHeatInput; updateObj.PipeAllowableStress = input.PipeAllowableStress; updateObj.PipeDiameter = input.PipeDiameter; updateObj.PipeWallThickness = input.PipeWallThickness; updateObj.VRData = input.VRData; updateObj.ProcessRouteNumber = input.ProcessRouteNumber; updateObj.PlannedStartTime = input.PlannedStartTime; updateObj.PlannedEndTime = input.PlannedEndTime; updateObj.TimeInfo = input.TimeInfo; updateObj.RedundantField1 = input.RedundantField1; updateObj.RedundantField2 = input.RedundantField2; updateObj.RedundantField3 = input.RedundantField3; updateObj.Remark = input.Remark; updateObj.IsDisabled = input.IsDisabled; await workPlanRepository.UpdateAsync(updateObj); return ObjectMapper.Map(updateObj); } /// /// 克隆作业计划表 /// /// /// public async Task> CloneAsync(IEnumerable ids) { //var workPlans = new List(); //if (ids != null) //{ // var sort = await workPlanRepository.GetMaxSortAsync(); // foreach (var id in ids) // { // var WorkPlan = await workPlanRepository.FindAsync(id); // if (WorkPlan != null) // { // var name = WorkPlan.Name + WorkPlanConsts.CloneTag; // var notExist = false; // while (!notExist) // { // var exist = await workPlanRepository.NameExistAsync(name); // if (exist || workPlans.Any(x => x.Name == name)) // { // name += WorkPlanConsts.CloneTag; // continue; // } // notExist = true; // } // //WorkPlan = await workPlanRepository.InsertAsync(WorkPlan.Clone(GuidGenerator.Create(), name, sort++)); // workPlans.Add(WorkPlan); // } // } //} //return ObjectMapper.Map, List>(workPlans); return new List(); } /// /// 删除单个作业计划表 /// /// /// public virtual Task DeleteAsync(Guid id) { return workPlanRepository.DeleteAsync(id); } /// /// 删除多个作业计划表 /// /// /// public async Task DeleteManyAsync(IEnumerable ids) { foreach (var id in ids) { await DeleteAsync(id); } } /// /// 调整排序作业计划表 /// /// /// /// public virtual async Task AdjustSortAsync(Guid id, int sort) { var list = await workPlanRepository.GetListAsync(null, nameof(WorkPlan.Sort)); if (list != null && list.Any()) { var initSort = 1; list.ForEach(x => x.AdjustSort(initSort++)); var entity = list.FirstOrDefault(x => x.Id == id); if (entity != null) { if (sort == 1) { list.Where(x => x.Id != id).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); } else if (entity.Sort > sort) { list.Where(x => x.Id != id && x.Sort >= sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); list.Where(x => x.Id != id && x.Sort < sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort - 1)); } else if (entity.Sort < sort) { list.Where(x => x.Id != id && x.Sort > sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); list.Where(x => x.Id != id && x.Sort <= sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort - 1)); } entity.AdjustSort(sort); } } await workPlanRepository.UpdateManyAsync(list); } /// /// 导入作业计划表 /// /// /// /// public async Task ImportAsync(WorkPlansImportModel input) { Check.NotNull(input, nameof(input)); var workPlanCreateDtos = new List<(int RowIndex, WorkPlanCreateDto Item)>(); var workPlanUpdateDtos = new List<(int RowIndex, Guid Id, WorkPlanUpdateDto Item)>(); var importItems = input.WorkPlans; if (importItems != null && importItems.Any()) { #region 导入校验 // 判断名称是否重复,并输出第几行重复 var duplicateWorkPlans = importItems.GroupBy(x => x.TaskCode).Where(x => x.Count() > 1).ToList(); if (duplicateWorkPlans?.Any() == true) { var duplicateWorkPlanMsgs = duplicateWorkPlans.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} 行:{x.Key} 名称重复"); var errorMsg = $"导入失败!配置, {string.Join(",", duplicateWorkPlanMsgs)},终止导入"; throw new UserFriendlyException(errorMsg); } #endregion foreach (var impItem in importItems) { if (impItem.TaskCode.IsNullOrWhiteSpace()) { continue; } if (impItem.TaskCode.IsNullOrWhiteSpace()) { var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:WorkPlan名称不能为空"; throw new UserFriendlyException(errorMsg); } var oldWorkPlan = await workPlanRepository.FindByNameAsync(impItem.TaskCode); if (oldWorkPlan != null) { var workPlanUpdateDto = new WorkPlanUpdateDto { TaskCode = impItem.TaskCode, OrgMaterialCode = impItem.OrgMaterialCode, FactoryCode = impItem.FactoryCode, ProductCode = impItem.ProductCode, WorkstationCode = impItem.WorkstationCode, EquipmentCode = impItem.EquipmentCode, WorkpieceName = impItem.WorkpieceName, ProcessName = impItem.ProcessName, PipeFittingCode = impItem.PipeFittingCode, PreSerialNumber = impItem.PreSerialNumber, DataIdentifier = impItem.DataIdentifier, PipeSpecCode = impItem.PipeSpecCode, PipeSectionName = impItem.PipeSectionName, OuterDiameter = impItem.OuterDiameter, Bevel = impItem.Bevel, Material = impItem.Material, Length = impItem.Length, DrillingPosition = impItem.DrillingPosition, Intersecting = impItem.Intersecting, InterfaceRequirement = impItem.InterfaceRequirement, HasMainSignature = impItem.HasMainSignature, Quantity = impItem.Quantity, MarkingContent = impItem.MarkingContent, CuttingFile = impItem.CuttingFile, BranchOuterDiameter = impItem.BranchOuterDiameter, BranchWallThickness = impItem.BranchWallThickness, BranchMaterial = impItem.BranchMaterial, BranchPortRadius = impItem.BranchPortRadius, BranchPortAngle = impItem.BranchPortAngle, BranchPortRequirement = impItem.BranchPortRequirement, IntersectingLineType = impItem.IntersectingLineType, IntersectingLineCategory = impItem.IntersectingLineCategory, FinishedProductScale = impItem.FinishedProductScale, FlangeThickness = impItem.FlangeThickness, FlangeInnerDiameter = impItem.FlangeInnerDiameter, WeldingHeatInput = impItem.WeldingHeatInput, PipeAllowableStress = impItem.PipeAllowableStress, PipeDiameter = impItem.PipeDiameter, PipeWallThickness = impItem.PipeWallThickness, VRData = impItem.VRData, ProcessRouteNumber = impItem.ProcessRouteNumber, PlannedStartTime = impItem.PlannedStartTime, PlannedEndTime = impItem.PlannedEndTime, TimeInfo = impItem.TimeInfo, RedundantField1 = impItem.RedundantField1, RedundantField2 = impItem.RedundantField2, RedundantField3 = impItem.RedundantField3, Remark = impItem.Remark, IsDisabled = impItem.IsDisabled, }; workPlanUpdateDtos.Add((impItem.RowIndex, oldWorkPlan.Id, workPlanUpdateDto)); } else { var workPlanCreateDto = new WorkPlanCreateDto { TaskCode = impItem.TaskCode, OrgMaterialCode = impItem.OrgMaterialCode, FactoryCode = impItem.FactoryCode, ProductCode = impItem.ProductCode, WorkstationCode = impItem.WorkstationCode, EquipmentCode = impItem.EquipmentCode, WorkpieceName = impItem.WorkpieceName, ProcessName = impItem.ProcessName, PipeFittingCode = impItem.PipeFittingCode, PreSerialNumber = impItem.PreSerialNumber, DataIdentifier = impItem.DataIdentifier, PipeSpecCode = impItem.PipeSpecCode, PipeSectionName = impItem.PipeSectionName, OuterDiameter = impItem.OuterDiameter, Bevel = impItem.Bevel, Material = impItem.Material, Length = impItem.Length, DrillingPosition = impItem.DrillingPosition, Intersecting = impItem.Intersecting, InterfaceRequirement = impItem.InterfaceRequirement, HasMainSignature = impItem.HasMainSignature, Quantity = impItem.Quantity, MarkingContent = impItem.MarkingContent, CuttingFile = impItem.CuttingFile, BranchOuterDiameter = impItem.BranchOuterDiameter, BranchWallThickness = impItem.BranchWallThickness, BranchMaterial = impItem.BranchMaterial, BranchPortRadius = impItem.BranchPortRadius, BranchPortAngle = impItem.BranchPortAngle, BranchPortRequirement = impItem.BranchPortRequirement, IntersectingLineType = impItem.IntersectingLineType, IntersectingLineCategory = impItem.IntersectingLineCategory, FinishedProductScale = impItem.FinishedProductScale, FlangeThickness = impItem.FlangeThickness, FlangeInnerDiameter = impItem.FlangeInnerDiameter, WeldingHeatInput = impItem.WeldingHeatInput, PipeAllowableStress = impItem.PipeAllowableStress, PipeDiameter = impItem.PipeDiameter, PipeWallThickness = impItem.PipeWallThickness, VRData = impItem.VRData, ProcessRouteNumber = impItem.ProcessRouteNumber, PlannedStartTime = impItem.PlannedStartTime, PlannedEndTime = impItem.PlannedEndTime, TimeInfo = impItem.TimeInfo, RedundantField1 = impItem.RedundantField1, RedundantField2 = impItem.RedundantField2, RedundantField3 = impItem.RedundantField3, Remark = impItem.Remark, IsDisabled = impItem.IsDisabled, }; workPlanCreateDtos.Add((impItem.RowIndex, workPlanCreateDto)); } } } // 新增 foreach (var workPlanDto in workPlanCreateDtos) { try { await CreateAsync(workPlanDto.Item); } catch (Exception e) { var errorMsg = $"导入失败!配置,第{workPlanDto.RowIndex}行:{e.Message},终止导入"; throw new UserFriendlyException(errorMsg); } } // 更新 foreach (var workPlanDto in workPlanUpdateDtos) { try { await UpdateAsync(workPlanDto.Id, workPlanDto.Item); } catch (Exception e) { var errorMsg = $"导入失败!配置,第{workPlanDto.RowIndex}行:{e.Message},终止导入"; throw new UserFriendlyException(errorMsg); } } } /// /// 导出作业计划表 /// /// /// public async Task<(Dictionary Sheets, string FileName)> ExportAsync(GetWorkPlanInput input) { Check.NotNull(input, nameof(input)); if (input.Sorting.IsNullOrWhiteSpace()) { input.Sorting = nameof(WorkPlan.Sort); } #region 动态构造查询条件 //动态构造查询条件 var whereConditions = DynamicGetQueryParams(input); #endregion var list = await workPlanRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true); var result = ObjectMapper.Map, List>(list); var sheets = new Dictionary { ["配置"] = ExportHelper.ConvertListToExportData(result), }; var fileName = result.Count > 1 ? "作业计划表列表" : result.Count == 1 ? result[0]?.TaskCode : "WorkPlan模版"; return (sheets, fileName); } /// /// 校验作业计划表,当新建或更新时 /// /// /// protected Task CheckCreateOrUpdateDtoAsync(WorkPlanCreateOrUpdateDtoBase input) { Check.NotNull(input, nameof(input)); Check.NotNullOrWhiteSpace(input.TaskCode, "任务编码", 64); Check.NotNullOrWhiteSpace(input.OrgMaterialCode, "原料编号", 64); Check.NotNull(input.HasMainSignature, "是否有主签"); Check.NotNull(input.Quantity, "包括数量"); return Task.CompletedTask; } }