diff --git a/content/aspnetcore/CompanyName.ProjectName.sln b/content/aspnetcore/CompanyName.ProjectName.sln index 19573a88..fb9af0df 100644 --- a/content/aspnetcore/CompanyName.ProjectName.sln +++ b/content/aspnetcore/CompanyName.ProjectName.sln @@ -46,6 +46,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BC7E3BFE-3644-4893-8475-E543F3957F2A}" ProjectSection(SolutionItems) = preProject common.props = common.props + NuGet.Config = NuGet.Config EndProjectSection EndProject Global diff --git a/content/aspnetcore/NuGet.Config b/content/aspnetcore/NuGet.Config index 0d5eaacd..a23bc850 100644 --- a/content/aspnetcore/NuGet.Config +++ b/content/aspnetcore/NuGet.Config @@ -1,10 +1,10 @@ - + - + \ No newline at end of file diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj index bbc3df36..0bd0bbe1 100644 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj +++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj @@ -26,6 +26,12 @@ + + + + + + @@ -35,7 +41,6 @@ - diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs index bc940c9b..5718bd32 100644 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs +++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/CompanyNameProjectNameHttpApiHostModule.cs @@ -25,9 +25,6 @@ using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Auditing; using Volo.Abp.Autofac; @@ -48,7 +45,6 @@ namespace CompanyNameProjectName typeof(AbpAspNetCoreMultiTenancyModule), typeof(CompanyNameProjectNameApplicationModule), typeof(CompanyNameProjectNameEntityFrameworkCoreDbMigrationsModule), - typeof(AbpAspNetCoreMvcUiBasicThemeModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpAccountWebIdentityServerModule), typeof(AbpAspNetCoreSerilogModule), @@ -76,7 +72,6 @@ namespace CompanyNameProjectName { var configuration = context.Services.GetConfiguration(); ConfigureOptions(context); - ConfigureBundles(); ConfigureUrls(configuration); ConfigureConventionalControllers(); ConfigureJwtAuthentication(context, configuration); @@ -88,6 +83,7 @@ namespace CompanyNameProjectName ConfigureCache(context.Services); ConfigureAuditLog(); ConfigureHangfire(context.Services); + ConfigureHealthChecks(context); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -101,12 +97,6 @@ namespace CompanyNameProjectName } app.UseAbpRequestLocalization(); - - if (!env.IsDevelopment()) - { - app.UseErrorPage(); - } - app.UseCorrelationId(); app.UseStaticFiles(); app.UseRouting(); @@ -114,7 +104,6 @@ namespace CompanyNameProjectName app.UseAuthentication(); app.UseJwtTokenMiddleware(); app.UseAuthorization(); - app.UseSwagger(); app.UseAbpSwaggerUI(c => { @@ -131,10 +120,27 @@ namespace CompanyNameProjectName }); app.UseConfiguredEndpoints(); - + app.UseEndpoints(endpoints => + { + endpoints.MapHealthChecks("/health"); + }); } #region ç§�有方法 + + + private void ConfigureHealthChecks(ServiceConfigurationContext context) + { + + var redisConnectionString = + context.Services.GetConfiguration().GetValue("Cache:Redis:ConnectionString") + +",defaultdatabase=" + + context.Services.GetConfiguration().GetValue("Cache:Redis:DatabaseId", 1); + + var mysqlConnectionString = context.Services.GetConfiguration().GetConnectionString("Default"); + context.Services.AddHealthChecks().AddRedis(redisConnectionString).AddMySql(mysqlConnectionString); + } + /// /// é…�ç½®options /// @@ -152,8 +158,8 @@ namespace CompanyNameProjectName { Configure(options => { - options.IsEnabled = true; - options.EntityHistorySelectors.AddAllEntities(); + options.IsEnabled = true; + options.EntityHistorySelectors.AddAllEntities(); options.ApplicationName = "CompanyName.ProjectName"; }); } @@ -187,21 +193,18 @@ namespace CompanyNameProjectName options.SendExceptionsDetailsToClients = true; }); } - } - - - private void ConfigureBundles() - { - Configure(options => + // 如果è¦�求返回值正确和异常格å¼�一致添加次特性 + context.Services.AddMvc(options => { - options.StyleBundles.Configure( - BasicThemeBundles.Styles.Global, - bundle => { bundle.AddFiles("/global-styles.css"); } - ); + options.Filters.Add(typeof(ResultExceptionFilter)); }); + } + + + private void ConfigureUrls(IConfiguration configuration) { Configure(options => @@ -231,7 +234,7 @@ namespace CompanyNameProjectName { options.ConventionalControllers.Create(typeof(CompanyNameProjectNameApplicationModule).Assembly); }); - + } /// @@ -362,7 +365,7 @@ namespace CompanyNameProjectName }); var redisConnectionString = services.GetConfiguration().GetSection("Cache:Redis:ConnectionString").Value; - var redisDatabaseId = Convert.ToInt32(services.GetConfiguration().GetSection("Cache:Redis:DatabaseId").Value); + var redisDatabaseId = services.GetConfiguration().GetValue("Cache:Redis:DatabaseId", 1); // å�¯ç”¨Hangfire 并使用Redis作为æŒ�久化 services.AddHangfire(config => diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile index 46d94190..0f9737e9 100644 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile +++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/aspnet:5.0 +FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim # ´´½¨Ä¿Â¼ RUN mkdir /apps diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/ResultExceptionFilter.cs b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/ResultExceptionFilter.cs new file mode 100644 index 00000000..48fe1827 --- /dev/null +++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/Extensions/Filters/ResultExceptionFilter.cs @@ -0,0 +1,129 @@ +using CompanyNameProjectName.Attributes; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.Authorization; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; +using Volo.Abp.ExceptionHandling; +using Volo.Abp.Http; +using Volo.Abp.Json; +using Volo.Abp.Validation; + + +namespace CompanyNameProjectName.Extensions.Filters +{ + public class ResultExceptionFilter : IFilterMetadata, IAsyncExceptionFilter, ITransientDependency + { + public ILogger Logger { get; set; } + + private readonly IExceptionToErrorInfoConverter _errorInfoConverter; + private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; + private readonly IJsonSerializer _jsonSerializer; + private readonly AbpExceptionHandlingOptions _exceptionHandlingOptions; + + public ResultExceptionFilter( + IExceptionToErrorInfoConverter errorInfoConverter, + IHttpExceptionStatusCodeFinder statusCodeFinder, + IJsonSerializer jsonSerializer, + IOptions exceptionHandlingOptions) + { + _errorInfoConverter = errorInfoConverter; + _statusCodeFinder = statusCodeFinder; + _jsonSerializer = jsonSerializer; + _exceptionHandlingOptions = exceptionHandlingOptions.Value; + Logger = NullLogger.Instance; + } + + public async Task OnExceptionAsync(ExceptionContext context) + { + if (!ShouldHandleException(context)) + { + return; + } + + + await HandleAndWrapException(context); + } + + protected virtual bool ShouldHandleException(ExceptionContext context) + { + if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any()) + { + return true; + } + + if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(DontWrapResultAttribute), true).Any()) + { + return true; + } + return false; + } + + protected virtual async Task HandleAndWrapException(ExceptionContext context) + { + //TODO: Trigger an AbpExceptionHandled event or something like that. + + context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); + var statusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); + context.HttpContext.Response.StatusCode = 200; + + var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception, _exceptionHandlingOptions.SendExceptionsDetailsToClients); + remoteServiceErrorInfo.Code = context.HttpContext.TraceIdentifier; + remoteServiceErrorInfo.Message = SimplifyMessage(context.Exception); + var result = new WrapResult(); + result.SetFail(remoteServiceErrorInfo.Message); + + // HttpResponse + context.Result = new ObjectResult(result); + + // 写日志 + var logLevel = context.Exception.GetLogLevel(); + var remoteServiceErrorInfoBuilder = new StringBuilder(); + remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------"); + remoteServiceErrorInfoBuilder.AppendLine(_jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); + Logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString()); + Logger.LogException(context.Exception, logLevel); + + await context.HttpContext + .RequestServices + .GetRequiredService() + .NotifyAsync( + new ExceptionNotificationContext(context.Exception) + ); + + context.Exception = null; //Handled! + } + + protected string SimplifyMessage(Exception error) + { + string message = string.Empty; + switch (error) + { + case AbpAuthorizationException e: + return message = "Authenticate failureï¼�"; + case AbpValidationException e: + return message = "Request param validate failureï¼�"; + case EntityNotFoundException e: + return message = "not found the entityï¼�"; + case BusinessException e: + return message = $"{e.Message}"; + case NotImplementedException e: + return message = "not implementï¼�"; + default: + return message = "server internal errorï¼�"; + } + } + } + +} diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json deleted file mode 100644 index cf517529..00000000 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Ali.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "App": { - "SelfUrl": "https://localhost:44363", - "CorsOrigins": "https://*.CompanyNameProjectName.com,http://localhost:8083,http://localhost:8081,https://localhost:44307," - }, - "StringEncryption": { - "DefaultPassPhrase": "MY2bTgp2iaHUEp66" - }, - "Settings": { - "Abp.Mailing.Smtp.Host": "127.0.0.1", - "Abp.Mailing.Smtp.Port": "25", - "Abp.Mailing.Smtp.UserName": "", - "Abp.Mailing.Smtp.Password": "", - "Abp.Mailing.Smtp.Domain": "", - "Abp.Mailing.Smtp.EnableSsl": "false", - "Abp.Mailing.Smtp.UseDefaultCredentials": "true", - "Abp.Mailing.DefaultFromAddress": "noreply@abp.io", - "Abp.Mailing.DefaultFromDisplayName": "ABP application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Information", - "Microsoft.AspNetCore": "Information", - "System": "Warning", - "Microsoft.Hosting.Lifetime": "Information", - "Microsoft.AspNetCore.Routing": "Information", - "Microsoft.AspNetCore.Hosting.Diagnostics": "Error" - } - } - }, - "ConnectionStrings": { - "Default": "Data Source=mysql.development.cn;Database=CompanyNameProjectName;uid=root;pwd=mysql@;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" - }, - "Cache": { - "Redis": { - "ConnectionString": "redis.development.yhglobal.cn,password=OD5VbzIuAWsHOZV5ncYx9xaDsAMsKXn7", - "DatabaseId": 231 - } - }, - "AuthServer": { - "Authority": "https://localhost:44363", - "RequireHttpsMetadata": "false" - }, - "Jwt": { - "Audience": "http://localhost:5010", //¿Í»§¶Ë±êʶ - "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=", - "Issuer": "CompanyNameProjectName", //Ç©·¢Õß - "ExpirationTime": 2 //¹ýÆÚʱ¼ä hour - }, - "LogToElasticSearch": { - "Enabled": "true", - "ElasticSearch": { - "Url": "http://es.cn", - "IndexFormat": "CompanyNameProjectName.admin.api.dev-{0:yyyy.MM.dd}", - "UserName": "CompanyNameProjectName", - "Password": "TCYobkZxWu0ELYZY" - } - } -} \ No newline at end of file diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json deleted file mode 100644 index cf517529..00000000 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.Staging.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "App": { - "SelfUrl": "https://localhost:44363", - "CorsOrigins": "https://*.CompanyNameProjectName.com,http://localhost:8083,http://localhost:8081,https://localhost:44307," - }, - "StringEncryption": { - "DefaultPassPhrase": "MY2bTgp2iaHUEp66" - }, - "Settings": { - "Abp.Mailing.Smtp.Host": "127.0.0.1", - "Abp.Mailing.Smtp.Port": "25", - "Abp.Mailing.Smtp.UserName": "", - "Abp.Mailing.Smtp.Password": "", - "Abp.Mailing.Smtp.Domain": "", - "Abp.Mailing.Smtp.EnableSsl": "false", - "Abp.Mailing.Smtp.UseDefaultCredentials": "true", - "Abp.Mailing.DefaultFromAddress": "noreply@abp.io", - "Abp.Mailing.DefaultFromDisplayName": "ABP application" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Information", - "Microsoft.AspNetCore": "Information", - "System": "Warning", - "Microsoft.Hosting.Lifetime": "Information", - "Microsoft.AspNetCore.Routing": "Information", - "Microsoft.AspNetCore.Hosting.Diagnostics": "Error" - } - } - }, - "ConnectionStrings": { - "Default": "Data Source=mysql.development.cn;Database=CompanyNameProjectName;uid=root;pwd=mysql@;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" - }, - "Cache": { - "Redis": { - "ConnectionString": "redis.development.yhglobal.cn,password=OD5VbzIuAWsHOZV5ncYx9xaDsAMsKXn7", - "DatabaseId": 231 - } - }, - "AuthServer": { - "Authority": "https://localhost:44363", - "RequireHttpsMetadata": "false" - }, - "Jwt": { - "Audience": "http://localhost:5010", //¿Í»§¶Ë±êʶ - "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=", - "Issuer": "CompanyNameProjectName", //Ç©·¢Õß - "ExpirationTime": 2 //¹ýÆÚʱ¼ä hour - }, - "LogToElasticSearch": { - "Enabled": "true", - "ElasticSearch": { - "Url": "http://es.cn", - "IndexFormat": "CompanyNameProjectName.admin.api.dev-{0:yyyy.MM.dd}", - "UserName": "CompanyNameProjectName", - "Password": "TCYobkZxWu0ELYZY" - } - } -} \ No newline at end of file diff --git a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json index 12a31825..61f6a91c 100644 --- a/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json +++ b/content/aspnetcore/host/CompanyName.ProjectName.HttpApi.Host/appsettings.json @@ -31,7 +31,7 @@ } }, "ConnectionStrings": { - "Default": "Data Source=localhost;Database=CompanyNameProjectName;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" + "Default": "Data Source=localhost;port=3307;Database=CompanyNameProjectName;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" }, "Cache": { "Redis": { diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/DontWrapResultAttribute.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/DontWrapResultAttribute.cs new file mode 100644 index 00000000..1ae4f609 --- /dev/null +++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/DontWrapResultAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace CompanyNameProjectName.Attributes +{ + public class DontWrapResultAttribute : Attribute + { + public DontWrapResultAttribute() + { + } + } + +} diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/WrapResult.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/WrapResult.cs new file mode 100644 index 00000000..c34b2105 --- /dev/null +++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Attributes/WrapResult.cs @@ -0,0 +1,31 @@ +namespace CompanyNameProjectName.Attributes +{ + public class WrapResult + { + public bool Success { get; set; } + + public string Message { get; set; } + + public T Data { get; set; } + public WrapResult() + { + Success = true; + Message = "Success"; + Data = default; + } + + public void SetSucess(T data, string message = "Success") + { + Success = true; + Data = data; + } + + public void SetFail(string message = "Fail") + { + Success = false; + Message = message; + } + + } + +} diff --git a/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs index ea759cea..d0e88c59 100644 --- a/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs +++ b/content/aspnetcore/src/CompanyName.ProjectName.Application/Users/LoginAppService.cs @@ -95,7 +95,6 @@ namespace CompanyNameProjectName.Users var handler = new JwtSecurityTokenHandler(); var token = handler.CreateToken(tokenDescriptor); return handler.WriteToken(token); - } } } diff --git a/content/aspnetcore/tools/CompanyName.ProjectName.DbMigrator/appsettings.json b/content/aspnetcore/tools/CompanyName.ProjectName.DbMigrator/appsettings.json index f01664e6..3e60ba7c 100644 --- a/content/aspnetcore/tools/CompanyName.ProjectName.DbMigrator/appsettings.json +++ b/content/aspnetcore/tools/CompanyName.ProjectName.DbMigrator/appsettings.json @@ -1,5 +1,5 @@ { "ConnectionStrings": { - "Default": "Data Source=localhost;Database=CompanyNameProjectName;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" + "Default": "Data Source=localhost;port=3307;Database=CompanyNameProjectName;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" } } diff --git a/content/vue/.husky/_/husky.sh b/content/vue/.husky/_/husky.sh new file mode 100644 index 00000000..ca2720e0 --- /dev/null +++ b/content/vue/.husky/_/husky.sh @@ -0,0 +1,30 @@ +#!/bin/sh +if [ -z "$husky_skip_init" ]; then + debug () { + [ "$HUSKY_DEBUG" = "1" ] && echo "husky (debug) - $1" + } + + readonly hook_name="$(basename "$0")" + debug "starting $hook_name..." + + if [ "$HUSKY" = "0" ]; then + debug "HUSKY env variable is set to 0, skipping hook" + exit 0 + fi + + if [ -f ~/.huskyrc ]; then + debug "sourcing ~/.huskyrc" + . ~/.huskyrc + fi + + export readonly husky_skip_init=1 + sh -e "$0" "$@" + exitCode="$?" + + if [ $exitCode != 0 ]; then + echo "husky - $hook_name hook exited with code $exitCode (error)" + exit $exitCode + fi + + exit 0 +fi