feat:增加swagger权限功能
parent
079cb6e313
commit
0210507de1
|
|
@ -58,6 +58,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\New_College.Common\New_College.Common.csproj" />
|
||||||
<ProjectReference Include="..\New_College.Extensions\New_College.Extensions.csproj" />
|
<ProjectReference Include="..\New_College.Extensions\New_College.Extensions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ using Essensoft.AspNetCore.Payment.Alipay;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using New_College.Common.Helper;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Text.Unicode;
|
||||||
|
|
||||||
namespace New_College
|
namespace New_College
|
||||||
{
|
{
|
||||||
|
|
@ -109,6 +113,7 @@ namespace New_College
|
||||||
services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
|
services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
|
||||||
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
|
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
|
||||||
|
|
||||||
|
|
||||||
services.AddControllers(o =>
|
services.AddControllers(o =>
|
||||||
{
|
{
|
||||||
// 全局异常过滤
|
// 全局异常过滤
|
||||||
|
|
@ -117,17 +122,40 @@ namespace New_College
|
||||||
//o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
|
//o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
|
||||||
// 全局路由前缀,统一修改路由
|
// 全局路由前缀,统一修改路由
|
||||||
o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
|
o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
|
||||||
})
|
}).AddJsonOptions(
|
||||||
//全局配置Json序列化处理
|
options =>
|
||||||
.AddNewtonsoftJson(options =>
|
|
||||||
{
|
{
|
||||||
//忽略循环引用
|
//格式化日期时间格式
|
||||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
|
||||||
//不使用驼峰样式的key
|
//数据格式首字母小写
|
||||||
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
//options.JsonSerializerOptions.PropertyNamingPolicy =JsonNamingPolicy.CamelCase;
|
||||||
//设置时间格式
|
//数据格式原样输出
|
||||||
//options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
|
options.JsonSerializerOptions.PropertyNamingPolicy = null;
|
||||||
|
//取消Unicode编码
|
||||||
|
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
|
||||||
|
//忽略空值
|
||||||
|
options.JsonSerializerOptions.IgnoreNullValues = true;
|
||||||
|
//允许额外符号
|
||||||
|
options.JsonSerializerOptions.AllowTrailingCommas = true;
|
||||||
|
//反序列化过程中属性名称是否使用不区分大小写的比较
|
||||||
|
options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
|
||||||
|
|
||||||
|
////忽略循环引用
|
||||||
|
//options.JsonSerializerOptions.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||||
|
////不使用驼峰样式的key
|
||||||
|
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||||
|
////设置时间格式
|
||||||
|
//options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
////忽略Model中为null的属性
|
||||||
|
////options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||||
|
////设置本地时间而非UTC时间
|
||||||
|
//options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
|
||||||
|
////添加Enum转string
|
||||||
|
//options.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||||
|
////将long类型转为string
|
||||||
|
//options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64));
|
||||||
});
|
});
|
||||||
|
//全局配置Json序列化处理
|
||||||
|
|
||||||
_services = services;
|
_services = services;
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +192,7 @@ namespace New_College
|
||||||
// 强制实施 HTTPS 在 ASP.NET Core,配合 app.UseHttpsRedirection
|
// 强制实施 HTTPS 在 ASP.NET Core,配合 app.UseHttpsRedirection
|
||||||
//app.UseHsts();
|
//app.UseHsts();
|
||||||
}
|
}
|
||||||
|
app.UseSwaggerAuthorized();
|
||||||
// 封装Swagger展示
|
// 封装Swagger展示
|
||||||
app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("New_College.Api.index.html"));
|
app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("New_College.Api.index.html"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
"Name": "New_College"
|
"Name": "New_College"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"urls": "http://*:8083", // IIS 部署,注释掉
|
"urls": "http://*:8082", // IIS 部署,注释掉
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"AppSettings": {
|
"AppSettings": {
|
||||||
"RedisCachingAOP": {
|
"RedisCachingAOP": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
[{"CodeRelationship":"0,","Name":"BCVP开发社区","Leader":"老张的哲学","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:47:25","ModifyTime":"2022-04-01 15:47:25","hasChildren":true,"Pid":0,"Id":1},{"CodeRelationship":"0,","Name":"DDD思想社区组织","Leader":"DDD","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:48:08","ModifyTime":"2022-04-01 15:48:08","hasChildren":true,"Pid":0,"Id":2},{"CodeRelationship":"0,1,","Name":"BCVP-北京分部","Leader":"北京","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:48:41","ModifyTime":"2022-04-01 15:48:41","hasChildren":true,"Pid":1,"Id":3},{"CodeRelationship":"0,1,","Name":"BCVP-上海分部","Leader":"上海","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:49:27","ModifyTime":"2022-04-01 15:49:27","hasChildren":true,"Pid":1,"Id":4},{"CodeRelationship":"0,1,","Name":"BCVP-广州分部","Leader":"广州","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:50:23","ModifyTime":"2022-04-01 15:50:44","hasChildren":true,"Pid":1,"Id":5},{"CodeRelationship":"0,1,3,","Name":"前端小组(1群)","Leader":"--","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:51:43","ModifyTime":"2022-04-01 15:51:43","hasChildren":true,"Pid":3,"Id":6},{"CodeRelationship":"0,1,4,","Name":"后端小组(2群)","Leader":"--","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 15:58:13","ModifyTime":"2022-04-01 15:58:13","hasChildren":true,"Pid":4,"Id":7},{"CodeRelationship":"0,","Name":"VUE学习联盟","Leader":"vue","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 16:14:21","ModifyTime":"2022-04-01 16:14:21","hasChildren":true,"Pid":0,"Id":8},{"CodeRelationship":"0,8,","Name":"ES指导(1组)","Leader":"es","OrderSort":0,"Status":true,"IsDeleted":false,"CreateBy":"老张的哲学","CreateTime":"2022-04-01 16:14:47","ModifyTime":"2022-04-01 16:15:00","hasChildren":true,"Pid":8,"Id":9}]
|
||||||
|
Can't render this file because it contains an unexpected character in line 1 and column 3.
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using New_College.Common.Helper;
|
||||||
|
using New_College.Common.HttpContextUser;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace New_College.Common;
|
||||||
|
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
static App()
|
||||||
|
{
|
||||||
|
EffectiveTypes = Assemblies.SelectMany(GetTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool _isRun;
|
||||||
|
|
||||||
|
/// <summary>是否正在运行</summary>
|
||||||
|
public static bool IsBuild { get; set; }
|
||||||
|
|
||||||
|
public static bool IsRun
|
||||||
|
{
|
||||||
|
get => _isRun;
|
||||||
|
set => _isRun = IsBuild = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>应用有效程序集</summary>
|
||||||
|
public static readonly IEnumerable<Assembly> Assemblies = RuntimeExtension.GetAllAssemblies();
|
||||||
|
|
||||||
|
/// <summary>有效程序集类型</summary>
|
||||||
|
public static readonly IEnumerable<Type> EffectiveTypes;
|
||||||
|
|
||||||
|
/// <summary>优先使用App.GetService()手动获取服务</summary>
|
||||||
|
public static IServiceProvider RootServices => IsRun || IsBuild ? InternalApp.RootServices : null;
|
||||||
|
|
||||||
|
/// <summary>获取Web主机环境,如,是否是开发环境,生产环境等</summary>
|
||||||
|
public static IWebHostEnvironment WebHostEnvironment => InternalApp.WebHostEnvironment;
|
||||||
|
|
||||||
|
/// <summary>获取泛型主机环境,如,是否是开发环境,生产环境等</summary>
|
||||||
|
public static IHostEnvironment HostEnvironment => InternalApp.HostEnvironment;
|
||||||
|
|
||||||
|
/// <summary>全局配置选项</summary>
|
||||||
|
public static IConfiguration Configuration => InternalApp.Configuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取请求上下文
|
||||||
|
/// </summary>
|
||||||
|
public static HttpContext HttpContext => RootServices?.GetService<IHttpContextAccessor>()?.HttpContext;
|
||||||
|
|
||||||
|
public static IUser User => GetService<IUser>();
|
||||||
|
|
||||||
|
#region Service
|
||||||
|
|
||||||
|
/// <summary>解析服务提供器</summary>
|
||||||
|
/// <param name="serviceType"></param>
|
||||||
|
/// <param name="mustBuild"></param>
|
||||||
|
/// <param name="throwException"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceProvider GetServiceProvider(Type serviceType, bool mustBuild = false, bool throwException = true)
|
||||||
|
{
|
||||||
|
if (App.HostEnvironment == null || App.RootServices != null &&
|
||||||
|
InternalApp.InternalServices
|
||||||
|
.Where((u =>
|
||||||
|
u.ServiceType ==
|
||||||
|
(serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType)))
|
||||||
|
.Any((u => u.Lifetime == ServiceLifetime.Singleton)))
|
||||||
|
return App.RootServices;
|
||||||
|
|
||||||
|
//获取请求生存周期的服务
|
||||||
|
if (HttpContext?.RequestServices != null)
|
||||||
|
return HttpContext.RequestServices;
|
||||||
|
|
||||||
|
if (App.RootServices != null)
|
||||||
|
{
|
||||||
|
IServiceScope scope = RootServices.CreateScope();
|
||||||
|
return scope.ServiceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mustBuild)
|
||||||
|
{
|
||||||
|
if (throwException)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("当前不可用,必须要等到 WebApplication Build后");
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceProvider serviceProvider = InternalApp.InternalServices.BuildServiceProvider();
|
||||||
|
return serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TService GetService<TService>(bool mustBuild = true) where TService : class =>
|
||||||
|
App.GetService(typeof(TService), null, mustBuild) as TService;
|
||||||
|
|
||||||
|
/// <summary>获取请求生存周期的服务</summary>
|
||||||
|
/// <typeparam name="TService"></typeparam>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <param name="mustBuild"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static TService GetService<TService>(IServiceProvider serviceProvider, bool mustBuild = true)
|
||||||
|
where TService : class => (serviceProvider ?? App.GetServiceProvider(typeof(TService), mustBuild, false))?.GetService<TService>();
|
||||||
|
|
||||||
|
/// <summary>获取请求生存周期的服务</summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <param name="mustBuild"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object GetService(Type type, IServiceProvider serviceProvider = null, bool mustBuild = true) =>
|
||||||
|
(serviceProvider ?? App.GetServiceProvider(type, mustBuild, false))?.GetService(type);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region private
|
||||||
|
|
||||||
|
/// <summary>加载程序集中的所有类型</summary>
|
||||||
|
/// <param name="ass"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<Type> GetTypes(Assembly ass)
|
||||||
|
{
|
||||||
|
Type[] source = Array.Empty<Type>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
source = ass.GetTypes();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$@"Error load `{ass.FullName}` assembly.".WriteErrorLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return source.Where(u => u.IsPublic);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Options
|
||||||
|
|
||||||
|
/// <summary>获取配置</summary>
|
||||||
|
/// <typeparam name="TOptions">强类型选项类</typeparam>
|
||||||
|
/// <returns>TOptions</returns>
|
||||||
|
public static TOptions GetConfig<TOptions>()
|
||||||
|
where TOptions : class, IConfigurableOptions
|
||||||
|
{
|
||||||
|
TOptions instance = App.Configuration
|
||||||
|
.GetSection(ConfigurableOptions.GetConfigurationPath(typeof(TOptions)))
|
||||||
|
.Get<TOptions>();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>获取选项</summary>
|
||||||
|
/// <typeparam name="TOptions">强类型选项类</typeparam>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <returns>TOptions</returns>
|
||||||
|
public static TOptions GetOptions<TOptions>(IServiceProvider serviceProvider = null) where TOptions : class, new()
|
||||||
|
{
|
||||||
|
IOptions<TOptions> service = App.GetService<IOptions<TOptions>>(serviceProvider ?? App.RootServices, false);
|
||||||
|
return service?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>获取选项</summary>
|
||||||
|
/// <typeparam name="TOptions">强类型选项类</typeparam>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <returns>TOptions</returns>
|
||||||
|
public static TOptions GetOptionsMonitor<TOptions>(IServiceProvider serviceProvider = null)
|
||||||
|
where TOptions : class, new()
|
||||||
|
{
|
||||||
|
IOptionsMonitor<TOptions> service =
|
||||||
|
App.GetService<IOptionsMonitor<TOptions>>(serviceProvider ?? App.RootServices, false);
|
||||||
|
return service?.CurrentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>获取选项</summary>
|
||||||
|
/// <typeparam name="TOptions">强类型选项类</typeparam>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <returns>TOptions</returns>
|
||||||
|
public static TOptions GetOptionsSnapshot<TOptions>(IServiceProvider serviceProvider = null)
|
||||||
|
where TOptions : class, new()
|
||||||
|
{
|
||||||
|
IOptionsSnapshot<TOptions> service = App.GetService<IOptionsSnapshot<TOptions>>(serviceProvider, false);
|
||||||
|
return service?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace New_College.Common;
|
||||||
|
|
||||||
|
public static class ConfigurableOptions
|
||||||
|
{
|
||||||
|
/// <summary>添加选项配置</summary>
|
||||||
|
/// <typeparam name="TOptions">选项类型</typeparam>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddConfigurableOptions<TOptions>(this IServiceCollection services)
|
||||||
|
where TOptions : class, IConfigurableOptions
|
||||||
|
{
|
||||||
|
Type optionsType = typeof(TOptions);
|
||||||
|
string path = GetConfigurationPath(optionsType);
|
||||||
|
services.Configure<TOptions>(App.Configuration.GetSection(path));
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddConfigurableOptions(this IServiceCollection services, Type type)
|
||||||
|
{
|
||||||
|
string path = GetConfigurationPath(type);
|
||||||
|
var config = App.Configuration.GetSection(path);
|
||||||
|
|
||||||
|
Type iOptionsChangeTokenSource = typeof(IOptionsChangeTokenSource<>);
|
||||||
|
Type iConfigureOptions = typeof(IConfigureOptions<>);
|
||||||
|
Type configurationChangeTokenSource = typeof(ConfigurationChangeTokenSource<>);
|
||||||
|
Type namedConfigureFromConfigurationOptions = typeof(NamedConfigureFromConfigurationOptions<>);
|
||||||
|
iOptionsChangeTokenSource = iOptionsChangeTokenSource.MakeGenericType(type);
|
||||||
|
iConfigureOptions = iConfigureOptions.MakeGenericType(type);
|
||||||
|
configurationChangeTokenSource = configurationChangeTokenSource.MakeGenericType(type);
|
||||||
|
namedConfigureFromConfigurationOptions = namedConfigureFromConfigurationOptions.MakeGenericType(type);
|
||||||
|
|
||||||
|
services.AddOptions();
|
||||||
|
services.AddSingleton(iOptionsChangeTokenSource,
|
||||||
|
Activator.CreateInstance(configurationChangeTokenSource, Options.DefaultName, config) ?? throw new InvalidOperationException());
|
||||||
|
return services.AddSingleton(iConfigureOptions,
|
||||||
|
Activator.CreateInstance(namedConfigureFromConfigurationOptions, Options.DefaultName, config) ?? throw new InvalidOperationException());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>获取配置路径</summary>
|
||||||
|
/// <param name="optionsType">选项类型</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetConfigurationPath(Type optionsType)
|
||||||
|
{
|
||||||
|
var endPath = new[] {"Option", "Options"};
|
||||||
|
var configurationPath = optionsType.Name;
|
||||||
|
foreach (var s in endPath)
|
||||||
|
{
|
||||||
|
if (configurationPath.EndsWith(s))
|
||||||
|
{
|
||||||
|
return configurationPath[..^s.Length];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configurationPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace New_College.Common;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 应用选项依赖接口 <br/>
|
||||||
|
/// 自动注入配置文件 <br/>
|
||||||
|
/// 文件名为Option或Options结尾
|
||||||
|
/// </summary>
|
||||||
|
public interface IConfigurableOptions
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,14 @@
|
||||||
/// true:表示启动IDS4
|
/// true:表示启动IDS4
|
||||||
/// false:表示使用JWT
|
/// false:表示使用JWT
|
||||||
public static bool IsUseIds4 = false;
|
public static bool IsUseIds4 = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前项目是否启用Authing权限方案
|
||||||
|
/// true:表示启动
|
||||||
|
/// false:表示使用JWT
|
||||||
|
public static bool IsUseAuthing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -24,6 +32,6 @@
|
||||||
/// 如果不需要,尽量留空,不要修改
|
/// 如果不需要,尽量留空,不要修改
|
||||||
/// 除非一定要在所有的 api 前统一加上特定前缀
|
/// 除非一定要在所有的 api 前统一加上特定前缀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string Name = "";
|
public static string Name = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace New_College.Common.Helper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 格式化返回的时间格式
|
||||||
|
/// </summary>
|
||||||
|
public class DatetimeJsonConverter : JsonConverter<DateTime>
|
||||||
|
{
|
||||||
|
private readonly string format;
|
||||||
|
public DatetimeJsonConverter(string _format)
|
||||||
|
{
|
||||||
|
format = _format;
|
||||||
|
}
|
||||||
|
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse(reader.GetString(), out DateTime date))
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
return reader.GetDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value.ToString(format));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,19 @@ using Newtonsoft.Json.Converters;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace New_College.Common.Helper
|
namespace New_College.Common.Helper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class JsonHelper
|
public class JsonHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Json 序列化配置
|
/// Json 序列化配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace New_College.Common.Helper
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <summary>
|
||||||
|
/// 大数据json序列化重写
|
||||||
|
/// </summary>
|
||||||
|
public sealed class NumberConverter : JsonConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 转换成字符串的类型
|
||||||
|
/// </summary>
|
||||||
|
private readonly NumberConverterShip _ship;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 大数据json序列化重写实例化
|
||||||
|
/// </summary>
|
||||||
|
public NumberConverter()
|
||||||
|
{
|
||||||
|
_ship = (NumberConverterShip)0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 大数据json序列化重写实例化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ship">转换成字符串的类型</param>
|
||||||
|
public NumberConverter(NumberConverterShip ship)
|
||||||
|
{
|
||||||
|
_ship = ship;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <summary>
|
||||||
|
/// 确定此实例是否可以转换指定的对象类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectType">对象的类型。</param>
|
||||||
|
/// <returns>如果此实例可以转换指定的对象类型,则为:<c>true</c>,否则为:<c>false</c></returns>
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
var typecode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ? objectType.GetGenericArguments().First() : objectType);
|
||||||
|
switch (typecode)
|
||||||
|
{
|
||||||
|
case TypeCode.Decimal:
|
||||||
|
return (_ship & NumberConverterShip.Decimal) == NumberConverterShip.Decimal;
|
||||||
|
case TypeCode.Double:
|
||||||
|
return (_ship & NumberConverterShip.Double) == NumberConverterShip.Double;
|
||||||
|
case TypeCode.Int64:
|
||||||
|
return (_ship & NumberConverterShip.Int64) == NumberConverterShip.Int64;
|
||||||
|
case TypeCode.UInt64:
|
||||||
|
return (_ship & NumberConverterShip.UInt64) == NumberConverterShip.UInt64;
|
||||||
|
case TypeCode.Single:
|
||||||
|
return (_ship & NumberConverterShip.Single) == NumberConverterShip.Single;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <summary>
|
||||||
|
/// 读取对象的JSON表示。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader">从 <see cref="T:Newtonsoft.Json.JsonReader" /> 中读取。</param>
|
||||||
|
/// <param name="objectType">对象的类型。</param>
|
||||||
|
/// <param name="existingValue">正在读取的对象的现有值。</param>
|
||||||
|
/// <param name="serializer">调用的序列化器实例。</param>
|
||||||
|
/// <returns>对象值。</returns>
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
return AsType(reader.Value.ObjToString(), objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字符串格式数据转其他类型数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">输入的字符串</param>
|
||||||
|
/// <param name="destinationType">目标格式</param>
|
||||||
|
/// <returns>转换结果</returns>
|
||||||
|
public static object AsType(string input, Type destinationType)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var converter = TypeDescriptor.GetConverter(destinationType);
|
||||||
|
if (converter.CanConvertFrom(typeof(string)))
|
||||||
|
{
|
||||||
|
return converter.ConvertFrom(null, null, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
converter = TypeDescriptor.GetConverter(typeof(string));
|
||||||
|
if (converter.CanConvertTo(destinationType))
|
||||||
|
{
|
||||||
|
return converter.ConvertTo(null, null, input, destinationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <summary>
|
||||||
|
/// 写入对象的JSON表示形式。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writer">要写入的 <see cref="T:Newtonsoft.Json.JsonWriter" /> 。</param>
|
||||||
|
/// <param name="value">要写入对象值</param>
|
||||||
|
/// <param name="serializer">调用的序列化器实例。</param>
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var objectType = value.GetType();
|
||||||
|
var typeCode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ? objectType.GetGenericArguments().First() : objectType);
|
||||||
|
switch (typeCode)
|
||||||
|
{
|
||||||
|
case TypeCode.Decimal:
|
||||||
|
writer.WriteValue(((decimal)value).ToString("f6"));
|
||||||
|
break;
|
||||||
|
case TypeCode.Double:
|
||||||
|
writer.WriteValue(((double)value).ToString("f4"));
|
||||||
|
break;
|
||||||
|
case TypeCode.Single:
|
||||||
|
writer.WriteValue(((float)value).ToString("f2"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
writer.WriteValue(value.ToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换成字符串的类型
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum NumberConverterShip
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 长整数
|
||||||
|
/// </summary>
|
||||||
|
Int64 = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 无符号长整数
|
||||||
|
/// </summary>
|
||||||
|
UInt64 = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 浮点数
|
||||||
|
/// </summary>
|
||||||
|
Single = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 双精度浮点数
|
||||||
|
/// </summary>
|
||||||
|
Double = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 大数字
|
||||||
|
/// </summary>
|
||||||
|
Decimal =16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace New_College.Extensions;
|
||||||
|
|
||||||
|
public static class HttpContextExtension
|
||||||
|
{
|
||||||
|
public static ISession GetSession(this HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return context.Session;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace New_College;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 内部只用于初始化使用
|
||||||
|
/// </summary>
|
||||||
|
public static class InternalApp
|
||||||
|
{
|
||||||
|
internal static IServiceCollection InternalServices;
|
||||||
|
|
||||||
|
/// <summary>根服务</summary>
|
||||||
|
internal static IServiceProvider RootServices;
|
||||||
|
|
||||||
|
/// <summary>获取Web主机环境</summary>
|
||||||
|
internal static IWebHostEnvironment WebHostEnvironment;
|
||||||
|
|
||||||
|
/// <summary>获取泛型主机环境</summary>
|
||||||
|
internal static IHostEnvironment HostEnvironment;
|
||||||
|
|
||||||
|
/// <summary>配置对象</summary>
|
||||||
|
internal static IConfiguration Configuration;
|
||||||
|
|
||||||
|
public static void ConfigureApplication(this WebApplicationBuilder wab)
|
||||||
|
{
|
||||||
|
HostEnvironment = wab.Environment;
|
||||||
|
WebHostEnvironment = wab.Environment;
|
||||||
|
InternalServices = wab.Services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConfigureApplication(this IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConfigureApplication(this IHost app)
|
||||||
|
{
|
||||||
|
RootServices = app.Services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
using Microsoft.Extensions.DependencyModel;
|
||||||
|
using Serilog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
|
||||||
|
namespace New_College;
|
||||||
|
|
||||||
|
public static class RuntimeExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IList<Assembly> GetAllAssemblies()
|
||||||
|
{
|
||||||
|
var list = new List<Assembly>();
|
||||||
|
var deps = DependencyContext.Default;
|
||||||
|
//只加载项目中的程序集
|
||||||
|
var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type == "project"); //排除所有的系统程序集、Nuget下载包
|
||||||
|
foreach (var lib in libs)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
|
||||||
|
list.Add(assembly);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Debug(e, "GetAllAssemblies Exception:{ex}", e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Assembly GetAssembly(string assemblyName)
|
||||||
|
{
|
||||||
|
return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<Type> GetAllTypes()
|
||||||
|
{
|
||||||
|
var list = new List<Type>();
|
||||||
|
foreach (var assembly in GetAllAssemblies())
|
||||||
|
{
|
||||||
|
var typeInfos = assembly.DefinedTypes;
|
||||||
|
foreach (var typeInfo in typeInfos)
|
||||||
|
{
|
||||||
|
list.Add(typeInfo.AsType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<Type> GetTypesByAssembly(string assemblyName)
|
||||||
|
{
|
||||||
|
var list = new List<Type>();
|
||||||
|
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
|
||||||
|
var typeInfos = assembly.DefinedTypes;
|
||||||
|
foreach (var typeInfo in typeInfos)
|
||||||
|
{
|
||||||
|
list.Add(typeInfo.AsType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type GetImplementType(string typeName, Type baseInterfaceType)
|
||||||
|
{
|
||||||
|
return GetAllTypes().FirstOrDefault(t =>
|
||||||
|
{
|
||||||
|
if (t.Name == typeName &&
|
||||||
|
t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
|
||||||
|
{
|
||||||
|
var typeInfo = t.GetTypeInfo();
|
||||||
|
return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace New_College.Common
|
||||||
|
{
|
||||||
|
public class SwaggerAuthMiddleware
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly RequestDelegate next;
|
||||||
|
|
||||||
|
public SwaggerAuthMiddleware(RequestDelegate next)
|
||||||
|
{
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
// 也可以根据是否是本地做判断 IsLocalRequest
|
||||||
|
if (context.Request.Path.Value.ToLower().Contains("index.html"))
|
||||||
|
{
|
||||||
|
// 判断权限是否正确
|
||||||
|
if (IsAuthorized(context))
|
||||||
|
{
|
||||||
|
await next.Invoke(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无权限,跳转swagger登录页
|
||||||
|
// context.RedirectSwaggerLogin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await next.Invoke(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAuthorized(HttpContext context)
|
||||||
|
{
|
||||||
|
//使用session模式
|
||||||
|
//可以使用其他的
|
||||||
|
return context.IsSuccessSwagger();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断是不是本地访问
|
||||||
|
/// 本地不用swagger拦截
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsLocalRequest(HttpContext context)
|
||||||
|
{
|
||||||
|
if (context.Connection.RemoteIpAddress == null && context.Connection.LocalIpAddress == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class SwaggerAuthorizeExtensions
|
||||||
|
{
|
||||||
|
public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<SwaggerAuthMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
using New_College.Extensions;
|
||||||
|
|
||||||
|
namespace New_College.Common;
|
||||||
|
public static class SwaggerContextExtension
|
||||||
|
{
|
||||||
|
public const string SwaggerCodeKey = "swagger-code";
|
||||||
|
public const string SwaggerJwt = "swagger-jwt";
|
||||||
|
|
||||||
|
public static bool IsSuccessSwagger()
|
||||||
|
{
|
||||||
|
return App.HttpContext?.GetSession()?.GetString(SwaggerCodeKey) == "success";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsSuccessSwagger(this HttpContext context)
|
||||||
|
{
|
||||||
|
return context.GetSession()?.GetString(SwaggerCodeKey) == "success";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SuccessSwagger()
|
||||||
|
{
|
||||||
|
App.HttpContext?.GetSession()?.SetString(SwaggerCodeKey, "success");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SuccessSwagger(this HttpContext context)
|
||||||
|
{
|
||||||
|
context.GetSession()?.SetString(SwaggerCodeKey, "success");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SuccessSwaggerJwt(this HttpContext context, string token)
|
||||||
|
{
|
||||||
|
context.GetSession()?.SetString(SwaggerJwt, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetSuccessSwaggerJwt(this HttpContext context)
|
||||||
|
{
|
||||||
|
return context.GetSession()?.GetString(SwaggerJwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RedirectSwaggerLogin(this HttpContext context)
|
||||||
|
{
|
||||||
|
var returnUrl = context.Request.GetDisplayUrl(); //获取当前url地址
|
||||||
|
context.Response.Redirect("/swg-login.html?returnUrl=" + returnUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,8 +15,9 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="3.1.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="3.1.0" />
|
||||||
<PackageReference Include="MiniProfiler.AspNetCore.Mvc" Version="4.1.0" />
|
<PackageReference Include="MiniProfiler.AspNetCore.Mvc" Version="4.1.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.3" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="5.1.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.5" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using New_College.Common;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace New_College.ServiceExtensions;
|
||||||
|
|
||||||
|
public static class AllOptionRegister
|
||||||
|
{
|
||||||
|
public static void AddAllOptionRegister(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||||
|
|
||||||
|
foreach (var optionType in App.EffectiveTypes.Where(s =>
|
||||||
|
!s.IsInterface && typeof(IConfigurableOptions).IsAssignableFrom(s)))
|
||||||
|
{
|
||||||
|
services.AddConfigurableOptions(optionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace New_College.Extensions;
|
||||||
|
|
||||||
|
public static class HttpContextExtension
|
||||||
|
{
|
||||||
|
public static ISession GetSession(this HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return context.Session;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -106,6 +106,7 @@ namespace New_College.Extensions
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
// services.AddSwaggerGenNewtonsoftSupport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
namespace New_College.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将前端UI压缩文件进行解压
|
||||||
|
/// </summary>
|
||||||
|
public static class UiFilesZipSetup
|
||||||
|
{
|
||||||
|
public static void AddUiFilesZipSetup(this IServiceCollection services, IWebHostEnvironment _env)
|
||||||
|
{
|
||||||
|
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||||
|
|
||||||
|
string wwwrootFolderPath = Path.Combine(_env.ContentRootPath, "wwwroot");
|
||||||
|
string zipUiItemFiles = Path.Combine(wwwrootFolderPath, "ui.zip");
|
||||||
|
if (!File.Exists(Path.Combine(wwwrootFolderPath, "ui", "index.html")))
|
||||||
|
{
|
||||||
|
ZipFile.ExtractToDirectory(zipUiItemFiles, wwwrootFolderPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ namespace New_College.Model.ViewModels
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string Code { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class uniMajorClassSelect
|
public class uniMajorClassSelect
|
||||||
|
|
@ -17,6 +18,8 @@ namespace New_College.Model.ViewModels
|
||||||
public int TradeId { get; set; }
|
public int TradeId { get; set; }
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Code { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace New_College.Repository
|
||||||
var response = await this.Db.Queryable<D_UniversityRank, D_University>((rank, u) => new object[] { JoinType.Left, rank.UniversityName == u.Name })
|
var response = await this.Db.Queryable<D_UniversityRank, D_University>((rank, u) => new object[] { JoinType.Left, rank.UniversityName == u.Name })
|
||||||
.Where((rank, u) => rank.UniversityType == query.Type)
|
.Where((rank, u) => rank.UniversityType == query.Type)
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(query.Name), (rank, u) => SqlFunc.Contains(rank.UniversityName, query.Name))
|
.WhereIF(!string.IsNullOrWhiteSpace(query.Name), (rank, u) => SqlFunc.Contains(rank.UniversityName, query.Name))
|
||||||
.WhereIF(query.SubjectType.HasValue, (rank, u) => u.Subject_Level == query.SubjectType)
|
.WhereIF(query.SubjectType.HasValue, (rank, u) => u.Type == query.SubjectType)
|
||||||
.OrderBy((rank, u) => rank.Rank, OrderByType.Asc)
|
.OrderBy((rank, u) => rank.Rank, OrderByType.Asc)
|
||||||
.Select((rank, u) => new UniversityPcRankList
|
.Select((rank, u) => new UniversityPcRankList
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ namespace New_College.Services
|
||||||
{
|
{
|
||||||
var result = new List<TreeMajorInfoResult>();
|
var result = new List<TreeMajorInfoResult>();
|
||||||
var classmajors = (await d_MajorClassRepository.Query(x => x.IsDelete == false && x.TradeId == tradeId)).Select(x => new uniMajorClassSelect() { Id = x.Id, Name = x.Name, TradeId = x.TradeId }).ToList();
|
var classmajors = (await d_MajorClassRepository.Query(x => x.IsDelete == false && x.TradeId == tradeId)).Select(x => new uniMajorClassSelect() { Id = x.Id, Name = x.Name, TradeId = x.TradeId }).ToList();
|
||||||
var majorinfo = (await d_MajorRepository.Query(x => x.IsDelete == false)).Select(s => new uniMajorClassSelect() { Id = s.Id, TradeId = s.CategoryClass_Id, Name = s.Name }).ToList();
|
var majorinfo = (await d_MajorRepository.Query(x => x.IsDelete == false)).Select(s => new uniMajorClassSelect() { Id = s.Id, TradeId = s.CategoryClass_Id, Name = s.Name,Code=s.MajorCode }).ToList();
|
||||||
classmajors.ForEach(a =>
|
classmajors.ForEach(a =>
|
||||||
{
|
{
|
||||||
var models = new TreeMajorInfoResult();
|
var models = new TreeMajorInfoResult();
|
||||||
|
|
@ -229,7 +229,8 @@ namespace New_College.Services
|
||||||
models.MajorsInfo = majorinfo.Where(e => e.TradeId == a.Id).Select(s => new uniMajorSelect()
|
models.MajorsInfo = majorinfo.Where(e => e.TradeId == a.Id).Select(s => new uniMajorSelect()
|
||||||
{
|
{
|
||||||
Id = s.Id,
|
Id = s.Id,
|
||||||
Name = s.Name
|
Name = s.Name,
|
||||||
|
Code=s.Code
|
||||||
}).ToList();
|
}).ToList();
|
||||||
result.Add(models);
|
result.Add(models);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue