wip: 未完善,还需继续努力。

main
NoahLan 10 months ago
parent 6a0f150a22
commit e6725d7938

@ -1,6 +0,0 @@
namespace NPin.Framework.Core.Extensions;
public static class HttpContextExtensions
{
// public static void FileInlineHandle(this HttpContext)
}

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Lan.Framework.Core</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Volo.Abp.Core" Version="8.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Data" />
</ItemGroup>
</Project>

@ -1,18 +1,38 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Core", "Framework\NPin.Framework.Core\NPin.Framework.Core.csproj", "{088B4948-AE5B-45B3-A9FA-B853671CFA05}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Core", "framework\NPin.Framework.Core\NPin.Framework.Core.csproj", "{088B4948-AE5B-45B3-A9FA-B853671CFA05}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "framework", "framework", "{F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{86F61EBB-4ACC-459C-AB3C-C8D486C3017D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{86F61EBB-4ACC-459C-AB3C-C8D486C3017D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Web", "src\NPin.Web\NPin.Web.csproj", "{91A9536C-FD3D-4099-8459-6C1C5238C037}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Web", "src\NPin.Web\NPin.Web.csproj", "{91A9536C-FD3D-4099-8459-6C1C5238C037}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Mapster", "Framework\NPin.Framework.Mapster\NPin.Framework.Mapster.csproj", "{E6BCF6D7-A0B0-445D-AFE0-8F8C779FAB6B}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Mapster", "framework\NPin.Framework.Mapster\NPin.Framework.Mapster.csproj", "{E6BCF6D7-A0B0-445D-AFE0-8F8C779FAB6B}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.SqlSugarCore.Abstractions", "Framework\NPin.Framework.SqlSugarCore.Abstractions\NPin.Framework.SqlSugarCore.Abstractions.csproj", "{CBC83167-9806-41ED-98FA-105D38825A88}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.SqlSugarCore.Abstractions", "framework\NPin.Framework.SqlSugarCore.Abstractions\NPin.Framework.SqlSugarCore.Abstractions.csproj", "{CBC83167-9806-41ED-98FA-105D38825A88}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.SqlSugarCore", "Framework\NPin.Framework.SqlSugarCore\NPin.Framework.SqlSugarCore.csproj", "{CC3D8269-F965-4C87-93F2-351AFEF9E3D2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.SqlSugarCore", "framework\NPin.Framework.SqlSugarCore\NPin.Framework.SqlSugarCore.csproj", "{CC3D8269-F965-4C87-93F2-351AFEF9E3D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Ddd.Application", "framework\NPin.Framework.Ddd.Application\NPin.Framework.Ddd.Application.csproj", "{15754E04-2D54-4741-8FF9-93FE036CAA17}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Caching.FreeRedis", "framework\NPin.Framework.Caching.FreeRedis\NPin.Framework.Caching.FreeRedis.csproj", "{92727A89-5E9C-4694-896F-CF78047EF2C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.Ddd.Application.Contracts", "framework\NPin.Framework.Ddd.Application.Contracts\NPin.Framework.Ddd.Application.Contracts.csproj", "{4C59B5B2-C140-48A7-ABFB-7581905BFDE4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.AspNetCore", "framework\NPin.Framework.AspNetCore\NPin.Framework.AspNetCore.csproj", "{BFDBFC7F-58D3-4816-AFA8-93265E28268C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPin.Framework.AspNetCore.Authentication.OAuth", "framework\NPin.Framework.AspNetCore.Authentication.OAuth\NPin.Framework.AspNetCore.Authentication.OAuth.csproj", "{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5E522BFB-5F48-475E-8E7F-A3B393DF5DEA}"
ProjectSection(SolutionItems) = preProject
common.props = common.props
end.sh = end.sh
start.sh = start.sh
using.props = using.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "module", "module", "{EEAD0AD4-0F90-46D9-A775-D88AE07E2869}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -40,6 +60,26 @@ Global
{CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Release|Any CPU.Build.0 = Release|Any CPU {CC3D8269-F965-4C87-93F2-351AFEF9E3D2}.Release|Any CPU.Build.0 = Release|Any CPU
{15754E04-2D54-4741-8FF9-93FE036CAA17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15754E04-2D54-4741-8FF9-93FE036CAA17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15754E04-2D54-4741-8FF9-93FE036CAA17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15754E04-2D54-4741-8FF9-93FE036CAA17}.Release|Any CPU.Build.0 = Release|Any CPU
{92727A89-5E9C-4694-896F-CF78047EF2C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92727A89-5E9C-4694-896F-CF78047EF2C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92727A89-5E9C-4694-896F-CF78047EF2C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92727A89-5E9C-4694-896F-CF78047EF2C6}.Release|Any CPU.Build.0 = Release|Any CPU
{4C59B5B2-C140-48A7-ABFB-7581905BFDE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C59B5B2-C140-48A7-ABFB-7581905BFDE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C59B5B2-C140-48A7-ABFB-7581905BFDE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C59B5B2-C140-48A7-ABFB-7581905BFDE4}.Release|Any CPU.Build.0 = Release|Any CPU
{BFDBFC7F-58D3-4816-AFA8-93265E28268C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BFDBFC7F-58D3-4816-AFA8-93265E28268C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BFDBFC7F-58D3-4816-AFA8-93265E28268C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BFDBFC7F-58D3-4816-AFA8-93265E28268C}.Release|Any CPU.Build.0 = Release|Any CPU
{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{088B4948-AE5B-45B3-A9FA-B853671CFA05} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C} {088B4948-AE5B-45B3-A9FA-B853671CFA05} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
@ -47,5 +87,10 @@ Global
{E6BCF6D7-A0B0-445D-AFE0-8F8C779FAB6B} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C} {E6BCF6D7-A0B0-445D-AFE0-8F8C779FAB6B} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{CBC83167-9806-41ED-98FA-105D38825A88} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C} {CBC83167-9806-41ED-98FA-105D38825A88} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{CC3D8269-F965-4C87-93F2-351AFEF9E3D2} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C} {CC3D8269-F965-4C87-93F2-351AFEF9E3D2} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{15754E04-2D54-4741-8FF9-93FE036CAA17} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{92727A89-5E9C-4694-896F-CF78047EF2C6} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{4C59B5B2-C140-48A7-ABFB-7581905BFDE4} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{BFDBFC7F-58D3-4816-AFA8-93265E28268C} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
{CE218FFC-52D5-4C6A-857D-5CAA649A3A2E} = {F2A0A89E-A2F9-48CF-AD38-0318B5ACD11C}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

