diff --git a/console/YANLib.Benchmarks/YANLib.Benchmarks.csproj b/console/YANLib.Benchmarks/YANLib.Benchmarks.csproj index 09466ba..c346cb2 100644 --- a/console/YANLib.Benchmarks/YANLib.Benchmarks.csproj +++ b/console/YANLib.Benchmarks/YANLib.Benchmarks.csproj @@ -1,19 +1,19 @@ - - Exe - net6.0 - enable - enable - + + Exe + net6.0 + enable + enable + - - - - + + + + - - - + + + diff --git a/database/YANLIB.sql b/database/YANLIB.sql new file mode 100644 index 0000000..0fceaac --- /dev/null +++ b/database/YANLIB.sql @@ -0,0 +1,38 @@ +CREATE DATABASE YANLIB; + +USE YANLIB; + +CREATE SCHEMA sample; + +CREATE TABLE sample.DeveloperTypes +( + Code INT PRIMARY KEY NOT NULL, + Name NVARCHAR(100) NOT NULL, + IsActive BIT NOT NULL, + CreatedDate DATETIME NOT NULL, + ModifiedDate DATETIME +); + +CREATE TABLE sample.Developers +( + Id VARCHAR(20) PRIMARY KEY NOT NULL, + Name NVARCHAR(100) NOT NULL, + Phone VARCHAR(20), + IdCard VARCHAR(20) NOT NULL, + DeveloperTypeCode INT NOT NULL, + IsActive BIT NOT NULL, + Version INT NOT NULL, + CreatedDate DATETIME NOT NULL, + ModifiedDate DATETIME, + FOREIGN KEY (DeveloperTypeCode) REFERENCES sample.DeveloperTypes(Code) +); + +CREATE TABLE sample.Certificates +( + Id VARCHAR(20) PRIMARY KEY NOT NULL, + Name NVARCHAR(100) NOT NULL, + GPA DOUBLE PRECISION, + DeveloperId VARCHAR(20), + CreatedDate DATETIME NOT NULL, + ModifiedDate DATETIME +); diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 968c7b3..f8b0df7 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -18,6 +18,9 @@ + + + diff --git a/docker-compose.yml b/docker-compose.yml index c020658..aab161a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: depends_on: - elasticsearch restart: unless-stopped - + rabbitmq: image: rabbitmq:3-management container_name: rabbitmq @@ -119,8 +119,6 @@ services: RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-} networks: - yan - depends_on: - - logstash restart: unless-stopped zookeeper: @@ -132,8 +130,6 @@ services: - ALLOW_ANONYMOUS_LOGIN=yes networks: - yan - depends_on: - - logstash restart: unless-stopped kafka: @@ -183,6 +179,7 @@ networks: volumes: setup: elasticsearch: + es-ingest: # Run with # docker-compose \ diff --git a/es-ingest/.dockerignore b/es-ingest/.dockerignore new file mode 100644 index 0000000..37eef9d --- /dev/null +++ b/es-ingest/.dockerignore @@ -0,0 +1,6 @@ +# Ignore Docker build files +Dockerfile +.dockerignore + +# Ignore OS artifacts +**/.DS_Store diff --git a/es-ingest/Dockerfile b/es-ingest/Dockerfile new file mode 100644 index 0000000..22528c6 --- /dev/null +++ b/es-ingest/Dockerfile @@ -0,0 +1,7 @@ +ARG ELASTIC_VERSION + +# https://www.docker.elastic.co/ +FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION} + +# Add your elasticsearch plugins setup here +# Example: RUN elasticsearch-plugin install analysis-icu diff --git a/es-ingest/config/elasticsearch.yml b/es-ingest/config/elasticsearch.yml new file mode 100644 index 0000000..edebb87 --- /dev/null +++ b/es-ingest/config/elasticsearch.yml @@ -0,0 +1,18 @@ +--- +## Default Elasticsearch configuration from Elasticsearch base image. +## https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/config/elasticsearch.yml +# +cluster.name: docker-cluster-neo +network.host: 0.0.0.0 + +## X-Pack settings +## see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html +# +xpack.license.self_generated.type: trial +xpack.security.enabled: true + +# server.publicBaseUrl: https://my-elasticsearch-cluster.example.com + +## Set the built-in users' passwords. +# Run the following command from the Elasticsearch directory: +# ./bin/elasticsearch-setup-passwords interactive diff --git a/extensions/curator/curator-compose.yml b/extensions/curator/curator-compose.yml index fc137e6..65ae2ba 100644 --- a/extensions/curator/curator-compose.yml +++ b/extensions/curator/curator-compose.yml @@ -4,10 +4,11 @@ services: curator: build: context: extensions/curator/ + container_name: curator init: true volumes: - - ./config/curator.yml:/.curator/curator.yml:ro,Z - - ./config/delete_log_files_curator.yml:/.curator/delete_log_files_curator.yml:ro,Z + - ./extensions/curator/config/curator.yml:/.curator/curator.yml:ro,Z + - ./extensions/curator/config/delete_log_files_curator.yml:/.curator/delete_log_files_curator.yml:ro,Z environment: ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-} networks: diff --git a/extensions/enterprise-search/config/enterprise-search.yml b/extensions/enterprise-search/config/enterprise-search.yml index a1f098d..a1beab2 100644 --- a/extensions/enterprise-search/config/enterprise-search.yml +++ b/extensions/enterprise-search/config/enterprise-search.yml @@ -6,7 +6,7 @@ ## --------------------- REQUIRED --------------------- # Encryption keys to protect application secrets. -secret_management.encryption_keys: +secret_management.encryption_keys: [680f94e568c90364bedf927b2f0f49609702d3eab9098688585a375b14274546] # example: #- 680f94e568c90364bedf927b2f0f49609702d3eab9098688585a375b14274546 diff --git a/extensions/enterprise-search/enterprise-search-compose.yml b/extensions/enterprise-search/enterprise-search-compose.yml index c4d422d..3b11d2e 100644 --- a/extensions/enterprise-search/enterprise-search-compose.yml +++ b/extensions/enterprise-search/enterprise-search-compose.yml @@ -6,8 +6,9 @@ services: context: extensions/enterprise-search/ args: ELASTIC_VERSION: ${ELASTIC_VERSION} + container_name: enterprise-search volumes: - - ./config/enterprise-search.yml:/usr/share/enterprise-search/config/enterprise-search.yml:ro,Z + - ./extensions/enterprise-search/config/enterprise-search.yml:/usr/share/enterprise-search/config/enterprise-search.yml:ro,Z environment: JAVA_OPTS: -Xms2g -Xmx2g ENT_SEARCH_DEFAULT_PASSWORD: 'changeme' diff --git a/extensions/filebeat/filebeat-compose.yml b/extensions/filebeat/filebeat-compose.yml index 84e3d1b..2eb56c1 100644 --- a/extensions/filebeat/filebeat-compose.yml +++ b/extensions/filebeat/filebeat-compose.yml @@ -8,6 +8,7 @@ services: ELASTIC_VERSION: ${ELASTIC_VERSION} # Run as 'root' instead of 'filebeat' (uid 1000) to allow reading # 'docker.sock' and the host's filesystem. + container_name: filebeat user: root command: # Log to stderr. @@ -17,7 +18,7 @@ services: # see: https://www.elastic.co/guide/en/beats/libbeat/current/config-file-permissions.html - --strict.perms=false volumes: - - ./config/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro,Z + - ./extensions/filebeat/config/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro,Z - type: bind source: /var/lib/docker/containers target: /var/lib/docker/containers diff --git a/extensions/fleet/agent-apmserver-compose.yml b/extensions/fleet/agent-apmserver-compose.yml index 0cda861..4d338ba 100644 --- a/extensions/fleet/agent-apmserver-compose.yml +++ b/extensions/fleet/agent-apmserver-compose.yml @@ -10,6 +10,7 @@ services: context: extensions/fleet/ args: ELASTIC_VERSION: ${ELASTIC_VERSION} + container_name: apm-server volumes: - apm-server:/usr/share/elastic-agent/state:Z environment: diff --git a/extensions/fleet/fleet-compose.yml b/extensions/fleet/fleet-compose.yml index 89a3ebc..61369e5 100644 --- a/extensions/fleet/fleet-compose.yml +++ b/extensions/fleet/fleet-compose.yml @@ -6,6 +6,7 @@ services: context: extensions/fleet/ args: ELASTIC_VERSION: ${ELASTIC_VERSION} + container_name: fleet-server volumes: - fleet-server:/usr/share/elastic-agent/state:Z environment: diff --git a/extensions/heartbeat/heartbeat-compose.yml b/extensions/heartbeat/heartbeat-compose.yml index 6ad85c8..e31d6b7 100644 --- a/extensions/heartbeat/heartbeat-compose.yml +++ b/extensions/heartbeat/heartbeat-compose.yml @@ -6,6 +6,7 @@ services: context: extensions/heartbeat/ args: ELASTIC_VERSION: ${ELASTIC_VERSION} + container_name: heartbeat command: # Log to stderr. - -e @@ -14,7 +15,7 @@ services: # see: https://www.elastic.co/guide/en/beats/libbeat/current/config-file-permissions.html - --strict.perms=false volumes: - - ./config/heartbeat.yml:/usr/share/heartbeat/heartbeat.yml:ro,Z + - ./extensions/heartbeat/config/heartbeat.yml:/usr/share/heartbeat/heartbeat.yml:ro,Z environment: HEARTBEAT_INTERNAL_PASSWORD: ${HEARTBEAT_INTERNAL_PASSWORD:-} BEATS_SYSTEM_PASSWORD: ${BEATS_SYSTEM_PASSWORD:-} diff --git a/extensions/logspout/logspout-compose.yml b/extensions/logspout/logspout-compose.yml index a05603e..f0ef100 100644 --- a/extensions/logspout/logspout-compose.yml +++ b/extensions/logspout/logspout-compose.yml @@ -4,6 +4,7 @@ services: logspout: build: context: extensions/logspout + container_name: logspout volumes: - type: bind source: /var/run/docker.sock diff --git a/extensions/metricbeat/config/metricbeat.yml b/extensions/metricbeat/config/metricbeat.yml index 1c2b6cb..33a1c54 100644 --- a/extensions/metricbeat/config/metricbeat.yml +++ b/extensions/metricbeat/config/metricbeat.yml @@ -18,7 +18,7 @@ metricbeat.autodiscover: metricbeat.modules: - module: elasticsearch hosts: [ http://elasticsearch:9200 ] - username: monitoring_internal + username: elastic password: ${MONITORING_INTERNAL_PASSWORD} xpack.enabled: true period: 10s @@ -30,7 +30,7 @@ metricbeat.modules: enabled: true - module: kibana hosts: [ http://kibana:5601 ] - username: monitoring_internal + username: elastic password: ${MONITORING_INTERNAL_PASSWORD} xpack.enabled: true period: 10s diff --git a/extensions/metricbeat/metricbeat-compose.yml b/extensions/metricbeat/metricbeat-compose.yml index c55a5e5..7a91e5d 100644 --- a/extensions/metricbeat/metricbeat-compose.yml +++ b/extensions/metricbeat/metricbeat-compose.yml @@ -8,6 +8,7 @@ services: ELASTIC_VERSION: ${ELASTIC_VERSION} # Run as 'root' instead of 'metricbeat' (uid 1000) to allow reading # 'docker.sock' and the host's filesystem. + container_name: metricbeat user: root command: # Log to stderr. @@ -20,7 +21,7 @@ services: # from within a container. - --system.hostfs=/hostfs volumes: - - ./config/metricbeat.yml:/usr/share/metricbeat/metricbeat.yml:ro,Z + - ./extensions/metricbeat/config/metricbeat.yml:/usr/share/metricbeat/metricbeat.yml:ro,Z - type: bind source: / target: /hostfs diff --git a/host/YANLib.HttpApi.Host/Program.cs b/host/YANLib.HttpApi.Host/Program.cs index ffecdb7..b26d383 100644 --- a/host/YANLib.HttpApi.Host/Program.cs +++ b/host/YANLib.HttpApi.Host/Program.cs @@ -13,20 +13,27 @@ public class Program public async static Task Main(string[] args) { Log.Logger = new LoggerConfiguration().MinimumLevel.Information().Enrich.FromLogContext().WriteTo.Async(c => c.Console()).CreateLogger(); + try { Log.Information("Starting YANLib.HttpApi.Host."); + var builder = CreateBuilder(args); + _ = builder.Host.AddAppSettingsSecretsJson().UseAutofac().UseSerilog((t, f) => f.Enrich.FromLogContext().ReadFrom.Configuration(t.Configuration)); _ = await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); await app.RunAsync(); - return 0; + + return default; } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; } finally diff --git a/host/YANLib.HttpApi.Host/YANLib.HttpApi.Host.csproj b/host/YANLib.HttpApi.Host/YANLib.HttpApi.Host.csproj index 52dba7c..53d49aa 100644 --- a/host/YANLib.HttpApi.Host/YANLib.HttpApi.Host.csproj +++ b/host/YANLib.HttpApi.Host/YANLib.HttpApi.Host.csproj @@ -1,52 +1,51 @@ - + - - net6.0 - YANLib - true - YANLib-4681b4fd-151f-4221-84a4-929d86723e4c - Linux - ..\.. - ..\..\docker-compose.dcproj - + + net6.0 + YANLib + true + YANLib-4681b4fd-151f-4221-84a4-929d86723e4c + Linux + ..\.. + ..\..\docker-compose.dcproj + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + diff --git a/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs b/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs index cff997b..d315aee 100644 --- a/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs +++ b/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs @@ -3,6 +3,7 @@ using Elastic.Apm.NetCoreAll; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -12,31 +13,33 @@ using System.Collections.Generic; using System.Linq; using Volo.Abp; -using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; -using Volo.Abp.Autofac; using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.SqlServer; using Volo.Abp.Http.Client; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.Swashbuckle; using YANLib.EntityFrameworkCore; +using YANLib.Utilities; using static Elastic.Apm.Agent; +using static HealthChecks.UI.Client.UIResponseWriter; +using static Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus; using static System.StringSplitOptions; namespace YANLib; + [DependsOn( typeof(YANLibHttpApiModule), typeof(YANLibApplicationModule), typeof(YANLibEntityFrameworkCoreModule), - typeof(AbpAutofacModule), - typeof(AbpAspNetCoreMultiTenancyModule), - typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), + //typeof(AbpAutofacModule), typeof(AbpAspNetCoreSerilogModule), typeof(AbpSwashbuckleModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(AbpCachingStackExchangeRedisModule), typeof(AbpHttpClientModule) )] @@ -45,10 +48,14 @@ public class YANLibHttpApiHostModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); + + context.Services.AddElasticsearch(configuration); + Configure(o => o.UseSqlServer()); ConfigureConventionalControllers(); ConfigureLocalization(); ConfigureCors(context, configuration); ConfigureSwaggerServices(context, configuration); + ConfigureHealthChecks(context, configuration); } private void ConfigureConventionalControllers() => Configure(o => o.ConventionalControllers.Create(typeof(YANLibApplicationModule).Assembly)); @@ -56,14 +63,15 @@ public override void ConfigureServices(ServiceConfigurationContext context) private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) { var hostingEnvironment = context.Services.GetHostingEnvironment(); + _ = context.Services.AddAbpSwaggerGenWithOAuth(configuration["AuthServer:Authority"], new Dictionary { - {"YANLib", "YANLib API"}, - {"YANJson", "YANJson API"} + {"YANLib Sample", "YANLib API Sample"}, + {"YANLib Test", "YANLib API Test"} }, o => { - o.SwaggerDoc("main", new OpenApiInfo { Title = $"YANLib API - {hostingEnvironment.EnvironmentName}", Version = "main" }); - o.SwaggerDoc("json", new OpenApiInfo { Title = $"YANJson API - {hostingEnvironment.EnvironmentName}", Version = "json" }); + o.SwaggerDoc("sample", new OpenApiInfo { Title = $"YANLib API Sample - {hostingEnvironment.EnvironmentName}", Version = "sample" }); + o.SwaggerDoc("test", new OpenApiInfo { Title = $"YANLib API Test - {hostingEnvironment.EnvironmentName}", Version = "test" }); o.CustomSchemaIds(t => t.FullName); o.HideAbpEndpoints(); o.EnableAnnotations(); @@ -92,26 +100,39 @@ private void ConfigureLocalization() => Configure(o => o.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de")); o.Languages.Add(new LanguageInfo("es", "es", "Español", "es")); o.Languages.Add(new LanguageInfo("el", "el", "Ελληνικά")); + o.Languages.Add(new LanguageInfo("vi", "vi", "Tiếng Việt")); }); - private static void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) => context.Services.AddCors(o => o.AddDefaultPolicy(b => b.WithOrigins(configuration["App:CorsOrigins"].Split(",", RemoveEmptyEntries).Select(o => o.RemovePostFix("/")).ToArray()).WithAbpExposedHeaders().SetIsOriginAllowedToAllowWildcardSubdomains().AllowAnyHeader().AllowAnyMethod().AllowCredentials())); + private static void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) => context.Services.AddCors(o => o + .AddDefaultPolicy(b => b + .WithOrigins(configuration["App:CorsOrigins"].Split(",", RemoveEmptyEntries).Select(o => o + .RemovePostFix("/")).ToArray()).WithAbpExposedHeaders().SetIsOriginAllowedToAllowWildcardSubdomains().AllowAnyHeader().AllowAnyMethod().AllowCredentials())); + + private static void ConfigureHealthChecks(ServiceConfigurationContext context, IConfiguration configuration) => context.Services.AddHealthChecks() + .AddSqlServer(connectionString: configuration["ConnectionStrings:Default"], name: "database", failureStatus: Degraded, tags: new string[] { "db", "sql", "sqlserver" }); public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); + _ = app.UseAllElasticApm(context.GetConfiguration()); _ = Subscribe(new HttpDiagnosticsSubscriber()); _ = Subscribe(new EfCoreDiagnosticsSubscriber()); + var env = context.GetEnvironment(); + if (env.IsDevelopment()) { _ = app.UseDeveloperExceptionPage(); } + _ = app.UseAbpRequestLocalization(); + if (!env.IsDevelopment()) { _ = app.UseErrorPage(); } + _ = app.UseCorrelationId(); _ = app.UseStaticFiles(); _ = app.UseRouting(); @@ -120,15 +141,24 @@ public override void OnApplicationInitialization(ApplicationInitializationContex _ = app.UseUnitOfWork(); _ = app.UseAuthorization(); _ = app.UseSwagger(); + _ = app.UseAbpSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/main/swagger.json", "YANLib API"); - c.SwaggerEndpoint("/swagger/json/swagger.json", "YANJson API"); + c.SwaggerEndpoint("/swagger/sample/swagger.json", "YANLib API Sample"); + c.SwaggerEndpoint("/swagger/test/swagger.json", "YANLib API Test"); c.OAuthClientId(context.ServiceProvider.GetRequiredService()["AuthServer:SwaggerClientId"]); c.OAuthScopes("YANLib"); }); + _ = app.UseAuditing(); _ = app.UseAbpSerilogEnrichers(); + + _ = app.UseHealthChecks("/health", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = WriteHealthCheckUIResponse + }); + _ = app.UseConfiguredEndpoints(); } } diff --git a/host/YANLib.HttpApi.Host/appsettings.Development.json b/host/YANLib.HttpApi.Host/appsettings.Development.json index 6ef7dfb..4d4c738 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Development.json +++ b/host/YANLib.HttpApi.Host/appsettings.Development.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "Default": "Server=localhost;Database=YANLIB;User ID=sa;Password=admin123@" + }, "Redis": { "Configuration": "localhost,password=admin123@" }, @@ -12,7 +15,7 @@ } }, "EventBus": { - "ClientName": "PublisherDev", + "ClientName": "SampleDev", "ExchangeName": "YanlibDev" } }, @@ -29,9 +32,17 @@ "TopicName": "yan.lib" } }, + "Elasticsearch": { + "Indices": { + "Sample": "yanlib_sample_index_dev" + }, + "Url": "http://localhost:9200/", + "Username": "elastic", + "Password": "admin123" + }, "RemoteServices": { "TestApi": { - "BaseUrl": "http://test-api.local/" + "BaseUrl": "http://sample-api.local/" } }, "Serilog": { @@ -90,7 +101,7 @@ "ElasticApm": { "ServiceName": "YANLib", "SecretToken": "YXBtOmFkbWluMTIz", - "ServerUrl": "http://apm-server:8200", + "ServerUrl": "http://localhost:8200", "Environment": "Development", "CaptureBody": "all", "LogLevel": "Trace" diff --git a/host/YANLib.HttpApi.Host/appsettings.Production.json b/host/YANLib.HttpApi.Host/appsettings.Production.json index 21a99ae..e98b888 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Production.json +++ b/host/YANLib.HttpApi.Host/appsettings.Production.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "Default": "Server=localhost;Database=YANLIB;User ID=sa;Password=admin123@" + }, "Redis": { "Configuration": "localhost,password=admin123@" }, @@ -12,7 +15,7 @@ } }, "EventBus": { - "ClientName": "PublisherProd", + "ClientName": "SampleProd", "ExchangeName": "YanlibProd" } }, @@ -26,12 +29,20 @@ }, "EventBus": { "GroupId": "YanlibProd", - "TopicName": "yan.prod" + "TopicName": "yan.lib" } }, + "Elasticsearch": { + "Indices": { + "Sample": "yanlib_sample_index_prod" + }, + "Url": "http://elasticsearch:9200/", + "Username": "elastic", + "Password": "admin123" + }, "RemoteServices": { "TestApi": { - "BaseUrl": "http://test-api.local/" + "BaseUrl": "http://sample-api.local/" } }, "Serilog": { diff --git a/host/YANLib.HttpApi.Host/appsettings.json b/host/YANLib.HttpApi.Host/appsettings.json index 6d1ea78..d10788b 100644 --- a/host/YANLib.HttpApi.Host/appsettings.json +++ b/host/YANLib.HttpApi.Host/appsettings.json @@ -5,7 +5,7 @@ "RedirectAllowedUrls": "" }, "ConnectionStrings": { - "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=YANLib;Trusted_Connection=True" + "Default": "Server=localhost;Database=YANLIB;User ID=sa;Password=admin123@" }, "AuthServer": { "Authority": "https://localhost:44380", diff --git a/lib/YANLib/Nullable/YANBool.Nullable.cs b/lib/YANLib/Nullable/YANBool.Nullable.cs index 4208e31..8e5c1ac 100644 --- a/lib/YANLib/Nullable/YANBool.Nullable.cs +++ b/lib/YANLib/Nullable/YANBool.Nullable.cs @@ -20,6 +20,7 @@ public static partial class YANBool { yield break; } + foreach (var num in nums) { yield return num.ToBool(); @@ -34,6 +35,7 @@ public static partial class YANBool { yield break; } + foreach (var num in strs) { yield return num.ToBool(dfltVal); diff --git a/lib/YANLib/Nullable/YANBool.cs b/lib/YANLib/Nullable/YANBool.cs index c09f855..5735e54 100644 --- a/lib/YANLib/Nullable/YANBool.cs +++ b/lib/YANLib/Nullable/YANBool.cs @@ -20,6 +20,7 @@ public static partial class YANBool { yield break; } + foreach (var num in nums) { yield return num.ToBool(); @@ -34,6 +35,7 @@ public static partial class YANBool { yield break; } + foreach (var num in strs) { yield return num.ToBool(); @@ -48,6 +50,7 @@ public static partial class YANBool { yield break; } + foreach (var num in strs) { yield return num.ToBool(dfltVal); diff --git a/lib/YANLib/Nullable/YANDateTime.cs b/lib/YANLib/Nullable/YANDateTime.cs index 70b2508..e5a7460 100644 --- a/lib/YANLib/Nullable/YANDateTime.cs +++ b/lib/YANLib/Nullable/YANDateTime.cs @@ -99,6 +99,7 @@ public static partial class YANDateTime public static DateTime? ChangeTimeZone(this DateTime dt, T1 tzSrc, T2 tzDst) where T1 : struct where T2 : struct { var diff = tzDst.ToInt() - tzSrc.ToInt(); + return diff.HasValue ? diff switch { < 0 when (dt - MinValue).TotalHours < Abs(diff.Value) => default, diff --git a/lib/YANLib/Nullable/YANNum.Byte.Nullable.cs b/lib/YANLib/Nullable/YANNum.Byte.Nullable.cs index e9be2b6..1836dd0 100644 --- a/lib/YANLib/Nullable/YANNum.Byte.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Byte.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToByte(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToByte(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Byte.cs b/lib/YANLib/Nullable/YANNum.Byte.cs index e470221..b73bffd 100644 --- a/lib/YANLib/Nullable/YANNum.Byte.cs +++ b/lib/YANLib/Nullable/YANNum.Byte.cs @@ -22,6 +22,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToByte(); @@ -38,6 +39,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToByte(); @@ -54,6 +56,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToByte(dfltVal); @@ -65,6 +68,7 @@ public static partial class YANNum { var minValue = min.ToByte(); var maxValue = max.ToByte(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().Next(minValue.Value, maxValue.Value).ToByte() : default; } diff --git a/lib/YANLib/Nullable/YANNum.Decimal.Nullable.cs b/lib/YANLib/Nullable/YANNum.Decimal.Nullable.cs index 20e6ca6..f851887 100644 --- a/lib/YANLib/Nullable/YANNum.Decimal.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Decimal.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToDecimal(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Decimal.cs b/lib/YANLib/Nullable/YANNum.Decimal.cs index d8a915e..9566c21 100644 --- a/lib/YANLib/Nullable/YANNum.Decimal.cs +++ b/lib/YANLib/Nullable/YANNum.Decimal.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToDecimal(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToDecimal(); var maxValue = max.ToDecimal(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextDecimal(minValue.Value, maxValue.Value) : default; } diff --git a/lib/YANLib/Nullable/YANNum.Double.Nullable.cs b/lib/YANLib/Nullable/YANNum.Double.Nullable.cs index 1badb4c..aff85ae 100644 --- a/lib/YANLib/Nullable/YANNum.Double.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Double.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToDouble(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDouble(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Double.cs b/lib/YANLib/Nullable/YANNum.Double.cs index 39ed876..80a5ffa 100644 --- a/lib/YANLib/Nullable/YANNum.Double.cs +++ b/lib/YANLib/Nullable/YANNum.Double.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToDouble(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDouble(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToDouble(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToDouble(); var maxValue = max.ToDouble(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextDouble(minValue.Value, maxValue.Value) : default; } diff --git a/lib/YANLib/Nullable/YANNum.Float.Nullable.cs b/lib/YANLib/Nullable/YANNum.Float.Nullable.cs index d6ddc8c..bf818a8 100644 --- a/lib/YANLib/Nullable/YANNum.Float.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Float.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToFloat(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToFloat(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Float.cs b/lib/YANLib/Nullable/YANNum.Float.cs index 3582b88..ae68047 100644 --- a/lib/YANLib/Nullable/YANNum.Float.cs +++ b/lib/YANLib/Nullable/YANNum.Float.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToFloat(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToFloat(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToFloat(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToFloat(); var maxValue = max.ToFloat(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextSingle(minValue.Value, maxValue.Value) : default; } diff --git a/lib/YANLib/Nullable/YANNum.Int.Nullable.cs b/lib/YANLib/Nullable/YANNum.Int.Nullable.cs index 8f9aef3..9612d77 100644 --- a/lib/YANLib/Nullable/YANNum.Int.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Int.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToInt(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToInt(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Int.cs b/lib/YANLib/Nullable/YANNum.Int.cs index d8fa337..29ecf96 100644 --- a/lib/YANLib/Nullable/YANNum.Int.cs +++ b/lib/YANLib/Nullable/YANNum.Int.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToInt(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToInt(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToInt(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToInt(); var maxValue = max.ToInt(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().Next(minValue.Value, maxValue.Value) : default; } diff --git a/lib/YANLib/Nullable/YANNum.Long.Nullable.cs b/lib/YANLib/Nullable/YANNum.Long.Nullable.cs index f1ce782..13a62aa 100644 --- a/lib/YANLib/Nullable/YANNum.Long.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Long.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToLong(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToLong(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Long.cs b/lib/YANLib/Nullable/YANNum.Long.cs index 3edceef..6acad80 100644 --- a/lib/YANLib/Nullable/YANNum.Long.cs +++ b/lib/YANLib/Nullable/YANNum.Long.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToLong(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToLong(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToLong(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToLong(); var maxValue = max.ToLong(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextInt64(minValue.Value, maxValue.Value) : default; } diff --git a/lib/YANLib/Nullable/YANNum.Nint.Nullable.cs b/lib/YANLib/Nullable/YANNum.Nint.Nullable.cs index 2e95e71..47d8bb5 100644 --- a/lib/YANLib/Nullable/YANNum.Nint.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Nint.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToNint(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNint(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Nint.cs b/lib/YANLib/Nullable/YANNum.Nint.cs index be7caf3..78ff92f 100644 --- a/lib/YANLib/Nullable/YANNum.Nint.cs +++ b/lib/YANLib/Nullable/YANNum.Nint.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToNint(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNint(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNint(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToNint(); var maxValue = max.ToNint(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextInt64(minValue.Value, maxValue.Value).ToNint() : default; } diff --git a/lib/YANLib/Nullable/YANNum.Nuint.Nullable.cs b/lib/YANLib/Nullable/YANNum.Nuint.Nullable.cs index 12b4d0b..e335a87 100644 --- a/lib/YANLib/Nullable/YANNum.Nuint.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Nuint.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToNuint(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNuint(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Nuint.cs b/lib/YANLib/Nullable/YANNum.Nuint.cs index 92182f4..8e69ea8 100644 --- a/lib/YANLib/Nullable/YANNum.Nuint.cs +++ b/lib/YANLib/Nullable/YANNum.Nuint.cs @@ -23,6 +23,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToNuint(); @@ -37,6 +38,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNuint(); @@ -51,6 +53,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToNuint(dfltVal); @@ -61,6 +64,7 @@ public static partial class YANNum { var minValue = min.ToNuint(); var maxValue = max.ToNuint(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : (new Random().NextInt64(nint.MinValue, (long)(maxValue - (minValue - (BigInteger)nint.MinValue))) - nint.MinValue).ToNuint() + minValue : default; } diff --git a/lib/YANLib/Nullable/YANNum.Sbyte.Nullable.cs b/lib/YANLib/Nullable/YANNum.Sbyte.Nullable.cs index 7791f85..12808c0 100644 --- a/lib/YANLib/Nullable/YANNum.Sbyte.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Sbyte.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToSbyte(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Sbyte.cs b/lib/YANLib/Nullable/YANNum.Sbyte.cs index 9075477..c32badd 100644 --- a/lib/YANLib/Nullable/YANNum.Sbyte.cs +++ b/lib/YANLib/Nullable/YANNum.Sbyte.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToSbyte(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToSbyte(); var maxValue = max.ToSbyte(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().Next(minValue.Value, maxValue.Value).ToSbyte() : default; } diff --git a/lib/YANLib/Nullable/YANNum.Short.Nullable.cs b/lib/YANLib/Nullable/YANNum.Short.Nullable.cs index 606d781..0cee16e 100644 --- a/lib/YANLib/Nullable/YANNum.Short.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Short.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToShort(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToShort(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Short.cs b/lib/YANLib/Nullable/YANNum.Short.cs index d640e72..bad0d0a 100644 --- a/lib/YANLib/Nullable/YANNum.Short.cs +++ b/lib/YANLib/Nullable/YANNum.Short.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToShort(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToShort(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToShort(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToShort(); var maxValue = max.ToShort(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().Next(minValue.Value, maxValue.Value).ToShort() : default; } diff --git a/lib/YANLib/Nullable/YANNum.Uint.Nullable.cs b/lib/YANLib/Nullable/YANNum.Uint.Nullable.cs index cbe73d7..088fc92 100644 --- a/lib/YANLib/Nullable/YANNum.Uint.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Uint.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUint(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUint(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Uint.cs b/lib/YANLib/Nullable/YANNum.Uint.cs index e3aa064..2d57f17 100644 --- a/lib/YANLib/Nullable/YANNum.Uint.cs +++ b/lib/YANLib/Nullable/YANNum.Uint.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUint(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUint(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUint(dfltVal); @@ -59,6 +62,7 @@ public static partial class YANNum { var minValue = min.ToUint(); var maxValue = max.ToUint(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : new Random().NextInt64(minValue.Value, maxValue.Value).ToUint() : default; } diff --git a/lib/YANLib/Nullable/YANNum.Ulong.Nullable.cs b/lib/YANLib/Nullable/YANNum.Ulong.Nullable.cs index 236cff4..0c02c79 100644 --- a/lib/YANLib/Nullable/YANNum.Ulong.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Ulong.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUlong(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUlong(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Ulong.cs b/lib/YANLib/Nullable/YANNum.Ulong.cs index 8b50835..e7f0a09 100644 --- a/lib/YANLib/Nullable/YANNum.Ulong.cs +++ b/lib/YANLib/Nullable/YANNum.Ulong.cs @@ -23,6 +23,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUlong(); @@ -37,6 +38,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUlong(); @@ -51,6 +53,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUlong(dfltVal); @@ -61,6 +64,7 @@ public static partial class YANNum { var minValue = min.ToUlong(); var maxValue = max.ToUlong(); + return minValue.HasValue && maxValue.HasValue ? minValue > maxValue ? default : (new Random().NextInt64(long.MinValue, (long)(maxValue - (minValue - (BigInteger)long.MinValue))) - long.MinValue).ToUlong() + minValue : default; } diff --git a/lib/YANLib/Nullable/YANNum.Ushort.Nullable.cs b/lib/YANLib/Nullable/YANNum.Ushort.Nullable.cs index e79a551..6922b19 100644 --- a/lib/YANLib/Nullable/YANNum.Ushort.Nullable.cs +++ b/lib/YANLib/Nullable/YANNum.Ushort.Nullable.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUshort(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUshort(dfltVal); diff --git a/lib/YANLib/Nullable/YANNum.Ushort.cs b/lib/YANLib/Nullable/YANNum.Ushort.cs index dcb29b7..cebbae2 100644 --- a/lib/YANLib/Nullable/YANNum.Ushort.cs +++ b/lib/YANLib/Nullable/YANNum.Ushort.cs @@ -21,6 +21,7 @@ public static partial class YANNum { yield break; } + foreach (var num in nums) { yield return num.ToUshort(); @@ -35,6 +36,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUshort(); @@ -49,6 +51,7 @@ public static partial class YANNum { yield break; } + foreach (var num in strs) { yield return num.ToUshort(dfltVal); diff --git a/lib/YANLib/Ultimate/Nullable/YANDateTime.Nullable.cs b/lib/YANLib/Ultimate/Nullable/YANDateTime.Nullable.cs index e1cf69f..1772861 100644 --- a/lib/YANLib/Ultimate/Nullable/YANDateTime.Nullable.cs +++ b/lib/YANLib/Ultimate/Nullable/YANDateTime.Nullable.cs @@ -16,6 +16,7 @@ public static partial class YANDateTime { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt, dfltVal); @@ -76,6 +77,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.GetWeekOfYear(); @@ -88,6 +90,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -100,6 +103,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -112,6 +116,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); diff --git a/lib/YANLib/Ultimate/Nullable/YANDateTime.cs b/lib/YANLib/Ultimate/Nullable/YANDateTime.cs index 45968ef..3284e0a 100644 --- a/lib/YANLib/Ultimate/Nullable/YANDateTime.cs +++ b/lib/YANLib/Ultimate/Nullable/YANDateTime.cs @@ -14,6 +14,7 @@ public static partial class YANDateTime { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(); @@ -33,6 +34,7 @@ public static partial class YANDateTime { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt); @@ -53,6 +55,7 @@ public static partial class YANDateTime { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt, dfltVal); @@ -73,6 +76,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.GetWeekOfYear(); @@ -85,6 +89,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -97,6 +102,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); @@ -109,6 +115,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -121,6 +128,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -133,6 +141,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -145,6 +154,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzSrc, tzDst); @@ -157,6 +167,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); @@ -169,6 +180,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); @@ -181,6 +193,7 @@ public static partial class YANDateTime { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); diff --git a/lib/YANLib/Ultimate/YANBytes.cs b/lib/YANLib/Ultimate/YANBytes.cs index f2618c5..30c6462 100644 --- a/lib/YANLib/Ultimate/YANBytes.cs +++ b/lib/YANLib/Ultimate/YANBytes.cs @@ -8,6 +8,7 @@ public static partial class YANBytes { yield break; } + foreach (var obj in objs) { yield return obj.ToByteArray(); @@ -20,6 +21,7 @@ public static partial class YANBytes { yield break; } + foreach (var arr in arrs) { yield return arr.FromByteArray(); diff --git a/lib/YANLib/Ultimate/YANDateTime.Nullable.cs b/lib/YANLib/Ultimate/YANDateTime.Nullable.cs index d2af07c..14896e5 100644 --- a/lib/YANLib/Ultimate/YANDateTime.Nullable.cs +++ b/lib/YANLib/Ultimate/YANDateTime.Nullable.cs @@ -16,6 +16,7 @@ public static IEnumerable ToDateTime(this IEnumerable strs, st { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt, dfltVal); @@ -76,6 +77,7 @@ public static IEnumerable GetWeekOfYear(this IEnumerable dts) { yield break; } + foreach (var dt in dts) { yield return dt.GetWeekOfYear(); @@ -88,6 +90,7 @@ public static IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); @@ -196,6 +207,7 @@ public static IEnumerable ChangeTimeZone(this IEnumerable ToDateTime(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(); @@ -33,6 +34,7 @@ public static IEnumerable ToDateTime(this IEnumerable strs, st { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt); @@ -53,6 +55,7 @@ public static IEnumerable ToDateTime(this IEnumerable strs, st { yield break; } + foreach (var str in strs) { yield return str.ToDateTime(fmt, dfltVal); @@ -73,6 +76,7 @@ public static IEnumerable GetWeekOfYear(this IEnumerable dts) { yield break; } + foreach (var dt in dts) { yield return dt.GetWeekOfYear(); @@ -85,6 +89,7 @@ public static IEnumerable ChangeTimeZone(this IEnumerable ChangeTimeZone(this IEnumerable { yield break; } + foreach (var dt in dts) { yield return dt.ChangeTimeZone(tzDst); diff --git a/lib/YANLib/Ultimate/YANJson.cs b/lib/YANLib/Ultimate/YANJson.cs index e977a38..153ca48 100644 --- a/lib/YANLib/Ultimate/YANJson.cs +++ b/lib/YANLib/Ultimate/YANJson.cs @@ -8,6 +8,7 @@ public static IEnumerable Serializes(this IEnumerable mdls) { yield break; } + foreach (var mdl in mdls) { yield return mdl.Serialize(); @@ -20,6 +21,7 @@ public static IEnumerable CamelSerializes(this IEnumerable mdls) { yield break; } + foreach (var mdl in mdls) { yield return mdl.CamelSerialize(); @@ -32,6 +34,7 @@ public static IEnumerable CamelSerializes(this IEnumerable mdls) { yield break; } + foreach (var str in strs) { yield return str.StandardDeserialize(); @@ -44,6 +47,7 @@ public static IEnumerable CamelSerializes(this IEnumerable mdls) { yield break; } + foreach (var str in strs) { yield return str.Deserialize(); diff --git a/lib/YANLib/Ultimate/YANNum.Byte.Nullable.cs b/lib/YANLib/Ultimate/YANNum.Byte.Nullable.cs index 109e832..29d0a6c 100644 --- a/lib/YANLib/Ultimate/YANNum.Byte.Nullable.cs +++ b/lib/YANLib/Ultimate/YANNum.Byte.Nullable.cs @@ -8,6 +8,7 @@ public static IEnumerable ToByte(this IEnumerable nums) where T : s { yield break; } + foreach (var num in nums) { yield return num.ToByte(); @@ -20,6 +21,7 @@ public static IEnumerable ToByte(this IEnumerable strs, T? dflt { yield break; } + foreach (var str in strs) { yield return str.ToByte(dfltVal); diff --git a/lib/YANLib/Ultimate/YANNum.Byte.cs b/lib/YANLib/Ultimate/YANNum.Byte.cs index aa6caa7..e789bd5 100644 --- a/lib/YANLib/Ultimate/YANNum.Byte.cs +++ b/lib/YANLib/Ultimate/YANNum.Byte.cs @@ -8,6 +8,7 @@ public static IEnumerable ToByte(this IEnumerable nums) where T : st { yield break; } + foreach (var num in nums) { yield return num.ToByte(); @@ -20,6 +21,7 @@ public static IEnumerable ToByte(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return YANLib.YANNum.ToByte(str); @@ -32,6 +34,7 @@ public static IEnumerable ToByte(this IEnumerable strs, T dfltV { yield break; } + foreach (var str in strs) { yield return str.ToByte(dfltVal); diff --git a/lib/YANLib/YANBool.Nullable.cs b/lib/YANLib/YANBool.Nullable.cs index a0988ed..5771fdf 100644 --- a/lib/YANLib/YANBool.Nullable.cs +++ b/lib/YANLib/YANBool.Nullable.cs @@ -22,6 +22,7 @@ public static IEnumerable ToBool(this IEnumerable nums) where T : s { yield break; } + foreach (var num in nums) { yield return num.ToBool(); @@ -36,6 +37,7 @@ public static IEnumerable ToBool(this IEnumerable strs, T? dflt { yield break; } + foreach (var num in strs) { yield return num.ToBool(dfltVal); diff --git a/lib/YANLib/YANBool.cs b/lib/YANLib/YANBool.cs index e54f94c..338f359 100644 --- a/lib/YANLib/YANBool.cs +++ b/lib/YANLib/YANBool.cs @@ -23,6 +23,7 @@ public static IEnumerable ToBool(this IEnumerable nums) where T : st { yield break; } + foreach (var num in nums) { yield return num.ToBool(); @@ -37,6 +38,7 @@ public static IEnumerable ToBool(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToBool(); @@ -51,6 +53,7 @@ public static IEnumerable ToBool(this IEnumerable strs, T dfltV { yield break; } + foreach (var num in strs) { yield return num.ToBool(dfltVal); diff --git a/lib/YANLib/YANDateTime.cs b/lib/YANLib/YANDateTime.cs index 227a5b7..1a4ff39 100644 --- a/lib/YANLib/YANDateTime.cs +++ b/lib/YANLib/YANDateTime.cs @@ -96,6 +96,7 @@ public static partial class YANDateTime public static DateTime ChangeTimeZone(this DateTime dt, T1 tzSrc, T2 tzDst) where T1 : struct where T2 : struct { var diff = tzDst.ToInt() - tzSrc.ToInt(); + return diff switch { < 0 when (dt - MinValue).TotalHours < Abs(diff) => default, diff --git a/lib/YANLib/YANEnumerable.cs b/lib/YANLib/YANEnumerable.cs index 8055d3b..3a8efc7 100644 --- a/lib/YANLib/YANEnumerable.cs +++ b/lib/YANLib/YANEnumerable.cs @@ -10,11 +10,14 @@ public static partial class YANEnumerable public static IEnumerable> ChunkBySize(this List srcs, T1 chunkSize) where T1 : struct { var size = chunkSize.ToInt(); + if (srcs.IsEmptyOrNull() && size < 1) { yield break; } + var cnt = srcs.Count; + for (var i = 0; i < cnt; i += size) { yield return srcs.GetRange(i, Min(size, cnt - i)); @@ -27,7 +30,9 @@ public static IEnumerable Clean(this IEnumerable srcs) { yield break; } + var t = typeof(T); + if (t.IsClass || GetUnderlyingType(t) is not null) { foreach (var src in srcs) @@ -53,6 +58,7 @@ public static IEnumerable Clean(this IEnumerable srcs) { yield break; } + foreach (var src in srcs) { if (src.IsNotWhiteSpaceAndNull()) diff --git a/lib/YANLib/YANModel.Property.cs b/lib/YANLib/YANModel.Property.cs index 0ab7500..f348296 100644 --- a/lib/YANLib/YANModel.Property.cs +++ b/lib/YANLib/YANModel.Property.cs @@ -12,14 +12,17 @@ public static bool AllPropertiesNotDefault(this T? mdl) { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly)) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return false; } } + return true; } @@ -31,14 +34,17 @@ public static bool AllPropertiesDefault(this T? mdl) { return false; } + foreach (var prop in typeof(T).GetProperties(Public | Instance | DeclaredOnly)) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default(T))) { return false; } } + return true; } @@ -50,14 +56,17 @@ public static bool AnyPropertiesNotDefault(this T? mdl) { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly)) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } @@ -69,14 +78,17 @@ public static bool AnyPropertiesDefault(this T? mdl) { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly)) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } @@ -88,14 +100,17 @@ public static bool AllPropertiesNotDefault(this T? mdl, params string[] names { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return false; } } + return true; } @@ -107,14 +122,17 @@ public static bool AllPropertiesDefault(this T? mdl, params string[] names) { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return false; } } + return true; } @@ -126,14 +144,17 @@ public static bool AnyPropertiesNotDefault(this T? mdl, params string[] names { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } @@ -145,14 +166,17 @@ public static bool AnyPropertiesDefault(this T? mdl, params string[] names) { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } @@ -164,14 +188,17 @@ public static bool AllPropertiesNotDefault(this T? mdl, IEnumerable n { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return false; } } + return true; } @@ -183,14 +210,17 @@ public static bool AllPropertiesDefault(this T? mdl, IEnumerable name { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return false; } } + return true; } @@ -202,14 +232,17 @@ public static bool AnyPropertiesNotDefault(this T? mdl, IEnumerable n { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (!EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } @@ -221,14 +254,17 @@ public static bool AnyPropertiesDefault(this T? mdl, IEnumerable name { return false; } + foreach (var prop in mdl.GetType().GetProperties(Public | Instance | DeclaredOnly).Where(p => names.Contains(p.Name))) { var type = prop.PropertyType; + if (EqualityComparer.Default.Equals(prop.GetValue(mdl), type.IsValueType ? CreateInstance(type) : default)) { return true; } } + return false; } diff --git a/lib/YANLib/YANModel.cs b/lib/YANLib/YANModel.cs index 80707b7..ba50310 100644 --- a/lib/YANLib/YANModel.cs +++ b/lib/YANLib/YANModel.cs @@ -5,17 +5,18 @@ namespace YANLib; public static partial class YANModel { - public static List ConvertList(this T mdl) where T : class => new() { mdl }; + public static List AsList(this T mdl) where T : class => new() { mdl }; - public static HashSet ConvertHashSet(this T mdl) where T : class => new() { mdl }; + public static HashSet AsHashSet(this T mdl) where T : class => new() { mdl }; - public static T[] ConvertArray(this T mdl) where T : class => new T[1] { mdl }; + public static T[] AsArray(this T mdl) where T : class => new T[1] { mdl }; public static T? ChangeTimeZoneAllProperties(this T? mdl, T1 tzSrc, T2 tzDst) where T : class where T1 : struct where T2 : struct { if (mdl is not null) { var properties = typeof(T).GetProperties(Public | Instance).Where(p => p.CanRead && p.CanWrite); + if (properties.Any()) { foreach (var prop in properties) @@ -24,11 +25,14 @@ public static partial class YANModel { continue; } + var val = prop.GetValue(mdl); + if (val is null) { continue; } + if (val is DateTime dt) { prop.SetValue(mdl, dt.ChangeTimeZone(tzSrc, tzDst)); @@ -44,6 +48,7 @@ public static partial class YANModel else if (val.GetType().IsGenericType && val.GetType().GetGenericTypeDefinition() == typeof(IList<>)) { var list = (IList)val; + if (list.Count > 0) { for (var i = 0; i < list.Count; i++) @@ -52,7 +57,9 @@ public static partial class YANModel { continue; } + var changedItem = ChangeTimeZoneAllProperties(list[i], tzSrc, tzDst); + if (changedItem is not null) { list[i] = changedItem; @@ -63,6 +70,7 @@ public static partial class YANModel } } } + return mdl; } @@ -72,6 +80,7 @@ public static partial class YANModel { yield break; } + foreach (var mdl in mdls) { yield return mdl.ChangeTimeZoneAllProperties(tzSrc, tzDst); @@ -83,6 +92,7 @@ public static partial class YANModel if (mdl is not null) { var properties = typeof(T).GetProperties(Public | Instance).Where(p => p.CanRead && p.CanWrite); + if (properties.Any()) { foreach (var prop in properties) @@ -91,11 +101,14 @@ public static partial class YANModel { continue; } + var val = prop.GetValue(mdl); + if (val is null) { continue; } + if (val is DateTime dt) { prop.SetValue(mdl, dt.ChangeTimeZone(tzSrc, tzDst)); @@ -111,6 +124,7 @@ public static partial class YANModel else if (val.GetType().IsGenericType && val.GetType().GetGenericTypeDefinition() == typeof(IList<>)) { var list = (IList)val; + if (list.Count > 0) { for (var i = 0; i < list.Count; i++) @@ -119,7 +133,9 @@ public static partial class YANModel { continue; } + var changedItem = ChangeTimeZoneAllProperties(list[i], tzSrc, tzDst); + if (changedItem is not null) { list[i] = changedItem; @@ -139,6 +155,7 @@ public static partial class YANModel { yield break; } + foreach (var mdl in mdls) { yield return mdl.ChangeTimeZoneAllProperties(tzSrc, tzDst); @@ -150,6 +167,7 @@ public static partial class YANModel if (mdl is not null) { var properties = typeof(T).GetProperties(Public | Instance).Where(p => p.CanRead && p.CanWrite); + if (properties.Any()) { foreach (var prop in properties) @@ -158,11 +176,14 @@ public static partial class YANModel { continue; } + var val = prop.GetValue(mdl); + if (val is null) { continue; } + if (val is DateTime dt) { prop.SetValue(mdl, dt.ChangeTimeZone(tzSrc, tzDst)); @@ -170,6 +191,7 @@ public static partial class YANModel else if (val.GetType().IsClass) { var changedVal = ChangeTimeZoneAllProperties(val, tzSrc, tzDst); + if (changedVal is not null) { prop.SetValue(mdl, changedVal); @@ -178,6 +200,7 @@ public static partial class YANModel else if (val.GetType().IsGenericType && val.GetType().GetGenericTypeDefinition() == typeof(IList<>)) { var list = (IList)val; + if (list.Count > 0) { for (var i = 0; i < list.Count; i++) @@ -186,7 +209,9 @@ public static partial class YANModel { continue; } + var changedItem = ChangeTimeZoneAllProperties(list[i], tzSrc, tzDst); + if (changedItem is not null) { list[i] = changedItem; @@ -197,6 +222,7 @@ public static partial class YANModel } } } + return mdl; } @@ -206,6 +232,7 @@ public static partial class YANModel { yield break; } + foreach (var mdl in mdls) { yield return mdl.ChangeTimeZoneAllProperties(tzSrc, tzDst); @@ -217,6 +244,7 @@ public static partial class YANModel if (mdl is not null) { var properties = typeof(T).GetProperties(Public | Instance).Where(p => p.CanRead && p.CanWrite); + if (properties.Any()) { foreach (var prop in properties) @@ -225,11 +253,14 @@ public static partial class YANModel { continue; } + var val = prop.GetValue(mdl); + if (val is null) { continue; } + if (val is DateTime dt) { prop.SetValue(mdl, dt.ChangeTimeZone(tzSrc, tzDst)); @@ -237,6 +268,7 @@ public static partial class YANModel else if (val.GetType().IsClass) { var changedVal = ChangeTimeZoneAllProperties(val, tzSrc, tzDst); + if (changedVal is not null) { prop.SetValue(mdl, changedVal); @@ -245,6 +277,7 @@ public static partial class YANModel else if (val.GetType().IsGenericType && val.GetType().GetGenericTypeDefinition() == typeof(IList<>)) { var list = (IList)val; + if (list.Count > 0) { for (var i = 0; i < list.Count; i++) @@ -253,7 +286,9 @@ public static partial class YANModel { continue; } + var changedItem = ChangeTimeZoneAllProperties(list[i], tzSrc, tzDst); + if (changedItem is not null) { list[i] = changedItem; @@ -264,6 +299,7 @@ public static partial class YANModel } } } + return mdl; } @@ -273,6 +309,7 @@ public static partial class YANModel { yield break; } + foreach (var mdl in mdls) { yield return mdl.ChangeTimeZoneAllProperties(tzSrc, tzDst); diff --git a/lib/YANLib/YANNum.Byte.cs b/lib/YANLib/YANNum.Byte.cs index 7411666..3d71672 100644 --- a/lib/YANLib/YANNum.Byte.cs +++ b/lib/YANLib/YANNum.Byte.cs @@ -31,6 +31,7 @@ public static byte GenerateRandomByte(T1 min, T2 max) where T1 : struct { var minValue = min.ToByte(); var maxValue = max.ToByte(); + return minValue > maxValue ? default : new Random().Next(minValue, maxValue).ToByte(); } diff --git a/lib/YANLib/YANNum.Decimal.Nullable.cs b/lib/YANLib/YANNum.Decimal.Nullable.cs index e9e0815..37aa629 100644 --- a/lib/YANLib/YANNum.Decimal.Nullable.cs +++ b/lib/YANLib/YANNum.Decimal.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToDecimal(this IEnumerable nums) where { yield break; } + foreach (var num in nums) { yield return num.ToDecimal(); @@ -35,6 +36,7 @@ public static IEnumerable ToDecimal(this IEnumerable strs, T { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(dfltVal); diff --git a/lib/YANLib/YANNum.Decimal.cs b/lib/YANLib/YANNum.Decimal.cs index 2795ce0..705a003 100644 --- a/lib/YANLib/YANNum.Decimal.cs +++ b/lib/YANLib/YANNum.Decimal.cs @@ -21,6 +21,7 @@ public static IEnumerable ToDecimal(this IEnumerable nums) where { yield break; } + foreach (var num in nums) { yield return num.ToDecimal(); @@ -35,6 +36,7 @@ public static IEnumerable ToDecimal(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(); @@ -49,6 +51,7 @@ public static IEnumerable ToDecimal(this IEnumerable strs, T { yield break; } + foreach (var num in strs) { yield return num.ToDecimal(dfltVal); @@ -59,6 +62,7 @@ public static decimal GenerateRandomDecimal(T1 min, T2 max) where T1 : s { var minValue = min.ToDecimal(); var maxValue = max.ToDecimal(); + return minValue > maxValue ? default : new Random().NextDecimal(minValue, maxValue); } diff --git a/lib/YANLib/YANNum.Double.Nullable.cs b/lib/YANLib/YANNum.Double.Nullable.cs index bd8b1fd..2845814 100644 --- a/lib/YANLib/YANNum.Double.Nullable.cs +++ b/lib/YANLib/YANNum.Double.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToDouble(this IEnumerable nums) where T { yield break; } + foreach (var num in nums) { yield return num.ToDouble(); @@ -35,6 +36,7 @@ public static IEnumerable ToDouble(this IEnumerable strs, T? { yield break; } + foreach (var num in strs) { yield return num.ToDouble(dfltVal); diff --git a/lib/YANLib/YANNum.Double.cs b/lib/YANLib/YANNum.Double.cs index 4891013..62864bc 100644 --- a/lib/YANLib/YANNum.Double.cs +++ b/lib/YANLib/YANNum.Double.cs @@ -21,6 +21,7 @@ public static IEnumerable ToDouble(this IEnumerable nums) where T { yield break; } + foreach (var num in nums) { yield return num.ToDouble(); @@ -35,6 +36,7 @@ public static IEnumerable ToDouble(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToDouble(); @@ -49,6 +51,7 @@ public static IEnumerable ToDouble(this IEnumerable strs, T d { yield break; } + foreach (var num in strs) { yield return num.ToDouble(dfltVal); @@ -59,6 +62,7 @@ public static double GenerateRandomDouble(T1 min, T2 max) where T1 : str { var minValue = min.ToDouble(); var maxValue = max.ToDouble(); + return minValue > maxValue ? default : new Random().NextDouble(minValue, maxValue); } diff --git a/lib/YANLib/YANNum.Float.Nullable.cs b/lib/YANLib/YANNum.Float.Nullable.cs index 1e3993f..25b99e8 100644 --- a/lib/YANLib/YANNum.Float.Nullable.cs +++ b/lib/YANLib/YANNum.Float.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToFloat(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToFloat(); @@ -35,6 +36,7 @@ public static IEnumerable ToFloat(this IEnumerable strs, T? df { yield break; } + foreach (var num in strs) { yield return num.ToFloat(dfltVal); diff --git a/lib/YANLib/YANNum.Float.cs b/lib/YANLib/YANNum.Float.cs index 7394ba7..6dc8949 100644 --- a/lib/YANLib/YANNum.Float.cs +++ b/lib/YANLib/YANNum.Float.cs @@ -21,6 +21,7 @@ public static IEnumerable ToFloat(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToFloat(); @@ -35,6 +36,7 @@ public static IEnumerable ToFloat(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToFloat(); @@ -49,6 +51,7 @@ public static IEnumerable ToFloat(this IEnumerable strs, T dfl { yield break; } + foreach (var num in strs) { yield return num.ToFloat(dfltVal); @@ -59,6 +62,7 @@ public static float GenerateRandomFloat(T1 min, T2 max) where T1 : struc { var minValue = min.ToFloat(); var maxValue = max.ToFloat(); + return minValue > maxValue ? default : new Random().NextSingle(minValue, maxValue); } diff --git a/lib/YANLib/YANNum.Int.Nullable.cs b/lib/YANLib/YANNum.Int.Nullable.cs index 6983a33..b0d1260 100644 --- a/lib/YANLib/YANNum.Int.Nullable.cs +++ b/lib/YANLib/YANNum.Int.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToInt(this IEnumerable nums) where T : str { yield break; } + foreach (var num in nums) { yield return num.ToInt(); @@ -35,6 +36,7 @@ public static IEnumerable ToInt(this IEnumerable strs, T? dfltVa { yield break; } + foreach (var num in strs) { yield return num.ToInt(dfltVal); diff --git a/lib/YANLib/YANNum.Int.cs b/lib/YANLib/YANNum.Int.cs index ca0e017..1f2dc9b 100644 --- a/lib/YANLib/YANNum.Int.cs +++ b/lib/YANLib/YANNum.Int.cs @@ -21,6 +21,7 @@ public static IEnumerable ToInt(this IEnumerable nums) where T : stru { yield break; } + foreach (var num in nums) { yield return num.ToInt(); @@ -35,6 +36,7 @@ public static IEnumerable ToInt(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToInt(); @@ -49,6 +51,7 @@ public static IEnumerable ToInt(this IEnumerable strs, T dfltVal { yield break; } + foreach (var num in strs) { yield return num.ToInt(dfltVal); @@ -59,6 +62,7 @@ public static int GenerateRandomInt(T1 min, T2 max) where T1 : struct wh { var minValue = min.ToInt(); var maxValue = max.ToInt(); + return minValue > maxValue ? default : new Random().Next(minValue, maxValue); } diff --git a/lib/YANLib/YANNum.Long.Nullable.cs b/lib/YANLib/YANNum.Long.Nullable.cs index 73182a8..2353d4b 100644 --- a/lib/YANLib/YANNum.Long.Nullable.cs +++ b/lib/YANLib/YANNum.Long.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToLong(this IEnumerable nums) where T : s { yield break; } + foreach (var num in nums) { yield return num.ToLong(); @@ -35,6 +36,7 @@ public static IEnumerable ToLong(this IEnumerable strs, T? dflt { yield break; } + foreach (var num in strs) { yield return num.ToLong(dfltVal); diff --git a/lib/YANLib/YANNum.Long.cs b/lib/YANLib/YANNum.Long.cs index ac67533..42a0d46 100644 --- a/lib/YANLib/YANNum.Long.cs +++ b/lib/YANLib/YANNum.Long.cs @@ -21,6 +21,7 @@ public static IEnumerable ToLong(this IEnumerable nums) where T : st { yield break; } + foreach (var num in nums) { yield return num.ToLong(); @@ -35,6 +36,7 @@ public static IEnumerable ToLong(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToLong(); @@ -49,6 +51,7 @@ public static IEnumerable ToLong(this IEnumerable strs, T dfltV { yield break; } + foreach (var num in strs) { yield return num.ToLong(dfltVal); @@ -59,6 +62,7 @@ public static long GenerateRandomLong(T1 min, T2 max) where T1 : struct { var minValue = min.ToLong(); var maxValue = max.ToLong(); + return minValue > maxValue ? default : new Random().NextInt64(minValue, maxValue); } diff --git a/lib/YANLib/YANNum.Nint.Nullable.cs b/lib/YANLib/YANNum.Nint.Nullable.cs index 31f0ebd..818764a 100644 --- a/lib/YANLib/YANNum.Nint.Nullable.cs +++ b/lib/YANLib/YANNum.Nint.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToNint(this IEnumerable nums) where T : s { yield break; } + foreach (var num in nums) { yield return num.ToNint(); @@ -35,6 +36,7 @@ public static IEnumerable ToNint(this IEnumerable strs, T? dflt { yield break; } + foreach (var num in strs) { yield return num.ToNint(dfltVal); diff --git a/lib/YANLib/YANNum.Nint.cs b/lib/YANLib/YANNum.Nint.cs index 5545c32..e23bc1f 100644 --- a/lib/YANLib/YANNum.Nint.cs +++ b/lib/YANLib/YANNum.Nint.cs @@ -21,6 +21,7 @@ public static IEnumerable ToNint(this IEnumerable nums) where T : st { yield break; } + foreach (var num in nums) { yield return num.ToNint(); @@ -35,6 +36,7 @@ public static IEnumerable ToNint(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToNint(); @@ -49,6 +51,7 @@ public static IEnumerable ToNint(this IEnumerable strs, T dfltV { yield break; } + foreach (var num in strs) { yield return num.ToNint(dfltVal); @@ -59,6 +62,7 @@ public static nint GenerateRandomNint(T1 min, T2 max) where T1 : struct { var minValue = min.ToNint(); var maxValue = max.ToNint(); + return minValue > maxValue ? default : new Random().NextInt64(minValue, maxValue).ToNint(); } diff --git a/lib/YANLib/YANNum.Nuint.Nullable.cs b/lib/YANLib/YANNum.Nuint.Nullable.cs index 138e348..ea0c25e 100644 --- a/lib/YANLib/YANNum.Nuint.Nullable.cs +++ b/lib/YANLib/YANNum.Nuint.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToNuint(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToNuint(); @@ -35,6 +36,7 @@ public static IEnumerable ToNuint(this IEnumerable strs, T? df { yield break; } + foreach (var num in strs) { yield return num.ToNuint(dfltVal); diff --git a/lib/YANLib/YANNum.Nuint.cs b/lib/YANLib/YANNum.Nuint.cs index 70f654d..85b30fe 100644 --- a/lib/YANLib/YANNum.Nuint.cs +++ b/lib/YANLib/YANNum.Nuint.cs @@ -23,6 +23,7 @@ public static IEnumerable ToNuint(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToNuint(); @@ -37,6 +38,7 @@ public static IEnumerable ToNuint(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToNuint(); @@ -51,6 +53,7 @@ public static IEnumerable ToNuint(this IEnumerable strs, T dfl { yield break; } + foreach (var num in strs) { yield return num.ToNuint(dfltVal); @@ -61,6 +64,7 @@ public static nuint GenerateRandomNuint(T1 min, T2 max) where T1 : struc { var minValue = min.ToNuint(); var maxValue = max.ToNuint(); + return minValue > maxValue ? default : (new Random().NextInt64(nint.MinValue, (long)(maxValue - (minValue - (BigInteger)nint.MinValue))) - nint.MinValue).ToNuint() + minValue; } diff --git a/lib/YANLib/YANNum.Sbyte.Nullable.cs b/lib/YANLib/YANNum.Sbyte.Nullable.cs index 005634e..2984807 100644 --- a/lib/YANLib/YANNum.Sbyte.Nullable.cs +++ b/lib/YANLib/YANNum.Sbyte.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToSbyte(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToSbyte(); @@ -35,6 +36,7 @@ public static IEnumerable ToSbyte(this IEnumerable strs, T? df { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(dfltVal); diff --git a/lib/YANLib/YANNum.Sbyte.cs b/lib/YANLib/YANNum.Sbyte.cs index 1fb5eeb..13a8ad7 100644 --- a/lib/YANLib/YANNum.Sbyte.cs +++ b/lib/YANLib/YANNum.Sbyte.cs @@ -21,6 +21,7 @@ public static IEnumerable ToSbyte(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToSbyte(); @@ -35,6 +36,7 @@ public static IEnumerable ToSbyte(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(); @@ -49,6 +51,7 @@ public static IEnumerable ToSbyte(this IEnumerable strs, T dfl { yield break; } + foreach (var num in strs) { yield return num.ToSbyte(dfltVal); @@ -59,6 +62,7 @@ public static sbyte GenerateRandomSbyte(T1 min, T2 max) where T1 : struc { var minValue = min.ToSbyte(); var maxValue = max.ToSbyte(); + return minValue > maxValue ? default : new Random().Next(minValue, maxValue).ToSbyte(); } diff --git a/lib/YANLib/YANNum.Short.Nullable.cs b/lib/YANLib/YANNum.Short.Nullable.cs index 0633083..fe9de13 100644 --- a/lib/YANLib/YANNum.Short.Nullable.cs +++ b/lib/YANLib/YANNum.Short.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToShort(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToShort(); @@ -35,6 +36,7 @@ public static IEnumerable ToShort(this IEnumerable strs, T? df { yield break; } + foreach (var num in strs) { yield return num.ToShort(dfltVal); diff --git a/lib/YANLib/YANNum.Short.cs b/lib/YANLib/YANNum.Short.cs index 76089d2..ea1fea1 100644 --- a/lib/YANLib/YANNum.Short.cs +++ b/lib/YANLib/YANNum.Short.cs @@ -21,6 +21,7 @@ public static IEnumerable ToShort(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToShort(); @@ -35,6 +36,7 @@ public static IEnumerable ToShort(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToShort(); @@ -49,6 +51,7 @@ public static IEnumerable ToShort(this IEnumerable strs, T dfl { yield break; } + foreach (var num in strs) { yield return num.ToShort(dfltVal); @@ -59,6 +62,7 @@ public static short GenerateRandomShort(T1 min, T2 max) where T1 : struc { var minValue = min.ToShort(); var maxValue = max.ToShort(); + return minValue > maxValue ? default : new Random().Next(minValue, maxValue).ToShort(); } diff --git a/lib/YANLib/YANNum.Uint.Nullable.cs b/lib/YANLib/YANNum.Uint.Nullable.cs index e1c6817..33ac9e3 100644 --- a/lib/YANLib/YANNum.Uint.Nullable.cs +++ b/lib/YANLib/YANNum.Uint.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToUint(this IEnumerable nums) where T : s { yield break; } + foreach (var num in nums) { yield return num.ToUint(); @@ -35,6 +36,7 @@ public static IEnumerable ToUint(this IEnumerable strs, T? dflt { yield break; } + foreach (var num in strs) { yield return num.ToUint(dfltVal); diff --git a/lib/YANLib/YANNum.Uint.cs b/lib/YANLib/YANNum.Uint.cs index 495fd81..ded8a9c 100644 --- a/lib/YANLib/YANNum.Uint.cs +++ b/lib/YANLib/YANNum.Uint.cs @@ -21,6 +21,7 @@ public static IEnumerable ToUint(this IEnumerable nums) where T : st { yield break; } + foreach (var num in nums) { yield return num.ToUint(); @@ -35,6 +36,7 @@ public static IEnumerable ToUint(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToUint(); @@ -49,6 +51,7 @@ public static IEnumerable ToUint(this IEnumerable strs, T dfltV { yield break; } + foreach (var num in strs) { yield return num.ToUint(dfltVal); @@ -59,6 +62,7 @@ public static uint GenerateRandomUint(T1 min, T2 max) where T1 : struct { var minValue = min.ToUint(); var maxValue = max.ToUint(); + return minValue > maxValue ? default : new Random().NextInt64(minValue, maxValue).ToUint(); } diff --git a/lib/YANLib/YANNum.Ulong.Nullable.cs b/lib/YANLib/YANNum.Ulong.Nullable.cs index 554afec..6f4921f 100644 --- a/lib/YANLib/YANNum.Ulong.Nullable.cs +++ b/lib/YANLib/YANNum.Ulong.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToUlong(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToUlong(); @@ -35,6 +36,7 @@ public static IEnumerable ToUlong(this IEnumerable strs, T? df { yield break; } + foreach (var num in strs) { yield return num.ToUlong(dfltVal); diff --git a/lib/YANLib/YANNum.Ulong.cs b/lib/YANLib/YANNum.Ulong.cs index bc05750..eb70089 100644 --- a/lib/YANLib/YANNum.Ulong.cs +++ b/lib/YANLib/YANNum.Ulong.cs @@ -23,6 +23,7 @@ public static IEnumerable ToUlong(this IEnumerable nums) where T : { yield break; } + foreach (var num in nums) { yield return num.ToUlong(); @@ -37,6 +38,7 @@ public static IEnumerable ToUlong(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToUlong(); @@ -51,6 +53,7 @@ public static IEnumerable ToUlong(this IEnumerable strs, T dfl { yield break; } + foreach (var num in strs) { yield return num.ToUlong(dfltVal); @@ -61,6 +64,7 @@ public static ulong GenerateRandomUlong(T1 min, T2 max) where T1 : struc { var minValue = min.ToUlong(); var maxValue = max.ToUlong(); + return minValue > maxValue ? default : (new Random().NextInt64(long.MinValue, (long)(maxValue - (minValue - (BigInteger)long.MinValue))) - long.MinValue).ToUlong() + minValue; } diff --git a/lib/YANLib/YANNum.Ushort.Nullable.cs b/lib/YANLib/YANNum.Ushort.Nullable.cs index 537b8d2..431ad26 100644 --- a/lib/YANLib/YANNum.Ushort.Nullable.cs +++ b/lib/YANLib/YANNum.Ushort.Nullable.cs @@ -21,6 +21,7 @@ public static IEnumerable ToUshort(this IEnumerable nums) where T { yield break; } + foreach (var num in nums) { yield return num.ToUshort(); @@ -35,6 +36,7 @@ public static IEnumerable ToUshort(this IEnumerable strs, T? { yield break; } + foreach (var num in strs) { yield return num.ToUshort(dfltVal); diff --git a/lib/YANLib/YANNum.Ushort.cs b/lib/YANLib/YANNum.Ushort.cs index 7568bc7..6356019 100644 --- a/lib/YANLib/YANNum.Ushort.cs +++ b/lib/YANLib/YANNum.Ushort.cs @@ -21,6 +21,7 @@ public static IEnumerable ToUshort(this IEnumerable nums) where T { yield break; } + foreach (var num in nums) { yield return num.ToUshort(); @@ -35,6 +36,7 @@ public static IEnumerable ToUshort(this IEnumerable strs) { yield break; } + foreach (var num in strs) { yield return num.ToUshort(); @@ -49,6 +51,7 @@ public static IEnumerable ToUshort(this IEnumerable strs, T d { yield break; } + foreach (var num in strs) { yield return num.ToUshort(dfltVal); @@ -59,6 +62,7 @@ public static ushort GenerateRandomUshort(T1 min, T2 max) where T1 : str { var minValue = min.ToUshort(); var maxValue = max.ToUshort(); + return minValue > maxValue ? default : new Random().Next(minValue, maxValue).ToUshort(); } diff --git a/lib/YANLib/YANNum.cs b/lib/YANLib/YANNum.cs index 3a123de..6c44e0b 100644 --- a/lib/YANLib/YANNum.cs +++ b/lib/YANLib/YANNum.cs @@ -9,7 +9,9 @@ public static partial class YANNum { return default; } + var min = nums[0]; + for (var i = 1; i < nums?.Length; i++) { if (nums[i] is not null && nums[i].CompareTo(min) < 0) @@ -17,6 +19,7 @@ public static partial class YANNum min = nums[i]; } } + return min; } @@ -26,7 +29,9 @@ public static partial class YANNum { return default; } + var max = nums[0]; + for (var i = 1; i < nums?.Length; i++) { if (nums[i]?.CompareTo(max) > 0) @@ -34,6 +39,7 @@ public static partial class YANNum max = nums[i]; } } + return max; } } diff --git a/lib/YANLib/YANPass.cs b/lib/YANLib/YANPass.cs index bc97236..0cabe1d 100644 --- a/lib/YANLib/YANPass.cs +++ b/lib/YANLib/YANPass.cs @@ -30,8 +30,10 @@ public class YANPass if (password.IsNotWhiteSpaceAndNull() && SaltSize > 0 && Iterations > 0 && KeySize > 0) { var salt = GetBytes(SaltSize); + return new StringBuilder().Append(ToHexString(Pbkdf2(password, salt, Iterations, Algorithm, KeySize))).Append(SegmentDelimiter).Append(ToHexString(salt)).Append(SegmentDelimiter).Append(Iterations).Append(SegmentDelimiter).Append(Algorithm).ToString(); } + return default; } @@ -40,12 +42,15 @@ public bool Verify(string password, string strHash) if (strHash.IsNotWhiteSpaceAndNull() && SegmentDelimiter.IsNotEmptyAndWhiteSpace()) { var segs = strHash.Split(SegmentDelimiter); + if (segs.Length > 3) { var hash = FromHexString(segs[0]); + return FixedTimeEquals(Pbkdf2(password, FromHexString(segs[1]), segs[2].ToInt(), new HashAlgorithmName(segs[3]), hash.Length), hash); } } + return false; } @@ -60,14 +65,18 @@ public bool IsValidPassword(string password, params char[] splChars) { return false; } + // has 8 characters if (password.Length < 8) { return false; } + // Check if the password matches the regex pattern var newPwdSplChar = new HashSet(PASSWORD_SPECIAL_CHARATERS_STANDARD); + newPwdSplChar.UnionWith(splChars); + return IsMatch(password, $@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[{Escape(new string(newPwdSplChar.ToArray()))}]).+$"); } @@ -78,14 +87,18 @@ public bool IsValidPassword(string password, IEnumerable splChars) { return false; } + // has 8 characters if (password.Length < 8) { return false; } + // Check if the password matches the regex pattern var newPwdSplChar = new HashSet(PASSWORD_SPECIAL_CHARATERS_STANDARD); + newPwdSplChar.UnionWith(splChars); + return IsMatch(password, $@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[{Escape(new string(newPwdSplChar.ToArray()))}]).+$"); } @@ -96,14 +109,18 @@ public bool IsValidPassword(string password, T len, params char[] splChars) w { return false; } + // has len character if (password.Length < len.ToByte()) { return false; } + // Check if the password matches the regex pattern var newPwdSplChar = new HashSet(PASSWORD_SPECIAL_CHARATERS_STANDARD); + newPwdSplChar.UnionWith(splChars); + return IsMatch(password, $@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[{Escape(new string(newPwdSplChar.ToArray()))}]).+$"); } @@ -114,14 +131,18 @@ public bool IsValidPassword(string password, T len, IEnumerable splChar { return false; } + // has len character if (password.Length < len.ToByte()) { return false; } + // Check if the password matches the regex pattern var newPwdSplChar = new HashSet(PASSWORD_SPECIAL_CHARATERS_STANDARD); + newPwdSplChar.UnionWith(splChars); + return IsMatch(password, $@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[{Escape(new string(newPwdSplChar.ToArray()))}]).+$"); } #endregion diff --git a/lib/YANLib/YANProcess.cs b/lib/YANLib/YANProcess.cs index cb4cfb3..e0023d6 100644 --- a/lib/YANLib/YANProcess.cs +++ b/lib/YANLib/YANProcess.cs @@ -16,6 +16,7 @@ await WhenAll(GetProcessesByName(name).Select(p => { p.Kill(); } + return p.WaitForExitAsync(); })); } @@ -31,6 +32,7 @@ await WhenAll(names.SelectMany(name => GetProcessesByName(name)).Select(p => { p.Kill(); } + return p.WaitForExitAsync(); })); } @@ -46,6 +48,7 @@ await WhenAll(names.SelectMany(name => GetProcessesByName(name)).Select(p => { p.Kill(); } + return p.WaitForExitAsync(); })); } diff --git a/lib/YANLib/YANRandom.cs b/lib/YANLib/YANRandom.cs index 1535609..38954b2 100644 --- a/lib/YANLib/YANRandom.cs +++ b/lib/YANLib/YANRandom.cs @@ -11,6 +11,7 @@ public static float NextSingle(this Random rnd, T1 min, T2 max) where T1 { var minValue = min.ToFloat(); var maxValue = max.ToFloat(); + return minValue < maxValue ? rnd.NextSingle() * (maxValue - minValue) + minValue : minValue == maxValue ? minValue : default; } @@ -18,6 +19,7 @@ public static double NextDouble(this Random rnd, T1 min, T2 max) where T { var minValue = min.ToDouble(); var maxValue = max.ToDouble(); + return minValue < maxValue ? rnd.NextDouble() * (maxValue - minValue) + minValue : minValue == maxValue ? minValue : default; } @@ -25,6 +27,7 @@ public static decimal NextDecimal(this Random rnd, T1 min, T2 max) where { var minValue = min.ToDecimal(); var maxValue = max.ToDecimal(); + return minValue < maxValue ? rnd.NextDecimal() * (maxValue - minValue) + minValue : minValue == maxValue ? minValue : default; } } diff --git a/lib/YANLib/YANTask.cs b/lib/YANLib/YANTask.cs index b79d233..8b2f5a0 100644 --- a/lib/YANLib/YANTask.cs +++ b/lib/YANLib/YANTask.cs @@ -12,11 +12,13 @@ public static partial class YANTask if (tasks is not null && tasks.Any()) { var cmplTask = await WhenAny(tasks.Select(t => t.AsTask()).ToList()).ConfigureAwait(false); + if (cmplTask.IsCompletedSuccessfully && typeof(T).IsValueType && cmplTask.Result.Equals(goodRslt)) { return cmplTask.Result; } } + return default; } @@ -27,8 +29,10 @@ public static partial class YANTask if (tasks is not null && tasks.Any()) { var valueTasks = tasks.Select(t => new ValueTask(t)); + return await valueTasks.WaitAnyWithCondition(goodRslt); } + return default; } @@ -39,17 +43,22 @@ public static partial class YANTask if (tasks is not null && tasks.Any()) { var taskSet = tasks.Select(t => t.AsTask()).ToHashSet(); + while (taskSet.Count > 0) { var cmplTask = await WhenAny(taskSet).ConfigureAwait(false); + _ = taskSet.Remove(cmplTask); + var rslt = await cmplTask.ConfigureAwait(false); + if (typeof(T).IsValueType && rslt.Equals(goodRslt)) { return rslt; } } } + return default; } @@ -60,8 +69,10 @@ public static partial class YANTask if (tasks is not null && tasks.Any()) { var valueTasks = tasks.Select(t => new ValueTask(t)); + return await valueTasks.WhenAnyWithCondition(goodRslt); } + return default; } } diff --git a/lib/YANLib/YANText.Char.cs b/lib/YANLib/YANText.Char.cs index 08cff60..5eab08c 100644 --- a/lib/YANLib/YANText.Char.cs +++ b/lib/YANLib/YANText.Char.cs @@ -143,7 +143,9 @@ public static bool AllNotEqualsIgnoreCase(params char[] cs) { return false; } + var hashSet = new HashSet(cs.Length); + for (var i = 0; i < cs.Length; i++) { if (!hashSet.Add(cs[i].ToLowerInvariant())) @@ -151,6 +153,7 @@ public static bool AllNotEqualsIgnoreCase(params char[] cs) return false; } } + return true; } @@ -162,7 +165,9 @@ public static bool AllNotEqualsIgnoreCase(this IEnumerable cs) { return false; } + var hashSet = new HashSet(cs.Count()); + foreach (var c in cs) { if (!hashSet.Add(c.ToLowerInvariant())) @@ -170,6 +175,7 @@ public static bool AllNotEqualsIgnoreCase(this IEnumerable cs) return false; } } + return true; } @@ -182,6 +188,7 @@ public static bool AllNotEqualsIgnoreCase(this IEnumerable cs) public static char GenerateRandomCharacter() { var chars = "abcdefghijklmnopqrstuvwxyz"; + return chars[GenerateRandomByte(chars.Length)]; } @@ -201,6 +208,7 @@ public static IEnumerable ToLower(this IEnumerable cs) { yield break; } + foreach (var c in cs) { yield return ToLower(c); @@ -215,6 +223,7 @@ public static IEnumerable ToLowerInvariant(this IEnumerable cs) { yield break; } + foreach (var c in cs) { yield return ToLowerInvariant(c); @@ -229,6 +238,7 @@ public static IEnumerable ToUpper(this IEnumerable cs) { yield break; } + foreach (var c in cs) { yield return ToUpper(c); @@ -243,6 +253,7 @@ public static IEnumerable ToUpperInvariant(this IEnumerable cs) { yield break; } + foreach (var c in cs) { yield return ToUpperInvariant(c); diff --git a/lib/YANLib/YANText.String.cs b/lib/YANLib/YANText.String.cs index 6d08e23..b1bb78d 100644 --- a/lib/YANLib/YANText.String.cs +++ b/lib/YANLib/YANText.String.cs @@ -84,7 +84,9 @@ public static bool AllNotEqualsIgnoreCase(params string[] strs) { return false; } + var hashSet = new HashSet(strs.Length, StringComparer.OrdinalIgnoreCase); + for (var i = 0; i < strs.Length; i++) { if (!hashSet.Add(strs[i])) @@ -92,6 +94,7 @@ public static bool AllNotEqualsIgnoreCase(params string[] strs) return false; } } + return true; } @@ -103,7 +106,9 @@ public static bool AllNotEqualsIgnoreCase(this IEnumerable strs) { return false; } + var hashSet = new HashSet(strs.Count(), StringComparer.OrdinalIgnoreCase); + foreach (var str in strs) { if (!hashSet.Add(str)) @@ -111,6 +116,7 @@ public static bool AllNotEqualsIgnoreCase(this IEnumerable strs) return false; } } + return true; } @@ -130,6 +136,7 @@ public static IEnumerable ToLower(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return ToLower(str); @@ -144,6 +151,7 @@ public static IEnumerable ToLowerInvariant(this IEnumerable strs { yield break; } + foreach (var str in strs) { yield return ToLowerInvariant(str); @@ -158,6 +166,7 @@ public static IEnumerable ToUpper(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return ToUpper(str); @@ -172,6 +181,7 @@ public static IEnumerable ToUpperInvariant(this IEnumerable strs { yield break; } + foreach (var str in strs) { yield return ToUpperInvariant(str); diff --git a/lib/YANLib/YANText.cs b/lib/YANLib/YANText.cs index aca885c..85eef62 100644 --- a/lib/YANLib/YANText.cs +++ b/lib/YANLib/YANText.cs @@ -14,6 +14,7 @@ public static IEnumerable ToTitle(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.ToTitle(); @@ -26,8 +27,10 @@ public static string ToCapitalize(this string str) { return str; } + var sb = new StringBuilder(str); var is1stChar = true; + for (var i = 0; i < sb.Length; i++) { if (is1stChar && sb[i].IsAlphabetic()) @@ -40,6 +43,7 @@ public static string ToCapitalize(this string str) sb[i] = sb[i].ToLower(); } } + return sb.ToString(); } @@ -49,6 +53,7 @@ public static IEnumerable ToCapitalize(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.ToCapitalize(); @@ -61,9 +66,12 @@ public static string CleanSpace(this string str) { return str; } + str = str.Trim(); + var sb = new StringBuilder(); var isWhtSp = false; + for (var i = 0; i < str.Length; i++) { if (str[i].IsWhiteSpace()) @@ -80,6 +88,7 @@ public static string CleanSpace(this string str) isWhtSp = false; } } + return sb.ToString(); } @@ -89,6 +98,7 @@ public static IEnumerable CleanSpace(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.CleanSpace(); @@ -101,18 +111,23 @@ public static string FormatName(this string str) { return str; } + str = str.Trim(); + var sb = new StringBuilder(); var isPrevCharWhtSp = true; + for (var i = 0; i < str.Length; i++) { if (str[i].IsPunctuation() || str[i].IsNumber() || isPrevCharWhtSp && str[i].IsWhiteSpace()) { continue; } + _ = isPrevCharWhtSp ? sb.Append(str[i].ToUpper()) : sb.Append(str[i].ToLower()); isPrevCharWhtSp = str[i].IsWhiteSpace(); } + return sb.ToString(); } @@ -122,6 +137,7 @@ public static IEnumerable FormatName(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.FormatName(); @@ -134,8 +150,11 @@ public static string FilterAlphabetic(this string str) { return str; } + str = str.Trim(); + var sb = new StringBuilder(); + for (var i = 0; i < str.Length; i++) { if (str[i].IsAlphabetic()) @@ -143,6 +162,7 @@ public static string FilterAlphabetic(this string str) _ = sb.Append(str[i]); } } + return sb.ToString(); } @@ -152,6 +172,7 @@ public static IEnumerable FilterAlphabetic(this IEnumerable strs { yield break; } + foreach (var str in strs) { yield return str.FilterAlphabetic(); @@ -164,8 +185,11 @@ public static string FilterNumber(this string str) { return str; } + str = str.Trim(); + var sb = new StringBuilder(); + for (var i = 0; i < str.Length; i++) { if (str[i].IsNumber()) @@ -173,6 +197,7 @@ public static string FilterNumber(this string str) _ = sb.Append(str[i]); } } + return sb.ToString(); } @@ -182,6 +207,7 @@ public static IEnumerable FilterNumber(this IEnumerable strs) { yield break; } + foreach (var str in strs) { yield return str.FilterNumber(); @@ -194,8 +220,11 @@ public static string FilterAlphanumeric(this string str) { return str; } + str = str.Trim(); + var sb = new StringBuilder(); + for (var i = 0; i < str.Length; i++) { if (str[i].IsNumber() || str[i].IsAlphabetic()) @@ -203,6 +232,7 @@ public static string FilterAlphanumeric(this string str) _ = sb.Append(str[i]); } } + return sb.ToString(); } @@ -212,6 +242,7 @@ public static IEnumerable FilterAlphanumeric(this IEnumerable st { yield break; } + foreach (var str in strs) { yield return str.FilterAlphanumeric(); diff --git a/logstash/pipeline/logstash.conf b/logstash/pipeline/logstash.conf index 10cb04c..3c441cd 100644 --- a/logstash/pipeline/logstash.conf +++ b/logstash/pipeline/logstash.conf @@ -7,6 +7,11 @@ input { port => 50000 } + udp { + port => 50000 + codec => json + } + file { path => "/usr/share/logstash/logs/*.log" sincedb_path => "/dev/null" diff --git a/src/YANLib.Application.Contracts/Common/RedisConstant.cs b/src/YANLib.Application.Contracts/Common/RedisConstant.cs new file mode 100644 index 0000000..4d8adf0 --- /dev/null +++ b/src/YANLib.Application.Contracts/Common/RedisConstant.cs @@ -0,0 +1,10 @@ +namespace YANLib.Common; + +public readonly struct RedisConstant +{ + public const string YANLIB_PREF = "yanlib"; + public const string SMP_PREF = "sample"; + public const string DEV_TYPE_PREF = "developtype"; + + public static readonly string DEV_TYPE_GRP = $"{YANLIB_PREF}:{SMP_PREF}:{DEV_TYPE_PREF}"; +} diff --git a/src/YANLib.Application.Contracts/DTOs/DeveloperTypeRedis.cs b/src/YANLib.Application.Contracts/DTOs/DeveloperTypeRedis.cs new file mode 100644 index 0000000..f6f7bdc --- /dev/null +++ b/src/YANLib.Application.Contracts/DTOs/DeveloperTypeRedis.cs @@ -0,0 +1,11 @@ +using System; + +namespace YANLib.DTOs; + +public sealed class DeveloperTypeRedis +{ + public string Name { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Dtos/JsonDto.cs b/src/YANLib.Application.Contracts/Dtos/JsonDto.cs deleted file mode 100644 index 6b0e780..0000000 --- a/src/YANLib.Application.Contracts/Dtos/JsonDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace YANLib.Dtos; - -public class JsonDto -{ - public Guid Id { get; set; } -} diff --git a/src/YANLib.Application.Contracts/Dtos/RedisDto.cs b/src/YANLib.Application.Contracts/Dtos/RedisDto.cs deleted file mode 100644 index bed1d38..0000000 --- a/src/YANLib.Application.Contracts/Dtos/RedisDto.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YANLib.Dtos; - -public class RedisDto -{ - public int Id { get; set; } - public string Name { get; set; } -} diff --git a/src/YANLib.Application.Contracts/EsIndexs/DeveloperIndex.cs b/src/YANLib.Application.Contracts/EsIndexs/DeveloperIndex.cs new file mode 100644 index 0000000..ade2c05 --- /dev/null +++ b/src/YANLib.Application.Contracts/EsIndexs/DeveloperIndex.cs @@ -0,0 +1,25 @@ +using Nest; +using System; +using System.Collections.Generic; +using YANLib.Responses; + +namespace YANLib.EsIndexs; + +public sealed class DeveloperIndex +{ + public string Id { get; set; } + [Keyword] + public string DeveloperId { get; set; } + public string Name { get; set; } + [Keyword] + public string Phone { get; set; } + public string IdCard { get; set; } + public bool IsActive { get; set; } + public int Version { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } + [Nested] + public DeveloperTypeResponse DeveloperType { get; set; } + [Nested] + public List Certificates { get; set; } +} diff --git a/src/YANLib.Application.Contracts/EsServices/IDeveloperEsService.cs b/src/YANLib.Application.Contracts/EsServices/IDeveloperEsService.cs new file mode 100644 index 0000000..591c905 --- /dev/null +++ b/src/YANLib.Application.Contracts/EsServices/IDeveloperEsService.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using YANLib.EsIndexs; + +namespace YANLib.EsServices; + +public interface IDeveloperEsService +{ + public ValueTask Get(string id); + public ValueTask Set(DeveloperIndex data); + public ValueTask SetBulk(List datas); + public ValueTask DeleteAll(); + public ValueTask> GetByDeveloperId(Guid developerId); + public ValueTask> GetByPhone(string phone); +} diff --git a/src/YANLib.Application.Contracts/Requests/CertificateRipRequest.cs b/src/YANLib.Application.Contracts/Requests/CertificateRipRequest.cs new file mode 100644 index 0000000..cfd18d7 --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/CertificateRipRequest.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace YANLib.Requests; + +public sealed class CertificateRipRequest +{ + [Required] + public string Name { get; set; } + public double? GPA { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Requests/DeveloperFreeRequest.cs b/src/YANLib.Application.Contracts/Requests/DeveloperFreeRequest.cs new file mode 100644 index 0000000..549514c --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/DeveloperFreeRequest.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace YANLib.Requests; + +public sealed class DeveloperFreeRequest +{ + public string Name { get; set; } + public string Phone { get; set; } + public int? DeveloperTypeCode { get; set; } + public List Certificates { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Requests/DeveloperRequest.cs b/src/YANLib.Application.Contracts/Requests/DeveloperRequest.cs new file mode 100644 index 0000000..5eebcb0 --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/DeveloperRequest.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace YANLib.Requests; + +public sealed class DeveloperRequest +{ + [Required] + public string Name { get; set; } + public string Phone { get; set; } + [Required] + public string IdCard { get; set; } + [Required] + public int DeveloperTypeCode { get; set; } + public List Certificates { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Requests/DeveloperTypeRequest.cs b/src/YANLib.Application.Contracts/Requests/DeveloperTypeRequest.cs new file mode 100644 index 0000000..7c03219 --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/DeveloperTypeRequest.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace YANLib.Requests; + +public sealed class DeveloperTypeRequest +{ + [Required] + public int Code { get; set; } + [Required] + public string Name { get; set; } + public bool IsActive { get; set; } = true; +} diff --git a/src/YANLib.Application.Contracts/Requests/SampleRequest.cs b/src/YANLib.Application.Contracts/Requests/SampleRequest.cs new file mode 100644 index 0000000..ead5b43 --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/SampleRequest.cs @@ -0,0 +1,8 @@ +using System; + +namespace YANLib.Requests; + +public sealed class SampleRequest +{ + public Guid Id { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Responses/CertificateResponse.cs b/src/YANLib.Application.Contracts/Responses/CertificateResponse.cs new file mode 100644 index 0000000..07b5fc8 --- /dev/null +++ b/src/YANLib.Application.Contracts/Responses/CertificateResponse.cs @@ -0,0 +1,13 @@ +using System; + +namespace YANLib.Responses; + +public sealed record CertificateResponse +{ + public Guid Id { get; set; } + public string Name { get; set; } + public double? GPA { get; set; } + public Guid? DeveloperId { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Responses/DeveloperResponse.cs b/src/YANLib.Application.Contracts/Responses/DeveloperResponse.cs new file mode 100644 index 0000000..c903287 --- /dev/null +++ b/src/YANLib.Application.Contracts/Responses/DeveloperResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace YANLib.Responses; + +public sealed record DeveloperResponse +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Phone { get; set; } + public string IdCard { get; set; } + public bool IsActive { get; set; } + public int Version { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } + public DeveloperTypeResponse DeveloperType { get; set; } + public List Certificates { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Responses/DeveloperTypeResponse.cs b/src/YANLib.Application.Contracts/Responses/DeveloperTypeResponse.cs new file mode 100644 index 0000000..be8ff8c --- /dev/null +++ b/src/YANLib.Application.Contracts/Responses/DeveloperTypeResponse.cs @@ -0,0 +1,12 @@ +using System; + +namespace YANLib.Responses; + +public sealed record DeveloperTypeResponse +{ + public int Code { get; set; } + public string Name { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Services/IDeveloperService.cs b/src/YANLib.Application.Contracts/Services/IDeveloperService.cs new file mode 100644 index 0000000..8c6df56 --- /dev/null +++ b/src/YANLib.Application.Contracts/Services/IDeveloperService.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using YANLib.Requests; +using YANLib.Responses; + +namespace YANLib.Services; + +public interface IDeveloperService : IApplicationService +{ + public ValueTask Get(Guid id); + public ValueTask Insert(DeveloperRequest request); + public ValueTask Adjust(string idCard, DeveloperFreeRequest request); + public ValueTask GetByIdCard(string idCard); + public ValueTask> GetByPhone(string phone); + public ValueTask SyncDbToEs(); +} diff --git a/src/YANLib.Application.Contracts/Services/IDeveloperTypeService.cs b/src/YANLib.Application.Contracts/Services/IDeveloperTypeService.cs new file mode 100644 index 0000000..64afb0d --- /dev/null +++ b/src/YANLib.Application.Contracts/Services/IDeveloperTypeService.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using YANLib.Requests; +using YANLib.Responses; + +namespace YANLib.Services; + +public interface IDeveloperTypeService : IApplicationService +{ + public ValueTask> GetAll(); + public ValueTask Get(int code); + public ValueTask Insert(DeveloperTypeRequest request); + public ValueTask Update(DeveloperTypeRequest request); + public ValueTask SyncDbToRedis(); +} diff --git a/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj b/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj index 3893c8f..8bb5f05 100644 --- a/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj +++ b/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj @@ -1,19 +1,20 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - - + + + + + - - - + + + diff --git a/src/YANLib.Application.Redis/Services/Implements/RedisService.cs b/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs similarity index 64% rename from src/YANLib.Application.Redis/Services/Implements/RedisService.cs rename to src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs index 012cf3c..6752f20 100644 --- a/src/YANLib.Application.Redis/Services/Implements/RedisService.cs +++ b/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs @@ -2,25 +2,25 @@ using StackExchange.Redis; using Volo.Abp; using YANLib.Application.Redis.ConnectionFactory; -using YANLib.Dtos; -using YANLib.Exceptions; +using YANLib.DTOs; using static System.Text.Encoding; using static System.Threading.Tasks.Task; -using static YANLib.Exceptions.ExceptionMessage; +using static YANLib.YANLibConsts; +using static YANLib.YANLibDomainErrorCodes; namespace YANLib.Application.Redis.Services.Implements; -public class RedisService : IRedisService +public class DeveloperTypeRedisService : IRedisService { #region Fields - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IRedisConnectionFactory _connectionFactory; private readonly ConnectionMultiplexer _connectionMultiplexer; private readonly IDatabase _database; #endregion #region Constructors - public RedisService(ILogger logger, IRedisConnectionFactory connectionFactory) + public DeveloperTypeRedisService(ILogger logger, IRedisConnectionFactory connectionFactory) { _logger = logger; _connectionFactory = connectionFactory; @@ -30,78 +30,89 @@ public RedisService(ILogger logger, IRedisConnectionFactory connec #endregion #region Implements - public async ValueTask Get(string group, string key) + public async ValueTask Get(string group, string key) { try { if (group.IsWhiteSpaceOrNull() || key.IsWhiteSpaceOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } + var val = await _database.HashGetAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)key.ToLowerInvariant()); - return val.HasValue ? UTF8.GetString(val!).Deserialize() : default; + + return val.HasValue ? UTF8.GetString(val!).Deserialize() : default; } catch (Exception ex) { - _logger.LogError(ex, "GetRedisService-Exception: {Group} ; {Key}", group, key); + _logger.LogError(ex, "GetDeveloperTypeRedisService-Exception: {Group} - {Key}", group, key); throw; } } - public async ValueTask?> GetBulk(string group, params string[] keys) + public async ValueTask?> GetBulk(string group, params string[] keys) { try { if (group.IsWhiteSpaceOrNull() || keys.AllWhiteSpaceOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } - var rslts = new Dictionary(); + + var rslts = new Dictionary(); var semSlim = new SemaphoreSlim(1); + await WhenAll(keys.Select(async k => { - var val = await _database.HashGetAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)k.ToLowerInvariant()); - if (val.HasValue) + await semSlim.WaitAsync(); + + try { - await semSlim.WaitAsync(); - try - { - rslts.Add(k, UTF8.GetString(val!).Deserialize()); - } - finally + var val = await _database.HashGetAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)k.ToLowerInvariant()); + + if (val.HasValue) { - _ = semSlim.Release(); + rslts.Add(k, UTF8.GetString(val!).Deserialize()); } } + finally + { + _ = semSlim.Release(); + } })); + return rslts; } catch (Exception ex) { - _logger.LogError(ex, "GetBulkRedisService-Exception: {Group} ; {Keys}", group, string.Join(", ", keys)); + _logger.LogError(ex, "GetBulkDeveloperTypeRedisService-Exception: {Group} - {Keys}", group, string.Join(", ", keys)); throw; } } - public async ValueTask?> GetAll(string group) + public async ValueTask?> GetAll(string group) { try { if (group.IsWhiteSpaceOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } - var rslts = new Dictionary(); + + var rslts = new Dictionary(); var semSlim = new SemaphoreSlim(1); + await WhenAll((await _database.HashGetAllAsync(group.ToLowerInvariant())).Where(e => e.Name.HasValue && e.Value.HasValue).Select(async x => { var val = x.Value; + if (val.HasValue) { await semSlim.WaitAsync(); + try { - rslts.Add(x.Name.ToString(), UTF8.GetString(val!).Deserialize()); + rslts.Add(x.Name.ToString(), UTF8.GetString(val!).Deserialize()); } finally { @@ -109,45 +120,49 @@ await WhenAll((await _database.HashGetAllAsync(group.ToLowerInvariant())).Where( } } })); + return rslts; } catch (Exception ex) { - _logger.LogError(ex, "GetAllRedisService-Exception: {Group}", group); + _logger.LogError(ex, "GetAllDeveloperTypeRedisService-Exception: {Group}", group); throw; } } - public async ValueTask Set(string group, string key, JsonDto value) + public async ValueTask Set(string group, string key, DeveloperTypeRedis value) { var jsonVal = value.CamelSerialize(); + try { return group.IsWhiteSpaceOrNull() || key.IsWhiteSpaceOrNull() || value is null - ? throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST) - : await Delete(group, key) && await _database.HashSetAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)key.ToLowerInvariant(), jsonVal); + ? throw new BusinessException(BAD_REQUEST) + : await _database.HashSetAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)key.ToLowerInvariant(), jsonVal); } catch (Exception ex) { - _logger.LogError(ex, "SetRedisService-Exception: {Group} ; {Key} ; {Value}", group, key, jsonVal); + _logger.LogError(ex, "SetDeveloperTypeRedisService-Exception: {Group} - {Key} - {Value}", group, key, jsonVal); throw; } } - public async ValueTask SetBulk(string group, IDictionary fields) + public async ValueTask SetBulk(string group, IDictionary fields) { try { if (group.IsWhiteSpaceOrNull() || fields.IsEmptyOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } + await _database.HashSetAsync(group.ToLowerInvariant(), fields.Select(p => new HashEntry(p.Key.ToLowerInvariant(), p.Value.CamelSerialize())).ToArray()); + return true; } catch (Exception ex) { - _logger.LogError(ex, "SetBulkRedisService-Exception: {Group} ; {Fields}", group, fields.CamelSerialize()); + _logger.LogError(ex, "SetBulkDeveloperTypeRedisService-Exception: {Group} - {Fields}", group, fields.CamelSerialize()); throw; } } @@ -156,13 +171,11 @@ public async ValueTask Delete(string group, string key) { try { - return group.IsWhiteSpaceOrNull() || key.IsWhiteSpaceOrNull() - ? throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST) - : await _database.HashDeleteAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)key.ToLowerInvariant()); + return group.IsWhiteSpaceOrNull() || key.IsWhiteSpaceOrNull() ? throw new BusinessException(BAD_REQUEST) : await _database.HashDeleteAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)key.ToLowerInvariant()); } catch (Exception ex) { - _logger.LogError(ex, "DeleteRedisService-Exception: {Group} ; {Key}", group, key); + _logger.LogError(ex, "DeleteDeveloperTypeRedisService-Exception: {Group} - {Key}", group, key); throw; } } @@ -173,13 +186,16 @@ public async ValueTask DeleteBulk(string group, params string[] keys) { if (group.IsWhiteSpaceOrNull() || keys.AllWhiteSpaceOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } + var rslt = true; var semSlim = new SemaphoreSlim(1); + await WhenAll(keys.Where(k => k.IsNotWhiteSpaceAndNull()).Select(async k => { await semSlim.WaitAsync(); + try { rslt = rslt && await _database.HashDeleteAsync((RedisKey)group.ToLowerInvariant(), (RedisValue)k.ToLowerInvariant()); @@ -189,11 +205,12 @@ await WhenAll(keys.Where(k => k.IsNotWhiteSpaceAndNull()).Select(async k => _ = semSlim.Release(); } })); + return rslt; } catch (Exception ex) { - _logger.LogError(ex, "DeleteBulkRedisService-Exception: {Group} ; {Keys}", group, string.Join(", ", keys)); + _logger.LogError(ex, "DeleteBulkDeveloperTypeRedisService-Exception: {Group} - {Keys}", group, string.Join(", ", keys)); throw; } } @@ -204,36 +221,43 @@ public async ValueTask DeleteAll(string group) { if (group.IsWhiteSpaceOrNull()) { - throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST); + throw new BusinessException(BAD_REQUEST); } + var dic = await GetAll(group); + return dic!.IsEmptyOrNull() || await DeleteBulk(group, dic!.Select(p => p.Key).ToArray()); } catch (Exception ex) { - _logger.LogError(ex, "DeleteAllRedisService-Exception: {Group}", group); + _logger.LogError(ex, "DeleteAllDeveloperTypeRedisService-Exception: {Group}", group); throw; } } - public async ValueTask?>?> GetGroup(string groupPreffix) + public async ValueTask?>?> GetGroup(string groupPreffix) { try { var redisRslt = await GetGroupKeys(groupPreffix); + if (redisRslt is not null) { var keys = (RedisKey[])redisRslt!; - var rslts = new Dictionary?>(); + var rslts = new Dictionary?>(); + if (keys.IsNotEmptyAndNull()) { var semSlim = new SemaphoreSlim(1); + await WhenAll(keys.Select(async k => { var dic = await GetAll(k!); + if (dic!.IsNotEmptyAndNull()) { await semSlim.WaitAsync(); + try { rslts.Add(k.ToString().Split(":").Reverse().FirstOrDefault() ?? string.Empty, dic!); @@ -245,13 +269,15 @@ await WhenAll(keys.Select(async k => } })); } + return rslts; } + return default; } catch (Exception ex) { - _logger.LogError(ex, "GetGroupRedisService-Exception: {GroupPreffix}", groupPreffix); + _logger.LogError(ex, "GetGroupDeveloperTypeRedisService-Exception: {GroupPreffix}", groupPreffix); throw; } } @@ -261,16 +287,19 @@ public async ValueTask DeleteGroup(string groupPreffix) try { var redisRslt = await GetGroupKeys(groupPreffix); + if (redisRslt is not null) { var keys = (RedisKey[])redisRslt!; + return keys.IsEmptyOrNull() || await _database.KeyDeleteAsync(keys) > 0; } - return false; + + return default; } catch (Exception ex) { - _logger.LogError(ex, "DeleteGroupRedisService-Exception: {GroupPreffix}", groupPreffix); + _logger.LogError(ex, "DeleteGroupDeveloperTypeRedisService-Exception: {GroupPreffix}", groupPreffix); throw; } } @@ -281,13 +310,11 @@ private async ValueTask GetGroupKeys(string groupPreffix) { try { - return groupPreffix.IsWhiteSpaceOrNull() - ? throw new BusinessException(code: ExceptionCode.BAD_REQUEST, message: BAD_REQUEST) - : await _database.ExecuteAsync("KEYS", $"{groupPreffix}*"); + return groupPreffix.IsWhiteSpaceOrNull() ? throw new BusinessException(BAD_REQUEST) : await _database.ExecuteAsync(RedisKeyCommand, $"{groupPreffix}*"); } catch (Exception ex) { - _logger.LogError(ex, "GetGroupKeysRedisService-Exception: {GroupPreffix}", groupPreffix); + _logger.LogError(ex, "GetGroupKeysDeveloperTypeRedisService-Exception: {GroupPreffix}", groupPreffix); throw; } } diff --git a/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj b/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj index 7707930..bf7d899 100644 --- a/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj +++ b/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj @@ -1,19 +1,19 @@ - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - - + + + - - - - - + + + + + diff --git a/src/YANLib.Application.Redis/YANLibApplicationRedisModule.cs b/src/YANLib.Application.Redis/YANLibApplicationRedisModule.cs index 5ae6132..555a28c 100644 --- a/src/YANLib.Application.Redis/YANLibApplicationRedisModule.cs +++ b/src/YANLib.Application.Redis/YANLibApplicationRedisModule.cs @@ -1,4 +1,10 @@ -using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Modularity; +using YANLib.Application.Redis.ConnectionFactory; +using YANLib.Application.Redis.Services; +using YANLib.Application.Redis.Services.Implements; +using YANLib.DTOs; namespace YANLib.Application.Redis; @@ -8,4 +14,13 @@ namespace YANLib.Application.Redis; )] public class YANLibApplicationRedisModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + Configure(o => o.RedisConnectionString = configuration["Redis:Configuration"]); + _ = context.Services.AddSingleton, DeveloperTypeRedisService>(); + } + + public override void OnApplicationShutdown(ApplicationShutdownContext context) => context.ServiceProvider.GetRequiredService().Connection().CloseAsync(); } diff --git a/src/YANLib.Application/EsServices/DeveloperEsService.cs b/src/YANLib.Application/EsServices/DeveloperEsService.cs new file mode 100644 index 0000000..a433e62 --- /dev/null +++ b/src/YANLib.Application/EsServices/DeveloperEsService.cs @@ -0,0 +1,120 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Nest; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using YANLib.EsIndexs; +using YANLib.Utilities; +using static System.Threading.Tasks.Task; +using static YANLib.YANLibConsts; + +namespace YANLib.EsServices; + +public class DeveloperEsService : YANLibAppService, IDeveloperEsService +{ + #region Fields + private readonly ILogger _logger; + private readonly IElasticClient _elasticClient; + private readonly IConfiguration _configuration; + #endregion + + #region Constructors + public DeveloperEsService(ILogger logger, IElasticClient elasticClient, IConfiguration configuration) + { + _logger = logger; + _elasticClient = elasticClient; + _configuration = configuration; + } + #endregion + + #region Implements + public async ValueTask Get(string id) + { + try + { + return (await _elasticClient.GetAsync(id)).Source ?? default; + } + catch (Exception ex) + { + _logger.LogError(ex, "GetDeveloperEsService-Exception: {Id}", id); + throw; + } + } + + public async ValueTask Set(DeveloperIndex data) + { + data.Id = data.IdCard; + + try + { + return await _elasticClient.IndexDocumentAsync(data) is not null; + } + catch (Exception ex) + { + _logger.LogError(ex, "SetDeveloperEsService-Exception: {Data}", data.CamelSerialize()); + throw; + } + } + + public async ValueTask SetBulk(List datas) + { + try + { + var index = _configuration.GetSection(IdxSample)?.Value; + + if (index.IsWhiteSpaceOrNull()) + { + return false; + } + + var reqs = new BulkDescriptor(); + + foreach (var data in datas.OrderBy(x => x.CreatedDate)) + { + data.Id = data.IdCard; + reqs.Index(x => x.Document(data).Index(index)); + } + + return await _elasticClient.BulkAsync(reqs) is not null; + } + catch (Exception ex) + { + _logger.LogError(ex, "SetBulkDeveloperEsService-Exception: {Datas}", datas.CamelSerialize()); + throw; + } + } + + public async ValueTask DeleteAll() + { + try + { + _ = _elasticClient.DeleteSampleIndex(); + + return await FromResult(true); + } + catch (Exception ex) + { + _logger.LogError(ex, "DeleteAllDeveloperEsService-Exception"); + throw; + } + } + + public async ValueTask> GetByDeveloperId(Guid developerId) => (await _elasticClient.SearchAsync(s => s + .Query(q => q + .Bool(b => b + .Must(d => d + .Match(m => m + .Field(c => c.DeveloperId) + .Query(developerId.ToString()))))))).Documents; + + public async ValueTask> GetByPhone(string phone) => (await _elasticClient.SearchAsync(s => s + .Query(q => q + .Bool(b => b + .Must(d => d + .Match(m => m + .Field(c => c.Phone) + .Query(phone))))))).Documents; + #endregion +} diff --git a/src/YANLib.Application/Mappers/CertificateMapper.cs b/src/YANLib.Application/Mappers/CertificateMapper.cs new file mode 100644 index 0000000..c297011 --- /dev/null +++ b/src/YANLib.Application/Mappers/CertificateMapper.cs @@ -0,0 +1,21 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; +using YANLib.Models; +using YANLib.Requests; +using YANLib.Responses; + +namespace YANLib.Mappers; + +public sealed class CertificateMapper : Profile +{ + public CertificateMapper() + { + _ = CreateMap() + .Ignore(d => d.Id) + .Ignore(d => d.DeveloperId) + .Ignore(d => d.CreatedDate) + .Ignore(d => d.ModifiedDate); + + _ = CreateMap().ReverseMap(); + } +} diff --git a/src/YANLib.Application/Mappers/DeveloperMapper.cs b/src/YANLib.Application/Mappers/DeveloperMapper.cs new file mode 100644 index 0000000..908d7c8 --- /dev/null +++ b/src/YANLib.Application/Mappers/DeveloperMapper.cs @@ -0,0 +1,39 @@ +using AutoMapper; +using System; +using Volo.Abp.AutoMapper; +using YANLib.EsIndexs; +using YANLib.Models; +using YANLib.Requests; +using YANLib.Responses; + +namespace YANLib.Mappers; + +public sealed class DeveloperMapper : Profile +{ + public DeveloperMapper() + { + _ = CreateMap() + .ForMember(d => d.Id, o => o.MapFrom(s => new Guid(s.DeveloperId))); + + _ = CreateMap() + .Ignore(d => d.IsActive) + .Ignore(d => d.Version) + .Ignore(d => d.CreatedDate) + .Ignore(d => d.ModifiedDate) + .Ignore(d => d.DeveloperType); + + _ = CreateMap() + .Ignore(d => d.Certificates); + + _ = CreateMap() + .ForMember(d => d.DeveloperId, o => o.MapFrom(s => s.Id.ToString())); + + _ = CreateMap() + .ForMember(d => d.Id, o => o.MapFrom(s => new Guid(s.DeveloperId))) + .ForMember(d => d.DeveloperTypeCode, o => o.MapFrom(s => s.DeveloperType.Code)) + .Ignore(d => d.DeveloperType); + + _ = CreateMap() + .ForMember(d => d.DeveloperId, o => o.MapFrom(s => s.Id.ToString())); + } +} diff --git a/src/YANLib.Application/Mappers/DeveloperTypeMapper.cs b/src/YANLib.Application/Mappers/DeveloperTypeMapper.cs new file mode 100644 index 0000000..a45fc31 --- /dev/null +++ b/src/YANLib.Application/Mappers/DeveloperTypeMapper.cs @@ -0,0 +1,33 @@ +using AutoMapper; +using System.Collections.Generic; +using Volo.Abp.AutoMapper; +using YANLib.DTOs; +using YANLib.Models; +using YANLib.Requests; +using YANLib.Responses; + +namespace YANLib.Mappers; + +public sealed class DeveloperTypeMapper : Profile +{ + public DeveloperTypeMapper() + { + _ = CreateMap() + .Ignore(d => d.CreatedDate) + .Ignore(d => d.ModifiedDate); + + _ = CreateMap().ReverseMap(); + + _ = CreateMap, DeveloperTypeResponse>() + .ForMember(d => d.Code, o => o.MapFrom(s => s.Key.ToInt())) + .ForMember(d => d.Name, o => o.MapFrom(s => s.Value.Name)) + .ForMember(d => d.IsActive, o => o.MapFrom(s => s.Value.IsActive)) + .ForMember(d => d.CreatedDate, o => o.MapFrom(s => s.Value.CreatedDate)) + .ForMember(d => d.ModifiedDate, o => o.MapFrom(s => s.Value.ModifiedDate)); + + _ = CreateMap() + .Ignore(d => d.Code); + + _ = CreateMap(); + } +} diff --git a/src/YANLib.Application/Services/DeveloperService.cs b/src/YANLib.Application/Services/DeveloperService.cs new file mode 100644 index 0000000..e6cce8a --- /dev/null +++ b/src/YANLib.Application/Services/DeveloperService.cs @@ -0,0 +1,190 @@ +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.EsIndexs; +using YANLib.EsServices; +using YANLib.Localization; +using YANLib.Models; +using YANLib.Repositories; +using YANLib.Requests; +using YANLib.Responses; +using static System.Guid; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Services; + +public class DeveloperService : YANLibAppService, IDeveloperService +{ + #region Fields + private readonly ILogger _logger; + private readonly IStringLocalizer _localizer; + private readonly IDeveloperRepository _repository; + private readonly IDeveloperEsService _esService; + private readonly ICertificateRepository _certificateRepository; + #endregion + + #region Constructors + public DeveloperService(ILogger logger, IStringLocalizer localizer, IDeveloperRepository repository, IDeveloperEsService esService, ICertificateRepository certificateRepository) + { + _logger = logger; + _localizer = localizer; + _repository = repository; + _esService = esService; + _certificateRepository = certificateRepository; + } + #endregion + + #region Implements + public async ValueTask Get(Guid id) + { + try + { + return ObjectMapper.Map((await _esService.GetByDeveloperId(id)).OrderByDescending(x => x.Version).FirstOrDefault()); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetDeveloperService-Exception: {Id}", id); + throw; + } + } + + public async ValueTask GetByIdCard(string idCard) + { + try + { + return ObjectMapper.Map(await _esService.Get(idCard)); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetByIdCardDeveloperService-Exception: {IdCard}", idCard); + throw; + } + } + + public async ValueTask> GetByPhone(string phone) + { + try + { + return ObjectMapper.Map, IEnumerable>(await _esService.GetByPhone(phone)).ToList(); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetByPhoneDeveloperService-Exception: {Phone}", phone); + throw; + } + } + + public async ValueTask Insert(DeveloperRequest request) + { + try + { + if (await _esService.Get(request.IdCard) is not null) + { + throw new BusinessException(EXIST_ID_CARD).WithData("IdCard", request.IdCard); + } + + var id = NewGuid(); + var ent = ObjectMapper.Map(request); + var certEnts = ObjectMapper.Map, List>(request.Certificates); + + ent.Id = id; + certEnts?.ForEach(x => x.DeveloperId = id); + + var rslt = ObjectMapper.Map(await _repository.Insert(ent)); + + if (request.Certificates.IsNotEmptyAndNull()) + { + rslt.Certificates = new List(ObjectMapper.Map, IEnumerable>(await _certificateRepository.Inserts(certEnts))); + } + + return await _esService.Set(ObjectMapper.Map(rslt)) ? rslt : throw new BusinessException(); + } + catch (Exception ex) + { + _logger.LogError(ex, "InsertDeveloperService-Exception: {Request}", request.CamelSerialize()); + throw; + } + } + + public async ValueTask Adjust(string idCard, DeveloperFreeRequest request) + { + try + { + var mdl = await _esService.Get(idCard) ?? throw new BusinessException(NOT_FOUND_DEV).WithData("IdCard", idCard); + var ent = ObjectMapper.Map(mdl); + var id = NewGuid(); + var certEnts = ObjectMapper.Map, List>(request.Certificates); + + ent.Id = id; + ent.Name = request.Name ?? ent.Name; + ent.Phone = request.Phone ?? ent.Phone; + ent.IdCard = idCard; + ent.DeveloperTypeCode = request.DeveloperTypeCode ?? ent.DeveloperTypeCode; + certEnts?.ForEach(x => x.DeveloperId = id); + + var rslt = ObjectMapper.Map(await _repository.Adjust(ent)); + + if (request.Certificates.IsNotEmptyAndNull()) + { + if (mdl.Certificates.IsNotEmptyAndNull()) + { + await _certificateRepository.Updates(ObjectMapper.Map, IEnumerable>(mdl.Certificates.Select(x => + { + x.DeveloperId = null; + return x; + }))); + } + + rslt.Certificates = new List(ObjectMapper.Map, IEnumerable>(await _certificateRepository.Inserts(certEnts))); + } + + return await _esService.Set(ObjectMapper.Map(rslt)) ? rslt : throw new BusinessException(); + } + catch (Exception ex) + { + _logger.LogError(ex, "AdjustDeveloperService-Exception: {Request}", request.CamelSerialize()); + throw; + } + } + + public async ValueTask SyncDbToEs() + { + try + { + var rslt = await _esService.DeleteAll(); + var mdls = await _repository.GetAll(); + var datas = new List(); + var semSlim = new SemaphoreSlim(1); + + await Task.WhenAll(mdls.Select(async x => + { + var dto = ObjectMapper.Map(x); + + await semSlim.WaitAsync(); + + try + { + dto.Certificates = new List(ObjectMapper.Map, IEnumerable>(await _certificateRepository.GetByDeveloperId(x.Id))); + datas.Add(dto); + } + finally + { + _ = semSlim.Release(); + } + })); + + return mdls.IsNotEmptyAndNull() ? rslt && await _esService.SetBulk(datas) : rslt; + } + catch (Exception ex) + { + _logger.LogError(ex, "SyncDbToEsDeveloperService-Exception"); + throw; + } + } + #endregion +} diff --git a/src/YANLib.Application/Services/DeveloperTypeService.cs b/src/YANLib.Application/Services/DeveloperTypeService.cs new file mode 100644 index 0000000..1866600 --- /dev/null +++ b/src/YANLib.Application/Services/DeveloperTypeService.cs @@ -0,0 +1,124 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using YANLib.Application.Redis.Services; +using YANLib.DTOs; +using YANLib.Models; +using YANLib.Repositories; +using YANLib.Requests; +using YANLib.Responses; +using static YANLib.Common.RedisConstant; + +namespace YANLib.Services; + +public class DeveloperTypeService : YANLibAppService, IDeveloperTypeService +{ + #region Fields + private readonly ILogger _logger; + private readonly IDeveloperTypeRepository _repository; + private readonly IRedisService _redisService; + #endregion + + #region Constructors + public DeveloperTypeService(ILogger logger, IDeveloperTypeRepository repository, IRedisService redisService) + { + _logger = logger; + _repository = repository; + _redisService = redisService; + } + #endregion + + #region Implements + public async ValueTask> GetAll() + { + try + { + return (await _redisService.GetAll(DEV_TYPE_GRP)).Select(ObjectMapper.Map, DeveloperTypeResponse>).ToList(); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetAllDeveloperTypeService-Exception"); + throw; + } + } + + public async ValueTask Get(int code) + { + try + { + var rslt = ObjectMapper.Map(await _redisService.Get(DEV_TYPE_GRP, code.ToString())); + + if (rslt is not null) + { + rslt.Code = code; + } + + return rslt; + } + catch (Exception ex) + { + _logger.LogError(ex, "GetDeveloperTypeService-Exception: {Code}", code); + throw; + } + } + + public async ValueTask Insert(DeveloperTypeRequest request) + { + try + { + var mdl = await _repository.Insert(ObjectMapper.Map(request)); + + if (mdl is not null) + { + await _redisService.Set(DEV_TYPE_GRP, mdl.Code.ToString(), ObjectMapper.Map(mdl)); + } + + return ObjectMapper.Map(mdl); + } + catch (Exception ex) + { + _logger.LogError(ex, "InsertDeveloperTypeService-Exception: {Request}", request.CamelSerialize()); + throw; + } + } + + public async ValueTask Update(DeveloperTypeRequest request) + { + try + { + var mdl = await _repository.Update(ObjectMapper.Map(request)); + + if (mdl is not null) + { + await _redisService.Set(DEV_TYPE_GRP, mdl.Code.ToString(), ObjectMapper.Map(mdl)); + } + + return ObjectMapper.Map(mdl); + } + catch (Exception ex) + { + _logger.LogError(ex, "UpdateDeveloperTypeService-Exception: {Request}", request.CamelSerialize()); + throw; + } + } + + public async ValueTask SyncDbToRedis() + { + try + { + var task = _redisService.DeleteAll(DEV_TYPE_GRP); + var mdls = await _repository.GetAll(); + var rslt = await task; + + return mdls.IsNotEmptyAndNull() ? rslt && await _redisService.SetBulk(DEV_TYPE_GRP, mdls.ToDictionary(x => x.Code.ToString(), ObjectMapper.Map)) : rslt; + } + catch (Exception ex) + { + _logger.LogError(ex, "SyncDbToRedisDeveloperTypeService-Exception"); + throw; + } + } + #endregion +} diff --git a/src/YANLib.Application/Services/YANJsonService.cs b/src/YANLib.Application/Services/YANJsonService.cs index 0d0359b..71eafca 100644 --- a/src/YANLib.Application/Services/YANJsonService.cs +++ b/src/YANLib.Application/Services/YANJsonService.cs @@ -2,7 +2,7 @@ using System.Text.Json; using System.Threading.Tasks; using Volo.Abp.Json; -using YANLib.Dtos; +using YANLib.Requests; using static Newtonsoft.Json.JsonConvert; using static System.Guid; using static System.Text.Json.JsonSerializer; @@ -12,107 +12,152 @@ namespace YANLib.Services; public class YANJsonService : YANLibAppService, IYANJsonService { + #region Fields private readonly IJsonSerializer _jsonSerializer; + #endregion + #region Constructors public YANJsonService(IJsonSerializer jsonSerializer) => _jsonSerializer = jsonSerializer; + #endregion + #region Implements public async ValueTask YanVsStandards(uint quantity, bool hideSystem) { - var json = new JsonDto + var json = new SampleRequest { Id = NewGuid() }.Serialize(); - var jsonCamel = new JsonDto + + var jsonCamel = new SampleRequest { Id = NewGuid() }.CamelSerialize(); + var newtonsoftTask = Run(() => { var sw = new Stopwatch(); + sw.Start(); + var first = string.Empty; var last = string.Empty; + for (var i = 0; i < quantity; i++) { - var dto = DeserializeObject(i is 0 ? json : jsonCamel); + var dto = DeserializeObject(i is 0 ? json : jsonCamel); + first = i is 0 ? dto.Id.ToString().Replace("-", string.Empty) : first; last = i == quantity - 1 ? dto.Id.ToString().Replace("-", string.Empty) : last; } + sw.Stop(); + return $"[{first} - {last}] {sw.Elapsed.TotalMilliseconds} ms"; }); + var voloTask = Run(() => { var sw = new Stopwatch(); + sw.Start(); + var first = string.Empty; var last = string.Empty; + for (var i = 0; i < quantity; i++) { - var dto = (JsonDto)_jsonSerializer.Deserialize(typeof(JsonDto), i is 0 ? json : jsonCamel); + var dto = (SampleRequest)_jsonSerializer.Deserialize(typeof(SampleRequest), i is 0 ? json : jsonCamel); + first = i is 0 ? dto.Id.ToString().Replace("-", string.Empty) : first; last = i == quantity - 1 ? dto.Id.ToString().Replace("-", string.Empty) : last; } + sw.Stop(); + return $"[{first} - {last}] {sw.Elapsed.TotalMilliseconds} ms"; }); + var yanTask = Run(() => { var sw = new Stopwatch(); + sw.Start(); + var first = string.Empty; var last = string.Empty; + for (var i = 0; i < quantity; i++) { - var dto = (i is 0 ? json : jsonCamel).Deserialize(); + var dto = (i is 0 ? json : jsonCamel).Deserialize(); + first = i is 0 ? dto.Id.ToString().Replace("-", string.Empty) : first; last = i == quantity - 1 ? dto.Id.ToString().Replace("-", string.Empty) : last; } + sw.Stop(); + return $"[{first} - {last}] {sw.Elapsed.TotalMilliseconds} ms"; }); + if (!hideSystem) { var textTask = Run(() => { var sw = new Stopwatch(); + sw.Start(); + var first = string.Empty; var last = string.Empty; + for (var i = 0; i < quantity; i++) { - var dto = Deserialize(i is 0 ? json : jsonCamel); + var dto = Deserialize(i is 0 ? json : jsonCamel); + first = i is 0 ? dto.Id.ToString().Replace("-", string.Empty) : first; last = i == quantity - 1 ? dto.Id.ToString().Replace("-", string.Empty) : last; } + sw.Stop(); + return $"[{first} - {last}] {sw.Elapsed.TotalMilliseconds} ms"; }); + var textOptTask = Run(() => { var sw = new Stopwatch(); + sw.Start(); + var first = string.Empty; var last = string.Empty; + for (var i = 0; i < quantity; i++) { - var dto = Deserialize(i is 0 ? json : jsonCamel, new JsonSerializerOptions + var dto = Deserialize(i is 0 ? json : jsonCamel, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + first = i is 0 ? dto.Id.ToString().Replace("-", string.Empty) : first; last = i == quantity - 1 ? dto.Id.ToString().Replace("-", string.Empty) : last; } + sw.Stop(); + return $"[{first} - {last}] {sw.Elapsed.TotalMilliseconds} ms"; }); + _ = await WhenAll(newtonsoftTask, voloTask, textTask, textOptTask, yanTask); + return $"Newtonsoft 13.0.3:\t{newtonsoftTask.Result}\nVolo.Abp 6.0.3:\t\t{voloTask.Result}\nSystem.Text:\t\t{textTask.Result}\nSystem.Text (option):\t{textOptTask.Result}\nYANLib:\t\t\t{yanTask.Result}"; } else { _ = await WhenAll(newtonsoftTask, voloTask, yanTask); + return $"Newtonsoft 13.0.3:\t{newtonsoftTask.Result}\nVolo.Abp 6.0.3:\t\t{voloTask.Result}\nYANLib:\t\t\t{yanTask.Result}"; } } + #endregion } diff --git a/src/YANLib.Application/Utilities/ElasticsearchUtil.cs b/src/YANLib.Application/Utilities/ElasticsearchUtil.cs new file mode 100644 index 0000000..35e3765 --- /dev/null +++ b/src/YANLib.Application/Utilities/ElasticsearchUtil.cs @@ -0,0 +1,58 @@ +using Elasticsearch.Net; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nest; +using System; +using System.Linq; +using YANLib.EsIndexs; +using static Elasticsearch.Net.CertificateValidations; +using static System.TimeSpan; +using static YANLib.YANLibConsts; + +namespace YANLib.Utilities; + +public static class ElasticsearchUtil +{ + #region Fields + private static string _indexSample; + #endregion + + #region Extensions + public static void AddElasticsearch(this IServiceCollection services, IConfiguration configuration) + { + var urlTag = "Elasticsearch:Url"; + var usernameTag = "Elasticsearch:Username"; + var pwdTag = "Elasticsearch:Password"; + var settings = new ConnectionSettings(configuration.GetSection(urlTag).GetChildren().Any() + ? new StaticConnectionPool((configuration.GetSection(urlTag).GetChildren().Any() + ? configuration.GetSection(urlTag).GetChildren().ToArray() + : (new IConfigurationSection[] { configuration.GetSection(urlTag) })).Select(s => new Uri(s.Value)).ToArray()) + : new SingleNodeConnectionPool(new Uri(configuration.GetSection(urlTag).Value))).DefaultIndex(configuration.GetSection(IdxSample)?.Value).EnableDebugMode().PrettyJson().RequestTimeout(FromMinutes(2)); + + if (configuration.GetSection(usernameTag).Value.IsNotWhiteSpaceAndNull()) + { + settings.ServerCertificateValidationCallback((o, certificate, chain, errors) => true); + settings.ServerCertificateValidationCallback(AllowAll); + settings.BasicAuthentication(configuration.GetSection(usernameTag).Value, configuration.GetSection(pwdTag).Value); + } + + _indexSample = configuration.GetSection(IdxSample)?.Value; + _ = settings.DefaultMappingFor(m => m.IndexName(_indexSample)); + + var client = new ElasticClient(settings); + + if (!client.Indices.Exists(configuration.GetSection(IdxSample)?.Value).Exists) + { + _ = client.Indices.Create(configuration.GetSection(IdxSample).Value, c => c + .Map(t => t + .AutoMap().Properties(p => p + .Text(d => d + .Name(x => x.Id))))); + } + + _ = services.AddSingleton(client); + } + + public static DeleteIndexResponse DeleteSampleIndex(this IElasticClient client) => _indexSample.IsNotWhiteSpaceAndNull() ? client.Indices.Delete(_indexSample) : default; + #endregion +} diff --git a/src/YANLib.Application/Validations/CertificateValidation.cs b/src/YANLib.Application/Validations/CertificateValidation.cs new file mode 100644 index 0000000..491f52d --- /dev/null +++ b/src/YANLib.Application/Validations/CertificateValidation.cs @@ -0,0 +1,35 @@ +using FluentValidation; +using System.Collections.Generic; +using System.Linq; +using YANLib.Requests; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Validations; + +public sealed class CertificateRipValidator : AbstractValidator +{ + public CertificateRipValidator() + { + _ = RuleFor(x => x.Name).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + _ = RuleFor(x => x.GPA).GreaterThan(0).WithErrorCode(BAD_REQUEST_GPA).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_GPA); + } +} + +public sealed class CertificateRipValidators : AbstractValidator> +{ + #region Constructors + public CertificateRipValidators() + { + _ = RuleFor(x => x).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleForEach(s => s).SetValidator(new CertificateRipValidator()); + _ = RuleFor(x => x).Must(IsNotEmptyAndNull).WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleFor(x => x).Must(NameIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + } + #endregion + + #region Methods + private bool IsNotEmptyAndNull(List requests) => requests.IsNotEmptyAndNull(); + + private bool NameIsNotWhiteSpace(List requests) => requests.Select(x => x.Name).AllNotWhiteSpaceAndNull(); + #endregion +} diff --git a/src/YANLib.Application/Validations/DeveloperTypeValidation.cs b/src/YANLib.Application/Validations/DeveloperTypeValidation.cs new file mode 100644 index 0000000..0ffb755 --- /dev/null +++ b/src/YANLib.Application/Validations/DeveloperTypeValidation.cs @@ -0,0 +1,35 @@ +using FluentValidation; +using System.Collections.Generic; +using System.Linq; +using YANLib.Requests; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Validations; + +public sealed class DeveloperTypeValidator : AbstractValidator +{ + public DeveloperTypeValidator() + { + _ = RuleFor(x => x.Code).NotNull().NotEmpty().GreaterThanOrEqualTo(0).WithErrorCode(BAD_REQUEST_ID).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_ID); + _ = RuleFor(x => x.Name).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + } +} + +public sealed class DeveloperTypeValidators : AbstractValidator> +{ + #region Constructors + public DeveloperTypeValidators() + { + _ = RuleFor(x => x).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleForEach(s => s).SetValidator(new DeveloperTypeValidator()); + _ = RuleFor(x => x).Must(IsNotEmptyAndNull).WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleFor(x => x).Must(NameIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + } + #endregion + + #region Methods + private bool IsNotEmptyAndNull(List requests) => requests.IsNotEmptyAndNull(); + + private bool NameIsNotWhiteSpace(List requests) => requests.Select(x => x.Name).AllNotWhiteSpaceAndNull(); + #endregion +} diff --git a/src/YANLib.Application/Validations/DeveloperValidation.cs b/src/YANLib.Application/Validations/DeveloperValidation.cs new file mode 100644 index 0000000..3e8590f --- /dev/null +++ b/src/YANLib.Application/Validations/DeveloperValidation.cs @@ -0,0 +1,39 @@ +using FluentValidation; +using System.Collections.Generic; +using System.Linq; +using YANLib.Requests; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Validations; + +public sealed class DeveloperValidator : AbstractValidator +{ + public DeveloperValidator() + { + _ = RuleFor(x => x.Name).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + _ = RuleFor(x => x.IdCard).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_ID_CARD).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_ID_CARD); + _ = RuleFor(x => x.DeveloperTypeCode).NotNull().NotEmpty().GreaterThanOrEqualTo(0).WithErrorCode(BAD_REQUEST_ID).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_ID); + } +} + +public sealed class DeveloperValidators : AbstractValidator> +{ + #region Constructors + public DeveloperValidators() + { + _ = RuleFor(x => x).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleForEach(s => s).SetValidator(new DeveloperValidator()); + _ = RuleFor(x => x).Must(IsNotEmptyAndNull).WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleFor(x => x).Must(NameIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_NAME).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_NAME); + _ = RuleFor(x => x).Must(IdCardIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_ID_CARD).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_ID_CARD); + } + #endregion + + #region Methods + private bool IsNotEmptyAndNull(List requests) => requests.IsNotEmptyAndNull(); + + private bool NameIsNotWhiteSpace(List requests) => requests.Select(x => x.Name).AllNotWhiteSpaceAndNull(); + + private bool IdCardIsNotWhiteSpace(List requests) => requests.Select(x => x.IdCard).AllNotWhiteSpaceAndNull(); + #endregion +} diff --git a/src/YANLib.Application/Validations/JsonValidation.cs b/src/YANLib.Application/Validations/JsonValidation.cs deleted file mode 100644 index e6d0029..0000000 --- a/src/YANLib.Application/Validations/JsonValidation.cs +++ /dev/null @@ -1,21 +0,0 @@ -using FluentValidation; -using System.Collections.Generic; -using YANLib.Dtos; -using YANLib.Exceptions; -using static YANLib.Exceptions.ExceptionMessage; - -namespace YANLib.Validations; - -public sealed class JsonValidator : AbstractValidator -{ - public JsonValidator() => RuleFor(d => d.Id).NotNull().NotEmpty().WithErrorCode(ExceptionCode.BAD_REQUEST_ID).WithMessage(BAD_REQUEST_ID); -} - -public sealed class JsonValidators : AbstractValidator> -{ - public JsonValidators() - { - _ = RuleFor(s => s).NotNull().NotEmpty().WithErrorCode(ExceptionCode.BAD_REQUEST_ID).WithMessage(BAD_REQUEST_ID); - _ = RuleForEach(s => s).SetValidator(new JsonValidator()); - } -} diff --git a/src/YANLib.Application/Validations/SampleValidation.cs b/src/YANLib.Application/Validations/SampleValidation.cs new file mode 100644 index 0000000..d3283c9 --- /dev/null +++ b/src/YANLib.Application/Validations/SampleValidation.cs @@ -0,0 +1,27 @@ +using FluentValidation; +using System.Collections.Generic; +using YANLib.Requests; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Validations; + +public sealed class SampleValidator : AbstractValidator +{ + public SampleValidator() => RuleFor(x => x.Id).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_ID).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST_ID); +} + +public sealed class SampleValidators : AbstractValidator> +{ + #region Constructors + public SampleValidators() + { + _ = RuleFor(x => x).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleForEach(s => s).SetValidator(new SampleValidator()); + _ = RuleFor(x => x).Must(IsNotEmptyAndNull).WithErrorCode(BAD_REQUEST).WithErrorCode(YANLibDomainErrorMessages.BAD_REQUEST); + } + #endregion + + #region Methods + private bool IsNotEmptyAndNull(List requests) => requests.IsNotEmptyAndNull(); + #endregion +} diff --git a/src/YANLib.Application/YANLib.Application.csproj b/src/YANLib.Application/YANLib.Application.csproj index 13493b3..20bd387 100644 --- a/src/YANLib.Application/YANLib.Application.csproj +++ b/src/YANLib.Application/YANLib.Application.csproj @@ -1,25 +1,27 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - - - - + + + + + + - - - - - - - + + + + + + + + + diff --git a/src/YANLib.Application/YANLibApplicationModule.cs b/src/YANLib.Application/YANLibApplicationModule.cs index c95af2c..07ee0d5 100644 --- a/src/YANLib.Application/YANLibApplicationModule.cs +++ b/src/YANLib.Application/YANLibApplicationModule.cs @@ -2,12 +2,14 @@ using Volo.Abp.AutoMapper; using Volo.Abp.FluentValidation; using Volo.Abp.Modularity; +using YANLib.Application.Redis; namespace YANLib; [DependsOn( typeof(YANLibDomainModule), typeof(YANLibApplicationContractsModule), + typeof(YANLibApplicationRedisModule), typeof(AbpDddApplicationModule), typeof(AbpAutoMapperModule), typeof(AbpFluentValidationModule) diff --git a/src/YANLib.Domain.Shared/Localization/YANLib/vi.json b/src/YANLib.Domain.Shared/Localization/YANLib/vi.json index c115a35..a10ce6b 100644 --- a/src/YANLib.Domain.Shared/Localization/YANLib/vi.json +++ b/src/YANLib.Domain.Shared/Localization/YANLib/vi.json @@ -1,8 +1,17 @@ { "culture": "vi", "texts": { - "Menu:Home": "Trang chủ", - "Welcome": "Chào mừng bạn", - "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." + "YANLib:400": "Dữ liệu truyền vào không hợp lệ!", + "YANLib:410": "Tên truyền vào không hợp lệ!", + "YANLib:420": "Mã định danh truyền vào không hợp lệ!", + "YANLib:430": "Mã truyền vào không hợp lệ!", + "YANLib:440": "Điểm truyền vào không hợp lệ!", + "YANLib:403": "Lỗi quy tắc!", + "YANLib:413": "Mã {Id} đã tồn tại!", + "YANLib:423": "Mã định danh {IdCard} đã tồn tại!", + "YANLib:404": "Không tìm thấy dữ liệu!", + "YANLib:414": "Không tìm thấy hồ sơ lập trình viên có mã định danh {IdCard}!", + "YANLib:424": "Không tìm thấy định nghĩa loại lập trình viên có mã {Code}!", + "YANLib:500": "Lỗi trong quá trình xử lý!" } } diff --git a/src/YANLib.Domain.Shared/YANLib.Domain.Shared.csproj b/src/YANLib.Domain.Shared/YANLib.Domain.Shared.csproj index a7b624f..af322c1 100644 --- a/src/YANLib.Domain.Shared/YANLib.Domain.Shared.csproj +++ b/src/YANLib.Domain.Shared/YANLib.Domain.Shared.csproj @@ -1,20 +1,21 @@ - + - - net6.0 - YANLib - true - + + net6.0 + YANLib + true + - - - - + + + + - - - + + + + diff --git a/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs b/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs index b07e79d..dc2f58e 100644 --- a/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs +++ b/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs @@ -2,5 +2,19 @@ public static class YANLibDomainErrorCodes { - /* You can add your business exception error codes here, as constants */ + public const string BAD_REQUEST = "YANLib:400"; + public const string BAD_REQUEST_NAME = "YANLib:410"; + public const string BAD_REQUEST_ID_CARD = "YANLib:420"; + public const string BAD_REQUEST_ID = "YANLib:430"; + public const string BAD_REQUEST_GPA = "YANLib:440"; + + public const string BUSINESS_ERROR = "YANLib:403"; + public const string EXIST_ID = "YANLib:413"; + public const string EXIST_ID_CARD = "YANLib:423"; + + public const string NOT_FOUND = "YANLib:404"; + public const string NOT_FOUND_DEV = "YANLib:414"; + public const string NOT_FOUND_DEV_TYPE = "YANLib:424"; + + public const string INTERNAL_SERVER_ERROR = "YANLib:500"; } diff --git a/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs b/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs new file mode 100644 index 0000000..55158d4 --- /dev/null +++ b/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs @@ -0,0 +1,20 @@ +namespace YANLib; + +public static class YANLibDomainErrorMessages +{ + public const string BAD_REQUEST = "Dữ liệu truyền vào không hợp lệ!"; + public const string BAD_REQUEST_NAME = "Tên truyền vào không hợp lệ!"; + public const string BAD_REQUEST_ID_CARD = "Mã định danh truyền vào không hợp lệ!"; + public const string BAD_REQUEST_ID = "Mã truyền vào không hợp lệ!"; + public const string BAD_REQUEST_GPA = "Điểm truyền vào không hợp lệ!"; + + public const string BUSINESS_ERROR = "Lỗi quy tắc!"; + public const string EXIST_ID = "Mã đã tồn tại!"; + public const string EXIST_ID_CARD = "Mã định danh đã tồn tại!"; + + public const string NOT_FOUND = "Không tìm thấy dữ liệu!"; + public const string NOT_FOUND_DEV = "Không tìm thấy hồ sơ lập trình viên!"; + public const string NOT_FOUND_DEV_TYPE = "Không tìm thấy định nghĩa loại lập trình viên!"; + + public const string INTERNAL_SERVER_ERROR = "Lỗi trong quá trình xử lý!"; +} diff --git a/src/YANLib.Domain.Shared/YANLibDomainSharedModule.cs b/src/YANLib.Domain.Shared/YANLibDomainSharedModule.cs index 2e20735..b936a6e 100644 --- a/src/YANLib.Domain.Shared/YANLibDomainSharedModule.cs +++ b/src/YANLib.Domain.Shared/YANLibDomainSharedModule.cs @@ -18,7 +18,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) Configure(o => o.FileSets.AddEmbedded()); Configure(o => { - _ = o.Resources.Add("en").AddBaseTypes(typeof(AbpValidationResource)).AddVirtualJson("/Localization/YANLib"); + _ = o.Resources.Add("vi").AddBaseTypes(typeof(AbpValidationResource)).AddVirtualJson("/Localization/YANLib"); o.DefaultResourceType = typeof(YANLibResource); }); Configure(o => o.MapCodeNamespace("YANLib", typeof(YANLibResource))); diff --git a/src/YANLib.Domain/Exceptions/ExceptionCode.cs b/src/YANLib.Domain/Exceptions/ExceptionCode.cs deleted file mode 100644 index 9e20132..0000000 --- a/src/YANLib.Domain/Exceptions/ExceptionCode.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YANLib.Exceptions; - -public static class ExceptionCode -{ - public const string BAD_REQUEST = "403"; - public const string BAD_REQUEST_ID = "413"; -} diff --git a/src/YANLib.Domain/Exceptions/ExceptionMessage.cs b/src/YANLib.Domain/Exceptions/ExceptionMessage.cs deleted file mode 100644 index cb7b191..0000000 --- a/src/YANLib.Domain/Exceptions/ExceptionMessage.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YANLib.Exceptions; - -public static class ExceptionMessage -{ - public const string BAD_REQUEST = "Tham số truyền vào không hợp lệ!"; - public const string BAD_REQUEST_ID = "Id truyền vào không hợp lệ!"; -} diff --git a/src/YANLib.Domain/Models/Certificate.cs b/src/YANLib.Domain/Models/Certificate.cs new file mode 100644 index 0000000..c79ef17 --- /dev/null +++ b/src/YANLib.Domain/Models/Certificate.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace YANLib.Models; + +[Table("Certificates")] +public sealed class Certificate +{ + [Key] + public Guid Id { get; set; } + public string Name { get; set; } + public double? GPA { get; set; } + public Guid? DeveloperId { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } +} diff --git a/src/YANLib.Domain/Models/Developer.cs b/src/YANLib.Domain/Models/Developer.cs new file mode 100644 index 0000000..1c5c7e9 --- /dev/null +++ b/src/YANLib.Domain/Models/Developer.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace YANLib.Models; + +[Table("Developers")] +public sealed class Developer +{ + [Key] + public Guid Id { get; set; } + public string Name { get; set; } + public string Phone { get; set; } + public string IdCard { get; set; } + public int DeveloperTypeCode { get; set; } + public bool IsActive { get; set; } + public int Version { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } + + [ForeignKey("DeveloperTypeCode")] + public DeveloperType DeveloperType { get; set; } +} diff --git a/src/YANLib.Domain/Models/DeveloperType.cs b/src/YANLib.Domain/Models/DeveloperType.cs new file mode 100644 index 0000000..92f2d1e --- /dev/null +++ b/src/YANLib.Domain/Models/DeveloperType.cs @@ -0,0 +1,16 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace YANLib.Models; + +[Table("DeveloperTypes")] +public sealed class DeveloperType +{ + [Key] + public int Code { get; set; } + public string Name { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? ModifiedDate { get; set; } +} diff --git a/src/YANLib.Domain/Repositories/ICertificateRepository.cs b/src/YANLib.Domain/Repositories/ICertificateRepository.cs new file mode 100644 index 0000000..efbb01c --- /dev/null +++ b/src/YANLib.Domain/Repositories/ICertificateRepository.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using YANLib.Models; + +namespace YANLib.Repositories; + +public interface ICertificateRepository : ITransientDependency +{ + public ValueTask> GetByDeveloperId(Guid developerId); + public ValueTask> Inserts(IEnumerable entities); + public ValueTask> Updates(IEnumerable entities); +} diff --git a/src/YANLib.Domain/Repositories/IDeveloperRepository.cs b/src/YANLib.Domain/Repositories/IDeveloperRepository.cs new file mode 100644 index 0000000..4d737b9 --- /dev/null +++ b/src/YANLib.Domain/Repositories/IDeveloperRepository.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using YANLib.Models; + +namespace YANLib.Repositories; + +public interface IDeveloperRepository : ITransientDependency +{ + public ValueTask> GetAll(); + public ValueTask Insert(Developer entity); + public ValueTask Adjust(Developer entity); +} diff --git a/src/YANLib.Domain/Repositories/IDeveloperTypeRepository.cs b/src/YANLib.Domain/Repositories/IDeveloperTypeRepository.cs new file mode 100644 index 0000000..53e9cfc --- /dev/null +++ b/src/YANLib.Domain/Repositories/IDeveloperTypeRepository.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using YANLib.Models; + +namespace YANLib.Repositories; + +public interface IDeveloperTypeRepository : ITransientDependency +{ + public ValueTask> GetAll(); + public ValueTask Insert(DeveloperType entity); + public ValueTask Update(DeveloperType entity); +} diff --git a/src/YANLib.Domain/YANLib.Domain.csproj b/src/YANLib.Domain/YANLib.Domain.csproj index 8871e47..9529bce 100644 --- a/src/YANLib.Domain/YANLib.Domain.csproj +++ b/src/YANLib.Domain/YANLib.Domain.csproj @@ -1,18 +1,18 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - + + + - - - + + + diff --git a/src/YANLib.Domain/YANLibConsts.cs b/src/YANLib.Domain/YANLibConsts.cs index 45546db..9938e85 100644 --- a/src/YANLib.Domain/YANLibConsts.cs +++ b/src/YANLib.Domain/YANLibConsts.cs @@ -4,5 +4,11 @@ public static class YANLibConsts { public const string DbTablePrefix = "App"; - public const string DbSchema = null; + public const string DbSchema = "sample"; + + public const string ConnectionStringName = "Default"; + + public const string IdxSample = "Elasticsearch:Indices:Sample"; + + public const string RedisKeyCommand = "KEYS"; } diff --git a/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/IYANLibDbContext.cs b/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/IYANLibDbContext.cs index c33ed85..0bbb1e5 100644 --- a/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/IYANLibDbContext.cs +++ b/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/IYANLibDbContext.cs @@ -1,9 +1,15 @@ -using Volo.Abp.Data; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using YANLib.Models; +using static YANLib.YANLibConsts; namespace YANLib.EntityFrameworkCore.DbContext; -[ConnectionStringName("Default")] +[ConnectionStringName(ConnectionStringName)] public interface IYANLibDbContext : IEfCoreDbContext { + public DbSet Developers { get; } + public DbSet DeveloperTypes { get; } + public DbSet Certificates { get; } } diff --git a/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/Implements/YANLibDbContext.cs b/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/Implements/YANLibDbContext.cs index e0f43c5..516fce0 100644 --- a/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/Implements/YANLibDbContext.cs +++ b/src/YANLib.EntityFrameworkCore/EntityFrameworkCore/DbContext/Implements/YANLibDbContext.cs @@ -1,23 +1,22 @@ using Microsoft.EntityFrameworkCore; -using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using YANLib.Models; +using static YANLib.YANLibConsts; namespace YANLib.EntityFrameworkCore.DbContext.Implements; -[ConnectionStringName("Default")] public class YANLibDbContext : AbpDbContext, IYANLibDbContext { - /* Add DbSet for each Aggregate Root here. Example: - * public DbSet Questions { get; set; } - */ + public DbSet Developers { get; set; } + public DbSet DeveloperTypes { get; set; } + public DbSet Certificates { get; set; } - public YANLibDbContext(DbContextOptions options) : base(options) - { - } + public YANLibDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); + _ = builder.HasDefaultSchema(DbSchema); builder.ConfigureYANLib(); } } diff --git a/src/YANLib.EntityFrameworkCore/Repositories/CertificateRepository.cs b/src/YANLib.EntityFrameworkCore/Repositories/CertificateRepository.cs new file mode 100644 index 0000000..d2d4c9b --- /dev/null +++ b/src/YANLib.EntityFrameworkCore/Repositories/CertificateRepository.cs @@ -0,0 +1,93 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.EntityFrameworkCore.DbContext; +using YANLib.Models; +using static System.DateTime; +using static System.Guid; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Repositories; + +public sealed class CertificateRepository : ICertificateRepository +{ + #region Fields + private readonly ILogger _logger; + private readonly IYANLibDbContext _dbContext; + #endregion + + #region Constructors + public CertificateRepository(ILogger logger, IYANLibDbContext dbContext) + { + _logger = logger; + _dbContext = dbContext; + } + #endregion + + #region Implements + public async ValueTask> GetByDeveloperId(Guid developerId) + { + try + { + return await _dbContext.Certificates.AsNoTracking().Where(x => x.DeveloperId == developerId).ToArrayAsync(); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetByDeveloperIdCertificateRepository-Exception: {DeveloperId}", developerId); + throw; + } + } + + public async ValueTask> Inserts(IEnumerable entities) + { + try + { + var ids = new HashSet(); + var rslts = entities.Select(x => + { + var id = NewGuid(); + + x.Id = id; + x.CreatedDate = Now; + _ = ids.Add(id); + + return x; + }); + + await _dbContext.Certificates.AddRangeAsync(rslts); + + return await _dbContext.SaveChangesAsync() > 0 ? rslts : throw new BusinessException(INTERNAL_SERVER_ERROR); + } + catch (Exception ex) + { + _logger.LogError(ex, "InsertsCertificateRepository-Exception: {Entities}", entities.CamelSerialize()); + throw; + } + } + + public async ValueTask> Updates(IEnumerable entities) + { + try + { + var rslts = entities.Select(x => + { + x.ModifiedDate = Now; + return x; + }); + + _dbContext.Certificates.UpdateRange(rslts); + + return await _dbContext.SaveChangesAsync() > 0 ? rslts : throw new BusinessException(INTERNAL_SERVER_ERROR); + } + catch (Exception ex) + { + _logger.LogError(ex, "UpdatesCertificateRepository-Exception: {Entities}", entities.CamelSerialize()); + throw; + } + } + #endregion +} diff --git a/src/YANLib.EntityFrameworkCore/Repositories/DeveloperRepository.cs b/src/YANLib.EntityFrameworkCore/Repositories/DeveloperRepository.cs new file mode 100644 index 0000000..c95172f --- /dev/null +++ b/src/YANLib.EntityFrameworkCore/Repositories/DeveloperRepository.cs @@ -0,0 +1,110 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.EntityFrameworkCore.DbContext; +using YANLib.Models; +using static System.DateTime; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Repositories; + +public sealed class DeveloperRepository : IDeveloperRepository +{ + #region Fields + private readonly ILogger _logger; + private readonly IYANLibDbContext _dbContext; + #endregion + + #region Constructors + public DeveloperRepository(ILogger logger, IYANLibDbContext dbContext) + { + _logger = logger; + _dbContext = dbContext; + } + #endregion + + #region Implements + public async ValueTask> GetAll() + { + try + { + return await _dbContext.Developers.AsNoTracking().Include(x => x.DeveloperType).ToArrayAsync(); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetAllDeveloperRepository-Exception"); + throw; + } + } + + public async ValueTask Insert(Developer entity) + { + try + { + entity.IsActive = true; + entity.Version = 1; + entity.CreatedDate = Now; + _ = await _dbContext.Developers.AddAsync(entity); + + if (await _dbContext.SaveChangesAsync() > 0) + { + entity.DeveloperType = await _dbContext.DeveloperTypes.AsNoTracking().FirstOrDefaultAsync(x => x.Code == entity.DeveloperTypeCode); + return entity; + } + else + { + throw new BusinessException(INTERNAL_SERVER_ERROR); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "InsertDeveloperRepository-Exception: {Entity}", entity.CamelSerialize()); + throw; + } + } + + public async ValueTask Adjust(Developer entity) + { + try + { + var mdls = await _dbContext.Developers.AsNoTracking().Where(x => x.IdCard == entity.IdCard).ToArrayAsync(); + + if (mdls.IsEmptyOrNull()) + { + throw new BusinessException(NOT_FOUND_DEV).WithData("IdCard", entity.IdCard); + } + + _dbContext.Developers.UpdateRange(mdls.Select(x => + { + x.IsActive = false; + x.ModifiedDate = Now; + return x; + })); + + entity.IsActive = true; + entity.Version++; + entity.CreatedDate = Now; + _ = await _dbContext.Developers.AddAsync(entity); + + if (await _dbContext.SaveChangesAsync() > 0) + { + entity.DeveloperType = await _dbContext.DeveloperTypes.AsNoTracking().FirstOrDefaultAsync(x => x.Code == entity.DeveloperTypeCode); + return entity; + } + else + { + throw new BusinessException(INTERNAL_SERVER_ERROR); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "AdjustDeveloperRepository-Exception: {Entity}", entity.CamelSerialize()); + throw; + } + } + #endregion +} diff --git a/src/YANLib.EntityFrameworkCore/Repositories/DeveloperTypeRepository.cs b/src/YANLib.EntityFrameworkCore/Repositories/DeveloperTypeRepository.cs new file mode 100644 index 0000000..9aa6589 --- /dev/null +++ b/src/YANLib.EntityFrameworkCore/Repositories/DeveloperTypeRepository.cs @@ -0,0 +1,86 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.EntityFrameworkCore.DbContext; +using YANLib.Models; +using static System.DateTime; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Repositories; + +public sealed class DeveloperTypeRepository : IDeveloperTypeRepository +{ + #region Fields + private readonly ILogger _logger; + private readonly IYANLibDbContext _dbContext; + #endregion + + #region Constructors + public DeveloperTypeRepository(ILogger logger, IYANLibDbContext dbContext) + { + _logger = logger; + _dbContext = dbContext; + } + #endregion + + #region Implements + public async ValueTask> GetAll() + { + try + { + return await _dbContext.DeveloperTypes.AsNoTracking().ToArrayAsync(); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetAllDeveloperTypeRepository-Exception"); + throw; + } + } + + public async ValueTask Insert(DeveloperType entity) + { + try + { + var mdl = await _dbContext.DeveloperTypes.AsNoTracking().FirstOrDefaultAsync(x => x.Code == entity.Code); + + if (mdl is not null) + { + throw new BusinessException(EXIST_ID).WithData("Id", entity.Code); + } + + entity.CreatedDate = Now; + _ = await _dbContext.DeveloperTypes.AddAsync(entity); + + return await _dbContext.SaveChangesAsync() > 0 ? entity : throw new BusinessException(INTERNAL_SERVER_ERROR); + } + catch (Exception ex) + { + _logger.LogError(ex, "InsertDeveloperTypeRepository-Exception: {Entity}", entity.CamelSerialize()); + throw; + } + } + + public async ValueTask Update(DeveloperType entity) + { + try + { + var mdl = await _dbContext.DeveloperTypes.AsNoTracking().FirstOrDefaultAsync(x => x.Code == entity.Code) ?? throw new BusinessException(NOT_FOUND_DEV_TYPE).WithData("Id", entity.Code); + + mdl.Name = entity.Name; + mdl.IsActive = entity.IsActive; + mdl.ModifiedDate = Now; + _dbContext.DeveloperTypes.Update(mdl); + + return await _dbContext.SaveChangesAsync() > 0 ? mdl : throw new BusinessException(INTERNAL_SERVER_ERROR); + } + catch (Exception ex) + { + _logger.LogError(ex, "UpdateDeveloperTypeRepository-Exception: {Entity}", entity.CamelSerialize()); + throw; + } + } + #endregion +} diff --git a/src/YANLib.EntityFrameworkCore/YANLib.EntityFrameworkCore.csproj b/src/YANLib.EntityFrameworkCore/YANLib.EntityFrameworkCore.csproj index 6dde882..2dec504 100644 --- a/src/YANLib.EntityFrameworkCore/YANLib.EntityFrameworkCore.csproj +++ b/src/YANLib.EntityFrameworkCore/YANLib.EntityFrameworkCore.csproj @@ -1,15 +1,16 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - - + + + + + diff --git a/src/YANLib.HttpApi.Client/YANLib.HttpApi.Client.csproj b/src/YANLib.HttpApi.Client/YANLib.HttpApi.Client.csproj index 0399751..11a1dfc 100644 --- a/src/YANLib.HttpApi.Client/YANLib.HttpApi.Client.csproj +++ b/src/YANLib.HttpApi.Client/YANLib.HttpApi.Client.csproj @@ -1,23 +1,23 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - + + + - - - + + + - - - - + + + + diff --git a/src/YANLib.HttpApi/Controllers/DeveloperController.cs b/src/YANLib.HttpApi/Controllers/DeveloperController.cs new file mode 100644 index 0000000..ffc0cd7 --- /dev/null +++ b/src/YANLib.HttpApi/Controllers/DeveloperController.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Annotations; +using System; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.Requests; +using YANLib.Services; + +namespace YANLib.Controllers; + +[RemoteService] +[ApiExplorerSettings(GroupName = "sample")] +[Route("api/yanlib/developers")] +public sealed class DeveloperController : YANLibController +{ + #region Fields + private readonly ILogger _logger; + private readonly IDeveloperService _service; + #endregion + + #region Constructors + public DeveloperController(ILogger logger, IDeveloperService service) + { + _logger = logger; + _service = service; + } + #endregion + + #region Methods + [HttpGet("{id}")] + [SwaggerOperation(Summary = "Tìm Developer theo Id")] + public async ValueTask Get([Required] Guid id) + { + _logger.LogInformation("GetDeveloperController: {Id}", id); + + return Ok(await _service.Get(id)); + } + + [HttpPost] + [SwaggerOperation(Summary = "Thêm mới Developer")] + public async ValueTask Insert([Required] DeveloperRequest request) + { + _logger.LogInformation("InsertDeveloperController: {Request}", request.CamelSerialize()); + + return Ok(await _service.Insert(request)); + } + + [HttpPatch("idCard")] + [SwaggerOperation(Summary = "Cập nhật Developer")] + public async ValueTask Adjust([Required] string idCard, [Required] DeveloperFreeRequest request) + { + _logger.LogInformation("AdjustDeveloperController: {IdCard} - {Request}", idCard, request.CamelSerialize()); + + return Ok(await _service.Adjust(idCard, request)); + } + + [HttpGet("get-by-id-card")] + [SwaggerOperation(Summary = "Tìm Developer theo Id Card")] + public async ValueTask GetByIdCard([Required] string idCard) + { + _logger.LogInformation("GetByIdCardDeveloperController: {IdCard}", idCard); + + return Ok(await _service.GetByIdCard(idCard)); + } + + [HttpGet("get-by-phone")] + [SwaggerOperation(Summary = "Tìm tất cả Developers theo Phone")] + public async ValueTask GetByPhone([Required] string phone) + { + _logger.LogInformation("GetByPhoneDeveloperController: {Phone}", phone); + + return Ok(await _service.GetByPhone(phone)); + } + + [HttpPost("sync-db-to-es")] + [SwaggerOperation(Summary = "Đồng bộ tất cả Developers từ Database lên Elasticsearch")] + public async ValueTask SyncDbToEs() => Ok(await _service.SyncDbToEs()); + #endregion +} diff --git a/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs b/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs new file mode 100644 index 0000000..ec5f74f --- /dev/null +++ b/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs @@ -0,0 +1,66 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Annotations; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.Requests; +using YANLib.Services; + +namespace YANLib.Controllers; + +[RemoteService] +[ApiExplorerSettings(GroupName = "sample")] +[Route("api/yanlib/developer-types")] +public sealed class DeveloperTypeController : YANLibController +{ + #region Fields + private readonly ILogger _logger; + private readonly IDeveloperTypeService _service; + #endregion + + #region Constructors + public DeveloperTypeController(ILogger logger, IDeveloperTypeService service) + { + _logger = logger; + _service = service; + } + #endregion + + #region Methods + [HttpGet] + [SwaggerOperation(Summary = "Tìm tất cả định nghĩa Developer Types")] + public async ValueTask GetAll() => Ok(await _service.GetAll()); + + [HttpGet("{code}")] + [SwaggerOperation(Summary = "Tìm định nghĩa Developer Type theo Code")] + public async ValueTask Get([Required] int code) + { + _logger.LogInformation("GetDeveloperTypeController: {Code}", code); + + return Ok(await _service.Get(code)); + } + + [HttpPost] + [SwaggerOperation(Summary = "Thêm mới định nghĩa Developer Type")] + public async ValueTask Insert([Required] DeveloperTypeRequest request) + { + _logger.LogInformation("InsertDeveloperTypeController: {Request}", request.CamelSerialize()); + + return Ok(await _service.Insert(request)); + } + + [HttpPut] + [SwaggerOperation(Summary = "Cập nhật định nghĩa Developer Type")] + public async ValueTask Update([Required] DeveloperTypeRequest request) + { + _logger.LogInformation("UpdateDeveloperTypeController: {Request}", request.CamelSerialize()); + + return Ok(await _service.Update(request)); + } + + [SwaggerOperation(Summary = "Đồng bộ tất cả định nghĩa Developer Types từ Database sang Redis")] + [HttpPost("sync-db-to-redis")] + public async ValueTask SyncDbToRedis() => Ok(await _service.SyncDbToRedis()); + #endregion +} diff --git a/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs b/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs new file mode 100644 index 0000000..5ca1f45 --- /dev/null +++ b/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Annotations; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.EsIndexs; +using YANLib.EsServices; + +namespace YANLib.Controllers; + +[RemoteService] +[ApiExplorerSettings(GroupName = "sample")] +[Route("api/yanlib/es")] +public sealed class ElasticsearchController : YANLibController +{ + #region Fields + private readonly ILogger _logger; + private readonly IDeveloperEsService _developerEsService; + #endregion + + #region Constructors + public ElasticsearchController(ILogger logger, IDeveloperEsService developerEsService) + { + _logger = logger; + _developerEsService = developerEsService; + } + #endregion + + #region Methods + [HttpGet("developers/{id}")] + [SwaggerOperation(Summary = "Tìm Developer theo Id trên Elasticsearch")] + public async ValueTask Get([Required] string id) + { + _logger.LogInformation("GetElasticsearchController: {Id}", id); + + return Ok(await _developerEsService.Get(id)); + } + + [HttpPost("developers")] + [SwaggerOperation(Summary = "Thêm mới Developer trên Elasticsearch")] + public async ValueTask Set([Required] DeveloperIndex request) + { + _logger.LogInformation("SetElasticsearchController: {Request}", request.CamelSerialize()); + + return Ok(await _developerEsService.Set(request)); + } + #endregion +} diff --git a/src/YANLib.HttpApi/Controllers/YANJsonController.cs b/src/YANLib.HttpApi/Controllers/YANJsonController.cs index b9c55ca..1803bcd 100644 --- a/src/YANLib.HttpApi/Controllers/YANJsonController.cs +++ b/src/YANLib.HttpApi/Controllers/YANJsonController.cs @@ -1,18 +1,16 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Swashbuckle.AspNetCore.Annotations; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Volo.Abp; -using YANLib.Dtos; using YANLib.Services; namespace YANLib.Controllers; [RemoteService] -[ApiExplorerSettings(GroupName = "json")] -[Route("api/tynab/yanlib/yanjson")] +[ApiExplorerSettings(GroupName = "test")] +[Route("api/yanlib/json")] public class YANJsonController : YANLibController { #region Fields @@ -30,43 +28,12 @@ public YANJsonController(ILogger logger, IYANJsonService serv #region Methods [HttpGet("yan-vs-standards")] - [SwaggerOperation(Summary = "Deserialize speed test (YAN vs Standards)")] + [SwaggerOperation(Summary = "Đo tốc độ của thư viện YANLib và các chuẩn khác")] public async ValueTask YanVsStandards([Required] uint quantity = 10000, [Required] bool hideSystem = true) { - _logger.LogInformation("YanVsStandardsYANJsonController: {Quantity}, {HideSystem}", quantity, hideSystem); + _logger.LogInformation("YanVsStandardsYANJsonController: {Quantity} - {HideSystem}", quantity, hideSystem); + return Ok(await _service.YanVsStandards(quantity, hideSystem)); } - - [HttpPost("serialize")] - [SwaggerOperation(Summary = "Serialize n-1 Pascal case")] - public IActionResult Serialize([Required] List request) => Ok(request.Serialize()); - - [HttpPost("camel-serialize")] - [SwaggerOperation(Summary = "Serialize n-1 Camel case")] - public IActionResult SerializeCamel([Required] List request) => Ok(request.CamelSerialize()); - - [HttpGet("standard-deserialize/{text}")] - [SwaggerOperation(Summary = "Deserialize 1-1 ignore case")] - public IActionResult DeserializeStandard([Required] string text = "{\"Id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}") => Ok(text.StandardDeserialize()); - - [HttpGet("deserialize/{text}")] - [SwaggerOperation(Summary = "Deserialize 1-1 Pascal case")] - public IActionResult Deserializes([Required] string text = "{\"Id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}") => Ok(text.Deserialize()); - - [HttpPost("serializes")] - [SwaggerOperation(Summary = "Serialize n-n Pascal case")] - public IActionResult Serializes([Required] List request) => Ok(request.Serializes()); - - [HttpPost("camel-serializes")] - [SwaggerOperation(Summary = "Serialize n-n Camel case")] - public IActionResult SerializeCamels([Required] List request) => Ok(request.CamelSerializes()); - - [HttpPost("deserializes")] - [SwaggerOperation(Summary = "Deserialize n-n Pascal case")] - public IActionResult Deserializes([Required] List text) => Ok(text.Deserializes()); - - [HttpPost("standard-deserializes")] - [SwaggerOperation(Summary = "Deserialize n-n ignore case")] - public IActionResult DeserializeStandards([Required] List text) => Ok(text.StandardDeserializes()); #endregion } diff --git a/src/YANLib.HttpApi/YANLib.HttpApi.csproj b/src/YANLib.HttpApi/YANLib.HttpApi.csproj index f2bf547..715184d 100644 --- a/src/YANLib.HttpApi/YANLib.HttpApi.csproj +++ b/src/YANLib.HttpApi/YANLib.HttpApi.csproj @@ -1,20 +1,20 @@ - + - - net6.0 - YANLib - + + net6.0 + YANLib + - - - - + + + + - - - - + + + + diff --git a/src/YANLib.MongoDB/YANLib.MongoDB.csproj b/src/YANLib.MongoDB/YANLib.MongoDB.csproj index ec1a496..7c511b5 100644 --- a/src/YANLib.MongoDB/YANLib.MongoDB.csproj +++ b/src/YANLib.MongoDB/YANLib.MongoDB.csproj @@ -1,17 +1,17 @@ - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - - + + + - - - + + +