From 4be03b0aab27fca1b8896a5ce4b22b4521e713b7 Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Fri, 3 Feb 2023 19:44:47 +0800
Subject: [PATCH] feat(cli): add generate vben ui script command.
---
.../LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj | 34 +--
.../LINGYUN/Abp/Cli/AbpCliModule.cs | 16 ++
.../Abp/Cli/Commands/GenerateProxyCommand.cs | 2 +-
.../Abp/Cli/Commands/GenerateViewCommand.cs | 139 ++++++++++++
.../CSharp/CSharpServiceProxyGenerator.cs | 7 +-
.../Abp/Cli/UI/AbpCliViewGeneratorOptions.cs | 13 ++
.../LINGYUN/Abp/Cli/UI/GenerateViewArgs.cs | 26 +++
.../LINGYUN/Abp/Cli/UI/IViewGenerator.cs | 7 +
.../Cli/UI/Vben/IVbenModelScriptGenerator.cs | 17 ++
.../Cli/UI/Vben/IVbenViewScriptGenerator.cs | 21 ++
.../Cli/UI/Vben/VbenModelScriptGenerator.cs | 212 ++++++++++++++++++
.../VbenScriptTemplateDefinitionProvider.cs | 50 +++++
.../Abp/Cli/UI/Vben/VbenViewGenerator.cs | 111 +++++++++
.../Cli/UI/Vben/VbenViewScriptGenerator.cs | 103 +++++++++
.../LINGYUN/Abp/Cli/UI/ViewGeneratorBase.cs | 70 ++++++
.../Properties/launchSettings.json | 3 +-
16 files changed, 814 insertions(+), 17 deletions(-)
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateViewCommand.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/AbpCliViewGeneratorOptions.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/GenerateViewArgs.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/IViewGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenModelScriptGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenViewScriptGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenModelScriptGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenScriptTemplateDefinitionProvider.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewScriptGenerator.cs
create mode 100644 aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/ViewGeneratorBase.cs
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj
index 671afeaa8..e948a6227 100644
--- a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj
@@ -1,20 +1,25 @@
-
-
- Exe
- net7.0
- 6.0.2
- colin
- Use LINGYUN.MicroService.Templates command line
- true
- labp
- ./nupkg
- MIT
- https://github.com/colinin/abp-next-admin
-
-
+
+
+ Exe
+ net7.0
+ 7.0.0
+ colin
+ Use LINGYUN.MicroService.Templates command line
+ true
+ labp
+ ./nupkg
+ MIT
+ https://github.com/colinin/abp-next-admin
+
+
+
+
+
+
+
@@ -26,6 +31,7 @@
+
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/AbpCliModule.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/AbpCliModule.cs
index 2d8f1bea4..82776be13 100644
--- a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/AbpCliModule.cs
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/AbpCliModule.cs
@@ -1,27 +1,38 @@
using LINGYUN.Abp.Cli.Commands;
using LINGYUN.Abp.Cli.ServiceProxying.CSharp;
using LINGYUN.Abp.Cli.ServiceProxying.TypeScript;
+using LINGYUN.Abp.Cli.UI;
+using LINGYUN.Abp.Cli.UI.Vben;
using Volo.Abp.Autofac;
using Volo.Abp.Cli;
using Volo.Abp.Cli.ServiceProxying;
using Volo.Abp.Modularity;
+using Volo.Abp.TextTemplating.Scriban;
+using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Cli
{
[DependsOn(
typeof(AbpCliCoreModule),
+ typeof(AbpTextTemplatingScribanModule),
typeof(AbpAutofacModule)
)]
public class AbpCliModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
Configure(options =>
{
options.Commands.Clear();
options.Commands[HelpCommand.Name] = typeof(HelpCommand);
options.Commands[CreateCommand.Name] = typeof(CreateCommand);
options.Commands[GenerateProxyCommand.Name] = typeof(GenerateProxyCommand);
+ options.Commands[GenerateViewCommand.Name] = typeof(GenerateViewCommand);
});
Configure(options =>
@@ -37,6 +48,11 @@ namespace LINGYUN.Abp.Cli
options.ScriptGenerators[VbenDynamicHttpApiScriptGenerator.Name] = new VbenDynamicHttpApiScriptGenerator();
options.ScriptGenerators[UniAppAxiosHttpApiScriptGenerator.Name] = new UniAppAxiosHttpApiScriptGenerator();
});
+
+ Configure(options =>
+ {
+ options.Generators[VbenViewGenerator.Name] = typeof(VbenViewGenerator);
+ });
}
}
}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateProxyCommand.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateProxyCommand.cs
index a76c5daaf..5a581ae59 100644
--- a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateProxyCommand.cs
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateProxyCommand.cs
@@ -66,7 +66,7 @@ public class GenerateProxyCommand : IConsoleCommand, ITransientDependency
var source = commandLineArgs.Options.GetOrNull(Options.Source.Short, Options.Source.Long);
var workDirectory = commandLineArgs.Options.GetOrNull(Options.WorkDirectory.Short, Options.WorkDirectory.Long) ?? Directory.GetCurrentDirectory();
var folder = commandLineArgs.Options.GetOrNull(Options.Folder.Long);
- var serviceTypeArg = commandLineArgs.Options.GetOrNull(Options.Module.Short, Options.ServiceType.Long);
+ var serviceTypeArg = commandLineArgs.Options.GetOrNull(Options.ServiceType.Short, Options.ServiceType.Long);
ServiceType? serviceType = null;
if (!serviceTypeArg.IsNullOrWhiteSpace())
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateViewCommand.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateViewCommand.cs
new file mode 100644
index 000000000..4296a1820
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/GenerateViewCommand.cs
@@ -0,0 +1,139 @@
+using LINGYUN.Abp.Cli.UI;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using System;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Cli;
+using Volo.Abp.Cli.Args;
+using Volo.Abp.Cli.Commands;
+using Volo.Abp.Cli.ServiceProxying;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Cli.Commands;
+public class GenerateViewCommand : IConsoleCommand, ITransientDependency
+{
+ public const string Name = "generate-view";
+
+ protected string CommandName => Name;
+
+ protected AbpCliViewGeneratorOptions ViewGeneratorOptions { get; }
+
+ protected IServiceScopeFactory ServiceScopeFactory { get; }
+
+ public GenerateViewCommand(
+ IOptions viewGeneratorOptions,
+ IServiceScopeFactory serviceScopeFactory)
+ {
+ ServiceScopeFactory = serviceScopeFactory;
+ ViewGeneratorOptions = viewGeneratorOptions.Value;
+ }
+
+ public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
+ {
+ var generateType = commandLineArgs.Options.GetOrNull(Options.GenerateType.Short, Options.GenerateType.Long)?.ToUpper();
+
+ if (!ViewGeneratorOptions.Generators.ContainsKey(generateType))
+ {
+ throw new CliUsageException("Option Type value is invalid" +
+ Environment.NewLine +
+ GetUsageInfo());
+ }
+
+ using var scope = ServiceScopeFactory.CreateScope();
+ var generatorType = ViewGeneratorOptions.Generators[generateType];
+ var serviceProxyGenerator = scope.ServiceProvider.GetService(generatorType).As();
+
+ await serviceProxyGenerator.GenerateAsync(BuildArgs(commandLineArgs));
+ }
+
+ private GenerateViewArgs BuildArgs(CommandLineArgs commandLineArgs)
+ {
+ var url = commandLineArgs.Options.GetOrNull(Options.Url.Short, Options.Url.Long);
+ var output = commandLineArgs.Options.GetOrNull(Options.Output.Short, Options.Output.Long);
+ var module = commandLineArgs.Options.GetOrNull(Options.Module.Short, Options.Module.Long) ?? "app";
+ var serviceTypeArg = commandLineArgs.Options.GetOrNull(Options.ServiceType.Short, Options.ServiceType.Long);
+
+ ServiceType? serviceType = null;
+ if (!serviceTypeArg.IsNullOrWhiteSpace())
+ {
+ serviceType = serviceTypeArg.ToLower() == "application"
+ ? ServiceType.Application
+ : serviceTypeArg.ToLower() == "integration"
+ ? ServiceType.Integration
+ : null;
+ }
+
+ return new GenerateViewArgs(
+ module,
+ url,
+ output,
+ serviceType);
+ }
+
+ public string GetShortDescription()
+ {
+ return "Generate the view code from the http api proxy.";
+ }
+
+ public string GetUsageInfo()
+ {
+ var sb = new StringBuilder();
+
+ sb.AppendLine("");
+ sb.AppendLine("Usage:");
+ sb.AppendLine("");
+ sb.AppendLine($" labp {CommandName}");
+ sb.AppendLine("");
+ sb.AppendLine("Options:");
+ sb.AppendLine("");
+ sb.AppendLine("-t Generate ui script(vben-view、vben-model).");
+ sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
+
+ sb.AppendLine("");
+ sb.AppendLine("Examples:");
+ sb.AppendLine("");
+
+ sb.AppendLine(" labp generate-proxy -t vben-view -m identity -o api/identity -url https://localhost:44302/");
+
+ return sb.ToString();
+ }
+
+ public static class Options
+ {
+ public static class GenerateType
+ {
+ public const string Short = "t";
+ public const string Long = "type";
+ }
+
+ public static class Module
+ {
+ public const string Short = "m";
+ public const string Long = "module";
+ }
+
+ public static class Output
+ {
+ public const string Short = "o";
+ public const string Long = "output";
+ }
+
+ public static class Folder
+ {
+ public const string Long = "folder";
+ }
+
+ public static class Url
+ {
+ public const string Short = "u";
+ public const string Long = "url";
+ }
+
+ public static class ServiceType
+ {
+ public const string Short = "st";
+ public const string Long = "service-type";
+ }
+ }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs
index eac4e173a..bd81db0c0 100644
--- a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/ServiceProxying/CSharp/CSharpServiceProxyGenerator.cs
@@ -86,7 +86,12 @@ public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase x.Controllers))
{
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/AbpCliViewGeneratorOptions.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/AbpCliViewGeneratorOptions.cs
new file mode 100644
index 000000000..d0e113615
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/AbpCliViewGeneratorOptions.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.Cli.UI;
+public class AbpCliViewGeneratorOptions
+{
+ public IDictionary Generators { get; }
+
+ public AbpCliViewGeneratorOptions()
+ {
+ Generators = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+ }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/GenerateViewArgs.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/GenerateViewArgs.cs
new file mode 100644
index 000000000..1501ed0cf
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/GenerateViewArgs.cs
@@ -0,0 +1,26 @@
+using Volo.Abp.Cli.ServiceProxying;
+
+namespace LINGYUN.Abp.Cli.UI;
+
+public class GenerateViewArgs
+{
+ public GenerateViewArgs(
+ string module,
+ string url,
+ string output,
+ ServiceType? serviceType = null)
+ {
+ Module = module;
+ Url = url;
+ Output = output;
+ ServiceType = serviceType;
+ }
+
+ public string Module { get; }
+
+ public string Output { get; }
+
+ public string Url { get; }
+
+ public ServiceType? ServiceType { get; }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/IViewGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/IViewGenerator.cs
new file mode 100644
index 000000000..f5f85cba4
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/IViewGenerator.cs
@@ -0,0 +1,7 @@
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Cli.UI;
+public interface IViewGenerator
+{
+ Task GenerateAsync(GenerateViewArgs args);
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenModelScriptGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenModelScriptGenerator.cs
new file mode 100644
index 000000000..9bc419120
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenModelScriptGenerator.cs
@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Volo.Abp.Http.Modeling;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+
+public interface IVbenModelScriptGenerator
+{
+ Task CreateModel(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel);
+
+ Task CreateTable(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel);
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenViewScriptGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenViewScriptGenerator.cs
new file mode 100644
index 000000000..e94510ef2
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/IVbenViewScriptGenerator.cs
@@ -0,0 +1,21 @@
+using System.Threading.Tasks;
+using Volo.Abp.Http.Modeling;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+public interface IVbenViewScriptGenerator
+{
+ Task CreateModal(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel);
+
+ Task CreateTable(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel);
+
+ Task CreateIndex(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel);
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenModelScriptGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenModelScriptGenerator.cs
new file mode 100644
index 000000000..a058a4881
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenModelScriptGenerator.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Http.Modeling;
+using Volo.Abp.TextTemplating;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+
+public class VbenModelScriptGenerator : IVbenModelScriptGenerator, ISingletonDependency
+{
+ private readonly ITemplateRenderer _templateRenderer;
+
+ public VbenModelScriptGenerator(
+ ITemplateRenderer templateRenderer)
+ {
+ _templateRenderer = templateRenderer;
+ }
+
+ public async virtual Task CreateModel(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel)
+ {
+ var searchModels = new List();
+ var inputModels = new List();
+
+ var moduleDefinition = appModel.Modules
+ .Where(module => module.Key.Equals(args.Module))
+ .Select(module => module.Value)
+ .FirstOrDefault();
+
+ var listResultAction = controllerModel.Actions
+ .Where(action => action.Value.ReturnValue.TypeSimple.Contains("ListResultDto"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+
+ searchModels.Add(
+ new ComponentModel
+ {
+ Name = "filter",
+ Component = "Input",
+ DisplayName = "Search",
+ ColProps = "{" +
+ "span: 24" +
+ "}",
+ });
+
+ if (listResultAction != null)
+ {
+ foreach (var inputParamter in listResultAction.Parameters)
+ {
+ if (appModel.Types.TryGetValue(inputParamter.Type, out var inputModelType))
+ {
+ var span = inputModelType.Properties.Length > 3 ? 8
+ : inputModelType.Properties.Length > 2 ? 12
+ : 24;
+ foreach (var inputModelProp in inputModelType.Properties)
+ {
+ var component = new ComponentModel
+ {
+ Name = inputModelProp.JsonName ?? inputModelProp.Name.ToCamelCase(),
+ Component = "Input",
+ DisplayName = "DisplayName:" + inputModelProp.Name.ToPascalCase(),
+ Required = inputModelProp.IsRequired,
+ ColProps = "" +
+ "{" +
+ $"span: {span}" +
+ "}",
+ };
+
+ if (appModel.Types.TryGetValue(inputModelProp.Type, out var inputModelPropType) &&
+ inputModelPropType.IsEnum)
+ {
+ component.Component = "Select";
+
+ var optionsStr = Environment.NewLine;
+
+ var options = new object[inputModelPropType.EnumNames.Length];
+ for (var index = 0; index < inputModelPropType.EnumNames.Length; index++)
+ {
+ optionsStr += "" +
+ "{" +
+ $"label: {inputModelPropType.EnumNames[index]}," +
+ $"value: {inputModelPropType.EnumValues[index]}," +
+ "}" +
+ "" + Environment.NewLine;
+ }
+ component.ComponentProps = "" +
+ "{" +
+ $"options: [{optionsStr}]" +
+ "}";
+ }
+
+ searchModels.Add(component);
+ }
+ }
+ }
+ }
+
+ var createOrUpdateAction = controllerModel.Actions
+ .Where(action => action.Value.UniqueName.Contains("Create") || action.Value.UniqueName.Contains("Update"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+
+ if (createOrUpdateAction != null)
+ {
+ foreach (var createOrUpdateParamter in createOrUpdateAction.Parameters)
+ {
+ if (appModel.Types.TryGetValue(createOrUpdateParamter.Type, out var inputModelType))
+ {
+ foreach (var inputModelProp in inputModelType.Properties)
+ {
+ var component = new ComponentModel
+ {
+ Name = inputModelProp.JsonName ?? inputModelProp.Name.ToCamelCase(),
+ Component = "Input",
+ DisplayName = "DisplayName:" + inputModelProp.Name.ToPascalCase(),
+ Required = inputModelProp.IsRequired,
+ ColProps = "" +
+ "{" +
+ "span: 24" +
+ "}",
+ ComponentProps = "{}"
+ };
+
+ inputModels.Add(component);
+ }
+ }
+ }
+ }
+
+ var modelDataContent = await _templateRenderer.RenderAsync(
+ "VbenModelData",
+ new
+ {
+ RemoteService = moduleDefinition.RemoteServiceName,
+ ExistsSearchModels = searchModels.Any(),
+ SearchModels = searchModels,
+ InputModels = inputModels,
+ });
+
+ return modelDataContent;
+ }
+
+ public async virtual Task CreateTable(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel)
+ {
+ var ouputModels = new List();
+
+ var moduleDefinition = appModel.Modules
+ .Where(module => module.Key.Equals(args.Module))
+ .Select(module => module.Value)
+ .FirstOrDefault();
+
+ var listResultAction = controllerModel.Actions
+ .Where(action => action.Value.ReturnValue.TypeSimple.Contains("ListResultDto")
+ || action.Value.ReturnValue.TypeSimple.Contains("PagedResultDto"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+
+ if (listResultAction != null)
+ {
+ foreach (var inputParamter in listResultAction.Parameters)
+ {
+ if (appModel.Types.TryGetValue(inputParamter.Type, out var inputModelType))
+ {
+ var span = inputModelType.Properties.Length > 3 ? 8
+ : inputModelType.Properties.Length > 2 ? 12
+ : 24;
+ foreach (var inputModelProp in inputModelType.Properties)
+ {
+ var component = new ComponentModel
+ {
+ Name = inputModelProp.JsonName ?? inputModelProp.Name.ToCamelCase(),
+ DisplayName = "DisplayName:" + inputModelProp.Name.ToPascalCase()
+ };
+
+ ouputModels.Add(component);
+ }
+ }
+ }
+ }
+
+ var tableDataContent = await _templateRenderer.RenderAsync(
+ "VbenTableData",
+ new
+ {
+ RemoteService = moduleDefinition.RemoteServiceName,
+ OuputModels = ouputModels,
+ });
+
+ return tableDataContent;
+ }
+}
+
+public class ComponentModel
+{
+ public string Name { get; set; }
+ public string Component { get; set; }
+ public string DisplayName { get; set; }
+ public object ColProps { get; set; }
+ public object ComponentProps { get; set; }
+ public string Align { get; set; } = "left";
+ public int Width { get; set; } = 120;
+ public bool Sorter { get; set; } = true;
+ public bool Resizable { get; set; } = true;
+ public bool Required { get; set; } = false;
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenScriptTemplateDefinitionProvider.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenScriptTemplateDefinitionProvider.cs
new file mode 100644
index 000000000..9a66c45ce
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenScriptTemplateDefinitionProvider.cs
@@ -0,0 +1,50 @@
+using Volo.Abp.Localization;
+using Volo.Abp.TextTemplating;
+using static Volo.Abp.Cli.Commands.AddPackageCommand.Options;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+
+public class VbenScriptTemplateDefinitionProvider : TemplateDefinitionProvider
+{
+ public override void Define(ITemplateDefinitionContext context)
+ {
+ context.Add(CreateCliTemplates());
+ }
+
+ private static TemplateDefinition[] CreateCliTemplates()
+ {
+ return new[]
+ {
+ new TemplateDefinition(
+ "VbenModelData",
+ typeof(DefaultResource),
+ L("Templates:VbenModelData")
+ ).WithVirtualFilePath("/LINGYUN/Abp/Cli/UI/Vben/Templates/VbenModelDataScript.tpl", true),
+ new TemplateDefinition(
+ "VbenModalView",
+ typeof(DefaultResource),
+ L("Templates:VbenModalView")
+ ).WithVirtualFilePath("/LINGYUN/Abp/Cli/UI/Vben/Templates/VbenModalViewScript.tpl", true),
+ new TemplateDefinition(
+ "VbenTableData",
+ typeof(DefaultResource),
+ L("Templates:VbenTableData")
+ ).WithVirtualFilePath("/LINGYUN/Abp/Cli/UI/Vben/Templates/VbenTableDataScript.tpl", true),
+ new TemplateDefinition(
+ "VbenTableView",
+ typeof(DefaultResource),
+ L("Templates:VbenTableView")
+ ).WithVirtualFilePath("/LINGYUN/Abp/Cli/UI/Vben/Templates/VbenTableViewScript.tpl", true),
+ new TemplateDefinition(
+ "VbenComponentIndex",
+ typeof(DefaultResource),
+ L("Templates:VbenComponentIndex")
+ ).WithVirtualFilePath("/LINGYUN/Abp/Cli/UI/Vben/Templates/VbenComponentIndexScript.tpl", true),
+ };
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewGenerator.cs
new file mode 100644
index 000000000..8a0a885f7
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewGenerator.cs
@@ -0,0 +1,111 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Volo.Abp.Cli.Http;
+using Volo.Abp.Cli.ServiceProxying;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Http.Modeling;
+using Volo.Abp.IO;
+using Volo.Abp.Json;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+public class VbenViewGenerator : ViewGeneratorBase, ISingletonDependency
+{
+ public const string Name = "Vben-View";
+
+ protected IVbenModelScriptGenerator ModelScriptGenerator { get; }
+ protected IVbenViewScriptGenerator ViewScriptGenerator { get; }
+ public VbenViewGenerator(
+ CliHttpClientFactory cliHttpClientFactory,
+ IJsonSerializer jsonSerializer,
+ IVbenModelScriptGenerator modelScriptGenerator,
+ IVbenViewScriptGenerator viewScriptGenerator)
+ : base(cliHttpClientFactory, jsonSerializer)
+ {
+ ModelScriptGenerator = modelScriptGenerator;
+ ViewScriptGenerator = viewScriptGenerator;
+ }
+
+ private async Task CreateAndSaveSciptToDisk(string scriptFile, string script)
+ {
+ Logger.LogInformation($"The script output file: {scriptFile}.");
+ Logger.LogInformation($"Saving script: {scriptFile}.");
+
+ FileHelper.DeleteIfExists(scriptFile);
+
+ await File.AppendAllTextAsync(scriptFile, script);
+
+ Logger.LogInformation($"Saved script: {scriptFile} has successful.");
+ }
+
+ public async override Task GenerateAsync(GenerateViewArgs args)
+ {
+ var applicationApiDescriptionModel = await GetApplicationApiDescriptionModelAsync(
+ args,
+ new ApplicationApiDescriptionModelRequestDto
+ {
+ IncludeTypes = true
+ });
+ var outputFolderRoot = args.Output;
+
+ foreach (var module in applicationApiDescriptionModel.Modules)
+ {
+ Logger.LogInformation($"Generating script with remote service: {module.Value.RemoteServiceName}.");
+
+ foreach (var controller in module.Value.Controllers)
+ {
+ var componentScriptPath = Path.Combine(
+ outputFolderRoot,
+ module.Value.RemoteServiceName.ToKebabCase(),
+ controller.Value.ControllerName.ToKebabCase());
+
+ var modelScriptPath = Path.Combine(componentScriptPath, "datas");
+ DirectoryHelper.CreateIfNotExists(modelScriptPath);
+
+ await CreateAndSaveSciptToDisk(
+ Path.Combine(modelScriptPath, "ModalData.ts"),
+ await ModelScriptGenerator.CreateModel(
+ args,
+ applicationApiDescriptionModel,
+ controller.Value));
+
+ await CreateAndSaveSciptToDisk(
+ Path.Combine(modelScriptPath, "TableData.ts"),
+ await ModelScriptGenerator.CreateTable(
+ args,
+ applicationApiDescriptionModel,
+ controller.Value));
+
+ var viewScriptPath = Path.Combine(componentScriptPath, "components");
+ DirectoryHelper.CreateIfNotExists(viewScriptPath);
+
+ await CreateAndSaveSciptToDisk(
+ Path.Combine(viewScriptPath, $"{controller.Value.ControllerName.ToPascalCase()}Modal.vue"),
+ await ViewScriptGenerator.CreateModal(
+ args,
+ applicationApiDescriptionModel,
+ controller.Value));
+
+ await CreateAndSaveSciptToDisk(
+ Path.Combine(viewScriptPath, $"{controller.Value.ControllerName.ToPascalCase()}Table.vue"),
+ await ViewScriptGenerator.CreateTable(
+ args,
+ applicationApiDescriptionModel,
+ controller.Value));
+
+ await CreateAndSaveSciptToDisk(
+ Path.Combine(componentScriptPath, "index.vue"),
+ await ViewScriptGenerator.CreateIndex(
+ args,
+ applicationApiDescriptionModel,
+ controller.Value));
+ }
+ }
+ }
+
+ protected override ServiceType? GetDefaultServiceType(GenerateViewArgs args)
+ {
+ return ServiceType.Application;
+ }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewScriptGenerator.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewScriptGenerator.cs
new file mode 100644
index 000000000..fd5543eff
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/Vben/VbenViewScriptGenerator.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Http.Modeling;
+using Volo.Abp.TextTemplating;
+
+namespace LINGYUN.Abp.Cli.UI.Vben;
+public class VbenViewScriptGenerator : IVbenViewScriptGenerator, ISingletonDependency
+{
+ private readonly ITemplateRenderer _templateRenderer;
+
+ public VbenViewScriptGenerator(
+ ITemplateRenderer templateRenderer)
+ {
+ _templateRenderer = templateRenderer;
+ }
+
+ public async virtual Task CreateModal(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel)
+ {
+ var moduleDefinition = appModel.Modules
+ .Where(module => module.Key.Equals(args.Module))
+ .Select(module => module.Value)
+ .FirstOrDefault();
+
+ var modalContent = await _templateRenderer.RenderAsync(
+ "VbenModalView",
+ new
+ {
+ Application = controllerModel.ControllerName,
+ ApiPath = $"/@/api/{moduleDefinition.RemoteServiceName.ToKebabCase()}/{controllerModel.ControllerName.ToKebabCase()}",
+ RemoteService = moduleDefinition.RemoteServiceName,
+ });
+
+ return modalContent;
+ }
+
+ public async virtual Task CreateTable(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel)
+ {
+ var moduleDefinition = appModel.Modules
+ .Where(module => module.Key.Equals(args.Module))
+ .Select(module => module.Value)
+ .FirstOrDefault();
+
+ var pagedResultAction = controllerModel.Actions
+ .Where(action => action.Value.ReturnValue.TypeSimple.Contains("PagedResultDto"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+
+ var deleteAction = controllerModel.Actions
+ .Where(action => action.Value.Name.Contains("DeleteAsync"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+ var updateAction = controllerModel.Actions
+ .Where(action => action.Value.Name.Contains("UpdateAsync"))
+ .Select(action => action.Value)
+ .FirstOrDefault();
+
+ var tableContent = await _templateRenderer.RenderAsync(
+ "VbenTableView",
+ new
+ {
+ PagedRequest = pagedResultAction != null,
+ UpdatePermission = updateAction != null && updateAction.AllowAnonymous != null && updateAction.AllowAnonymous != true,
+ UpdatePermissionName = $"{moduleDefinition.RemoteServiceName.ToKebabCase()}.{controllerModel.ControllerName.ToKebabCase()}.Update",
+ DeletePermission = deleteAction != null && deleteAction.AllowAnonymous != null && deleteAction.AllowAnonymous != true,
+ DeletePermissionName = $"{moduleDefinition.RemoteServiceName.ToKebabCase()}.{controllerModel.ControllerName.ToKebabCase()}.Delete",
+ Application = controllerModel.ControllerName,
+ ModalName = $"{controllerModel.ControllerName.ToPascalCase()}Modal",
+ ApiPath = $"/@/api/{moduleDefinition.RemoteServiceName.ToKebabCase()}/{controllerModel.ControllerName.ToKebabCase()}",
+ RemoteService = moduleDefinition.RemoteServiceName,
+ });
+
+ return tableContent;
+ }
+
+ public async virtual Task CreateIndex(
+ GenerateViewArgs args,
+ ApplicationApiDescriptionModel appModel,
+ ControllerApiDescriptionModel controllerModel)
+ {
+ var moduleDefinition = appModel.Modules
+ .Where(module => module.Key.Equals(args.Module))
+ .Select(module => module.Value)
+ .FirstOrDefault();
+
+ var modalContent = await _templateRenderer.RenderAsync(
+ "VbenComponentIndex",
+ new
+ {
+ TableName = $"{controllerModel.ControllerName}Table",
+ Application = $"{moduleDefinition.RemoteServiceName.ToPascalCase()}{controllerModel.ControllerName.ToPascalCase()}".EnsureEndsWith('s')
+ });
+
+ return modalContent;
+ }
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/ViewGeneratorBase.cs b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/ViewGeneratorBase.cs
new file mode 100644
index 000000000..28edc7351
--- /dev/null
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/UI/ViewGeneratorBase.cs
@@ -0,0 +1,70 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Cli;
+using Volo.Abp.Cli.Http;
+using Volo.Abp.Cli.ServiceProxying;
+using Volo.Abp.Http.Modeling;
+using Volo.Abp.Json;
+
+namespace LINGYUN.Abp.Cli.UI;
+public abstract class ViewGeneratorBase : IViewGenerator where T : IViewGenerator
+{
+ public IJsonSerializer JsonSerializer { get; }
+
+ public CliHttpClientFactory CliHttpClientFactory { get; }
+
+ public ILogger Logger { get; set; }
+
+ protected ViewGeneratorBase(CliHttpClientFactory cliHttpClientFactory, IJsonSerializer jsonSerializer)
+ {
+ CliHttpClientFactory = cliHttpClientFactory;
+ JsonSerializer = jsonSerializer;
+ Logger = NullLogger.Instance;
+ }
+
+ protected virtual async Task GetApplicationApiDescriptionModelAsync(GenerateViewArgs args, ApplicationApiDescriptionModelRequestDto requestDto = null)
+ {
+ Check.NotNull(args.Url, nameof(args.Url));
+
+ var client = CliHttpClientFactory.CreateClient();
+
+ var apiDefinitionResult = await client.GetStringAsync(CliUrls.GetApiDefinitionUrl(args.Url, requestDto));
+ var apiDefinition = JsonSerializer.Deserialize(apiDefinitionResult);
+
+ var moduleDefinition = apiDefinition.Modules.FirstOrDefault(x => string.Equals(x.Key, args.Module, StringComparison.CurrentCultureIgnoreCase)).Value;
+ if (moduleDefinition == null)
+ {
+ throw new CliUsageException($"Module name: {args.Module} is invalid");
+ }
+
+ var serviceType = GetServiceType(args);
+ switch (serviceType)
+ {
+ case ServiceType.Application:
+ moduleDefinition.Controllers.RemoveAll(x => !x.Value.IsRemoteService);
+ break;
+ case ServiceType.Integration:
+ moduleDefinition.Controllers.RemoveAll(x => !x.Value.IsIntegrationService);
+ break;
+ }
+
+ var apiDescriptionModel = ApplicationApiDescriptionModel.Create();
+ apiDescriptionModel.Types = apiDefinition.Types;
+ apiDescriptionModel.AddModule(moduleDefinition);
+ return apiDescriptionModel;
+ }
+
+ protected virtual ServiceType? GetServiceType(GenerateViewArgs args)
+ {
+ return args.ServiceType ?? GetDefaultServiceType(args);
+ }
+
+ protected abstract ServiceType? GetDefaultServiceType(GenerateViewArgs args);
+
+ public abstract Task GenerateAsync(GenerateViewArgs args);
+}
diff --git a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json
index a58b5a7c4..ad7255939 100644
--- a/aspnet-core/modules/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json
+++ b/aspnet-core/modules/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json
@@ -2,7 +2,8 @@
"profiles": {
"LINGYUN.Abp.Cli": {
"commandName": "Project",
- "commandLineArgs": "generate-proxy -t ts -asp uni-app-axios -u http://127.0.0.1:30025 -m Platform -o D:\\Projects\\Development\\type-script"
+ "commandLineArgs": "generate-view -t vben-view -m identity -o D:\\Projects\\Development\\view-script -url http://10.21.15.28:30015/"
+ //"commandLineArgs": "generate-proxy -t ts -asp uni-app-axios -u http://127.0.0.1:30025 -m Platform -o D:\\Projects\\Development\\type-script"
}
}
}
\ No newline at end of file