@ -0,0 +1,31 @@
<Project>
<Import Project="usings.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
<NoWarn>$(NoWarn);CS1591;CS8618;CS1998;CS8604;CS8620;CS8600;CS8602</NoWarn>
<AbpProjectType>app</AbpProjectType>
<PublishDocumentationFiles>true</PublishDocumentationFiles>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target>
<ItemGroup>
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
</ItemGroup>
</Project>

@ -0,0 +1,3 @@
#!/bin/bash
kill -9 $(lsof -t -i:19001)
echo "Yi-进程已关闭"

@ -0,0 +1,5 @@
namespace NPin.Framework.AspNetCore.Authentication.OAuth;
public class Class1
{
}

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\NPin.Framework.AspNetCore\NPin.Framework.AspNetCore.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,14 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Builder;
using NPin.Framework.AspNetCore.Microsoft.AspNetCore.Middlewares;
namespace NPin.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
public static class ApiInfoBuilderExtensions
{
public static IApplicationBuilder UseNPinApiMiddleware([NotNull] this IApplicationBuilder app)
{
app.UseMiddleware<ApiInfoMiddleware>();
return app;
}
}

@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc;
namespace NPin.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
public static class SwaggerBuilderExtensions
{
public static IApplicationBuilder UseNPinSwagger(this IApplicationBuilder app, params SwaggerModel[] swaggerModels)
{
var mvcOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>().Value;
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var setting in mvcOptions.ConventionalControllers.ConventionalControllerSettings)
{
c.SwaggerEndpoint($"/swagger/{setting.RemoteServiceName}/swagger.json", setting.RemoteServiceName);
}
if (mvcOptions.ConventionalControllers.ConventionalControllerSettings.Count==0&&swaggerModels.Length == 0)
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Yi.Framework");
}
else
{
foreach (var k in swaggerModels)
{
c.SwaggerEndpoint(k.Url, k.Name);
}
}
});
return app;
}
}
public class SwaggerModel
{
public SwaggerModel(string name)
{
this.Name = name;
this.Url = "/swagger/v1/swagger.json";
}
public SwaggerModel(string url, string name)
{
this.Url = url;
this.Name = name;
}
public string Url { get; set; }
public string Name { get; set; }
}

