diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/DTOs/SafetyStockBalancesDto.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/DTOs/SafetyStockBalancesDto.cs
new file mode 100644
index 000000000..708f52d0c
--- /dev/null
+++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/DTOs/SafetyStockBalancesDto.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using DocumentFormat.OpenXml.Wordprocessing;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Wms.Inventory.Application.Contracts;
+using Win_in.Sfs.Wms.Inventory.Domain;
+
+namespace Win_in.Sfs.Wms.Inventory;
+public class SafetyStockBalancesDto: SfsBasicDTOBase
+{
+ ///
+ /// 物品代码
+ ///
+ [Display(Name = "物品代码")]
+ public string ItemCode { get; set; }
+
+ ///
+ /// 仓库代码
+ ///
+ [Display(Name = "仓库代码")]
+ public string WarehouseCode { get; set; }
+
+ ///
+ /// 存储关系类型
+ ///
+ [Display(Name = "存储关系类型")]
+ public EnumStoreRelationType StoreRelationType { get; set; }
+
+ ///
+ /// 存储关系代码
+ ///
+ [Display(Name = "存储关系代码")]
+ public string StoreValue { get; set; }
+
+ ///
+ /// 最大库存
+ ///
+ [Display(Name = "最大库存")]
+ public decimal MaxStock { get; set; }
+
+ ///
+ /// 最小库存
+ ///
+ [Display(Name = "最小库存")]
+ public decimal MinStock { get; set; }
+
+ ///
+ /// 安全库存
+ ///
+ [Display(Name = "安全库存")]
+ public decimal SafetyStock { get; set; }
+
+ ///
+ /// 安全库存状态
+ ///
+ [Display(Name = "安全库存状态")]
+ public string SafetyStockStatus { get; set; }
+
+ public List BalancesDtos { get; set; } = new List();
+}
diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/ISafetyStockBalancesAppservice.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/ISafetyStockBalancesAppservice.cs
new file mode 100644
index 000000000..a88272e4b
--- /dev/null
+++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/SafetyStockBalances/ISafetyStockBalancesAppservice.cs
@@ -0,0 +1,12 @@
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Win_in.Sfs.Basedata.Application.Contracts;
+
+namespace Win_in.Sfs.Wms.Inventory.Application.Contracts;
+
+public interface
+ ISafetyStockBalancesAppservice : ISfsInventoryCrudAppServiceBase
+{
+ Task> GetPagedListByFilterAsync(
+ SfsBaseDataRequestInputBase sfsBaseDataRequestInputBase);
+}
diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/SafetyStockBalances/SafetyStockBalancesAppservice.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/SafetyStockBalances/SafetyStockBalancesAppservice.cs
new file mode 100644
index 000000000..f96387e77
--- /dev/null
+++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/SafetyStockBalances/SafetyStockBalancesAppservice.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp.Application.Dtos;
+using Win_in.Sfs.Basedata.Application.Contracts;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Wms.Inventory.Application;
+using Win_in.Sfs.Wms.Inventory.Application.Contracts;
+using Win_in.Sfs.Wms.Inventory.Domain;
+using Win_in.Sfs.Wms.Inventory.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Inventory;
+
+///
+/// 安全库存
+///
+[Route($"{InventoryConsts.RootPath}safety-stock-inventory-balance")]
+[ApiExplorerSettings(GroupName = nameof(Inventory))]
+public class SafetyStockBalancesAppservice : SfsInventoryAppServiceBase, ISafetyStockBalancesAppservice
+{
+ private readonly IItemSafetyStockAppService _itemSafetyStockAppService;
+ private readonly IBalanceAppService _balanceAppService;
+
+ public SafetyStockBalancesAppservice(IBalanceRepository repository,
+ IItemSafetyStockAppService itemSafetyStockAppService,
+ IBalanceAppService balanceAppService) : base(repository)
+ {
+ _itemSafetyStockAppService = itemSafetyStockAppService;
+ _balanceAppService = balanceAppService;
+ }
+
+ [HttpPost("list-page")]
+ public async Task> GetPagedListByFilterAsync(
+ SfsBaseDataRequestInputBase sfsBaseDataRequestInputBase)
+ {
+ var pagedResultDto = new PagedResultDto();
+
+ var resultDto = await _itemSafetyStockAppService.GetPagedListByFilterAsync(sfsBaseDataRequestInputBase)
+ .ConfigureAwait(false);
+
+ pagedResultDto.TotalCount = resultDto.TotalCount;
+
+ var stockBalancesDtos = new List();
+ foreach (var stockDto in resultDto.Items)
+ {
+ var safetyStockBalancesDto = new SafetyStockBalancesDto();
+ safetyStockBalancesDto.Id = stockDto.Id;
+ safetyStockBalancesDto.ItemCode = stockDto.ItemCode;
+ safetyStockBalancesDto.StoreValue=stockDto.StoreValue;
+ safetyStockBalancesDto.MaxStock=stockDto.MaxStock;
+ safetyStockBalancesDto.MinStock=stockDto.MinStock;
+ safetyStockBalancesDto.SafetyStock=stockDto.SafetyStock;
+ safetyStockBalancesDto.StoreRelationType=stockDto.StoreRelationType;
+ safetyStockBalancesDto.WarehouseCode=stockDto.WarehouseCode;
+
+ //库存查询条件
+ var input = new SfsInventoryRequestInputBase { Condition = new Condition { Filters = new List() } };
+ input.Condition.Filters.Add(new Filter(nameof(BalanceDTO.ItemCode), safetyStockBalancesDto.ItemCode));
+ switch (stockDto.StoreRelationType)
+ {
+ case EnumStoreRelationType.None:
+ break;
+ case EnumStoreRelationType.Warehouse:
+ input.Condition.Filters.Add(new Filter(nameof(BalanceDTO.WarehouseCode), safetyStockBalancesDto.StoreValue));
+ break;
+ case EnumStoreRelationType.Area:
+ input.Condition.Filters.Add(new Filter(nameof(BalanceDTO.LocationArea), safetyStockBalancesDto.StoreValue));
+ break;
+ case EnumStoreRelationType.StoreGroup:
+ input.Condition.Filters.Add(new Filter(nameof(BalanceDTO.LocationGroup), safetyStockBalancesDto.StoreValue));
+ break;
+ case EnumStoreRelationType.Location:
+ input.Condition.Filters.Add(new Filter(nameof(BalanceDTO.LocationCode), safetyStockBalancesDto.StoreValue));
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ //符合条件的库存
+ safetyStockBalancesDto.BalancesDtos = await _balanceAppService.GetAllListByFilterAsync(input).ConfigureAwait(false);
+ var sumQty = safetyStockBalancesDto.BalancesDtos.Sum(p => p.Qty);
+ if (sumQty > safetyStockBalancesDto.SafetyStock)
+ {
+ safetyStockBalancesDto.SafetyStockStatus = ConsoleColor.Green.ToString();
+ }
+ else if(sumQty == safetyStockBalancesDto.SafetyStock)
+ {
+ safetyStockBalancesDto.SafetyStockStatus = ConsoleColor.Yellow.ToString();
+ }
+ else
+ {
+ safetyStockBalancesDto.SafetyStockStatus = ConsoleColor.Red.ToString();
+ }
+
+ stockBalancesDtos.Add(safetyStockBalancesDto);
+ }
+
+ pagedResultDto.Items = stockBalancesDtos;
+
+ return pagedResultDto;
+ }
+}