Merge pull request 'BUG自动生成代码' (#206) from koy07555/Admin.NET.Pro:BUG自动生成代码 into main

Reviewed-on: http://101.43.53.74:3000/Admin.NET/Admin.NET.Pro/pulls/206
This commit is contained in:
zuohuaijun 2024-12-18 12:02:42 +08:00
commit deb9b3050f
4 changed files with 134 additions and 67 deletions

View File

@ -0,0 +1,81 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Admin.NET.Application.Entity;
/// <summary>
/// 代码自动生成DEMO
/// </summary>
/// <remarks>这个类型主要用于给新人快速体验代码自动生成功能和测试该功能是否正常</remarks>
[SugarTable(null, "代码自动生成DEMO")]
public class TestCodeGenDemo : EntityBase
{
/// <summary>
/// 文本
/// </summary>
[SugarColumn(ColumnDescription = "文本", Length = 128)]
public string? Name { get; set; }
/// <summary>
/// 数值
/// </summary>
[SugarColumn(ColumnDescription = "数值")]
public int Age { get; set; }
/// <summary>
/// 时间选择
/// </summary>
[SugarColumn(ColumnDescription = "时间选择")]
public DateTime? Date1 { get; set; }
/// <summary>
/// 开关
/// </summary>
[SugarColumn(ColumnDescription = "开关")]
public bool IsOk { get; set; }
/// <summary>
/// 外键(sys_user)
/// </summary>
[SugarColumn(ColumnDescription = "外键(sys_user)")]
public long UserId { get; set; }
/// <summary>
/// 树选择框(sys_org)
/// </summary>
[SugarColumn(ColumnDescription = "树选择框(sys_org)")]
public long OrgId { get; set; }
/// <summary>
/// 字典1
/// </summary>
[SugarColumn(ColumnDescription = "字典1")]
public string Dict1 { get; set; }
/// <summary>
/// 枚举1
/// </summary>
[SugarColumn(ColumnDescription = "枚举1")]
public string Enum1 { get; set; }
/// <summary>
/// 常量1
/// </summary>
[SugarColumn(ColumnDescription = "常量1")]
public int Const1 { get; set; }
/// <summary>
/// 上传控件
/// </summary>
[SugarColumn(ColumnDescription = "上传控件")]
public long UploadImage { get; set; }
}

View File

@ -1,4 +1,4 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
// //
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
// //
@ -179,8 +179,8 @@ public class SysCodeGenService : IDynamicApiController, ITransient
var config = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault(u => configId.Equals(u.ConfigId)); var config = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault(u => configId.Equals(u.ConfigId));
IEnumerable<EntityInfo> entityInfos = await GetEntityInfos(); // 获取所有实体定义 IEnumerable<EntityInfo> entityInfos = await GetEntityInfos(false); // 获取所有实体定义
//entityInfos = entityInfos.OrderBy(u => u.EntityName.StartsWith("Sys") ? 1 : 0).ThenBy(u => u.EntityName); entityInfos = entityInfos.OrderBy(u => u.EntityName.StartsWith("Sys") ? 1 : 0).ThenBy(u => u.EntityName);
var tableOutputList = new List<TableOutput>(); var tableOutputList = new List<TableOutput>();
foreach (var item in entityInfos) foreach (var item in entityInfos)
@ -222,7 +222,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
var entityType = provider.DbMaintenance.GetTableInfoList(false).FirstOrDefault(u => u.Name == tableName); var entityType = provider.DbMaintenance.GetTableInfoList(false).FirstOrDefault(u => u.Name == tableName);
if (entityType == null) return null; if (entityType == null) return null;
var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)]; var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)];
var properties = GetEntityInfos().Result.First(u => u.DbTableName == tableName).Type.GetProperties() var properties = GetEntityInfos().Result.First(u => u.DbTableName.ToLower() == tableName.ToLower()).Type.GetProperties()
.Where(e => e.GetCustomAttribute<SugarColumn>()?.IsIgnore == false).Select(u => new .Where(e => e.GetCustomAttribute<SugarColumn>()?.IsIgnore == false).Select(u => new
{ {
PropertyName = u.Name, PropertyName = u.Name,
@ -241,6 +241,8 @@ public class SysCodeGenService : IDynamicApiController, ITransient
}).ToList(); }).ToList();
foreach (var column in columnList) foreach (var column in columnList)
{ {
if (!properties.Any(u => u.ColumnName == column.ColumnName))
continue;
var property = properties.First(u => u.ColumnName == column.ColumnName); var property = properties.First(u => u.ColumnName == column.ColumnName);
column.ColumnComment ??= property?.ColumnComment; column.ColumnComment ??= property?.ColumnComment;
column.PropertyName = property?.PropertyName; column.PropertyName = property?.PropertyName;
@ -318,7 +320,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
/// 获取库表信息 /// 获取库表信息
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task<IEnumerable<EntityInfo>> GetEntityInfos() private async Task<IEnumerable<EntityInfo>> GetEntityInfos(bool filtSysTable = false)
{ {
var types = new List<Type>(); var types = new List<Type>();
if (_codeGenOptions.EntityAssemblyNames != null) if (_codeGenOptions.EntityAssemblyNames != null)
@ -354,8 +356,8 @@ public class SysCodeGenService : IDynamicApiController, ITransient
foreach (var ct in cosType) foreach (var ct in cosType)
{ {
//// 若实体贴[SysTable]特性,则禁止显示系统自带的 //// 若实体贴[SysTable]特性,则禁止显示系统自带的
//if (ct.IsDefined(typeof(SysTableAttribute), false)) if (filtSysTable && ct.IsDefined(typeof(SysTableAttribute), false))
// continue; continue;
var des = ct.GetCustomAttributes(typeof(DescriptionAttribute), false); var des = ct.GetCustomAttributes(typeof(DescriptionAttribute), false);
var description = des.Length > 0 ? ((DescriptionAttribute)des[0]).Description : ""; var description = des.Length > 0 ? ((DescriptionAttribute)des[0]).Description : "";

View File

@ -4,6 +4,9 @@
// //
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using NewLife.Reflection;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using Npgsql; using Npgsql;
namespace Admin.NET.Core.Service; namespace Admin.NET.Core.Service;
@ -344,8 +347,9 @@ public class SysDatabaseService : IDynamicApiController, ITransient
// 优先用创建时间排序 // 优先用创建时间排序
DbColumnInfo orderField = dbColumnInfos.FirstOrDefault(u => u.DbColumnName.ToLower() == "create_time" || u.DbColumnName.ToLower() == "createtime"); DbColumnInfo orderField = dbColumnInfos.FirstOrDefault(u => u.DbColumnName.ToLower() == "create_time" || u.DbColumnName.ToLower() == "createtime");
if (orderField != null) query = query.OrderBy(orderField.DbColumnName); if (orderField != null) query = query.OrderBy(orderField.DbColumnName);
// 再使用第一个主键排序 // 优先用创建时间排序,再使用第一个主键排序
//query = query.OrderBy(dbColumnInfos.First(u => u.IsPrimarykey).DbColumnName); if (dbColumnInfos.Any(u => u.IsPrimarykey))
query = query.OrderBy(dbColumnInfos.First(u => u.IsPrimarykey).DbColumnName);
var records = ((IEnumerable)await query.ToListAsync()).ToDynamicList(); var records = ((IEnumerable)await query.ToListAsync()).ToDynamicList();
// 过滤已存在的数据 // 过滤已存在的数据
@ -402,34 +406,35 @@ public class SysDatabaseService : IDynamicApiController, ITransient
} }
} }
// 检查有没有 System.Text.Json.Serialization.JsonIgnore 的属性 // 检查有没有 System.Text.Json.Serialization.JsonIgnore 或 Newtonsoft.Json.JsonIgnore 的属性
// var jsonIgnoreProperties = entityType.GetProperties().Where(p => (p.GetAttribute<System.Text.Json.Serialization.JsonIgnoreAttribute>() != null || // 如果 JsonIgnore 和 SugarColumn 都存在那么后成序更化时就生成这了这些字段就需要在这里另外补充以处理用户表SysUser中的Password为例
// p.GetAttribute<JsonIgnoreAttribute>() != null) && p.GetAttribute<SugarColumn>() != null).ToList(); var jsonIgnoreProperties = entityType.GetProperties().Where(p => (p.GetAttribute<System.Text.Json.Serialization.JsonIgnoreAttribute>() != null ||
// var jsonIgnoreInfo = new List<List<JsonIgnoredPropertyData>>(); p.GetAttribute<Newtonsoft.Json.JsonIgnoreAttribute>() != null) && p.GetAttribute<SugarColumn>() != null).ToList();
// if (jsonIgnoreProperties.Count > 0) var jsonIgnoreInfo = new List<List<JsonIgnoredPropertyData>>();
// { if (jsonIgnoreProperties.Count > 0)
// int recordIndex = 0; {
// foreach (var r in (IEnumerable)records) int recordIndex = 0;
// { foreach (var r in (IEnumerable)records)
// List<JsonIgnoredPropertyData> record = new(); {
// foreach (var item in jsonIgnoreProperties) List<JsonIgnoredPropertyData> record = new();
// { foreach (var item in jsonIgnoreProperties)
// object v = item.GetValue(r); {
// string strValue = "null"; object v = item.GetValue(r);
// if (v != null) string strValue = "null";
// { if (v != null)
// strValue = v.ToString(); {
// if (v.GetType() == typeof(string)) strValue = v.ToString();
// strValue = "\"" + strValue + "\""; if (v.GetType() == typeof(string))
// else if (v.GetType() == typeof(DateTime)) strValue = "\"" + strValue + "\"";
// strValue = "DateTime.Parse(\"" + ((DateTime)v).ToString("yyyy-MM-dd HH:mm:ss") + "\")"; else if (v.GetType() == typeof(DateTime))
// } strValue = "DateTime.Parse(\"" + ((DateTime)v).ToString("yyyy-MM-dd HH:mm:ss") + "\")";
// record.Add(new JsonIgnoredPropertyData { RecordIndex = recordIndex, Name = item.Name, Value = strValue }); }
// } record.Add(new JsonIgnoredPropertyData { RecordIndex = recordIndex, Name = item.Name, Value = strValue });
// recordIndex++; }
// jsonIgnoreInfo.Add(record); recordIndex++;
// } jsonIgnoreInfo.Add(record);
// } }
}
// 获取所有字段信息 // 获取所有字段信息
var propertyList = entityType.GetProperties().Where(x => false == (x.GetCustomAttribute<SugarColumn>()?.IsIgnore ?? false)).ToList(); var propertyList = entityType.GetProperties().Where(x => false == (x.GetCustomAttribute<SugarColumn>()?.IsIgnore ?? false)).ToList();
@ -440,30 +445,8 @@ public class SysDatabaseService : IDynamicApiController, ITransient
for (var j = i; j > 0; j--) propertyList[j] = propertyList[j - 1]; for (var j = i; j > 0; j--) propertyList[j] = propertyList[j - 1];
propertyList[0] = temp; propertyList[0] = temp;
} }
// 拼接数据 var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
var recordList = records.Select(obj => string.Join(", ", propertyList.Select(prop => var recordList = JsonConvert.SerializeObject(records, Formatting.Indented, timeConverter);
{
var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object value = prop.GetValue(obj);
if (value == null) value = "null";
else if (propType == typeof(string))
{
value = $"\"{value}\"";
}
else if (propType.IsEnum)
{
value = $"{propType.Name}.{value}";
}
else if (propType == typeof(bool))
{
value = (bool)value ? "true" : "false";
}
else if (propType == typeof(DateTime))
{
value = $"DateTime.Parse(\"{((DateTime)value):yyyy-MM-dd HH:mm:ss.fff}\")";
}
return $"{prop.Name}={value}";
}))).ToList();
var tContent = await File.ReadAllTextAsync(templatePath); var tContent = await File.ReadAllTextAsync(templatePath);
var data = new var data = new
@ -475,8 +458,8 @@ public class SysDatabaseService : IDynamicApiController, ITransient
input.SeedDataName, input.SeedDataName,
input.ConfigId, input.ConfigId,
tableInfo.Description, tableInfo.Description,
JsonIgnoreInfo = new List<List<JsonIgnoredPropertyData>>(), JsonIgnoreInfo = jsonIgnoreInfo,
RecordList = JSON.Serialize(recordList) RecordList = recordList
}; };
var tResult = await _viewEngine.RunCompileAsync(tContent, data, builderAction: builder => var tResult = await _viewEngine.RunCompileAsync(tContent, data, builderAction: builder =>
{ {

View File

@ -133,7 +133,7 @@ if (@column.QueryWhether == "Y"){
/// <returns></returns> /// <returns></returns>
[ApiDescriptionSettings(Name = "add", Description = "增加@(@Model.BusName)", Order = 990), HttpPost] [ApiDescriptionSettings(Name = "add", Description = "增加@(@Model.BusName)", Order = 990), HttpPost]
[DisplayName("增加@(@Model.BusName)")] [DisplayName("增加@(@Model.BusName)")]
public async Task<bool> Add(Add@(@Model.ClassName)Input input) public async Task<long> Add(Add@(@Model.ClassName)Input input)
{ {
var entity = input.Adapt<@(@Model.ClassName)>(); var entity = input.Adapt<@(@Model.ClassName)>();
@if(Model.RemoteVerify){ @if(Model.RemoteVerify){
@ -144,7 +144,8 @@ if (@column.QueryWhether == "Y"){
@:throw Oops.Oh(ErrorCodeEnum.D1006); @:throw Oops.Oh(ErrorCodeEnum.D1006);
@:} @:}
} }
return await _@(@Model.LowerClassName)Rep.InsertAsync(entity); await _@(@Model.LowerClassName)Rep.InsertAsync(entity);
return entity.@(@PKName);
} }
/// <summary> /// <summary>