diff --git a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj index c89ea47b..d1e85a6e 100644 --- a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj +++ b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj @@ -43,6 +43,7 @@ + diff --git a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs index 81389a74..b6ce4113 100644 --- a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs +++ b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using NLog; +using RestSharp; using StackExchange.Redis; using System; using System.Collections.Generic; @@ -21,6 +22,15 @@ namespace EgwCoreLib.Lux.Data.Services svgChannel = _config.GetValue("ServerConf:SvgChannel") ?? "svg:img"; liveTag = _config.GetValue("ServerConf:ImageLiveTag") ?? "svg"; cacheTag = _config.GetValue("ServerConf:ImageFileTag") ?? "svgfile"; + calcTag = _config.GetValue("ServerConf:ImageCalcTag") ?? "svg-preview"; + // verifico la url base + apiUrl = _config.GetValue("ServerConf:Prog.ApiUrl") ?? "https://iis01.egalware.com/lux/srv/api/window"; + // fix opzioni base del RestClient + restOptStd = new RestClientOptions + { + Timeout = TimeSpan.FromSeconds(60), + BaseUrl = new Uri(apiUrl) + }; Log.Info("ImageCache Service Started"); } @@ -28,6 +38,45 @@ namespace EgwCoreLib.Lux.Data.Services #region Public Methods + /// + /// Effettua una generica chiamata ApiRest + /// + /// URL Api di base + /// Richiesta completa + /// + public async Task CallRestGet(string ApiUrl, string ApiRequest) + { + RestResponse response; + // cerco online + using (RestClient client = new RestClient(ApiUrl)) + { + var request = new RestRequest(ApiRequest, Method.Get); + response = await client.GetAsync(request); + } + return response; + } + + /// + /// Effettua una generica chiamata ApiRest + /// + /// URL Api di base + /// Richiesta completa + /// Corpo Json trasmesso con richiesta + /// + public async Task CallRestPost(string ApiUrl, string ApiRequest, string JsonBody) + { + RestResponse response; + // cerco online + using (RestClient client = new RestClient(ApiUrl)) + { + var request = new RestRequest(ApiRequest, Method.Post); + string rawData = JsonConvert.SerializeObject(JsonBody); + request.AddJsonBody(rawData); + response = await client.ExecutePostAsync(request); + } + return response; + } + /// /// Calcola URL immagine dato /// @@ -70,6 +119,41 @@ namespace EgwCoreLib.Lux.Data.Services return $"{rawVal}"; } + /// + /// Calcola URL immagine dato + /// + /// Base url IMG server (da config) + /// UID elemento/immagine + /// JWD serializzato di cui si richiede l'immagine aggiornata + /// + public string ReqUpdateSvg(string baseUrl, string imgUID, string serJwd) + { + string answ = ""; + if (imgUID.EndsWith(".svg")) + { + imgUID.Replace(".svg", ""); + } + string fullUrl = $"{baseUrl}/svg-preview/{imgUID}".Replace("////", "//"); + + return answ; + } + + /// + /// Salva e invia su channel img redis SVG per il doc richiesto + /// + /// + /// + public async Task SaveBomAsync(string imgId, string bomContent) + { + // salvo img in cache + string currKey = $"{redisBaseKey}:BOM:{imgId.Replace("/", ":")}"; + var done = await _redisService.SetAsync(currKey, bomContent); + // invio notifica nuova svg generata sul canale... viene inviato solo svg con ID nel canale + string notifyChannel = $"{bomChannel}:{imgId}"; + long numSent = await _redisService.PublishAsync(notifyChannel, bomContent); + return done; + } + /// /// Salva e invia su channel img redis SVG per il doc richiesto /// @@ -103,36 +187,43 @@ namespace EgwCoreLib.Lux.Data.Services return done; } - /// - /// Salva e invia su channel img redis SVG per il doc richiesto - /// - /// - /// - public async Task SaveBomAsync(string imgId, string bomContent) - { - // salvo img in cache - string currKey = $"{redisBaseKey}:BOM:{imgId.Replace("/", ":")}"; - var done = await _redisService.SetAsync(currKey, bomContent); - // invio notifica nuova svg generata sul canale... viene inviato solo svg con ID nel canale - string notifyChannel = $"{bomChannel}:{imgId}"; - long numSent = await _redisService.PublishAsync(notifyChannel, bomContent); - return done; - } - #endregion Public Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IRedisService _redisService; - private readonly string cacheTag = "svgfile"; - private readonly string liveTag = "svg"; - private readonly string svgChannel = "svg:img"; + + private readonly string apiUrl = ""; + private readonly string bomChannel = "bom:item"; + + private readonly string cacheTag = "svgfile"; + + private readonly string calcTag = "svgpreview"; + + private readonly string liveTag = "svg"; + + private readonly string svgChannel = "svg:img"; + private IConfiguration _config; + private string imageBaseUrl = ""; + private string redisBaseKey = "Lux"; #endregion Private Fields + + #region Private Properties + + /// + /// Conf client RestSharp standard: + /// - base URI al sito + /// - timeout 1 min + /// + private RestClientOptions restOptStd { get; set; } = new RestClientOptions(); + + #endregion Private Properties } } \ No newline at end of file diff --git a/Lux.API/Controllers/WindowController.cs b/Lux.API/Controllers/WindowController.cs index 423e58a9..e0c83adb 100644 --- a/Lux.API/Controllers/WindowController.cs +++ b/Lux.API/Controllers/WindowController.cs @@ -33,7 +33,7 @@ namespace Lux.API.Controllers /// /// Chiamata POST: riceve Json in formato JWD serializzato, invia richeista calcolo modo 2 (BOM) - /// PUT: api/svgPreview/svg/00000000-0000-0000-0000-000000000000 + /// PUT: api/window/bom/00000000-0000-0000-0000-000000000000 /// /// id oggetto /// @@ -77,7 +77,7 @@ namespace Lux.API.Controllers /// /// Chiamata POST: riceve Json in formato JWD serializzato, lo ripete come risposta - /// PUT: api/svgPreview/svg/00000000-0000-0000-0000-000000000000 + /// PUT: api/window/svg/00000000-0000-0000-0000-000000000000 /// /// id oggetto /// @@ -99,7 +99,7 @@ namespace Lux.API.Controllers /// /// Chiamata POST: riceve Json in formato JWD serializzato, lo ripete come risposta - /// PUT: api/svgPreview/svg/00000000-0000-0000-0000-000000000000 + /// PUT: api/window/svg-file/00000000-0000-0000-0000-000000000000 /// /// id oggetto /// @@ -130,10 +130,11 @@ namespace Lux.API.Controllers /// /// Chiamata POST: riceve Json in formato JWD serializzato, lo ripete come risposta - /// PUT: api/svg-preview/svg/00000000-0000-0000-0000-000000000000 + /// PUT: api/window/svg-preview/00000000-0000-0000-0000-000000000000 /// /// id oggetto /// + [HttpPost("svgpreview/{id}")] [HttpPost("svg-preview/{id}")] public async Task> svgPreview(string id, [FromBody] string currJwd) { diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index ab891ea5..a484e024 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 0.9.2508.0411 + 0.9.2508.0412 diff --git a/Lux.UI/Components/Layout/NavMenu.razor b/Lux.UI/Components/Layout/NavMenu.razor index c723eb65..c6747519 100644 --- a/Lux.UI/Components/Layout/NavMenu.razor +++ b/Lux.UI/Components/Layout/NavMenu.razor @@ -47,8 +47,8 @@ diff --git a/Lux.UI/Components/Pages/Scratch.razor b/Lux.UI/Components/Pages/Scratch.razor new file mode 100644 index 00000000..8789b29f --- /dev/null +++ b/Lux.UI/Components/Pages/Scratch.razor @@ -0,0 +1,23 @@ +@page "/scratch" + +

