From 344be332d79ef984cf52abf1e7101145b7753e1b Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Fri, 13 Mar 2026 21:26:08 +0700 Subject: [PATCH] fix: resolve POS duplicate products + settings shop name display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P2: Products appeared 2x in POS grid — BFF now filters isActive=true by default, plus client-side dedup by product ID as safety net. P3: Admin Settings showed "--" for shop name — parent ShopPage now passes ShopName and VerticalLabel parameters to ShopSettings component. Co-Authored-By: Claude Opus 4.6 --- .../Pages/Admin/Shop/ShopPage.razor | 2 +- .../WebClientTpos.Client/Services/PosDataService.cs | 13 ++++++++++++- .../Controllers/CatalogController.cs | 11 +++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor index b0c01f21..3ecd45bf 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor @@ -252,7 +252,7 @@ break; case "settings": - + break; case "schedule": diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs b/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs index 3e0f0940..76800fd1 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Services/PosDataService.cs @@ -212,8 +212,19 @@ public class PosDataService public async Task GetShopByIdAsync(Guid shopId) => await GetObjectFromApiAsync($"api/bff/shops/{shopId}"); + /// + /// EN: Get products for a shop. Deduplicates by product ID to prevent UI duplication + /// when the API response contains duplicate entries (e.g. from multi-format deserialization). + /// VI: Lấy sản phẩm của shop. Loại bỏ trùng lặp theo ID để tránh hiển thị đôi trên UI + /// khi API response chứa bản ghi trùng (ví dụ từ deserialization đa định dạng). + /// public async Task> GetProductsAsync(Guid shopId) - => await GetListFromApiAsync($"api/bff/shops/{shopId}/products"); + { + var products = await GetListFromApiAsync($"api/bff/shops/{shopId}/products"); + // EN: Deduplicate by Id — prevents double-display regardless of API response shape. + // VI: Loại trùng theo Id — ngăn hiển thị đôi bất kể định dạng API response. + return products.GroupBy(p => p.Id).Select(g => g.First()).ToList(); + } public async Task> GetCategoriesAsync(Guid shopId) => await GetListFromApiAsync($"api/bff/shops/{shopId}/categories"); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/CatalogController.cs b/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/CatalogController.cs index ce230020..6d9dc667 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/CatalogController.cs +++ b/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/CatalogController.cs @@ -34,12 +34,15 @@ public class CatalogController : ControllerBase } /// - /// EN: Get products for a specific shop. - /// VI: Lấy sản phẩm của một cửa hàng cụ thể. + /// EN: Get products for a specific shop. POS-facing — only returns active products by default. + /// VI: Lấy sản phẩm của một cửa hàng cụ thể. Dành cho POS — chỉ trả về sản phẩm đang hoạt động. /// [HttpGet("shops/{shopId}/products")] - public Task GetShopProducts(Guid shopId) => - _catalog.GetAsync($"/api/v1/shops/{shopId}/products").ProxyAsync(); + public Task GetShopProducts(Guid shopId, [FromQuery] bool? isActive = true) + { + var qs = isActive.HasValue ? $"?isActive={isActive.Value.ToString().ToLower()}" : ""; + return _catalog.GetAsync($"/api/v1/shops/{shopId}/products{qs}").ProxyAsync(); + } /// /// EN: Create a product.