@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Http;
using NPin.Framework.Core.Extensions;
using Volo.Abp.DependencyInjection;
namespace NPin.Framework.AspNetCore.Microsoft.AspNetCore.Middlewares;
public class ApiInfoMiddleware : IMiddleware, ITransientDependency
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.Response.OnStarting(() =>
{
if (context.Response.StatusCode == StatusCodes.Status200OK &&
context.Response.Headers["Content-Type"].ToString() == "application/vnd.ms-excel")
{
context.FileAttachmentHandle($"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.xlsx");
}
return Task.CompletedTask;
});
await next(context);
}
}

@ -0,0 +1,148 @@
using System.ComponentModel;
using System.Text;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Volo.Abp.AspNetCore.Mvc;
namespace NPin.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
public static class SwaggerAddExtensions
{
public static IServiceCollection AddNPinSwaggerGen<Program>(this IServiceCollection services,
Action<SwaggerGenOptions>? action = null)
{
var serviceProvider = services.BuildServiceProvider();
var mvcOptions = serviceProvider.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>();
var mvcSettings = mvcOptions.Value.ConventionalControllers.ConventionalControllerSettings
.DistinctBy(x => x.RemoteServiceName);
services.AddAbpSwaggerGen(
options =>
{
action?.Invoke(options);
// 配置分组,还需要去重,支持重写,如果外部传入后,将以外部为准
foreach (var setting in mvcSettings.OrderBy(x => x.RemoteServiceName))
{
if (!options.SwaggerGeneratorOptions.SwaggerDocs.ContainsKey(setting.RemoteServiceName))
{
options.SwaggerDoc(setting.RemoteServiceName,
new OpenApiInfo { Title = setting.RemoteServiceName, Version = "v1" });
}
}
// 根据分组名称过滤 API 文档
options.DocInclusionPredicate((docName, apiDesc) =>
{
if (apiDesc.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
var settingOrNull = mvcSettings
.FirstOrDefault(x => x.Assembly == controllerActionDescriptor.ControllerTypeInfo.Assembly);
if (settingOrNull is not null)
{
return docName == settingOrNull.RemoteServiceName;
}
}
return false;
});
options.CustomSchemaIds(type => type.FullName);
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if (basePath is not null)
{
foreach (var item in Directory.GetFiles(basePath, "*.xml"))
{
options.IncludeXmlComments(item, true);
}
}
options.AddSecurityDefinition("JWT", new OpenApiSecurityScheme
{
Description = "输入JWT-Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});
var schema = new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "JWT" }
};
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
[schema] = Array.Empty<string>()
});
options.OperationFilter<AddRequiredHeaderParameter>();
options.SchemaFilter<EnumSchemaFilter>();
});
return services;
}
}
/// <summary>
/// Swagger文档枚举字段显示枚举属性和枚举值,以及枚举描述
/// </summary>
public class EnumSchemaFilter : ISchemaFilter
{
/// <summary>
/// 实现接口
/// </summary>
/// <param name="model"></param>
/// <param name="context"></param>
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
model.Enum.Clear();
model.Type = "string";
model.Format = null;
StringBuilder stringBuilder = new StringBuilder();
Enum.GetNames(context.Type)
.ToList()
.ForEach(name =>
{
Enum e = (Enum)Enum.Parse(context.Type, name);
var descrptionOrNull = GetEnumDescription(e);
model.Enum.Add(new OpenApiString(name));
stringBuilder.Append(
$"【枚举:{name}{(descrptionOrNull is null ? string.Empty : $"({descrptionOrNull})")}={Convert.ToInt64(Enum.Parse(context.Type, name))}】<br />");
});
model.Description = stringBuilder.ToString();
}
}
private static string? GetEnumDescription(Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : null;
}
}
public class AddRequiredHeaderParameter : IOperationFilter
{
public static string HeaderKey { get; set; } = "__tenant";
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();
operation.Parameters.Add(new OpenApiParameter
{
Name = HeaderKey,
In = ParameterLocation.Header,
Required = false,
AllowEmptyValue = true,
Description = "租户id或者租户名称可空默认租户"
});
}
}

