222
schangxiang@126.com
2025-05-11 847e7a89974cb6f5bcfbf7fc8fbe84f085502af6
222
已修改9个文件
917 ■■■■■ 文件已修改
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application.Contracts/Services/ICallMaterialOrderAppService.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/CallMaterialOrderAppService.cs 592 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/SharedService.cs 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/WorkPlanAppService.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Domain/CallMaterialOrder/ICallMaterialOrderRepository.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Domain/WorkPlan/IWorkPlanRepository.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.EntityFrameworkCore/Extensions/CMSPluginEfCoreExtensions.CallMaterialOrderRecord.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.EntityFrameworkCore/Repositories/EfCoreWorkPlanRepository.cs 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems/Controller/CallMaterialOrderController.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application.Contracts/Services/ICallMaterialOrderAppService.cs
@@ -20,8 +20,11 @@
    /// </summary> 
    /// <param name="ids"></param> 
    /// <returns></returns> 
    Task DeleteManyAsync(IEnumerable<Guid> ids);
    Task DeleteManyAsync(IEnumerable<Guid> ids);
     Task CallMaterialByDataIdentifier(Guid id);
    /// <summary> 
    /// 调整排序叫料单表 
    /// </summary> 
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/CallMaterialOrderAppService.cs
@@ -1,127 +1,135 @@
using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.CallMaterialOrder;
using CMS.Plugin.PipeLineLems.Application.Contracts.Services;
using CMS.Plugin.PipeLineLems.Domain.Shared;
using CmsQueryExtensions;
using CMS.Plugin.PipeLineLems.Domain.CallMaterialOrder;
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;
using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.CallMaterialOrder;
using CMS.Plugin.PipeLineLems.Application.Contracts.Services;
using CMS.Plugin.PipeLineLems.Domain.Shared;
using CmsQueryExtensions;
using CMS.Plugin.PipeLineLems.Domain.CallMaterialOrder;
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;
/// <summary> 
/// 叫料单表应用服务 
/// </summary> 
public class CallMaterialOrderAppService : CMSPluginAppService, ICallMaterialOrderAppService
{
    private readonly ICallMaterialOrderRepository callMaterialOrderRepository;
public class CallMaterialOrderAppService : CMSPluginAppService, ICallMaterialOrderAppService
{
    private readonly ICallMaterialOrderRepository callMaterialOrderRepository;
    private readonly SharedService _sharedService;
    private readonly IServiceProvider _serviceProvider;
    /// <summary> 
    /// Initializes a new instance of the <see cref="CallMaterialOrderAppService"/> class. 
    /// </summary> 
    /// <param name="CallMaterialOrderRepository">The task job repository.</param> 
    public CallMaterialOrderAppService(ICallMaterialOrderRepository _CallMaterialOrderRepository)
    {
        callMaterialOrderRepository = _CallMaterialOrderRepository;
    }
    public CallMaterialOrderAppService(ICallMaterialOrderRepository _CallMaterialOrderRepository, SharedService sharedService, IServiceProvider serviceProvider)
    {
        callMaterialOrderRepository = _CallMaterialOrderRepository;
        _sharedService = sharedService;
        _serviceProvider = serviceProvider;
    }
    /// <summary> 
    /// 获取指定叫料单表 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public virtual async Task<CallMaterialOrderDto> GetAsync(Guid id)
    {
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(await callMaterialOrderRepository.GetAsync(id));
    }
    public virtual async Task<CallMaterialOrderDto> GetAsync(Guid id)
    {
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(await callMaterialOrderRepository.GetAsync(id));
    }
    public virtual async Task CallMaterialByDataIdentifier(Guid id)
    {
        await _sharedService.CallMaterialByDataIdentifier(id, _serviceProvider);
    }
    /// <summary> 
    /// 分页获取叫料单表 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    public virtual async Task<PagedResultDto<CallMaterialOrderDto>> GetListAsync(GetCallMaterialOrderInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(CallMaterialOrder.Sort);
        }
    public virtual async Task<PagedResultDto<CallMaterialOrderDto>> GetListAsync(GetCallMaterialOrderInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(CallMaterialOrder.Sort);
        }
        #region 动态构造查询条件  
        //动态构造查询条件  
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var count = await callMaterialOrderRepository.GetCountAsync(whereConditions);
        var list = await callMaterialOrderRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount);
        return new PagedResultDto<CallMaterialOrderDto>(count, ObjectMapper.Map<List<CallMaterialOrder>, List<CallMaterialOrderDto>>(list));
    }
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var count = await callMaterialOrderRepository.GetCountAsync(whereConditions);
        var list = await callMaterialOrderRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount);
        return new PagedResultDto<CallMaterialOrderDto>(count, ObjectMapper.Map<List<CallMaterialOrder>, List<CallMaterialOrderDto>>(list));
    }
    /// <summary>  
    /// 动态构造查询条件  
    /// </summary>  
    /// <param name="input">输入参数</param>  
    /// <returns></returns>  
    private FunReturnResultModel<Expression<Func<CallMaterialOrder, bool>>> DynamicGetQueryParams(GetCallMaterialOrderInput input)
    {
    private FunReturnResultModel<Expression<Func<CallMaterialOrder, bool>>> DynamicGetQueryParams(GetCallMaterialOrderInput input)
    {
        //动态构造查询条件  
        var whereConditions = WhereConditionsExtensions.GetWhereConditions<CallMaterialOrder, GetCallMaterialOrderInput>(input);
        if (!whereConditions.IsSuccess)
        {
            throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg);
        }
        var whereConditions = WhereConditionsExtensions.GetWhereConditions<CallMaterialOrder, GetCallMaterialOrderInput>(input);
        if (!whereConditions.IsSuccess)
        {
            throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg);
        }
        //也可再次自定义构建查询条件  
        Expression<Func<CallMaterialOrder, bool>> extendExpression = a => a.IsDeleted == false;
        Expression<Func<CallMaterialOrder, bool>> extendExpression = a => a.IsDeleted == false;
        // 使用 System.Linq.PredicateBuilder 的 And 
        var pres = (System.Linq.Expressions.Expression<Func<CallMaterialOrder, bool>>)(whereConditions.data);
        whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression);
        return whereConditions;
    }
        var pres = (System.Linq.Expressions.Expression<Func<CallMaterialOrder, 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<CallMaterialOrderDto> CreateAsync(CallMaterialOrderCreateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var exist = await callMaterialOrderRepository.NameExistAsync(input.DataIdentifier);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.DataIdentifier]);
        }
        var maxSort = await callMaterialOrderRepository.GetMaxSortAsync();
        var sort = input.Sort ?? maxSort;
        var insertObj = ObjectMapper.Map<CallMaterialOrderCreateDto, CallMaterialOrder>(input);
        insertObj.Sort = sort;
        input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None);
        await callMaterialOrderRepository.InsertAsync(insertObj);
    public virtual async Task<CallMaterialOrderDto> CreateAsync(CallMaterialOrderCreateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var exist = await callMaterialOrderRepository.NameExistAsync(input.DataIdentifier);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.DataIdentifier]);
        }
        var maxSort = await callMaterialOrderRepository.GetMaxSortAsync();
        var sort = input.Sort ?? maxSort;
        var insertObj = ObjectMapper.Map<CallMaterialOrderCreateDto, CallMaterialOrder>(input);
        insertObj.Sort = sort;
        input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None);
        await callMaterialOrderRepository.InsertAsync(insertObj);
        //if (input.Sort.HasValue && insertObj.Sort != maxSort) 
        //{ 
        //    await AdjustSortAsync(insertObj.Id, insertObj.Sort); 
        //} 
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(insertObj);
    }
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(insertObj);
    }
    /// <summary> 
    /// 更新叫料单表 
    /// </summary> 
