Ancora update metodi SPEC

This commit is contained in:
Samuele Locatelli
2026-05-29 07:23:54 +02:00
parent ff36dadadc
commit 116d7395c9
12 changed files with 224 additions and 296 deletions
+43 -14
View File
@@ -401,7 +401,44 @@ namespace MP.Data.Controllers
.CountAsync();
return result;
}
/// <summary>
/// Conteggio articoli data condizione ricerca
/// </summary>
/// <param name="tipoArt"></param>
/// <param name="azienda"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<int> ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = "")
{
using var dbCtx = new MoonProContext(options);
IQueryable<AnagArticoliModel> query = dbCtx.DbSetArticoli.AsNoTracking();
// filtro tipo articolo
if (tipoArt != "*")
{
//query = query.Where(x => x.Tipo.ToLower() == tipoArt.ToLower());
query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt));
}
// filtro azienda
if (azienda != "*")
{
//query = query.Where(x => x.Azienda.ToLower() == azienda.ToLower());
query = query.Where(x => EF.Functions.Like(x.Azienda, azienda));
}
// filtro ricerca
if (!string.IsNullOrWhiteSpace(searchVal))
{
string pattern = $"%{searchVal}%";
query = query.Where(x =>
EF.Functions.Like(x.CodArticolo, pattern) ||
EF.Functions.Like(x.DescArticolo, pattern) ||
EF.Functions.Like(x.Disegno, pattern));
}
return await query
.OrderBy(x => x.CodArticolo)
.CountAsync();
}
/// <summary>
/// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async
/// </summary>
@@ -499,10 +536,6 @@ namespace MP.Data.Controllers
// filtro ricerca
if (!string.IsNullOrWhiteSpace(searchVal))
{
//query = query.Where(x =>
// x.CodArticolo.Contains(searchVal) ||
// x.DescArticolo.Contains(searchVal) ||
// x.Disegno.Contains(searchVal));
string pattern = $"%{searchVal}%";
query = query.Where(x =>
EF.Functions.Like(x.CodArticolo, pattern) ||
@@ -651,16 +684,12 @@ namespace MP.Data.Controllers
/// <returns></returns>
public async Task<List<ConfigModel>> ConfigGetAllAsync()
{
List<ConfigModel> dbResult = new List<ConfigModel>();
using (var dbCtx = new MoonProContext(options))
{
dbResult = await dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToListAsync();
}
return dbResult;
using var dbCtx = new MoonProContext(options);
return await dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToListAsync() ?? new();
}
/// <summary>
+1 -1
View File
@@ -224,7 +224,7 @@ namespace MP.SPEC.Components
protected override async Task OnInitializedAsync()
{
await MDService.ConfigResetCache();
await MDService.ConfigResetCacheAsync();
ListGruppiFase = await MDService.ElencoGruppiFaseAsync();
ListStati = await MDService.AnagStatiCommAsync();
selAzienda = await MDService.ConfigTryGetAsync("AZIENDA");
+1 -1
View File
@@ -171,7 +171,7 @@ namespace MP.SPEC.Components
protected override async Task OnInitializedAsync()
{
SelFilter = new SelectFluxParams();
await MDService.ConfigResetCache();
await MDService.ConfigResetCacheAsync();
var result = await MDService.ConfigTryGetAsync("SPEC_ParamTempoAgg");
if (result != null)
{
+156 -251
View File
@@ -90,6 +90,15 @@ namespace MP.SPEC.Data
public MessagePipe BroadastMsgPipe { get; set; } = null!;
public Dictionary<string, List<TagData>> currTagConf { get; set; } = new Dictionary<string, List<TagData>>();
/// <summary>
/// Expiry DateTime x refresh pagina parametri
/// </summary>
public DateTime DtParamExpiry
{
get => _dtParamExpiry;
set => _dtParamExpiry = value;
}
#endregion Public Properties
#region Public Methods
@@ -252,6 +261,33 @@ namespace MP.SPEC.Data
);
}
public async Task<int> ArticoliCountAsync()
{
string redisKey = $"{Utils.redisArtList}:Count";
return await GetOrFetchAsync(
operationName: "ArticoliCountAsync",
cacheKey: redisKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliCountAsync(),
tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountAll"]
);
}
public async Task<int> ArticoliCountSearchAsync(string tipo = "*", string azienda = "*", string searchVal = "")
{
string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim();
string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{searchVal}:Count";
return await GetOrFetchAsync(
operationName: "ArticoliCountSearchAsync",
cacheKey: redisKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliCountSearchAsync(tipo, azienda, searchVal),
tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountSearch"]
);
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
@@ -278,7 +314,7 @@ namespace MP.SPEC.Data
public async Task<List<AnagArticoliModel>> ArticoliGetByTipoAsync(string tipo, string azienda = "*")
{
string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim();
string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}";
string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}";
return await GetOrFetchAsync(
operationName: "ArticoliGetByTipoAsync",
cacheKey: redisKey,
@@ -289,23 +325,6 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Elenco articoli contenuti in Kit (come child), non eliminabli
/// </summary>
/// <returns></returns>
public async Task<List<AnagArticoliModel>> ArticoliInKitAsync()
{
string redisKey = $"{Utils.redisArtList}:InKit";
return await GetOrFetchAsync(
operationName: "ArticoliInKitAsync",
cacheKey: redisKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliInKitAsync() ?? new List<AnagArticoliModel>(),
tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"]
);
}
/// <summary>
/// Restitusice elenco articoli cercati
/// </summary>
@@ -328,6 +347,23 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Elenco articoli contenuti in Kit (come child), non eliminabli
/// </summary>
/// <returns></returns>
public async Task<List<AnagArticoliModel>> ArticoliInKitAsync()
{
string redisKey = $"{Utils.redisArtList}:InKit";
return await GetOrFetchAsync(
operationName: "ArticoliInKitAsync",
cacheKey: redisKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliInKitAsync() ?? new List<AnagArticoliModel>(),
tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"]
);
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
@@ -458,14 +494,14 @@ namespace MP.SPEC.Data
/// Reset dati cache config
/// </summary>
/// <returns></returns>
public async Task ConfigResetCache()
public async Task ConfigResetCacheAsync()
{
using var activity = ActivitySource.StartActivity("ConfigResetCache");
using var activity = ActivitySource.StartActivity("ConfigResetCacheAsync");
string source = "REDIS";
await ResetConfigCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ConfigResetCache Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
LogTrace($"ConfigResetCacheAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
@@ -696,7 +732,6 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Elenco link validi per il menu
/// </summary>
@@ -901,47 +936,6 @@ namespace MP.SPEC.Data
return answ;
}
/// <summary>
/// Imposta in redis la scadenza della pagina x il reload
/// </summary>
/// <param name="expTime"></param>
/// <returns></returns>
public DateTime ExpiryReloadParamGet()
{
using var activity = ActivitySource.StartActivity("ExpiryReloadParamGet");
string source = "REDIS";
DateTime dtRif = DateTime.Now;
string currKey = $"{Utils.redisParamPageExp}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
dtRif = JsonConvert.DeserializeObject<DateTime>($"{rawData}");
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExpiryReloadParamGet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dtRif;
}
/// <summary>
/// Imposta in redis la scadenza della pagina x il reload
/// </summary>
/// <param name="expTime"></param>
/// <returns></returns>
public bool ExpiryReloadParamSet(DateTime expTime)
{
using var activity = ActivitySource.StartActivity("ExpiryReloadParamSet");
string source = "REDIS";
bool fatto = false;
string currKey = $"{Utils.redisParamPageExp}";
string rawData = JsonConvert.SerializeObject(expTime);
fatto = redisDb.StringSet(currKey, rawData);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExpiryReloadParamSet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Cancellazione FusionCache (totale)
/// </summary>
@@ -1449,24 +1443,6 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Elenco operatori filtrati x gruppo
/// </summary>
/// <param name="codGruppo"></param>
/// <returns></returns>
public async Task<List<AnagOperatoriModel>> OperatoriGetFiltAsync(string codGruppo)
{
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
string currKey = $"{Utils.redisOprList}:{keyGrp}";
return await GetOrFetchAsync(
operationName: "OperatoriGetFiltAsync",
cacheKey: currKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List<AnagOperatoriModel>(),
tagList: [Utils.redisOprList]
);
}
/// <summary>
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
/// </summary>
@@ -1534,33 +1510,6 @@ namespace MP.SPEC.Data
},
tagList: [Utils.redisIobConf]
);
#if false
using var activity = ActivitySource.StartActivity("MachIobConfAsync");
string source = "DB";
Dictionary<string, string> result = new Dictionary<string, string>();
// cerco in redis...
string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync");
try
{
result = (await redisDb.HashGetAllAsync(currKey))
.ToDictionary(x => $"{x.Name}", x => $"{x.Value}");
source = "REDIS";
}
catch (Exception exc)
{
Log.Error($"Errore in MachIobConfAsync{Environment.NewLine}{exc}");
}
if (result == null)
{
result = new Dictionary<string, string>();
LogTrace($"Init valore default MachIobConfAsync | IdxMacchina: {IdxMacchina}");
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"MachIobConfAsync per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
#endif
}
/// <summary>
@@ -1728,7 +1677,6 @@ namespace MP.SPEC.Data
/// <returns></returns>
public async Task<List<ODLExpModel>> OdlListGetFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate)
{
string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
return await GetOrFetchAsync(
operationName: "OdlListGetFiltAsync",
@@ -1737,36 +1685,25 @@ namespace MP.SPEC.Data
fetchFunc: async () => await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(),
tagList: [Utils.redisOdlList]
);
}
#if false
using var activity = ActivitySource.StartActivity("OdlListGetFiltAsync");
List<ODLExpModel>? result = new List<ODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<ODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<ODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"OdlListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
#endif
/// <summary>
/// Elenco operatori filtrati x gruppo
/// </summary>
/// <param name="codGruppo"></param>
/// <returns></returns>
public async Task<List<AnagOperatoriModel>> OperatoriGetFiltAsync(string codGruppo)
{
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
string currKey = $"{Utils.redisOprList}:{keyGrp}";
return await GetOrFetchAsync(
operationName: "OperatoriGetFiltAsync",
cacheKey: currKey,
expiration: getRandTOut(redisLongTimeCache),
fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List<AnagOperatoriModel>(),
tagList: [Utils.redisOprList]
);
}
/// <summary>
@@ -1786,6 +1723,75 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Restituisce dizionario ODL/PODL data lista IdxOdl
/// </summary>
/// <param name="idxOdlList"></param>
/// <returns></returns>
public async Task<Dictionary<int, int>> PODL_getDictOdlPodlAsync(List<int> idxOdlList)
{
if (idxOdlList == null || !idxOdlList.Any())
return new Dictionary<int, int>();
var distinctIds = idxOdlList.Distinct().ToList();
var resultDictionary = new Dictionary<int, int>();
var missingIds = new List<int>();
// STEP 1: Controllo rapido in FusionCache (L1/Memory cache)
foreach (var id in distinctIds)
{
var cacheKey = $"val:{id}";
var cachedValue = await _cache.TryGetAsync<int>(cacheKey);
if (cachedValue.HasValue)
{
resultDictionary[id] = cachedValue.Value;
}
else
{
// ID non presente in cache, andrà cercato tramite il servizio EF
missingIds.Add(id);
}
}
// STEP 2: Se ci sono cache miss, interroghiamo il servizio EF Core
if (missingIds.Any())
{
// Riceviamo direttamente un Dictionary<int, int> ottimizzato da EF Core
Dictionary<int, int> dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds);
// STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale
foreach (var kvp in dbResults)
{
var id = kvp.Key;
var targetValue = kvp.Value;
resultDictionary[id] = targetValue;
// Salvataggio atomico e globale su FusionCache
var cacheKey = $"val:{id}";
await _cache.SetAsync(cacheKey, targetValue, TimeSpan.FromMinutes(30));
}
// STEP 4 [Altamente Consigliato]: Cache Penetration Protection
// Se un ID era tra i "missing" ma NON è presente nei risultati del DB, significa che non esiste.
// Salviamo un valore sentinella (es. 0 o -1) per evitare di ricontrollare il DB al prossimo giro.
foreach (var id in missingIds)
{
if (!dbResults.ContainsKey(id))
{
resultDictionary[id] = 0; // Imposta un default per l'output corrente
var cacheKey = $"val:{id}";
await _cache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(2)); // Scadenza breve per i record inesistenti
}
}
}
return resultDictionary;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
@@ -1886,75 +1892,6 @@ namespace MP.SPEC.Data
);
}
/// <summary>
/// Restituisce dizionario ODL/PODL data lista IdxOdl
/// </summary>
/// <param name="idxOdlList"></param>
/// <returns></returns>
public async Task<Dictionary<int, int>> PODL_getDictOdlPodlAsync(List<int> idxOdlList)
{
if (idxOdlList == null || !idxOdlList.Any())
return new Dictionary<int, int>();
var distinctIds = idxOdlList.Distinct().ToList();
var resultDictionary = new Dictionary<int, int>();
var missingIds = new List<int>();
// STEP 1: Controllo rapido in FusionCache (L1/Memory cache)
foreach (var id in distinctIds)
{
var cacheKey = $"val:{id}";
var cachedValue = await _cache.TryGetAsync<int>(cacheKey);
if (cachedValue.HasValue)
{
resultDictionary[id] = cachedValue.Value;
}
else
{
// ID non presente in cache, andrà cercato tramite il servizio EF
missingIds.Add(id);
}
}
// STEP 2: Se ci sono cache miss, interroghiamo il servizio EF Core
if (missingIds.Any())
{
// Riceviamo direttamente un Dictionary<int, int> ottimizzato da EF Core
Dictionary<int, int> dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds);
// STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale
foreach (var kvp in dbResults)
{
var id = kvp.Key;
var targetValue = kvp.Value;
resultDictionary[id] = targetValue;
// Salvataggio atomico e globale su FusionCache
var cacheKey = $"val:{id}";
await _cache.SetAsync(cacheKey, targetValue, TimeSpan.FromMinutes(30));
}
// STEP 4 [Altamente Consigliato]: Cache Penetration Protection
// Se un ID era tra i "missing" ma NON è presente nei risultati del DB, significa che non esiste.
// Salviamo un valore sentinella (es. 0 o -1) per evitare di ricontrollare il DB al prossimo giro.
foreach (var id in missingIds)
{
if (!dbResults.ContainsKey(id))
{
resultDictionary[id] = 0; // Imposta un default per l'output corrente
var cacheKey = $"val:{id}";
await _cache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(2)); // Scadenza breve per i record inesistenti
}
}
}
return resultDictionary;
}
/// <summary>
/// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored
/// </summary>
@@ -2281,35 +2218,6 @@ namespace MP.SPEC.Data
fetchFunc: async () => await dbController.StatoMacchinaAsync(idxMacchina) ?? new(),
tagList: [Utils.redisStatoMacch]
);
#if false
using var activity = ActivitySource.StartActivity("StatoMacchinaAsync");
// setup parametri costanti
string source = "DB";
StatoMacchineModel? result = new StatoMacchineModel();
// cerco in redisConn...
string currKey = $"{Utils.redisStatoMacch}:{idxMacchina}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<StatoMacchineModel>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.StatoMacchina(idxMacchina);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(1));
}
if (result == null)
{
result = new StatoMacchineModel();
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"StatoMacchinaAsync | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
#endif
}
/// <summary>
@@ -2385,7 +2293,7 @@ namespace MP.SPEC.Data
if (ForceDb)
{
// Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB
// Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB
// e aggiornare la cache.
var result = await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List<TksScoreModel>();
await _cache.SetAsync(currKey, result, TimeSpan.FromMinutes(redisLongTimeCache), tags: [Utils.redisKitScore]);
@@ -2620,14 +2528,16 @@ namespace MP.SPEC.Data
private static readonly ActivitySource ActivitySource = new ActivitySource("MP.DATA.Tracer");
private static IConfiguration _configuration = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
private readonly IFusionCache _cache;
private DateTime _artCacheExpiry = DateTime.MinValue;
private Dictionary<string, string> _configData = new();
private DateTime _dtParamExpiry = DateTime.Now;
/// <summary>
/// Elenco CodArticolo usati in istanza KIT (per verifica eliminabilità)
/// </summary>
private HashSet<string> _listCodArtInKit = new();
/// <summary>
/// Elenco CodArticolo NON usati (per verifica eliminabilità)
@@ -2639,11 +2549,6 @@ namespace MP.SPEC.Data
/// </summary>
private HashSet<string> _listCodArtUsed = new();
/// <summary>
/// Elenco CodArticolo usati in istanza KIT (per verifica eliminabilità)
/// </summary>
private HashSet<string> _listCodArtInKit = new();
private string canCacheParametri = "";
private string MpIoNS = "";
@@ -2680,6 +2585,11 @@ namespace MP.SPEC.Data
/// </summary>
private int redisShortTimeCache = 5;
/// <summary>
/// Soglia minima (ms) per log timing in console
/// </summary>
private double slowLogThresh = 0;
private bool traceEnabled = false;
#endregion Private Fields
@@ -2722,11 +2632,6 @@ namespace MP.SPEC.Data
}
}
/// <summary>
/// Soglia minima (ms) per log timing in console
/// </summary>
private double slowLogThresh = 0;
/// <summary>
/// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività
/// </summary>
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>8.16.2605.2819</Version>
<Version>8.16.2605.2907</Version>
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
+7 -6
View File
@@ -19,8 +19,8 @@
</div>
</div>
</div>
<div class="px-0 align-content-center">
<div class="input-group">
<div class="px-0 align-items-center d-flex justify-content-end gap-1">
<div class="input-group flex-grow-1">
<span class="input-group-text"><i class="fa fa-rectangle-list"></i></span>
<select @bind="@selTipoArt" class="form-select form-select-sm" style="width: 8rem; flex: 0 0 auto;" title="Selezionare il tipo di Articolo da mostrare" @bind:after="ResetDataAsync">
<option value="*">--- Tutti ---</option>
@@ -33,10 +33,12 @@
}
</select>
<span class="input-group-text"><i class="fa fa-search"></i></span>
<input type="text" class="form-control form-control-sm" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal" @bind:after="ResetDataAsync">
<input type="text" class="form-control form-control-sm" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal" @bind:after="ResetDataAsync" >
<button class="btn @searchCss" @onclick="() => ResetSearch()"><i class="fa fa-ban"></i></button>
<span class="input-group-text"><i class="fa fa-database"></i></span>
<input type="number" inputmode="numeric" min="10" max="100000" class="form-control form-control-sm text-end" style="width: 6rem; flex: 0 0 auto;" aria-label="Num record" title="Num massimo record da recuperare" @bind="@maxNumRecord" @bind:after="ReloadDataAsync">
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@selAzienda" class="form-select form-select-sm" style="width: 15rem; flex: 0 0 auto;" title="Selezionare l'azienda da visualizzare" @bind:after="ReloadAziendaAsync">
<select @bind="@selAzienda" class="form-select" style="width: 15rem; flex: 0 0 auto;" title="Selezionare l'azienda da visualizzare" @bind:after="ReloadAziendaAsync">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
@@ -45,8 +47,7 @@
}
}
</select>
<span class="input-group-text"><i class="fa fa-database"></i></span>
<input type="number" inputmode="numeric" min="10" max="100000" class="form-control form-control-sm text-end" style="width: 6rem; flex: 0 0 auto;" aria-label="Num record" title="Num massimo record da recuperare" @bind="@maxNumRecord" @bind:after="ReloadDataAsync">
<span class="input-group-text p-1"><small>#: @availRecord</small></span>
</div>
</div>
</div>
+5 -2
View File
@@ -190,7 +190,9 @@ namespace MP.SPEC.Pages
private List<AnagGruppiModel>? ListAziende;
private List<AnagArticoliModel>? ListRecords;
private List<ListValuesModel>? ListTipoArt;
private int maxNumRecord = 5000;
private int maxNumRecord = 1000;
private int availRecord = 1000;
private int totRecord = 0;
private List<AnagArticoliModel>? SearchRecords;
#endregion Private Fields
@@ -256,7 +258,7 @@ namespace MP.SPEC.Pages
Valore = selAzienda
};
await MDService.ConfigUpdateAsync(updRec);
await MDService.ConfigResetCache();
await MDService.ConfigResetCacheAsync();
// ricarico
await ResetDataAsync();
}
@@ -302,6 +304,7 @@ namespace MP.SPEC.Pages
{
isLoading = true;
SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selTipoArt, selAzienda, SearchVal);
availRecord = await MDService.ArticoliCountSearchAsync(selTipoArt, selAzienda, searchVal);
totalCount = SearchRecords.Count;
UpdateTable();
}
+1 -1
View File
@@ -26,7 +26,7 @@ namespace MP.SPEC.Pages
protected override async Task OnInitializedAsync()
{
await MDService.ConfigResetCache();
await MDService.ConfigResetCacheAsync();
giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze");
await Task.Delay(1);
padCodXdl = await MDService.ConfigTryGetAsync("PadCodXdl");
+6 -16
View File
@@ -1,9 +1,8 @@
using Microsoft.AspNetCore.Components;
using EgwCoreLib.Razor;
using Microsoft.AspNetCore.Components;
using MP.Data.DbModels;
using MP.SPEC.Components;
using MP.SPEC.Data;
using NLog;
using EgwCoreLib.Razor;
namespace MP.SPEC.Pages
{
@@ -23,7 +22,7 @@ namespace MP.SPEC.Pages
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
{
// controllo se sia scaduto tempo massimo (in redis) x ricaricare pagina in modo completo...
var dtRif = MDService.ExpiryReloadParamGet();
var dtRif = MDService.DtParamExpiry;
if (dtRif > DateTime.Now)
{
Log.Trace("----- Elapsed check PARAMS.cs -----");
@@ -32,7 +31,7 @@ namespace MP.SPEC.Pages
{
var pUpd = Task.Run(async () =>
{
MDService.ExpiryReloadParamSet(DateTime.Now.AddSeconds(intForceReload));
MDService.DtParamExpiry = DateTime.Now.AddSeconds(intForceReload);
aTimer.Elapsed -= ElapsedTimer;
aTimer.Stop();
aTimer.Close();
@@ -91,7 +90,6 @@ namespace MP.SPEC.Pages
{
updFilter.lastUpdate = updFilter.lastUpdate == "-" ? $"{adesso:yyyy/MM/dd HH:mm:ss}" : updFilter.lastUpdate;
updFilter.IdxMacchina = newRec.IdxMacchina;
//updFilter.CodFlux = newRec.CodFlux;
}
else
{
@@ -124,7 +122,6 @@ namespace MP.SPEC.Pages
currPage = newNum;
DateTime adesso = DateTime.Now.AddSeconds(1);
var updFilter = currFilter;
//updFilter.LiveUpdate = (currPage == 1);
updFilter.LiveUpdate = (currFilter.CurrPage == 1);
updFilter.lastUpdate = updFilter.LiveUpdate ? "-" : $"{adesso:yyyy/MM/dd HH:mm:ss}";
// salvo filtro
@@ -211,10 +208,10 @@ namespace MP.SPEC.Pages
private void setExpiryReload()
{
// verifico se ho una scadenza expiry del periodo desiderato, sennò imposto nuova...
var dtRif = MDService.ExpiryReloadParamGet();
var dtRif = MDService.DtParamExpiry;
if (dtRif <= DateTime.Now)
{
MDService.ExpiryReloadParamSet(DateTime.Now.AddSeconds(intForceReload));
MDService.DtParamExpiry = DateTime.Now.AddSeconds(intForceReload);
}
}
@@ -222,18 +219,11 @@ namespace MP.SPEC.Pages
{
isFiltering = false;
isLoading = true;
await Task.Delay(1);
currPage = 1;
if (newParams.CurrPage == 0)
{
newParams.CurrPage = 1;
//newParams.LiveUpdate = false;
}
else
{
//newParams.LiveUpdate = (currPage == 1);
}
await Task.Delay(1);
await InvokeAsync(() => StateHasChanged());
currFilter = newParams;
isLoading = false;
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 8.16.2605.2819</h4>
<h4>Versione: 8.16.2605.2907</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
8.16.2605.2819
8.16.2605.2907
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>8.16.2605.2819</version>
<version>8.16.2605.2907</version>
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>