diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/GlobalUsings.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/GlobalUsings.cs
index 78059794..04d8dad0 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/GlobalUsings.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/GlobalUsings.cs
@@ -18,6 +18,7 @@ global using Microsoft.Extensions.Options;
global using Octokit;
global using Polly;
global using Polly.Retry;
+global using Spectre.Console;
global using Volo.Abp;
global using Volo.Abp.DependencyInjection;
global using Volo.Abp.Domain;
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion.AbpPro.Cli.Core.csproj b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion.AbpPro.Cli.Core.csproj
index 2967b5d8..bb07cd2a 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion.AbpPro.Cli.Core.csproj
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion.AbpPro.Cli.Core.csproj
@@ -11,14 +11,12 @@
+
-
-
-
-
+
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/AbpProCliCoreModule.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/AbpProCliCoreModule.cs
index b5d74677..f3f22c8a 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/AbpProCliCoreModule.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/AbpProCliCoreModule.cs
@@ -12,6 +12,7 @@ public class AbpProCliCoreModule : AbpModule
Configure(options => { options.Commands[LoginCommand.Name] = typeof(LoginCommand); });
Configure(options => { options.Commands[CreateCommand.Name] = typeof(CreateCommand); });
Configure(options => { options.Commands[CodeCommand.Name] = typeof(CodeCommand); });
+ Configure(options => { options.Commands[ConfigCommand.Name] = typeof(ConfigCommand); });
Configure(options =>
{
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Args/CommandOptions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Args/CommandOptions.cs
index fabb09d4..9bb91c93 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Args/CommandOptions.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Args/CommandOptions.cs
@@ -67,11 +67,56 @@ public static class CommandOptions
}
///
- /// 版本
+ /// Token
///
public static class Token
{
public const string Short = "token";
public const string Long = "token";
}
+
+ ///
+ /// 版本
+ ///
+ public static class Sln
+ {
+ public const string Short = "sln";
+ public const string Long = "sln";
+ }
+
+ ///
+ /// UserName
+ ///
+ public static class UserName
+ {
+ public const string Short = "u";
+ public const string Long = "UserName";
+ }
+
+ ///
+ /// Password
+ ///
+ public static class Password
+ {
+ public const string Short = "p";
+ public const string Long = "Password";
+ }
+
+ ///
+ /// 版本
+ ///
+ public static class TenantName
+ {
+ public const string Short = "t";
+ public const string Long = "TenantName";
+ }
+
+ ///
+ /// CodeServiceUrl
+ ///
+ public static class CodeServiceUrl
+ {
+ public const string Short = "c";
+ public const string Long = "CodeServiceUrl";
+ }
}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/ConfigService.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/ConfigService.cs
new file mode 100644
index 00000000..658e7108
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/ConfigService.cs
@@ -0,0 +1,41 @@
+using System.Text.Json;
+
+namespace Lion.AbpPro.Cli.Auth;
+
+public class ConfigService : IConfigService, ITransientDependency
+{
+ private readonly IJsonSerializer _jsonSerializer;
+
+ public ConfigService(IJsonSerializer jsonSerializer)
+ {
+ _jsonSerializer = jsonSerializer;
+ }
+
+ public async Task SetAsync(string config)
+ {
+ if (!Directory.Exists(CliPaths.Root))
+ {
+ Directory.CreateDirectory(CliPaths.Root);
+ }
+
+ await File.WriteAllTextAsync(CliPaths.Config, config, Encoding.UTF8);
+ }
+
+ public async Task GetAsync()
+ {
+ if (!File.Exists(CliPaths.Config))
+ {
+ return new ConfigOptions()
+ {
+ CodeServiceUrl = "http://182.43.18.151:44317",
+ UserName = "admin",
+ Password = "1q2w3E*",
+ TenantName = string.Empty,
+ TenantId = string.Empty
+ };
+ }
+
+ var content = await File.ReadAllTextAsync(CliPaths.Config);
+ return _jsonSerializer.Deserialize(content);
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/IConfigService.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/IConfigService.cs
new file mode 100644
index 00000000..ca6dddc8
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Auth/IConfigService.cs
@@ -0,0 +1,14 @@
+namespace Lion.AbpPro.Cli.Auth;
+
+public interface IConfigService
+{
+ ///
+ /// 设置token
+ ///
+ Task SetAsync(string config);
+
+ ///
+ /// 获取token
+ ///
+ Task GetAsync();
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliPaths.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliPaths.cs
index 28de54b2..0ed2c387 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliPaths.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliPaths.cs
@@ -6,6 +6,7 @@ public class CliPaths
public static string Root => Path.Combine(AbpRootPath, "cli");
public static string AccessToken => Path.Combine(AbpRootPath, "cli", "access-token.bin");
+ public static string Config => Path.Combine(AbpRootPath, "cli", "config.bin");
public static string Output => Path.Combine(AbpRootPath, "cli", "code", "output");
public static string Source => Path.Combine(AbpRootPath, "cli", "code", "source");
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliService.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliService.cs
index ecd011cc..ede610e9 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliService.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CliService.cs
@@ -20,8 +20,8 @@ public class CliService : DomainService
public async Task RunAsync(string[] args)
{
- Logger.LogInformation("ABP Pro CLI (http://doc.cncore.club/)");
- Logger.LogInformation("请输入 lion.abp help 查看所有命令");
+ AnsiConsole.MarkupLine("[green]ABP Pro CLI (http://doc.cncore.club/)[/]");
+ AnsiConsole.MarkupLine("[green]请输入lion.abp help 查看所有命令[/]");
try
{
var commandLineArgs = _commandLineArgumentParser.Parse(args);
@@ -30,7 +30,7 @@ public class CliService : DomainService
catch (Exception ex)
{
- Logger.LogError(ex.Message);
+ AnsiConsole.MarkupLine($"[red]{ex.Message}[/]");
}
}
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CodeService.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CodeService.cs
index b5136dff..e7ad1737 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CodeService.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/CodeService.cs
@@ -1,3 +1,4 @@
+using Lion.AbpPro.Cli.Auth;
using Lion.AbpPro.Cli.Dto;
using FileMode = System.IO.FileMode;
@@ -8,71 +9,171 @@ public class CodeService : ICodeService, ITransientDependency
private readonly ILogger _logger;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IJsonSerializer _jsonSerializer;
+ private readonly IConfigService _configService;
- public CodeService(ILogger logger, IHttpClientFactory httpClientFactory, IJsonSerializer jsonSerializer)
+ public CodeService(ILogger logger, IHttpClientFactory httpClientFactory, IJsonSerializer jsonSerializer, IConfigService configService)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
_jsonSerializer = jsonSerializer;
+ _configService = configService;
}
- public async Task GetAccessTokenAsync()
+ private async Task GetConfigOptionsAsync()
+ {
+ return await _configService.GetAsync();
+ }
+
+ private async Task GetHttpClientAsync()
+ {
+ var options = await GetConfigOptionsAsync();
+ var httpClient = _httpClientFactory.CreateClient();
+ httpClient.BaseAddress = new Uri(options.CodeServiceUrl);
+ return httpClient;
+ }
+
+ public async Task LoginAsync(string url, string userName, string password)
{
using var httpClient = _httpClientFactory.CreateClient();
- httpClient.BaseAddress = new Uri("http://182.43.18.151:44317/");
+ httpClient.BaseAddress = new Uri(url);
var data = new
{
- name = "admin",
- password = "1q2w3E*"
+ name = userName,
+ password = password
};
var content = new StringContent(_jsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("/api/app/account/login", content);
- if (response.IsSuccessStatusCode)
+ if (!response.IsSuccessStatusCode)
{
- _logger.LogInformation($"登录代码生成器服务成功");
+ throw new UserFriendlyException($"用户或者密码错误");
}
- else
+
+ return _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync()).Token;
+ }
+
+ public async Task GetAccessTokenAsync()
+ {
+ var options = await GetConfigOptionsAsync();
+ using var httpClient = await GetHttpClientAsync();
+ var data = new
{
- _logger.LogError($"登录代码生成器服务失败,状态码{response.StatusCode}");
+ name = options.UserName,
+ password = options.Password
+ };
+ httpClient.DefaultRequestHeaders.Add("__tenant", $"{options.TenantId}");
+ var content = new StringContent(_jsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
+ var response = await httpClient.PostAsync("/api/app/account/login", content);
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new UserFriendlyException($"用户或者密码错误");
}
return _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync()).Token;
}
- public async Task DownloadAsync(string accessToken, Guid projectId, Guid templateId)
+ public async Task DownloadAsync(string accessToken, Guid projectId, Guid templateId, List entityId)
{
+ var options = await GetConfigOptionsAsync();
var path = Path.Combine(CliPaths.Source, $"{templateId}_{projectId}.zip");
if (File.Exists(path))
{
File.Delete(path);
}
- using var httpClient = _httpClientFactory.CreateClient();
- httpClient.BaseAddress = new Uri("http://182.43.18.151:44317/");
+
+ using var httpClient = await GetHttpClientAsync();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
- // 3a179906-5c79-b1e8-69f6-872afc276592
- // 3a18123b-4ac4-b8e7-ddb8-73ac01179aff
+ httpClient.DefaultRequestHeaders.Add("__tenant", $"{options.TenantId}");
var data = new
{
templateId = templateId,
- projectId = projectId
+ projectId = projectId,
+ entityId = entityId
};
var content = new StringContent(_jsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("/Generator/Down", content);
- if (response.IsSuccessStatusCode)
+ if (!response.IsSuccessStatusCode)
{
- _logger.LogInformation($"下载代码成功");
- }
- else
- {
- _logger.LogError($"下载代码失败,状态码{response.StatusCode}");
+ throw new UserFriendlyException($"下载代码失败,状态码{response.StatusCode}");
}
// 保存到本地
await using var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
await response.Content.CopyToAsync(fileStream);
- _logger.LogInformation($"保存代码成功");
return path;
}
+
+ public async Task GetProjectAndEntityAsync(string accessToken, Guid projectId)
+ {
+ var options = await GetConfigOptionsAsync();
+ using var httpClient = await GetHttpClientAsync();
+ var data = new
+ {
+ id = projectId,
+ };
+ var content = new StringContent(_jsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
+ httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
+ httpClient.DefaultRequestHeaders.Add("__tenant", $"{options.TenantId}");
+ var response = await httpClient.PostAsync("/Projects/GetProjectAndEntity", content);
+ if (!response.IsSuccessStatusCode)
+ {
+ var error = _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync());
+ throw new UserFriendlyException(error.error.message);
+ }
+
+ return _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync());
+ }
+
+ public async Task FindTenantAsync(string url, string tenantName)
+ {
+ using var httpClient = _httpClientFactory.CreateClient();
+ httpClient.BaseAddress = GetUri(url);
+ var data = new
+ {
+ name = tenantName,
+ };
+ var content = new StringContent(_jsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
+ var response = await httpClient.PostAsync("Tenants/find", content);
+ if (!response.IsSuccessStatusCode)
+ {
+ var error = _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync());
+ throw new UserFriendlyException(error.error.message);
+ }
+
+
+ var result = _jsonSerializer.Deserialize(await response.Content.ReadAsStringAsync());
+ if (!result.Success)
+ {
+ throw new UserFriendlyException($"租户不存在:{tenantName}");
+ }
+
+ return result;
+ }
+
+ public async Task CheckHealthAsync(string url)
+ {
+ using var httpClient = _httpClientFactory.CreateClient();
+ httpClient.BaseAddress = GetUri(url);
+ var response = await httpClient.GetAsync("/health");
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new UserFriendlyException($"服务异常:{url}");
+ }
+ }
+
+ private Uri GetUri(string url)
+ {
+ Uri uri;
+ try
+ {
+ uri = new Uri(url);
+ }
+ catch (Exception e)
+ {
+ throw new UserFriendlyException($"url格式错误:{url}");
+ }
+
+ return uri;
+ }
}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CodeCommand.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CodeCommand.cs
index e5a34cbe..83a8a538 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CodeCommand.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CodeCommand.cs
@@ -1,8 +1,12 @@
+using Lion.AbpPro.Cli.Dto;
+
namespace Lion.AbpPro.Cli.Commands;
public class CodeCommand : IConsoleCommand, ITransientDependency
{
public const string Name = "code";
+ private const string Dotnet = "dotnet";
+ private const string Vue3 = "vue3";
private readonly ILogger _logger;
private readonly ICodeService _codeService;
@@ -12,25 +16,218 @@ public class CodeCommand : IConsoleCommand, ITransientDependency
_logger = logger;
}
+ ///
+ /// code -p 3a1821f9-9c71-4d5e-205e-008267cee6b9 -t 3a182572-1a21-ffd4-db9d-4d6065c4eac8 -s C:\Users\Administrator\.abp.pro\cli\code\output\ErpOA9.1.1-rc3\src
+ ///
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
var template = commandLineArgs.Options.GetOrNull(CommandOptions.Template.Short, CommandOptions.Template.Long);
var project = commandLineArgs.Options.GetOrNull(CommandOptions.Project.Short, CommandOptions.Project.Long);
- var accessToken = await _codeService.GetAccessTokenAsync();
+ var source = commandLineArgs.Options.GetOrNull(CommandOptions.Source.Short, CommandOptions.Source.Long);
+ source = source.IsNullOrWhiteSpace() ? Directory.GetCurrentDirectory() : source;
if (Guid.TryParse(template, out Guid templateId) && Guid.TryParse(project, out Guid projectId))
{
- var path = await _codeService.DownloadAsync(accessToken, projectId, templateId);
- ZipHelper.Extract(path);
+ // 生成后端代码还是前端代码
+ var type = AnsiConsole.Prompt(new SelectionPrompt().Title("请选择生成的代码?").AddChoices(new[]
+ {
+ Dotnet,
+ Vue3
+ }));
+
+ if (type == Dotnet)
+ {
+ await GenerateBackCode(projectId, templateId, source);
+ }
+ else if (type == Vue3)
+ {
+ await GenerateFrontCode(projectId, templateId, source);
+ }
+
+ AnsiConsole.MarkupLine("[green]恭喜你,代码生成成功,请打开项目检查![/]");
}
else
{
- Console.WriteLine("输入的模板 ID 或项目 ID 不是有效的 GUID 格式,请检查后重新输入。");
+ AnsiConsole.MarkupLine("[red]输入的模板 ID 或项目 ID 不是有效的 GUID 格式,请检查后重新输入。[/]");
+ }
+ }
+
+ private async Task GetProjectAsync(string accessToken, Guid projectId)
+ {
+ var project = await _codeService.GetProjectAndEntityAsync(accessToken, projectId);
+ if (project.Entities.Count == 0)
+ {
+ throw new UserFriendlyException("当前项目未定义实体");
}
+
+ return project;
+ }
+
+ ///
+ /// 生成后端代码
+ /// // https://spectreconsole.net/prompts/multiselection
+ ///
+ private async Task GenerateBackCode(Guid projectId, Guid templateId, string sourcePath)
+ {
+ var accessToken = await _codeService.GetAccessTokenAsync();
+
+ // 获取项目信息
+ var project = await GetProjectAsync(accessToken, projectId);
+
+ //判断是否是标准abp的项目结构方式
+ Utils.DirectoryHelper.IsAbpProjectStructure(sourcePath, project.Project.CompanyName, project.Project.ProjectName);
+
+ // 可以选择需要生成的实体
+ var entities = AnsiConsole.Prompt(
+ new MultiSelectionPrompt()
+ .Title("请选择需要生成的实体")
+ .Required()
+ .InstructionsText(
+ "[grey](按下空格键 [blue][/]切换是否选中, " +
+ "[white]上下建切换,[/] " +
+ "[green]按下回车键[/]确认)[/]")
+ .AddChoices(project.Entities.Select(e => e.Code)));
+
+
+ // 获取选中的实体信息
+ var entityId = project.Entities.Where(e => entities.Contains(e.Code)).Select(p => p.Id).ToList();
+
+ // 下载代码
+ var path = await _codeService.DownloadAsync(accessToken, projectId, templateId, entityId);
+
+ // 解压下载的代码
+ var extractPath = ZipHelper.Extract(path);
+
+ // 遍历选中实体生成对应层级的代码
+ foreach (var id in entityId)
+ {
+ var item = project.Entities.First(e => e.Id == id);
+ GenerateCode(extractPath, sourcePath, "Domain.Shared", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ GenerateCode(extractPath, sourcePath, "Domain", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ GenerateCode(extractPath, sourcePath, "Application.Contracts", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ GenerateCode(extractPath, sourcePath, "Application", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ GenerateCode(extractPath, sourcePath, "HttpApi", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ AppendIDbContextCode(extractPath, sourcePath, "EntityFrameworkCore", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ AppendDbContextCode(extractPath, sourcePath, "EntityFrameworkCore", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ AppendDbContextModelCreatingExtensionsCode(extractPath, sourcePath, "EntityFrameworkCore", item.CodePluralized, project.Project.CompanyName, project.Project.ProjectName);
+ }
+ }
+
+ ///
+ /// 生成前端代码
+ ///
+ private async Task GenerateFrontCode(Guid projectId, Guid templateId, string sourcePath)
+ {
+ var accessToken = await _codeService.GetAccessTokenAsync();
+ // 获取项目信息
+ var project = await GetProjectAsync(accessToken, projectId);
+
+ //判断是否是标准vben5的项目结构方式
+ Utils.DirectoryHelper.IsVben5ProjectStructure(sourcePath);
+
+ // 可以选择需要生成的实体
+ var entities = AnsiConsole.Prompt(
+ new MultiSelectionPrompt()
+ .Title("请选择需要生成的实体")
+ .Required()
+ .InstructionsText(
+ "[grey](按下空格键 [blue][/]切换是否选中, " +
+ "[white]上下建切换,[/] " +
+ "[green]按下回车键[/]确认)[/]")
+ .AddChoices(project.Entities.Select(e => e.Code)));
+
+
+ // 获取选中的实体信息
+ var entityId = project.Entities.Where(e => entities.Contains(e.Code)).Select(p => p.Id).ToList();
+
+ // 下载代码
+ var path = await _codeService.DownloadAsync(accessToken, projectId, templateId, entityId);
+
+ // 解压下载的代码
+ var extractPath = ZipHelper.Extract(path);
+
+ // 遍历选中实体生成对应层级的代码
+ foreach (var id in entityId)
+ {
+ var item = project.Entities.First(e => e.Id == id);
+ var sourceCodePath = Path.Combine(extractPath, "Vben5", "routes", item.CodePluralized);
+ var targetCodePath = Path.Combine(sourcePath, "router", "routes", "modules");
+ Utils.DirectoryHelper.CopyFolder(sourceCodePath, targetCodePath);
+
+ var sourceViewCodePath = Path.Combine(extractPath, "Vben5", "views", item.CodePluralized);
+ var targetViewCodePath = Path.Combine(sourcePath, "views", item.CodePluralized);
+ Utils.DirectoryHelper.CopyFolder(sourceViewCodePath, targetViewCodePath);
+ }
+ }
+
+ private void GenerateCode(string templateSourceCodePath, string sourcePath, string type, string entityCodePluralized, string companyName, string projectName)
+ {
+ var sourceCodePath = Path.Combine(templateSourceCodePath, "AspNetCore", "src", type, entityCodePluralized);
+ var targetCodePath = Path.Combine(sourcePath, $"{companyName}.{projectName}.{type}", entityCodePluralized);
+ Utils.DirectoryHelper.CopyFolder(sourceCodePath, targetCodePath);
+ }
+
+ private void AppendIDbContextCode(string templateSourceCodePath, string sourcePath, string type, string entityCodePluralized, string companyName, string projectName)
+ {
+ var basePath = Path.Combine(templateSourceCodePath, "AspNetCore", "src", type);
+ // 给IDbContext追加dbset
+ var sourceCodePath = Path.Combine(basePath, $"I{projectName}DbContext.cs");
+ var code = File.ReadAllText(sourceCodePath);
+
+ var targetCodePath = Path.Combine(sourcePath, $"{companyName}.{projectName}.{type}", type, $"I{projectName}DbContext.cs");
+ // 判断代码是否已经生成
+ if (CodeHelper.IsExistCode(targetCodePath, code))
+ {
+ return;
+ }
+
+ Utils.CodeHelper.AddCodeToInterface(targetCodePath, $"I{projectName}DbContext", code);
+ CodeHelper.AddUsing(targetCodePath, $"using {companyName}.{projectName}.{entityCodePluralized};");
+ }
+
+ private void AppendDbContextCode(string templateSourceCodePath, string sourcePath, string type, string entityCodePluralized, string companyName, string projectName)
+ {
+ var basePath = Path.Combine(templateSourceCodePath, "AspNetCore", "src", type);
+ // 给DbContext追加dbset
+ var dbContextCodePath = Path.Combine(basePath, $"{projectName}DbContext.cs");
+ var dbContextCode = File.ReadAllText(dbContextCodePath);
+
+ var targetDbContextCodePath = Path.Combine(sourcePath, $"{companyName}.{projectName}.{type}", type, $"{projectName}DbContext.cs");
+ // 判断代码是否已经生成
+ if (CodeHelper.IsExistCode(targetDbContextCodePath, dbContextCode))
+ {
+ return;
+ }
+
+ Utils.CodeHelper.AddCodeToClass(targetDbContextCodePath, $"{projectName}DbContext", dbContextCode);
+ CodeHelper.AddUsing(targetDbContextCodePath, $"using {companyName}.{projectName}.{entityCodePluralized};");
+ }
+
+ private void AppendDbContextModelCreatingExtensionsCode(string templateSourceCodePath, string sourcePath, string type, string entityCodePluralized, string companyName, string projectName)
+ {
+ var basePath = Path.Combine(templateSourceCodePath, "AspNetCore", "src", type);
+ // 给ContextModelCreatingExtensions追加ef 配置
+ var dbContextModelCreatingExtensionsPath = Path.Combine(basePath, $"{projectName}DbContextModelCreatingExtensions.cs");
+ var dbContextModelCreatingExtensionsCode = File.ReadAllText(dbContextModelCreatingExtensionsPath);
+ var targetDbContextModelCreatingExtensionsCodePath = Path.Combine(sourcePath, $"{companyName}.{projectName}.{type}", type, $"{projectName}DbContextModelCreatingExtensions.cs");
+ // 判断代码是否已经生成
+ if (CodeHelper.IsExistCode(targetDbContextModelCreatingExtensionsCodePath, dbContextModelCreatingExtensionsCode))
+ {
+ return;
+ }
+
+ Utils.CodeHelper.AddCodeToMethod(targetDbContextModelCreatingExtensionsCodePath, $"Configure{projectName}", dbContextModelCreatingExtensionsCode);
+ CodeHelper.AddUsing(targetDbContextModelCreatingExtensionsCodePath, $"using {companyName}.{projectName}.{entityCodePluralized};");
}
public void GetUsageInfo()
{
+ var sb = new StringBuilder();
+ sb.AppendLine("");
+ sb.AppendLine("Usage:");
+ sb.AppendLine(" lion.abp create");
+ sb.AppendLine("lion.abp create -t 模板名称(source | nuget) -c 公司名称 -p 项目名称");
+ AnsiConsole.MarkupLine($"[green]{sb.ToString()}[/]");
}
public string GetShortDescription()
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/ConfigCommand.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/ConfigCommand.cs
new file mode 100644
index 00000000..8aec7321
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/ConfigCommand.cs
@@ -0,0 +1,73 @@
+using Lion.AbpPro.Cli.Auth;
+
+namespace Lion.AbpPro.Cli.Commands;
+
+public class ConfigCommand : IConsoleCommand, ITransientDependency
+{
+ public const string Name = "config";
+ private readonly ILogger _logger;
+ private readonly IConfigService _configService;
+ private readonly IJsonSerializer _jsonSerializer;
+ private readonly ICodeService _codeService;
+
+ public ConfigCommand(ILogger logger, IConfigService configService, IJsonSerializer jsonSerializer, ICodeService codeService)
+ {
+ _logger = logger;
+ _configService = configService;
+ _jsonSerializer = jsonSerializer;
+ _codeService = codeService;
+ }
+
+ ///
+ /// config -c http://182.43.18.151:44317 -u admin -p 1q2w3E* -t ss
+ ///
+ public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
+ {
+ // 获取参数
+ var url = commandLineArgs.Options.GetOrNull(CommandOptions.CodeServiceUrl.Short, CommandOptions.CodeServiceUrl.Long);
+ var userName = commandLineArgs.Options.GetOrNull(CommandOptions.UserName.Short, CommandOptions.UserName.Long);
+ var password = commandLineArgs.Options.GetOrNull(CommandOptions.Password.Short, CommandOptions.Password.Long);
+ var tenantName = commandLineArgs.Options.GetOrNull(CommandOptions.TenantName.Short, CommandOptions.TenantName.Long);
+
+ //1 判断url是否有效
+ await _codeService.CheckHealthAsync(url);
+
+ var tenantId = string.Empty;
+ //2 判断租户是否存在
+ if (!tenantName.IsNullOrWhiteSpace())
+ {
+ var tenant = await _codeService.FindTenantAsync(url, tenantName);
+ tenantId = tenant.TenantId.ToString();
+ }
+
+ //3. 判断用户是否存在
+ await _codeService.LoginAsync(url, userName, password);
+
+ var content = new ConfigOptions()
+ {
+ CodeServiceUrl = url,
+ UserName = userName,
+ Password = password,
+ TenantName = tenantName,
+ TenantId = tenantId
+ };
+ await _configService.SetAsync(_jsonSerializer.Serialize(content));
+ AnsiConsole.MarkupLine("[green]恭喜你,恭喜你设置config成功![/]");
+ }
+
+ public void GetUsageInfo()
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine("");
+ sb.AppendLine("Usage:");
+ sb.AppendLine(" lion.abp config");
+ sb.AppendLine("");
+ sb.AppendLine("配置: lion.abp config");
+ _logger.LogInformation(sb.ToString());
+ }
+
+ public string GetShortDescription()
+ {
+ return "配置: lion.abp config -c http://182.43.18.151:44317 -u admin -p 1q2w3E* -t test";
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CreateCommand.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CreateCommand.cs
index 725df37c..5aa1951c 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CreateCommand.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/CreateCommand.cs
@@ -1,4 +1,5 @@
using Lion.AbpPro.Cli.Auth;
+using DirectoryHelper = Lion.AbpPro.Cli.Utils.DirectoryHelper;
namespace Lion.AbpPro.Cli.Commands;
@@ -116,7 +117,7 @@ public class CreateCommand : IConsoleCommand, ITransientDependency
- DirectoryAndFileHelper.CopyFolder(contentPath, output, templateOptions.ExcludeFiles);
+ DirectoryHelper.CopyFolder(contentPath, output, templateOptions.ExcludeFiles);
ReplaceHelper.ReplaceTemplates(
output,
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/NewCommand.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/NewCommand.cs
index 58e4088a..c484621e 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/NewCommand.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Commands/NewCommand.cs
@@ -1,4 +1,6 @@
-namespace Lion.AbpPro.Cli.Commands;
+using DirectoryHelper = Lion.AbpPro.Cli.Utils.DirectoryHelper;
+
+namespace Lion.AbpPro.Cli.Commands;
public class NewCommand : IConsoleCommand, ITransientDependency
{
@@ -126,7 +128,7 @@ public class NewCommand : IConsoleCommand, ITransientDependency
}
- DirectoryAndFileHelper.CopyFolder(contentPath, output, templateOptions.ExcludeFiles);
+ DirectoryHelper.CopyFolder(contentPath, output, templateOptions.ExcludeFiles);
ReplaceHelper.ReplaceTemplates(
output,
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/ErrorResponse.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/ErrorResponse.cs
new file mode 100644
index 00000000..a26ef348
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/ErrorResponse.cs
@@ -0,0 +1,15 @@
+namespace Lion.AbpPro.Cli.Dto;
+
+public class ErrorResponse
+{
+ public Error error { get; set; }
+}
+
+public class Error
+{
+ public object code { get; set; }
+ public string message { get; set; }
+ public object details { get; set; }
+ public object data { get; set; }
+ public object validationErrors { get; set; }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/FindTenantResponse.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/FindTenantResponse.cs
new file mode 100644
index 00000000..56e292f2
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/FindTenantResponse.cs
@@ -0,0 +1,8 @@
+namespace Lion.AbpPro.Cli.Dto;
+
+public class FindTenantResponse
+{
+ public Guid? TenantId { get; set; }
+
+ public bool Success { get; set; }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/GetProjectAndEntityResponse.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/GetProjectAndEntityResponse.cs
new file mode 100644
index 00000000..6afaa5cb
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Dto/GetProjectAndEntityResponse.cs
@@ -0,0 +1,54 @@
+namespace Lion.AbpPro.Cli.Dto;
+
+public class GetProjectAndEntityResponse
+{
+ public GetProjectAndEntityResponse()
+ {
+ Entities = new List();
+ }
+
+ public ProjectOutput Project { get; set; }
+
+ public List Entities { get; set; }
+}
+
+public class ProjectOutput
+{
+ public Guid Id { get; set; }
+
+ ///
+ /// 公司名称
+ ///
+ public string CompanyName { get; set; }
+
+ ///
+ /// 项目名称
+ ///
+ public string ProjectName { get; set; }
+}
+
+public class EntityOutput
+{
+ public Guid Id { get; set; }
+
+ ///
+ /// 编码
+ ///
+ public string Code { get; set; }
+
+ ///
+ /// 描述
+ ///
+ public string Description { get; set; }
+
+
+ ///
+ /// 首字母小写
+ ///
+ public string CodeCamelCase { get; set; }
+
+ ///
+ /// 复数形式
+ ///
+ public string CodePluralized { get; set; }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Github/AbpProManager.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Github/AbpProManager.cs
index 1532c63c..904dfdcb 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Github/AbpProManager.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Github/AbpProManager.cs
@@ -1,3 +1,4 @@
+using DirectoryHelper = Volo.Abp.IO.DirectoryHelper;
using Uri = System.Uri;
namespace Lion.AbpPro.Cli.Github;
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/ICodeService.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/ICodeService.cs
index 2cb2e866..d4dc86f8 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/ICodeService.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/ICodeService.cs
@@ -1,8 +1,19 @@
+using Lion.AbpPro.Cli.Dto;
+
namespace Lion.AbpPro.Cli;
public interface ICodeService
{
Task GetAccessTokenAsync();
- Task DownloadAsync(string accessToken, Guid projectId, Guid templateId);
+ Task DownloadAsync(string accessToken, Guid projectId, Guid templateId, List entityId);
+
+ Task GetProjectAndEntityAsync(string accessToken, Guid projectId);
+
+
+ Task CheckHealthAsync(string url);
+
+ Task FindTenantAsync(string url, string tenantName);
+
+ Task LoginAsync(string url, string userName, string password);
}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Options/ConfigOptions.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Options/ConfigOptions.cs
new file mode 100644
index 00000000..5fab6f22
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Options/ConfigOptions.cs
@@ -0,0 +1,14 @@
+namespace Lion.AbpPro.Cli.Options;
+
+public class ConfigOptions
+{
+ public string CodeServiceUrl { get; set; }
+
+ public string UserName { get; set; }
+
+ public string Password { get; set; }
+
+ public string TenantName { get; set; }
+
+ public string TenantId { get; set; }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/CodeHelper.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/CodeHelper.cs
new file mode 100644
index 00000000..6d71b766
--- /dev/null
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/CodeHelper.cs
@@ -0,0 +1,154 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Lion.AbpPro.Cli.Utils;
+
+public static class CodeHelper
+{
+ ///
+ /// 把指定代码添加到对应方法中
+ ///
+ public static void AddCodeToMethod(string filePath, string methodName, string addCode)
+ {
+ try
+ {
+ // 读取文件内容
+ var code = File.ReadAllText(filePath);
+
+ // 解析代码为语法树
+ var tree = CSharpSyntaxTree.ParseText(code);
+ var root = tree.GetCompilationUnitRoot();
+
+ // 查找所有的方法声明
+ var methodDeclarations = root.DescendantNodes().OfType();
+
+ // 筛选出名为 ConfigureOA 的方法
+ var configureOAMethod = methodDeclarations.FirstOrDefault(m => m.Identifier.ValueText == methodName);
+
+ if (configureOAMethod == null) return;
+ // 解析要添加的代码为语句
+ var newStatement = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot().DescendantNodes().OfType().FirstOrDefault();
+
+ if (newStatement == null) return;
+ // 在方法体中添加新语句
+ var newMethodBody = configureOAMethod?.Body?.AddStatements(newStatement);
+ var newMethod = configureOAMethod.WithBody(newMethodBody);
+
+ // 替换原方法为新方法
+ var newRoot = root.ReplaceNode(configureOAMethod, newMethod);
+
+ // 获取更新后的代码文本
+ var newCode = newRoot.GetText().ToString();
+ // 将更新后的代码写回文件
+ File.WriteAllText(filePath, newCode);
+ }
+ catch (Exception ex)
+ {
+ throw new UserFriendlyException($"发生错误AddCodeToMethod: {ex.Message}");
+ }
+ }
+
+ public static void AddCodeToClass(string filePath, string className, string addCode)
+ {
+ try
+ {
+ // 读取文件内容
+ var code = File.ReadAllText(filePath);
+ // 解析代码为语法树
+ var tree = CSharpSyntaxTree.ParseText(code);
+ var root = tree.GetCompilationUnitRoot();
+
+ // 查找 IOADbContext 接口声明
+ var interfaceDeclaration = root.DescendantNodes().OfType()
+ .FirstOrDefault(i => i.Identifier.ValueText == className);
+
+ if (interfaceDeclaration == null) return;
+ // 解析要添加的属性代码
+ var newProperty = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot()
+ .DescendantNodes().OfType().FirstOrDefault();
+
+ if (newProperty == null) return;
+ // 在接口成员中添加新属性
+ var newMembers = interfaceDeclaration.Members.Add(newProperty);
+ var newInterface = interfaceDeclaration.WithMembers(newMembers);
+
+ // 替换原接口声明为新接口声明
+ var newRoot = root.ReplaceNode(interfaceDeclaration, newInterface);
+
+ // 获取更新后的代码文本
+ var newCode = newRoot.GetText().ToString();
+ // 将更新后的代码写回文件
+ File.WriteAllText(filePath, newCode);
+ }
+ catch (Exception ex)
+ {
+ throw new UserFriendlyException($"发生错误AddCodeToClass: {ex.Message}");
+ }
+ }
+
+ public static void AddCodeToInterface(string filePath, string interfaceName, string addCode)
+ {
+ try
+ {
+ // 读取文件内容
+ var code = File.ReadAllText(filePath);
+
+ // 解析代码为语法树
+ var tree = CSharpSyntaxTree.ParseText(code);
+ var root = tree.GetCompilationUnitRoot();
+
+ // 查找 IOADbContext 接口声明
+ var interfaceDeclaration = root.DescendantNodes().OfType()
+ .FirstOrDefault(i => i.Identifier.ValueText == interfaceName);
+
+ if (interfaceDeclaration == null) return;
+ // 解析要添加的属性代码
+ var newProperty = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot()
+ .DescendantNodes().OfType().FirstOrDefault();
+
+ if (newProperty == null) return;
+ // 在接口成员中添加新属性
+ var newMembers = interfaceDeclaration.Members.Add(newProperty);
+ var newInterface = interfaceDeclaration.WithMembers(newMembers);
+
+ // 替换原接口声明为新接口声明
+ var newRoot = root.ReplaceNode(interfaceDeclaration, newInterface);
+
+ // 获取更新后的代码文本
+ var newCode = newRoot.GetText().ToString();
+ // 将更新后的代码写回文件
+ File.WriteAllText(filePath, newCode);
+ }
+ catch (Exception ex)
+ {
+ throw new UserFriendlyException($"发生错误AddCodeToInterface: {ex.Message}");
+ }
+ }
+
+ public static void AddUsing(string filePath, string addCode)
+ {
+ try
+ {
+ // 读取文件内容
+ var code = File.ReadAllText(filePath);
+
+ // 在第一行添加代码
+ var newSourceText = SourceText.From(addCode + Environment.NewLine + code);
+
+ // 将修改后的内容写回文件
+ File.WriteAllText(filePath, newSourceText.ToString());
+ }
+ catch (Exception ex)
+ {
+ throw new UserFriendlyException($"发生错误AddUsing: {ex.Message}");
+ }
+ }
+
+ public static bool IsExistCode(string filePath, string code)
+ {
+ var content = File.ReadAllText(filePath).Replace(" ", "");
+ return content.Contains(code.Replace(" ","").Replace("\r\n",""));
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryAndFileHelper.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryHelper.cs
similarity index 55%
rename from aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryAndFileHelper.cs
rename to aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryHelper.cs
index 3b7dc0ff..25606524 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryAndFileHelper.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/DirectoryHelper.cs
@@ -1,6 +1,6 @@
namespace Lion.AbpPro.Cli.Utils;
-public static class DirectoryAndFileHelper
+public static class DirectoryHelper
{
///
/// 复制文件夹及文件
@@ -95,4 +95,79 @@ public static class DirectoryAndFileHelper
throw new UserFriendlyException("删除文件失败!");
}
}
+
+ ///
+ /// 获取指定路径下所有扩展名为 .sln 的文件
+ ///
+ public static List GetSolutionFiles(string path)
+ {
+ var solutionFiles = new List();
+ var files = Directory.GetFiles(path, "*.sln", SearchOption.AllDirectories);
+ solutionFiles.AddRange(files);
+ return solutionFiles;
+ }
+
+ public static void IsAbpProjectStructure(string path, string companyName, string projectName)
+ {
+ var dir = Directory.GetDirectories(path);
+
+ if (
+ // 判断是否有Application
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.Application") &&
+ // 判断是否有Application.Contracts
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.Application.Contracts") &&
+ // 判断是否有Domain
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.Domain") &&
+ // 判断是否有Domain.Shared
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.Domain.Shared") &&
+ // 判断是否有EntityFrameworkCore
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.EntityFrameworkCore") &&
+ // 判断是否有HttpApi
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.HttpApi") &&
+ // 判断是否有HttpApi.Client
+ dir.Any(e => Path.GetFileName(e) == $"{companyName}.{projectName}.HttpApi.Client")
+ )
+ {
+ return;
+ }
+ else
+ {
+ throw new UserFriendlyException($"请确认项目路径下的项目是否是abp标准结构:{path}");
+ }
+ }
+
+ public static void IsVben5ProjectStructure(string path)
+ {
+ var dir = Directory.GetDirectories(path);
+
+ if (
+ // 判断是否有Application
+ dir.Any(e => Path.GetFileName(e) == $"router") &&
+ // 判断是否有Application.Contracts
+ dir.Any(e => Path.GetFileName(e) == $"views")
+ )
+ {
+ return;
+ }
+ else
+ {
+ throw new UserFriendlyException($"请确认项目路径下的项目是否是vben5标准结构:{path}");
+ }
+ }
+
+ private static bool CheckFolder(string path, string name)
+ {
+ var dir = Directory.GetDirectories(path);
+
+ // 检查路径是否指向一个文件夹
+ if (Directory.Exists(path))
+ {
+ // 获取文件夹名
+ var folderName = Path.GetFileName(path);
+ // 判断文件夹名是否以 'Application' 结尾
+ return folderName.EndsWith(name, StringComparison.OrdinalIgnoreCase);
+ }
+
+ return false;
+ }
}
\ No newline at end of file
diff --git a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/ZipHelper.cs b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/ZipHelper.cs
index 78649df0..b2887112 100644
--- a/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/ZipHelper.cs
+++ b/aspnet-core/frameworks/src/Lion.AbpPro.Cli.Core/Lion/AbpPro/Cli/Utils/ZipHelper.cs
@@ -40,7 +40,7 @@ public static class ZipHelper
if (Directory.Exists(targetPath))
{
- DirectoryAndFileHelper.DeletedDir(targetPath);
+ DirectoryHelper.DeletedDir(targetPath);
}
System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, targetPath, Encoding.UTF8, true);
diff --git a/aspnet-core/services/src/Lion.AbpPro.Domain/AbpProConsts.cs b/aspnet-core/services/src/Lion.AbpPro.Domain/AbpProDbProperties.cs
similarity index 75%
rename from aspnet-core/services/src/Lion.AbpPro.Domain/AbpProConsts.cs
rename to aspnet-core/services/src/Lion.AbpPro.Domain/AbpProDbProperties.cs
index 21d44dbb..75cb7c40 100644
--- a/aspnet-core/services/src/Lion.AbpPro.Domain/AbpProConsts.cs
+++ b/aspnet-core/services/src/Lion.AbpPro.Domain/AbpProDbProperties.cs
@@ -1,6 +1,6 @@
namespace Lion.AbpPro
{
- public static class AbpProConsts
+ public static class AbpProDbProperties
{
public const string DbTablePrefix = "App";
diff --git a/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs b/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs
index a5c259b1..297f406c 100644
--- a/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs
+++ b/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContext.cs
@@ -7,15 +7,6 @@ using Lion.AbpPro.LanguageManagement.LanguageTexts.Aggregates;
using Lion.AbpPro.NotificationManagement.Notifications.Aggregates;
namespace Lion.AbpPro.EntityFrameworkCore
{
- /* This is your actual DbContext used on runtime.
- * It includes only your entities.
- * It does not include entities of the used modules, because each module has already
- * its own DbContext class. If you want to share some database tables with the used modules,
- * just create a structure like done for AppUser.
- *
- * Don't use this DbContext for database migrations since it does not contain tables of the
- * used modules (as explained above). See AbpProMigrationsDbContext for migrations.
- */
[ConnectionStringName("Default")]
public class AbpProDbContext : AbpDbContext, IAbpProDbContext,
IBasicManagementDbContext,
@@ -87,8 +78,5 @@ namespace Lion.AbpPro.EntityFrameworkCore
// 文件模块
builder.ConfigureFileManagement();
}
-
-
-
}
}
\ No newline at end of file
diff --git a/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContextModelCreatingExtensions.cs b/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContextModelCreatingExtensions.cs
index 7eecca5c..4a7f0862 100644
--- a/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContextModelCreatingExtensions.cs
+++ b/aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProDbContextModelCreatingExtensions.cs
@@ -1,19 +1,11 @@
-namespace Lion.AbpPro.EntityFrameworkCore
-{
- public static class AbpProDbContextModelCreatingExtensions
- {
- public static void ConfigureAbpPro(this ModelBuilder builder)
- {
- Check.NotNull(builder, nameof(builder));
+using Volo.Abp.EntityFrameworkCore.Modeling;
- /* Configure your own tables/entities inside here */
+namespace Lion.AbpPro.EntityFrameworkCore;
- //builder.Entity(b =>
- //{
- // b.ToTable(AbpProConsts.DbTablePrefix + "YourEntities", AbpProConsts.DbSchema);
- // b.ConfigureByConvention(); //auto configure for the base class props
- // //...
- //});
- }
+public static class AbpProDbContextModelCreatingExtensions
+{
+ public static void ConfigureAbpPro(this ModelBuilder builder)
+ {
+ Check.NotNull(builder, nameof(builder));
}
}
\ No newline at end of file
diff --git a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameConsts.cs b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameProperties.cs
similarity index 50%
rename from templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameConsts.cs
rename to templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameProperties.cs
index b6fa3d11..f364cad0 100644
--- a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameConsts.cs
+++ b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.Domain/MyProjectNameProperties.cs
@@ -1,8 +1,8 @@
namespace MyCompanyName.MyProjectName
{
- public static class MyProjectNameConsts
+ public static class MyProjectNameProperties
{
- public const string DbTablePrefix = "App";
+ public const string DbTablePrefix = "Abp";
public const string DbSchema = null;
}
diff --git a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
index 610ddc91..89dc4517 100644
--- a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
+++ b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
@@ -1,14 +1,5 @@
namespace MyCompanyName.MyProjectName.EntityFrameworkCore
{
- /* This is your actual DbContext used on runtime.
- * It includes only your entities.
- * It does not include entities of the used modules, because each module has already
- * its own DbContext class. If you want to share some database tables with the used modules,
- * just create a structure like done for AppUser.
- *
- * Don't use this DbContext for database migrations since it does not contain tables of the
- * used modules (as explained above). See MyProjectNameMigrationsDbContext for migrations.
- */
[ConnectionStringName("Default")]
public class MyProjectNameDbContext : AbpDbContext, IMyProjectNameDbContext,
IBasicManagementDbContext,
diff --git a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs
index b7f02aa1..f355186d 100644
--- a/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs
+++ b/templates/pro-nuget/service/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContextModelCreatingExtensions.cs
@@ -1,19 +1,11 @@
-namespace MyCompanyName.MyProjectName.EntityFrameworkCore
-{
- public static class MyProjectNameDbContextModelCreatingExtensions
- {
- public static void ConfigureMyProjectName(this ModelBuilder builder)
- {
- Check.NotNull(builder, nameof(builder));
+using Volo.Abp.EntityFrameworkCore.Modeling;
- /* Configure your own tables/entities inside here */
+namespace MyCompanyName.MyProjectName.EntityFrameworkCore;
- //builder.Entity(b =>
- //{
- // b.ToTable(MyProjectNameConsts.DbTablePrefix + "YourEntities", MyProjectNameConsts.DbSchema);
- // b.ConfigureByConvention(); //auto configure for the base class props
- // //...
- //});
- }
+public static class MyProjectNameDbContextModelCreatingExtensions
+{
+ public static void ConfigureMyProjectName(this ModelBuilder builder)
+ {
+ Check.NotNull(builder, nameof(builder));
}
}
\ No newline at end of file