diff --git a/sql/migrate_warehouse_module.sql b/sql/migrate_warehouse_module.sql index b59332b..ce2e99d 100644 --- a/sql/migrate_warehouse_module.sql +++ b/sql/migrate_warehouse_module.sql @@ -19,6 +19,7 @@ CREATE TABLE IF NOT EXISTS `C_sku` ( `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -37,6 +38,7 @@ CREATE TABLE IF NOT EXISTS `C_bin_location` ( `IsEnabled` TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用:0-否,1-是', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -54,6 +56,7 @@ CREATE TABLE IF NOT EXISTS `C_inventory` ( `BinLocationId` INT NOT NULL COMMENT '库位ID → C_bin_location.Id', `Qty` INT NOT NULL DEFAULT 0 COMMENT '可用库存数量', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -75,6 +78,7 @@ CREATE TABLE IF NOT EXISTS `C_inbound_notice` ( `ActualArrivalTime` DATETIME NULL COMMENT '实际到货时间', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -95,6 +99,7 @@ CREATE TABLE IF NOT EXISTS `C_inbound_box` ( `HeightCm` DECIMAL(10,2) NULL COMMENT '高(cm)', `IsReceived` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已收货:0-否,1-是', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -112,6 +117,7 @@ CREATE TABLE IF NOT EXISTS `C_inbound_box_line` ( `ReceivedQty` INT NULL COMMENT '实收数量', `BinLocationId` INT NULL COMMENT '上架库位ID → C_bin_location.Id', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -131,6 +137,7 @@ CREATE TABLE IF NOT EXISTS `C_parcel` ( `ArrivalTime` DATETIME NULL COMMENT '到仓时间', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -150,6 +157,7 @@ CREATE TABLE IF NOT EXISTS `C_parcel_item` ( `BinLocationId` INT NULL COMMENT '上架库位ID', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -166,6 +174,7 @@ CREATE TABLE IF NOT EXISTS `C_sku_platform_map` ( `SkuId` INT NOT NULL COMMENT '库内SKU ID → C_sku.Id', `SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -198,6 +207,7 @@ CREATE TABLE IF NOT EXISTS `t_sales_store` ( `IsAutoFulfill` TINYINT NOT NULL DEFAULT 0 COMMENT '是否自动发货:0-否,1-是', `Remark` VARCHAR(512) NULL COMMENT '备注', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -231,6 +241,7 @@ CREATE TABLE IF NOT EXISTS `t_sales_store_order` ( `LastSyncTime` DATETIME NULL COMMENT '最近同步时间', `PlatformExtraJson` JSON NULL COMMENT '平台扩展字段', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', @@ -254,6 +265,7 @@ CREATE TABLE IF NOT EXISTS `t_sales_store_order_line` ( `IsShipExcluded` TINYINT NOT NULL DEFAULT 0 COMMENT '是否拒绝发货', `MappedSkuId` INT NULL COMMENT '映射库内SKU → C_sku.Id', `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳', `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人', `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `UpdateUserId` INT NULL COMMENT '更新人', diff --git a/sql/migrate_warehouse_module_concurrency.sql b/sql/migrate_warehouse_module_concurrency.sql new file mode 100644 index 0000000..a5eda23 --- /dev/null +++ b/sql/migrate_warehouse_module_concurrency.sql @@ -0,0 +1,50 @@ +-- 已执行旧版 migrate_warehouse_module.sql 的库补 ConcurrencyStamp(与 AggregateRoot 实体对齐) +-- 勿在 ALTER 中使用 DEFAULT(UUID()),复制环境会报 Error 1674 + +ALTER TABLE `C_sku` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_sku` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_bin_location` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_bin_location` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_inventory` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_inventory` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_inbound_notice` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_inbound_notice` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_inbound_box` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_inbound_box` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_inbound_box_line` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_inbound_box_line` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_parcel` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_parcel` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_parcel_item` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_parcel_item` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `C_sku_platform_map` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `C_sku_platform_map` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `t_sales_store` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `t_sales_store` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `t_sales_store_order` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `t_sales_store_order` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; + +ALTER TABLE `t_sales_store_order_line` + ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '' COMMENT '并发戳' AFTER `IsDeleted`; +UPDATE `t_sales_store_order_line` SET `ConcurrencyStamp` = UUID() WHERE `ConcurrencyStamp` = ''; diff --git a/src/Oms.Application/Services/Orders/PlatformStoreOrderService.cs b/src/Oms.Application/Services/Orders/PlatformStoreOrderService.cs index a0b13c1..d10b8f3 100644 --- a/src/Oms.Application/Services/Orders/PlatformStoreOrderService.cs +++ b/src/Oms.Application/Services/Orders/PlatformStoreOrderService.cs @@ -125,8 +125,9 @@ public class PlatformStoreOrderService : ApplicationService CustomerRepository, CurrentUser, customerId); + var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(resolvedCustomerId); var orders = await StoreOrderRepository.GetListAsync(x => - (!resolvedCustomerId.HasValue || x.CustomerId == resolvedCustomerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!storeId.HasValue || x.StoreId == storeId.Value)); return new PlatformStoreOrderSummaryOutput @@ -232,8 +233,9 @@ public class PlatformStoreOrderService : ApplicationService CustomerRepository, CurrentUser, input.CustomerId); + var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId); var orders = await StoreOrderRepository.GetListAsync(x => - (!customerId.HasValue || x.CustomerId == customerId.Value) && input.Ids.Contains(x.Id)); + (!hasCustomerFilter || x.CustomerId == customerIdValue) && input.Ids.Contains(x.Id)); foreach (var order in orders) { var lines = await StoreOrderLineRepository.GetListAsync(x => x.StoreOrderId == order.Id); @@ -594,11 +596,12 @@ public class PlatformStoreOrderService : ApplicationService private static Expression> BuildListPredicate(int? customerId, PlatformStoreOrderListInput input) { + var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId); var fulfillStatus = input.FulfillStatus?.Trim(); var platformOrderNo = input.PlatformOrderNo?.Trim(); return x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!input.StoreId.HasValue || x.StoreId == input.StoreId.Value) && (string.IsNullOrWhiteSpace(fulfillStatus) || x.FulfillStatus == fulfillStatus) && (!input.IsSuspended.HasValue || x.IsSuspended == input.IsSuspended.Value) diff --git a/src/Oms.Application/Services/Orders/PlatformStoreService.cs b/src/Oms.Application/Services/Orders/PlatformStoreService.cs index d366369..357bffa 100644 --- a/src/Oms.Application/Services/Orders/PlatformStoreService.cs +++ b/src/Oms.Application/Services/Orders/PlatformStoreService.cs @@ -142,8 +142,9 @@ public class PlatformStoreService : ApplicationService CustomerRepository, CurrentUser, null); + var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId); var entities = await StoreRepository.GetListAsync(x => - (!customerId.HasValue || x.CustomerId == customerId.Value) && input.Ids.Contains(x.Id)); + (!hasCustomerFilter || x.CustomerId == customerIdValue) && input.Ids.Contains(x.Id)); foreach (var entity in entities) { await StoreRepository.DeleteAsync(entity); @@ -165,6 +166,7 @@ public class PlatformStoreService : ApplicationService private static Expression> BuildListPredicate(int? customerId, PlatformStorePageInput input) { + var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId); var platformCode = input.PlatformCode?.Trim(); var nickname = input.StoreNickname?.Trim(); var filter = input.ExpirationFilter?.Trim().ToLowerInvariant(); @@ -172,7 +174,7 @@ public class PlatformStoreService : ApplicationService var within7Days = now.AddDays(7); return x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (string.IsNullOrWhiteSpace(platformCode) || x.PlatformCode == platformCode) && (string.IsNullOrWhiteSpace(nickname) || x.StoreNickname.Contains(nickname)) && (string.IsNullOrWhiteSpace(filter) || filter == "normal" diff --git a/src/Oms.Application/Services/Warehouse/WarehouseService.Helpers.cs b/src/Oms.Application/Services/Warehouse/WarehouseService.Helpers.cs index 82316da..fd40d93 100644 --- a/src/Oms.Application/Services/Warehouse/WarehouseService.Helpers.cs +++ b/src/Oms.Application/Services/Warehouse/WarehouseService.Helpers.cs @@ -18,6 +18,9 @@ public partial class WarehouseService CurrentUser, requestedCustomerId); + private static (bool HasFilter, int Value) CustomerFilter(int? customerId) => + WarehouseCustomerHelper.ToCustomerFilter(customerId); + private async Task GetSkuOrThrowAsync(int? customerId, int skuId) { var entity = customerId.HasValue diff --git a/src/Oms.Application/Services/Warehouse/WarehouseService.Inbound.cs b/src/Oms.Application/Services/Warehouse/WarehouseService.Inbound.cs index 1ed70a3..3e5b40b 100644 --- a/src/Oms.Application/Services/Warehouse/WarehouseService.Inbound.cs +++ b/src/Oms.Application/Services/Warehouse/WarehouseService.Inbound.cs @@ -20,12 +20,13 @@ public partial class WarehouseService public async Task> GetInboundListAsync(WarehouseInboundListInput input) { var customerId = await ResolveListCustomerIdAsync(input.CustomerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(customerId); var keyword = input.Keyword?.Trim(); var hasKeyword = !string.IsNullOrWhiteSpace(keyword); var receiptStatus = input.ReceiptStatus?.Trim(); Expression> predicate = x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!input.WarehouseId.HasValue || x.WarehouseId == input.WarehouseId.Value) && (string.IsNullOrWhiteSpace(receiptStatus) || x.ReceiptStatus == receiptStatus) && (!hasKeyword || x.NoticeNo.Contains(keyword!) || (x.MarkReference != null && x.MarkReference.Contains(keyword!))); @@ -300,8 +301,9 @@ public partial class WarehouseService public async Task GetInboundSummaryAsync([FromQuery] int? customerId = null, [FromQuery] int? warehouseId = null) { var resolvedCustomerId = await ResolveListCustomerIdAsync(customerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(resolvedCustomerId); var notices = await InboundNoticeRepository.GetListAsync(x => - (!resolvedCustomerId.HasValue || x.CustomerId == resolvedCustomerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!warehouseId.HasValue || x.WarehouseId == warehouseId.Value)); return new WarehouseInboundSummaryOutput diff --git a/src/Oms.Application/Services/Warehouse/WarehouseService.Inventory.cs b/src/Oms.Application/Services/Warehouse/WarehouseService.Inventory.cs index e27698c..74476a2 100644 --- a/src/Oms.Application/Services/Warehouse/WarehouseService.Inventory.cs +++ b/src/Oms.Application/Services/Warehouse/WarehouseService.Inventory.cs @@ -17,8 +17,9 @@ public partial class WarehouseService public async Task> GetInventoryListAsync(WarehouseInventoryListInput input) { var customerId = await ResolveListCustomerIdAsync(input.CustomerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(customerId); var inventories = await InventoryRepository.GetListAsync(x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && x.Qty > 0 && (!input.WarehouseId.HasValue || x.WarehouseId == input.WarehouseId.Value)); @@ -26,7 +27,7 @@ public partial class WarehouseService var skus = skuIds.Length == 0 ? [] : await SkuRepository.GetListAsync(x => - (!customerId.HasValue || x.CustomerId == customerId.Value) && skuIds.Contains(x.Id)); + (!hasCustomerFilter || x.CustomerId == customerIdValue) && skuIds.Contains(x.Id)); var skuMap = skus.ToDictionary(x => x.Id); var keyword = input.Keyword?.Trim(); @@ -83,10 +84,11 @@ public partial class WarehouseService } var resolvedCustomerId = await ResolveListCustomerIdAsync(customerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(resolvedCustomerId); await GetSkuOrThrowAsync(resolvedCustomerId, skuId); var inventories = await InventoryRepository.GetListAsync(x => - (!resolvedCustomerId.HasValue || x.CustomerId == resolvedCustomerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && x.WarehouseId == warehouseId && x.SkuId == skuId && x.Qty > 0); diff --git a/src/Oms.Application/Services/Warehouse/WarehouseService.Parcel.cs b/src/Oms.Application/Services/Warehouse/WarehouseService.Parcel.cs index c20fd18..954d207 100644 --- a/src/Oms.Application/Services/Warehouse/WarehouseService.Parcel.cs +++ b/src/Oms.Application/Services/Warehouse/WarehouseService.Parcel.cs @@ -20,12 +20,13 @@ public partial class WarehouseService public async Task> GetParcelListAsync(WarehouseParcelListInput input) { var customerId = await ResolveListCustomerIdAsync(input.CustomerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(customerId); var keyword = input.Keyword?.Trim(); var hasKeyword = !string.IsNullOrWhiteSpace(keyword); var lifecycleStatus = input.LifecycleStatus?.Trim(); Expression> predicate = x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!input.WarehouseId.HasValue || x.WarehouseId == input.WarehouseId.Value) && (string.IsNullOrWhiteSpace(lifecycleStatus) || x.LifecycleStatus == lifecycleStatus) && (!hasKeyword || x.TrackingNo.Contains(keyword!) || (x.CarrierName != null && x.CarrierName.Contains(keyword!))); diff --git a/src/Oms.Application/Services/Warehouse/WarehouseService.Sku.cs b/src/Oms.Application/Services/Warehouse/WarehouseService.Sku.cs index f789648..6a2a5b9 100644 --- a/src/Oms.Application/Services/Warehouse/WarehouseService.Sku.cs +++ b/src/Oms.Application/Services/Warehouse/WarehouseService.Sku.cs @@ -18,11 +18,12 @@ public partial class WarehouseService public async Task> GetSkuListAsync(WarehouseSkuListInput input) { var customerId = await ResolveListCustomerIdAsync(input.CustomerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(customerId); var keyword = input.Keyword?.Trim(); var hasKeyword = !string.IsNullOrWhiteSpace(keyword); Expression> predicate = x => - (!customerId.HasValue || x.CustomerId == customerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && (!hasKeyword || x.SkuCode.Contains(keyword!) || x.SkuName.Contains(keyword!)); var pageIndex = OmsDocHelper.NormalizePage(input.Page); @@ -38,7 +39,7 @@ public partial class WarehouseService var inventories = skuIds.Length == 0 ? [] : await InventoryRepository.GetListAsync(x => - (!customerId.HasValue || x.CustomerId == customerId.Value) && skuIds.Contains(x.SkuId)); + (!hasCustomerFilter || x.CustomerId == customerIdValue) && skuIds.Contains(x.SkuId)); var qtyMap = inventories .GroupBy(x => x.SkuId) .ToDictionary(g => g.Key, g => g.Sum(x => x.Qty)); @@ -60,9 +61,10 @@ public partial class WarehouseService public async Task GetSkuDetailAsync([FromQuery] int id, [FromQuery] int? customerId = null) { var resolvedCustomerId = await ResolveListCustomerIdAsync(customerId); + var (hasCustomerFilter, customerIdValue) = CustomerFilter(resolvedCustomerId); var entity = await GetSkuOrThrowAsync(resolvedCustomerId, id); var inventories = await InventoryRepository.GetListAsync(x => - (!resolvedCustomerId.HasValue || x.CustomerId == resolvedCustomerId.Value) + (!hasCustomerFilter || x.CustomerId == customerIdValue) && x.SkuId == id); return MapSkuOutput(entity, inventories.Sum(x => x.Qty)); } diff --git a/src/Oms.Application/Shared/WarehouseCustomerHelper.cs b/src/Oms.Application/Shared/WarehouseCustomerHelper.cs index acaa57c..ae2c8f2 100644 --- a/src/Oms.Application/Shared/WarehouseCustomerHelper.cs +++ b/src/Oms.Application/Shared/WarehouseCustomerHelper.cs @@ -35,6 +35,9 @@ public static class WarehouseCustomerHelper return customerId.Value; } + public static (bool HasFilter, int Value) ToCustomerFilter(int? customerId) => + (customerId.HasValue, customerId.GetValueOrDefault()); + public static string GenerateInboundNoticeNo() => $"IN{DateTime.Now:yyyyMMddHHmmss}{Random.Shared.Next(1000, 9999)}"; }