12
This commit is contained in:
parent
7cbea2a3ef
commit
9f5f837a4b
|
|
@ -11,6 +11,7 @@ namespace MiaoYu.Api.Admin;
|
|||
[ImportStartupModule<
|
||||
CoreQuartzStartup,
|
||||
CoreRazorStartup,
|
||||
CoreCodeGeneratorStartup,
|
||||
CoreRedisStartup,
|
||||
CoreIdentityStartup,
|
||||
AdminRepositoryStartup,
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源配置
|
||||
/// </summary>
|
||||
public class DataSourceConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库标识(如:Admin, MiaoYuChat, LiveForum)
|
||||
/// </summary>
|
||||
public string DatabaseKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称
|
||||
/// </summary>
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 实体项目命名空间
|
||||
/// </summary>
|
||||
public string EntityNamespace { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 实体类路径模板(支持占位符:{RootPath}, {Namespace}, {EntityName}, {EntityNamePlural}, {TableName})
|
||||
/// </summary>
|
||||
public string ModelPathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 服务层路径模板
|
||||
/// </summary>
|
||||
public string ServicePathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 控制器路径模板
|
||||
/// </summary>
|
||||
public string ControllerPathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 前端Index页面路径模板
|
||||
/// </summary>
|
||||
public string ClientIndexPathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 前端Info页面路径模板
|
||||
/// </summary>
|
||||
public string ClientInfoPathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 前端Service路径模板
|
||||
/// </summary>
|
||||
public string ClientServicePathTemplate { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成模板目录
|
||||
/// </summary>
|
||||
public string TemplatePath { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 实体类命名规则(保持原名 or 驼峰转换)
|
||||
/// </summary>
|
||||
public EntityNamingStrategy NamingStrategy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序权重(数字越小越靠前)
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用实体类名前缀(用于避免多数据源同名表冲突)
|
||||
/// </summary>
|
||||
public bool EnableEntityPrefix { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 实体类名前缀(如:Chat、Forum)
|
||||
/// </summary>
|
||||
public string EntityPrefix { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用复数形式的路径(如 /Users/ vs /User/)
|
||||
/// </summary>
|
||||
public bool UsesPluralPath { get; set; } = true;
|
||||
}
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源常量
|
||||
/// </summary>
|
||||
public static class DataSourceConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// 后台管理系统数据库
|
||||
/// </summary>
|
||||
public const string Admin = "Admin";
|
||||
|
||||
/// <summary>
|
||||
/// 喵语AI聊天数据库
|
||||
/// </summary>
|
||||
public const string MiaoYuChat = "MiaoYuChat";
|
||||
|
||||
/// <summary>
|
||||
/// 直播论坛数据库(预留)
|
||||
/// </summary>
|
||||
public const string LiveForum = "LiveForum";
|
||||
}
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 实体命名策略
|
||||
/// </summary>
|
||||
public enum EntityNamingStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 保持数据库表名原样
|
||||
/// </summary>
|
||||
KeepOriginal = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 转换为驼峰命名(去除前缀下划线)
|
||||
/// </summary>
|
||||
ToPascalCase = 1
|
||||
}
|
||||
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源提供者接口
|
||||
/// </summary>
|
||||
public interface IDataSourceProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据源配置
|
||||
/// </summary>
|
||||
DataSourceConfig Config { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取该数据源的所有表信息
|
||||
/// </summary>
|
||||
/// <returns>表信息列表</returns>
|
||||
List<DbTableInfo> GetTables();
|
||||
|
||||
/// <summary>
|
||||
/// 获取DbContext(用于获取FreeSql实例)
|
||||
/// </summary>
|
||||
/// <returns>数据库上下文</returns>
|
||||
DbContext GetDbContext();
|
||||
}
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源扩展方法
|
||||
/// </summary>
|
||||
public static class DataSourceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 从 Schema 中提取数据库标识
|
||||
/// </summary>
|
||||
/// <param name="schema">Schema字符串</param>
|
||||
/// <returns>数据库标识</returns>
|
||||
public static string ExtractDatabaseKey(this string schema)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(schema))
|
||||
return DataSourceConstants.Admin;
|
||||
|
||||
if (schema.Contains("."))
|
||||
{
|
||||
var parts = schema.Split('.');
|
||||
return parts.Length > 1 ? parts[1] : DataSourceConstants.Admin;
|
||||
}
|
||||
|
||||
return DataSourceConstants.Admin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理 Schema(移除数据库标识)
|
||||
/// </summary>
|
||||
/// <param name="schema">Schema字符串</param>
|
||||
/// <returns>清理后的Schema</returns>
|
||||
public static string CleanSchema(this string schema)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(schema))
|
||||
return schema;
|
||||
|
||||
return schema.Contains(".")
|
||||
? schema.Split('.')[0]
|
||||
: schema;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
using HZY.Framework.DependencyInjection.Attributes;
|
||||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源管理器
|
||||
/// </summary>
|
||||
[Component]
|
||||
public class DataSourceManager : IScopedDependency
|
||||
{
|
||||
private readonly IEnumerable<IDataSourceProvider> _providers;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数(通过依赖注入自动收集所有IDataSourceProvider实现)
|
||||
/// </summary>
|
||||
/// <param name="providers">所有数据源提供者</param>
|
||||
public DataSourceManager(IEnumerable<IDataSourceProvider> providers)
|
||||
{
|
||||
_providers = providers.OrderBy(p => p.Config.Order);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据源提供者
|
||||
/// </summary>
|
||||
/// <returns>数据源提供者集合</returns>
|
||||
public IEnumerable<IDataSourceProvider> GetAllProviders() => _providers;
|
||||
|
||||
/// <summary>
|
||||
/// 根据数据库标识获取数据源提供者
|
||||
/// </summary>
|
||||
/// <param name="databaseKey">数据库标识(如:Admin, MiaoYuChat)</param>
|
||||
/// <returns>数据源提供者,如果未找到返回null</returns>
|
||||
public IDataSourceProvider? GetProvider(string databaseKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(databaseKey))
|
||||
return null;
|
||||
|
||||
return _providers.FirstOrDefault(p =>
|
||||
p.Config.DatabaseKey.Equals(databaseKey, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据源的表信息
|
||||
/// </summary>
|
||||
/// <returns>所有表信息列表</returns>
|
||||
public List<DbTableInfo> GetAllTables()
|
||||
{
|
||||
var allTables = new List<DbTableInfo>();
|
||||
|
||||
foreach (var provider in _providers)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tables = provider.GetTables();
|
||||
if (tables != null && tables.Count > 0)
|
||||
{
|
||||
allTables.AddRange(tables);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogUtil.Log.Warning($"获取数据源 {provider.Config.DatabaseKey} 的表信息失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return allTables;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
using HZY.Framework.DependencyInjection.Attributes;
|
||||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 路径解析器
|
||||
/// </summary>
|
||||
[Component]
|
||||
public class PathResolver : IScopedDependency
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
|
||||
public PathResolver(IWebHostEnvironment environment)
|
||||
{
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析路径模板
|
||||
/// </summary>
|
||||
/// <param name="template">路径模板(支持占位符)</param>
|
||||
/// <param name="config">数据源配置</param>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <returns>解析后的完整路径</returns>
|
||||
public string ResolvePath(string template, DataSourceConfig config, string tableName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(template))
|
||||
return string.Empty;
|
||||
|
||||
var rootPath = _environment.ContentRootPath
|
||||
.Replace("\\" + _environment.ApplicationName, "");
|
||||
|
||||
var entityName = GetEntityName(tableName, config);
|
||||
var entityNamePlural = config.UsesPluralPath ? entityName + "s" : entityName;
|
||||
|
||||
return template
|
||||
.Replace("{RootPath}", rootPath)
|
||||
.Replace("{AppPath}", _environment.ContentRootPath)
|
||||
.Replace("{Namespace}", config.EntityNamespace)
|
||||
.Replace("{EntityName}", entityName)
|
||||
.Replace("{EntityNamePlural}", entityNamePlural)
|
||||
.Replace("{TableName}", tableName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据命名策略和配置获取实体名
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="config">数据源配置</param>
|
||||
/// <returns>实体名</returns>
|
||||
public string GetEntityName(string tableName, DataSourceConfig config)
|
||||
{
|
||||
var baseName = config.NamingStrategy == EntityNamingStrategy.ToPascalCase
|
||||
? tableName.ToLineConvertHump()
|
||||
: tableName;
|
||||
|
||||
// 应用前缀(如果启用)
|
||||
if (config.EnableEntityPrefix && !string.IsNullOrWhiteSpace(config.EntityPrefix))
|
||||
{
|
||||
return config.EntityPrefix + baseName;
|
||||
}
|
||||
|
||||
return baseName;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成服务
|
||||
/// </summary>
|
||||
public interface ICodeGenerationService : IScopedDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成上下文集合
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
PagingView GetGenContextDtos(int page, int size, GenFormDto search);
|
||||
|
||||
/// <summary>
|
||||
/// 获取表字段集合
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="databaseKey">数据库标识(可选)</param>
|
||||
/// <returns></returns>
|
||||
GenDbTableDto GetGenContextDtoByTableName(string tableName, string? databaseKey = null);
|
||||
|
||||
/// <summary>
|
||||
/// 根据 lowCodeTable 填充路径
|
||||
/// </summary>
|
||||
/// <param name="lowCodeTable"></param>
|
||||
/// <returns></returns>
|
||||
LowCodeTable FillPathByLowCodeTable(LowCodeTable lowCodeTable);
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码生成上下文
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
GenDbTableDto GetGenContextDto(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 model
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenModelAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 service
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenServiceAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 controller
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenControllerAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 serviceJs
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenServiceJsAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 Index
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenIndexAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 生成 Info
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GenInfoAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetCodeByTypeAndTableNameAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 下载
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<(byte[] codeBytes, string contentType, string fileName)> DownloadAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 根据类型下载类型下所有的代码
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<(byte[] codeBytes, string contentType, string fileName)> DownloadAllAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有代码文件
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> CreateAllCodeFilesAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 创建数据字典文件 excel
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
(byte[] excel, string dataBase) CreateDataDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成自动导入项目
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
Task AutoImprotProjectAsync(GenFormDto genFormDto);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据库列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<DataSourceDto> GetAllDataSources();
|
||||
}
|
||||
|
|
@ -1,700 +0,0 @@
|
|||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成服务
|
||||
/// </summary>
|
||||
public class CodeGenerationService : ICodeGenerationService
|
||||
{
|
||||
private readonly string _webRootPath;
|
||||
private readonly string templateRootPath = "/wwwroot/code_generation/template/";
|
||||
private readonly string templateRootPath_v4 = "/wwwroot/code_generation/templatev4/";
|
||||
private readonly string codesRootPath = "/code_generation/codes";
|
||||
private readonly string zipRootPath = "/code_generation/zip";
|
||||
|
||||
//domain 模板文件
|
||||
private readonly string templateModel = "tempModel.cshtml";
|
||||
private readonly string templateService = "tempService.cshtml";
|
||||
private readonly string templateController = "tempController.cshtml";
|
||||
private readonly string templateServiceJs = "tempClientService.cshtml";
|
||||
private readonly string templateIndex = "tempClientIndex.cshtml";
|
||||
private readonly string templateInfo = "tempClientInfo.cshtml";
|
||||
|
||||
// 客户端名称
|
||||
private readonly string projectClientName = "admin-client";
|
||||
|
||||
private readonly IDatabaseTableService _databaseTableService;
|
||||
private readonly IRazorViewRender _razorViewRender;
|
||||
private readonly DataSourceManager _dataSourceManager;
|
||||
private readonly PathResolver _pathResolver;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="databaseTableService">数据库表服务</param>
|
||||
/// <param name="razorViewRender">Razor视图渲染器</param>
|
||||
/// <param name="webHostEnvironment">Web宿主环境</param>
|
||||
/// <param name="dataSourceManager">数据源管理器</param>
|
||||
/// <param name="pathResolver">路径解析器</param>
|
||||
public CodeGenerationService(IDatabaseTableService databaseTableService,
|
||||
IRazorViewRender razorViewRender,
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
DataSourceManager dataSourceManager,
|
||||
PathResolver pathResolver)
|
||||
{
|
||||
_databaseTableService = databaseTableService;
|
||||
_razorViewRender = razorViewRender;
|
||||
_webRootPath = webHostEnvironment.WebRootPath;
|
||||
_dataSourceManager = dataSourceManager;
|
||||
_pathResolver = pathResolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成上下文集合
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public PagingView GetGenContextDtos(int page, int size, GenFormDto search)
|
||||
{
|
||||
var PagingView = new PagingView(page, size);
|
||||
var result = new List<Dictionary<string, object>>();
|
||||
|
||||
var query = _databaseTableService.GetAllTablesByCache()
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(search.TableName), w => w.TableName.Contains(search.TableName))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(search.DataBase), w => w.DataBase == search.DataBase);
|
||||
|
||||
var tables = query
|
||||
.Skip((page - 1) * size)
|
||||
.Take(size)
|
||||
.ToList();
|
||||
|
||||
foreach (var item in tables)
|
||||
{
|
||||
var dic = new Dictionary<string, object>();
|
||||
dic.Add(nameof(item.TableName), item.TableName);
|
||||
dic.Add(nameof(item.Remark), item.Remark);
|
||||
dic.Add(nameof(item.DataBase), item.DataBase);
|
||||
|
||||
result.Add(dic);
|
||||
}
|
||||
|
||||
PagingView.Total = query.LongCount();
|
||||
PagingView.Page = page;
|
||||
PagingView.Size = size;
|
||||
PagingView.DataSource = result;
|
||||
PagingView.PageCount = PagingView.Total / size;
|
||||
return PagingView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有表集合信息
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="databaseKey">数据库标识(可选)</param>
|
||||
/// <returns></returns>
|
||||
public GenDbTableDto GetGenContextDtoByTableName(string tableName, string? databaseKey = null)
|
||||
{
|
||||
var query = _databaseTableService.GetAllTables().AsEnumerable();
|
||||
|
||||
// 如果指定了数据库,则精确匹配
|
||||
if (!string.IsNullOrWhiteSpace(databaseKey))
|
||||
{
|
||||
query = query.Where(w => w.TableName == tableName && w.DataBase == databaseKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.Where(w => w.TableName == tableName);
|
||||
}
|
||||
|
||||
var genDbTableDto = query.FirstOrDefault();
|
||||
|
||||
if (genDbTableDto != null)
|
||||
{
|
||||
FillPathByLowCodeTable(genDbTableDto);
|
||||
}
|
||||
|
||||
return genDbTableDto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 lowCodeTable 填充路径(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="lowCodeTable">低代码表配置</param>
|
||||
/// <returns>填充路径后的低代码表配置</returns>
|
||||
public LowCodeTable FillPathByLowCodeTable(LowCodeTable lowCodeTable)
|
||||
{
|
||||
var provider = _dataSourceManager.GetProvider(lowCodeTable.DataBase ?? DataSourceConstants.Admin);
|
||||
if (provider == null)
|
||||
{
|
||||
LogUtil.Log.Warning($"未找到数据源 {lowCodeTable.DataBase},使用默认Admin配置");
|
||||
provider = _dataSourceManager.GetProvider(DataSourceConstants.Admin);
|
||||
}
|
||||
|
||||
var config = provider!.Config;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ModelPath))
|
||||
{
|
||||
lowCodeTable.ModelPath = _pathResolver.ResolvePath(
|
||||
config.ModelPathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ServicePath))
|
||||
{
|
||||
lowCodeTable.ServicePath = _pathResolver.ResolvePath(
|
||||
config.ServicePathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ControllerPath))
|
||||
{
|
||||
lowCodeTable.ControllerPath = _pathResolver.ResolvePath(
|
||||
config.ControllerPathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientIndexPath))
|
||||
{
|
||||
lowCodeTable.ClientIndexPath = _pathResolver.ResolvePath(
|
||||
config.ClientIndexPathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientInfoPath))
|
||||
{
|
||||
lowCodeTable.ClientInfoPath = _pathResolver.ResolvePath(
|
||||
config.ClientInfoPathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientServicePath))
|
||||
{
|
||||
lowCodeTable.ClientServicePath = _pathResolver.ResolvePath(
|
||||
config.ClientServicePathTemplate, config, lowCodeTable.TableName);
|
||||
}
|
||||
|
||||
return lowCodeTable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码生成上下文
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public GenDbTableDto GetGenContextDto(GenFormDto genFormDto)
|
||||
{
|
||||
var tableName = genFormDto.TableName;
|
||||
var tableInfo = GetGenContextDtoByTableName(tableName, genFormDto.DataBase);
|
||||
|
||||
if (tableInfo == null) return null;
|
||||
tableInfo.Namespace = Tools.GetNamespacePrefix<CodeGenerationService>();
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成model(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenModelAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateModel, context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成service(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenServiceAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateService, context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成controller(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenControllerAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateController, context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成service js(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenServiceJsAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateServiceJs, context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成 index vue(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenIndexAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateIndex, context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成 info vue(支持多数据源)
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GenInfoAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
|
||||
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
|
||||
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateInfo, context));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetCodeByTypeAndTableNameAsync(GenFormDto genFormDto)
|
||||
{
|
||||
return genFormDto.Type switch
|
||||
{
|
||||
"MiaoYu.Models" => await GenModelAsync(genFormDto),
|
||||
//"MiaoYu.Repository.DbSet" => await this.CreateRepositoryDbSetAsync(),
|
||||
"MiaoYu.Services.Admin" => await GenServiceAsync(genFormDto),
|
||||
"MiaoYu.Controllers.Admin" => await GenControllerAsync(genFormDto),
|
||||
"Client.Index" => await GenIndexAsync(genFormDto),
|
||||
"Client.Info" => await GenInfoAsync(genFormDto),
|
||||
"Client.Service" => await GenServiceJsAsync(genFormDto),
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有代码文件
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> CreateAllCodeFilesAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var tables = _databaseTableService.GetAllTablesByCache();
|
||||
|
||||
foreach (var item in tables)
|
||||
{
|
||||
genFormDto.TableName = item.TableName;
|
||||
genFormDto.DataBase = item.DataBase;
|
||||
await CreateCodeFilesAsync(genFormDto);
|
||||
await Task.Delay(25);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载代码信息
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<(byte[] codeBytes, string contentType, string fileName)> DownloadAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var fileName = FindCodeFileClassName(genFormDto);
|
||||
|
||||
var contentType = Tools.GetFileContentType[".cs"];
|
||||
if (fileName == "Index.vue" || fileName == "Info.vue")
|
||||
{
|
||||
contentType = Tools.GetFileContentType[".txt"];
|
||||
}
|
||||
|
||||
return (Encoding.UTF8.GetBytes(await GetCodeByTypeAndTableNameAsync(genFormDto)), contentType, fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据类型下载所有代码
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<(byte[] codeBytes, string contentType, string fileName)> DownloadAllAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var isViews = genFormDto.Type == "Client.Index" || genFormDto.Type == "Client.Info";
|
||||
var success = await CreateAllCodeFilesAsync(genFormDto);
|
||||
|
||||
if (!success) LogUtil.Log.Warning("无法下载,代码创建失败!");
|
||||
|
||||
string path;
|
||||
string zipPath;
|
||||
|
||||
if (isViews)
|
||||
{
|
||||
path = $"{_webRootPath}{codesRootPath}/pages";
|
||||
zipPath = $"{_webRootPath}{zipRootPath}";
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(zipPath))
|
||||
{
|
||||
Directory.CreateDirectory(zipPath);
|
||||
}
|
||||
|
||||
zipPath += "/pages.zip";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = $"{_webRootPath}{codesRootPath}/{genFormDto.Type}";
|
||||
zipPath = $"{_webRootPath}{zipRootPath}";
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(zipPath))
|
||||
{
|
||||
Directory.CreateDirectory(zipPath);
|
||||
}
|
||||
|
||||
zipPath += $"/{genFormDto.Type}.zip";
|
||||
}
|
||||
|
||||
//开始压缩
|
||||
var zip = new Zip(path, zipPath);
|
||||
var bytes = await File.ReadAllBytesAsync(zipPath);
|
||||
|
||||
//删除文件
|
||||
if (File.Exists(zipPath)) File.Delete(zipPath);
|
||||
if (Directory.Exists(path)) Directory.Delete(path, true);
|
||||
|
||||
return (bytes, Tools.GetFileContentType[".zip"], $"{(isViews ? "pages" : genFormDto.Type)}.zip");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建数据库字典文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public (byte[] excel, string dataBase) CreateDataDictionary()
|
||||
{
|
||||
var tables = _databaseTableService.GetAllTablesByCache();
|
||||
var workbook = new XSSFWorkbook();
|
||||
var dataBaseName = _databaseTableService.GetDatabaseName();
|
||||
|
||||
foreach (var item in tables)
|
||||
{
|
||||
var sheet = workbook.CreateSheet(item.TableName + (string.IsNullOrWhiteSpace(item.Remark) ? "" : "_" + item.Remark));
|
||||
|
||||
var i = 0;
|
||||
|
||||
#region 配置表头
|
||||
|
||||
var rowTitle = sheet.CreateRow(i);
|
||||
rowTitle.CreateCell(0).SetCellValue("表空间");
|
||||
sheet.SetColumnWidth(0, 20 * 256);
|
||||
rowTitle.CreateCell(1).SetCellValue("表名");
|
||||
sheet.SetColumnWidth(1, 20 * 256);
|
||||
rowTitle.CreateCell(2).SetCellValue("表描述");
|
||||
sheet.SetColumnWidth(2, 20 * 256);
|
||||
rowTitle.CreateCell(3).SetCellValue("字段");
|
||||
sheet.SetColumnWidth(3, 20 * 256);
|
||||
rowTitle.CreateCell(4).SetCellValue("字段描述");
|
||||
sheet.SetColumnWidth(4, 20 * 256);
|
||||
rowTitle.CreateCell(5).SetCellValue("是否主键");
|
||||
sheet.SetColumnWidth(5, 20 * 256);
|
||||
rowTitle.CreateCell(6).SetCellValue("是否自增");
|
||||
sheet.SetColumnWidth(6, 20 * 256);
|
||||
rowTitle.CreateCell(7).SetCellValue("可否为 Null");
|
||||
sheet.SetColumnWidth(7, 20 * 256);
|
||||
rowTitle.CreateCell(8).SetCellValue("数据库类型");
|
||||
sheet.SetColumnWidth(8, 20 * 256);
|
||||
rowTitle.CreateCell(9).SetCellValue("C#类型");
|
||||
sheet.SetColumnWidth(9, 20 * 256);
|
||||
rowTitle.CreateCell(10).SetCellValue("数据长度");
|
||||
sheet.SetColumnWidth(10, 20 * 256);
|
||||
|
||||
#endregion
|
||||
//组装数据
|
||||
foreach (var tableInfo in item.TableInfos)
|
||||
{
|
||||
i++;
|
||||
var index = item.TableInfos.IndexOf(tableInfo);
|
||||
var row = sheet.CreateRow(i);
|
||||
//row.CreateCell(0).SetCellValue(item.Schema);
|
||||
row.CreateCell(1).SetCellValue(item.TableName);
|
||||
row.CreateCell(2).SetCellValue(item.Remark);
|
||||
row.CreateCell(3).SetCellValue(tableInfo.ColumnName);
|
||||
row.CreateCell(4).SetCellValue(tableInfo.Describe);
|
||||
row.CreateCell(5).SetCellValue(tableInfo.IsPrimary ? "是" : "否");
|
||||
row.CreateCell(6).SetCellValue(tableInfo.IsIdentity ? "是" : "否");
|
||||
row.CreateCell(7).SetCellValue(tableInfo.IsNullable ? "是" : "否");
|
||||
row.CreateCell(8).SetCellValue(tableInfo.DatabaseColumnType);
|
||||
row.CreateCell(9).SetCellValue(tableInfo.CsType);
|
||||
row.CreateCell(10).SetCellValue(tableInfo.MaxLength ?? 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//填充byte
|
||||
using var ms = new MemoryStream();
|
||||
workbook.Write(ms);
|
||||
return (ms.ToArray(), dataBaseName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动导入文件到项目
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task AutoImprotProjectAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var context = GetGenContextDto(genFormDto);
|
||||
if (context == null)
|
||||
{
|
||||
MessageBox.Show("找不到此数据表!");
|
||||
return;
|
||||
}
|
||||
|
||||
//获取表路径信息
|
||||
var tables = _databaseTableService.GetAllTablesByCache();
|
||||
var tableInfo = tables.FirstOrDefault(w =>
|
||||
w.TableName == genFormDto.TableName &&
|
||||
w.DataBase == genFormDto.DataBase);
|
||||
|
||||
var fileTyps = Enum.GetValues<FileTypeEnum>();
|
||||
|
||||
foreach (var fileType in fileTyps)
|
||||
{
|
||||
var (filePath, oldName, replaceName) = GetFileAbsolutelyPath(
|
||||
genFormDto.TableName, fileType, genFormDto.DataBase);
|
||||
await SaveToFileAsync(genFormDto.TableName, fileType, filePath, oldName, replaceName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据库列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<DataSourceDto> GetAllDataSources()
|
||||
{
|
||||
var providers = _dataSourceManager.GetAllProviders()
|
||||
.OrderBy(p => p.Config.Order)
|
||||
.ToList();
|
||||
|
||||
return providers.Select(p => new DataSourceDto
|
||||
{
|
||||
Key = p.Config.DatabaseKey,
|
||||
DisplayName = p.Config.DisplayName
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
#region 私有方法
|
||||
|
||||
/// <summary>
|
||||
/// 清除多余符号
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
private string ClearSymbol(StringBuilder code)
|
||||
{
|
||||
return code
|
||||
.ToString()
|
||||
.Replace("<pre>", "")
|
||||
.Replace("</pre>", "")
|
||||
.Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建代码文件
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> CreateCodeFilesAsync(GenFormDto genFormDto)
|
||||
{
|
||||
var path = $"{_webRootPath}{codesRootPath}";
|
||||
|
||||
if (genFormDto.Type == "Client.Index" || genFormDto.Type == "Client.Info")
|
||||
{
|
||||
path += $"/pages"; //
|
||||
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
||||
path += $"/{genFormDto.TableName}";
|
||||
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
||||
//Index
|
||||
var codeString = await GenIndexAsync(genFormDto);
|
||||
await File.WriteAllTextAsync($"{path}/Index.vue", codeString, Encoding.UTF8);
|
||||
//Info
|
||||
codeString = await GenInfoAsync(genFormDto);
|
||||
await File.WriteAllTextAsync($"{path}/Info.vue", codeString, Encoding.UTF8);
|
||||
return path;
|
||||
}
|
||||
|
||||
//
|
||||
path = $"{_webRootPath}{codesRootPath}/{genFormDto.Type}";
|
||||
var className = FindCodeFileClassName(genFormDto);
|
||||
var code = await GetCodeByTypeAndTableNameAsync(genFormDto);
|
||||
//
|
||||
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
|
||||
await File.WriteAllTextAsync($"{path}/{className}", code, Encoding.UTF8);
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取代码文件名称
|
||||
/// </summary>
|
||||
/// <param name="genFormDto"></param>
|
||||
/// <returns></returns>
|
||||
private string FindCodeFileClassName(GenFormDto genFormDto)
|
||||
{
|
||||
var provider = _dataSourceManager.GetProvider(genFormDto.DataBase ?? DataSourceConstants.Admin);
|
||||
var entityName = _pathResolver.GetEntityName(genFormDto.TableName, provider.Config);
|
||||
|
||||
return genFormDto.Type switch
|
||||
{
|
||||
"MiaoYu.Models" => $"{entityName}.cs",
|
||||
"MiaoYu.Services.Admin" => $"{entityName}Service.cs",
|
||||
"MiaoYu.Controllers.Admin" => $"{entityName}Controller.cs",
|
||||
"Client.Index" => $"Index.vue",
|
||||
"Client.Info" => $"Info.vue",
|
||||
"Client.Service" => $"{entityName}Service.ts",
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取要生成文件的绝对路径
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="databaseKey">数据库标识(可选)</param>
|
||||
/// <returns></returns>
|
||||
private (string, string, string) GetFileAbsolutelyPath(string tableName, FileTypeEnum type, string? databaseKey = null)
|
||||
{
|
||||
var replaceName = string.Empty;
|
||||
var oldFileName = string.Empty;
|
||||
var dto = new GenFormDto() { TableName = tableName, Type = GetEnumDescription(type), DataBase = databaseKey };
|
||||
|
||||
var provider = _dataSourceManager.GetProvider(databaseKey ?? DataSourceConstants.Admin);
|
||||
var entityName = _pathResolver.GetEntityName(tableName, provider.Config);
|
||||
var entityNameWithPath = provider.Config.UsesPluralPath ? entityName + "s" : entityName;
|
||||
|
||||
var fileName = FindCodeFileClassName(dto);
|
||||
var path = string.Empty;
|
||||
//获取表路径信息
|
||||
var tableInfo = GetGenContextDtoByTableName(tableName, databaseKey);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FileTypeEnum.Model:
|
||||
path = provider.Config.UsesPluralPath
|
||||
? $"{tableInfo.ModelPath}/{entityNameWithPath}"
|
||||
: tableInfo.ModelPath;
|
||||
break;
|
||||
case FileTypeEnum.Service:
|
||||
path = provider.Config.UsesPluralPath
|
||||
? $"{tableInfo.ServicePath}/{entityNameWithPath}"
|
||||
: tableInfo.ServicePath;
|
||||
break;
|
||||
case FileTypeEnum.Controller:
|
||||
path = provider.Config.UsesPluralPath
|
||||
? $"{tableInfo.ControllerPath}/{entityNameWithPath}"
|
||||
: tableInfo.ControllerPath;
|
||||
break;
|
||||
case FileTypeEnum.ClientIndex:
|
||||
path = tableInfo.ClientIndexPath + $"/{tableName}s";
|
||||
break;
|
||||
case FileTypeEnum.ClientInfo:
|
||||
path = tableInfo.ClientInfoPath + $"/{tableName}s";
|
||||
break;
|
||||
case FileTypeEnum.ClientService:
|
||||
path = tableInfo.ClientServicePath + $"/{tableName}s";
|
||||
break;
|
||||
}
|
||||
|
||||
var fileDirPath = Path.Combine(path);
|
||||
if (!Directory.Exists(fileDirPath))
|
||||
{
|
||||
Directory.CreateDirectory(fileDirPath);
|
||||
}
|
||||
|
||||
// 组合成完整路劲
|
||||
var filePath = $"{fileDirPath}/{fileName}";
|
||||
// 判断是否覆盖文件
|
||||
if (!(tableInfo.IsCover ?? false))
|
||||
{
|
||||
// 如果文件已存在 加尾缀 重新创建文件夹
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
oldFileName = FindCodeFileClassName(dto);
|
||||
replaceName = $"{oldFileName}{DateTime.Now.ToString("yyyyMMddHHmmss")}";
|
||||
filePath = $"{fileDirPath}/{replaceName}";
|
||||
}
|
||||
}
|
||||
|
||||
return (filePath, oldFileName, replaceName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存到文件
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="oldName"></param>
|
||||
/// <param name="replaceName"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SaveToFileAsync(string tableName, FileTypeEnum type, string filePath, string oldName, string replaceName)
|
||||
{
|
||||
var dto = new GenFormDto() { TableName = tableName, Type = GetEnumDescription(type) };
|
||||
var codeString = await GetCodeByTypeAndTableNameAsync(dto);
|
||||
if (!string.IsNullOrWhiteSpace(replaceName) && !string.IsNullOrWhiteSpace(oldName))
|
||||
{
|
||||
if (type == FileTypeEnum.Model || type == FileTypeEnum.Service || type == FileTypeEnum.Controller)
|
||||
{
|
||||
codeString = codeString.Replace(oldName, replaceName);
|
||||
}
|
||||
}
|
||||
await Task.Delay(500);
|
||||
await File.WriteAllTextAsync(filePath, codeString, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举上的描述特性
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
private string GetEnumDescription(FileTypeEnum type)
|
||||
{
|
||||
return type.GetType().GetField(Enum.GetName(type)).GetCustomAttribute<DescriptionAttribute>().Description;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum FileTypeEnum
|
||||
{
|
||||
[Description("MiaoYu.Models")]
|
||||
Model,
|
||||
[Description("MiaoYu.Services.Admin")]
|
||||
Service,
|
||||
[Description("MiaoYu.Controllers.Admin")]
|
||||
Controller,
|
||||
[Description("Client.Index")]
|
||||
ClientIndex,
|
||||
[Description("Client.Info")]
|
||||
ClientInfo,
|
||||
[Description("Client.Service")]
|
||||
ClientService
|
||||
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库表服务
|
||||
/// </summary>
|
||||
public class DatabaseTableService : IDatabaseTableService
|
||||
{
|
||||
private readonly string TableInfoKey = "TableInfo:GenDbTableDto";
|
||||
private readonly int CacheTime = 12;
|
||||
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly IRepository<LowCodeTable> _lowCodeTableRepository;
|
||||
private readonly IRepository<LowCodeTableInfo> _lowCodeTableInfoRepository;
|
||||
|
||||
private readonly IRepository<T_Image_Config> _imageConfig;
|
||||
private readonly DataSourceManager _dataSourceManager;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="memoryCache">内存缓存</param>
|
||||
/// <param name="lowCodeTableRepository">低代码表仓储</param>
|
||||
/// <param name="lowCodeTableInfoRepository">低代码表字段仓储</param>
|
||||
/// <param name="imageConfig">图片配置仓储</param>
|
||||
/// <param name="dataSourceManager">数据源管理器</param>
|
||||
public DatabaseTableService(
|
||||
IMemoryCache memoryCache,
|
||||
IRepository<LowCodeTable> lowCodeTableRepository,
|
||||
IRepository<LowCodeTableInfo> lowCodeTableInfoRepository,
|
||||
IRepository<T_Image_Config> imageConfig,
|
||||
DataSourceManager dataSourceManager
|
||||
)
|
||||
{
|
||||
_memoryCache = memoryCache;
|
||||
_lowCodeTableRepository = lowCodeTableRepository;
|
||||
_lowCodeTableInfoRepository = lowCodeTableInfoRepository;
|
||||
_imageConfig = imageConfig;
|
||||
_dataSourceManager = dataSourceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的表 包含表下面的列(支持多数据源)
|
||||
/// </summary>
|
||||
/// <returns>所有表信息列表</returns>
|
||||
public virtual List<DbTableInfo> GetAllTableInfos()
|
||||
{
|
||||
return _dataSourceManager.GetAllTables();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的表 包含表下面的列
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual List<GenDbTableDto> GetAllTables()
|
||||
{
|
||||
var tables = _lowCodeTableRepository.ToListAll();
|
||||
var tableColumns = _lowCodeTableInfoRepository.ToListAll();
|
||||
|
||||
var result = new List<GenDbTableDto>();
|
||||
foreach (var item in tables)
|
||||
{
|
||||
var table = item.MapTo<LowCodeTable, GenDbTableDto>();
|
||||
table.TableInfos = tableColumns.Where(w => w.Low_Code_TableId == item.Id).ToList();
|
||||
result.Add(table);
|
||||
}
|
||||
|
||||
_memoryCache.Set(TableInfoKey, result, DateTime.Now.AddHours(CacheTime));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取表信息根据缓存
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<GenDbTableDto> GetAllTablesByCache() => _memoryCache.Get<List<GenDbTableDto>>(TableInfoKey) ?? GetAllTables();
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有表缓存信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearAllTablesByCache()
|
||||
{
|
||||
_memoryCache.Remove(TableInfoKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库名称
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string? GetDatabaseName() => _lowCodeTableRepository.GetContext()?.Database.GetDbConnection().Database;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
using MiaoYu.Repository.Admin.Entities.LowCode;
|
||||
using CoreIDatabaseTableService = MiaoYu.Core.CodeGenerator.Services.IDatabaseTableService;
|
||||
using CoreITableMetaConfigService = MiaoYu.Core.CodeGenerator.Services.ITableMetaConfigService;
|
||||
using CoreGenDbTableDto = MiaoYu.Core.CodeGenerator.Models.GenDbTableDto;
|
||||
using CoreTableMetaConfig = MiaoYu.Core.CodeGenerator.Models.TableMetaConfig;
|
||||
using CoreColumnMetaConfig = MiaoYu.Core.CodeGenerator.Models.ColumnMetaConfig;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
|
||||
|
||||
|
|
@ -7,62 +12,102 @@ namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
|
|||
/// </summary>
|
||||
public class LowCodeTableInfoService : ApplicationService<IRepository<LowCodeTableInfo>>
|
||||
{
|
||||
private readonly IDatabaseTableService _databaseTableService;
|
||||
private readonly CoreIDatabaseTableService _databaseTableService;
|
||||
private readonly IRepository<LowCodeTable> _lowCodeTableRepository;
|
||||
private readonly CoreITableMetaConfigService _tableMetaConfigService;
|
||||
|
||||
public LowCodeTableInfoService(
|
||||
IDatabaseTableService databaseTableService,
|
||||
CoreIDatabaseTableService databaseTableService,
|
||||
IRepository<LowCodeTableInfo> defaultRepository,
|
||||
IRepository<LowCodeTable> lowCodeTableRepository) : base(defaultRepository)
|
||||
IRepository<LowCodeTable> lowCodeTableRepository,
|
||||
CoreITableMetaConfigService tableMetaConfigService) : base(defaultRepository)
|
||||
{
|
||||
_databaseTableService = databaseTableService;
|
||||
_lowCodeTableRepository = lowCodeTableRepository;
|
||||
_tableMetaConfigService = tableMetaConfigService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表数据
|
||||
/// 获取列表数据(从 Core 层查询表结构并合并配置)
|
||||
/// </summary>
|
||||
/// <param name="pagingSearchInput"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagingView> FindListAsync(PagingSearchInput<LowCodeTableInfo> pagingSearchInput)
|
||||
{
|
||||
var query = _defaultRepository.SelectNoTracking
|
||||
.WhereIf(pagingSearchInput.Search.Low_Code_TableId != Guid.Empty, w => w.Low_Code_TableId == pagingSearchInput.Search.Low_Code_TableId)
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search.ColumnName), w => w.ColumnName.Contains(pagingSearchInput.Search.ColumnName))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search.Describe), w => w.Describe.Contains(pagingSearchInput.Search.Describe))
|
||||
.OrderBy(w => w.Position)
|
||||
.ThenByDescending(w => w.CreationTime)
|
||||
.Select(w => new
|
||||
{
|
||||
w.Id,
|
||||
w.IsPrimary,
|
||||
w.IsIdentity,
|
||||
w.IsNullable,
|
||||
w.Position,
|
||||
w.ColumnName,
|
||||
w.Describe,
|
||||
w.DatabaseColumnType,
|
||||
w.CsType,
|
||||
w.CsField,
|
||||
w.DisplayName,
|
||||
w.Low_Code_TableId,
|
||||
w.LastModificationTime,
|
||||
w.CreationTime,
|
||||
IsTableColumnShow = w.IsTableColumnShow ?? true,
|
||||
w.IsTableSelect,
|
||||
w.IsImageId,
|
||||
OrderById = w.OrderById ?? 10
|
||||
})
|
||||
;
|
||||
|
||||
var result = await _defaultRepository.AsPagingViewAsync(query, pagingSearchInput);
|
||||
//覆盖值
|
||||
result
|
||||
.FormatValue(query, w => w.CreationTime, (oldValue) => oldValue.ToString("yyyy-MM-dd"))
|
||||
.FormatValue(query, w => w.LastModificationTime, (oldValue) => oldValue?.ToString("yyyy-MM-dd"))
|
||||
;
|
||||
|
||||
return result;
|
||||
// ✅ 从 Core 层获取所有表信息(已包含配置合并)
|
||||
var allTables = _databaseTableService.GetAllTables();
|
||||
|
||||
// 根据 Low_Code_TableId 查找对应的表名和数据库
|
||||
string? targetTableName = null;
|
||||
string? targetDatabase = null;
|
||||
|
||||
if (pagingSearchInput.Search.Low_Code_TableId != Guid.Empty)
|
||||
{
|
||||
var lowCodeTable = await _lowCodeTableRepository.FindAsync(w => w.Id == pagingSearchInput.Search.Low_Code_TableId);
|
||||
if (lowCodeTable != null)
|
||||
{
|
||||
targetTableName = lowCodeTable.TableName;
|
||||
targetDatabase = lowCodeTable.DataBase;
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选目标表
|
||||
var targetTable = allTables.FirstOrDefault(t =>
|
||||
t.TableName == targetTableName && t.DataBase == targetDatabase);
|
||||
|
||||
if (targetTable == null || targetTable.TableInfos == null)
|
||||
{
|
||||
return new PagingView(pagingSearchInput.Page, pagingSearchInput.Size);
|
||||
}
|
||||
|
||||
// 应用筛选条件
|
||||
var columns = targetTable.TableInfos.AsEnumerable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.ColumnName))
|
||||
{
|
||||
columns = columns.Where(w => w.ColumnName != null && w.ColumnName.Contains(pagingSearchInput.Search.ColumnName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.Describe))
|
||||
{
|
||||
columns = columns.Where(w => w.Describe != null && w.Describe.Contains(pagingSearchInput.Search.Describe));
|
||||
}
|
||||
|
||||
// 排序和分页
|
||||
var orderedColumns = columns
|
||||
.OrderBy(w => w.Position)
|
||||
.Skip((pagingSearchInput.Page - 1) * pagingSearchInput.Size)
|
||||
.Take(pagingSearchInput.Size)
|
||||
.Select(w => new Dictionary<string, object?>
|
||||
{
|
||||
["id"] = Guid.NewGuid(), // 临时 ID,因为是从内存查询
|
||||
["isPrimary"] = w.IsPrimary,
|
||||
["isIdentity"] = w.IsIdentity,
|
||||
["isNullable"] = w.IsNullable,
|
||||
["position"] = w.Position,
|
||||
["columnName"] = w.ColumnName,
|
||||
["describe"] = w.Describe,
|
||||
["databaseColumnType"] = w.DatabaseColumnType,
|
||||
["csType"] = w.CsType,
|
||||
["csField"] = w.CsField,
|
||||
["displayName"] = w.DisplayName,
|
||||
["low_Code_TableId"] = pagingSearchInput.Search.Low_Code_TableId,
|
||||
["lastModificationTime"] = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
["creationTime"] = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
["isTableColumnShow"] = w.IsTableColumnShow ?? true,
|
||||
["isTableSelect"] = w.IsTableSelect,
|
||||
["isImageId"] = w.IsImageId,
|
||||
["orderById"] = w.OrderById ?? 10,
|
||||
["maxLength"] = w.MaxLength
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return new PagingView(pagingSearchInput.Page, pagingSearchInput.Size)
|
||||
{
|
||||
Total = columns.Count(),
|
||||
DataSource = orderedColumns,
|
||||
PageCount = (columns.Count() + pagingSearchInput.Size - 1) / pagingSearchInput.Size
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -89,10 +134,7 @@ public class LowCodeTableInfoService : ApplicationService<IRepository<LowCodeTab
|
|||
|
||||
// 修复:同时匹配表名和数据库标识
|
||||
var tableInfo = allTables.Find(w =>
|
||||
{
|
||||
var dbKey = w.Schema.ExtractDatabaseKey();
|
||||
return w.Name == table.TableName && dbKey == table.DataBase;
|
||||
});
|
||||
w.Name == table.TableName && w.DataBase == table.DataBase);
|
||||
|
||||
//查询出当前表所有的字段
|
||||
var tableColumns = await _defaultRepository.ToListAsync(w => w.Low_Code_TableId == table.Id);
|
||||
|
|
@ -115,8 +157,8 @@ public class LowCodeTableInfoService : ApplicationService<IRepository<LowCodeTab
|
|||
model.Position = item.Position;
|
||||
model.Low_Code_TableId = table.Id;
|
||||
model.ColumnName = item.Name;
|
||||
model.DatabaseColumnType = item.DbTypeTextFull;
|
||||
model.CsType = item.CsType.Name;
|
||||
model.DatabaseColumnType = item.DbType;
|
||||
model.CsType = item.CsType;
|
||||
model.CsField = item.Name;
|
||||
model.MaxLength = item.MaxLength;
|
||||
//model.IsImageId = item.IsImageId;
|
||||
|
|
@ -143,11 +185,11 @@ public class LowCodeTableInfoService : ApplicationService<IRepository<LowCodeTab
|
|||
model.IsPrimary = item.IsPrimary;
|
||||
model.IsIdentity = item.IsIdentity;
|
||||
model.IsNullable = item.IsNullable;
|
||||
model.Position = item.Position;
|
||||
model.Low_Code_TableId = table.Id;
|
||||
model.ColumnName = item.Name;
|
||||
model.DatabaseColumnType = item.DbTypeTextFull;
|
||||
model.CsType = item.CsType.Name;
|
||||
model.Position = item.Position;
|
||||
model.Low_Code_TableId = table.Id;
|
||||
model.ColumnName = item.Name;
|
||||
model.DatabaseColumnType = item.DbType;
|
||||
model.CsType = item.CsType;
|
||||
model.CsField = item.Name;
|
||||
model.MaxLength = item.MaxLength;
|
||||
if (!string.IsNullOrWhiteSpace(item.Comment))
|
||||
|
|
@ -175,14 +217,104 @@ public class LowCodeTableInfoService : ApplicationService<IRepository<LowCodeTab
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 变更数据
|
||||
/// 变更数据(保存到配置文件)
|
||||
/// </summary>
|
||||
/// <param name="lowCodeTableInfos"></param>
|
||||
/// <returns></returns>
|
||||
public Task ChangeAsync(List<LowCodeTableInfo> lowCodeTableInfos)
|
||||
public async Task ChangeAsync(List<LowCodeTableInfo> lowCodeTableInfos)
|
||||
{
|
||||
// 清除缓存
|
||||
_databaseTableService.ClearAllTablesByCache();
|
||||
return _defaultRepository.UpdateRangeAsync(lowCodeTableInfos);
|
||||
|
||||
// 按表分组保存
|
||||
var groupedByTable = lowCodeTableInfos.GroupBy(c => c.Low_Code_TableId);
|
||||
|
||||
foreach (var group in groupedByTable)
|
||||
{
|
||||
var tableId = group.Key;
|
||||
var lowCodeTable = await _lowCodeTableRepository.FindAsync(w => w.Id == tableId);
|
||||
|
||||
if (lowCodeTable == null || string.IsNullOrEmpty(lowCodeTable.DataBase) || string.IsNullOrEmpty(lowCodeTable.TableName))
|
||||
continue;
|
||||
|
||||
// 获取完整的表信息(包含所有列)
|
||||
var allTables = _databaseTableService.GetAllTables();
|
||||
var targetTable = allTables.FirstOrDefault(t =>
|
||||
t.TableName == lowCodeTable.TableName &&
|
||||
t.DataBase == lowCodeTable.DataBase);
|
||||
|
||||
if (targetTable == null)
|
||||
continue;
|
||||
|
||||
// 更新用户修改的列配置
|
||||
foreach (var changedColumn in group)
|
||||
{
|
||||
var existingColumn = targetTable.TableInfos?.FirstOrDefault(c => c.ColumnName == changedColumn.ColumnName);
|
||||
if (existingColumn != null)
|
||||
{
|
||||
existingColumn.DisplayName = changedColumn.DisplayName;
|
||||
existingColumn.Describe = changedColumn.Describe;
|
||||
existingColumn.CsField = changedColumn.CsField;
|
||||
existingColumn.IsTableSelect = changedColumn.IsTableSelect;
|
||||
existingColumn.IsImageId = changedColumn.IsImageId;
|
||||
existingColumn.IsTableColumnShow = changedColumn.IsTableColumnShow;
|
||||
existingColumn.OrderById = changedColumn.OrderById;
|
||||
existingColumn.Width = changedColumn.Width;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到配置文件
|
||||
await SaveTableMetaConfigAsync(targetTable);
|
||||
}
|
||||
|
||||
// 注意:不再更新数据库表,改为更新配置文件
|
||||
// await _defaultRepository.UpdateRangeAsync(lowCodeTableInfos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存表元信息到配置文件
|
||||
/// </summary>
|
||||
private async Task SaveTableMetaConfigAsync(CoreGenDbTableDto tableDto)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tableDto.DataBase) || string.IsNullOrEmpty(tableDto.TableName))
|
||||
return;
|
||||
|
||||
var config = new CoreTableMetaConfig
|
||||
{
|
||||
DisplayName = tableDto.DisplayName,
|
||||
EntityName = tableDto.EntityName,
|
||||
Remark = tableDto.Remark,
|
||||
ModelPath = tableDto.ModelPath,
|
||||
ServicePath = tableDto.ServicePath,
|
||||
ControllerPath = tableDto.ControllerPath,
|
||||
ClientIndexPath = tableDto.ClientIndexPath,
|
||||
ClientInfoPath = tableDto.ClientInfoPath,
|
||||
ClientServicePath = tableDto.ClientServicePath,
|
||||
IsCover = tableDto.IsCover ?? false,
|
||||
Columns = new Dictionary<string, CoreColumnMetaConfig>()
|
||||
};
|
||||
|
||||
// 保存列配置
|
||||
if (tableDto.TableInfos != null)
|
||||
{
|
||||
foreach (var column in tableDto.TableInfos)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(column.ColumnName))
|
||||
{
|
||||
config.Columns[column.ColumnName] = new CoreColumnMetaConfig
|
||||
{
|
||||
DisplayName = column.DisplayName,
|
||||
Describe = column.Describe,
|
||||
CsField = column.CsField,
|
||||
IsTableSelect = column.IsTableSelect,
|
||||
IsImageId = column.IsImageId,
|
||||
IsTableColumnShow = column.IsTableColumnShow
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await _tableMetaConfigService.SaveConfigAsync(tableDto.DataBase!, tableDto.TableName!, config);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
|
||||
using MiaoYu.Repository.Admin.Entities.LowCode;
|
||||
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
||||
using CoreIDatabaseTableService = MiaoYu.Core.CodeGenerator.Services.IDatabaseTableService;
|
||||
using CoreICodeGenerationService = MiaoYu.Core.CodeGenerator.Services.ICodeGenerationService;
|
||||
using CoreDataSourceManager = MiaoYu.Core.CodeGenerator.Core.DataSourceManager;
|
||||
using CoreITableMetaConfigService = MiaoYu.Core.CodeGenerator.Services.ITableMetaConfigService;
|
||||
using CoreITableSchemaCache = MiaoYu.Core.CodeGenerator.Services.ITableSchemaCache;
|
||||
using CoreEntityNamingStrategy = MiaoYu.Core.CodeGenerator.Abstractions.EntityNamingStrategy;
|
||||
using CorePathResolver = MiaoYu.Core.CodeGenerator.Core.PathResolver;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
|
||||
|
||||
|
|
@ -11,66 +17,116 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
{
|
||||
private readonly IRepository<LowCodeTableInfo> _lowCodeTableInfoRepository;
|
||||
private readonly LowCodeTableInfoService _lowCodeTableInfoService;
|
||||
private readonly IDatabaseTableService _databaseTableService;
|
||||
private readonly ICodeGenerationService _codeGenerationService;
|
||||
private readonly DataSourceManager _dataSourceManager;
|
||||
private readonly CoreIDatabaseTableService _databaseTableService;
|
||||
private readonly CoreICodeGenerationService _codeGenerationService;
|
||||
private readonly CoreDataSourceManager _dataSourceManager;
|
||||
private readonly CoreITableMetaConfigService _tableMetaConfigService;
|
||||
private readonly CoreITableSchemaCache _tableSchemaCache;
|
||||
private readonly CorePathResolver _pathResolver;
|
||||
|
||||
public LowCodeTableService(
|
||||
IRepository<LowCodeTable> defaultRepository,
|
||||
LowCodeTableInfoService lowCodeTableInfoService,
|
||||
IRepository<LowCodeTableInfo> lowCodeTableInfoRepository,
|
||||
IDatabaseTableService databaseTableService,
|
||||
ICodeGenerationService codeGenerationService,
|
||||
DataSourceManager dataSourceManager) : base(defaultRepository)
|
||||
CoreIDatabaseTableService databaseTableService,
|
||||
CoreICodeGenerationService codeGenerationService,
|
||||
CoreDataSourceManager dataSourceManager,
|
||||
CoreITableMetaConfigService tableMetaConfigService,
|
||||
CoreITableSchemaCache tableSchemaCache,
|
||||
CorePathResolver pathResolver) : base(defaultRepository)
|
||||
{
|
||||
_lowCodeTableInfoService = lowCodeTableInfoService;
|
||||
_lowCodeTableInfoRepository = lowCodeTableInfoRepository;
|
||||
_databaseTableService = databaseTableService;
|
||||
_codeGenerationService = codeGenerationService;
|
||||
_dataSourceManager = dataSourceManager;
|
||||
_tableMetaConfigService = tableMetaConfigService;
|
||||
_tableSchemaCache = tableSchemaCache;
|
||||
_pathResolver = pathResolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表数据
|
||||
/// 获取列表数据(从 Core 层查询表结构并合并配置)
|
||||
/// </summary>
|
||||
/// <param name="pagingSearchInput"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagingView> FindListAsync(PagingSearchInput<LowCodeTable> pagingSearchInput)
|
||||
{
|
||||
|
||||
var query = _defaultRepository.SelectNoTracking
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search.TableName),
|
||||
w => w.TableName.Contains(pagingSearchInput.Search.TableName))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search.EntityName),
|
||||
w => w.EntityName.Contains(pagingSearchInput.Search.EntityName))
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search.DisplayName),
|
||||
w => w.DisplayName.Contains(pagingSearchInput.Search.DisplayName))
|
||||
.OrderByDescending(w => w.CreationTime)
|
||||
.ThenByDescending(w => w.LastModificationTime)
|
||||
.Select(w => new
|
||||
{
|
||||
w.Id,
|
||||
w.TableName,
|
||||
w.DisplayName,
|
||||
w.EntityName,
|
||||
w.Remark,
|
||||
w.LastModificationTime,
|
||||
w.CreationTime,
|
||||
w.DataBase,
|
||||
})
|
||||
;
|
||||
|
||||
//获取一下数据用于缓存
|
||||
_databaseTableService.GetAllTables();
|
||||
|
||||
var result = await _defaultRepository.AsPagingViewAsync(query, pagingSearchInput);
|
||||
//覆盖值
|
||||
result
|
||||
.FormatValue(query, w => w.CreationTime, (oldValue) => oldValue.ToString("yyyy-MM-dd"))
|
||||
.FormatValue(query, w => w.LastModificationTime, (oldValue) => oldValue?.ToString("yyyy-MM-dd"))
|
||||
;
|
||||
|
||||
return result;
|
||||
// ✅ 从 Core 层获取所有表信息(已包含配置合并)
|
||||
var allTables = _databaseTableService.GetAllTables();
|
||||
|
||||
// 应用筛选条件
|
||||
var filteredTables = allTables.AsEnumerable();
|
||||
|
||||
// ✅ 数据库筛选条件(重要:支持多数据源筛选)
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.DataBase))
|
||||
{
|
||||
filteredTables = filteredTables.Where(t =>
|
||||
t.DataBase == pagingSearchInput.Search.DataBase);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.TableName))
|
||||
{
|
||||
filteredTables = filteredTables.Where(t =>
|
||||
t.TableName != null && t.TableName.Contains(pagingSearchInput.Search.TableName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.EntityName))
|
||||
{
|
||||
filteredTables = filteredTables.Where(t =>
|
||||
t.EntityName != null && t.EntityName.Contains(pagingSearchInput.Search.EntityName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.DisplayName))
|
||||
{
|
||||
filteredTables = filteredTables.Where(t =>
|
||||
t.DisplayName != null && t.DisplayName.Contains(pagingSearchInput.Search.DisplayName));
|
||||
}
|
||||
|
||||
// 排序和分页
|
||||
var pagedTablesList = filteredTables
|
||||
.Skip((pagingSearchInput.Page - 1) * pagingSearchInput.Size)
|
||||
.Take(pagingSearchInput.Size)
|
||||
.ToList();
|
||||
|
||||
// 异步获取 ID 并构建结果
|
||||
var pagedTables = new List<Dictionary<string, object?>>();
|
||||
foreach (var t in pagedTablesList)
|
||||
{
|
||||
var id = await GetOrCreateTableId(t.TableName, t.DataBase);
|
||||
pagedTables.Add(new Dictionary<string, object?>
|
||||
{
|
||||
["id"] = id,
|
||||
["tableName"] = t.TableName,
|
||||
["displayName"] = t.DisplayName,
|
||||
["entityName"] = t.EntityName,
|
||||
["remark"] = t.Remark,
|
||||
["lastModificationTime"] = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
["creationTime"] = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
["dataBase"] = t.DataBase
|
||||
});
|
||||
}
|
||||
|
||||
return new PagingView(pagingSearchInput.Page, pagingSearchInput.Size)
|
||||
{
|
||||
Total = filteredTables.Count(),
|
||||
DataSource = pagedTables,
|
||||
PageCount = (filteredTables.Count() + pagingSearchInput.Size - 1) / pagingSearchInput.Size
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或创建表的 ID(用于兼容性)
|
||||
/// </summary>
|
||||
private async Task<Guid> GetOrCreateTableId(string? tableName, string? dataBase)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(dataBase))
|
||||
return Guid.NewGuid();
|
||||
|
||||
var existingTable = await _defaultRepository.FindAsync(t =>
|
||||
t.TableName == tableName && t.DataBase == dataBase);
|
||||
|
||||
return existingTable?.Id ?? Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -80,12 +136,32 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
/// <returns></returns>
|
||||
public async Task DeleteListAsync(List<Guid> ids)
|
||||
{
|
||||
// 查询要删除的表信息,用于删除配置文件
|
||||
var tablesToDelete = await _defaultRepository.Select.Where(w => ids.Contains(w.Id)).ToListAsync();
|
||||
|
||||
_databaseTableService.ClearAllTablesByCache();
|
||||
|
||||
//删除子表
|
||||
//await this._lowCodeTableInfoRepository.DeleteBulkAsync(w => ids.Contains(w.Low_Code_TableId));
|
||||
await _lowCodeTableInfoRepository.DeleteAsync(w => ids.Contains(w.Low_Code_TableId));
|
||||
|
||||
//删除主表
|
||||
await _defaultRepository.DeleteByIdsAsync(ids);
|
||||
|
||||
// 删除对应的配置文件
|
||||
foreach (var table in tablesToDelete)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(table.DataBase) && !string.IsNullOrEmpty(table.TableName))
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tableMetaConfigService.DeleteConfigAsync(table.DataBase, table.TableName);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 配置文件可能不存在,忽略异常
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -93,6 +169,9 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
/// </summary>
|
||||
public async Task SynchronizationAsync()
|
||||
{
|
||||
// 刷新表结构缓存(从数据库重新加载表结构)
|
||||
_tableSchemaCache.RefreshCache();
|
||||
|
||||
var allTables = _databaseTableService.GetAllTableInfos();
|
||||
var oldAllTables = await _defaultRepository.ToListAllAsync();
|
||||
|
||||
|
|
@ -102,12 +181,12 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
|
||||
foreach (var item in allTables)
|
||||
{
|
||||
var table = oldAllTables.Find(w => w.TableName == item.Name);
|
||||
// 修复:同时匹配表名和数据库标识,避免多数据源同名表冲突
|
||||
var table = oldAllTables.Find(w => w.TableName == item.Name && w.DataBase == item.DataBase);
|
||||
var id = Guid.NewGuid();
|
||||
|
||||
// 使用扩展方法提取数据库标识
|
||||
var databaseKey = item.Schema.ExtractDatabaseKey();
|
||||
var provider = _dataSourceManager.GetProvider(databaseKey);
|
||||
// 获取数据源提供者
|
||||
var provider = _dataSourceManager.GetProvider(item.DataBase ?? "Admin");
|
||||
|
||||
if (table == null)
|
||||
{
|
||||
|
|
@ -116,12 +195,12 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
Id = id,
|
||||
DisplayName = item.Comment,
|
||||
TableName = item.Name,
|
||||
DataBase = databaseKey,
|
||||
Schema = item.Schema.CleanSchema(),
|
||||
DataBase = item.DataBase,
|
||||
Schema = item.Schema,
|
||||
// 根据命名策略生成实体名
|
||||
EntityName = provider?.Config.NamingStrategy == Abstractions.EntityNamingStrategy.KeepOriginal
|
||||
EntityName = provider?.Config.NamingStrategy == CoreEntityNamingStrategy.KeepOriginal
|
||||
? item.Name
|
||||
: item.Name.ToLineConvertHump()
|
||||
: ConvertToPascalCase(item.Name)
|
||||
};
|
||||
|
||||
insertList.Add(lowCodeTable);
|
||||
|
|
@ -129,11 +208,11 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
else
|
||||
{
|
||||
id = table.Id;
|
||||
table.DataBase = databaseKey;
|
||||
table.Schema = item.Schema.CleanSchema();
|
||||
table.EntityName = provider?.Config.NamingStrategy == Abstractions.EntityNamingStrategy.KeepOriginal
|
||||
table.DataBase = item.DataBase;
|
||||
table.Schema = item.Schema;
|
||||
table.EntityName = provider?.Config.NamingStrategy == CoreEntityNamingStrategy.KeepOriginal
|
||||
? item.Name
|
||||
: item.Name.ToLineConvertHump();
|
||||
: ConvertToPascalCase(item.Name);
|
||||
|
||||
updateList.Add(table);
|
||||
}
|
||||
|
|
@ -151,12 +230,40 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
await _defaultRepository.UpdateRangeAsync(updateList);
|
||||
}
|
||||
|
||||
// 同步列信息
|
||||
foreach (var item in ids)
|
||||
{
|
||||
await _lowCodeTableInfoService.SynchronizationColumnByTableIdAsync(item, true);
|
||||
}
|
||||
|
||||
_databaseTableService.ClearAllTablesByCache();
|
||||
// 注意:这里不需要清除缓存,因为缓存在开始时已经刷新过了
|
||||
// 清除缓存会导致下次查询重新加载,没有必要
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将下划线命名转换为 PascalCase
|
||||
/// </summary>
|
||||
private static string ConvertToPascalCase(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
|
||||
var words = input.Split(new[] { '_', '-' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var result = new System.Text.StringBuilder();
|
||||
|
||||
foreach (var word in words)
|
||||
{
|
||||
if (word.Length > 0)
|
||||
{
|
||||
result.Append(char.ToUpper(word[0]));
|
||||
if (word.Length > 1)
|
||||
{
|
||||
result.Append(word.Substring(1).ToLower());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -192,7 +299,7 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
var res = new Dictionary<string, object>();
|
||||
var form = (await _defaultRepository.FindByIdAsync(id)).NullSafe();
|
||||
|
||||
_codeGenerationService.FillPathByLowCodeTable(form);
|
||||
FillPathByLowCodeTable(form);
|
||||
|
||||
res[nameof(id)] = id == Guid.Empty ? "" : id;
|
||||
res[nameof(form)] = form;
|
||||
|
|
@ -201,6 +308,36 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
|
|||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 lowCodeTable 填充路径(支持多数据源)
|
||||
/// </summary>
|
||||
private void FillPathByLowCodeTable(LowCodeTable lowCodeTable)
|
||||
{
|
||||
var provider = _dataSourceManager.GetProvider(lowCodeTable.DataBase ?? "Admin");
|
||||
if (provider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ModelPath))
|
||||
lowCodeTable.ModelPath = _pathResolver.ResolvePath(provider.Config.ModelPathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ServicePath))
|
||||
lowCodeTable.ServicePath = _pathResolver.ResolvePath(provider.Config.ServicePathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ControllerPath))
|
||||
lowCodeTable.ControllerPath = _pathResolver.ResolvePath(provider.Config.ControllerPathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ClientIndexPath))
|
||||
lowCodeTable.ClientIndexPath = _pathResolver.ResolvePath(provider.Config.ClientIndexPathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ClientInfoPath))
|
||||
lowCodeTable.ClientInfoPath = _pathResolver.ResolvePath(provider.Config.ClientInfoPathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
|
||||
if (string.IsNullOrEmpty(lowCodeTable.ClientServicePath))
|
||||
lowCodeTable.ClientServicePath = _pathResolver.ResolvePath(provider.Config.ClientServicePathTemplate, provider.Config, lowCodeTable.TableName!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存数据
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
using HZY.Framework.DependencyInjection.Attributes;
|
||||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
using MiaoYu.Core.CodeGenerator.Abstractions;
|
||||
using CoreDbTableInfo = MiaoYu.Core.CodeGenerator.Models.DbTableInfo;
|
||||
using CoreDbColumnInfo = MiaoYu.Core.CodeGenerator.Models.DbColumnInfo;
|
||||
using MiaoYu.Repository.Admin.Entities.LowCode;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers;
|
||||
|
||||
|
|
@ -35,11 +38,42 @@ public class AdminDataSourceProvider : IDataSourceProvider, IScopedDependency
|
|||
UsesPluralPath = true
|
||||
};
|
||||
|
||||
public List<DbTableInfo> GetTables()
|
||||
public List<CoreDbTableInfo> GetTables()
|
||||
{
|
||||
return _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
|
||||
var freeSqlTables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
|
||||
return ConvertToDbTableInfoList(freeSqlTables);
|
||||
}
|
||||
|
||||
public DbContext GetDbContext() => _repository.GetContext()!;
|
||||
public object GetDbContext() => _repository.GetContext()!;
|
||||
|
||||
private List<CoreDbTableInfo> ConvertToDbTableInfoList(List<FreeSql.DatabaseModel.DbTableInfo> freeSqlTables)
|
||||
{
|
||||
var result = new List<CoreDbTableInfo>();
|
||||
foreach (var table in freeSqlTables)
|
||||
{
|
||||
var dbTableInfo = new CoreDbTableInfo
|
||||
{
|
||||
DataBase = Config.DatabaseKey,
|
||||
Schema = table.Schema,
|
||||
Name = table.Name,
|
||||
Type = table.Type.ToString(),
|
||||
Comment = table.Comment,
|
||||
Columns = table.Columns?.Select(c => new CoreDbColumnInfo
|
||||
{
|
||||
Name = c.Name,
|
||||
Comment = c.Comment,
|
||||
IsPrimary = c.IsPrimary,
|
||||
IsIdentity = c.IsIdentity,
|
||||
IsNullable = c.IsNullable,
|
||||
Position = c.Position,
|
||||
DbType = c.DbTypeTextFull,
|
||||
CsType = c.CsType?.Name,
|
||||
MaxLength = c.MaxLength
|
||||
}).ToList()
|
||||
};
|
||||
result.Add(dbTableInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using HZY.Framework.DependencyInjection.Attributes;
|
||||
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
|
||||
using MiaoYu.Core.CodeGenerator.Abstractions;
|
||||
using CoreDbTableInfo = MiaoYu.Core.CodeGenerator.Models.DbTableInfo;
|
||||
using CoreDbColumnInfo = MiaoYu.Core.CodeGenerator.Models.DbColumnInfo;
|
||||
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
||||
|
||||
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers;
|
||||
|
|
@ -36,14 +38,42 @@ public class MiaoYuChatDataSourceProvider : IDataSourceProvider, IScopedDependen
|
|||
UsesPluralPath = false
|
||||
};
|
||||
|
||||
public List<DbTableInfo> GetTables()
|
||||
public List<CoreDbTableInfo> GetTables()
|
||||
{
|
||||
var tables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
|
||||
// 标记数据源来源
|
||||
tables.ForEach(t => t.Schema = t.Schema + "." + Config.DatabaseKey);
|
||||
return tables;
|
||||
var freeSqlTables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
|
||||
return ConvertToDbTableInfoList(freeSqlTables);
|
||||
}
|
||||
|
||||
public DbContext GetDbContext() => _repository.GetContext()!;
|
||||
public object GetDbContext() => _repository.GetContext()!;
|
||||
|
||||
private List<CoreDbTableInfo> ConvertToDbTableInfoList(List<FreeSql.DatabaseModel.DbTableInfo> freeSqlTables)
|
||||
{
|
||||
var result = new List<CoreDbTableInfo>();
|
||||
foreach (var table in freeSqlTables)
|
||||
{
|
||||
var dbTableInfo = new CoreDbTableInfo
|
||||
{
|
||||
DataBase = Config.DatabaseKey,
|
||||
Schema = table.Schema,
|
||||
Name = table.Name,
|
||||
Type = table.Type.ToString(),
|
||||
Comment = table.Comment,
|
||||
Columns = table.Columns?.Select(c => new CoreDbColumnInfo
|
||||
{
|
||||
Name = c.Name,
|
||||
Comment = c.Comment,
|
||||
IsPrimary = c.IsPrimary,
|
||||
IsIdentity = c.IsIdentity,
|
||||
IsNullable = c.IsNullable,
|
||||
Position = c.Position,
|
||||
DbType = c.DbTypeTextFull,
|
||||
CsType = c.CsType?.Name,
|
||||
MaxLength = c.MaxLength
|
||||
}).ToList()
|
||||
};
|
||||
result.Add(dbTableInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
using CoreICodeGenerationService = MiaoYu.Core.CodeGenerator.Services.ICodeGenerationService;
|
||||
using CoreDataSourceDto = MiaoYu.Core.CodeGenerator.Models.DataSourceDto;
|
||||
using CorePagingView = MiaoYu.Core.CodeGenerator.Models.PagingView;
|
||||
using CoreGenFormDto = MiaoYu.Core.CodeGenerator.Models.GenFormDto;
|
||||
|
||||
namespace MiaoYu.Api.Admin.Controllers.DevelopmentTools;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成器控制器
|
||||
/// </summary>
|
||||
[ControllerDescriptor(MenuId = "31")]
|
||||
public class CodeGenerationController : AdminControllerBase<ICodeGenerationService>
|
||||
public class CodeGenerationController : AdminControllerBase<CoreICodeGenerationService>
|
||||
{
|
||||
public CodeGenerationController(ICodeGenerationService defaultService) : base(defaultService)
|
||||
public CodeGenerationController(CoreICodeGenerationService defaultService) : base(defaultService)
|
||||
{
|
||||
|
||||
|
||||
|
|
@ -18,7 +23,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "获取数据库列表")]
|
||||
[HttpGet]
|
||||
public List<DataSourceDto> GetDatabasesAsync()
|
||||
public List<CoreDataSourceDto> GetDatabasesAsync()
|
||||
{
|
||||
return _defaultService.GetAllDataSources();
|
||||
}
|
||||
|
|
@ -32,7 +37,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "查询列表")]
|
||||
[HttpPost("{size}/{page}")]
|
||||
public PagingView FindListAsync([FromRoute] int size, [FromRoute] int page, [FromBody] GenFormDto search)
|
||||
public CorePagingView FindListAsync([FromRoute] int size, [FromRoute] int page, [FromBody] CoreGenFormDto search)
|
||||
{
|
||||
return _defaultService.GetGenContextDtos(page, size, search);
|
||||
}
|
||||
|
|
@ -44,7 +49,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "获取代码")]
|
||||
[HttpPost]
|
||||
public async Task<dynamic> GetCodeAsync([FromBody] GenFormDto genFormDto)
|
||||
public async Task<dynamic> GetCodeAsync([FromBody] CoreGenFormDto genFormDto)
|
||||
{
|
||||
var code = await _defaultService.GetCodeByTypeAndTableNameAsync(genFormDto);
|
||||
|
||||
|
|
@ -85,7 +90,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "下载当前代码")]
|
||||
[HttpPost]
|
||||
public async Task DownloadAsync([FromBody] GenFormDto genFormDto)
|
||||
public async Task DownloadAsync([FromBody] CoreGenFormDto genFormDto)
|
||||
{
|
||||
var (codeBytes, contentType, fileName) = await _defaultService.DownloadAsync(genFormDto);
|
||||
HttpContext.DownLoadFile(codeBytes, contentType, fileName);
|
||||
|
|
@ -98,7 +103,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "创建代码文件")]
|
||||
[HttpPost]
|
||||
public async Task DownloadAllAsync([FromBody] GenFormDto genFormDto)
|
||||
public async Task DownloadAllAsync([FromBody] CoreGenFormDto genFormDto)
|
||||
{
|
||||
var (codeBytes, contentType, fileName) = await _defaultService.DownloadAllAsync(genFormDto);
|
||||
HttpContext.DownLoadFile(codeBytes, contentType, fileName);
|
||||
|
|
@ -126,7 +131,7 @@ public class CodeGenerationController : AdminControllerBase<ICodeGenerationServi
|
|||
/// <returns></returns>
|
||||
[ActionDescriptor(DisplayName = "生成代码并自动导入项目")]
|
||||
[HttpPost]
|
||||
public async Task<bool> AutoImprotProjectAsync([FromBody] GenFormDto genFormDto)
|
||||
public async Task<bool> AutoImprotProjectAsync([FromBody] CoreGenFormDto genFormDto)
|
||||
{
|
||||
await _defaultService.AutoImprotProjectAsync(genFormDto);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MiaoYu.Core.CodeGenerator\MiaoYu.Core.CodeGenerator.csproj" />
|
||||
<ProjectReference Include="..\MiaoYu.Core.Cos\MiaoYu.Core.Cos.csproj" />
|
||||
<ProjectReference Include="..\MiaoYu.Core.Identity\MiaoYu.Core.Identity.csproj" />
|
||||
<ProjectReference Include="..\MiaoYu.Core.Quartz\MiaoYu.Core.Quartz.csproj" />
|
||||
|
|
|
|||
|
|
@ -1384,561 +1384,6 @@
|
|||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig">
|
||||
<summary>
|
||||
数据源配置
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.DatabaseKey">
|
||||
<summary>
|
||||
数据库标识(如:Admin, MiaoYuChat, LiveForum)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.DisplayName">
|
||||
<summary>
|
||||
显示名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.EntityNamespace">
|
||||
<summary>
|
||||
实体项目命名空间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ModelPathTemplate">
|
||||
<summary>
|
||||
实体类路径模板(支持占位符:{RootPath}, {Namespace}, {EntityName}, {EntityNamePlural}, {TableName})
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ServicePathTemplate">
|
||||
<summary>
|
||||
服务层路径模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ControllerPathTemplate">
|
||||
<summary>
|
||||
控制器路径模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientIndexPathTemplate">
|
||||
<summary>
|
||||
前端Index页面路径模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientInfoPathTemplate">
|
||||
<summary>
|
||||
前端Info页面路径模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientServicePathTemplate">
|
||||
<summary>
|
||||
前端Service路径模板
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.TemplatePath">
|
||||
<summary>
|
||||
代码生成模板目录
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.NamingStrategy">
|
||||
<summary>
|
||||
实体类命名规则(保持原名 or 驼峰转换)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.Order">
|
||||
<summary>
|
||||
排序权重(数字越小越靠前)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.EnableEntityPrefix">
|
||||
<summary>
|
||||
是否启用实体类名前缀(用于避免多数据源同名表冲突)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.EntityPrefix">
|
||||
<summary>
|
||||
实体类名前缀(如:Chat、Forum)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.UsesPluralPath">
|
||||
<summary>
|
||||
是否使用复数形式的路径(如 /Users/ vs /User/)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants">
|
||||
<summary>
|
||||
数据源常量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.Admin">
|
||||
<summary>
|
||||
后台管理系统数据库
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.MiaoYuChat">
|
||||
<summary>
|
||||
喵语AI聊天数据库
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.LiveForum">
|
||||
<summary>
|
||||
直播论坛数据库(预留)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy">
|
||||
<summary>
|
||||
实体命名策略
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy.KeepOriginal">
|
||||
<summary>
|
||||
保持数据库表名原样
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy.ToPascalCase">
|
||||
<summary>
|
||||
转换为驼峰命名(去除前缀下划线)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider">
|
||||
<summary>
|
||||
数据源提供者接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.Config">
|
||||
<summary>
|
||||
数据源配置
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.GetTables">
|
||||
<summary>
|
||||
获取该数据源的所有表信息
|
||||
</summary>
|
||||
<returns>表信息列表</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.GetDbContext">
|
||||
<summary>
|
||||
获取DbContext(用于获取FreeSql实例)
|
||||
</summary>
|
||||
<returns>数据库上下文</returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions">
|
||||
<summary>
|
||||
数据源扩展方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions.ExtractDatabaseKey(System.String)">
|
||||
<summary>
|
||||
从 Schema 中提取数据库标识
|
||||
</summary>
|
||||
<param name="schema">Schema字符串</param>
|
||||
<returns>数据库标识</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions.CleanSchema(System.String)">
|
||||
<summary>
|
||||
清理 Schema(移除数据库标识)
|
||||
</summary>
|
||||
<param name="schema">Schema字符串</param>
|
||||
<returns>清理后的Schema</returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager">
|
||||
<summary>
|
||||
数据源管理器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.#ctor(System.Collections.Generic.IEnumerable{MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider})">
|
||||
<summary>
|
||||
构造函数(通过依赖注入自动收集所有IDataSourceProvider实现)
|
||||
</summary>
|
||||
<param name="providers">所有数据源提供者</param>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetAllProviders">
|
||||
<summary>
|
||||
获取所有数据源提供者
|
||||
</summary>
|
||||
<returns>数据源提供者集合</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetProvider(System.String)">
|
||||
<summary>
|
||||
根据数据库标识获取数据源提供者
|
||||
</summary>
|
||||
<param name="databaseKey">数据库标识(如:Admin, MiaoYuChat)</param>
|
||||
<returns>数据源提供者,如果未找到返回null</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetAllTables">
|
||||
<summary>
|
||||
获取所有数据源的表信息
|
||||
</summary>
|
||||
<returns>所有表信息列表</returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver">
|
||||
<summary>
|
||||
路径解析器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver.ResolvePath(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig,System.String)">
|
||||
<summary>
|
||||
解析路径模板
|
||||
</summary>
|
||||
<param name="template">路径模板(支持占位符)</param>
|
||||
<param name="config">数据源配置</param>
|
||||
<param name="tableName">表名</param>
|
||||
<returns>解析后的完整路径</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver.GetEntityName(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig)">
|
||||
<summary>
|
||||
根据命名策略和配置获取实体名
|
||||
</summary>
|
||||
<param name="tableName">表名</param>
|
||||
<param name="config">数据源配置</param>
|
||||
<returns>实体名</returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService">
|
||||
<summary>
|
||||
代码生成服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GetGenContextDtos(System.Int32,System.Int32,MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成上下文集合
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GetGenContextDtoByTableName(System.String,System.String)">
|
||||
<summary>
|
||||
获取表字段集合
|
||||
</summary>
|
||||
<param name="tableName"></param>
|
||||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.FillPathByLowCodeTable(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable)">
|
||||
<summary>
|
||||
根据 lowCodeTable 填充路径
|
||||
</summary>
|
||||
<param name="lowCodeTable"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GetGenContextDto(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取代码生成上下文
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenModelAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 model
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenServiceAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 service
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenControllerAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 controller
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenServiceJsAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 serviceJs
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenIndexAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 Index
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GenInfoAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 Info
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GetCodeByTypeAndTableNameAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取代码
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.DownloadAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
下载
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.DownloadAllAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
根据类型下载类型下所有的代码
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.CreateAllCodeFilesAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
创建所有代码文件
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.CreateDataDictionary">
|
||||
<summary>
|
||||
创建数据字典文件 excel
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.AutoImprotProjectAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
代码生成自动导入项目
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService.GetAllDataSources">
|
||||
<summary>
|
||||
获取所有数据库列表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService">
|
||||
<summary>
|
||||
代码生成服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.#ctor(MiaoYu.Shared.Admin.ApplicationServices.IDatabaseTableService,MiaoYu.Core.Razor.Services.IRazorViewRender,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver)">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="databaseTableService">数据库表服务</param>
|
||||
<param name="razorViewRender">Razor视图渲染器</param>
|
||||
<param name="webHostEnvironment">Web宿主环境</param>
|
||||
<param name="dataSourceManager">数据源管理器</param>
|
||||
<param name="pathResolver">路径解析器</param>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetGenContextDtos(System.Int32,System.Int32,MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成上下文集合
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetGenContextDtoByTableName(System.String,System.String)">
|
||||
<summary>
|
||||
获取所有表集合信息
|
||||
</summary>
|
||||
<param name="tableName">表名</param>
|
||||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.FillPathByLowCodeTable(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable)">
|
||||
<summary>
|
||||
根据 lowCodeTable 填充路径(支持多数据源)
|
||||
</summary>
|
||||
<param name="lowCodeTable">低代码表配置</param>
|
||||
<returns>填充路径后的低代码表配置</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetGenContextDto(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取代码生成上下文
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenModelAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成model(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenServiceAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成service(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenControllerAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成controller(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenServiceJsAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成service js(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenIndexAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 index vue(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenInfoAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
生成 info vue(支持多数据源)
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetCodeByTypeAndTableNameAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取代码
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.CreateAllCodeFilesAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
创建所有代码文件
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.DownloadAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取下载代码信息
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.DownloadAllAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
根据类型下载所有代码
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.CreateDataDictionary">
|
||||
<summary>
|
||||
创建数据库字典文件
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.AutoImprotProjectAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
自动导入文件到项目
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetAllDataSources">
|
||||
<summary>
|
||||
获取所有数据库列表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.ClearSymbol(System.Text.StringBuilder)">
|
||||
<summary>
|
||||
清除多余符号
|
||||
</summary>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.CreateCodeFilesAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
创建代码文件
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.FindCodeFileClassName(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<summary>
|
||||
获取代码文件名称
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetFileAbsolutelyPath(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.FileTypeEnum,System.String)">
|
||||
<summary>
|
||||
获取要生成文件的绝对路径
|
||||
</summary>
|
||||
<param name="tableName"></param>
|
||||
<param name="type"></param>
|
||||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.SaveToFileAsync(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.FileTypeEnum,System.String,System.String,System.String)">
|
||||
<summary>
|
||||
保存到文件
|
||||
</summary>
|
||||
<param name="tableName"></param>
|
||||
<param name="type"></param>
|
||||
<param name="filePath"></param>
|
||||
<param name="oldName"></param>
|
||||
<param name="replaceName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetEnumDescription(MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.FileTypeEnum)">
|
||||
<summary>
|
||||
获取枚举上的描述特性
|
||||
</summary>
|
||||
<param name="type"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService">
|
||||
<summary>
|
||||
数据库表服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.#ctor(Microsoft.Extensions.Caching.Memory.IMemoryCache,HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config},MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager)">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="memoryCache">内存缓存</param>
|
||||
<param name="lowCodeTableRepository">低代码表仓储</param>
|
||||
<param name="lowCodeTableInfoRepository">低代码表字段仓储</param>
|
||||
<param name="imageConfig">图片配置仓储</param>
|
||||
<param name="dataSourceManager">数据源管理器</param>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetAllTableInfos">
|
||||
<summary>
|
||||
获取所有的表 包含表下面的列(支持多数据源)
|
||||
</summary>
|
||||
<returns>所有表信息列表</returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetAllTables">
|
||||
<summary>
|
||||
获取所有的表 包含表下面的列
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetAllTablesByCache">
|
||||
<summary>
|
||||
获取表信息根据缓存
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.ClearAllTablesByCache">
|
||||
<summary>
|
||||
清空所有表缓存信息
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetDatabaseName">
|
||||
<summary>
|
||||
获取数据库名称
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableInfoService">
|
||||
<summary>
|
||||
服务 Low_Code_Table_InfoService
|
||||
|
|
@ -1946,7 +1391,7 @@
|
|||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableInfoService.FindListAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo})">
|
||||
<summary>
|
||||
获取列表数据
|
||||
获取列表数据(从 Core 层查询表结构并合并配置)
|
||||
</summary>
|
||||
<param name="pagingSearchInput"></param>
|
||||
<returns></returns>
|
||||
|
|
@ -1968,11 +1413,16 @@
|
|||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableInfoService.ChangeAsync(System.Collections.Generic.List{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo})">
|
||||
<summary>
|
||||
变更数据
|
||||
变更数据(保存到配置文件)
|
||||
</summary>
|
||||
<param name="lowCodeTableInfos"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableInfoService.SaveTableMetaConfigAsync(MiaoYu.Core.CodeGenerator.Models.GenDbTableDto)">
|
||||
<summary>
|
||||
保存表元信息到配置文件
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService">
|
||||
<summary>
|
||||
服务 Low_Code_TableService
|
||||
|
|
@ -1980,11 +1430,16 @@
|
|||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.FindListAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable})">
|
||||
<summary>
|
||||
获取列表数据
|
||||
获取列表数据(从 Core 层查询表结构并合并配置)
|
||||
</summary>
|
||||
<param name="pagingSearchInput"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.GetOrCreateTableId(System.String,System.String)">
|
||||
<summary>
|
||||
获取或创建表的 ID(用于兼容性)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.DeleteListAsync(System.Collections.Generic.List{System.Guid})">
|
||||
<summary>
|
||||
根据id数组删除
|
||||
|
|
@ -1997,6 +1452,11 @@
|
|||
同步表(支持多数据源)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.ConvertToPascalCase(System.String)">
|
||||
<summary>
|
||||
将下划线命名转换为 PascalCase
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.ChangeAsync(System.Collections.Generic.List{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable})">
|
||||
<summary>
|
||||
变更数据
|
||||
|
|
@ -2011,6 +1471,11 @@
|
|||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.FillPathByLowCodeTable(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable)">
|
||||
<summary>
|
||||
根据 lowCodeTable 填充路径(支持多数据源)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.SaveFormAsync(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable)">
|
||||
<summary>
|
||||
保存数据
|
||||
|
|
@ -3859,7 +3324,7 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.FindListAsync(System.Int32,System.Int32,MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.FindListAsync(System.Int32,System.Int32,MiaoYu.Core.CodeGenerator.Models.GenFormDto)">
|
||||
<summary>
|
||||
获取列表
|
||||
</summary>
|
||||
|
|
@ -3868,21 +3333,21 @@
|
|||
<param name="search"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.GetCodeAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.GetCodeAsync(MiaoYu.Core.CodeGenerator.Models.GenFormDto)">
|
||||
<summary>
|
||||
获取代码 根据 表名 和 类型
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.DownloadAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.DownloadAsync(MiaoYu.Core.CodeGenerator.Models.GenFormDto)">
|
||||
<summary>
|
||||
下载当前代码
|
||||
</summary>
|
||||
<param name="genFormDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.DownloadAllAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.DownloadAllAsync(MiaoYu.Core.CodeGenerator.Models.GenFormDto)">
|
||||
<summary>
|
||||
创建代码文件
|
||||
</summary>
|
||||
|
|
@ -3895,7 +3360,7 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.AutoImprotProjectAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
|
||||
<member name="M:MiaoYu.Api.Admin.Controllers.DevelopmentTools.CodeGenerationController.AutoImprotProjectAsync(MiaoYu.Core.CodeGenerator.Models.GenFormDto)">
|
||||
<summary>
|
||||
生成代码并自动导入项目
|
||||
</summary>
|
||||
|
|
@ -4902,7 +4367,7 @@
|
|||
版本
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AspNetCoreGeneratedDocument.wwwroot_code_generation_templatev4_tempModel.GetTypeNew(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo)">
|
||||
<member name="M:AspNetCoreGeneratedDocument.wwwroot_code_generation_templatev4_tempModel.GetTypeNew(MiaoYu.Core.CodeGenerator.Models.LowCodeTableInfo)">
|
||||
<summary>
|
||||
获取类型 根据 appTableInfo
|
||||
</summary>
|
||||
|
|
@ -4915,7 +4380,7 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AspNetCoreGeneratedDocument.wwwroot_code_generation_template_tempModel.GetTypeNew(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo)">
|
||||
<member name="M:AspNetCoreGeneratedDocument.wwwroot_code_generation_template_tempModel.GetTypeNew(MiaoYu.Core.CodeGenerator.Models.LowCodeTableInfo)">
|
||||
<summary>
|
||||
获取类型 根据 appTableInfo
|
||||
</summary>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ global using MiaoYu.Core.Quartz.Models;
|
|||
global using MiaoYu.Core.Quartz.Services;
|
||||
global using MiaoYu.Core.Razor;
|
||||
global using MiaoYu.Core.Razor.Services;
|
||||
global using MiaoYu.Core.CodeGenerator;
|
||||
global using MiaoYu.Core.Redis;
|
||||
global using MiaoYu.Core.Swagger;
|
||||
global using MiaoYu.Core.Zips;
|
||||
|
|
@ -59,7 +60,10 @@ global using MiaoYu.Shared.Admin.ApplicationServices;
|
|||
global using MiaoYu.Shared.Admin.Extensions;
|
||||
global using MiaoYu.Shared.Admin.Filters;
|
||||
global using MiaoYu.Shared.Admin.Models.Consts;
|
||||
global using MiaoYu.Shared.Admin.Models.LowCodes;
|
||||
// ❌ 已废弃,重构到 Core 层
|
||||
// global using MiaoYu.Shared.Admin.Models.LowCodes;
|
||||
// ⚠️ 不能全局引入 Core.CodeGenerator.Models,会与 Repository 层的实体类型冲突
|
||||
// 需要时使用类型别名:CoreGenDbTableDto, CoreLowCodeTable 等
|
||||
global using MiaoYu.Shared.Admin.Models.PagingViews;
|
||||
global using MiaoYu.Shared.Filters;
|
||||
global using MiaoYu.Shared.Upload;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
@* 代码生成器模型命名空间 *@
|
||||
@using MiaoYu.Core.CodeGenerator.Models
|
||||
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
@functions
|
||||
{
|
||||
//获取类型 根据 appTableInfo
|
||||
string GetType(DbColumnInfo appTableInfo)
|
||||
string GetType(LowCodeTableInfo appTableInfo)
|
||||
{
|
||||
switch (appTableInfo.DbTypeText)
|
||||
switch (appTableInfo.DatabaseColumnType)
|
||||
{
|
||||
case "uniqueidentifier":
|
||||
return appTableInfo.IsPrimary ? "Guid" : "Guid?";
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
case "decimal":
|
||||
return appTableInfo.IsNullable ? "decimal?" : "decimal";
|
||||
default:
|
||||
return appTableInfo.IsNullable ? appTableInfo.CsType.Name + "?" : appTableInfo.CsType.Name;
|
||||
return appTableInfo.IsNullable ? appTableInfo.CsType + "?" : appTableInfo.CsType;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
@* 代码生成器模型命名空间 *@
|
||||
@using MiaoYu.Core.CodeGenerator.Models
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@model GenDbTableDto
|
||||
@model GenDbTableDto
|
||||
@{
|
||||
var className = Model.EntityName;
|
||||
var classNameRemark = Model.DisplayName;
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
@functions
|
||||
{
|
||||
//获取类型 根据 appTableInfo
|
||||
string GetType(DbColumnInfo appTableInfo)
|
||||
string GetType(LowCodeTableInfo appTableInfo)
|
||||
{
|
||||
switch (appTableInfo.DbTypeText)
|
||||
switch (appTableInfo.DatabaseColumnType)
|
||||
{
|
||||
case "uniqueidentifier":
|
||||
return appTableInfo.IsPrimary ? "Guid" : "Guid?";
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
case "decimal":
|
||||
return appTableInfo.IsNullable ? "decimal?" : "decimal";
|
||||
default:
|
||||
return appTableInfo.IsNullable ? appTableInfo.CsType.Name + "?" : appTableInfo.CsType.Name;
|
||||
return appTableInfo.IsNullable ? appTableInfo.CsType + "?" : appTableInfo.CsType;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,4 +20,3 @@ public static class DataSourceConstants
|
|||
/// </summary>
|
||||
public const string LiveForum = "LiveForum";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
namespace MiaoYu.Core.CodeGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// 代码生成器模块启动器
|
||||
/// </summary>
|
||||
public class CoreCodeGeneratorStartup : StartupModule<CoreCodeGeneratorStartup>
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置服务
|
||||
/// </summary>
|
||||
/// <param name="webApplicationBuilder"></param>
|
||||
public override void ConfigureServices(WebApplicationBuilder webApplicationBuilder)
|
||||
{
|
||||
var services = webApplicationBuilder.Services;
|
||||
|
||||
// 服务已通过 [Component] 和 IScopedDependency 自动注册
|
||||
// 无需手动注册
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置中间件
|
||||
/// </summary>
|
||||
/// <param name="webApplication"></param>
|
||||
public override void Configure(WebApplication webApplication)
|
||||
{
|
||||
// 无需配置中间件
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -141,6 +141,23 @@
|
|||
</summary>
|
||||
<returns>数据库上下文</returns>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Core.CodeGenerator.CoreCodeGeneratorStartup">
|
||||
<summary>
|
||||
代码生成器模块启动器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.CoreCodeGeneratorStartup.ConfigureServices(Microsoft.AspNetCore.Builder.WebApplicationBuilder)">
|
||||
<summary>
|
||||
配置服务
|
||||
</summary>
|
||||
<param name="webApplicationBuilder"></param>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.CoreCodeGeneratorStartup.Configure(Microsoft.AspNetCore.Builder.WebApplication)">
|
||||
<summary>
|
||||
配置中间件
|
||||
</summary>
|
||||
<param name="webApplication"></param>
|
||||
</member>
|
||||
<member name="T:MiaoYu.Core.CodeGenerator.Core.DataSourceExtensions">
|
||||
<summary>
|
||||
数据源扩展方法
|
||||
|
|
@ -681,7 +698,7 @@
|
|||
获取所有表集合信息
|
||||
</summary>
|
||||
<param name="tableName">表名</param>
|
||||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<param name="databaseKey">数据库标识(强烈建议传入,避免多数据源同名表冲突)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.CodeGenerationService.FillPathByLowCodeTable(MiaoYu.Core.CodeGenerator.Models.LowCodeTable)">
|
||||
|
|
@ -817,7 +834,7 @@
|
|||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.CodeGenerationService.SaveToFileAsync(System.String,MiaoYu.Core.CodeGenerator.Services.FileTypeEnum,System.String,System.String,System.String)">
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.CodeGenerationService.SaveToFileAsync(System.String,MiaoYu.Core.CodeGenerator.Services.FileTypeEnum,System.String,System.String,System.String,System.String)">
|
||||
<summary>
|
||||
保存到文件
|
||||
</summary>
|
||||
|
|
@ -826,6 +843,7 @@
|
|||
<param name="filePath"></param>
|
||||
<param name="oldName"></param>
|
||||
<param name="replaceName"></param>
|
||||
<param name="databaseKey">数据库标识(可选)</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.CodeGenerationService.GetEnumDescription(MiaoYu.Core.CodeGenerator.Services.FileTypeEnum)">
|
||||
|
|
@ -846,12 +864,14 @@
|
|||
数据库表服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.DatabaseTableService.#ctor(MiaoYu.Core.CodeGenerator.Services.ITableSchemaCache,MiaoYu.Core.CodeGenerator.Services.ITableMetaConfigService,Microsoft.Extensions.Logging.ILogger{MiaoYu.Core.CodeGenerator.Services.DatabaseTableService})">
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.DatabaseTableService.#ctor(MiaoYu.Core.CodeGenerator.Services.ITableSchemaCache,MiaoYu.Core.CodeGenerator.Services.ITableMetaConfigService,MiaoYu.Core.CodeGenerator.Core.DataSourceManager,MiaoYu.Core.CodeGenerator.Core.PathResolver,Microsoft.Extensions.Logging.ILogger{MiaoYu.Core.CodeGenerator.Services.DatabaseTableService})">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="tableSchemaCache">表结构缓存</param>
|
||||
<param name="tableMetaConfigService">表元信息配置服务</param>
|
||||
<param name="dataSourceManager">数据源管理器</param>
|
||||
<param name="pathResolver">路径解析器</param>
|
||||
<param name="logger">日志</param>
|
||||
</member>
|
||||
<member name="M:MiaoYu.Core.CodeGenerator.Services.DatabaseTableService.GetAllTableInfos">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ namespace MiaoYu.Core.CodeGenerator.Services;
|
|||
/// <summary>
|
||||
/// 代码生成服务
|
||||
/// </summary>
|
||||
public class CodeGenerationService : ICodeGenerationService
|
||||
[Component]
|
||||
public class CodeGenerationService : ICodeGenerationService, IScopedDependency
|
||||
{
|
||||
private readonly string _webRootPath;
|
||||
private readonly string templateRootPath = "/wwwroot/code_generation/template/";
|
||||
|
|
@ -103,7 +104,7 @@ public class CodeGenerationService : ICodeGenerationService
|
|||
/// 获取所有表集合信息
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="databaseKey">数据库标识(可选)</param>
|
||||
/// <param name="databaseKey">数据库标识(强烈建议传入,避免多数据源同名表冲突)</param>
|
||||
/// <returns></returns>
|
||||
public GenDbTableDto GetGenContextDtoByTableName(string tableName, string? databaseKey = null)
|
||||
{
|
||||
|
|
@ -116,7 +117,17 @@ public class CodeGenerationService : ICodeGenerationService
|
|||
}
|
||||
else
|
||||
{
|
||||
// 警告:如果多个数据源有同名表,将返回第一个匹配的表
|
||||
// 建议:始终传入 databaseKey 参数以避免歧义
|
||||
query = query.Where(w => w.TableName == tableName);
|
||||
|
||||
// 记录警告日志
|
||||
var matchedTables = query.ToList();
|
||||
if (matchedTables.Count > 1)
|
||||
{
|
||||
var databases = string.Join(", ", matchedTables.Select(t => t.DataBase));
|
||||
LogUtil.Log.Warning($"表 '{tableName}' 在多个数据源中存在: [{databases}]。未指定 databaseKey,将使用第一个匹配项。");
|
||||
}
|
||||
}
|
||||
|
||||
var genDbTableDto = query.FirstOrDefault();
|
||||
|
|
@ -670,10 +681,11 @@ public class CodeGenerationService : ICodeGenerationService
|
|||
/// <param name="filePath"></param>
|
||||
/// <param name="oldName"></param>
|
||||
/// <param name="replaceName"></param>
|
||||
/// <param name="databaseKey">数据库标识(可选)</param>
|
||||
/// <returns></returns>
|
||||
private async Task SaveToFileAsync(string tableName, FileTypeEnum type, string filePath, string oldName, string replaceName)
|
||||
private async Task SaveToFileAsync(string tableName, FileTypeEnum type, string filePath, string oldName, string replaceName, string? databaseKey = null)
|
||||
{
|
||||
var dto = new GenFormDto() { TableName = tableName, Type = GetEnumDescription(type) };
|
||||
var dto = new GenFormDto() { TableName = tableName, Type = GetEnumDescription(type), DataBase = databaseKey };
|
||||
var codeString = await GetCodeByTypeAndTableNameAsync(dto);
|
||||
if (!string.IsNullOrWhiteSpace(replaceName) && !string.IsNullOrWhiteSpace(oldName))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ namespace MiaoYu.Core.CodeGenerator.Services;
|
|||
/// <summary>
|
||||
/// 数据库表服务
|
||||
/// </summary>
|
||||
public class DatabaseTableService : IDatabaseTableService
|
||||
[Component]
|
||||
public class DatabaseTableService : IDatabaseTableService, IScopedDependency
|
||||
{
|
||||
private readonly ITableSchemaCache _tableSchemaCache;
|
||||
private readonly ITableMetaConfigService _tableMetaConfigService;
|
||||
private readonly DataSourceManager _dataSourceManager;
|
||||
private readonly PathResolver _pathResolver;
|
||||
private readonly ILogger<DatabaseTableService> _logger;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -14,14 +17,20 @@ public class DatabaseTableService : IDatabaseTableService
|
|||
/// </summary>
|
||||
/// <param name="tableSchemaCache">表结构缓存</param>
|
||||
/// <param name="tableMetaConfigService">表元信息配置服务</param>
|
||||
/// <param name="dataSourceManager">数据源管理器</param>
|
||||
/// <param name="pathResolver">路径解析器</param>
|
||||
/// <param name="logger">日志</param>
|
||||
public DatabaseTableService(
|
||||
ITableSchemaCache tableSchemaCache,
|
||||
ITableMetaConfigService tableMetaConfigService,
|
||||
DataSourceManager dataSourceManager,
|
||||
PathResolver pathResolver,
|
||||
ILogger<DatabaseTableService> logger)
|
||||
{
|
||||
_tableSchemaCache = tableSchemaCache;
|
||||
_tableMetaConfigService = tableMetaConfigService;
|
||||
_dataSourceManager = dataSourceManager;
|
||||
_pathResolver = pathResolver;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +100,12 @@ public class DatabaseTableService : IDatabaseTableService
|
|||
/// </summary>
|
||||
private GenDbTableDto MergeTableWithConfig(DbTableInfo schemaTable)
|
||||
{
|
||||
// 获取数据源配置以应用命名策略
|
||||
var provider = _dataSourceManager.GetProvider(schemaTable.DataBase ?? "");
|
||||
var defaultEntityName = provider != null
|
||||
? _pathResolver.GetEntityName(schemaTable.Name ?? "", provider.Config)
|
||||
: schemaTable.Name;
|
||||
|
||||
var genTable = new GenDbTableDto
|
||||
{
|
||||
TableName = schemaTable.Name,
|
||||
|
|
@ -98,6 +113,9 @@ public class DatabaseTableService : IDatabaseTableService
|
|||
Schema = schemaTable.Schema,
|
||||
Type = schemaTable.Type,
|
||||
Remark = schemaTable.Comment,
|
||||
// 提供默认的实体名和显示名(应用命名策略)
|
||||
EntityName = defaultEntityName,
|
||||
DisplayName = schemaTable.Comment ?? schemaTable.Name,
|
||||
TableInfos = schemaTable.Columns?.Select(c => new LowCodeTableInfo
|
||||
{
|
||||
ColumnName = c.Name,
|
||||
|
|
@ -118,10 +136,13 @@ public class DatabaseTableService : IDatabaseTableService
|
|||
var config = _tableMetaConfigService.LoadConfig(schemaTable.DataBase, schemaTable.Name);
|
||||
if (config != null)
|
||||
{
|
||||
// 使用配置文件中的元信息覆盖
|
||||
genTable.DisplayName = config.DisplayName;
|
||||
genTable.EntityName = config.EntityName;
|
||||
genTable.Remark = config.Remark ?? genTable.Remark;
|
||||
// 使用配置文件中的元信息覆盖(如果配置文件中有值才覆盖)
|
||||
if (!string.IsNullOrEmpty(config.DisplayName))
|
||||
genTable.DisplayName = config.DisplayName;
|
||||
if (!string.IsNullOrEmpty(config.EntityName))
|
||||
genTable.EntityName = config.EntityName;
|
||||
if (!string.IsNullOrEmpty(config.Remark))
|
||||
genTable.Remark = config.Remark;
|
||||
genTable.ModelPath = config.ModelPath;
|
||||
genTable.ServicePath = config.ServicePath;
|
||||
genTable.ControllerPath = config.ControllerPath;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace MiaoYu.Core.CodeGenerator.Services;
|
|||
/// 表元信息配置服务实现
|
||||
/// </summary>
|
||||
[Component]
|
||||
public class TableMetaConfigService : ITableMetaConfigService
|
||||
public class TableMetaConfigService : ITableMetaConfigService, IScopedDependency
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly ILogger<TableMetaConfigService> _logger;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace MiaoYu.Core.CodeGenerator.Services;
|
|||
/// 表结构缓存服务实现
|
||||
/// </summary>
|
||||
[Component]
|
||||
public class TableSchemaCache : ITableSchemaCache
|
||||
public class TableSchemaCache : ITableSchemaCache, IScopedDependency
|
||||
{
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly DataSourceManager _dataSourceManager;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ global using Microsoft.Extensions.DependencyInjection;
|
|||
global using Microsoft.Extensions.Caching.Memory;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
global using Microsoft.AspNetCore.Hosting;
|
||||
global using Microsoft.AspNetCore.Builder;
|
||||
global using NPOI.XSSF.UserModel;
|
||||
global using HZY.Framework.Core;
|
||||
global using HZY.Framework.Core.AspNetCore;
|
||||
global using HZY.Framework.DependencyInjection;
|
||||
global using HZY.Framework.DependencyInjection.Attributes;
|
||||
global using MiaoYu.Core.Logs;
|
||||
|
|
|
|||
1386
admin-server/代码生成器架构说明.md
Normal file
1386
admin-server/代码生成器架构说明.md
Normal file
File diff suppressed because it is too large
Load Diff
885
admin-server/代码生成器流程文档.md
Normal file
885
admin-server/代码生成器流程文档.md
Normal file
|
|
@ -0,0 +1,885 @@
|
|||
# 代码生成器架构与流程文档
|
||||
|
||||
## 一、整体架构
|
||||
|
||||
### 1.1 架构设计原则
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 代码生成器核心架构 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ API层 (MiaoYu.Api.Admin) │
|
||||
│ ├── Controllers (对外接口) │
|
||||
│ ├── Providers (数据源提供者实现) │
|
||||
│ │ ├── AdminDataSourceProvider │
|
||||
│ │ ├── MiaoYuChatDataSourceProvider │
|
||||
│ │ └── LiveForumDataSourceProvider (待实现) │
|
||||
│ └── Services (业务逻辑) │
|
||||
│ ├── LowCodeTableService (表列表管理) │
|
||||
│ └── LowCodeTableInfoService (列配置管理) │
|
||||
│ │
|
||||
│ ───────────────────────────────────────────────────── │
|
||||
│ │
|
||||
│ 核心层 (MiaoYu.Core.CodeGenerator) │
|
||||
│ ├── Abstractions (抽象接口) │
|
||||
│ │ ├── IDataSourceProvider (数据源提供者接口) │
|
||||
│ │ ├── DataSourceConfig (数据源配置) │
|
||||
│ │ └── EntityNamingStrategy (命名策略枚举) │
|
||||
│ ├── Core (核心逻辑) │
|
||||
│ │ ├── DataSourceManager (数据源管理器) │
|
||||
│ │ └── PathResolver (路径解析器) │
|
||||
│ ├── Services (核心服务) │
|
||||
│ │ ├── CodeGenerationService (代码生成服务) │
|
||||
│ │ ├── DatabaseTableService (数据库表服务) │
|
||||
│ │ ├── TableMetaConfigService (表元信息配置服务) │
|
||||
│ │ └── TableSchemaCache (表结构缓存) │
|
||||
│ └── Models (数据模型) │
|
||||
│ ├── GenDbTableDto (统一的表模型) │
|
||||
│ ├── LowCodeTableInfo (列信息模型) │
|
||||
│ ├── DbTableInfo (数据库表信息) │
|
||||
│ └── TableMetaConfig (表元信息配置) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.2 核心设计模式
|
||||
|
||||
1. **Provider 模式**: 支持多数据源扩展
|
||||
2. **策略模式**: 命名策略可配置(PascalCase、KeepOriginal)
|
||||
3. **模板方法模式**: 统一的代码生成流程
|
||||
4. **缓存模式**: 表结构缓存,提升性能
|
||||
5. **配置驱动**: 路径、命名等通过配置文件管理
|
||||
|
||||
---
|
||||
|
||||
## 二、核心流程详解
|
||||
|
||||
### 2.1 启动初始化流程
|
||||
|
||||
```
|
||||
应用启动
|
||||
↓
|
||||
注册数据源提供者 (AdminDataSourceProvider, MiaoYuChatDataSourceProvider)
|
||||
↓
|
||||
DataSourceManager 收集所有 IDataSourceProvider 实例
|
||||
↓
|
||||
TableSchemaCache 从所有数据源加载表结构
|
||||
↓
|
||||
缓存有效期:20分钟
|
||||
```
|
||||
|
||||
**关键代码位置**:
|
||||
- `MiaoYu.Core.CodeGenerator/CoreCodeGeneratorStartup.cs` - 核心模块注册
|
||||
- `MiaoYu.Core.CodeGenerator/Core/DataSourceManager.cs` - 数据源管理
|
||||
- `MiaoYu.Core.CodeGenerator/Services/TableSchemaCache.cs` - 缓存服务
|
||||
|
||||
---
|
||||
|
||||
### 2.2 获取表列表流程
|
||||
|
||||
```
|
||||
前端请求 GET /api/v1/admin/LowCodeTable/list?dataBase=Admin
|
||||
↓
|
||||
LowCodeTableService.FindListAsync()
|
||||
↓
|
||||
调用 DatabaseTableService.GetAllTables()
|
||||
↓
|
||||
├─→ TableSchemaCache.GetAllTables() (从缓存获取原始表信息)
|
||||
│ ↓
|
||||
│ 遍历所有 DataSourceProvider 获取表结构
|
||||
│ ↓
|
||||
│ 返回 List<DbTableInfo>
|
||||
│
|
||||
↓
|
||||
遍历每个 DbTableInfo,调用 MergeTableWithConfig()
|
||||
↓
|
||||
├─→ 获取数据源配置 (DataSourceConfig)
|
||||
├─→ 应用命名策略生成默认 EntityName
|
||||
│ 例如: "song_likes" → "SongLikes" (ToPascalCase)
|
||||
├─→ 加载 TableMetaConfig (如果存在)
|
||||
│ 路径: configs/{dataBase}/{tableName}.json
|
||||
├─→ 合并配置:配置文件中的值覆盖默认值
|
||||
└─→ 返回 GenDbTableDto (统一的表模型)
|
||||
↓
|
||||
过滤 (dataBase, tableName 等条件)
|
||||
↓
|
||||
分页返回
|
||||
```
|
||||
|
||||
**数据转换链**:
|
||||
```
|
||||
DbTableInfo (数据库原始信息)
|
||||
↓
|
||||
+ DataSourceConfig (数据源配置)
|
||||
↓
|
||||
+ TableMetaConfig (用户自定义配置,可选)
|
||||
↓
|
||||
= GenDbTableDto (最终统一模型)
|
||||
```
|
||||
|
||||
**关键文件**:
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/DatabaseTableService.cs`
|
||||
|
||||
---
|
||||
|
||||
### 2.3 修改列配置流程
|
||||
|
||||
```
|
||||
前端请求 PUT /api/v1/admin/LowCodeTableInfo/change
|
||||
↓
|
||||
LowCodeTableInfoService.ChangeAsync(List<LowCodeTableInfo>)
|
||||
↓
|
||||
清除缓存: DatabaseTableService.ClearAllTablesByCache()
|
||||
↓
|
||||
按表分组处理
|
||||
↓
|
||||
对每个表:
|
||||
├─→ 获取 LowCodeTable (从数据库,用于获取 tableName 和 dataBase)
|
||||
├─→ 从 DatabaseTableService.GetAllTables() 获取最新的表信息
|
||||
├─→ 查找目标表
|
||||
├─→ 更新列配置 (DisplayName, Describe, CsField, IsTableSelect 等)
|
||||
└─→ 调用 SaveTableMetaConfigAsync()
|
||||
↓
|
||||
TableMetaConfigService.SaveConfigAsync()
|
||||
↓
|
||||
保存到: configs/{dataBase}/{tableName}.json
|
||||
↓
|
||||
文件内容示例:
|
||||
{
|
||||
"DisplayName": "歌曲点赞记录",
|
||||
"EntityName": "SongLike",
|
||||
"Remark": "记录用户对歌曲的点赞",
|
||||
"Columns": {
|
||||
"SongId": {
|
||||
"DisplayName": "歌曲ID",
|
||||
"Describe": "被点赞的歌曲ID",
|
||||
"CsField": "SongId",
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**配置文件结构**:
|
||||
```json
|
||||
{
|
||||
"DisplayName": "显示名称",
|
||||
"EntityName": "实体类名",
|
||||
"Remark": "备注说明",
|
||||
"ModelPath": "模型路径",
|
||||
"ServicePath": "服务路径",
|
||||
"ControllerPath": "控制器路径",
|
||||
"ClientIndexPath": "前端索引页路径",
|
||||
"ClientInfoPath": "前端详情页路径",
|
||||
"ClientServicePath": "前端服务路径",
|
||||
"IsCover": true,
|
||||
"Columns": {
|
||||
"ColumnName1": {
|
||||
"DisplayName": "列显示名",
|
||||
"Describe": "列描述",
|
||||
"CsField": "C#字段名",
|
||||
"IsTableSelect": true,
|
||||
"IsImageId": false,
|
||||
"IsTableColumnShow": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**关键文件**:
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableInfoService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/TableMetaConfigService.cs`
|
||||
|
||||
---
|
||||
|
||||
### 2.4 代码生成流程
|
||||
|
||||
```
|
||||
前端请求 POST /api/v1/admin/CodeGeneration/getCode
|
||||
参数: { tableName: "song_likes", fileTypeEnum: 1 (Model) }
|
||||
↓
|
||||
CodeGenerationController.GetCodeAsync()
|
||||
↓
|
||||
CoreICodeGenerationService.GetCodeAsync()
|
||||
↓
|
||||
CodeGenerationService.GetCodeAsync()
|
||||
↓
|
||||
1. 获取表信息
|
||||
├─→ GetGenContextDtoByTableName("song_likes")
|
||||
├─→ DatabaseTableService.GetAllTables()
|
||||
└─→ 找到对应的 GenDbTableDto
|
||||
↓
|
||||
2. 确定数据源和配置
|
||||
├─→ DataSourceManager.GetProvider(dataBase)
|
||||
└─→ 获取 DataSourceConfig (包含模板路径、命名策略等)
|
||||
↓
|
||||
3. 解析路径
|
||||
├─→ PathResolver.ResolvePath(template, config, tableName)
|
||||
├─→ 替换占位符:
|
||||
│ {RootPath} → 项目根路径
|
||||
│ {AppPath} → 应用路径
|
||||
│ {EntityName} → SongLike (应用命名策略)
|
||||
│ {EntityNamePlural} → SongLikes
|
||||
│ {TableName} → song_likes
|
||||
└─→ 生成完整路径
|
||||
↓
|
||||
4. 渲染模板
|
||||
├─→ 根据 fileTypeEnum 选择模板文件
|
||||
│ FileTypeEnum.Model → tempModel.cshtml
|
||||
│ FileTypeEnum.Service → tempService.cshtml
|
||||
│ FileTypeEnum.Controller → tempController.cshtml
|
||||
│ 等等
|
||||
├─→ 加载 Razor 模板
|
||||
├─→ 传入 Model: GenDbTableDto
|
||||
└─→ RazorViewRender.RenderToStringAsync()
|
||||
↓
|
||||
5. 返回生成的代码
|
||||
├─→ ModelCode: "public class SongLike { ... }"
|
||||
├─→ FilePath: "D:\\...\\Entities\\Apps\\SongLikes"
|
||||
└─→ FileName: "SongLike.cs"
|
||||
```
|
||||
|
||||
**模板渲染过程**:
|
||||
```
|
||||
tempModel.cshtml (Razor模板)
|
||||
↓
|
||||
@model GenDbTableDto
|
||||
↓
|
||||
访问模型属性:
|
||||
@Model.EntityName → "SongLike"
|
||||
@Model.DisplayName → "歌曲点赞记录"
|
||||
@Model.TableName → "song_likes"
|
||||
@Model.TableInfos → List<LowCodeTableInfo>
|
||||
↓
|
||||
遍历列信息:
|
||||
@foreach (var item in tableInfos)
|
||||
{
|
||||
public @GetType(item) @item.ColumnName { get; set; }
|
||||
}
|
||||
↓
|
||||
生成最终代码
|
||||
```
|
||||
|
||||
**关键文件**:
|
||||
- `MiaoYu.Api.Admin/Controllers/DevelopmentTools/CodeGenerationController.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/CodeGenerationService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Core/PathResolver.cs`
|
||||
- `MiaoYu.Api.Admin/wwwroot/code_generation/template/*.cshtml`
|
||||
|
||||
---
|
||||
|
||||
## 三、关键组件详解
|
||||
|
||||
### 3.1 DataSourceManager (数据源管理器)
|
||||
|
||||
**职责**:
|
||||
- 收集所有 `IDataSourceProvider` 实现
|
||||
- 提供按 key 查询特定数据源的能力
|
||||
- 聚合所有数据源的表信息
|
||||
|
||||
**核心方法**:
|
||||
```csharp
|
||||
public IDataSourceProvider? GetProvider(string key)
|
||||
public List<DbTableInfo> GetAllTables()
|
||||
```
|
||||
|
||||
**使用场景**:
|
||||
- 初始化时收集所有数据源
|
||||
- 生成代码时根据 dataBase 获取对应的 Provider 和配置
|
||||
|
||||
---
|
||||
|
||||
### 3.2 DatabaseTableService (数据库表服务)
|
||||
|
||||
**职责**:
|
||||
- 管理表结构信息
|
||||
- 合并数据库 schema 和用户配置
|
||||
- 提供统一的表数据模型
|
||||
|
||||
**核心方法**:
|
||||
```csharp
|
||||
// 获取所有表(已合并配置)
|
||||
public List<GenDbTableDto> GetAllTables()
|
||||
|
||||
// 合并表结构和配置文件信息
|
||||
private GenDbTableDto MergeTableWithConfig(DbTableInfo schemaTable)
|
||||
```
|
||||
|
||||
**合并逻辑**:
|
||||
1. 创建 `GenDbTableDto`,设置基础信息
|
||||
2. 应用命名策略生成默认 `EntityName`
|
||||
3. 从配置文件加载 `TableMetaConfig`
|
||||
4. 用配置文件中的值覆盖默认值(如果配置存在且有值)
|
||||
5. 合并列级配置
|
||||
|
||||
---
|
||||
|
||||
### 3.3 TableMetaConfigService (表元信息配置服务)
|
||||
|
||||
**职责**:
|
||||
- 加载和保存表的元信息配置
|
||||
- 管理配置文件(JSON格式)
|
||||
|
||||
**配置文件路径规则**:
|
||||
```
|
||||
configs/{dataBase}/{tableName}.json
|
||||
```
|
||||
|
||||
**核心方法**:
|
||||
```csharp
|
||||
public TableMetaConfig? LoadConfig(string dataBase, string tableName)
|
||||
public void SaveConfigAsync(string dataBase, string tableName, TableMetaConfig config)
|
||||
```
|
||||
|
||||
**使用场景**:
|
||||
- 用户修改列配置后保存
|
||||
- 加载表信息时读取用户自定义配置
|
||||
|
||||
---
|
||||
|
||||
### 3.4 PathResolver (路径解析器)
|
||||
|
||||
**职责**:
|
||||
- 解析路径模板中的占位符
|
||||
- 应用命名策略转换表名为实体名
|
||||
|
||||
**支持的占位符**:
|
||||
- `{RootPath}`: 项目根路径
|
||||
- `{AppPath}`: 应用路径
|
||||
- `{Namespace}`: 命名空间
|
||||
- `{EntityName}`: 实体名(单数,应用命名策略)
|
||||
- `{EntityNamePlural}`: 实体名(复数)
|
||||
- `{TableName}`: 原始表名
|
||||
|
||||
**命名策略**:
|
||||
```csharp
|
||||
public enum EntityNamingStrategy
|
||||
{
|
||||
KeepOriginal, // 保持原样
|
||||
ToPascalCase // 转为 PascalCase (song_likes → SongLikes)
|
||||
}
|
||||
```
|
||||
|
||||
**转换规则**:
|
||||
```csharp
|
||||
private static string ConvertToPascalCase(string input)
|
||||
{
|
||||
// "song_likes" → ["song", "likes"]
|
||||
var words = input.Split('_', '-');
|
||||
|
||||
// 首字母大写: ["Song", "Likes"]
|
||||
foreach (var word in words)
|
||||
{
|
||||
result.Append(char.ToUpper(word[0]));
|
||||
result.Append(word.Substring(1).ToLower());
|
||||
}
|
||||
|
||||
// 结果: "SongLikes"
|
||||
return result.ToString();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.5 TableSchemaCache (表结构缓存)
|
||||
|
||||
**职责**:
|
||||
- 缓存所有数据源的表结构信息
|
||||
- 减少数据库查询次数
|
||||
- 提供缓存刷新机制
|
||||
|
||||
**缓存策略**:
|
||||
```csharp
|
||||
private const int CacheDurationMinutes = 20;
|
||||
```
|
||||
|
||||
**核心方法**:
|
||||
```csharp
|
||||
public List<DbTableInfo> GetAllTables()
|
||||
public void ClearCache()
|
||||
```
|
||||
|
||||
**缓存刷新时机**:
|
||||
- 应用启动时自动加载
|
||||
- 缓存过期(20分钟)
|
||||
- 用户手动清除(修改列配置后)
|
||||
|
||||
---
|
||||
|
||||
## 四、数据源配置详解
|
||||
|
||||
### 4.1 DataSourceConfig 配置项
|
||||
|
||||
```csharp
|
||||
public class DataSourceConfig
|
||||
{
|
||||
// 数据库标识键
|
||||
public string DatabaseKey { get; set; }
|
||||
|
||||
// 显示名称
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
// 实体命名空间
|
||||
public string EntityNamespace { get; set; }
|
||||
|
||||
// 路径模板(支持占位符)
|
||||
public string ModelPathTemplate { get; set; }
|
||||
public string ServicePathTemplate { get; set; }
|
||||
public string ControllerPathTemplate { get; set; }
|
||||
public string ClientIndexPathTemplate { get; set; }
|
||||
public string ClientInfoPathTemplate { get; set; }
|
||||
public string ClientServicePathTemplate { get; set; }
|
||||
|
||||
// 模板路径
|
||||
public string TemplatePath { get; set; }
|
||||
|
||||
// 命名策略
|
||||
public EntityNamingStrategy NamingStrategy { get; set; }
|
||||
|
||||
// 实体前缀配置
|
||||
public bool EnableEntityPrefix { get; set; }
|
||||
public string EntityPrefix { get; set; }
|
||||
|
||||
// 路径是否使用复数形式
|
||||
public bool UsesPluralPath { get; set; }
|
||||
|
||||
// 显示顺序
|
||||
public int Order { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 示例:Admin 数据源配置
|
||||
|
||||
```csharp
|
||||
public DataSourceConfig Config => new DataSourceConfig
|
||||
{
|
||||
DatabaseKey = "Admin",
|
||||
DisplayName = "后台管理系统",
|
||||
EntityNamespace = "MiaoYu.Repository.Admin.Entities",
|
||||
|
||||
// 模型路径: D:\...\MiaoYu.Repository.Admin\Entities\Apps\SongLikes
|
||||
ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\Apps\\{EntityNamePlural}",
|
||||
|
||||
// 服务路径: D:\...\MiaoYu.Api.Admin\ApplicationServices\Apps\SongLikes
|
||||
ServicePathTemplate = "{AppPath}\\ApplicationServices\\Apps\\{EntityNamePlural}",
|
||||
|
||||
// 控制器路径
|
||||
ControllerPathTemplate = "{AppPath}\\Controllers\\Apps\\{EntityNamePlural}",
|
||||
|
||||
// 前端路径
|
||||
ClientIndexPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
|
||||
ClientInfoPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
|
||||
ClientServicePathTemplate = "{RootPath}\\admin-client\\src\\services\\apps\\{TableName}s",
|
||||
|
||||
// 模板路径
|
||||
TemplatePath = "/wwwroot/code_generation/template/",
|
||||
|
||||
// 命名策略:转为 PascalCase
|
||||
NamingStrategy = EntityNamingStrategy.ToPascalCase,
|
||||
|
||||
// 不使用前缀
|
||||
EnableEntityPrefix = false,
|
||||
EntityPrefix = "",
|
||||
|
||||
// 路径使用复数
|
||||
UsesPluralPath = true,
|
||||
|
||||
Order = 1
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、Razor 模板详解
|
||||
|
||||
### 5.1 模板文件结构
|
||||
|
||||
```
|
||||
wwwroot/code_generation/
|
||||
├── template/ # 模板 V1
|
||||
│ ├── _ViewImports.cshtml # Razor 视图导入(重要!)
|
||||
│ ├── tempModel.cshtml # 实体模型模板
|
||||
│ ├── tempService.cshtml # 服务模板
|
||||
│ ├── tempController.cshtml # 控制器模板
|
||||
│ ├── tempIndex.cshtml # 前端索引页模板
|
||||
│ ├── tempInfo.cshtml # 前端详情页模板
|
||||
│ └── tempService_admin.cshtml # 前端服务模板
|
||||
└── templatev4/ # 模板 V4(新版本)
|
||||
├── _ViewImports.cshtml
|
||||
├── tempModel.cshtml
|
||||
└── ...
|
||||
```
|
||||
|
||||
### 5.2 _ViewImports.cshtml 的重要性
|
||||
|
||||
**作用**: 定义 Razor 模板的全局 using 指令
|
||||
|
||||
```cshtml
|
||||
@* 代码生成器模型命名空间 *@
|
||||
@using MiaoYu.Core.CodeGenerator.Models
|
||||
```
|
||||
|
||||
**为什么需要**:
|
||||
1. 解决类型冲突:`GenDbTableDto` 在多个命名空间存在
|
||||
2. 明确指定模板使用 Core 层的模型
|
||||
3. 避免 Razor 编译时的类型歧义错误
|
||||
|
||||
**历史问题回顾**:
|
||||
```
|
||||
错误: The model item is of type 'MiaoYu.Core.CodeGenerator.Models.GenDbTableDto',
|
||||
but this ViewDataDictionary requires 'MiaoYu.Shared.Admin.Models.LowCodes.GenDbTableDto'
|
||||
|
||||
原因: 缺少 _ViewImports.cshtml,Razor 引擎使用了错误的类型
|
||||
|
||||
解决: 创建 _ViewImports.cshtml 明确指定使用 Core 层的模型
|
||||
```
|
||||
|
||||
### 5.3 模板示例:tempModel.cshtml
|
||||
|
||||
```cshtml
|
||||
@model GenDbTableDto
|
||||
@{
|
||||
var className = Model.EntityName; // "SongLike"
|
||||
var classNameRemark = Model.DisplayName; // "歌曲点赞记录"
|
||||
|
||||
// 需要忽略的字段
|
||||
var ignores = new string[] {
|
||||
"Id", "CreationTime", "CreatorUserId",
|
||||
"LastModificationTime", "LastModifierUserId",
|
||||
"DeletionTime", "DeleterUserId",
|
||||
"IsDeleted", "TenantId"
|
||||
};
|
||||
|
||||
// 过滤并排序列
|
||||
var tableInfos = Model.TableInfos
|
||||
.Where(w => !ignores.Contains(w.ColumnName))
|
||||
.OrderBy(w => w.Position)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@functions
|
||||
{
|
||||
// 根据列信息获取 C# 类型
|
||||
string GetType(LowCodeTableInfo appTableInfo)
|
||||
{
|
||||
switch (appTableInfo.DatabaseColumnType)
|
||||
{
|
||||
case "uniqueidentifier":
|
||||
return appTableInfo.IsNullable ? "Guid?" : "Guid";
|
||||
case "int":
|
||||
return appTableInfo.IsNullable ? "int?" : "int";
|
||||
case "bigint":
|
||||
return appTableInfo.IsNullable ? "long?" : "long";
|
||||
case "datetime":
|
||||
return appTableInfo.IsNullable ? "DateTime?" : "DateTime";
|
||||
// ... 更多类型映射
|
||||
default:
|
||||
// 使用数据库提供的 C# 类型
|
||||
return appTableInfo.IsNullable
|
||||
? appTableInfo.CsType + "?"
|
||||
: appTableInfo.CsType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<pre>
|
||||
namespace @Model.EntityNamespace.Entities.Apps;
|
||||
|
||||
/// <summary>
|
||||
/// @classNameRemark
|
||||
/// </summary>
|
||||
[EntityDescription(FieldIgnored = true)]
|
||||
[Table("@Model.TableName")]
|
||||
public class @className : DefaultEntityV4
|
||||
{
|
||||
@foreach (var item in tableInfos)
|
||||
{
|
||||
<text>
|
||||
/// <summary>
|
||||
/// @(item.DisplayName ?? item.ColumnName) => 备注: @(item.Describe ?? item.ColumnName)
|
||||
/// </summary>
|
||||
public @GetType(item) @item.ColumnName { get; set; }
|
||||
</text>
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、常见问题与解决方案
|
||||
|
||||
### 6.1 生成的类名为空
|
||||
|
||||
**现象**:
|
||||
```csharp
|
||||
[Table("")]
|
||||
public class : DefaultEntityV4
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- `GenDbTableDto.EntityName` 和 `TableName` 为 null
|
||||
- `DatabaseTableService` 未提供默认值
|
||||
|
||||
**解决方案**:
|
||||
- 在 `MergeTableWithConfig` 中为 `EntityName` 提供默认值
|
||||
- 使用 `PathResolver.GetEntityName()` 应用命名策略
|
||||
- 从 `schemaTable.Name` 转换为 PascalCase
|
||||
|
||||
### 6.2 Razor 模板类型错误
|
||||
|
||||
**现象**:
|
||||
```
|
||||
InvalidOperationException: The model item is of type 'X' but requires type 'Y'
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- 缺少 `_ViewImports.cshtml`
|
||||
- 类型在多个命名空间存在,导致歧义
|
||||
|
||||
**解决方案**:
|
||||
- 创建 `_ViewImports.cshtml`
|
||||
- 明确指定: `@using MiaoYu.Core.CodeGenerator.Models`
|
||||
|
||||
### 6.3 属性访问错误
|
||||
|
||||
**现象**:
|
||||
```
|
||||
'DbColumnInfo' does not contain a definition for 'DbTypeText'
|
||||
'string' does not contain a definition for 'Name'
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- 模板中使用了不存在的属性名
|
||||
- 属性类型已更改(如 `CsType` 从 `Type` 改为 `string`)
|
||||
|
||||
**解决方案**:
|
||||
- 检查模型定义,使用正确的属性名
|
||||
- `DbTypeText` → `DatabaseColumnType`
|
||||
- `CsType.Name` → `CsType` (因为已是字符串)
|
||||
|
||||
### 6.4 数据库过滤不生效
|
||||
|
||||
**现象**:
|
||||
- 选择 "Admin" 数据库,仍显示所有数据库的表
|
||||
|
||||
**原因**:
|
||||
- `LowCodeTableService.FindListAsync()` 未应用 `dataBase` 过滤
|
||||
|
||||
**解决方案**:
|
||||
```csharp
|
||||
if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.DataBase))
|
||||
{
|
||||
filteredTables = filteredTables.Where(t =>
|
||||
t.DataBase == pagingSearchInput.Search.DataBase);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、扩展指南
|
||||
|
||||
### 7.1 添加新的数据源
|
||||
|
||||
**步骤**:
|
||||
|
||||
1. **创建 Provider 实现**:
|
||||
|
||||
```csharp
|
||||
[Component]
|
||||
public class LiveForumDataSourceProvider : IDataSourceProvider, IScopedDependency
|
||||
{
|
||||
private readonly IRepository<SomeEntity> _repository;
|
||||
|
||||
public LiveForumDataSourceProvider(IRepository<SomeEntity> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public DataSourceConfig Config => new DataSourceConfig
|
||||
{
|
||||
DatabaseKey = DataSourceConstants.LiveForum,
|
||||
DisplayName = "直播论坛",
|
||||
EntityNamespace = "MiaoYu.Repository.LiveForum.Entities",
|
||||
ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\{EntityNamePlural}",
|
||||
// ... 其他配置
|
||||
NamingStrategy = EntityNamingStrategy.ToPascalCase,
|
||||
Order = 3
|
||||
};
|
||||
|
||||
public List<DbTableInfo> GetTables()
|
||||
{
|
||||
var freeSqlTables = _repository.UnitOfWork.FreeSqlOrm
|
||||
.DbFirst.GetTablesByDatabase();
|
||||
return ConvertToDbTableInfoList(freeSqlTables);
|
||||
}
|
||||
|
||||
public object GetDbContext() => _repository.GetContext()!;
|
||||
|
||||
private List<DbTableInfo> ConvertToDbTableInfoList(/* ... */)
|
||||
{
|
||||
// 转换逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **添加常量**:
|
||||
|
||||
```csharp
|
||||
// MiaoYu.Core.CodeGenerator/Abstractions/DataSourceConstants.cs
|
||||
public static class DataSourceConstants
|
||||
{
|
||||
public const string Admin = "Admin";
|
||||
public const string MiaoYuChat = "MiaoYuChat";
|
||||
public const string LiveForum = "LiveForum"; // 新增
|
||||
}
|
||||
```
|
||||
|
||||
3. **自动注册**:
|
||||
- 使用 `[Component]` 特性,框架会自动注册
|
||||
- `DataSourceManager` 会自动发现并收集
|
||||
|
||||
### 7.2 添加新的命名策略
|
||||
|
||||
**步骤**:
|
||||
|
||||
1. **扩展枚举**:
|
||||
|
||||
```csharp
|
||||
public enum EntityNamingStrategy
|
||||
{
|
||||
KeepOriginal,
|
||||
ToPascalCase,
|
||||
ToSnakeCase // 新增: PascalCase → snake_case
|
||||
}
|
||||
```
|
||||
|
||||
2. **实现转换逻辑**:
|
||||
|
||||
```csharp
|
||||
// PathResolver.cs
|
||||
public string GetEntityName(string tableName, DataSourceConfig config)
|
||||
{
|
||||
var baseName = config.NamingStrategy switch
|
||||
{
|
||||
EntityNamingStrategy.ToPascalCase => ConvertToPascalCase(tableName),
|
||||
EntityNamingStrategy.ToSnakeCase => ConvertToSnakeCase(tableName),
|
||||
_ => tableName
|
||||
};
|
||||
// ...
|
||||
}
|
||||
|
||||
private static string ConvertToSnakeCase(string input)
|
||||
{
|
||||
// 实现 PascalCase → snake_case 转换
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 自定义模板
|
||||
|
||||
**步骤**:
|
||||
|
||||
1. **创建新模板**: 复制现有模板并修改
|
||||
2. **定义模板路径**: 在 `DataSourceConfig` 中配置
|
||||
3. **添加文件类型**: 扩展 `FileTypeEnum`
|
||||
4. **实现生成逻辑**: 在 `CodeGenerationService` 中添加对应处理
|
||||
|
||||
---
|
||||
|
||||
## 八、性能优化建议
|
||||
|
||||
### 8.1 缓存策略
|
||||
|
||||
1. **表结构缓存**: 20 分钟有效期,避免频繁查询数据库
|
||||
2. **配置文件缓存**: 考虑使用 `MemoryCache` 缓存 JSON 配置
|
||||
3. **模板编译缓存**: Razor 引擎已内置缓存
|
||||
|
||||
### 8.2 并发处理
|
||||
|
||||
1. **读写分离**: 读取表结构和生成代码不影响数据库写入
|
||||
2. **异步处理**: 所有 IO 操作使用 `async/await`
|
||||
3. **并行生成**: 批量生成时可使用 `Parallel.ForEach`
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
### 9.1 核心优势
|
||||
|
||||
1. **多数据源支持**: 轻松扩展新数据源
|
||||
2. **配置驱动**: 灵活的路径和命名策略
|
||||
3. **模板化**: Razor 模板,易于定制
|
||||
4. **文件化配置**: JSON 配置文件,支持版本控制
|
||||
5. **缓存优化**: 减少数据库查询,提升性能
|
||||
|
||||
### 9.2 设计亮点
|
||||
|
||||
1. **Provider 模式**: 实现数据源的插件化
|
||||
2. **双层合并**: 数据库 schema + 用户配置
|
||||
3. **命名策略**: 智能转换表名为类名
|
||||
4. **统一模型**: `GenDbTableDto` 作为中间层
|
||||
5. **路径解析**: 占位符系统,灵活配置
|
||||
|
||||
### 9.3 后续改进方向
|
||||
|
||||
1. **LiveForum 数据源**: 补充第三个数据源实现
|
||||
2. **模板管理**: 支持在线编辑和版本管理
|
||||
3. **增量生成**: 只生成变更的部分
|
||||
4. **代码预览**: 生成前预览代码
|
||||
5. **批量操作**: 支持批量表生成
|
||||
|
||||
---
|
||||
|
||||
## 十、参考资料
|
||||
|
||||
### 10.1 核心文件清单
|
||||
|
||||
**API 层**:
|
||||
- `MiaoYu.Api.Admin/Controllers/DevelopmentTools/CodeGenerationController.cs`
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableService.cs`
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableInfoService.cs`
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Providers/AdminDataSourceProvider.cs`
|
||||
- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Providers/MiaoYuChatDataSourceProvider.cs`
|
||||
|
||||
**核心层**:
|
||||
- `MiaoYu.Core.CodeGenerator/CoreCodeGeneratorStartup.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Core/DataSourceManager.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Core/PathResolver.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/CodeGenerationService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/DatabaseTableService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/TableMetaConfigService.cs`
|
||||
- `MiaoYu.Core.CodeGenerator/Services/TableSchemaCache.cs`
|
||||
|
||||
**模板**:
|
||||
- `MiaoYu.Api.Admin/wwwroot/code_generation/template/_ViewImports.cshtml`
|
||||
- `MiaoYu.Api.Admin/wwwroot/code_generation/template/tempModel.cshtml`
|
||||
|
||||
### 10.2 配置文件示例
|
||||
|
||||
**表元信息配置**: `configs/Admin/song_likes.json`
|
||||
```json
|
||||
{
|
||||
"DisplayName": "歌曲点赞记录",
|
||||
"EntityName": "SongLike",
|
||||
"Remark": "记录用户对歌曲的点赞行为",
|
||||
"IsCover": true,
|
||||
"Columns": {
|
||||
"SongId": {
|
||||
"DisplayName": "歌曲ID",
|
||||
"Describe": "被点赞的歌曲标识",
|
||||
"CsField": "SongId",
|
||||
"IsTableSelect": true,
|
||||
"IsTableColumnShow": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2025-11-07
|
||||
**维护者**: AI Assistant
|
||||
|
||||
Loading…
Reference in New Issue
Block a user