소스 검색

!1421 生成种子数据时允许过滤重复数据。
Merge pull request !1421 from koy0755/优化种子数据生成

zuohuaijun 1 년 전
부모
커밋
fbd3a70b43

+ 9 - 0
Admin.NET/Admin.NET.Core/Service/DataBase/Dto/CreateSeedDataInput.cs

@@ -42,4 +42,13 @@ public class CreateSeedDataInput
     /// </summary>
     /// <example>Web.Application</example>
     public string Suffix { get; set; }
+
+    /// <summary>
+    /// 过滤已有数据
+    /// </summary>
+    /// <remarks>
+    /// 如果数据在其它不同名的已有的种子类型的数据中出现过,就不生成这个数据
+    /// 主要用于生成菜单功能,菜单功能往往与子项目绑定,如果生成完整数据就会导致菜单项多处理重复。
+    /// </remarks>
+    public bool FilterExistingData { get; set; }
 }

+ 63 - 1
Admin.NET/Admin.NET.Core/Service/DataBase/SysDatabaseService.cs

@@ -4,9 +4,11 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+using Mapster.Adapters;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Converters;
 using Npgsql;
+using System.Linq;
 
 namespace Admin.NET.Core.Service;
 
@@ -351,7 +353,67 @@ public class SysDatabaseService : IDynamicApiController, ITransient
         orderField = dbColumnInfos.Where(u => u.DbColumnName.ToLower() == "id").FirstOrDefault();
         if (orderField != null)
             query.OrderBy(orderField.DbColumnName);
-        object records = query.ToList();
+        IEnumerable recordsTmp = (IEnumerable)query.ToList();
+        List<dynamic> records = recordsTmp.ToDynamicList();
+        //这里要过滤已存在的数据
+        if (input.FilterExistingData && records.Count() > 0)
+        {
+            //获取实体类型
+            //获取所有种数据数据类型
+            var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false) && u.FullName.EndsWith("." + input.EntityName))
+                .Where(u => !u.GetCustomAttributes<IgnoreTableAttribute>().Any())
+                .ToList();
+            if (entityTypes.Count == 1) //只有一个实体匹配才能过滤
+            {
+                //获取实体的主键对应的属性名称
+                var pkInfo = entityTypes[0].GetProperties().Where(u => u.GetCustomAttribute<SugarColumn>() != null && u.GetCustomAttribute<SugarColumn>().IsPrimaryKey).First();
+                if (pkInfo != null)
+                {
+                    var seedDataTypes = App.EffectiveTypes
+                        .Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.GetInterfaces().Any(
+                            i => i.HasImplementedRawGeneric(typeof(ISqlSugarEntitySeedData<>)) && i.GenericTypeArguments[0] == entityTypes[0]
+                            )
+                        )
+                        .ToList();
+                    //可能会重名的种子数据不作为过滤项
+                    string doNotFilterfullName1 = $"{input.Position}.SeedData.{input.SeedDataName}";
+                    string doNotFilterfullName2 = $"{input.Position}.{input.SeedDataName}"; //Core中的命名空间没有SeedData
+
+                    PropertyInfo idPropertySeedData = records[0].GetType().GetProperty("Id");
+
+                    for (int i = seedDataTypes.Count - 1; i >= 0; i--)
+                    {
+                        string fullName = seedDataTypes[i].FullName;
+                        if ((fullName == doNotFilterfullName1) || (fullName == doNotFilterfullName2))
+                            continue;
+                        //开始删除重复数据
+                        var instance = Activator.CreateInstance(seedDataTypes[i]);
+                        var hasDataMethod = seedDataTypes[i].GetMethod("HasData");
+                        var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>();
+                        if (seedData == null) continue;
+
+                        List<object> recordsToRemove = new List<object>();
+                        foreach (var record in records)
+                        {
+                            object recordId = pkInfo.GetValue(record);
+                            foreach (var d1 in seedData)
+                            {
+                                object dataId = idPropertySeedData.GetValue(d1);
+                                if (recordId != null && dataId != null && recordId.Equals(dataId))
+                                {
+                                    recordsToRemove.Add(record);
+                                    break;
+                                }
+                            }
+                        }
+                        foreach (var itemToRemove in recordsToRemove)
+                        {
+                            records.Remove(itemToRemove);
+                        }
+                    }
+                }
+            }
+        }
         var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
         var recordsJSON = JsonConvert.SerializeObject(records, Formatting.Indented, timeConverter);
 

+ 6 - 0
Web/src/views/system/database/component/genSeedData.vue

@@ -27,6 +27,11 @@
 							</el-select>
 						</el-form-item>
 					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+						<el-form-item label="过滤重复数据" prop="filterExistingData">
+							<el-switch v-model="state.ruleForm.filterExistingData" ></el-switch>
+						</el-form-item>
+					</el-col>
 				</el-row>
 			</el-form>
 			<template #footer>
@@ -69,6 +74,7 @@ const openDialog = (row: any) => {
 	state.ruleForm.configId = row.configId;
 	state.ruleForm.tableName = row.tableName;
 	state.ruleForm.position = row.position;
+	state.ruleForm.filterExistingData = false;
 	state.isShowDialog = true;
 };