UNIVPLMDataIntegration/Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs

769 lines
30 KiB
C#
Raw Normal View History

2025-09-14 16:30:13 +08:00
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.CodeGen;
using System.IO.Compression;
namespace Admin.NET.Core;
/// <summary>
/// 系统代码生成器服务 🧩
/// </summary>
[ApiDescriptionSettings(Order = 270, Description = "代码生成器")]
public class SysCodeGenService : IDynamicApiController, ITransient
{
private readonly CodeGenStrategyFactory _codeGenStrategyFactory;
private readonly SysCodeGenColumnService _codeGenColumnService;
private readonly DbConnectionOptions _dbConnectionOptions;
private readonly SysCacheService _sysCacheService;
private readonly SysMenuService _sysMenuService;
private readonly CodeGenOptions _codeGenOptions;
private readonly ISqlSugarClient _db;
public SysCodeGenService(
IOptions<DbConnectionOptions> dbConnectionOptions,
CodeGenStrategyFactory codeGenStrategyFactory,
SysCodeGenColumnService codeGenColumnService,
IOptions<CodeGenOptions> codeGenOptions,
SysCacheService sysCacheService,
SysMenuService sysMenuService,
ISqlSugarClient db)
{
_db = db;
_sysMenuService = sysMenuService;
_sysCacheService = sysCacheService;
_codeGenOptions = codeGenOptions.Value;
_codeGenColumnService = codeGenColumnService;
_codeGenStrategyFactory = codeGenStrategyFactory;
_dbConnectionOptions = dbConnectionOptions.Value;
}
/// <summary>
/// 获取代码生成分页列表 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取代码生成分页列表")]
public async Task<SqlSugarPagedList<SysCodeGen>> Page(PageCodeGenInput input)
{
return await _db.Queryable<SysCodeGen>().Includes(u => u.TableList)
.WhereIF(!string.IsNullOrWhiteSpace(input.TableName), u => u.TableList.Any(a => a.TableName.Contains(input.TableName.Trim()) || a.EntityName.Contains(input.TableName.Trim())))
.WhereIF(!string.IsNullOrWhiteSpace(input.BusName), u => u.BusName.Contains(input.BusName.Trim()))
2025-09-14 16:30:13 +08:00
.OrderBy(u => u.Id, OrderByType.Desc)
.ToPagedListAsync(input.Page, input.PageSize);
}
/// <summary>
/// 增加代码生成 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("增加代码生成")]
[ApiDescriptionSettings(Name = "Add"), HttpPost]
public async Task AddCodeGen(AddCodeGenInput input)
{
try
{
// 验证参数
ValidateTemplateParameters(input.Adapt<UpdateCodeGenInput>());
await _db.Ado.BeginTranAsync();
// 保存代码生成记录
var codegen = input.Adapt<SysCodeGen>();
await _db.Insertable(codegen).ExecuteCommandAsync();
// 保存关联表
codegen.TableList.ForEach(e => e.CodeGenId = codegen.Id);
await _db.Insertable(codegen.TableList).ExecuteCommandAsync();
// 处理并保存表字段配置
codegen.TableList.ForEach(e =>
{
int orderNo = 1;
e.ColumnList = e.ColumnList.DistinctBy(u => u.PropertyName).ToList(); // 去重
e.ColumnList.ForEach(a =>
{
a.CodeGenTableId = e.Id; // 关联表id
a.OrderNo = orderNo++; // 排序
});
});
await _db.Storageable(codegen.TableList.SelectMany(e => e.ColumnList).ToList()).ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 更新代码生成 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("更新代码生成")]
[ApiDescriptionSettings(Name = "Update"), HttpPost]
public async Task UpdateCodeGen(UpdateCodeGenInput input)
{
try
{
// 验证参数
ValidateTemplateParameters(input);
await _db.Ado.BeginTranAsync();
// 保存代码生成记录
var codegen = input.Adapt<SysCodeGen>();
await _db.Updateable(codegen).ExecuteCommandAsync();
// 保存关联表
codegen.TableList.ForEach(e => e.CodeGenId = codegen.Id);
await _db.Storageable(codegen.TableList).ExecuteCommandAsync();
// 更新配置表
var tableIds = codegen.TableList.Select(w => w.Id).ToList();
await _db.Deleteable<SysCodeGenColumn>().Where(u => tableIds.Contains(u.CodeGenTableId)).ExecuteCommandAsync();
// 处理并保存表字段配置
codegen.TableList.ForEach(e =>
{
int orderNo = 1;
e.ColumnList = e.ColumnList.DistinctBy(u => u.PropertyName).ToList(); // 去重
e.ColumnList.ForEach(a =>
{
a.CodeGenTableId = e.Id; // 关联表id
a.OrderNo = orderNo++; // 排序
});
});
await _db.Storageable(codegen.TableList.SelectMany(e => e.ColumnList).ToList()).ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 删除代码生成 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("删除代码生成")]
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
public async Task DeleteCodeGen(BaseIdInput input)
{
try
{
await _db.Ado.BeginTranAsync();
var entity = await GetDetail(input.Id);
if (entity == null) return;
await _db.Deleteable(entity).ExecuteCommandAsync();
var tableList = entity.TableList;
await _db.Deleteable(tableList).ExecuteCommandAsync();
// 删除表字段配置
var tableIds = tableList.Select(u => u.Id).ToList();
await _db.Deleteable<SysCodeGenColumn>().Where(u => tableIds.Contains(u.CodeGenTableId))
.ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 同步代码生成 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("同步代码生成")]
[ApiDescriptionSettings(Name = "Sync"), HttpPost]
public async Task SyncCodeGen(BaseIdInput input)
{
try
{
await _db.Ado.BeginTranAsync();
var entity = await GetDetail(input.Id);
if (entity == null) return;
var addColumns = new List<SysCodeGenColumn>();
var updateColumns = new List<SysCodeGenColumn>();
var deleteColumns = new List<SysCodeGenColumn>();
foreach (var tableConfig in entity.TableList)
{
// 获取默认字段配置
var columns = await GetDefaultColumnConfigList(new DefaultColumnConfigInput { ConfigId = tableConfig.ConfigId, TableName = tableConfig.TableName });
// 计算新增字段
var addList = columns.Where(u => tableConfig.ColumnList.All(a => a.PropertyName != u.PropertyName))
.Select(u =>
{
u.CodeGenTableId = tableConfig.Id;
return u;
}).ToList();
// 计算更新字段
var updateList = columns.Join(tableConfig.ColumnList,
c => c.PropertyName,
t => t.PropertyName,
(c, t) => new { Column = c, OldColumn = t })
.Where(x => x.Column.NetType != x.OldColumn.NetType ||
x.Column.DataType != x.OldColumn.DataType ||
x.Column.IsPrimarykey != x.OldColumn.IsPrimarykey ||
x.Column.IsRequired != x.OldColumn.IsRequired ||
x.Column.ColumnLength != x.OldColumn.ColumnLength)
.Select(x =>
{
x.Column.Id = x.OldColumn.Id;
x.Column.CodeGenTableId = x.OldColumn.CodeGenTableId;
return x.Column;
}).ToList();
// 计算删除字段
var deleteList = tableConfig.ColumnList.Where(u => columns.All(c => c.PropertyName != u.PropertyName)).ToList();
// 追加到集合
addColumns.AddRange(addList);
updateColumns.AddRange(updateList);
deleteColumns.AddRange(deleteList);
}
// 保存新增、更新、删除字段
if (addColumns.Count > 0) await _db.Insertable(addColumns).ExecuteCommandAsync();
if (updateColumns.Count > 0) await _db.Updateable(updateColumns).ExecuteCommandAsync();
if (deleteColumns.Count > 0) await _db.Deleteable(deleteColumns).ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 获取代码生成详情 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取代码生成详情")]
public async Task<SysCodeGen> GetDetail([FromQuery] BaseIdInput input)
{
return await GetDetail(input.Id);
}
/// <summary>
/// 获取代码生成详情 🔖
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[NonAction]
private async Task<SysCodeGen> GetDetail(long id)
{
return await _db.Queryable<SysCodeGen>().Includes(u => u.TableList, w => w.ColumnList).FirstAsync(u => u.Id == id);
}
/// <summary>
/// 获取代码生成表详情 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取代码生成表详情")]
public async Task<SysCodeGenTable> GetTableDetail([FromQuery] BaseIdInput input)
{
return await _db.Queryable<SysCodeGenTable>().Includes(u => u.ColumnList).FirstAsync(u => u.Id == input.Id);
}
/// <summary>
/// 获取默认表字段配置列表 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取默认表字段配置列表")]
[ApiDescriptionSettings, HttpPost]
public async Task<List<SysCodeGenColumn>> GetDefaultColumnConfigList(DefaultColumnConfigInput input)
{
var list = await GetColumnListByTableName(input.TableName, input.ConfigId);
return _codeGenColumnService.GetDefaultColumnConfigList(list, 0);
}
/// <summary>
/// 获取数据库集合 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取数据库集合")]
public async Task<List<DatabaseOutput>> GetDatabaseList()
{
var dbConfigs = _dbConnectionOptions.ConnectionConfigs;
return await Task.FromResult(dbConfigs.Adapt<List<DatabaseOutput>>());
}
/// <summary>
/// 获取数据库表(实体)集合 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取数据库表(实体)集合")]
public async Task<List<TableOutput>> GetTableList(string configId = SqlSugarConst.MainConfigId)
{
var provider = _db.AsTenant().GetConnectionScope(configId);
var dbTableInfos = provider.DbMaintenance.GetTableInfoList(false);
var config = _dbConnectionOptions.ConnectionConfigs.FirstOrDefault(u => configId.Equals(u.ConfigId));
IEnumerable<EntityInfo> entityInfos = await _codeGenColumnService.GetEntityInfos(); // 获取所有实体定义
entityInfos = entityInfos.OrderBy(u => u.EntityName.StartsWith("Sys") ? 1 : 0).ThenBy(u => u.EntityName);
var tableOutputList = new List<TableOutput>();
foreach (var item in entityInfos)
{
var tbConfigId = item.Type.GetCustomAttribute<TenantAttribute>()?.configId as string ?? SqlSugarConst.MainConfigId;
if (item.Type.IsDefined(typeof(LogTableAttribute))) tbConfigId = SqlSugarConst.LogConfigId;
if (tbConfigId != configId) continue;
var dbTableName = item.DbTableName;
int bracketIndex = dbTableName.IndexOf('{');
if (bracketIndex != -1)
dbTableName = dbTableName.Substring(0, bracketIndex);
var table = dbTableInfos.FirstOrDefault(u => u.Name.ToLower().Equals((config != null && config.DbSettings.EnableUnderLine ? UtilMethods.ToUnderLine(dbTableName) : dbTableName).ToLower()));
if (table == null) continue;
// 计算字段个数
var columnCount = 0;
try
{
var columns = await GetColumnListByTableName(table.Name, configId);
columnCount = columns?.Count ?? 0;
}
catch (Exception)
{
// 如果获取字段失败设为0不影响主流程
columnCount = 0;
}
// 获取程序集名称
var assemblyName = item.Type.Assembly.ManifestModule.Name ?? "";
tableOutputList.Add(new TableOutput
{
ConfigId = configId,
EntityName = item.EntityName,
TableName = table.Name,
TableComment = item.TableDescription,
ColumnCount = columnCount,
AssemblyName = assemblyName
});
}
return tableOutputList;
}
/// <summary>
/// 根据表名获取列集合 🔖
/// </summary>
/// <returns></returns>
[DisplayName("根据表名获取列集合")]
public async Task<List<ColumnOutput>> GetColumnListByTableName([Required] string tableName, string configId = SqlSugarConst.MainConfigId)
{
// 切库---多库代码生成用
var provider = _db.AsTenant().GetConnectionScope(configId);
var config = _dbConnectionOptions.ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == configId);
// 获取实体类型属性
tableName = CodeGenHelper.GetRealName(tableName, config);
var entityType = provider.DbMaintenance.GetTableInfoList(false).FirstOrDefault(u => u.Name == tableName);
if (entityType == null) return null;
//var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenantBaseData)];
var entityList = await _codeGenColumnService.GetEntityInfos();
var entityInfo = entityList.FirstOrDefault(u => CodeGenHelper.GetRealName(u.DbTableName, config).EqualIgnoreCase(tableName));
if (entityInfo == null) throw new Exception($"未找到实体类型:{tableName}");
var entityProps = entityInfo.Type.GetProperties();
var sugarProperties = entityProps.Where(u => u.GetCustomAttribute<SugarColumn>()?.IsIgnore == false).Select(u => new
{
PropertyInfo = u,
PropertyName = u.Name,
NetType = u.PropertyType,
EntityInfo = entityInfo,
ColumnComment = u.GetCustomAttribute<SugarColumn>()?.ColumnDescription,
ColumnName = CodeGenHelper.GetRealName(u.GetCustomAttribute<SugarColumn>()?.ColumnName ?? u.Name, config),
ForeignProperty = entityProps.FirstOrDefault(w => w.GetCustomAttribute<Navigate>()?.GetName() == u.Name)
}).ToList();
// 按原始类型的顺序获取所有实体类型属性不包含导航属性会返回null
var columnList = provider.DbMaintenance.GetColumnInfosByTableName(entityType.Name).Select(u => new ColumnOutput
{
IsNullable = u.IsNullable,
IsPrimarykey = u.IsPrimarykey,
DataType = u.DataType.ToString(),
ColumnComment = u.ColumnDescription,
ColumnName = CodeGenHelper.GetRealName(u.DbColumnName, config),
NetType = CodeGenHelper.ConvertDataType(u, provider.CurrentConnectionConfig.DbType)
}).ToList();
foreach (var property in sugarProperties)
{
var column = columnList.FirstOrDefault(u => u.ColumnName == property.ColumnName);
if (column == null) continue;
column.ColumnComment ??= property.ColumnComment;
column.PropertyName = property.PropertyName;
column.PropertyType = property.NetType;
column.PropertyInfo = property.PropertyInfo;
// 设置外键配置
if (property.ForeignProperty != null)
{
column.IsForeignKey = true;
column.ForeignProperty = property.ForeignProperty;
column.ForeignEntityType = property.ForeignProperty.PropertyType.GetGenericArguments().FirstOrDefault() ?? property.ForeignProperty.PropertyType;
}
}
return columnList.Where(u => !string.IsNullOrWhiteSpace(u.PropertyName)).ToList();
}
/// <summary>
/// 获取程序保存位置 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取程序保存位置")]
public List<string> GetApplicationNamespaces()
{
return _codeGenOptions.BackendApplicationNamespaces;
}
/// <summary>
/// 获取快捷设置外键配置 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取快捷设置外键配置")]
public async Task<dynamic> GetQuickConfigMap()
{
return new
{
sysUser = await GetEffectTreeConfig<SysUser>(u => u.Id, u => u.RealName, u => u.RealName),
sysOrg = await GetEffectTreeConfig<SysOrg>(u => u.Id, u => u.Name, u => u.Name, u => u.Pid)
};
}
/// <summary>
/// 获取联表配置信息
/// </summary>
/// <param name="linkExp"></param>
/// <param name="dispExp"></param>
/// <param name="searchExp"></param>
/// <param name="parentExp"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private async Task<EffectTreeConfigInput> GetEffectTreeConfig<T>(Expression<Func<T, object>> linkExp, Expression<Func<T, object>> dispExp, Expression<Func<T, object>> searchExp, Expression<Func<T, object>> parentExp = null)
{
var entity = _db.EntityMaintenance.GetEntityInfoNoCache(typeof(T));
var configId = entity.Type.GetCustomAttribute<TenantAttribute>()?.configId?.ToString() ?? SqlSugarConst.MainConfigId;
var provider = _db.AsTenant().GetConnectionScope(configId);
var linkProperty = GetPropertyInfo(linkExp);
var disProperty = GetPropertyInfo(dispExp);
var searchProperty = GetPropertyInfo(searchExp);
var parentProperty = GetPropertyInfo(parentExp);
// 获取字段对应的 .NET 类型
var columnNetTypeMap = (await GetColumnListByTableName(entity.Type.Name, configId))
?.ToDictionary(u => u.PropertyName, u => u.NetType) ?? new();
return new()
{
ConfigId = configId,
EntityName = entity.EntityName,
TableName = entity.DbTableName,
TableComment = entity.TableDescription,
TreeTitle = entity.TableDescription,
LinkPropertyName = linkProperty.Name,
DisplayPropertyNames = disProperty.Name,
SearchPropertyName = searchProperty.Name,
ParentPropertyName = parentProperty?.Name,
LinkPropertyType = columnNetTypeMap.GetValueOrDefault(linkProperty.Name),
SearchPropertyType = columnNetTypeMap.GetValueOrDefault(searchProperty.Name),
ParentPropertyType = columnNetTypeMap.GetValueOrDefault(parentProperty?.Name ?? ""),
};
}
/// <summary>
/// 获取表达式属性信息
/// </summary>
/// <param name="expression"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> expression)
{
if (expression == null) return null;
if (expression.Body is UnaryExpression { Operand: MemberExpression member }) return (PropertyInfo)member.Member;
if (expression.Body is MemberExpression memberExpression) return (PropertyInfo)memberExpression.Member;
throw Oops.Oh("表达式必须是一个属性访问: " + expression);
}
/// <summary>
/// 执行代码生成 🔖
/// </summary>
/// <returns></returns>
[DisplayName("执行代码生成")]
public async Task<dynamic> Generate(BaseIdInput input)
{
var codeGen = await GetDetail(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
var codeGenStrategy = _codeGenStrategyFactory.GetStrategy<SysCodeGen>(codeGen.Scene);
var templateList = await codeGenStrategy.GenerateCode(codeGen);
// 删除旧目录
string outputPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "codeGen", codeGen.ModuleName);
if (Directory.Exists(outputPath)) Directory.Delete(outputPath, true);
// 输出文件
foreach (var template in templateList)
{
var dirPath = new DirectoryInfo(template.OutPath).Parent!.FullName;
if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
await File.WriteAllTextAsync(template.OutPath, template.Context);
}
// 生成菜单
if (codeGen.GenerateMenu)
{
var menuList = await GetMenusByCodeGen(codeGen);
await AddMenu(menuList, codeGen.MenuPid);
}
// 非下载模式则返回空
if (!codeGen.GenerateMethod.ToString().StartsWith("DownloadZip")) return null;
// 删除同名文件
var downloadPath = outputPath + ".zip";
if (File.Exists(downloadPath)) File.Delete(downloadPath);
// 创建压缩文件并下载
ZipFile.CreateFromDirectory(outputPath, downloadPath);
return new { url = $"{App.HttpContext.Request.Scheme}://{App.HttpContext.Request.Host.Value}/codeGen/{codeGen.ModuleName}.zip" };
}
/// <summary>
/// 获取代码生成预览 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取代码生成预览")]
public async Task<Dictionary<string, string>> Preview(BaseIdInput input)
{
var codeGen = await GetDetail(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
var codeGenStrategy = _codeGenStrategyFactory.GetStrategy<SysCodeGen>(codeGen.Scene);
return (await codeGenStrategy.GenerateCode(codeGen)).ToDictionary(u => u.Name, u => u.Context);
}
/// <summary>
/// 增加菜单
/// </summary>
/// <param name="menus"></param>
/// <param name="pid"></param>
/// <returns></returns>
private async Task AddMenu(List<SysMenu> menus, long pid)
{
var first = menus.First();
var menu = await _db.Queryable<SysMenu>().FirstAsync(u => u.Type == first.Type && u.Name == first.Name && u.Pid == first.Pid);
if (menu != null) await _sysMenuService.DeleteMenu(new() { Id = menu.Id });
await _db.Insertable(menus).ExecuteCommandAsync();
// 删除角色菜单按钮缓存
_sysCacheService.RemoveByPrefixKey(CacheConst.KeyUserApi);
}
/// <summary>
/// 获取菜单列表
/// </summary>
/// <param name="codeGen"></param>
/// <returns></returns>
private async Task<List<SysMenu>> GetMenusByCodeGen(SysCodeGen codeGen)
{
string pPath;
// 若 pid=0 为顶级则创建菜单目录
SysMenu menuType0 = null;
long tempPid = codeGen.MenuPid;
var menuList = new List<SysMenu>();
var classNameLower = codeGen.ModuleName.ToLower();
var classNameFirstLower = codeGen.ModuleName.ToFirstLetterLowerCase();
if (codeGen.MenuPid == 0)
{
// 目录
menuType0 = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = 0,
Title = codeGen.BusName + "管理",
Type = MenuTypeEnum.Dir,
Icon = "ele-Menu",
Path = $"/{classNameLower}Manage",
Name = classNameFirstLower + "Manage",
Component = "Layout",
OrderNo = 100,
CreateTime = DateTime.Now
};
codeGen.MenuPid = menuType0.Id;
pPath = menuType0.Path;
}
else
{
var pMenu = await _db.Queryable<SysMenu>().FirstAsync(u => u.Id == codeGen.MenuPid) ?? throw Oops.Oh(ErrorCodeEnum.D1505);
pPath = pMenu.Path;
}
// 菜单
var menuType = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = codeGen.MenuPid,
Title = codeGen.BusName + "管理",
Name = classNameFirstLower,
Type = MenuTypeEnum.Menu,
Icon = codeGen.MenuIcon,
Path = pPath + "/" + classNameLower,
Component = $"/{codeGen.PagePath}/{classNameFirstLower}/index"
};
var menuPid = menuType.Id;
int menuOrder = 100;
// 按钮-page
var menuTypePage = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = menuPid,
Title = "查询",
Type = MenuTypeEnum.Btn,
Permission = classNameFirstLower + "/page",
OrderNo = menuOrder,
CreateTime = DateTime.Now
};
menuOrder += 10;
menuList.Add(menuTypePage);
// 按钮-detail
var menuTypeDetail = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = menuPid,
Title = "详情",
Type = MenuTypeEnum.Btn,
Permission = classNameFirstLower + "/detail",
OrderNo = menuOrder,
CreateTime = DateTime.Now
};
menuOrder += 10;
menuList.Add(menuTypeDetail);
// 按钮-add
var menuTypeAdd = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = menuPid,
Title = "增加",
Type = MenuTypeEnum.Btn,
Permission = classNameFirstLower + "/add",
OrderNo = menuOrder,
CreateTime = DateTime.Now
};
menuOrder += 10;
menuList.Add(menuTypeAdd);
// 按钮-delete
var menuTypeDelete = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = menuPid,
Title = "删除",
Type = MenuTypeEnum.Btn,
Permission = classNameFirstLower + "/delete",
OrderNo = menuOrder,
CreateTime = DateTime.Now
};
menuOrder += 10;
menuList.Add(menuTypeDelete);
// 按钮-update
var menuTypeUpdate = new SysMenu
{
Id = YitIdHelper.NextId(),
Pid = menuPid,
Title = "编辑",
Type = MenuTypeEnum.Btn,
Permission = classNameFirstLower + "/update",
OrderNo = menuOrder,
CreateTime = DateTime.Now
};
menuList.Add(menuTypeUpdate);
menuList.Insert(0, menuType);
if (tempPid == 0) menuList.Insert(0, menuType0); // 顶级目录需要添加目录本身
return menuList;
}
/// <summary>
/// 验证模板参数
/// </summary>
/// <param name="input"></param>
[NonAction]
public void ValidateTemplateParameters(UpdateCodeGenInput input)
{
switch (input.Scene)
{
case CodeGenSceneEnum.SingleTable: // 单表操作
break;
case CodeGenSceneEnum.TreeSingleTable: // 树单表操作
if (input.TreeConfig == null) throw Oops.Oh(ErrorCodeEnum.D1402);
input.TreeConfig.Adapt<TreeWithTableConfigInput>().Validate();
input.Validate();
break;
}
// 字段组件配置参数校验
foreach (var column in input.TableList.SelectMany(x => x.ColumnList))
{
if (column.IsCommon) return;
if (column.EffectType is CodeGenEffectTypeEnum.DictSelector or
CodeGenEffectTypeEnum.EnumSelector or CodeGenEffectTypeEnum.ConstSelector
or CodeGenEffectTypeEnum.ApiTreeSelector or CodeGenEffectTypeEnum.ForeignKey
or CodeGenEffectTypeEnum.Upload or CodeGenEffectTypeEnum.DatePicker && column.Config == null) throw Oops.Oh(ErrorCodeEnum.D1403);
switch (column.EffectType)
{
case CodeGenEffectTypeEnum.DictSelector or CodeGenEffectTypeEnum.EnumSelector or CodeGenEffectTypeEnum.ConstSelector:
JSON.Deserialize<EffectDictConfigInput>(column.Config)?.Validate();
break;
case CodeGenEffectTypeEnum.ApiTreeSelector:
JSON.Deserialize<EffectTreeConfigInput>(column.Config)?.Validate();
break;
case CodeGenEffectTypeEnum.ForeignKey:
JSON.Deserialize<EffectForeignKeyConfigInput>(column.Config)?.Validate();
break;
case CodeGenEffectTypeEnum.Upload:
JSON.Deserialize<EffectFileConfigInput>(column.Config)?.Validate();
break;
case CodeGenEffectTypeEnum.DatePicker:
JSON.Deserialize<EffectFileConfigInput>(column.Config)?.Validate();
break;
default:
column.Config = null;
break;
}
}
}
2024-06-15 13:02:35 +08:00
}