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