feat:搭建yi-abp tool框架

This commit is contained in:
橙子
2024-06-02 13:09:25 +08:00
parent daaa3513ae
commit cbc34ade78
35 changed files with 822 additions and 9 deletions

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Abp.Tool.Domain.Shared.Enums;
namespace Yi.Abp.Tool.Application.Contracts.Dtos
{
public class TemplateGenCreateInputDto
{
/// <summary>
/// 模块名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 数据库提供者
/// </summary>
public DbmsEnum Dbms { get; set; }
/// <summary>
/// 需要替换的字符串内容
/// </summary>
public Dictionary<string, string> ReplaceStrData { get; set; }=new Dictionary<string, string>();
public void SetNameReplace()
{
ReplaceStrData.Add("Yi.Abp", Name);
ReplaceStrData.Add("YiAbp", Name.Replace(".", ""));
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Yi.Abp.Tool.Application.Contracts.Dtos;
namespace Yi.Abp.Tool.Application.Contracts
{
public interface ITemplateGenService
{
Task<IActionResult> CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto);
Task<IActionResult> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto);
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Abp.Tool.Domain.Shared\Yi.Abp.Tool.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
using Yi.Abp.Tool.Domain.Shared;
namespace Yi.Abp.Tool.Application.Contracts
{
[DependsOn(typeof(YiAbpToolDomainSharedModule))]
public class YiAbpToolApplicationContractsModule:AbpModule
{
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection;
using Yi.Abp.Tool.Application.Contracts;
using Yi.Abp.Tool.Application.Contracts.Dtos;
using Yi.Abp.Tool.Domain;
using Yi.Abp.Tool.Domain.Shared.Dtos;
using Yi.Framework.Core.Helper;
namespace Yi.Abp.Tool.Application
{
public class TemplateGenService : IRemoteService, ITemplateGenService, ITransientDependency
{
private readonly TemplateGenManager _templateGenManager;
public TemplateGenService(TemplateGenManager templateGenManager) { _templateGenManager = templateGenManager; }
/// <summary>
/// 下载模块文件
/// </summary>
/// <returns></returns>
public async Task<IActionResult> CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto)
{
moduleCreateInputDto.SetNameReplace();
var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>();
input.SetTemplateFilePath(_templateGenManager._toolOptions.ModuleTemplateFilePath);
var filePath = await _templateGenManager.CreateTemplateAsync(input);
//考虑从路径中获取
var fileContentType = MimeHelper.GetMimeMapping(Path.GetFileName(filePath));
//设置附件下载,下载名称
return new FileContentResult(await File.ReadAllBytesAsync(filePath), fileContentType);
}
/// <summary>
/// 下载模块文件
/// </summary>
/// <returns></returns>
public async Task<IActionResult> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto)
{
moduleCreateInputDto.SetNameReplace();
var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>();
input.SetTemplateFilePath(_templateGenManager._toolOptions.ProjectTemplateFilePath);
var filePath = await _templateGenManager.CreateTemplateAsync(input);
//考虑从路径中获取
var fileContentType = MimeHelper.GetMimeMapping(Path.GetFileName(filePath));
//设置附件下载,下载名称
return new FileContentResult(await File.ReadAllBytesAsync(filePath), fileContentType);
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Abp.Tool.Application.Contracts\Yi.Abp.Tool.Application.Contracts.csproj" />
<ProjectReference Include="..\Yi.Abp.Tool.Domain\Yi.Abp.Tool.Domain.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,12 @@
using Yi.Abp.Tool.Application.Contracts;
using Yi.Abp.Tool.Domain;
namespace Yi.Abp.Tool.Application
{
[DependsOn(typeof(YiAbpToolApplicationContractsModule),
typeof(YiAbpToolDomainModule))]
public class YiAbpToolApplicationModule:AbpModule
{
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Abp.Tool.Domain.Shared.Enums;
namespace Yi.Abp.Tool.Domain.Shared.Dtos
{
public class TemplateGenCreateDto
{
public void SetTemplateFilePath(string templateFilePath)
{
this.TemplateFilePath = templateFilePath;
}
/// <summary>
/// 模板文件路径
/// </summary>
public string TemplateFilePath { get; set; }
/// <summary>
/// 模块名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 数据库提供者
/// </summary>
public DbmsEnum Dbms { get; set; }
/// <summary>
/// 需要替换的字符串内容
/// </summary>
public Dictionary<string, string> ReplaceStrData { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Abp.Tool.Domain.Shared.Enums
{
public enum DbmsEnum
{
MySQL,
SQLite,
SQLServer,
Oracle,
PostgreSQL
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Abp.Tool.Domain.Shared.Options
{
public class ToolOptions
{
/// <summary>
/// 模块模板zip文件路径
/// </summary>
public string ModuleTemplateFilePath { get; set; }
/// <summary>
/// 项目模板zip文件路径
/// </summary>
public string ProjectTemplateFilePath { get; set; }
/// <summary>
/// 临时文件目录
/// </summary>
public string TempDirPath { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.Core\Yi.Framework.Core.csproj" />
<ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
using Yi.Framework.Core;
namespace Yi.Abp.Tool.Domain.Shared
{
[DependsOn(typeof(YiFrameworkCoreModule))]
public class YiAbpToolDomainSharedModule : AbpModule
{
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Yi.Abp.Tool.Domain.Shared.Dtos;
using Yi.Abp.Tool.Domain.Shared.Options;
namespace Yi.Abp.Tool.Domain
{
public class TemplateGenManager : ITransientDependency
{
public readonly ToolOptions _toolOptions;
public TemplateGenManager(IOptionsMonitor<ToolOptions> toolOptions) { _toolOptions = toolOptions.CurrentValue; }
public async Task<string> CreateTemplateAsync(TemplateGenCreateDto input)
{
if (string.IsNullOrEmpty(input.TemplateFilePath))
{
throw new UserFriendlyException($"模板路径无法找到,请检查,[{input.TemplateFilePath}]路径");
}
if (string.IsNullOrEmpty(_toolOptions.TempDirPath))
{
throw new UserFriendlyException($"临时目录路径无法找到,请检查,[{_toolOptions.TempDirPath}]路径");
}
var id = Guid.NewGuid().ToString("N");
var tempFileDirPath = Path.Combine(_toolOptions.TempDirPath, $"{id}");
if (!Directory.Exists(tempFileDirPath))
{
Directory.CreateDirectory(tempFileDirPath);
}
//文件解压覆盖
ZipFile.ExtractToDirectory(input.TemplateFilePath, tempFileDirPath, true);
await ReplaceContentAsync(tempFileDirPath, input.ReplaceStrData);
var tempFilePath = Path.Combine(_toolOptions.TempDirPath, $"{id}.zip");
ZipFile.CreateFromDirectory(tempFileDirPath, tempFilePath);
//创建压缩包后删除临时目录
Directory.Delete(tempFileDirPath, true);
return tempFilePath;
}
/// <summary>
/// 替换内容,key为要替换的内容value为替换成的内容
/// </summary>
/// <returns></returns>
private async Task ReplaceContentAsync(string rootDirectory, Dictionary<string, string> dic)
{
foreach (var dicEntry in dic)
{
await ReplaceInDirectory(rootDirectory, dicEntry.Key, dicEntry.Value);
}
//替换目录名
static async Task ReplaceInDirectory(string directoryPath, string searchString, string replaceString)
{
// 替换当前目录下的文件和文件夹名称
var newDirPath = await ReplaceInFiles(directoryPath, searchString, replaceString);
// 递归遍历子目录
string[] subDirectories = Directory.GetDirectories(newDirPath);
foreach (string subDirectory in subDirectories)
{
await ReplaceInDirectory(subDirectory, searchString, replaceString);
}
}
//替换文件名
static async Task<string> ReplaceInFiles(string directoryPath, string searchString, string replaceString)
{
// 替换目录名
string directoryName = new DirectoryInfo(directoryPath).Name;
string newDirectoryName = directoryName.Replace(searchString, replaceString);
if (directoryName != newDirectoryName)
{
string parentDirectory = Path.GetDirectoryName(directoryPath);
string newDirectoryPath = Path.Combine(parentDirectory, newDirectoryName);
Directory.Move(directoryPath, newDirectoryPath);
directoryPath = newDirectoryPath;
}
// 替换文件名
string[] files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
string newFileName = file.Replace(searchString, replaceString);
if (file != newFileName)
{
File.Move(file, newFileName);
}
}
files = Directory.GetFiles(directoryPath);
// 替换文件内容
foreach (string file in files)
{
string fileContent = await File.ReadAllTextAsync(file);
string newFileContent = fileContent.Replace(searchString, replaceString);
await File.WriteAllTextAsync(file, newFileContent);
}
return directoryPath;
}
}
}
}

View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Abp.Tool.Domain.Shared\Yi.Abp.Tool.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Yi.Abp.Tool.Domain.Shared;
using Yi.Abp.Tool.Domain.Shared.Options;
namespace Yi.Abp.Tool.Domain
{
[DependsOn(typeof(YiAbpToolDomainSharedModule))]
public class YiAbpToolDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<ToolOptions>(configuration.GetSection("ToolOptions"));
var toolOptions = new ToolOptions();
configuration.GetSection("ToolOptions").Bind(toolOptions);
if (!Directory.Exists(toolOptions.TempDirPath))
{
Directory.CreateDirectory(toolOptions.TempDirPath);
}
}
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Abp.Tool.Application.Contracts\Yi.Abp.Tool.Application.Contracts.csproj" />
<PackageReference Include="Volo.Abp.Http.Client" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Autofac;
using Volo.Abp.Http.Client;
using Yi.Abp.Tool.Application.Contracts;
namespace Yi.Abp.Tool.HttpApi.Client
{
[DependsOn(typeof(AbpHttpClientModule),
typeof(AbpAutofacModule),
typeof(YiAbpToolApplicationContractsModule))]
public class YiAbpToolHttpApiClientModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//创建动态客户端代理
context.Services.AddHttpClientProxies(
typeof(YiAbpToolApplicationContractsModule).Assembly
);
Configure<AbpRemoteServiceOptions>(options =>
{
options.RemoteServices.Default =
new RemoteServiceConfiguration("http://localhost:19002");
});
}
}
}

View File

@@ -0,0 +1,9 @@
using Yi.Abp.Tool.Web;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls(builder.Configuration["App:SelfUrl"]);
builder.Host.UseAutofac();
await builder.Services.AddApplicationAsync<YiAbpToolWebModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();

View File

@@ -0,0 +1,25 @@
{
"profiles": {
"Yi.Abp.Tool.Web": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
//"ASPNETCORE_ENVIRONMENT": "Staging"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:19002"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_HTTP_PORTS": "19002"
},
"publishAllPorts": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj" />
<ProjectReference Include="..\Yi.Abp.Tool.Application\Yi.Abp.Tool.Application.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,159 @@
using System.Globalization;
using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Cors;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Converters;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.Autofac;
using Volo.Abp.Swashbuckle;
using Yi.Abp.Tool.Application;
using Yi.Framework.AspNetCore;
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
namespace Yi.Abp.Tool.Web
{
[DependsOn(typeof(YiAbpToolApplicationModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAutofacModule),
typeof(AbpSwashbuckleModule),
typeof(YiFrameworkAspNetCoreModule)
)]
public class YiAbpToolWebModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";
public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var host = context.Services.GetHostingEnvironment();
var service = context.Services;
//动态Api
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(YiAbpToolApplicationModule).Assembly, options => options.RemoteServiceName = "tool");
//统一前缀
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
});
//设置api格式
service.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
Configure<AbpAntiForgeryOptions>(options =>
{
options.AutoValidate = false;
});
//Swagger
context.Services.AddYiSwaggerGen<YiAbpToolWebModule>(options =>
{
options.SwaggerDoc("default", new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
});
//跨域
context.Services.AddCors(options =>
{
options.AddPolicy(DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]!
.Split(";", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//速率限制
//每60秒限制100个请求滑块添加分6段
service.AddRateLimiter(_ =>
{
_.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
_.OnRejected = (context, _) =>
{
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
{
context.HttpContext.Response.Headers.RetryAfter =
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
}
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
return new ValueTask();
};
//全局使用,链式表达式
_.GlobalLimiter = PartitionedRateLimiter.CreateChained(
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
{
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
return RateLimitPartition.GetSlidingWindowLimiter
(userAgent, _ =>
new SlidingWindowRateLimiterOptions
{
PermitLimit = 1000,
Window = TimeSpan.FromSeconds(60),
SegmentsPerWindow = 6,
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
});
}));
});
return Task.CompletedTask;
}
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
var service = context.ServiceProvider;
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();
app.UseRouting();
//跨域
app.UseCors(DefaultCorsPolicyName);
if (!env.IsDevelopment())
{
//速率限制
app.UseRateLimiter();
}
//swagger
app.UseYiSwagger();
//请求处理
app.UseYiApiHandlinge();
//静态资源
app.UseStaticFiles("/api/app/wwwroot");
app.UseDefaultFiles();
app.UseDirectoryBrowser("/api/app/wwwroot");
//终节点
app.UseConfiguredEndpoints();
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,19 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
//应用启动
"App": {
"SelfUrl": "http://*:19002",
"CorsOrigins": "http://localhost:19002;http://localhost:18002"
},
"ToolOptions": {
"TempDirPath": "wwwroot/temp",
"ModuleTemplateFilePath": "wwwroot/ModuleTemplate.zip",
"ProjectTemplateFilePath": "wwwroot/ProjectTemplate.zip"
}
}

View File

@@ -62,7 +62,7 @@ namespace Yi.Abp.Tool
}
await commandOrNull.InvokerAsync(options);
await commandOrNull.InvokerAsync(options,args);
}
/// <summary>

View File

@@ -11,7 +11,7 @@ namespace Yi.Abp.Tool.Commands
{
public List<string> CommandStrs => new List<string> { "h", "help", "-h", "-help" };
public Task InvokerAsync(Dictionary<string, string> options)
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
{
string? errorMsg = null;
if (options.TryGetValue("error", out _))

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Yi.Abp.Tool.Application.Contracts;
using Yi.Abp.Tool.Application.Contracts.Dtos;
namespace Yi.Abp.Tool.Commands
{
public class NewCommand : ICommand
{
private readonly ITemplateGenService _templateGenService;
public NewCommand(ITemplateGenService templateGenService)
{
_templateGenService = templateGenService;
}
public List<string> CommandStrs => new List<string>() { "new" };
public async Task InvokerAsync(Dictionary<string, string> options, string[] args)
{
//只有一个new
if (args.Length <= 1)
{
throw new UserFriendlyException("命令错误new命令后必须添加 名称");
}
string name = args[1];
options.TryGetValue("t", out var templateType);
if (templateType == "module")
{
//代表模块生成
var fileResult = await _templateGenService.CreateModuleAsync(new TemplateGenCreateInputDto
{
Name = name,
});
var fileContent = fileResult as FileContentResult;
File.WriteAllText("./", Encoding.UTF8.GetString(fileContent.FileContents));
}
else
{
//暂未实现
throw new NotImplementedException();
//代表模块生成
var fileResult = await _templateGenService.CreateProjectAsync(new TemplateGenCreateInputDto
{
Name = name,
});
}
}
}
}

View File

@@ -4,7 +4,7 @@
{
public List<string> CommandStrs => new List<string> { "version", "v", "-version", "-v" };
public Task InvokerAsync(Dictionary<string, string> options)
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
{
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
Console.WriteLine($"Yi-ABP TOOL {version}");

View File

@@ -18,6 +18,6 @@ namespace Yi.Abp.Tool
/// 执行
/// </summary>
/// <returns></returns>
public Task InvokerAsync(Dictionary<string,string> options);
public Task InvokerAsync(Dictionary<string,string> options, string[] args);
}
}

View File

@@ -15,6 +15,7 @@ class Program
//args = ["-h"];
//args = [];
//args = ["12312"];
args = ["new", "Acme.Book","-t", "module", "-csf"];
#endif
try
{
@@ -34,6 +35,7 @@ class Program
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
Console.ReadKey();
}
}

View File

@@ -31,6 +31,11 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Abp.Tool.HttpApi.Client\Yi.Abp.Tool.HttpApi.Client.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="readme.md">
<Pack>True</Pack>

View File

@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Abp.Tool.HttpApi.Client;
namespace Yi.Abp.Tool
{
[DependsOn(typeof(YiAbpToolHttpApiClientModule))]
public class YiAbpToolModule : AbpModule
{
}