From cbc34ade7891393be607aa588b87eaadf53e4aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 2 Jun 2024 13:09:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=90=AD=E5=BB=BAyi-abp=20tool=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/Yi.Abp.sln | 42 +++++ .../Middlewares/ApiInfoMiddleware.cs | 7 +- Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 4 - .../Dtos/TemplateGenCreateInputDto.cs | 35 ++++ .../ITemplateGenService.cs | 16 ++ .../Yi.Abp.Tool.Application.Contracts.csproj | 13 ++ .../YiAbpToolApplicationContractsModule.cs | 10 ++ .../TemplateGenService.cs | 59 +++++++ .../Yi.Abp.Tool.Application.csproj | 13 ++ .../YiAbpToolApplicationModule.cs | 12 ++ .../Dtos/TemplateGenCreateDto.cs | 39 +++++ .../Enums/DbmsEnum.cs | 17 ++ .../Options/ToolOptions.cs | 27 +++ .../Yi.Abp.Tool.Domain.Shared.csproj | 13 ++ .../YiAbpToolDomainSharedModule.cs | 10 ++ .../Yi.Abp.Tool.Domain/TemplateGenManager.cs | 114 +++++++++++++ .../Yi.Abp.Tool.Domain.csproj | 12 ++ .../YiAbpToolDomainModule.cs | 24 +++ .../Yi.Abp.Tool.HttpApi.Client.csproj | 16 ++ .../YiAbpToolHttpApiClientModule.cs | 27 +++ Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Program.cs | 9 + .../Properties/launchSettings.json | 25 +++ .../Yi.Abp.Tool.Web/Yi.Abp.Tool.Web.csproj | 24 +++ .../Yi.Abp.Tool.Web/YiAbpToolWebModule.cs | 159 ++++++++++++++++++ .../appsettings.Development.json | 8 + .../tool/Yi.Abp.Tool.Web/appsettings.json | 19 +++ .../wwwroot/ModuleTemplate.zip | Bin 0 -> 10290 bytes .../tool/Yi.Abp.Tool/CommandSelector.cs | 2 +- .../tool/Yi.Abp.Tool/Commands/HelpCommand.cs | 2 +- .../tool/Yi.Abp.Tool/Commands/NewCommand.cs | 60 +++++++ .../Yi.Abp.Tool/Commands/VersionCommand.cs | 2 +- Yi.Abp.Net8/tool/Yi.Abp.Tool/ICommand.cs | 2 +- Yi.Abp.Net8/tool/Yi.Abp.Tool/Program.cs | 2 + .../tool/Yi.Abp.Tool/Yi.Abp.Tool.csproj | 5 + .../tool/Yi.Abp.Tool/YiAbpToolModule.cs | 2 + 35 files changed, 822 insertions(+), 9 deletions(-) create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Dtos/TemplateGenCreateInputDto.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/ITemplateGenService.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Yi.Abp.Tool.Application.Contracts.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/YiAbpToolApplicationContractsModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/TemplateGenService.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/Yi.Abp.Tool.Application.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/YiAbpToolApplicationModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Dtos/TemplateGenCreateDto.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Enums/DbmsEnum.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Options/ToolOptions.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Yi.Abp.Tool.Domain.Shared.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/YiAbpToolDomainSharedModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/TemplateGenManager.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/Yi.Abp.Tool.Domain.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/YiAbpToolDomainModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/Yi.Abp.Tool.HttpApi.Client.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/YiAbpToolHttpApiClientModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Program.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Properties/launchSettings.json create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Yi.Abp.Tool.Web.csproj create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/YiAbpToolWebModule.cs create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.json create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/wwwroot/ModuleTemplate.zip create mode 100644 Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/NewCommand.cs diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln index dd4a26a7..fef906fa 100644 --- a/Yi.Abp.Net8/Yi.Abp.sln +++ b/Yi.Abp.Net8/Yi.Abp.sln @@ -154,6 +154,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tool", "tool", "{084CBEEC-5 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool", "tool\Yi.Abp.Tool\Yi.Abp.Tool.csproj", "{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.Web", "tool\Yi.Abp.Tool.Web\Yi.Abp.Tool.Web.csproj", "{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.Application", "tool\Yi.Abp.Tool.Application\Yi.Abp.Tool.Application.csproj", "{776590BA-B900-4C8B-986A-5B721FA4B306}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.Application.Contracts", "tool\Yi.Abp.Tool.Application.Contracts\Yi.Abp.Tool.Application.Contracts.csproj", "{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.Domain", "tool\Yi.Abp.Tool.Domain\Yi.Abp.Tool.Domain.csproj", "{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.Domain.Shared", "tool\Yi.Abp.Tool.Domain.Shared\Yi.Abp.Tool.Domain.Shared.csproj", "{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Abp.Tool.HttpApi.Client", "tool\Yi.Abp.Tool.HttpApi.Client\Yi.Abp.Tool.HttpApi.Client.csproj", "{C8F97775-D903-4365-A4FF-3DA97E318CD2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -384,6 +396,30 @@ Global {4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Debug|Any CPU.Build.0 = Debug|Any CPU {4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Release|Any CPU.ActiveCfg = Release|Any CPU {4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Release|Any CPU.Build.0 = Release|Any CPU + {2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Release|Any CPU.Build.0 = Release|Any CPU + {776590BA-B900-4C8B-986A-5B721FA4B306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {776590BA-B900-4C8B-986A-5B721FA4B306}.Debug|Any CPU.Build.0 = Debug|Any CPU + {776590BA-B900-4C8B-986A-5B721FA4B306}.Release|Any CPU.ActiveCfg = Release|Any CPU + {776590BA-B900-4C8B-986A-5B721FA4B306}.Release|Any CPU.Build.0 = Release|Any CPU + {3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Release|Any CPU.Build.0 = Release|Any CPU + {68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Release|Any CPU.Build.0 = Release|Any CPU + {4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Release|Any CPU.Build.0 = Release|Any CPU + {C8F97775-D903-4365-A4FF-3DA97E318CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8F97775-D903-4365-A4FF-3DA97E318CD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8F97775-D903-4365-A4FF-3DA97E318CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8F97775-D903-4365-A4FF-3DA97E318CD2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -452,6 +488,12 @@ Global {B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB} {9ECF0841-53BE-4FD8-95D1-A7223C7F3A07} = {0D10EEF2-FBAE-4C72-B816-A52823FC299B} {4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {776590BA-B900-4C8B-986A-5B721FA4B306} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {68F73B7B-0F8A-41C1-8092-6D6FFAED32F8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {4AE84CDE-2A47-4D68-8E93-86193F72E4E8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} + {C8F97775-D903-4365-A4FF-3DA97E318CD2} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18} diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/AspNetCore/Middlewares/ApiInfoMiddleware.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/AspNetCore/Middlewares/ApiInfoMiddleware.cs index ab0f42a9..5345ff89 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/AspNetCore/Middlewares/ApiInfoMiddleware.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/AspNetCore/Middlewares/ApiInfoMiddleware.cs @@ -15,10 +15,15 @@ namespace Yi.Framework.AspNetCore.Microsoft.AspNetCore.Middlewares context.Response.OnStarting(() => { if (context.Response.StatusCode == StatusCodes.Status200OK -&& context.Response.Headers["Content-Type"].ToString() == "application/vnd.ms-excel") + && context.Response.Headers["Content-Type"].ToString() == "application/vnd.ms-excel") { context.FileAttachmentHandle($"{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.xlsx"); } + if (context.Response.StatusCode == StatusCodes.Status200OK && + context.Response.Headers["Content-Type"].ToString() == "application/x-zip-compressed") + { + context.FileAttachmentHandle($"{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.zip"); + } return Task.CompletedTask; }); diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index e6f33dec..6c86fbe1 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -260,10 +260,6 @@ namespace Yi.Abp.Web { var service = context.ServiceProvider; - var sss=service.GetRequiredService>().Value; - - - var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Dtos/TemplateGenCreateInputDto.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Dtos/TemplateGenCreateInputDto.cs new file mode 100644 index 00000000..c65e1101 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Dtos/TemplateGenCreateInputDto.cs @@ -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 + { + /// + /// 模块名称 + /// + public string Name { get; set; } + + + /// + /// 数据库提供者 + /// + public DbmsEnum Dbms { get; set; } + + + /// + /// 需要替换的字符串内容 + /// + public Dictionary ReplaceStrData { get; set; }=new Dictionary(); + + public void SetNameReplace() + { + ReplaceStrData.Add("Yi.Abp", Name); + ReplaceStrData.Add("YiAbp", Name.Replace(".", "")); + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/ITemplateGenService.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/ITemplateGenService.cs new file mode 100644 index 00000000..f5830b68 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/ITemplateGenService.cs @@ -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 CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto); + Task CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto); + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Yi.Abp.Tool.Application.Contracts.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Yi.Abp.Tool.Application.Contracts.csproj new file mode 100644 index 00000000..90506e73 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/Yi.Abp.Tool.Application.Contracts.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/YiAbpToolApplicationContractsModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/YiAbpToolApplicationContractsModule.cs new file mode 100644 index 00000000..f5668c2a --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application.Contracts/YiAbpToolApplicationContractsModule.cs @@ -0,0 +1,10 @@ +using Yi.Abp.Tool.Domain.Shared; + +namespace Yi.Abp.Tool.Application.Contracts +{ + [DependsOn(typeof(YiAbpToolDomainSharedModule))] + public class YiAbpToolApplicationContractsModule:AbpModule + { + + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/TemplateGenService.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/TemplateGenService.cs new file mode 100644 index 00000000..4290aacf --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/TemplateGenService.cs @@ -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; } + + /// + /// 下载模块文件 + /// + /// + public async Task CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto) + { + moduleCreateInputDto.SetNameReplace(); + + var input = moduleCreateInputDto.Adapt(); + 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); + } + + /// + /// 下载模块文件 + /// + /// + public async Task CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto) + { + moduleCreateInputDto.SetNameReplace(); + + var input = moduleCreateInputDto.Adapt(); + 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); + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/Yi.Abp.Tool.Application.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/Yi.Abp.Tool.Application.csproj new file mode 100644 index 00000000..cd464635 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/Yi.Abp.Tool.Application.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/YiAbpToolApplicationModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/YiAbpToolApplicationModule.cs new file mode 100644 index 00000000..76535e45 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Application/YiAbpToolApplicationModule.cs @@ -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 + { + + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Dtos/TemplateGenCreateDto.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Dtos/TemplateGenCreateDto.cs new file mode 100644 index 00000000..9259ae84 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Dtos/TemplateGenCreateDto.cs @@ -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; + } + + + /// + /// 模板文件路径 + /// + public string TemplateFilePath { get; set; } + /// + /// 模块名称 + /// + public string Name { get; set; } + + + /// + /// 数据库提供者 + /// + public DbmsEnum Dbms { get; set; } + + + /// + /// 需要替换的字符串内容 + /// + public Dictionary ReplaceStrData { get; set; } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Enums/DbmsEnum.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Enums/DbmsEnum.cs new file mode 100644 index 00000000..a59a98cc --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Enums/DbmsEnum.cs @@ -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 + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Options/ToolOptions.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Options/ToolOptions.cs new file mode 100644 index 00000000..a2084956 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Options/ToolOptions.cs @@ -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 + { + /// + /// 模块模板zip文件路径 + /// + public string ModuleTemplateFilePath { get; set; } + + /// + /// 项目模板zip文件路径 + /// + public string ProjectTemplateFilePath { get; set; } + + + /// + /// 临时文件目录 + /// + public string TempDirPath { get; set; } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Yi.Abp.Tool.Domain.Shared.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Yi.Abp.Tool.Domain.Shared.csproj new file mode 100644 index 00000000..eaf50bd2 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/Yi.Abp.Tool.Domain.Shared.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/YiAbpToolDomainSharedModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/YiAbpToolDomainSharedModule.cs new file mode 100644 index 00000000..734a62e1 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain.Shared/YiAbpToolDomainSharedModule.cs @@ -0,0 +1,10 @@ +using Yi.Framework.Core; + +namespace Yi.Abp.Tool.Domain.Shared +{ + [DependsOn(typeof(YiFrameworkCoreModule))] + public class YiAbpToolDomainSharedModule : AbpModule + { + + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/TemplateGenManager.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/TemplateGenManager.cs new file mode 100644 index 00000000..b9edbe74 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/TemplateGenManager.cs @@ -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.CurrentValue; } + public async Task 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; + } + + /// + /// 替换内容,key为要替换的内容,value为替换成的内容 + /// + /// + private async Task ReplaceContentAsync(string rootDirectory, Dictionary 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 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; + } + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/Yi.Abp.Tool.Domain.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/Yi.Abp.Tool.Domain.csproj new file mode 100644 index 00000000..062edcec --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/Yi.Abp.Tool.Domain.csproj @@ -0,0 +1,12 @@ + + + + net8.0 + enable + enable + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/YiAbpToolDomainModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/YiAbpToolDomainModule.cs new file mode 100644 index 00000000..b8559b2f --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/YiAbpToolDomainModule.cs @@ -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(configuration.GetSection("ToolOptions")); + var toolOptions = new ToolOptions(); + configuration.GetSection("ToolOptions").Bind(toolOptions); + if (!Directory.Exists(toolOptions.TempDirPath)) + { + Directory.CreateDirectory(toolOptions.TempDirPath); + } + + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/Yi.Abp.Tool.HttpApi.Client.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/Yi.Abp.Tool.HttpApi.Client.csproj new file mode 100644 index 00000000..a0fff017 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/Yi.Abp.Tool.HttpApi.Client.csproj @@ -0,0 +1,16 @@ + + + + net8.0 + enable + enable + + + + + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/YiAbpToolHttpApiClientModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/YiAbpToolHttpApiClientModule.cs new file mode 100644 index 00000000..cd33b08e --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.HttpApi.Client/YiAbpToolHttpApiClientModule.cs @@ -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(options => + { + options.RemoteServices.Default = + new RemoteServiceConfiguration("http://localhost:19002"); + }); + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Program.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Program.cs new file mode 100644 index 00000000..c0ad451f --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Program.cs @@ -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(); +var app = builder.Build(); +await app.InitializeApplicationAsync(); +await app.RunAsync(); \ No newline at end of file diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Properties/launchSettings.json b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Properties/launchSettings.json new file mode 100644 index 00000000..0c73d601 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Properties/launchSettings.json @@ -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" +} \ No newline at end of file diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Yi.Abp.Tool.Web.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Yi.Abp.Tool.Web.csproj new file mode 100644 index 00000000..8c2119ac --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/Yi.Abp.Tool.Web.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/YiAbpToolWebModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/YiAbpToolWebModule.cs new file mode 100644 index 00000000..dd4cc1c7 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/YiAbpToolWebModule.cs @@ -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(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(options => + { + options.AutoValidate = false; + }); + + //Swagger + context.Services.AddYiSwaggerGen(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 => + { + 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; + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.json b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.json new file mode 100644 index 00000000..a9d33481 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.json @@ -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" + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/wwwroot/ModuleTemplate.zip b/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/wwwroot/ModuleTemplate.zip new file mode 100644 index 0000000000000000000000000000000000000000..1c4a0fd1f82cc5575eaaed2041a06a762e1a2b6d GIT binary patch literal 10290 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 R0RUX+Pb2h9F(CcE`X6RoWIF%= literal 0 HcmV?d00001 diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/CommandSelector.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/CommandSelector.cs index 28844a62..70d58aef 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/CommandSelector.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/CommandSelector.cs @@ -62,7 +62,7 @@ namespace Yi.Abp.Tool } - await commandOrNull.InvokerAsync(options); + await commandOrNull.InvokerAsync(options,args); } /// diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/HelpCommand.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/HelpCommand.cs index 0edf9947..5aab22bf 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/HelpCommand.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/HelpCommand.cs @@ -11,7 +11,7 @@ namespace Yi.Abp.Tool.Commands { public List CommandStrs => new List { "h", "help", "-h", "-help" }; - public Task InvokerAsync(Dictionary options) + public Task InvokerAsync(Dictionary options, string[] args) { string? errorMsg = null; if (options.TryGetValue("error", out _)) diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/NewCommand.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/NewCommand.cs new file mode 100644 index 00000000..6a812d00 --- /dev/null +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/NewCommand.cs @@ -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 CommandStrs => new List() { "new" }; + + + public async Task InvokerAsync(Dictionary 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, + }); + } + + + + } + } +} diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/VersionCommand.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/VersionCommand.cs index b472cd45..86c56f96 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/VersionCommand.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Commands/VersionCommand.cs @@ -4,7 +4,7 @@ { public List CommandStrs => new List { "version", "v", "-version", "-v" }; - public Task InvokerAsync(Dictionary options) + public Task InvokerAsync(Dictionary options, string[] args) { var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; Console.WriteLine($"Yi-ABP TOOL {version}"); diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/ICommand.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/ICommand.cs index 577b299d..8b9f9108 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/ICommand.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/ICommand.cs @@ -18,6 +18,6 @@ namespace Yi.Abp.Tool /// 执行 /// /// - public Task InvokerAsync(Dictionary options); + public Task InvokerAsync(Dictionary options, string[] args); } } diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Program.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Program.cs index 96e8416f..61893169 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Program.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Program.cs @@ -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(); } } \ No newline at end of file diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Yi.Abp.Tool.csproj b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Yi.Abp.Tool.csproj index 4ef7f100..662938e1 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/Yi.Abp.Tool.csproj +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/Yi.Abp.Tool.csproj @@ -31,6 +31,11 @@ + + + + + True diff --git a/Yi.Abp.Net8/tool/Yi.Abp.Tool/YiAbpToolModule.cs b/Yi.Abp.Net8/tool/Yi.Abp.Tool/YiAbpToolModule.cs index 1f8c6fb8..02ca7846 100644 --- a/Yi.Abp.Net8/tool/Yi.Abp.Tool/YiAbpToolModule.cs +++ b/Yi.Abp.Net8/tool/Yi.Abp.Tool/YiAbpToolModule.cs @@ -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 { }