@ -0,0 +1,63 @@
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
namespace NPin.Framework.AspNetCore.Mvc;
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IConventionalRouteBuilder))]
public class NPinConventionalRouteBuilder:ConventionalRouteBuilder
{
public NPinConventionalRouteBuilder(IOptions<AbpConventionalControllerOptions> options) : base(options)
{
}
public override string Build(string rootPath, string controllerName, ActionModel action, string httpMethod,
ConventionalControllerSetting? configuration)
{
var apiRoutePrefix = GetApiRoutePrefix(action, configuration);
var controllerNameInUrl =
NormalizeUrlControllerName(rootPath, controllerName, action, httpMethod, configuration);
var url = $"{apiRoutePrefix}/{rootPath}/{NormalizeControllerNameCase(controllerNameInUrl, configuration)}";
// Add {id} path if needed
var idParameterModel = action.Parameters.FirstOrDefault(p => p.ParameterName == "id");
if (idParameterModel != null)
{
if (TypeHelper.IsPrimitiveExtended(idParameterModel.ParameterType, includeEnums: true))
{
url += "/{id}";
}
else
{
var properties =
idParameterModel.ParameterType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var property in properties)
{
url += "/{" + NormalizeIdPropertyNameCase(property, configuration) + "}";
}
}
}
// Add action name if needed
var actionNameInUrl = NormalizeUrlActionName(rootPath, controllerName, action, httpMethod, configuration);
if (!actionNameInUrl.IsNullOrEmpty())
{
url += $"/{NormalizeActionNameCase(actionNameInUrl, configuration)}";
// Add secondary Id
var secondaryIds = action.Parameters
.Where(p => p.ParameterName.EndsWith("Id", StringComparison.Ordinal)).ToList();
if (secondaryIds.Count == 1)
{
url += $"/{{{NormalizeSecondaryIdNameCase(secondaryIds[0], configuration)}}}";
}
}
return url;
}
}

