feat: 将数据库结构同步和种子数据初始化作为命令行开关 (#78)

This commit is contained in:
nsnail 2024-01-05 16:08:50 +08:00 committed by GitHub
parent 22628e79ca
commit 05ed3d3746
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 57 deletions

View File

@ -4,4 +4,4 @@ EXPOSE 8080
RUN apt update
RUN apt install -y redis
COPY ./dist/backend/NetAdmin.BizServer.Host/bin/Release/net8.0/publish .
ENTRYPOINT redis-server --daemonize yes && dotnet NetAdmin.BizServer.Host.dll
ENTRYPOINT redis-server --daemonize yes && dotnet NetAdmin.BizServer.Host.dll -is

View File

@ -42,7 +42,7 @@ docker run -p 8080:8080 nsnail/netadmin
```
4. 运行后端WebApi
``` shell
dotnet run --project ./src/backend/NetAdmin.BizServer.Host/NetAdmin.BizServer.Host.csproj --urls http://[::]:5010
dotnet run --project ./src/backend/NetAdmin.BizServer.Host/NetAdmin.BizServer.Host.csproj --urls http://[::]:5010 -is
```
5. 体验WebApi程序
- 浏览器打开 http://localhost:5010 将看到SwaggerKnife4jUI界面

View File

@ -0,0 +1,21 @@
using Spectre.Console.Cli;
namespace NetAdmin.BizServer.Host;
/// <summary>
/// 命令行参数
/// </summary>
public sealed class CommandLineArgs : CommandSettings
{
/// <summary>
/// 插入种子数据
/// </summary>
[CommandOption("-i|--insert-seed-data")]
public bool InsertSeedData { get; set; }
/// <summary>
/// 同步数据库结构
/// </summary>
[CommandOption("-s|--sync-structure")]
public bool SyncStructure { get; set; }
}

View File

@ -15,10 +15,11 @@ public static class ServiceCollectionExtensions
/// <summary>
/// 添加 FreeSql
/// </summary>
public static IServiceCollection AddFreeSql(this IServiceCollection me)
public static IServiceCollection AddFreeSqlWithArgs(this IServiceCollection me)
{
return me.AddFreeSql( //
FreeSqlInitMethods.SyncStructure | FreeSqlInitMethods.InsertSeedData, freeSql => {
(Startup.Args.SyncStructure ? FreeSqlInitMethods.SyncStructure : FreeSqlInitMethods.None) |
(Startup.Args.InsertSeedData ? FreeSqlInitMethods.InsertSeedData : FreeSqlInitMethods.None), freeSql => {
// 数据权限过滤器
_ = freeSql.GlobalFilter.ApplyOnlyIf<IFieldOwner>( //
Chars.FLG_GLOBAL_FILTER_DATA

View File

@ -10,6 +10,14 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"InitDB": {
"commandName": "Project",
"dotnetRunMessages": true,
"commandLineArgs": "-is",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -1,71 +1,97 @@
using NetAdmin.BizServer.Host;
using NetAdmin.BizServer.Host.Extensions;
using NetAdmin.Host.Extensions;
using NetAdmin.Host.Middlewares;
using Spectre.Console.Cli;
using ValidationResult = Spectre.Console.ValidationResult;
#if !DEBUG
using Prometheus;
#endif
namespace NetAdmin.BizServer.Host;
NetAdmin.Host.Startup.Entry<Startup>(args);
/// <summary>
/// 启动类
/// </summary>
public sealed class Startup : NetAdmin.Host.Startup
namespace NetAdmin.BizServer.Host
{
/// <summary>
/// 程序入口
/// 启动类
/// </summary>
public static void Main(string[] args)
public sealed class Startup : NetAdmin.Host.Startup, ICommand<CommandLineArgs>
{
ShowBanner();
_ = Serve.Run(RunOptions.Default.WithArgs(args));
}
/// <summary>
/// 命令行参数
/// </summary>
public static CommandLineArgs Args { get; private set; }
/// <summary>
/// 配置应用程序中间件
/// </summary>
public void Configure(IApplicationBuilder app)
{
_ = app //
.UseRealIp() // 使用RealIp中间件用于获取真实客户端IP地址
.EnableBuffering() // 启用请求体缓冲,允许多次读取请求体
.UseMiddleware<RequestAuditMiddleware>() // 使用RequestAuditMiddleware中间件执行请求审计
#if DEBUG
.UseOpenApiSkin() // 使用OpenApiSkin中间件仅在调试模式下提供Swagger UI皮肤
#else
/// <summary>
/// 配置应用程序中间件
/// </summary>
public void Configure(IApplicationBuilder app)
{
_ = app //
.UseRealIp() // 使用RealIp中间件用于获取真实客户端IP地址
.EnableBuffering() // 启用请求体缓冲,允许多次读取请求体
.UseMiddleware<RequestAuditMiddleware>() // 使用RequestAuditMiddleware中间件执行请求审计
#if DEBUG
.UseOpenApiSkin() // 使用OpenApiSkin中间件仅在调试模式下提供Swagger UI皮肤
#else
.UseVueAdmin() // 托管管理后台,仅在非调试模式下
.UseHttpMetrics() // 使用HttpMetrics中间件启用HTTP性能监控
#endif
.UseInject(string.Empty) // 使用Inject中间件Furion脚手架的依赖注入支持
.UseUnifyResultStatusCodes() // 使用UnifyResultStatusCodes中间件用于统一处理结果状态码
.UseCorsAccessor() // 使用CorsAccessor中间件启用跨域资源共享CORS支持
.UseRouting() // 使用Routing中间件配置路由映射
.UseAuthentication() // 使用Authentication中间件启用身份验证
.UseAuthorization() // 使用Authorization中间件启用授权
.UseMiddleware<RemoveNullNodeMiddleware>() // 使用RemoveNullNodeMiddleware中间件删除JSON中的空节点
.UseEndpoints(); // 配置端点以处理请求
}
#endif
.UseInject(string.Empty) // 使用Inject中间件Furion脚手架的依赖注入支持
.UseUnifyResultStatusCodes() // 使用UnifyResultStatusCodes中间件用于统一处理结果状态码
.UseCorsAccessor() // 使用CorsAccessor中间件启用跨域资源共享CORS支持
.UseRouting() // 使用Routing中间件配置路由映射
.UseAuthentication() // 使用Authentication中间件启用身份验证
.UseAuthorization() // 使用Authorization中间件启用授权
.UseMiddleware<RemoveNullNodeMiddleware>() // 使用RemoveNullNodeMiddleware中间件删除JSON中的空节点
.UseEndpoints(); // 配置端点以处理请求
}
/// <summary>
/// 配置服务容器
/// </summary>
public void ConfigureServices(IServiceCollection services)
{
_ = services.AddConsoleFormatter() // 添加控制台日志模板
.AddAllOptions() // 添加配置项
.AddJwt() // 添加 Jwt 授权处理器
.AddSnowflake() // 添加雪花编号生成器
.AddEventBus() // 添加事件总线
.AddFreeSql() // 添加 freeSql
.AddRemoteRequest() // 添加远程请求
.AddCorsAccessor() // 添加支持跨域访问
.AddContextUser() // 添加上下文用户
.AddRedisCache() // 添加 Redis 缓存
/// <summary>
/// 配置服务容器
/// </summary>
public void ConfigureServices(IServiceCollection services)
{
_ = services.AddConsoleFormatter() // 添加控制台日志模板
.AddAllOptions() // 添加配置项
.AddJwt() // 添加 Jwt 授权处理器
.AddSnowflake() // 添加雪花编号生成器
.AddEventBus() // 添加事件总线
.AddFreeSqlWithArgs() // 添加 freeSql
.AddRemoteRequest() // 添加远程请求
.AddCorsAccessor() // 添加支持跨域访问
.AddContextUser() // 添加上下文用户
.AddRedisCache() // 添加 Redis 缓存
// IMvcBuilder
.AddControllers() // 添加控制器
.AddJsonSerializer(true) // 添加JSON序列化器并设置显示枚举名而非数字枚举值
.AddDefaultApiResultHandler() // 添加默认的API结果处理程序
;
// IMvcBuilder
.AddControllers() // 添加控制器
.AddJsonSerializer(true) // 添加JSON序列化器并设置显示枚举名而非数字枚举值
.AddDefaultApiResultHandler() // 添加默认的API结果处理程序
;
}
/// <inheritdoc />
#pragma warning disable ASA001
public Task<int> Execute(CommandContext context, CommandLineArgs settings)
#pragma warning restore ASA001
{
Args = settings;
_ = Serve.Run(RunOptions.Default.WithArgs(context.Remaining.Raw.ToArray()));
return Task.FromResult(0);
}
/// <inheritdoc />
#pragma warning disable ASA001
public Task<int> Execute(CommandContext context, CommandSettings settings)
#pragma warning restore ASA001
{
return Execute(context, (settings as CommandLineArgs)!);
}
/// <inheritdoc />
public ValidationResult Validate(CommandContext context, CommandSettings settings)
{
return ValidationResult.Success();
}
}
}

View File

@ -5,7 +5,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="IGeekFan.AspNetCore.Knife4jUI.NS" Condition="'$(Configuration)' == 'Debug'" Version="0.0.15-ns2"/>
<PackageReference Include="Spectre.Console.NS" Version="0.45.1-preview.0.124"/>
<PackageReference Include="Spectre.Console.Cli.NS" Version="0.45.1-preview.0.124"/>
<PackageReference Include="prometheus-net.AspNetCore" Condition="'$(Configuration)' != 'Debug'" Version="8.1.0"/>
</ItemGroup>
</Project>

View File

@ -1,4 +1,5 @@
using Spectre.Console;
using Spectre.Console.Cli;
namespace NetAdmin.Host;
@ -7,6 +8,21 @@ namespace NetAdmin.Host;
/// </summary>
public abstract class Startup : AppStartup
{
/// <summary>
/// 程序入口
/// </summary>
public static void Entry<T>(IEnumerable<string> args, Action<IConfigurator> commandConfig = null)
where T : class, ICommand
{
ShowBanner();
var app = new CommandApp<T>();
if (commandConfig != null) {
app.Configure(commandConfig);
}
_ = app.Run(args);
}
/// <summary>
/// 打印Banner
/// </summary>