Scratch Test

+ + +
+
+
+ + +
+ +
+ + +
+ + +
+
+ @outSvg +
+
diff --git a/Lux.UI/Components/Pages/Scratch.razor.cs b/Lux.UI/Components/Pages/Scratch.razor.cs new file mode 100644 index 00000000..c3ab8bd5 --- /dev/null +++ b/Lux.UI/Components/Pages/Scratch.razor.cs @@ -0,0 +1,66 @@ +using EgwCoreLib.Lux.Data; +using EgwCoreLib.Lux.Data.Services; +using Microsoft.AspNetCore.Components; + +namespace Lux.UI.Components.Pages +{ + public partial class Scratch + { + private string windowUid = "TestWindow"; + /// + /// Demorichiesta jwd x fare test richiesta calcolo + /// + private string demoJwd = "{\r\n\"ProfilePath\":\"Profilo78\",\r\n\"AreaList\":[\r\n{\r\n\"Shape\":\"RECTANGLE\",\r\n\"DimensionList\":[\r\n{\r\n\"nIndex\":1,\r\n\"sName\":\"Width\",\r\n\"dValue\":1200.0\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"sName\":\"Height\",\r\n\"dValue\":1500.0\r\n}\r\n],\r\n\"JointList\":[\r\n{\r\n\"nIndex\":1,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":3,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":4,\r\n\"JointType\":\"FULL_V\"\r\n}\r\n],\r\n\"BottomRail\":false,\r\n\"BottomRailQty\":0,\r\n\"AreaList\":[\r\n{\r\n\"bIsSashVertical\":true,\r\n\"SashList\":[\r\n{\r\n\"OpeningType\":\"TURNONLY_LEFT\",\r\n\"bHasHandle\":false,\r\n\"dDimension\":50.0\r\n},\r\n{\r\n\"OpeningType\":\"TILTTURN_RIGHT\",\r\n\"bHasHandle\":true,\r\n\"dDimension\":50.0\r\n}\r\n],\r\n\"SashType\":\"NULL\",\r\n\"JointList\":[\r\n{\r\n\"nIndex\":1,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":3,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":4,\r\n\"JointType\":\"FULL_V\"\r\n}\r\n],\r\n\"Hardware\":\"000000\",\r\n\"AreaList\":[\r\n{\r\n\"AreaList\":[\r\n{\r\n\"FillType\":\"GLASS\",\r\n\"AreaList\":[],\r\n\"AreaType\":\"FILL\"\r\n}\r\n],\r\n\"AreaType\":\"SPLITTED\"\r\n},\r\n{\r\n\"AreaList\":[\r\n{\r\n\"FillType\":\"GLASS\",\r\n\"AreaList\":[],\r\n\"AreaType\":\"FILL\"\r\n}\r\n],\r\n\"AreaType\":\"SPLITTED\"\r\n}\r\n],\r\n\"AreaType\":\"SASH\"\r\n}\r\n],\r\n\"AreaType\":\"FRAME\"\r\n}\r\n]\r\n}"; + + + [Inject] + protected ImageCacheService ICService { get; set; } = null!; + + + [Inject] + protected IRedisService RedServ { get; set; } = null!; + + [Inject] + protected IConfiguration Config { get; set; } = null!; + + private string apiUrl = ""; + private string calcTag = ""; + private string subChannel = ""; + private string currChannel = ""; + + + protected override Task OnInitializedAsync() + { + apiUrl = Config.GetValue("ServerConf:Prog.ApiUrl") ?? ""; + calcTag = Config.GetValue("ServerConf:ImageCalcTag") ?? ""; + subChannel = Config.GetValue("ServerConf:SvgChannel") ?? ""; + RedServ.Subscribe($"{subChannel}:*", (ch, msg) => + { + saveSvg($"{ch}", $"{msg}"); + }); + + return Task.CompletedTask; + } + + private void saveSvg(string channel, string newSvg) + { + // se è la mia immagine + if (channel.EndsWith(windowUid) || true) + { + currSvg = newSvg; + } + } + + + protected async Task SendCalc() + { + await ICService.CallRestPost(apiUrl, $"{calcTag}/{windowUid}", demoJwd); + } + + + protected MarkupString outSvg { get; set; } = (MarkupString)""; + + private string currSvg = ""; + + } +} \ No newline at end of file diff --git a/Lux.UI/Components/Pages/Weather.razor b/Lux.UI/Components/Pages/Weather.razor deleted file mode 100644 index 43a1ecbe..00000000 --- a/Lux.UI/Components/Pages/Weather.razor +++ /dev/null @@ -1,64 +0,0 @@ -@page "/weather" -@attribute [StreamRendering] - -Weather - -

Weather

- -

This component demonstrates showing data.

- -@if (forecasts == null) -{ -

Loading...

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - // Simulate asynchronous loading to demonstrate streaming rendering - await Task.Delay(500); - - var startDate = DateOnly.FromDateTime(DateTime.Now); - var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; - forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = startDate.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = summaries[Random.Shared.Next(summaries.Length)] - }).ToArray(); - } - - private class WeatherForecast - { - public DateOnly Date { get; set; } - public int TemperatureC { get; set; } - public string? Summary { get; set; } - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } -} diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index 612375d1..bfe18a94 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 0.9.2508.0411 + 0.9.2508.0412 diff --git a/Lux.UI/Program.cs b/Lux.UI/Program.cs index 1051d866..bfdf5006 100644 --- a/Lux.UI/Program.cs +++ b/Lux.UI/Program.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using NLog; using NLog.Web; +using StackExchange.Redis; using System.Globalization; var builder = WebApplication.CreateBuilder(args); @@ -50,8 +51,19 @@ builder.Services.AddIdentityCore(options => options.SignIn.Requ builder.Services.AddSingleton, IdentityNoOpEmailSender>(); + +// costruzione connectionMultiplexer redis... +string connStr = configuration.GetConnectionString("Redis") ?? "localhost"; +ConnectionMultiplexer redisConn = ConnectionMultiplexer.Connect(connStr); +// registro connMultiplexer REDIS +builder.Services.AddSingleton(redisConn); +// registro wrapper servizi REDIS +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + // Aggiunta servizi specifici builder.Services.AddSingleton(); +builder.Services.AddSingleton(); var app = builder.Build(); diff --git a/Lux.UI/appsettings.json b/Lux.UI/appsettings.json index 71d937b0..dc5a90d6 100644 --- a/Lux.UI/appsettings.json +++ b/Lux.UI/appsettings.json @@ -58,6 +58,8 @@ "Redis": "redis.ufficio:26379, serviceName=devel, DefaultDatabase=6, keepAlive=180, connectTimeout=15000, syncTimeout=15000, asyncTimeout=15000, abortConnect=false, ssl=false, allowAdmin=true" }, "ServerConf": { + "ImageCalcTag": "svg-preview", + "Prog.ApiUrl": "https://iis01.egalware.com/lux/srv/api/window", "PubChannel": "EgwEngineInput", "SubChannel": "EgwEngineOutput", "SvgChannel": "svg:img", diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index f1f5a40d..243d0079 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

Versione: 0.9.2508.0411

+

Versione: 0.9.2508.0412


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index 5a123db6..d7bcfacd 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -0.9.2508.0411 +0.9.2508.0412 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index f87db0a0..3d9f583b 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 0.9.2508.0411 + 0.9.2508.0412 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false