完善基础数据

This commit is contained in:
yanpeng200212
2026-10-08 15:44:07 +08:00
parent 8430ba0452
commit 2ffb83830c
95 changed files with 37759 additions and 5 deletions
@@ -0,0 +1,138 @@
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using FreeSql;
using F9WebAiTest.Domain.Entities.SYS.Registries;
namespace F9WebAiTest.Infrastructure.Data;
/// <summary>
/// 注册表配置导入:来源于 F9 系统 biz_base_registry 表导出数据。
/// 幂等:按原始 Id 判重,已存在则跳过;数据类型归一化为小写。
/// </summary>
public static class RegistrySeedData
{
private const string RegistryResource = "F9WebAiTest.Infrastructure.Data.SeedData.biz_base_registry.json";
private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true };
public static void Seed(IFreeSql fsql)
{
try
{
var items = Load(RegistryResource);
if (items.Count == 0) return;
var existIds = fsql.Select<Registry>()
.DisableGlobalFilter("软删除")
.ToList()
.Select(x => x.Id)
.ToHashSet();
// 同命名空间 + 键名也算重复,避免唯一性问题
var existKeys = fsql.Select<Registry>()
.DisableGlobalFilter("软删除")
.ToList()
.Select(x => $"{x.Category}|{x.KeyName}")
.ToHashSet();
var inserts = new List<Registry>();
var duplicate = 0;
foreach (var item in items)
{
if (item.Id <= 0 || existIds.Contains(item.Id)) continue;
if (string.IsNullOrWhiteSpace(item.Category) || string.IsNullOrWhiteSpace(item.KeyName)) continue;
var category = item.Category.Trim();
var keyName = item.KeyName.Trim();
var key = $"{category}|{keyName}";
if (existKeys.Contains(key) || inserts.Any(x => x.Category == category && x.KeyName == keyName))
{
duplicate++;
continue;
}
inserts.Add(new Registry(item.Id, category, keyName, item.Value ?? string.Empty,
(item.DataType ?? "string").Trim().ToLowerInvariant(), item.Description ?? string.Empty,
ParseActive(item.IsActive))
{
CreatedAt = ParseLegacyDate(item.CreatedAt) ?? DateTime.Now,
CreatedBy = item.CreatedBy ?? string.Empty,
UpdatedAt = ParseLegacyDate(item.UpdatedAt)
});
}
if (inserts.Count > 0) fsql.Insert(inserts).ExecuteAffrows();
Console.WriteLine($"[RegistrySeed] 注册表:来源 {items.Count} 条,新增 {inserts.Count} 条,跳过已存在 {items.Count - inserts.Count - duplicate} 条,重复 {duplicate} 条");
}
catch (Exception ex)
{
Console.WriteLine($"[RegistrySeed] 注册表数据导入跳过:{ex.Message}");
}
}
/// <summary>is_active 在导出数据里可能是 "1"/"0" 字符串、数字或布尔</summary>
private static bool ParseActive(JsonElement element)
{
switch (element.ValueKind)
{
case JsonValueKind.String:
var text = element.GetString();
return text == "1" || string.Equals(text, "true", StringComparison.OrdinalIgnoreCase);
case JsonValueKind.Number:
return element.GetInt32() != 0;
case JsonValueKind.True:
return true;
default:
return false;
}
}
private static List<RegistrySeedItem> Load(string resourceName)
{
var assembly = typeof(RegistrySeedData).Assembly;
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{
Console.WriteLine($"[RegistrySeed] 未找到内嵌资源:{resourceName}");
return new List<RegistrySeedItem>();
}
return JsonSerializer.Deserialize<List<RegistrySeedItem>>(stream, JsonOptions) ?? new List<RegistrySeedItem>();
}
/// <summary>解析 F9 导出的日期(形如 d/M/yyyy H:mm:ss.fff),1970 占位值视为未更新返回 null</summary>
private static readonly string[] LegacyDateFormats =
{
"d/M/yyyy H:mm:ss.fff", "d/M/yyyy H:mm:ss", "d/M/yyyy H:mm",
"M/d/yyyy H:mm:ss.fff", "M/d/yyyy H:mm:ss", "M/d/yyyy H:mm",
"yyyy-MM-dd HH:mm:ss.fff", "yyyy-MM-dd HH:mm:ss"
};
private static DateTime? ParseLegacyDate(string value)
{
if (string.IsNullOrWhiteSpace(value)) return null;
if (DateTime.TryParseExact(value, LegacyDateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var exact))
return exact.Year <= 1900 ? null : exact;
if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var any))
return any.Year <= 1900 ? null : any;
return null;
}
private sealed class RegistrySeedItem
{
[JsonPropertyName("id")] public long Id { get; set; }
[JsonPropertyName("created_by")] public string CreatedBy { get; set; }
[JsonPropertyName("created_at")] public string CreatedAt { get; set; }
[JsonPropertyName("update_by")] public string UpdateBy { get; set; }
[JsonPropertyName("updated_at")] public string UpdatedAt { get; set; }
[JsonPropertyName("category")] public string Category { get; set; }
[JsonPropertyName("key_name")] public string KeyName { get; set; }
[JsonPropertyName("value")] public string Value { get; set; }
[JsonPropertyName("data_type")] public string DataType { get; set; }
[JsonPropertyName("description")] public string Description { get; set; }
[JsonPropertyName("is_active")] public JsonElement IsActive { get; set; }
}
}