222
schangxiang@126.com
2025-05-13 3c54ed0a7cb25274f6f21fba716c6f6b31fc0283
Weben_CMSרÓôúÂëÉú³ÉÆ÷/Weben_CMS_TemplateDemo/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsMaterialAppService.cs
@@ -1,130 +1,132 @@
using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsMaterial;
using CMS.Plugin.HIAWms.Application.Contracts.Services;
using CMS.Plugin.HIAWms.Domain.Shared;
using CMS.Plugin.HIAWms.Domain.Shared.Util;
using CMS.Plugin.HIAWms.Domain.Shared.WmsMaterial;
using CMS.Plugin.HIAWms.Domain.WmsMaterial;
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.HIAWms.Application.Implements;
using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsMaterial;
using CMS.Plugin.HIAWms.Application.Contracts.Services;
using CMS.Plugin.HIAWms.Domain.Shared;
using CmsQueryExtensions;
using CMS.Plugin.HIAWms.Domain.WmsMaterial;
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;
using CmsQueryExtensions.Entitys;
namespace CMS.Plugin.HIAWms.Application.Implements;
/// <summary> 
/// ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨åº”用服务 
/// </summary> 
public class WmsMaterialAppService : CMSPluginAppService, IWmsMaterialAppService
{
    private readonly IWmsMaterialRepository wmsmaterialsRepository;
public class WmsMaterialAppService : CMSPluginAppService, IWmsMaterialAppService
{
    private readonly IWmsMaterialRepository wmsMaterialRepository;
    /// <summary> 
    /// Initializes a new instance of the <see cref="WmsMaterialAppService"/> class. 
    /// </summary> 
    /// <param name="WmsMaterialRepository">The task job repository.</param> 
    public WmsMaterialAppService(IWmsMaterialRepository WmsMaterialRepository)
    {
        wmsmaterialsRepository = WmsMaterialRepository;
    }
    public WmsMaterialAppService(IWmsMaterialRepository _WmsMaterialRepository)
    {
        wmsMaterialRepository = _WmsMaterialRepository;
    }
    /// <summary> 
    /// èŽ·å–æŒ‡å®šç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public virtual async Task<WmsMaterialDto> GetAsync(Guid id)
    {
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(await wmsmaterialsRepository.GetAsync(id));
    }
    public virtual async Task<WmsMaterialDto> GetAsync(Guid id)
    {
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(await wmsMaterialRepository.GetAsync(id));
    }
    /// <summary> 
    /// åˆ†é¡µèŽ·å–ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    public virtual async Task<PagedResultDto<WmsMaterialDto>> GetListAsync(GetWmsMaterialInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(WmsMaterial.Sort);
        }
    public virtual async Task<PagedResultDto<WmsMaterialDto>> GetListAsync(GetWmsMaterialInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(WmsMaterial.Sort);
        }
        #region åŠ¨æ€æž„é€ æŸ¥è¯¢æ¡ä»¶  
        //动态构造查询条件  
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var count = await wmsmaterialsRepository.GetCountAsync(whereConditions);
        var list = await wmsmaterialsRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount);
        return new PagedResultDto<WmsMaterialDto>(count, ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(list));
    }
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var count = await wmsMaterialRepository.GetCountAsync(whereConditions);
        var list = await wmsMaterialRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount);
        return new PagedResultDto<WmsMaterialDto>(count, ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(list));
    }
    /// <summary>  
    /// åŠ¨æ€æž„é€ æŸ¥è¯¢æ¡ä»¶  
    /// </summary>  
    /// <param name="input">输入参数</param>  
    /// <returns></returns>  
    private FunReturnResultModel<Expression<Func<WmsMaterial, bool>>> DynamicGetQueryParams(GetWmsMaterialInput input)
    {
    private FunReturnResultModel<Expression<Func<WmsMaterial, bool>>> DynamicGetQueryParams(GetWmsMaterialInput input)
    {
        //动态构造查询条件  
        var whereConditions = WhereConditionsExtensions.GetWhereConditions<WmsMaterial, GetWmsMaterialInput>(input);
        if (!whereConditions.IsSuccess)
        {
            throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg);
        }
        var whereConditions = WhereConditionsExtensions.GetWhereConditions<WmsMaterial, GetWmsMaterialInput>(input);
        if (!whereConditions.IsSuccess)
        {
            throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg);
        }
        //也可再次自定义构建查询条件  
        Expression<Func<WmsMaterial, bool>> extendExpression = a => a.IsDeleted == false;
        Expression<Func<WmsMaterial, bool>> extendExpression = a => a.IsDeleted == false;
        // ä½¿ç”¨ System.Linq.PredicateBuilder çš„ And 
        var pres = (System.Linq.Expressions.Expression<Func<WmsMaterial, bool>>)(whereConditions.data);
        whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression);
        return whereConditions;
    }
        var pres = (System.Linq.Expressions.Expression<Func<WmsMaterial, bool>>)(whereConditions.data);
        whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression);
        return whereConditions;
    }
    /// <summary> 
    /// æ–°å»ºç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    /// <exception cref="UserFriendlyException"></exception> 
    public virtual async Task<WmsMaterialDto> CreateAsync(WmsMaterialCreateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var exist = await wmsmaterialsRepository.NameExistAsync(input.MaterialCode);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]);
        }
        var maxSort = await wmsmaterialsRepository.GetMaxSortAsync();
        var sort = input.Sort ?? maxSort;
        var insertObj = ObjectMapper.Map<WmsMaterialCreateDto, WmsMaterial>(input);
        insertObj.Sort = sort;
        input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None);
    public virtual async Task<WmsMaterialDto> CreateAsync(WmsMaterialCreateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        await wmsmaterialsRepository.InsertAsync(insertObj);
        if (input.Sort.HasValue && insertObj.Sort != maxSort)
        {
            await AdjustSortAsync(insertObj.Id, insertObj.Sort);
        }
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(insertObj);
    }
        var exist = await wmsMaterialRepository.NameExistAsync(input.MaterialCode);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]);
        }
        var maxSort = await wmsMaterialRepository.GetMaxSortAsync();
        var sort = input.Sort ?? maxSort;
        var insertObj = ObjectMapper.Map<WmsMaterialCreateDto, WmsMaterial>(input);
        insertObj.Sort = sort;
        input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None);
        insertObj.CreatorName = input.CreatorName;//创建人
        await wmsMaterialRepository.InsertAsync(insertObj);
        //if (input.Sort.HasValue && insertObj.Sort != maxSort)
        //{
        //    await AdjustSortAsync(insertObj.Id, insertObj.Sort);
        //}
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(insertObj);
    }
    /// <summary> 
    /// æ›´æ–°ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
@@ -132,22 +134,27 @@
    /// <param name="input"></param> 
    /// <returns></returns> 
    /// <exception cref="UserFriendlyException"></exception> 
    public virtual async Task<WmsMaterialDto> UpdateAsync(Guid id, WmsMaterialUpdateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var updateObj = await wmsmaterialsRepository.GetAsync(id);
        var exist = await wmsmaterialsRepository.NameExistAsync(input.MaterialCode, updateObj.Id);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]);
        }
        updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
        input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None);
                updateObj.MaterialCode = input.MaterialCode;
    public virtual async Task<WmsMaterialDto> UpdateAsync(Guid id, WmsMaterialUpdateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var updateObj = await wmsMaterialRepository.GetAsync(id);
        var exist = await wmsMaterialRepository.NameExistAsync(input.MaterialCode, updateObj.Id);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]);
        }
        updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
        input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None);
        updateObj.MaterialCode = input.MaterialCode;
        updateObj.IsValid = input.IsValid;
        updateObj.IsSelfMade = input.IsSelfMade;
        updateObj.Num = input.Num;
        updateObj.SelfNum = input.SelfNum;
        updateObj.MaterialName = input.MaterialName;
        updateObj.NullLength = input.NullLength;
        updateObj.PurchaseType = input.PurchaseType;
        updateObj.MaterialType = input.MaterialType;
        updateObj.PrimaryUnit = input.PrimaryUnit;
