Merge branch 'release/UpdateCacheApiCall'

This commit is contained in:
Samuele Locatelli
2022-01-13 17:41:14 +01:00
30 changed files with 1735 additions and 350 deletions
+18
View File
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Core
{
/// <summary>
/// Tipologia di ticket
/// </summary>
public enum TipologiaTicket
{
ND = 0,
Licenze,
FileUpload
}
}
+2
View File
@@ -18,6 +18,8 @@ namespace Core
public string ContactPhone { get; set; } = "";
public int idxSubLic { get; set; } = 0;
public TipologiaTicket Tipo { get; set; } = TipologiaTicket.ND;
public bool IsValid
{
get => !string.IsNullOrEmpty(MasterKey) && !string.IsNullOrEmpty(ContactEmail) && !string.IsNullOrEmpty(CodInst) && !string.IsNullOrEmpty(CodApp);
+10
View File
@@ -0,0 +1,10 @@
namespace Core
{
public class UploadResult
{
public bool Uploaded { get; set; }
public string? FileName { get; set; }
public string? StoredFileName { get; set; }
public int ErrorCode { get; set; }
}
}
+197
View File
@@ -0,0 +1,197 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Core;
using LiMan.APi.Data;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace LiMan.APi.Controllers
{
/// <summary>
/// Controller caricamento file
/// </summary>
[ApiController]
[Route("api/filesave")]
public class FilesaveController : ControllerBase
{
private readonly IWebHostEnvironment env;
private readonly ILogger<FilesaveController> logger;
/// <summary>
/// Dataservice x accesso DB
/// </summary>
protected ApiDataService dataService { get; set; }
/// <summary>
/// Init generico
/// </summary>
/// <param name="DataService"></param>
public FilesaveController(ApiDataService DataService, IWebHostEnvironment env, ILogger<FilesaveController> logger)
{
dataService = DataService;
this.env = env;
this.logger = logger;
logger.LogInformation("Avviata classe FilesaveController");
}
/// <summary>
/// Caricamento file effettivo via POST
/// </summary>
/// <param name="ticketId">TicketId x riferimento</param>
/// <param name="files">Elenco files da caricare</param>
/// <returns></returns>
[HttpPost("single")]
public async Task<ActionResult<UploadResult>> PostSingleFile([FromForm] int ticketId, [FromForm] IFormFile file)
{
// max 20 mb
long maxFileSize = 1024 * 1024 * 20;
string ticketDir = $"T{ticketId:000000000}";
var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/api/filesave/{ticketDir}");
List<UploadResult> uploadResults = new();
string fileDir = env.ContentRootPath;
string relDir = env.EnvironmentName;
var uploadResult = new UploadResult();
string trustedFileNameForFileStorage;
var untrustedFileName = file.FileName;
uploadResult.FileName = untrustedFileName;
var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName);
if (file.Length == 0)
{
logger.LogInformation("{FileName} length is 0 (Err: 1)", trustedFileNameForDisplay);
uploadResult.ErrorCode = 1;
}
else if (file.Length > maxFileSize)
{
logger.LogInformation("{FileName} of {Length} bytes is larger than the limit of {Limit} bytes (Err: 2)", trustedFileNameForDisplay, file.Length, maxFileSize);
uploadResult.ErrorCode = 2;
}
else
{
try
{
DateTime oggi = DateTime.Today;
trustedFileNameForFileStorage = Path.GetRandomFileName();
relDir = Path.Combine(env.EnvironmentName, "unsafe_uploads", ticketDir);
fileDir = Path.Combine(env.ContentRootPath, relDir);
//string fileDir = Path.Combine(env.ContentRootPath, env.EnvironmentName, "unsafe_uploads", $"{oggi:yyyy}", $"{oggi:MM}", $"{oggi:dd}");
if (!Directory.Exists(fileDir))
{
Directory.CreateDirectory(fileDir);
}
var path = Path.Combine(fileDir, trustedFileNameForFileStorage);
await using FileStream fs = new(path, FileMode.Create);
await file.CopyToAsync(fs);
logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path);
uploadResult.Uploaded = true;
uploadResult.StoredFileName = trustedFileNameForFileStorage;
}
catch (IOException ex)
{
logger.LogError("{FileName} error on upload (Err: 3): {Message}", trustedFileNameForDisplay, ex.Message);
uploadResult.ErrorCode = 3;
}
}
uploadResults.Add(uploadResult);
// salvo su DB
var fatto = dataService.FileAdd(ticketId, relDir, uploadResults);
return new CreatedResult(resourcePath, uploadResult);
}
/// <summary>
/// Caricamento file effettivo via POST
/// </summary>
/// <param name="ticketId">TicketId x riferimento</param>
/// <param name="files">Elenco files da caricare</param>
/// <returns></returns>
[HttpPost()]
public async Task<ActionResult<IList<UploadResult>>> PostFiles([FromForm] int ticketId, [FromForm] IEnumerable<IFormFile> files)
{
// max 3 files
var maxAllowedFiles = 3;
// max 20 mb
long maxFileSize = 1024 * 1024 * 20;
var filesProcessed = 0;
string ticketDir = $"T{ticketId:000000000}";
var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/api/filesave/{ticketDir}");
List<UploadResult> uploadResults = new();
string fileDir = env.ContentRootPath;
string relDir = env.EnvironmentName;
foreach (var file in files)
{
var uploadResult = new UploadResult();
string trustedFileNameForFileStorage;
var untrustedFileName = file.FileName;
uploadResult.FileName = untrustedFileName;
var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName);
if (filesProcessed < maxAllowedFiles)
{
if (file.Length == 0)
{
logger.LogInformation("{FileName} length is 0 (Err: 1)", trustedFileNameForDisplay);
uploadResult.ErrorCode = 1;
}
else if (file.Length > maxFileSize)
{
logger.LogInformation("{FileName} of {Length} bytes is larger than the limit of {Limit} bytes (Err: 2)", trustedFileNameForDisplay, file.Length, maxFileSize);
uploadResult.ErrorCode = 2;
}
else
{
try
{
DateTime oggi = DateTime.Today;
trustedFileNameForFileStorage = Path.GetRandomFileName();
relDir = Path.Combine(env.EnvironmentName, "unsafe_uploads", ticketDir);
fileDir = Path.Combine(env.ContentRootPath, relDir);
//string fileDir = Path.Combine(env.ContentRootPath, env.EnvironmentName, "unsafe_uploads", $"{oggi:yyyy}", $"{oggi:MM}", $"{oggi:dd}");
if (!Directory.Exists(fileDir))
{
Directory.CreateDirectory(fileDir);
}
var path = Path.Combine(fileDir, trustedFileNameForFileStorage);
await using FileStream fs = new(path, FileMode.Create);
await file.CopyToAsync(fs);
logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path);
uploadResult.Uploaded = true;
uploadResult.StoredFileName = trustedFileNameForFileStorage;
}
catch (IOException ex)
{
logger.LogError("{FileName} error on upload (Err: 3): {Message}", trustedFileNameForDisplay, ex.Message);
uploadResult.ErrorCode = 3;
}
}
filesProcessed++;
}
else
{
logger.LogInformation("{FileName} not uploaded because the request exceeded the allowed {Count} of files (Err: 4)", trustedFileNameForDisplay, maxAllowedFiles);
uploadResult.ErrorCode = 4;
}
uploadResults.Add(uploadResult);
}
// salvo su DB
var fatto = dataService.FileAdd(ticketId, relDir, uploadResults);
return new CreatedResult(resourcePath, uploadResults);
}
}
}
+1 -1
View File
@@ -74,7 +74,7 @@ namespace LiMan.APi.Controllers
/// <param name="AppInfo">Info licenza in formato LicenseCoord</param>
/// <returns></returns>
[HttpPost()]
public async Task<List<DB.DTO.ApplicativoDTO>> Get([FromBody] LicenseCoord AppInfo)
public async Task<List<DB.DTO.ApplicativoDTO>> Post([FromBody] LicenseCoord AppInfo)
{
var result = await dataService.LicenzeSearch(AppInfo.CodInst, AppInfo.CodApp, AppInfo.MasterKey, false);
await dataService.recordCall(AppInfo.CodInst, AppInfo.CodApp, $"POST:api/licenza:{AppInfo.MasterKey}");
+5 -4
View File
@@ -54,7 +54,7 @@ namespace LiMan.APi.Controllers
/// GET api/ticket/id
/// <summary>
/// Recupera elenco applicativi dati cliente
/// Recupera elenco Ticket dato cliente / applicazione / chiave
/// </summary>
/// <param name="id">Codice cliente/Installazione</param>
/// <param name="CodApp">Codice Applicazione</param>
@@ -74,9 +74,9 @@ namespace LiMan.APi.Controllers
/// <param name="CurrRequest">Obj Richiesta</param>
// POST api/ticket/sendReq
[HttpPost("sendReq")]
public async Task<List<TicketDTO>> sendReq([FromBody] SupportRequest CurrRequest)
public async Task<TicketDTO> sendReq([FromBody] SupportRequest CurrRequest)
{
List<TicketDTO> result = new List<TicketDTO>();
TicketDTO result = new TicketDTO();
// controllo valori
if (CurrRequest.IsValid)
{
@@ -84,7 +84,8 @@ namespace LiMan.APi.Controllers
var insRes = await dataService.TicketAdd(CurrRequest);
}
// restituisco richieste aperte
result = await dataService.TicketByCliente(CurrRequest.CodInst, CurrRequest.CodApp, CurrRequest.MasterKey);
var rawResult= await dataService.TicketByCliente(CurrRequest.CodInst, CurrRequest.CodApp, CurrRequest.MasterKey, 1);
result = rawResult.FirstOrDefault();
await dataService.recordCall(CurrRequest.CodInst, CurrRequest.CodApp, $"POST:api/ticket/sendReq:{CurrRequest.MasterKey}");
return result;
}
+305 -242
View File
@@ -1,20 +1,19 @@
using Core;
using LiMan.DB.DBModels;
using LiMan.DB.DTO;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis.Extensions.Core.Abstractions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static LiMan.DB.Enum;
using StackExchange.Redis.Extensions.Core.Abstractions;
using LiMan.DB.DTO;
namespace LiMan.APi.Data
{
@@ -23,48 +22,24 @@ namespace LiMan.APi.Data
/// </summary>
public class ApiDataService : IDisposable
{
#region Public Fields
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
public static LiMan.DB.Controllers.DbController dbController;
#endregion Public Fields
#region Protected Fields
/// <summary>
/// TTL da 1 h x cache Redis
/// </summary>
protected const int hourTTL = 60 * 60;
/// <summary>
/// Chiave redis x statistiche in acquisizione
/// </summary>
protected const string rKeySampleStats = "LiMan.UI:SampleStats:Curr";
/// <summary>
/// Chiave redis x statistiche in acquisizione
/// </summary>
protected const string rKeySampleVars = "LiMan.UI:SampleStats:Vars";
/// <summary>
/// Chiave redis x licenze da MasterKey
/// </summary>
protected const string rKeyLicenze = "LiMan.UI:Licenze:ListByKey";
#endregion Protected Fields
#region Private Fields
private static IConfiguration _configuration;
private static ILogger<ApiDataService> _logger;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private readonly IEmailSender _emailSender;
//private readonly IDistributedCache distributedCache;
private readonly IRedisCacheClient _redisCacheClient;
/// <summary>
/// Elenco obj in cache
/// </summary>
private List<string> cachedDataList = new List<string>();
/// <summary>
/// Durata assoluta massima della cache IN SECONDI
/// </summary>
@@ -78,6 +53,49 @@ namespace LiMan.APi.Data
#endregion Private Fields
#region Protected Fields
/// <summary>
/// TTL da 1 h x cache Redis
/// </summary>
protected const int hourTTL = 60 * 60;
/// <summary>
/// Chiave redis x attivazioni da IdxLic
/// </summary>
protected const string rKeyAttivByLic = "LiMan.UI:Licenze:AttByIdxLic";
/// <summary>
/// Chiave redis x licenze da MasterKey
/// </summary>
protected const string rKeyLicByMKey = "LiMan.UI:Licenze:ListByKey";
/// <summary>
/// Chiave redis x statistiche in acquisizione
/// </summary>
protected const string rKeySampleStats = "LiMan.UI:SampleStats:Curr";
/// <summary>
/// Chiave redis x statistiche in acquisizione
/// </summary>
protected const string rKeySampleVars = "LiMan.UI:SampleStats:Vars";
/// <summary>
/// TTL da 1 min x cache Redis
/// </summary>
protected const int shortTTL = 60 * 5;
#endregion Protected Fields
#region Public Fields
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
public static LiMan.DB.Controllers.DbController dbController;
#endregion Public Fields
#region Public Constructors
/// <summary>
@@ -112,6 +130,174 @@ namespace LiMan.APi.Data
#endregion Public Constructors
#region Private Methods
/// <summary>
/// Parametri per generare opzioni cache
/// </summary>
/// <param name="multFact">Fattore di moltiplica cache (se 1 --> 2 e 5 min)</param>
/// <returns></returns>
private DistributedCacheEntryOptions cacheOpt(int multFact)
{
var numSecAbsExp = multFact <= 0 ? chAbsExp : chAbsExp * multFact;
var numSecSliExp = multFact <= 0 ? chSliExp : chSliExp * multFact;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
#endregion Private Methods
#region Protected Methods
/// <summary>
/// Recupera statistiche correnti
/// </summary>
/// <returns></returns>
protected async Task<SampleStats> getCurrStats()
{
DateTime adesso = DateTime.Now;
SampleStats answ = new SampleStats()
{
Name = "ApiStats"
};
// in primis check data/ora prima/ultima scrittura del set... (2 date, lista chiavi gestite)
string rawData = await getRSV(rKeySampleStats);
if (rawData != null)
{
answ = JsonConvert.DeserializeObject<SampleStats>(rawData);
// aggiorno ultimo controllo e salvo...
answ.DtLast = adesso;
// salvo!
await setCurrStats(answ);
}
// controllo se scadute...
if (adesso.Subtract(answ.DtFirst).TotalMinutes > 60)
{
// se scaduto --> registrazione set sul DB (async), resettando i vari contatori...
bool salvato = await saveStatsToDb(answ.VList);
// inizio NUOVO set vuoto con record corrente
answ = new SampleStats()
{
Name = "ApiStats"
};
// salvo!
await setCurrStats(answ);
}
// restituisco record!
return answ;
}
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync<string>(rKey);
return answ;
}
/// <summary>
/// Recupera contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<int> redCount(string rKey)
{
int currCount = 0;
string rawVal = await getRSV(rKey);
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out currCount);
}
return currCount;
}
/// <summary>
/// Resetta contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<bool> redCountClear(string rKey)
{
bool answ = false;
int currCount = 0;
answ = await setRSV(rKey, currCount, 2 * hourTTL);
return answ;
}
/// <summary>
/// Incrementa contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<bool> redCountIncr(string rKey)
{
bool answ = false;
int currCount = 0;
string rawVal = await getRSV(rKey);
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out currCount);
}
currCount++;
answ = await setRSV(rKey, currCount, 2 * hourTTL);
return answ;
}
/// <summary>
/// Salva statistiche correnti
/// </summary>
/// <returns></returns>
protected async Task<bool> setCurrStats(SampleStats newVal)
{
bool answ = false;
string rawData = JsonConvert.SerializeObject(newVal);
answ = await setRSV(rKeySampleStats, rawData, 24 * hourTTL);
return answ;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rVal"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, string rVal, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rValInt"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, int rValInt, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync<int>(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
@@ -121,9 +307,9 @@ namespace LiMan.APi.Data
/// <param name="CodApp">Codice Applicazione</param>
/// <param name="HideData">Indica se nascondere i dati sensibili</param>
/// <returns></returns>
public async Task<List<DB.DTO.ApplicativoDTO>> ApplicativiSearch(string CodInst, string CodApp, bool HideData)
public async Task<List<ApplicativoDTO>> ApplicativiSearch(string CodInst, string CodApp, bool HideData)
{
List<DB.DTO.ApplicativoDTO> dbResult = new List<DB.DTO.ApplicativoDTO>();
List<ApplicativoDTO> dbResult = new List<ApplicativoDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
@@ -142,9 +328,9 @@ namespace LiMan.APi.Data
/// <param name="CodImpiego">Codice Impiego licenza</param>
/// <param name="HideData">Indica se nascondere i dati sensibili</param>
/// <returns></returns>
public async Task<DB.DTO.AttivazioneDTO> AttivazioneSearch(string Chiave, string CodImpiego, bool HideData)
public async Task<AttivazioneDTO> AttivazioneSearch(string Chiave, string CodImpiego, bool HideData)
{
DB.DTO.AttivazioneDTO dbResult = new DB.DTO.AttivazioneDTO();
AttivazioneDTO dbResult = new AttivazioneDTO();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
@@ -160,20 +346,30 @@ namespace LiMan.APi.Data
/// <summary>
/// Elenco Attivaizoni da ID Licenza master
/// </summary>
/// <param name="IdxLic">Idx Licenza Master</param>
/// <param name="HideData">Indica se nascondere i dati sensibili</param>
/// <param name="idxLic">Idx Licenza Master</param>
/// <param name="hideData">Indica se nascondere i dati sensibili</param>
/// <returns></returns>
public async Task<List<DB.DTO.AttivazioneDTO>> AttivazioniByLic(int IdxLic, bool HideData)
public async Task<List<AttivazioneDTO>> AttivazioniByLic(int idxLic, bool hideData)
{
List<DB.DTO.AttivazioneDTO> dbResult = new List<DB.DTO.AttivazioneDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.GetAttivazioniByLic(IdxLic, HideData);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AttivazioniByLic: {ts.TotalMilliseconds} ms");
List<AttivazioneDTO> dbResult = new List<AttivazioneDTO>();
string cacheKey = $"{rKeyAttivByLic}:{hideData}:{idxLic}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<AttivazioneDTO>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.GetAttivazioniByLic(idxLic, hideData);
rawData = JsonConvert.SerializeObject(dbResult);
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AttivazioniByLic: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(dbResult);
}
@@ -184,21 +380,24 @@ namespace LiMan.APi.Data
/// <param name="MasterKey">Licenza Master</param>
/// <param name="HideData">Indica se nascondere i dati sensibili</param>
/// <returns></returns>
public async Task<List<DB.DTO.AttivazioneDTO>> AttivazioniByMasterKey(string MasterKey, bool HideData)
public async Task<List<AttivazioneDTO>> AttivazioniByMasterKey(string MasterKey, bool HideData)
{
List<DB.DTO.AttivazioneDTO> dbResult = new List<DB.DTO.AttivazioneDTO>();
List<AttivazioneDTO> dbResult = new List<AttivazioneDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var licenza = dbController.GetLicenza(MasterKey);
#if false
LicenzaModel licenza = dbController.GetLicenza(MasterKey);
#endif
LicenzaModel licenza = await LicenzaByMasterKey(MasterKey);
if (licenza != null)
{
dbResult = dbController.GetAttivazioniByLic(licenza.IdxLic, HideData);
dbResult = await AttivazioniByLic(licenza.IdxLic, HideData);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AttivazioniByLic: {ts.TotalMilliseconds} ms");
Log.Trace($"Effettuata lettura da DB per AttivazioniByMasterKey: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
@@ -215,11 +414,11 @@ namespace LiMan.APi.Data
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var licenza = dbController.GetLicenza(MasterKey);
LicenzaModel licenza = await LicenzaByMasterKey(MasterKey);
if (licenza != null)
{
answ = dbController.AttivazioniDelete(ParamDict, MasterKey);
await InvalidateAllCache();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
@@ -239,11 +438,12 @@ namespace LiMan.APi.Data
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
LicenzaModel licenza = await LicenzaByMasterKey(MasterKey);
var licenza = dbController.GetLicenza(MasterKey);
if (licenza != null)
{
answ = dbController.AttivazioniResetAvail(MasterKey);
await InvalidateAllCache();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
@@ -268,6 +468,7 @@ namespace LiMan.APi.Data
stopWatch.Start();
taskDone = dbController.AttivazioniTryAdd(MasterKey, ParamDict, DayVeto);
await InvalidateAllCache();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata scrittura + rilettura da DB per AttivazioniTryAdd: {ts.TotalMilliseconds} ms");
@@ -290,6 +491,7 @@ namespace LiMan.APi.Data
stopWatch.Start();
taskDone = dbController.AttivazioniTryRefresh(MasterKey, ParamDict);
await InvalidateAllCache();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata scrittura + rilettura da DB per AttivazioniTryRefresh: {ts.TotalMilliseconds} ms");
@@ -306,6 +508,41 @@ namespace LiMan.APi.Data
dbController.Dispose();
}
/// <summary>
/// Esegue aggiunta file dato ticket e list uploadResult
/// </summary>
/// <param name="idxTicket">Identificativo del ticket</param>
/// <param name="baseDir">Directory di salvataggio dei file</param>
/// <param name="fileUploaded">lista risultati della funzione di upload</param>
/// <returns></returns>
public async Task<bool> FileAdd(int idxTicket, string baseDir, List<UploadResult> fileUploaded)
{
bool fatto = false;
// inserimento!
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
fatto = dbController.FileAdd(idxTicket, baseDir, fileUploaded);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata inserimento con FileAdd: {ts.TotalMilliseconds} ms");
// restituisce elenco
return await Task.FromResult(fatto);
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
foreach (var item in cachedDataList)
{
await _redisCacheClient.GetDbFromConfiguration().RemoveAsync(item);
}
cachedDataList = new List<string>();
}
/// <summary>
/// Elenco licenze dato cliente
/// </summary>
@@ -314,7 +551,8 @@ namespace LiMan.APi.Data
public async Task<LicenzaModel> LicenzaByMasterKey(string chiave)
{
LicenzaModel dbResult = new LicenzaModel();
string cacheKey = $"{rKeyLicenze}:{chiave}";
string cacheKey = $"{rKeyLicByMKey}:{chiave}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
@@ -340,10 +578,11 @@ namespace LiMan.APi.Data
/// </summary>
/// <param name="appInfo"></param>
/// <returns></returns>
public async Task<DB.DTO.ApplicativoDTO> LicenzaRefreshPayload(LicenseCoord appInfo)
public async Task<ApplicativoDTO> LicenzaRefreshPayload(LicenseCoord appInfo)
{
// chiamo metodo x ricalcolare payload dato enigma
bool done = await dbController.LicenseUpdatePayload(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, appInfo.Enigma);
await InvalidateAllCache();
// ora recupero i dati
var licList = await LicenzeSearch(appInfo.CodInst, appInfo.CodApp, appInfo.MasterKey, false);
return licList.FirstOrDefault();
@@ -376,9 +615,9 @@ namespace LiMan.APi.Data
/// <param name="Chiave">Chiave Licenza da validare</param>
/// <param name="HideData">Indica se nascondere i dati sensibili</param>
/// <returns></returns>
public async Task<List<DB.DTO.ApplicativoDTO>> LicenzeSearch(string CodInst, string CodApp, string Chiave, bool HideData)
public async Task<List<ApplicativoDTO>> LicenzeSearch(string CodInst, string CodApp, string Chiave, bool HideData)
{
List<DB.DTO.ApplicativoDTO> dbResult = new List<DB.DTO.ApplicativoDTO>();
List<ApplicativoDTO> dbResult = new List<ApplicativoDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
@@ -452,7 +691,7 @@ namespace LiMan.APi.Data
{
CodInst = valStr[0],
CodApp = valStr[1],
TargetUrl = valStr[2],
TargetUrl = item.Replace($"{rKeySampleVars}:", ""), //valStr[2],
DataRif = DateTime.Now,
NumCall = currCount
};
@@ -516,13 +755,13 @@ namespace LiMan.APi.Data
/// <param name="MasterKey"></param>
/// <param name="numRec"></param>
/// <returns></returns>
public async Task<List<TicketDTO>> TicketByCliente(string CodInst, string CodApp, string MasterKey, int numRec = 50)
public async Task<List<TicketDTO>> TicketByCliente(string CodInst, string CodApp, string MasterKey, int numRec = 10)
{
List<TicketDTO> dbResult = new List<TicketDTO>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.TicketGetFilt(true, CodApp, CodInst, MasterKey, numRec);
dbResult = dbController.TicketGetFilt(true, TipologiaTicket.ND, CodApp, CodInst, MasterKey, numRec);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per TicketByCliente: {ts.TotalMilliseconds} ms");
@@ -553,181 +792,5 @@ namespace LiMan.APi.Data
#endregion Public Methods
#region Protected Methods
/// <summary>
/// Recupera statistiche correnti
/// </summary>
/// <returns></returns>
protected async Task<SampleStats> getCurrStats()
{
DateTime adesso = DateTime.Now;
SampleStats answ = new SampleStats()
{
Name = "ApiStats"
};
// in primis check data/ora prima/ultima scrittura del set... (2 date, lista chiavi gestite)
string rawData = await getRSV(rKeySampleStats);
if (rawData != null)
{
answ = JsonConvert.DeserializeObject<SampleStats>(rawData);
// aggiorno ultimo controllo e salvo...
answ.DtLast = adesso;
// salvo!
await setCurrStats(answ);
}
// controllo se scadute...
if (adesso.Subtract(answ.DtFirst).TotalMinutes > 60)
{
// se scaduto --> registrazione set sul DB (async), resettando i vari contatori...
bool salvato = await saveStatsToDb(answ.VList);
// inizio NUOVO set vuoto con record corrente
answ = new SampleStats()
{
Name = "ApiStats"
};
// salvo!
await setCurrStats(answ);
}
// restituisco record!
return answ;
}
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync<string>(rKey);
return answ;
}
/// <summary>
/// Resetta contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<bool> redCountClear(string rKey)
{
bool answ = false;
int currCount = 0;
answ = await setRSV(rKey, currCount, 2 * hourTTL);
return answ;
}
/// <summary>
/// Recupera contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<int> redCount(string rKey)
{
int currCount = 0;
string rawVal = await getRSV(rKey);
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out currCount);
}
return currCount;
}
/// <summary>
/// Incrementa contatore x la chiave redis indicata...
/// </summary>
/// <returns></returns>
protected async Task<bool> redCountIncr(string rKey)
{
bool answ = false;
int currCount = 0;
string rawVal = await getRSV(rKey);
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out currCount);
}
currCount++;
answ = await setRSV(rKey, currCount, 2 * hourTTL);
return answ;
}
/// <summary>
/// Salva statistiche correnti
/// </summary>
/// <returns></returns>
protected async Task<bool> setCurrStats(SampleStats newVal)
{
bool answ = false;
string rawData = JsonConvert.SerializeObject(newVal);
answ = await setRSV(rKeySampleStats, rawData, 24 * hourTTL);
return answ;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rVal"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, string rVal, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rValInt"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, int rValInt, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync<int>(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
#endregion Protected Methods
#region Private Methods
/// <summary>
/// Parametri per generare opzioni cache
/// </summary>
/// <param name="multFact">Fattore di moltiplica cache (se 1 --> 2 e 5 min)</param>
/// <returns></returns>
private DistributedCacheEntryOptions cacheOpt(int multFact)
{
var numSecAbsExp = multFact <= 0 ? chAbsExp : chAbsExp * multFact;
var numSecSliExp = multFact <= 0 ? chSliExp : chSliExp * multFact;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
#endregion Private Methods
#if false
/// <summary>
/// Elenco ticket dato licenza (limitato a maxRec)
/// </summary>
/// <param name="idxLic"></param>
/// <param name="maxRec"></param>
/// <returns></returns>
public async Task<List<LiMan.DB.DBModels.TicketModel>> TicketByLic(int idxLic, int maxRec = 100)
{
List<DB.DBModels.TicketModel> dbResult = new List<DB.DBModels.TicketModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.TicketGetByLic(idxLic, maxRec);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per TicketByLic: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
#endif
}
}
@@ -0,0 +1 @@

+9
View File
@@ -31,11 +31,20 @@
</ItemGroup>
<ItemGroup>
<None Update="Development\unsafe_uploads\.placeholder.file">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="LiMan.APi.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="logs\.placeholder.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Production\unsafe_uploads\.placeholder.file">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Staging\unsafe_uploads\.placeholder.file">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+156 -88
View File
@@ -93,6 +93,38 @@
<param name="codImpiego">Codice univoco impiego licenza</param>
<returns></returns>
</member>
<member name="T:LiMan.APi.Controllers.FilesaveController">
<summary>
Controller caricamento file
</summary>
</member>
<member name="P:LiMan.APi.Controllers.FilesaveController.dataService">
<summary>
Dataservice x accesso DB
</summary>
</member>
<member name="M:LiMan.APi.Controllers.FilesaveController.#ctor(LiMan.APi.Data.ApiDataService,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,Microsoft.Extensions.Logging.ILogger{LiMan.APi.Controllers.FilesaveController})">
<summary>
Init generico
</summary>
<param name="DataService"></param>
</member>
<member name="M:LiMan.APi.Controllers.FilesaveController.PostSingleFile(System.Int32,Microsoft.AspNetCore.Http.IFormFile)">
<summary>
Caricamento file effettivo via POST
</summary>
<param name="ticketId">TicketId x riferimento</param>
<param name="files">Elenco files da caricare</param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Controllers.FilesaveController.PostFiles(System.Int32,System.Collections.Generic.IEnumerable{Microsoft.AspNetCore.Http.IFormFile})">
<summary>
Caricamento file effettivo via POST
</summary>
<param name="ticketId">TicketId x riferimento</param>
<param name="files">Elenco files da caricare</param>
<returns></returns>
</member>
<member name="T:LiMan.APi.Controllers.InstallazioniController">
<summary>
Controller livello INSTALLAZIONI
@@ -153,7 +185,7 @@
<param name="Chiave">Chiave licenza da validare</param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Controllers.LicenzaController.Get(Core.LicenseCoord)">
<member name="M:LiMan.APi.Controllers.LicenzaController.Post(Core.LicenseCoord)">
POST api/licenza
<summary>
Recupera dati Licenza Applicativa (id licenza + num utenze) dati cliente + programma + licenza ATTUALE
@@ -192,7 +224,7 @@
<member name="M:LiMan.APi.Controllers.TicketController.Get(System.String,System.String,System.String)">
GET api/ticket/id
<summary>
Recupera elenco applicativi dati cliente
Recupera elenco Ticket dato cliente / applicazione / chiave
</summary>
<param name="id">Codice cliente/Installazione</param>
<param name="CodApp">Codice Applicazione</param>
@@ -210,29 +242,9 @@
Classe astrazione accesso dati
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.dbController">
<member name="F:LiMan.APi.Data.ApiDataService.cachedDataList">
<summary>
Classe Accesso metodi DB
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.hourTTL">
<summary>
TTL da 1 h x cache Redis
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeySampleStats">
<summary>
Chiave redis x statistiche in acquisizione
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeySampleVars">
<summary>
Chiave redis x statistiche in acquisizione
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeyLicenze">
<summary>
Chiave redis x licenze da MasterKey
Elenco obj in cache
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.chAbsExp">
@@ -246,6 +258,41 @@
NON estende oltre il tempo massimo di validità della cache (chAbsExp)
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.hourTTL">
<summary>
TTL da 1 h x cache Redis
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeyAttivByLic">
<summary>
Chiave redis x attivazioni da IdxLic
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeyLicByMKey">
<summary>
Chiave redis x licenze da MasterKey
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeySampleStats">
<summary>
Chiave redis x statistiche in acquisizione
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.rKeySampleVars">
<summary>
Chiave redis x statistiche in acquisizione
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.shortTTL">
<summary>
TTL da 1 min x cache Redis
</summary>
</member>
<member name="F:LiMan.APi.Data.ApiDataService.dbController">
<summary>
Classe Accesso metodi DB
</summary>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILogger{LiMan.APi.Data.ApiDataService},Microsoft.AspNetCore.Identity.UI.Services.IEmailSender,StackExchange.Redis.Extensions.Core.Abstractions.IRedisCacheClient)">
<summary>
Init classe
@@ -256,6 +303,74 @@
<param name="emailSender"></param>
<param name="redisCacheClient"></param>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.cacheOpt(System.Int32)">
<summary>
Parametri per generare opzioni cache
</summary>
<param name="multFact">Fattore di moltiplica cache (se 1 --> 2 e 5 min)</param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.getCurrStats">
<summary>
Recupera statistiche correnti
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.getRSV(System.String)">
<summary>
Recupero chiave da redis
</summary>
<param name="rKey"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCount(System.String)">
<summary>
Recupera contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCountClear(System.String)">
<summary>
Resetta contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCountIncr(System.String)">
<summary>
Incrementa contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setCurrStats(Core.SampleStats)">
<summary>
Salva statistiche correnti
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setRSV(System.String,System.String,System.Int32)">
<summary>
Salvataggio chiave in redis
</summary>
<param name="rKey"></param>
<param name="rVal"></param>
<param name="ttlSec"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setRSV(System.String,System.Int32,System.Int32)">
<summary>
Salvataggio chiave in redis
</summary>
<param name="rKey"></param>
<param name="rValInt"></param>
<param name="ttlSec"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.trackCache(System.String)">
<summary>
Registra in cache chiave se non fosse già in elenco
</summary>
<param name="newKey"></param>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.ApplicativiSearch(System.String,System.String,System.Boolean)">
<summary>
Elenco licenze dato cliente
@@ -278,8 +393,8 @@
<summary>
Elenco Attivaizoni da ID Licenza master
</summary>
<param name="IdxLic">Idx Licenza Master</param>
<param name="HideData">Indica se nascondere i dati sensibili</param>
<param name="idxLic">Idx Licenza Master</param>
<param name="hideData">Indica se nascondere i dati sensibili</param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.AttivazioniByMasterKey(System.String,System.Boolean)">
@@ -329,6 +444,21 @@
Dispose classe
</summary>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.FileAdd(System.Int32,System.String,System.Collections.Generic.List{Core.UploadResult})">
<summary>
Esegue aggiunta file dato ticket e list uploadResult
</summary>
<param name="idxTicket">Identificativo del ticket</param>
<param name="baseDir">Directory di salvataggio dei file</param>
<param name="fileUploaded">lista risultati della funzione di upload</param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.InvalidateAllCache">
<summary>
invalida tutta la cache in caso di update
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.LicenzaByMasterKey(System.String)">
<summary>
Elenco licenze dato cliente
@@ -416,67 +546,5 @@
<param name="NewStatus"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.getCurrStats">
<summary>
Recupera statistiche correnti
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.getRSV(System.String)">
<summary>
Recupero chiave da redis
</summary>
<param name="rKey"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCountClear(System.String)">
<summary>
Resetta contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCount(System.String)">
<summary>
Recupera contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.redCountIncr(System.String)">
<summary>
Incrementa contatore x la chiave redis indicata...
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setCurrStats(Core.SampleStats)">
<summary>
Salva statistiche correnti
</summary>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setRSV(System.String,System.String,System.Int32)">
<summary>
Salvataggio chiave in redis
</summary>
<param name="rKey"></param>
<param name="rVal"></param>
<param name="ttlSec"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.setRSV(System.String,System.Int32,System.Int32)">
<summary>
Salvataggio chiave in redis
</summary>
<param name="rKey"></param>
<param name="rValInt"></param>
<param name="ttlSec"></param>
<returns></returns>
</member>
<member name="M:LiMan.APi.Data.ApiDataService.cacheOpt(System.Int32)">
<summary>
Parametri per generare opzioni cache
</summary>
<param name="multFact">Fattore di moltiplica cache (se 1 --> 2 e 5 min)</param>
<returns></returns>
</member>
</members>
</doc>
@@ -0,0 +1 @@

@@ -0,0 +1 @@

+76 -6
View File
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Configuration;
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
@@ -277,6 +278,74 @@ namespace LiMan.DB.Controllers
//Log.Info("Dispose di GWMSController");
}
/// <summary>
/// Elenco files attach da registrare
/// </summary>
/// <param name="idxTicket">Identificativo del ticket</param>
/// <param name="baseDir">Directory di salvataggio dei file</param>
/// <param name="fileUploaded">lista risultati della funzione di upload</param>
/// <returns></returns>
public bool FileAdd(int idxTicket, string baseDir, List<UploadResult> fileUploaded)
{
bool fatto = false;
if (fileUploaded == null || fileUploaded.Count == 0)
{
Log.Error("Errore FileAdd: fileUploaded è vuoto/nullo");
}
else
{
using (LMDbContext localDbCtx = new LMDbContext(_configuration))
{
// verifico Ticket sia esistente
var currTicket = localDbCtx
.DbSetTicket
.Where(x => x.IdxTicket == idxTicket)
.FirstOrDefault();
if (currTicket != null)
{
var newFiles = fileUploaded
.Select(x => new FileAttachModel()
{
IdxTicket = idxTicket,
OriginalName = x.FileName,
StorageName = x.StoredFileName,
DtEvent = DateTime.Now,
FullStoragePath = Path.Combine(baseDir, x.StoredFileName)
}).ToList();
localDbCtx
.DbSetFileAttach
.AddRange(newFiles);
localDbCtx.SaveChanges();
fatto = true;
}
}
}
return fatto;
}
/// <summary>
/// Elenco file registrati dato ticket id
/// </summary>
/// <param name="idxTicket">Identificativo del ticket</param>
/// <returns></returns>
public List<FileAttachModel> FileGetFilt(int idxTicket)
{
List<FileAttachModel> dbResult = new List<FileAttachModel>();
using (LMDbContext localDbCtx = new LMDbContext(_configuration))
{
// recupero locenza...
dbResult = localDbCtx
.DbSetFileAttach
.Where(x => x.IdxTicket == idxTicket)
.ToList();
}
return dbResult;
}
public List<ApplicativoDTO> GetApplicativiFilt(bool OnlyActive, string CodApp, string CodInst, bool hideData)
{
List<ApplicativoDTO> dbResult = new List<ApplicativoDTO>();
@@ -775,7 +844,8 @@ namespace LiMan.DB.Controllers
ContactPhone = currRequest.ContactPhone,
ReqBody = currRequest.ReqBody,
Status = Enum.StatoRichiesta.Richiesta,
Tipo = Enum.TipoLicenza.UserKey
Tipo = Enum.TipoLicenza.UserKey,
TType = currRequest.Tipo
};
localDbCtx
@@ -790,12 +860,12 @@ namespace LiMan.DB.Controllers
return fatto;
}
public List<TicketDTO> TicketGetFilt(bool onlyOpen, string CodApp, string CodInst, string MasterKey, int maxNum)
public List<TicketDTO> TicketGetFilt(bool onlyOpen, TipologiaTicket Tipo, string CodApp, string CodInst, string MasterKey, int maxNum)
{
List<TicketDTO> dbResult = new List<TicketDTO>();
using (LMDbContext localDbCtx = new LMDbContext(_configuration))
{
// recupero locenza...
// recupero licenza...
var currLic = localDbCtx
.DbSetLicenze
.Where(x => x.CodApp == CodApp && x.CodInst == CodInst && x.Chiave == MasterKey)
@@ -805,8 +875,8 @@ namespace LiMan.DB.Controllers
{
dbResult = localDbCtx
.DbSetTicket
.Where(x => x.IdxLic == currLic.IdxLic)
.OrderByDescending(x => x.DtReq)
.Where(x => x.IdxLic == currLic.IdxLic && (x.Status <= StatoRichiesta.Valutazione || !onlyOpen) && (x.TType == Tipo || Tipo == TipologiaTicket.ND))
.OrderByDescending(x => x.IdxTicket)
.Take(maxNum)
.Select(x => new TicketDTO
{
@@ -823,7 +893,7 @@ namespace LiMan.DB.Controllers
SupplAnsw = x.SupplAnsw,
SupplEmail = x.SupplEmail,
SupplUserCode = x.SupplUserCode,
Tipo= x.Tipo
Tipo = x.Tipo
})
.ToList();
}
+53
View File
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using static LiMan.DB.Enum;
#nullable disable
namespace LiMan.DB.DBModels
{
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
//[Index(nameof(Installazione), nameof(Active), nameof(DiskStatus))]
[Table("FileAttach")]
public partial class FileAttachModel
{
#region Public Properties
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdxFileAttach { get; set; }
/// <summary>
/// Id del ticket cui è collegato
/// </summary>
public int IdxTicket { get; set; }
/// <summary>
/// DataOra evento
/// </summary>
public DateTime DtEvent { get; set; } = DateTime.Now;
/// <summary>
/// Codice univoco della sub licenza (opzionale)
/// </summary>
public string OriginalName { get; set; } = "";
/// <summary>
/// Nome con cui è salvato il file localmente
/// </summary>
public string StorageName { get; set; } = "";
/// <summary>
/// Path completo del file
/// </summary>
public string FullStoragePath { get; set; } = "";
[ForeignKey("IdxTicket")]
public virtual TicketModel TicketNav { get; set; }
#endregion Public Properties
}
}
+7 -3
View File
@@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using Core;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using static LiMan.DB.Enum;
@@ -11,7 +11,6 @@ namespace LiMan.DB.DBModels
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
//[Index(nameof(Installazione), nameof(Active), nameof(DiskStatus))]
[Table("TicketLog")]
public partial class TicketModel
{
@@ -22,6 +21,11 @@ namespace LiMan.DB.DBModels
public DateTime DtReq { get; set; } = DateTime.Now;
/// <summary>
/// Tipologia di ticket
/// </summary>
public TipologiaTicket TType { get; set; } = TipologiaTicket.Licenze;
/// <summary>
/// Tipologia di licenza gestita
/// </summary>
+2
View File
@@ -51,6 +51,8 @@ namespace LiMan.DB
CheckSumKey
}
#endregion Public Enums
}
}
+2 -1
View File
@@ -49,6 +49,7 @@ namespace LiMan.DB
#region Public Properties
public virtual DbSet<ApplicativoModel> DbSetApp { get; set; }
public virtual DbSet<FileAttachModel> DbSetFileAttach { get; set; }
public virtual DbSet<InstallazioneModel> DbSetInst { get; set; }
public virtual DbSet<LicenzaModel> DbSetLicenze { get; set; }
public virtual DbSet<LogCallModel> DbSetLogCall { get; set; }
@@ -57,7 +58,7 @@ namespace LiMan.DB
public virtual DbSet<TicketModel> DbSetTicket { get; set; }
#endregion Public Properties
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
@@ -0,0 +1,371 @@
// <auto-generated />
using System;
using LiMan.DB;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace LiMan.DB.Migrations
{
[DbContext(typeof(LMDbContext))]
[Migration("20211220181913_AddFileAttach")]
partial class AddFileAttach
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.10")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("LiMan.DB.DBModels.ApplicativoModel", b =>
{
b.Property<string>("CodApp")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Descrizione")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.HasKey("CodApp");
b.ToTable("Applicativi");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.Property<int>("IdxFileAttach")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DtEvent")
.HasColumnType("datetime2");
b.Property<string>("FullStoragePath")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxTicket")
.HasColumnType("int");
b.Property<string>("OriginalName")
.HasColumnType("nvarchar(max)");
b.Property<string>("StorageName")
.HasColumnType("nvarchar(max)");
b.HasKey("IdxFileAttach");
b.HasIndex("IdxTicket");
b.ToTable("FileAttach");
});
modelBuilder.Entity("LiMan.DB.DBModels.InstallazioneModel", b =>
{
b.Property<string>("CodInst")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Cliente")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Contatto")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Descrizione")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Email")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.HasKey("CodInst");
b.ToTable("Installazioni");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.Property<int>("IdxLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(50)");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(50)");
b.Property<DateTime>("DataEnigma")
.HasColumnType("datetime2");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<string>("Enigma")
.HasColumnType("nvarchar(max)");
b.Property<bool>("Locked")
.HasColumnType("bit");
b.Property<int>("NumLicenze")
.HasColumnType("int");
b.Property<string>("Payload")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("Scadenza")
.HasColumnType("datetime2");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxLic");
b.HasIndex("CodApp");
b.HasIndex("CodInst");
b.ToTable("Licenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogCallModel", b =>
{
b.Property<DateTime>("DataRif")
.HasColumnType("datetime2");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(450)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(450)");
b.Property<string>("TargetUrl")
.HasColumnType("nvarchar(450)");
b.Property<int>("NumCall")
.HasColumnType("int");
b.HasKey("DataRif", "CodInst", "CodApp", "TargetUrl");
b.ToTable("LogCall");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
{
b.Property<int>("IdxLogLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(50)");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(50)");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("NumLicenze")
.HasColumnType("int");
b.Property<DateTime>("Scadenza")
.HasColumnType("datetime2");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxLogLic");
b.HasIndex("CodApp");
b.HasIndex("CodInst");
b.HasIndex("IdxLic");
b.ToTable("LogLicenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
{
b.Property<int>("IdxSubLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodImpiego")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("Tipo")
.HasColumnType("int");
b.Property<DateTime>("VetoUnlock")
.HasColumnType("datetime2");
b.HasKey("IdxSubLic");
b.HasIndex("IdxLic");
b.ToTable("SubLicenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
{
b.Property<int>("IdxTicket")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("CodImpiego")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactEmail")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactName")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactPhone")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DtReq")
.HasColumnType("datetime2");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("IdxSubLic")
.HasColumnType("int");
b.Property<string>("ReqBody")
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("SupplAnsw")
.HasColumnType("nvarchar(max)");
b.Property<string>("SupplEmail")
.HasColumnType("nvarchar(max)");
b.Property<string>("SupplUserCode")
.HasColumnType("nvarchar(max)");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxTicket");
b.HasIndex("IdxLic");
b.ToTable("TicketLog");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.HasOne("LiMan.DB.DBModels.TicketModel", "TicketNav")
.WithMany()
.HasForeignKey("IdxTicket")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TicketNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
.WithMany()
.HasForeignKey("CodApp");
b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
.WithMany()
.HasForeignKey("CodInst");
b.Navigation("ApplicativoNav");
b.Navigation("InstallazioneNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
.WithMany()
.HasForeignKey("CodApp");
b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
.WithMany()
.HasForeignKey("CodInst");
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany()
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApplicativoNav");
b.Navigation("InstallazioneNav");
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany("Attivazioni")
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
{
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany("Tickets")
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.Navigation("Attivazioni");
b.Navigation("Tickets");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,45 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace LiMan.DB.Migrations
{
public partial class AddFileAttach : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "FileAttach",
columns: table => new
{
IdxFileAttach = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
IdxTicket = table.Column<int>(type: "int", nullable: false),
DtEvent = table.Column<DateTime>(type: "datetime2", nullable: false),
OriginalName = table.Column<string>(type: "nvarchar(max)", nullable: true),
StorageName = table.Column<string>(type: "nvarchar(max)", nullable: true),
FullStoragePath = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_FileAttach", x => x.IdxFileAttach);
table.ForeignKey(
name: "FK_FileAttach_TicketLog_IdxTicket",
column: x => x.IdxTicket,
principalTable: "TicketLog",
principalColumn: "IdxTicket",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_FileAttach_IdxTicket",
table: "FileAttach",
column: "IdxTicket");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FileAttach");
}
}
}
@@ -0,0 +1,374 @@
// <auto-generated />
using System;
using LiMan.DB;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace LiMan.DB.Migrations
{
[DbContext(typeof(LMDbContext))]
[Migration("20211221090447_UpdTicket_TType")]
partial class UpdTicket_TType
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.10")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("LiMan.DB.DBModels.ApplicativoModel", b =>
{
b.Property<string>("CodApp")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Descrizione")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.HasKey("CodApp");
b.ToTable("Applicativi");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.Property<int>("IdxFileAttach")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DtEvent")
.HasColumnType("datetime2");
b.Property<string>("FullStoragePath")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxTicket")
.HasColumnType("int");
b.Property<string>("OriginalName")
.HasColumnType("nvarchar(max)");
b.Property<string>("StorageName")
.HasColumnType("nvarchar(max)");
b.HasKey("IdxFileAttach");
b.HasIndex("IdxTicket");
b.ToTable("FileAttach");
});
modelBuilder.Entity("LiMan.DB.DBModels.InstallazioneModel", b =>
{
b.Property<string>("CodInst")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Cliente")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Contatto")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Descrizione")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.Property<string>("Email")
.HasMaxLength(250)
.HasColumnType("nvarchar(250)");
b.HasKey("CodInst");
b.ToTable("Installazioni");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.Property<int>("IdxLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(50)");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(50)");
b.Property<DateTime>("DataEnigma")
.HasColumnType("datetime2");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<string>("Enigma")
.HasColumnType("nvarchar(max)");
b.Property<bool>("Locked")
.HasColumnType("bit");
b.Property<int>("NumLicenze")
.HasColumnType("int");
b.Property<string>("Payload")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("Scadenza")
.HasColumnType("datetime2");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxLic");
b.HasIndex("CodApp");
b.HasIndex("CodInst");
b.ToTable("Licenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogCallModel", b =>
{
b.Property<DateTime>("DataRif")
.HasColumnType("datetime2");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(450)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(450)");
b.Property<string>("TargetUrl")
.HasColumnType("nvarchar(450)");
b.Property<int>("NumCall")
.HasColumnType("int");
b.HasKey("DataRif", "CodInst", "CodApp", "TargetUrl");
b.ToTable("LogCall");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
{
b.Property<int>("IdxLogLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodApp")
.HasColumnType("nvarchar(50)");
b.Property<string>("CodInst")
.HasColumnType("nvarchar(50)");
b.Property<string>("Descrizione")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("NumLicenze")
.HasColumnType("int");
b.Property<DateTime>("Scadenza")
.HasColumnType("datetime2");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxLogLic");
b.HasIndex("CodApp");
b.HasIndex("CodInst");
b.HasIndex("IdxLic");
b.ToTable("LogLicenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
{
b.Property<int>("IdxSubLic")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Chiave")
.HasColumnType("nvarchar(max)");
b.Property<string>("CodImpiego")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("Tipo")
.HasColumnType("int");
b.Property<DateTime>("VetoUnlock")
.HasColumnType("datetime2");
b.HasKey("IdxSubLic");
b.HasIndex("IdxLic");
b.ToTable("SubLicenze");
});
modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
{
b.Property<int>("IdxTicket")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("CodImpiego")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactEmail")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactName")
.HasColumnType("nvarchar(max)");
b.Property<string>("ContactPhone")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DtReq")
.HasColumnType("datetime2");
b.Property<int>("IdxLic")
.HasColumnType("int");
b.Property<int>("IdxSubLic")
.HasColumnType("int");
b.Property<string>("ReqBody")
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("SupplAnsw")
.HasColumnType("nvarchar(max)");
b.Property<string>("SupplEmail")
.HasColumnType("nvarchar(max)");
b.Property<string>("SupplUserCode")
.HasColumnType("nvarchar(max)");
b.Property<int>("TType")
.HasColumnType("int");
b.Property<int>("Tipo")
.HasColumnType("int");
b.HasKey("IdxTicket");
b.HasIndex("IdxLic");
b.ToTable("TicketLog");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.HasOne("LiMan.DB.DBModels.TicketModel", "TicketNav")
.WithMany()
.HasForeignKey("IdxTicket")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TicketNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
.WithMany()
.HasForeignKey("CodApp");
b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
.WithMany()
.HasForeignKey("CodInst");
b.Navigation("ApplicativoNav");
b.Navigation("InstallazioneNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LogLicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
.WithMany()
.HasForeignKey("CodApp");
b.HasOne("LiMan.DB.DBModels.InstallazioneModel", "InstallazioneNav")
.WithMany()
.HasForeignKey("CodInst");
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany()
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApplicativoNav");
b.Navigation("InstallazioneNav");
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.SubLicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany("Attivazioni")
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.TicketModel", b =>
{
b.HasOne("LiMan.DB.DBModels.LicenzaModel", "LicenzaNav")
.WithMany("Tickets")
.HasForeignKey("IdxLic")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LicenzaNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.Navigation("Attivazioni");
b.Navigation("Tickets");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LiMan.DB.Migrations
{
public partial class UpdTicket_TType : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "TType",
table: "TicketLog",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TType",
table: "TicketLog");
}
}
}
@@ -35,6 +35,35 @@ namespace LiMan.DB.Migrations
b.ToTable("Applicativi");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.Property<int>("IdxFileAttach")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<DateTime>("DtEvent")
.HasColumnType("datetime2");
b.Property<string>("FullStoragePath")
.HasColumnType("nvarchar(max)");
b.Property<int>("IdxTicket")
.HasColumnType("int");
b.Property<string>("OriginalName")
.HasColumnType("nvarchar(max)");
b.Property<string>("StorageName")
.HasColumnType("nvarchar(max)");
b.HasKey("IdxFileAttach");
b.HasIndex("IdxTicket");
b.ToTable("FileAttach");
});
modelBuilder.Entity("LiMan.DB.DBModels.InstallazioneModel", b =>
{
b.Property<string>("CodInst")
@@ -247,6 +276,9 @@ namespace LiMan.DB.Migrations
b.Property<string>("SupplUserCode")
.HasColumnType("nvarchar(max)");
b.Property<int>("TType")
.HasColumnType("int");
b.Property<int>("Tipo")
.HasColumnType("int");
@@ -257,6 +289,17 @@ namespace LiMan.DB.Migrations
b.ToTable("TicketLog");
});
modelBuilder.Entity("LiMan.DB.DBModels.FileAttachModel", b =>
{
b.HasOne("LiMan.DB.DBModels.TicketModel", "TicketNav")
.WithMany()
.HasForeignKey("IdxTicket")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TicketNav");
});
modelBuilder.Entity("LiMan.DB.DBModels.LicenzaModel", b =>
{
b.HasOne("LiMan.DB.DBModels.ApplicativoModel", "ApplicativoNav")
+5
View File
@@ -48,6 +48,11 @@ namespace LiMan.UI.Components
}
}
protected override async Task OnInitializedAsync()
{
await ReloadAllData();
}
private bool isLoading { get; set; } = false;
[Inject]
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>1.1.2111.1815</Version>
<Version>1.1.2201.1317</Version>
<RootNamespace>LiMan.UI</RootNamespace>
<AssemblyName>LiMan.UI</AssemblyName>
</PropertyGroup>
+17
View File
@@ -0,0 +1,17 @@
@page "/ListaTicket"
@using LiMan.UI.Components
@using LiMan.UI.Data
@inject MessageService AppMService
<Tickets></Tickets>
@code {
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.PageName = "Elenco Tickets";
AppMService.PageIcon = "oi oi-list-rich";
}
}
@@ -13,7 +13,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>34200ca2-489c-435a-a60b-34de7b7ba04d</ProjectGuid>
<MSDeployServiceURL>https://IIS02:8172/MsDeploy.axd</MSDeployServiceURL>
<MSDeployServiceURL>https://IIS02.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
<DeployIisAppPath>Default Web Site/ELM.UI</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 1.1.2111.1815</h4>
<h4>Versione: 1.1.2201.1317</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
1.1.2111.1815
1.1.2201.1317
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.1.2111.1815</version>
<version>1.1.2201.1317</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+5
View File
@@ -29,6 +29,11 @@
<NavMenuItem IconClass="fas fa-user-tag" Text="Install. Clienti" />
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="ListaTicket">
<NavMenuItem IconClass="fas fa-user-tag" Text="Lista Ticket" />
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="LiManGLS">
<NavMenuItem IconClass="fas fa-lock" Text="Licenze STW" />