@ -0,0 +1,77 @@
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
namespace NPin.Framework.AspNetCore.Mvc;
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IAbpServiceConvention))]
public class NPinServiceConvention : AbpServiceConvention
{
public NPinServiceConvention(IOptions<AbpAspNetCoreMvcOptions> options,
IConventionalRouteBuilder conventionalRouteBuilder) : base(options, conventionalRouteBuilder)
{
}
protected override void ConfigureSelector(string rootPath, string controllerName, ActionModel action,
ConventionalControllerSetting? configuration)
{
RemoveEmptySelectors(action.Selectors);
var remoteServiceAtt =
ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(action.ActionMethod);
if (remoteServiceAtt != null && !remoteServiceAtt.IsEnabledFor(action.ActionMethod))
{
return;
}
if (!action.Selectors.Any())
{
AddAbpServiceSelector(rootPath, controllerName, action, configuration);
}
else
{
NormalizeSelectorRoutes(rootPath, controllerName, action, configuration);
}
}
protected override void NormalizeSelectorRoutes(string rootPath, string controllerName, ActionModel action,
ConventionalControllerSetting? configuration)
{
foreach (var selector in action.Selectors)
{
var httpMethod = selector.ActionConstraints
.OfType<HttpMethodActionConstraint>()
.FirstOrDefault()?
.HttpMethods?
.FirstOrDefault() ?? SelectHttpMethod(action, configuration);
if (selector.AttributeRouteModel == null)
{
selector.AttributeRouteModel =
CreateAbpServiceAttributeRouteModel(rootPath, controllerName, action, httpMethod, configuration);
}
else
{
var template = selector.AttributeRouteModel.Template;
if (!template.StartsWith('/'))
{
var route = $"{AbpAspNetCoreConsts.DefaultApiPrefix}/{rootPath}/{template}";
selector.AttributeRouteModel.Template = route;
}
}
if (!selector.ActionConstraints.OfType<HttpMethodActionConstraint>().Any())
{
selector.ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
}
}
}
}

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<Compile Remove="Cors\**" />
<EmbeddedResource Remove="Cors\**" />
<None Remove="Cors\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Json" Version="8.0.0" />
<PackageReference Include="Volo.Abp.Swashbuckle" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NPin.Framework.Core\NPin.Framework.Core.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,9 @@
using NPin.Framework.Core;
using Volo.Abp.Modularity;
namespace NPin.Framework.AspNetCore;
[DependsOn(typeof(NPinFrameworkCoreModule))]
public class NPinFrameworkAspNetCoreModule : AbpModule
{
}

@ -0,0 +1,42 @@
namespace NPin.Framework.AspNetCore;
[Serializable]
public class RemoteServiceSuccessInfo
{
/// <summary>
/// code.
/// </summary>
public string? Code { get; set; }
/// <summary>
/// message.
/// </summary>
public string? Message { get; set; }
/// <summary>
/// details.
/// </summary>
public string? Details { get; set; }
/// <summary>
/// data.
/// </summary>
public object? Data { get; set; }
public RemoteServiceSuccessInfo(){}
/// <summary>
/// Creates a new instance of <see cref="RemoteServiceSuccessInfo"/>.
/// </summary>
/// <param name="code">Error code</param>
/// <param name="details">Error details</param>
/// <param name="message">Error message</param>
/// <param name="data">Error data</param>
public RemoteServiceSuccessInfo(string message, string? details = null, string? code = null, object? data = null)
{
Message = message;
Details = details;
Code = code;
Data = data;
}
}

@ -0,0 +1,10 @@
using FreeRedis;
namespace NPin.Framework.Caching.FreeRedis;
/// <summary>
/// 配置定义
/// </summary>
public class FreeSqlOptions : ConnectionStringBuilder
{
}

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<PackageReference Include="FreeRedis" Version="1.2.13" />
<PackageReference Include="FreeRedis.DistributedCache" Version="1.2.5" />
<PackageReference Include="Volo.Abp.Caching" Version="8.0.3" />
</ItemGroup>
</Project>

@ -0,0 +1,29 @@
using FreeRedis;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Caching;
using Volo.Abp.Modularity;
namespace NPin.Framework.Caching.FreeRedis;
/// <summary>
/// FreeRedis支持分布式缓存(IDistributedCache)与abp无缝斜街
/// </summary>
[DependsOn(typeof(AbpCachingModule))]
public class NPinFrameworkCachingFreeRedisModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var enabled = configuration["Redis:IsEnabled"];
if (enabled.IsNullOrEmpty() || bool.Parse(enabled))
{
var redisConfiguration = configuration["Redis:Configuration"];
var redisClient = new RedisClient(redisConfiguration);
context.Services.AddSingleton<IRedisClient>(redisClient);
context.Services.Replace(ServiceDescriptor.Singleton<IDistributedCache>(new DistributedCache(redisClient)));
}
}
}