@@ -163,277 +170,322 @@
        updateObj.RedundantField2 = input.RedundantField2;
        updateObj.RedundantField3 = input.RedundantField3;
        updateObj.Remark = input.Remark;
        updateObj.IsDisabled = input.IsDisabled;
        await wmsmaterialsRepository.UpdateAsync(updateObj);
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(updateObj);
    }
        updateObj.LastModifierName = input.LastModifierName;//修改人
        await wmsMaterialRepository.UpdateAsync(updateObj);
        return ObjectMapper.Map<WmsMaterial, WmsMaterialDto>(updateObj);
    }
    /// <summary> 
    /// å…‹éš†ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="ids"></param> 
    /// <returns></returns> 
    public async Task<List<WmsMaterialDto>> CloneAsync(IEnumerable<Guid> ids)
    {
        //var wmsmaterialss = new List<WmsMaterial>();
    public async Task<List<WmsMaterialDto>> CloneAsync(IEnumerable<Guid> ids, MyCurrentUser myCurrentUser)
    {
        //var wmsMaterials = new List<WmsMaterial>();
        //if (ids != null) 
        //{ 
        //    var sort = await wmsmaterialsRepository.GetMaxSortAsync();
        //    var sort = await wmsMaterialRepository.GetMaxSortAsync();
        //    foreach (var id in ids) 
        //    { 
        //        var WmsMaterial = await wmsmaterialsRepository.FindAsync(id);
        //        var WmsMaterial = await wmsMaterialRepository.FindAsync(id);
        //        if (WmsMaterial != null) 
        //        { 
        //            var name = WmsMaterial.Name + WmsMaterialConsts.CloneTag; 
        //            var notExist = false; 
        //            while (!notExist) 
        //            { 
        //                var exist = await wmsmaterialsRepository.NameExistAsync(name);
        //                if (exist || wmsmaterialss.Any(x => x.Name == name))
        //                var exist = await wmsMaterialRepository.NameExistAsync(name);
        //                if (exist || wmsMaterials.Any(x => x.Name == name))
        //                { 
        //                    name += WmsMaterialConsts.CloneTag; 
        //                    continue; 
        //                } 
        //                notExist = true; 
        //            } 
        //            //WmsMaterial = await wmsmaterialsRepository.InsertAsync(WmsMaterial.Clone(GuidGenerator.Create(), name, sort++));
        //            wmsmaterialss.Add(WmsMaterial);
        //            //WmsMaterial = await wmsMaterialRepository.InsertAsync(WmsMaterial.Clone(GuidGenerator.Create(), name, sort++));
        //            wmsMaterials.Add(WmsMaterial);
        //        } 
        //    } 
        //} 
        //return ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(wmsmaterialss);
        return new List<WmsMaterialDto>();
    }
        //return ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(wmsMaterials);
        return new List<WmsMaterialDto>();
    }
    /// <summary> 
    /// åˆ é™¤å•个物料基础信息表 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public virtual Task DeleteAsync(Guid id)
    {
        return wmsmaterialsRepository.DeleteAsync(id);
    }
    public virtual Task DeleteAsync(Guid id)
    {
        return wmsMaterialRepository.DeleteAsync(id);
    }
    /// <summary> 
    /// åˆ é™¤å¤šä¸ªç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="ids"></param> 
    /// <returns></returns> 
    public async Task DeleteManyAsync(IEnumerable<Guid> ids)
    {
        foreach (var id in ids)
        {
            await DeleteAsync(id);
        }
    }
    public async Task DeleteManyAsync(IEnumerable<Guid> ids, MyCurrentUser myCurrentUser)
    {
        foreach (var id in ids)
        {
            await DeleteAsync(id);
        }
    }
    /// <summary>
    /// ç‰©ç†åˆ é™¤ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨
    /// </summary>
    /// <param name="id">物料ID</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task DeletePermanentlyAsync(Guid id, MyCurrentUser myCurrentUser, CancellationToken cancellationToken = default)
    {
        wmsMaterialRepository.DeletePermanentlyAsync(id);
    }
    /// <summary>
    /// æ‰¹é‡ç‰©ç†åˆ é™¤ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ï¼ˆç›´æŽ¥åˆ é™¤ï¼Œä¸è½¯åˆ é™¤ï¼‰
    /// </summary>
    /// <param name="ids">要删除的物料ID列表</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task BatchDeletePermanentlyAsync(IEnumerable<Guid> ids, MyCurrentUser myCurrentUser, CancellationToken cancellationToken = default)
    {
        wmsMaterialRepository.BatchDeletePermanentlyAsync(ids);
    }
    /// <summary> 
    /// è°ƒæ•´æŽ’序物料基础信息表 
    /// </summary> 
    /// <param name="id"></param> 
    /// <param name="sort"></param> 
    /// <returns></returns> 
    public virtual async Task AdjustSortAsync(Guid id, int sort)
    {
        var list = await wmsmaterialsRepository.GetListAsync(null, nameof(WmsMaterial.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 wmsmaterialsRepository.UpdateManyAsync(list);
    }
    public virtual async Task AdjustSortAsync(Guid id, int sort)
    {
        var list = await wmsMaterialRepository.GetListAsync(null, nameof(WmsMaterial.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 wmsMaterialRepository.UpdateManyAsync(list);
    }
    /// <summary> 
    /// å¯¼å…¥ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    /// <exception cref="UserFriendlyException"></exception> 
    public async Task ImportAsync(WmsMaterialsImportModel input)
    {
        Check.NotNull(input, nameof(input));
        var wmsmaterialsCreateDtos = new List<(int RowIndex, WmsMaterialCreateDto Item)>();
        var wmsmaterialsUpdateDtos = new List<(int RowIndex, Guid Id, WmsMaterialUpdateDto Item)>();
        var importItems = input.WmsMaterials;
        if (importItems != null && importItems.Any())
        {
    public async Task ImportAsync(WmsMaterialsImportModel input, MyCurrentUser myCurrentUser)
    {
        Check.NotNull(input, nameof(input));
        var wmsMaterialCreateDtos = new List<(int RowIndex, WmsMaterialCreateDto Item)>();
        var wmsMaterialUpdateDtos = new List<(int RowIndex, Guid Id, WmsMaterialUpdateDto Item)>();
        var importItems = input.WmsMaterials;
        if (importItems != null && importItems.Any())
        {
            #region å¯¼å…¥æ ¡éªŒ 
            // åˆ¤æ–­åç§°æ˜¯å¦é‡å¤ï¼Œå¹¶è¾“出第几行重复 
            var duplicateWmsMaterials = importItems.GroupBy(x => x.MaterialCode).Where(x => x.Count() > 1).ToList();
            if (duplicateWmsMaterials?.Any() == true)
            {
                var duplicateWmsMaterialMsgs = duplicateWmsMaterials.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} è¡Œï¼š{x.Key}  åç§°é‡å¤");
                var errorMsg = $"导入失败!配置, {string.Join(",", duplicateWmsMaterialMsgs)},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
            #endregion
            foreach (var impItem in importItems)
            {
                if (impItem.MaterialCode.IsNullOrWhiteSpace() && impItem.MaterialName.IsNullOrWhiteSpace())
                {
                    continue;
                }
                if (impItem.MaterialCode.IsNullOrWhiteSpace())
                {
                    var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:WmsMaterial名称不能为空";
                    throw new UserFriendlyException(errorMsg);
                }
                var oldWmsMaterial = await wmsmaterialsRepository.FindByNameAsync(impItem.MaterialCode);
                if (oldWmsMaterial != null)
                {
                    var wmsmaterialsUpdateDto = new WmsMaterialUpdateDto
                    {
                        MaterialCode = impItem.MaterialCode,
                        MaterialName = impItem.MaterialName,
                        PurchaseType = impItem.PurchaseType,
                        MaterialType = impItem.MaterialType,
                        PrimaryUnit = impItem.PrimaryUnit,
                        Standard = impItem.Standard,
                        OuterDiameter = impItem.OuterDiameter,
                        WallThickness = impItem.WallThickness,
                        MaterialQuality = impItem.MaterialQuality,
                        Length = impItem.Length,
                        IsMainBranch = impItem.IsMainBranch,
                        Factory = impItem.Factory,
                        Certification = impItem.Certification,
                        Remark = impItem.Remark,
                    };
                    wmsmaterialsUpdateDtos.Add((impItem.RowIndex, oldWmsMaterial.Id, wmsmaterialsUpdateDto));
                }
                else
                {
                    var wmsmaterialsCreateDto = new WmsMaterialCreateDto
                    {
                        MaterialCode = impItem.MaterialCode,
                        MaterialName = impItem.MaterialName,
                        PurchaseType = impItem.PurchaseType,
                        MaterialType = impItem.MaterialType,
                        PrimaryUnit = impItem.PrimaryUnit,
                        Standard = impItem.Standard,
                        OuterDiameter = impItem.OuterDiameter,
                        WallThickness = impItem.WallThickness,
                        MaterialQuality = impItem.MaterialQuality,
                        Length = impItem.Length,
                        IsMainBranch = impItem.IsMainBranch,
                        Factory = impItem.Factory,
                        Certification = impItem.Certification,
                        Remark = impItem.Remark,
                    };
                    wmsmaterialsCreateDtos.Add((impItem.RowIndex, wmsmaterialsCreateDto));
                }
            }
        }
            var duplicateWmsMaterials = importItems.GroupBy(x => x.MaterialCode).Where(x => x.Count() > 1).ToList();
            if (duplicateWmsMaterials?.Any() == true)
            {
                var duplicateWmsMaterialMsgs = duplicateWmsMaterials.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} è¡Œï¼š{x.Key}  åç§°é‡å¤");
                var errorMsg = $"导入失败!配置, {string.Join(",", duplicateWmsMaterialMsgs)},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
            #endregion
            foreach (var impItem in importItems)
            {
                if (impItem.MaterialCode.IsNullOrWhiteSpace())
                {
                    continue;
                }
                if (impItem.MaterialCode.IsNullOrWhiteSpace())
                {
                    var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:WmsMaterial名称不能为空";
                    throw new UserFriendlyException(errorMsg);
                }
                var oldWmsMaterial = await wmsMaterialRepository.FindByNameAsync(impItem.MaterialCode);
                if (oldWmsMaterial != null)
                {
                    var wmsMaterialUpdateDto = new WmsMaterialUpdateDto
                    {
                        MaterialCode = impItem.MaterialCode,
                        IsValid = impItem.IsValid,
                        IsSelfMade = impItem.IsSelfMade,
                        Num = impItem.Num,
                        SelfNum = impItem.SelfNum,
                        MaterialName = impItem.MaterialName,
                        NullLength = impItem.NullLength,
                        PurchaseType = impItem.PurchaseType,
                        MaterialType = impItem.MaterialType,
                        PrimaryUnit = impItem.PrimaryUnit,
                        Standard = impItem.Standard,
                        OuterDiameter = impItem.OuterDiameter,
                        WallThickness = impItem.WallThickness,
                        MaterialQuality = impItem.MaterialQuality,
                        Length = impItem.Length,
                        IsMainBranch = impItem.IsMainBranch,
                        Factory = impItem.Factory,
                        Certification = impItem.Certification,
                        RedundantField1 = impItem.RedundantField1,
                        RedundantField2 = impItem.RedundantField2,
                        RedundantField3 = impItem.RedundantField3,
                        Remark = impItem.Remark,
                    };
                    wmsMaterialUpdateDtos.Add((impItem.RowIndex, oldWmsMaterial.Id, wmsMaterialUpdateDto));
                }
                else
                {
                    var wmsMaterialCreateDto = new WmsMaterialCreateDto
                    {
                        MaterialCode = impItem.MaterialCode,
                        IsValid = impItem.IsValid,
                        IsSelfMade = impItem.IsSelfMade,
                        Num = impItem.Num,
                        SelfNum = impItem.SelfNum,
                        MaterialName = impItem.MaterialName,
                        NullLength = impItem.NullLength,
                        PurchaseType = impItem.PurchaseType,
                        MaterialType = impItem.MaterialType,
                        PrimaryUnit = impItem.PrimaryUnit,
                        Standard = impItem.Standard,
                        OuterDiameter = impItem.OuterDiameter,
                        WallThickness = impItem.WallThickness,
                        MaterialQuality = impItem.MaterialQuality,
                        Length = impItem.Length,
                        IsMainBranch = impItem.IsMainBranch,
                        Factory = impItem.Factory,
                        Certification = impItem.Certification,
                        RedundantField1 = impItem.RedundantField1,
                        RedundantField2 = impItem.RedundantField2,
                        RedundantField3 = impItem.RedundantField3,
                        Remark = impItem.Remark,
                    };
                    wmsMaterialCreateDtos.Add((impItem.RowIndex, wmsMaterialCreateDto));
                }
            }
        }
        // æ–°å¢ž 
        foreach (var wmsmaterialsDto in wmsmaterialsCreateDtos)
        {
            try
            {
                await CreateAsync(wmsmaterialsDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{wmsmaterialsDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
        foreach (var wmsMaterialDto in wmsMaterialCreateDtos)
        {
            try
            {
                wmsMaterialDto.Item.CreatorName = myCurrentUser.UserAccount;//创建人
                await CreateAsync(wmsMaterialDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{wmsMaterialDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
        // æ›´æ–° 
        foreach (var wmsmaterialsDto in wmsmaterialsUpdateDtos)
        {
            try
            {
                await UpdateAsync(wmsmaterialsDto.Id, wmsmaterialsDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{wmsmaterialsDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
    }
        foreach (var wmsMaterialDto in wmsMaterialUpdateDtos)
        {
            try
            {
                wmsMaterialDto.Item.LastModifierName = myCurrentUser.UserAccount;//修改人
                await UpdateAsync(wmsMaterialDto.Id, wmsMaterialDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{wmsMaterialDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
    }
    /// <summary> 
    /// å¯¼å‡ºç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    public async Task<(Dictionary<string, object> Sheets, string FileName)> ExportAsync(GetWmsMaterialInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(WmsMaterial.Sort);
        }
    public async Task<(Dictionary<string, object> Sheets, string FileName)> ExportAsync(GetWmsMaterialInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(WmsMaterial.Sort);
        }
        #region åŠ¨æ€æž„é€ æŸ¥è¯¢æ¡ä»¶  
        //动态构造查询条件  
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var list = await wmsmaterialsRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true);
        var result = ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(list);
        var sheets = new Dictionary<string, object>
        {
            ["配置"] = ExportHelper.ConvertListToExportData(result),
        };
        var fileName = result.Count > 1 ? "WmsMaterial列表" : result.Count == 1 ? result[0]?.MaterialCode : "WmsMaterial模版";
        return (sheets, fileName);
    }
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var list = await wmsMaterialRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true);
        var result = ObjectMapper.Map<List<WmsMaterial>, List<WmsMaterialDto>>(list);
        var sheets = new Dictionary<string, object>
        {
            ["配置"] = ExportHelper.ConvertListToExportData(result),
        };
        var fileName = "物料信息";
        return (sheets, fileName);
    }
    /// <summary> 
    /// æ ¡éªŒç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨ï¼Œå½“新建或更新时 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    protected Task CheckCreateOrUpdateDtoAsync(WmsMaterialCreateOrUpdateDtoBase input)
    {
        Check.NotNull(input, nameof(input));
                Check.NotNullOrWhiteSpace(input.MaterialCode, "物料编码(唯一标识)", 64);
    protected Task CheckCreateOrUpdateDtoAsync(WmsMaterialCreateOrUpdateDtoBase input)
    {
        Check.NotNull(input, nameof(input));
        Check.NotNullOrWhiteSpace(input.MaterialCode, "物料编码(唯一标识)", 64);
        Check.NotNull(input.IsValid, "是否有效物料");
        Check.NotNull(input.Num, "数量");
        Check.NotNullOrWhiteSpace(input.MaterialName, "物料名称", 128);
        Check.NotNull(input.PurchaseType, "采购类型(枚举值)");
        Check.NotNull(input.MaterialType, "物料类型(枚举值)");
@@ -441,7 +493,31 @@
        Check.NotNull(input.WallThickness, "壁厚(单位:mm)");
        Check.NotNull(input.Length, "长度(单位:m)");
        Check.NotNull(input.IsMainBranch, "是否为主支管");
        return Task.CompletedTask;
    }
}
        return Task.CompletedTask;
    }
    /// <summary>
    /// æ ¹æ®æ¡ä»¶èŽ·å–ç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨åˆ—è¡¨
    /// </summary>
    /// <param name="whereConditions"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public async Task<List<WmsMaterial>> GetListByFilterAsync(Expression<Func<WmsMaterial, bool>> whereConditions, CancellationToken cancellationToken = default)
    {
        return await wmsMaterialRepository.GetListByFilterAsync(whereConditions);
    }
    /// <summary>
    ///  æ ¹æ®æ¡ä»¶èŽ·å–å•ä¸ªç‰©æ–™åŸºç¡€ä¿¡æ¯è¡¨
    /// </summary>
    /// <param name="whereConditions"></param>
    /// <param name="isMultipleThrowException">是否查询出多条就报错</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="UserFriendlyException"></exception>
    public async Task<WmsMaterial> GetSingleByFilterAsync(Expression<Func<WmsMaterial, bool>> whereConditions, bool is​MultipleThrowException = false, CancellationToken cancellationToken = default)
    {
        return await wmsMaterialRepository.GetSingleByFilterAsync(whereConditions, is​MultipleThrowException);
    }
}