From cf0d4e2aed1210f950f85ceb4e1a48a57b36b207 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 9 Aug 2025 10:04:46 +0200 Subject: [PATCH] Update pag articoli - fix ricerca - fix cache REDIS - filtro search in pagina(RAM) --- .../Controllers/LuxController.cs | 141 +++++++++++++++++- .../Services/DataLayerServices.cs | 101 +++++++++---- Lux.UI/Components/Pages/Items.razor | 9 +- Lux.UI/Components/Pages/Items.razor.cs | 86 +++++++++-- 4 files changed, 283 insertions(+), 54 deletions(-) diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs index 39176839..0dad2054 100644 --- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs +++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using static EgwCoreLib.Lux.Core.Enums; using static System.Runtime.InteropServices.JavaScript.JSType; namespace EgwCoreLib.Lux.Data.Controllers @@ -124,11 +125,13 @@ namespace EgwCoreLib.Lux.Data.Controllers } /// - /// Elenco item da ricerca + /// Elenco item da ricerca filtro x gruppo/tipo /// - /// + /// + /// + /// /// - public List ItemGetSearch(string term) + public List ItemGetFilt(string CodGroup, ItemClassType ItemType) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) @@ -138,7 +141,131 @@ namespace EgwCoreLib.Lux.Data.Controllers { dbResult = dbCtx .DbSetItem - .Where(x => x.Description.Contains(term)) + .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) + && (ItemType == ItemClassType.ND || x.ItemType == ItemType)) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemGetFilt{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Elenco item da ricerca completa + /// + /// + /// + /// + /// + public List ItemGetFilt(string CodGroup, ItemClassType ItemType, string SearchVal) + { + List dbResult = new List(); + //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = dbCtx + .DbSetItem + .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) + && (ItemType == ItemClassType.ND || x.ItemType == ItemType) + && (string.IsNullOrEmpty(SearchVal) || + x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || + x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || + x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) + ) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemGetFilt{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Elenco item da ricerca filtro x gruppo/tipo Async + /// + /// + /// + /// + /// + public async Task> ItemGetFiltAsync(string CodGroup, ItemClassType ItemType) + { + List dbResult = new List(); + //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = await dbCtx + .DbSetItem + .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) + && (ItemType == ItemClassType.ND || x.ItemType == ItemType)) + .ToListAsync(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemGetFiltAsync{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Elenco item da ricerca completa Async + /// + /// + /// + /// + /// + public async Task> ItemGetFiltAsync(string CodGroup, ItemClassType ItemType, string SearchVal) + { + List dbResult = new List(); + //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = await dbCtx + .DbSetItem + .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) + && (ItemType == ItemClassType.ND || x.ItemType == ItemType) + && (string.IsNullOrEmpty(SearchVal) || + x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || + x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || + x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) + ) + .ToListAsync(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemGetFiltAsync{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Elenco item da ricerca + /// + /// + /// + public List ItemGetSearch(string SearchVal) + { + List dbResult = new List(); + //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = dbCtx + .DbSetItem + .Where(x => x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) .ToList(); } catch (Exception exc) @@ -152,9 +279,9 @@ namespace EgwCoreLib.Lux.Data.Controllers /// /// Elenco item da ricerca async /// - /// + /// /// - public async Task> ItemGetSearchAsync(string term) + public async Task> ItemGetSearchAsync(string SearchVal) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) @@ -164,7 +291,7 @@ namespace EgwCoreLib.Lux.Data.Controllers { dbResult = await dbCtx .DbSetItem - .Where(x => x.Description.Contains(term) || string.IsNullOrEmpty(term)) + .Where(x => x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) .ToListAsync(); } catch (Exception exc) diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index b914833a..1f89d06b 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using static EgwCoreLib.Lux.Core.Enums; using static System.Runtime.InteropServices.JavaScript.JSType; namespace EgwCoreLib.Lux.Data.Services @@ -147,40 +148,91 @@ namespace EgwCoreLib.Lux.Data.Services } /// - /// Elenco completo offerte da DB + /// Eliminazione record item /// + /// /// - public async Task> OfferGetAll() + public async Task ItemDeleteAsync(ItemModel rec2del) + { + bool result = await dbController.ItemDeleteAsync(rec2del); + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Item:*"); + return result; + } + + /// + /// Elenco item da ricerca completa Async + /// + /// + /// + /// + /// + public async Task> ItemGetFiltAsync(string SearchVal, string CodGroup, ItemClassType ItemType) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); - List? result = new List(); + List? result = new List(); // cerco in redis... - string currKey = $"{redisBaseKey}:Offers:ALL"; + string searchTok = string.IsNullOrEmpty(SearchVal) ? "ALL" : SearchVal; + string groupTok = string.IsNullOrEmpty(CodGroup) ? "ALL" : CodGroup; + string currKey = $"{redisBaseKey}:Item:Filt:{groupTok}:{ItemType}:{searchTok}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); - //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { - result = JsonConvert.DeserializeObject>($"{rawData}"); + result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { - result = await dbController.OfferGetAll(); + result = await dbController.ItemGetFiltAsync(SearchVal, CodGroup, ItemType); // serializzo e salvo con config x evitare loop... rawData = JsonConvert.SerializeObject(result, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { - result = new List(); + result = new List(); } sw.Stop(); - Log.Debug($"OfferGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ItemGetFiltAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } + /// + /// Elenco item da ricerca async + /// + /// + /// + public async Task> ItemGetSearchAsync(string term) + { + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List? result = new List(); + // cerco in redis... + string token = string.IsNullOrEmpty(term) ? "ALL" : term; + string currKey = $"{redisBaseKey}:Item:Search:{token}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = await dbController.ItemGetSearchAsync(term); + // serializzo e salvo con config x evitare loop... + rawData = JsonConvert.SerializeObject(result, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, LongCache); + } + if (result == null) + { + result = new List(); + } + sw.Stop(); + Log.Debug($"ItemGetSearchAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } /// /// Elenco completo ItemGroup gestiti @@ -217,50 +269,37 @@ namespace EgwCoreLib.Lux.Data.Services } /// - /// Elenco item da ricerca async + /// Elenco completo offerte da DB /// - /// /// - public async Task> ItemGetSearchAsync(string term) + public async Task> OfferGetAll() { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); - List? result = new List(); + List? result = new List(); // cerco in redis... - string token = string.IsNullOrEmpty(term) ? "ALL" : term; - string currKey = $"{redisBaseKey}:Item:{token}"; + string currKey = $"{redisBaseKey}:Offers:ALL"; RedisValue rawData = await redisDb.StringGetAsync(currKey); + //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { - result = JsonConvert.DeserializeObject>($"{rawData}"); + result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { - result = await dbController.ItemGetSearchAsync(term); + result = await dbController.OfferGetAll(); // serializzo e salvo con config x evitare loop... rawData = JsonConvert.SerializeObject(result, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { - result = new List(); + result = new List(); } sw.Stop(); - Log.Debug($"ItemGetSearchAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; - } - - /// - /// Eliminazione record item - /// - /// - /// - public async Task ItemDeleteAsync(ItemModel rec2del) - { - bool result = await dbController.ItemDeleteAsync(rec2del); - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Item:*"); + Log.Debug($"OfferGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/Lux.UI/Components/Pages/Items.razor b/Lux.UI/Components/Pages/Items.razor index 4dd16141..506c5d86 100644 --- a/Lux.UI/Components/Pages/Items.razor +++ b/Lux.UI/Components/Pages/Items.razor @@ -8,7 +8,7 @@
- @if (!string.IsNullOrEmpty(SelCodGroup)) + @if (!string.IsNullOrEmpty(SelCodGroup) && SelType != Enums.ItemClassType.ND) { } @@ -25,7 +25,6 @@ Tipo - + +
@@ -107,7 +106,7 @@ } - + } diff --git a/Lux.UI/Components/Pages/Items.razor.cs b/Lux.UI/Components/Pages/Items.razor.cs index d062f799..2dda1d36 100644 --- a/Lux.UI/Components/Pages/Items.razor.cs +++ b/Lux.UI/Components/Pages/Items.razor.cs @@ -13,11 +13,6 @@ namespace Lux.UI.Components.Pages protected List ListItemGroup = new List(); protected List ListRecords = new List(); - protected string searchVal = ""; - - protected string? SelCodGroup = null; - protected EgwCoreLib.Lux.Core.Enums.ItemClassType? SelType = null; - #endregion Protected Fields #region Protected Properties @@ -28,6 +23,63 @@ namespace Lux.UI.Components.Pages [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; + protected string SearchVal + { + get => searchVal; + set + { + if (searchVal != value) + { + searchVal = value; + currPage = 1; + var pUpd = Task.Run(async () => + { + await ReloadData(); + UpdateTable(); + }); + pUpd.Wait(); + } + } + } + + protected string SelCodGroup + { + get => selCodGroup; + set + { + if (selCodGroup != value) + { + selCodGroup = value; + currPage = 1; + var pUpd = Task.Run(async () => + { + await ReloadData(); + UpdateTable(); + }); + pUpd.Wait(); + } + } + } + + protected EgwCoreLib.Lux.Core.Enums.ItemClassType SelType + { + get => selType; + set + { + if (selType != value) + { + selType = value; + currPage = 1; + var pUpd = Task.Run(async () => + { + await ReloadData(); + UpdateTable(); + }); + pUpd.Wait(); + } + } + } + #endregion Protected Properties #region Protected Methods @@ -59,8 +111,8 @@ namespace Lux.UI.Components.Pages { if (!await JSRuntime.InvokeAsync("confirm", $"Sicuro di voler eliminare il record? Dettagli: {selRec.ItemID} | {selRec.CodGroup} | {selRec.ItemType} | {selRec.ExtItemCode}")) return; - // esegue eliminazione del record... - await DLService.ItemDeleteAsync(selRec); + //// esegue eliminazione del record... + //await DLService.ItemDeleteAsync(selRec); EditRecord = null; SelRecord = null; @@ -91,9 +143,9 @@ namespace Lux.UI.Components.Pages UpdateTable(); } - protected void resetSearch() + protected void ResetSearch() { - searchVal = ""; + SearchVal = ""; } protected void SaveNumRec(int newNum) @@ -113,11 +165,13 @@ namespace Lux.UI.Components.Pages #region Private Fields private int currPage = 1; - private ItemModel? EditRecord = null; private bool isLoading = false; private int numRecord = 10; + private string searchVal = ""; + private string selCodGroup = ""; private ItemModel? SelRecord = null; + private EgwCoreLib.Lux.Core.Enums.ItemClassType selType = EgwCoreLib.Lux.Core.Enums.ItemClassType.ND; private int totalCount = 0; #endregion Private Fields @@ -132,7 +186,17 @@ namespace Lux.UI.Components.Pages private async Task ReloadData() { isLoading = true; - AllRecords = await DLService.ItemGetSearchAsync(searchVal); + AllRecords = await DLService.ItemGetFiltAsync(SelCodGroup, SelType); + // se ho ricerca testuale faccio filtro ulteriore... + if (!string.IsNullOrEmpty(SearchVal)) + { + AllRecords = AllRecords + .Where(x => + x.Description.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) || + x.ExtItemCode.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) || + x.SupplCode.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase)) + .ToList(); + } totalCount = AllRecords.Count; }