@@ -129,41 +137,41 @@
    /// <param name="input"></param> 
    /// <returns></returns> 
    /// <exception cref="UserFriendlyException"></exception> 
    public virtual async Task<CallMaterialOrderDto> UpdateAsync(Guid id, CallMaterialOrderUpdateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var updateObj = await callMaterialOrderRepository.GetAsync(id);
        var exist = await callMaterialOrderRepository.NameExistAsync(input.DataIdentifier, updateObj.Id);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.DataIdentifier]);
        }
        updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
        input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None);
                updateObj.DataIdentifier = input.DataIdentifier;
    public virtual async Task<CallMaterialOrderDto> UpdateAsync(Guid id, CallMaterialOrderUpdateDto input)
    {
        await CheckCreateOrUpdateDtoAsync(input);
        var updateObj = await callMaterialOrderRepository.GetAsync(id);
        var exist = await callMaterialOrderRepository.NameExistAsync(input.DataIdentifier, updateObj.Id);
        if (exist)
        {
            throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.DataIdentifier]);
        }
        updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
        input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None);
        updateObj.DataIdentifier = input.DataIdentifier;
        updateObj.MaterialMode = input.MaterialMode;
        updateObj.CallMaterialStatus = input.CallMaterialStatus;
        updateObj.Quantity = input.Quantity;
        updateObj.WmsRetResult = input.WmsRetResult;
        updateObj.WmsTaskNo = input.WmsTaskNo;
        updateObj.Remark = input.Remark;
        await callMaterialOrderRepository.UpdateAsync(updateObj);
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(updateObj);
    }
        await callMaterialOrderRepository.UpdateAsync(updateObj);
        return ObjectMapper.Map<CallMaterialOrder, CallMaterialOrderDto>(updateObj);
    }
    /// <summary> 
    /// 克隆叫料单表 
    /// </summary> 
    /// <param name="ids"></param> 
    /// <returns></returns> 
    public async Task<List<CallMaterialOrderDto>> CloneAsync(IEnumerable<Guid> ids)
    {
    public async Task<List<CallMaterialOrderDto>> CloneAsync(IEnumerable<Guid> ids)
    {
        //var callMaterialOrders = new List<CallMaterialOrder>(); 
        //if (ids != null) 
        //{ 
@@ -183,234 +191,234 @@
        //                    name += CallMaterialOrderConsts.CloneTag; 
        //                    continue; 
        //                } 
        //                notExist = true; 
        //            } 
        //            //CallMaterialOrder = await callMaterialOrderRepository.InsertAsync(CallMaterialOrder.Clone(GuidGenerator.Create(), name, sort++)); 
        //            callMaterialOrders.Add(CallMaterialOrder); 
        //        } 
        //    } 
        //} 
        //return ObjectMapper.Map<List<CallMaterialOrder>, List<CallMaterialOrderDto>>(callMaterialOrders); 
        return new List<CallMaterialOrderDto>();
    }
        return new List<CallMaterialOrderDto>();
    }
    /// <summary> 
    /// 删除单个叫料单表 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public virtual Task DeleteAsync(Guid id)
    {
        return callMaterialOrderRepository.DeleteAsync(id);
    }
    public virtual Task DeleteAsync(Guid id)
    {
        return callMaterialOrderRepository.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)
    {
        foreach (var id in ids)
        {
            await DeleteAsync(id);
        }
    }
    /// <summary> 
    /// 调整排序叫料单表 
    /// </summary> 
    /// <param name="id"></param> 
    /// <param name="sort"></param> 
    /// <returns></returns> 
    public virtual async Task AdjustSortAsync(Guid id, int sort)
    {
        var list = await callMaterialOrderRepository.GetListAsync(null, nameof(CallMaterialOrder.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 callMaterialOrderRepository.UpdateManyAsync(list);
    }
    public virtual async Task AdjustSortAsync(Guid id, int sort)
    {
        var list = await callMaterialOrderRepository.GetListAsync(null, nameof(CallMaterialOrder.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 callMaterialOrderRepository.UpdateManyAsync(list);
    }
    /// <summary> 
    /// 导入叫料单表 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    /// <exception cref="UserFriendlyException"></exception> 
    public async Task ImportAsync(CallMaterialOrdersImportModel input)
    {
        Check.NotNull(input, nameof(input));
        var callMaterialOrderCreateDtos = new List<(int RowIndex, CallMaterialOrderCreateDto Item)>();
        var callMaterialOrderUpdateDtos = new List<(int RowIndex, Guid Id, CallMaterialOrderUpdateDto Item)>();
        var importItems = input.CallMaterialOrders;
        if (importItems != null && importItems.Any())
        {
    public async Task ImportAsync(CallMaterialOrdersImportModel input)
    {
        Check.NotNull(input, nameof(input));
        var callMaterialOrderCreateDtos = new List<(int RowIndex, CallMaterialOrderCreateDto Item)>();
        var callMaterialOrderUpdateDtos = new List<(int RowIndex, Guid Id, CallMaterialOrderUpdateDto Item)>();
        var importItems = input.CallMaterialOrders;
        if (importItems != null && importItems.Any())
        {
            #region 导入校验 
            // 判断名称是否重复,并输出第几行重复 
            var duplicateCallMaterialOrders = importItems.GroupBy(x => x.DataIdentifier).Where(x => x.Count() > 1).ToList();
            if (duplicateCallMaterialOrders?.Any() == true)
            {
                var duplicateCallMaterialOrderMsgs = duplicateCallMaterialOrders.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} 行:{x.Key}  名称重复");
                var errorMsg = $"导入失败!配置, {string.Join(",", duplicateCallMaterialOrderMsgs)},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
            #endregion
            foreach (var impItem in importItems)
            {
                if (impItem.DataIdentifier.IsNullOrWhiteSpace())
                {
                    continue;
                }
                if (impItem.DataIdentifier.IsNullOrWhiteSpace())
                {
                    var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:CallMaterialOrder名称不能为空";
                    throw new UserFriendlyException(errorMsg);
                }
                var oldCallMaterialOrder = await callMaterialOrderRepository.FindByNameAsync(impItem.DataIdentifier);
                if (oldCallMaterialOrder != null)
                {
                    var callMaterialOrderUpdateDto = new CallMaterialOrderUpdateDto
                    {
            var duplicateCallMaterialOrders = importItems.GroupBy(x => x.DataIdentifier).Where(x => x.Count() > 1).ToList();
            if (duplicateCallMaterialOrders?.Any() == true)
            {
                var duplicateCallMaterialOrderMsgs = duplicateCallMaterialOrders.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} 行:{x.Key}  名称重复");
                var errorMsg = $"导入失败!配置, {string.Join(",", duplicateCallMaterialOrderMsgs)},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
            #endregion
            foreach (var impItem in importItems)
            {
                if (impItem.DataIdentifier.IsNullOrWhiteSpace())
                {
                    continue;
                }
                if (impItem.DataIdentifier.IsNullOrWhiteSpace())
                {
                    var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:CallMaterialOrder名称不能为空";
                    throw new UserFriendlyException(errorMsg);
                }
                var oldCallMaterialOrder = await callMaterialOrderRepository.FindByNameAsync(impItem.DataIdentifier);
                if (oldCallMaterialOrder != null)
                {
                    var callMaterialOrderUpdateDto = new CallMaterialOrderUpdateDto
                    {
                        DataIdentifier = impItem.DataIdentifier,
MaterialMode = impItem.MaterialMode,
CallMaterialStatus = impItem.CallMaterialStatus,
Quantity = impItem.Quantity,
WmsRetResult = impItem.WmsRetResult,
WmsTaskNo = impItem.WmsTaskNo,
Remark = impItem.Remark,
                    };
                    callMaterialOrderUpdateDtos.Add((impItem.RowIndex, oldCallMaterialOrder.Id, callMaterialOrderUpdateDto));
                }
                else
                {
                    var callMaterialOrderCreateDto = new CallMaterialOrderCreateDto
                    {
                        MaterialMode = impItem.MaterialMode,
                        CallMaterialStatus = impItem.CallMaterialStatus,
                        Quantity = impItem.Quantity,
                        WmsRetResult = impItem.WmsRetResult,
                        WmsTaskNo = impItem.WmsTaskNo,
                        Remark = impItem.Remark,
                    };
                    callMaterialOrderUpdateDtos.Add((impItem.RowIndex, oldCallMaterialOrder.Id, callMaterialOrderUpdateDto));
                }
                else
                {
                    var callMaterialOrderCreateDto = new CallMaterialOrderCreateDto
                    {
                        DataIdentifier = impItem.DataIdentifier,
MaterialMode = impItem.MaterialMode,
CallMaterialStatus = impItem.CallMaterialStatus,
Quantity = impItem.Quantity,
WmsRetResult = impItem.WmsRetResult,
WmsTaskNo = impItem.WmsTaskNo,
Remark = impItem.Remark,
                    };
                    callMaterialOrderCreateDtos.Add((impItem.RowIndex, callMaterialOrderCreateDto));
                }
            }
        }
                        MaterialMode = impItem.MaterialMode,
                        CallMaterialStatus = impItem.CallMaterialStatus,
                        Quantity = impItem.Quantity,
                        WmsRetResult = impItem.WmsRetResult,
                        WmsTaskNo = impItem.WmsTaskNo,
                        Remark = impItem.Remark,
                    };
                    callMaterialOrderCreateDtos.Add((impItem.RowIndex, callMaterialOrderCreateDto));
                }
            }
        }
        // 新增 
        foreach (var callMaterialOrderDto in callMaterialOrderCreateDtos)
        {
            try
            {
                await CreateAsync(callMaterialOrderDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{callMaterialOrderDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
        foreach (var callMaterialOrderDto in callMaterialOrderCreateDtos)
        {
            try
            {
                await CreateAsync(callMaterialOrderDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{callMaterialOrderDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
        // 更新 
        foreach (var callMaterialOrderDto in callMaterialOrderUpdateDtos)
        {
            try
            {
                await UpdateAsync(callMaterialOrderDto.Id, callMaterialOrderDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{callMaterialOrderDto.RowIndex}行:{e.Message},终止导入";
                throw new UserFriendlyException(errorMsg);
            }
        }
    }
        foreach (var callMaterialOrderDto in callMaterialOrderUpdateDtos)
        {
            try
            {
                await UpdateAsync(callMaterialOrderDto.Id, callMaterialOrderDto.Item);
            }
            catch (Exception e)
            {
                var errorMsg = $"导入失败!配置,第{callMaterialOrderDto.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(GetCallMaterialOrderInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(CallMaterialOrder.Sort);
        }
    public async Task<(Dictionary<string, object> Sheets, string FileName)> ExportAsync(GetCallMaterialOrderInput input)
    {
        Check.NotNull(input, nameof(input));
        if (input.Sorting.IsNullOrWhiteSpace())
        {
            input.Sorting = nameof(CallMaterialOrder.Sort);
        }
        #region 动态构造查询条件  
        //动态构造查询条件  
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var list = await callMaterialOrderRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true);
        var result = ObjectMapper.Map<List<CallMaterialOrder>, List<CallMaterialOrderDto>>(list);
        var sheets = new Dictionary<string, object>
        {
            ["配置"] = ExportHelper.ConvertListToExportData(result),
        };
        var fileName = "叫料单";
        return (sheets, fileName);
    }
        var whereConditions = DynamicGetQueryParams(input);
        #endregion
        var list = await callMaterialOrderRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true);
        var result = ObjectMapper.Map<List<CallMaterialOrder>, List<CallMaterialOrderDto>>(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(CallMaterialOrderCreateOrUpdateDtoBase input)
    {
        Check.NotNull(input, nameof(input));
                Check.NotNullOrWhiteSpace(input.DataIdentifier, "原料标识", 256);
    protected Task CheckCreateOrUpdateDtoAsync(CallMaterialOrderCreateOrUpdateDtoBase input)
    {
        Check.NotNull(input, nameof(input));
        Check.NotNullOrWhiteSpace(input.DataIdentifier, "原料标识", 256);
        Check.NotNull(input.CallMaterialStatus, "叫料状态");
        Check.NotNull(input.Quantity, "叫料数量");
        return Task.CompletedTask;
    }
}
        return Task.CompletedTask;
    }
}
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/SharedService.cs
@@ -12,6 +12,9 @@
using CMS.Plugin.PipeLineLems.Application.Contracts.Services;
using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.CallMaterialOrder;
using Volo.Abp.Uow;
using System.Text;
using CMS.Plugin.PipeLineLems.Domain.WorkPlan;
using CMS.Plugin.PipeLineLems.Domain.CallMaterialOrderRecord;
namespace CMS.Plugin.PipeLineLems.Application.Implements;
@@ -20,6 +23,14 @@
/// </summary> 
public class SharedService : CMSPluginAppService
{
    /// <summary>
    /// 创建作业计划
    /// </summary>
    /// <param name="input"></param>
    /// <param name="_serviceProvider"></param>
    /// <param name="workPlanAppService"></param>
    /// <returns></returns>
    /// <exception cref="UserFriendlyException"></exception>
    public async Task<MesOrderResponse> CommonCreatebyApsAsync(List<WorkPlanInput> input, IServiceProvider _serviceProvider,
        WorkPlanAppService workPlanAppService
@@ -191,12 +202,12 @@
        }
        catch (Exception)
        {
            await uow.RollbackAsync();
            throw;
        }
        finally
        {
            await uow.RollbackAsync();
        }
@@ -255,4 +266,107 @@
        return (true, string.Empty);
    }
    /// <summary>
    /// 根据原料标识进行叫料操作
    /// </summary>
    /// <param name="dataIdentifier">原料标识</param>
    /// <param name="_serviceProvider">服务提供者</param>
    /// <returns>操作结果</returns>
    /// <exception cref="UserFriendlyException">当数据不存在或状态不允许叫料时抛出</exception>
    public async Task<MesOrderResponse> CallMaterialByDataIdentifier(Guid id, IServiceProvider _serviceProvider)
    {
        if (string.IsNullOrEmpty(id.ToString()))
        {
            throw new UserFriendlyException("原料标识不能为空");
        }
        var callMaterialOrderRepository = _serviceProvider.GetRequiredService<ICallMaterialOrderRepository>();
        var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
        var callMaterialOrderRecordRepository = _serviceProvider.GetRequiredService<ICallMaterialOrderRecordRepository>();
        var orderManager = _serviceProvider.GetRequiredService<IOrderManager>();
        // 查找数据
        var callMaterialOrder = await callMaterialOrderRepository.GetAsync(id);
        if (callMaterialOrder == null)
        {
            throw new UserFriendlyException($"找不到叫料记录");
        }
        // 验证状态
        //if (callMaterialOrder.CallMaterialStatus != Domain.Shared.Enums.CallMaterialStatusEnum.未执行)
        //{
        //    throw new UserFriendlyException($"原料标识为 '{callMaterialOrder.DataIdentifier}' 的叫料记录状态为 '{callMaterialOrder.CallMaterialStatus}',不允许叫料");
        //}
        // 更新数据
        callMaterialOrder.WmsRetResult = "成功";
        callMaterialOrder.WmsTaskNo = GenerateRandomTaskNo();
        callMaterialOrder.CallMaterialStatus = Domain.Shared.Enums.CallMaterialStatusEnum.叫料完成;
        callMaterialOrder.LastModifierName = "SuperAdmin";
        await callMaterialOrderRepository.UpdateAsync(callMaterialOrder);
        //更新作业计划表
        var workPlanList = await workPlanRepository.FindByDataIdentifierAsync(callMaterialOrder.DataIdentifier);
        foreach (var item in workPlanList)
        {
            item.CallMaterialStatus = Domain.Shared.Enums.CallMaterialStatusEnum.叫料完成;
            item.LastModifierName = "SuperAdmin";
        }
        await workPlanRepository.UpdateManyAsync(workPlanList);
        //新增叫料记录表
        var callMaterialOrderRecord = new CallMaterialOrderRecord()
        {
            CallMaterialStatus = Domain.Shared.Enums.CallMaterialStatusEnum.叫料完成,
            MaterialMode = callMaterialOrder.MaterialMode,
            DataIdentifier = callMaterialOrder.DataIdentifier,
            Quantity = 1,
            WmsRetResult = callMaterialOrder.WmsRetResult,
            WmsTaskNo = callMaterialOrder.WmsTaskNo,
            CreatorName = "SuperAdmin"
        };
        await callMaterialOrderRecordRepository.InsertAsync(callMaterialOrderRecord);
        //更新工单表的状态
        var pipeSpecCodeList = workPlanList.Select(x => x.PipeSpecCode).Distinct().ToList();
        foreach (var item in pipeSpecCodeList)
        {
            var prodOrderNo = "Order_" + item;
            var order = await orderManager.GetByCodeAsync(prodOrderNo);
            if (order != null)
            {
                order.ExtraProperties["CallMaterialStatus"] = Domain.Shared.Enums.CallMaterialStatusEnum.叫料完成.ToString();
            }
            await orderManager.UpdateAsync(order);
        }
        // 返回结果
        var response = new MesOrderResponse
        {
            Code = "000000",
            Fail = false,
            Mesg = "叫料成功",
            Success = true,
            Time = DateTime.UtcNow
        };
        return response;
    }
    /// <summary>
    /// 生成随机的WmsTaskNo
    /// </summary>
    /// <returns>随机生成的任务编号</returns>
    private string GenerateRandomTaskNo()
    {
        // 获取当前时间戳(从1970-01-01 00:00:00 UTC到现在的秒数)
        long timestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        // 生成前缀
        return $"WMS{timestamp}";
    }
}
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Application/Implements/WorkPlanAppService.cs
@@ -113,6 +113,7 @@
        var insertObj = ObjectMapper.Map<WorkPlanCreateDto, WorkPlan>(input);
        insertObj.Sort = sort;
        insertObj.CreatorName = "SuperAdmin";
        input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None);
        await workPlanRepository.InsertAsync(insertObj);
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Domain/CallMaterialOrder/ICallMaterialOrderRepository.cs
@@ -29,8 +29,11 @@
    /// 获取最大排序叫料单表 
    /// </summary> 
    /// <returns></returns> 
    Task<int> GetMaxSortAsync();
    Task<int> GetMaxSortAsync();
    /// <summary> 
    /// 获取分页列表叫料单表 
    /// </summary> 
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.Domain/WorkPlan/IWorkPlanRepository.cs
@@ -23,14 +23,23 @@
    /// <param name="name"></param> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    Task<bool> NameExistAsync(string name, Guid? id = null);
    Task<bool> NameExistAsync(string name, Guid? id = null);
    /// <summary> 
    /// 获取最大排序作业计划表 
    /// </summary> 
    /// <returns></returns> 
    Task<int> GetMaxSortAsync();
    Task<int> GetMaxSortAsync();
    /// <summary>
    /// 按照 原料标记 查找作业计划表
    /// </summary>
    /// <param name="name"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<List<WorkPlan>> FindByDataIdentifierAsync(string dataIdentifier, CancellationToken cancellationToken = default);
    /// <summary> 
    /// 获取分页列表作业计划表 
    /// </summary> 
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.EntityFrameworkCore/Extensions/CMSPluginEfCoreExtensions.CallMaterialOrderRecord.cs
@@ -56,7 +56,6 @@
            b.ConfigureMyCmsEntityForRecord();
            // Configure indexes
            b.HasIndex(u => u.DataIdentifier).IsUnique();
            b.HasIndex(u => u.DataIdentifier);
            b.ApplyObjectExtensionMappings();
PipeLineLems/server/src/CMS.Plugin.PipeLineLems.EntityFrameworkCore/Repositories/EfCoreWorkPlanRepository.cs
@@ -1,73 +1,90 @@
using CMS.Plugin.PipeLineLems.Domain.WorkPlan;
using CMS.Plugin.PipeLineLems.EntityFrameworkCore.Extensions;
using CmsQueryExtensions.Extension;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace CMS.Plugin.PipeLineLems.EntityFrameworkCore.Repositories;
using CMS.Plugin.PipeLineLems.Domain.WorkPlan;
using CMS.Plugin.PipeLineLems.EntityFrameworkCore.Extensions;
using CmsQueryExtensions.Extension;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace CMS.Plugin.PipeLineLems.EntityFrameworkCore.Repositories;
/// <summary> 
/// 作业计划表仓储实现 
/// </summary> 
public class EfCoreWorkPlanRepository : EfCoreRepository<ICMSPluginDbContext, WorkPlan, Guid>, IWorkPlanRepository
{
public class EfCoreWorkPlanRepository : EfCoreRepository<ICMSPluginDbContext, WorkPlan, Guid>, IWorkPlanRepository
{
    /// <summary> 
    /// Initializes a new instance of the <see cref="EfCoreWorkPlanRepository"/> class. 
    /// </summary> 
    /// <param name="dbContextProvider">The database context provider.</param> 
    public EfCoreWorkPlanRepository(IDbContextProvider<ICMSPluginDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }
    public EfCoreWorkPlanRepository(IDbContextProvider<ICMSPluginDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }
    /// <summary> 
    /// 按照名称查找作业计划表 
    /// </summary> 
    /// <param name="name"></param> 
    /// <param name="cancellationToken"></param> 
    /// <returns></returns> 
    public virtual async Task<WorkPlan> FindByNameAsync(string name, CancellationToken cancellationToken = default)
    {
        return await (await GetDbSetAsync())
            .IncludeDetails()
            .Where(x => !x.IsDeleted)
            .OrderByDescending(x=>x.CreationTime)
            .FirstOrDefaultAsync(t => t.TaskCode == name, GetCancellationToken(cancellationToken));
    }
    public virtual async Task<WorkPlan> FindByNameAsync(string name, CancellationToken cancellationToken = default)
    {
        return await (await GetDbSetAsync())
            .IncludeDetails()
            .Where(x => !x.IsDeleted)
            .OrderByDescending(x => x.CreationTime)
            .FirstOrDefaultAsync(t => t.TaskCode == name, GetCancellationToken(cancellationToken));
    }
    /// <summary>
    /// 按照 原料标记 查找作业计划表
    /// </summary>
    /// <param name="name"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task<List<WorkPlan>> FindByDataIdentifierAsync(string dataIdentifier, CancellationToken cancellationToken = default)
    {
        return await (await GetDbSetAsync())
            .IncludeDetails()
            .Where(x => !x.IsDeleted)
            .Where(t => t.DataIdentifier == dataIdentifier)
            .OrderByDescending(x => x.CreationTime)
             .ToListAsync(GetCancellationToken(cancellationToken));
    }
    /// <summary> 
    /// 验证名称是否存在作业计划表 
    /// </summary> 
    /// <param name="name">校验值</param> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public async Task<bool> NameExistAsync(string name, Guid? id = null)
    {
        return await (await GetDbSetAsync()).WhereIf(id.HasValue, p => p.Id != id).Where(x => !x.IsDeleted).AnyAsync(x => x.TaskCode == name);
    }
    public async Task<bool> NameExistAsync(string name, Guid? id = null)
    {
        return await (await GetDbSetAsync()).WhereIf(id.HasValue, p => p.Id != id).Where(x => !x.IsDeleted).AnyAsync(x => x.TaskCode == name);
    }
    /// <summary> 
    /// 获取最大排序作业计划表 
    /// </summary> 
    /// <returns></returns> 
    public async Task<int> GetMaxSortAsync()
    {
        var hasAny = await (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).AnyAsync();
        if (!hasAny)
        {
            return 1;
        }
        var sort = await (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).MaxAsync(x => x.Sort);
        return sort + 1;
    }
    public async Task<int> GetMaxSortAsync()
    {
        var hasAny = await (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).AnyAsync();
        if (!hasAny)
        {
            return 1;
        }
        var sort = await (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).MaxAsync(x => x.Sort);
        return sort + 1;
    }
    /// <summary> 
    /// 获取分页列表作业计划表 
    /// </summary> 
@@ -78,36 +95,36 @@
    /// <param name="includeDetails"></param> 
    /// <param name="cancellationToken"></param> 
    /// <returns></returns> 
    public async Task<List<WorkPlan>> GetListAsync(FunReturnResultModel<Expression<Func<WorkPlan, bool>>> whereConditions, string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, bool includeDetails = false, CancellationToken cancellationToken = default)
    {
        return await (await GetDbSetAsync())
            .IncludeDetails(includeDetails)
            .WhereIf(whereConditions != null, whereConditions.data)
            .Where(x => !x.IsDeleted)
            .OrderByDescending(x=>x.CreationTime)
            .PageBy(skipCount, maxResultCount)
            .ToListAsync(GetCancellationToken(cancellationToken));
    }
    public async Task<List<WorkPlan>> GetListAsync(FunReturnResultModel<Expression<Func<WorkPlan, bool>>> whereConditions, string sorting = null, int maxResultCount = int.MaxValue, int skipCount = 0, bool includeDetails = false, CancellationToken cancellationToken = default)
    {
        return await (await GetDbSetAsync())
            .IncludeDetails(includeDetails)
            .WhereIf(whereConditions != null, whereConditions.data)
            .Where(x => !x.IsDeleted)
            .OrderByDescending(x => x.CreationTime)
            .PageBy(skipCount, maxResultCount)
            .ToListAsync(GetCancellationToken(cancellationToken));
    }
    /// <summary> 
    /// 获取总数作业计划表 
    /// </summary> 
    /// <param name="whereConditions"></param> 
    /// <param name="cancellationToken"></param> 
    /// <returns></returns> 
    public async Task<long> GetCountAsync(FunReturnResultModel<Expression<Func<WorkPlan, bool>>> whereConditions, CancellationToken cancellationToken = default)
    {
        return await (await GetQueryableAsync())
            .WhereIf(whereConditions != null, whereConditions.data)
            .Where(x => !x.IsDeleted)
            .CountAsync(cancellationToken: GetCancellationToken(cancellationToken));
    }
    public async Task<long> GetCountAsync(FunReturnResultModel<Expression<Func<WorkPlan, bool>>> whereConditions, CancellationToken cancellationToken = default)
    {
        return await (await GetQueryableAsync())
            .WhereIf(whereConditions != null, whereConditions.data)
            .Where(x => !x.IsDeleted)
            .CountAsync(cancellationToken: GetCancellationToken(cancellationToken));
    }
    /// <inheritdoc /> 
    public override async Task<IQueryable<WorkPlan>> WithDetailsAsync()
    {
        return (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).IncludeDetails();
    }
}
    public override async Task<IQueryable<WorkPlan>> WithDetailsAsync()
    {
        return (await GetQueryableAsync())
            .Where(x => !x.IsDeleted).IncludeDetails();
    }
}
PipeLineLems/server/src/CMS.Plugin.PipeLineLems/Controller/CallMaterialOrderController.cs
@@ -44,8 +44,15 @@
        public virtual Task<CallMaterialOrderDto> GetAsync(Guid id) 
        { 
            return _callMaterialOrderAppService.GetAsync(id); 
        }
        }
        [HttpPut]
        [Route("CallMaterialByDataIdentifier/{id}")]
        public virtual Task CallMaterialByDataIdentifier(Guid id)
        {
            return _callMaterialOrderAppService.CallMaterialByDataIdentifier(id);
        }
        /// <summary> 
        /// 分页获取叫料单表的列表. 
        /// </summary>