@ -0,0 +1,99 @@
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
namespace NPin.Framework.Core.Extensions;
public static class HttpContextExtensions
{
/// <summary>
/// 设置文件下载名称
/// </summary>
/// <param name="httpContext"></param>
/// <param name="fileName"></param>
public static void FileInlineHandle(this HttpContext httpContext, string fileName)
{
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
httpContext.Response.Headers.Add("Content-Disposition", "inline;filename=" + encodeFilename);
}
/// <summary>
/// 设置文件附件名称
/// </summary>
/// <param name="httpContext"></param>
/// <param name="fileName"></param>
public static void FileAttachmentHandle(this HttpContext httpContext, string fileName)
{
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + encodeFilename);
}
/// <summary>
/// 获取语言种类
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
public static string GetLanguage(this HttpContext httpContext)
{
string res = "zh-CN";
var str = httpContext.Request.Headers["Accept-Language"].FirstOrDefault();
if (str is not null)
{
res = str.Split(",")[0];
}
return res;
}
/// <summary>
/// 判断是否为异步请求
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsAjaxRequest(this HttpRequest request)
{
string header = request.Headers["X-Requested-With"];
return "XMLHttpRequest".Equals(header);
}
/// <summary>
/// 获取客户端IP
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetClientIp(this HttpContext context)
{
if (context == null) return "";
var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (string.IsNullOrEmpty(result))
{
result = context.Connection.RemoteIpAddress?.ToString();
}
if (string.IsNullOrEmpty(result) || result.Contains("::1"))
result = "127.0.0.1";
result = result.Replace("::ffff:", "127.0.0.1");
//Ip规则效验
var regResult = Regex.IsMatch(result, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
result = regResult ? result : "127.0.0.1";
return result;
}
/// <summary>
/// 获取浏览器标识
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetUserAgent(this HttpContext context)
{
return context.Request.Headers["User-Agent"];
}
public static string[]? GetUserPermissions(this HttpContext context, string permissionsName)
{
return context.User.Claims.Where(x => x.Type == permissionsName).Select(x => x.Value).ToArray();
}
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props"/>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="Volo.Abp.Core" Version="8.0.2"/>
</ItemGroup>
</Project>

@ -0,0 +1,5 @@
namespace NPin.Framework.Ddd.Application.Contracts;
public class Class1
{
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="8.1.0-rc.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NPin.Framework.Core\NPin.Framework.Core.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,5 @@
namespace NPin.Framework.Ddd.Application;
public class Class1
{
}

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\NPin.Framework.Ddd.Application.Contracts\NPin.Framework.Ddd.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="MiniExcel" Version="1.31.3" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="8.1.0-rc.1" />
</ItemGroup>
</Project>

@ -1,10 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Mapster" Version="7.4.0" /> <PackageReference Include="Mapster" Version="7.4.0" />

@ -1,10 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.140" /> <PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.140" />

@ -1,10 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MySqlBackup.NET.MySqlConnector" Version="2.3.8" /> <PackageReference Include="MySqlBackup.NET.MySqlConnector" Version="2.3.8" />

@ -0,0 +1,5 @@
namespace module;
public class Class1
{
}

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -0,0 +1,4 @@
#!/bin/bash
./end.sh
nohup dotnet Yi.Abp.Web.dll > /dev/null 2>&1 &
echo "Yi-启动成功!"

@ -0,0 +1,6 @@
<Project>
<ItemGroup>
<Using Include="Volo.Abp" />
<Using Include="Volo.Abp.Modularity" />
</ItemGroup>
</Project>
Loading…
Cancel
Save