28 changed files with 864 additions and 94 deletions
@ -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<ConfigOptions> 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<ConfigOptions>(content); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
namespace Lion.AbpPro.Cli.Auth; |
|||
|
|||
public interface IConfigService |
|||
{ |
|||
/// <summary>
|
|||
/// 设置token
|
|||
/// </summary>
|
|||
Task SetAsync(string config); |
|||
|
|||
/// <summary>
|
|||
/// 获取token
|
|||
/// </summary>
|
|||
Task<ConfigOptions> GetAsync(); |
|||
} |
|||
@ -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<ConfigCommand> _logger; |
|||
private readonly IConfigService _configService; |
|||
private readonly IJsonSerializer _jsonSerializer; |
|||
private readonly ICodeService _codeService; |
|||
|
|||
public ConfigCommand(ILogger<ConfigCommand> logger, IConfigService configService, IJsonSerializer jsonSerializer, ICodeService codeService) |
|||
{ |
|||
_logger = logger; |
|||
_configService = configService; |
|||
_jsonSerializer = jsonSerializer; |
|||
_codeService = codeService; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// config -c http://182.43.18.151:44317 -u admin -p 1q2w3E* -t ss
|
|||
/// </summary>
|
|||
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"; |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Lion.AbpPro.Cli.Dto; |
|||
|
|||
public class FindTenantResponse |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public bool Success { get; set; } |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
namespace Lion.AbpPro.Cli.Dto; |
|||
|
|||
public class GetProjectAndEntityResponse |
|||
{ |
|||
public GetProjectAndEntityResponse() |
|||
{ |
|||
Entities = new List<EntityOutput>(); |
|||
} |
|||
|
|||
public ProjectOutput Project { get; set; } |
|||
|
|||
public List<EntityOutput> Entities { get; set; } |
|||
} |
|||
|
|||
public class ProjectOutput |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 公司名称
|
|||
/// </summary>
|
|||
public string CompanyName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 项目名称
|
|||
/// </summary>
|
|||
public string ProjectName { get; set; } |
|||
} |
|||
|
|||
public class EntityOutput |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 编码
|
|||
/// </summary>
|
|||
public string Code { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 描述
|
|||
/// </summary>
|
|||
public string Description { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 首字母小写
|
|||
/// </summary>
|
|||
public string CodeCamelCase { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 复数形式
|
|||
/// </summary>
|
|||
public string CodePluralized { get; set; } |
|||
} |
|||
@ -1,8 +1,19 @@ |
|||
using Lion.AbpPro.Cli.Dto; |
|||
|
|||
namespace Lion.AbpPro.Cli; |
|||
|
|||
public interface ICodeService |
|||
{ |
|||
Task<string> GetAccessTokenAsync(); |
|||
|
|||
Task<string> DownloadAsync(string accessToken, Guid projectId, Guid templateId); |
|||
Task<string> DownloadAsync(string accessToken, Guid projectId, Guid templateId, List<Guid> entityId); |
|||
|
|||
Task<GetProjectAndEntityResponse> GetProjectAndEntityAsync(string accessToken, Guid projectId); |
|||
|
|||
|
|||
Task CheckHealthAsync(string url); |
|||
|
|||
Task<FindTenantResponse> FindTenantAsync(string url, string tenantName); |
|||
|
|||
Task<string> LoginAsync(string url, string userName, string password); |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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 |
|||
{ |
|||
/// <summary>
|
|||
/// 把指定代码添加到对应方法中
|
|||
/// </summary>
|
|||
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<MethodDeclarationSyntax>(); |
|||
|
|||
// 筛选出名为 ConfigureOA 的方法
|
|||
var configureOAMethod = methodDeclarations.FirstOrDefault(m => m.Identifier.ValueText == methodName); |
|||
|
|||
if (configureOAMethod == null) return; |
|||
// 解析要添加的代码为语句
|
|||
var newStatement = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot().DescendantNodes().OfType<StatementSyntax>().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<ClassDeclarationSyntax>() |
|||
.FirstOrDefault(i => i.Identifier.ValueText == className); |
|||
|
|||
if (interfaceDeclaration == null) return; |
|||
// 解析要添加的属性代码
|
|||
var newProperty = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot() |
|||
.DescendantNodes().OfType<PropertyDeclarationSyntax>().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<InterfaceDeclarationSyntax>() |
|||
.FirstOrDefault(i => i.Identifier.ValueText == interfaceName); |
|||
|
|||
if (interfaceDeclaration == null) return; |
|||
// 解析要添加的属性代码
|
|||
var newProperty = CSharpSyntaxTree.ParseText(addCode).GetCompilationUnitRoot() |
|||
.DescendantNodes().OfType<PropertyDeclarationSyntax>().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","")); |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
namespace Lion.AbpPro |
|||
{ |
|||
public static class AbpProConsts |
|||
public static class AbpProDbProperties |
|||
{ |
|||
public const string DbTablePrefix = "App"; |
|||
|
|||
@ -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<YourEntity>(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)); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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<YourEntity>(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)); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue