From d48dc62fe7ed392a57c3a88478524cf9dd6f2f29 Mon Sep 17 00:00:00 2001 From: kozhilya Date: Wed, 7 May 2025 15:43:38 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=BE=D0=BC=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Processors/Types/RuleProcessor.cs | 98 +++++++++++++++++-- ...signer.cs => 20250507112626_1.Designer.cs} | 27 ++++- ...0250507075826_1.cs => 20250507112626_1.cs} | 12 +++ .../Migrations/Pf2eDbContextModelSnapshot.cs | 25 +++++ Pf2eModel/Model/Structure/Rule.cs | 10 ++ Pf2eModel/Pf2eDbContextModel.cs | 6 ++ 6 files changed, 171 insertions(+), 7 deletions(-) rename Pf2eModel/Migrations/{20250507075826_1.Designer.cs => 20250507112626_1.Designer.cs} (99%) rename Pf2eModel/Migrations/{20250507075826_1.cs => 20250507112626_1.cs} (99%) diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/DataBuilder/Processors/Types/RuleProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/DataBuilder/Processors/Types/RuleProcessor.cs index 5a5bf81..a18371c 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/DataBuilder/Processors/Types/RuleProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/DataBuilder/Processors/Types/RuleProcessor.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Data; +using Microsoft.EntityFrameworkCore.Migrations.Operations; using Newtonsoft.Json.Linq; +using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; +using Rule = Pf2eModel.Model.Structure.Rule; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types; @@ -22,8 +21,95 @@ internal class RuleProcessor(AonprdProcessorInput input) : AbstractEntityProcess { base.Process(); - Object.Breadcrumbs = (Input.GetOptional("breadcrumbs") ?? []) + string[] breadcrumbs = (Input.GetOptional("breadcrumbs") ?? []) .Select(token => token.ToString()) .ToArray(); + + RuleStructureItem item = GetStructureItem( + [.. breadcrumbs, Entity.Name[LocaleType.English]] + ); + + item.IsHandled = true; + item.RuleId = Object.Id; + item.Id = Input.GetRequired("id"); + + if (item.Parent?.IsHandled ?? false) + { + Object.ParentId = item.Parent.RuleId!; + // Object.Order = item.Parent.ChildrenOrder?.IndexOf(item.Id) ?? 0; + Object.Order = 0; + } + + item.ChildrenOrder = []; + + List childrenIds = item + .Children.Select(i => i.RuleId) + .Where(id => id != null) + .OfType() + .ToList(); + + List rules = Context.Rules.Where(i => childrenIds.Contains(i.Id)).ToList(); + + foreach (Rule rule in rules) + { + rule.Order = 0; + } + /* + * TODO + * Обработка порядка из полей + * + "next_link": { + "label": "Chapter 3: Classes", + "url": "/Rules.aspx?ID=134" + }, + "previous_link": { + "label": "Chapter 1: Introduction", + "url": "/Rules.aspx?ID=1" + }, + */ + } + + private static readonly List Roots = []; + + private RuleStructureItem GetStructureItem(string[] breadcrumbs, RuleStructureItem? from = null) + { + while (true) + { + List children = from?.Children ?? Roots; + + if (breadcrumbs.Length == 0) + { + return from!; + } + + string root = breadcrumbs[0]; + RuleStructureItem? item = children.FirstOrDefault(i => i.Name == root); + + if (item is null) + { + item = new(root, from); + children.Add(item); + } + + breadcrumbs = breadcrumbs[1..]; + from = item; + } } } + +internal class RuleStructureItem(string name, RuleStructureItem? parent) +{ + public string? Id { get; set; } = null; + + public string Name { get; set; } = name; + + public int? RuleId { get; set; } = null; + + public bool IsHandled { get; set; } = false; + + public RuleStructureItem? Parent { get; set; } = parent; + + public List? ChildrenOrder { get; set; } = null; + + public List Children { get; } = []; +} diff --git a/Pf2eModel/Migrations/20250507075826_1.Designer.cs b/Pf2eModel/Migrations/20250507112626_1.Designer.cs similarity index 99% rename from Pf2eModel/Migrations/20250507075826_1.Designer.cs rename to Pf2eModel/Migrations/20250507112626_1.Designer.cs index ff6d8fb..d96c48a 100644 --- a/Pf2eModel/Migrations/20250507075826_1.Designer.cs +++ b/Pf2eModel/Migrations/20250507112626_1.Designer.cs @@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum; namespace Pf2eModel.Migrations { [DbContext(typeof(Pf2eDbContext))] - [Migration("20250507075826_1")] + [Migration("20250507112626_1")] partial class _1 { /// @@ -1407,9 +1407,22 @@ namespace Pf2eModel.Migrations .HasColumnType("text[]") .HasColumnName("breadcrumbs"); + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order") + .HasColumnOrder(2); + + b.Property("ParentId") + .HasColumnType("integer") + .HasColumnName("parent_id") + .HasColumnOrder(3); + b.HasKey("Id") .HasName("pk_rules"); + b.HasIndex("ParentId") + .HasDatabaseName("ix_rules_parent_id"); + b.ToTable("rules", (string)null); }); @@ -2276,7 +2289,14 @@ namespace Pf2eModel.Migrations .IsRequired() .HasConstraintName("fk_rules_entities_id"); + b.HasOne("Pf2eModel.Model.Structure.Rule", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .HasConstraintName("fk_rules_rules_parent_id"); + b.Navigation("Entity"); + + b.Navigation("Parent"); }); modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b => @@ -2456,6 +2476,11 @@ namespace Pf2eModel.Migrations b.Navigation("Checks"); }); + modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b => + { + b.Navigation("Children"); + }); + modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b => { b.Navigation("SpellAreas"); diff --git a/Pf2eModel/Migrations/20250507075826_1.cs b/Pf2eModel/Migrations/20250507112626_1.cs similarity index 99% rename from Pf2eModel/Migrations/20250507075826_1.cs rename to Pf2eModel/Migrations/20250507112626_1.cs index 5dc37f9..496b5da 100644 --- a/Pf2eModel/Migrations/20250507075826_1.cs +++ b/Pf2eModel/Migrations/20250507112626_1.cs @@ -329,6 +329,8 @@ namespace Pf2eModel.Migrations columns: table => new { id = table.Column(type: "integer", nullable: false), + order = table.Column(type: "integer", nullable: false), + parent_id = table.Column(type: "integer", nullable: true), breadcrumbs = table.Column(type: "text[]", nullable: false) }, constraints: table => @@ -340,6 +342,11 @@ namespace Pf2eModel.Migrations principalTable: "entities", principalColumn: "id", onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_rules_rules_parent_id", + column: x => x.parent_id, + principalTable: "rules", + principalColumn: "id"); }); migrationBuilder.CreateTable( @@ -1293,6 +1300,11 @@ namespace Pf2eModel.Migrations table: "ritual_checks", column: "training_id"); + migrationBuilder.CreateIndex( + name: "ix_rules_parent_id", + table: "rules", + column: "parent_id"); + migrationBuilder.CreateIndex( name: "ix_spell_areas_spell_id", table: "spell_areas", diff --git a/Pf2eModel/Migrations/Pf2eDbContextModelSnapshot.cs b/Pf2eModel/Migrations/Pf2eDbContextModelSnapshot.cs index 2daa5a1..07100d7 100644 --- a/Pf2eModel/Migrations/Pf2eDbContextModelSnapshot.cs +++ b/Pf2eModel/Migrations/Pf2eDbContextModelSnapshot.cs @@ -1404,9 +1404,22 @@ namespace Pf2eModel.Migrations .HasColumnType("text[]") .HasColumnName("breadcrumbs"); + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order") + .HasColumnOrder(2); + + b.Property("ParentId") + .HasColumnType("integer") + .HasColumnName("parent_id") + .HasColumnOrder(3); + b.HasKey("Id") .HasName("pk_rules"); + b.HasIndex("ParentId") + .HasDatabaseName("ix_rules_parent_id"); + b.ToTable("rules", (string)null); }); @@ -2273,7 +2286,14 @@ namespace Pf2eModel.Migrations .IsRequired() .HasConstraintName("fk_rules_entities_id"); + b.HasOne("Pf2eModel.Model.Structure.Rule", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .HasConstraintName("fk_rules_rules_parent_id"); + b.Navigation("Entity"); + + b.Navigation("Parent"); }); modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b => @@ -2453,6 +2473,11 @@ namespace Pf2eModel.Migrations b.Navigation("Checks"); }); + modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b => + { + b.Navigation("Children"); + }); + modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b => { b.Navigation("SpellAreas"); diff --git a/Pf2eModel/Model/Structure/Rule.cs b/Pf2eModel/Model/Structure/Rule.cs index 9ed8c69..2cefc47 100644 --- a/Pf2eModel/Model/Structure/Rule.cs +++ b/Pf2eModel/Model/Structure/Rule.cs @@ -15,5 +15,15 @@ public class Rule : IEntity public Entity Entity { get; set; } = null!; + [Column(Order = 2)] + public int Order { get; set; } + + [Column(Order = 3)] + public int? ParentId { get; set; } = null; + + public Rule? Parent { get; set; } = null; + + public ICollection Children { get; set; } = []; + public string[] Breadcrumbs { get; set; } = []; } diff --git a/Pf2eModel/Pf2eDbContextModel.cs b/Pf2eModel/Pf2eDbContextModel.cs index 5c10d03..d898dd9 100644 --- a/Pf2eModel/Pf2eDbContextModel.cs +++ b/Pf2eModel/Pf2eDbContextModel.cs @@ -508,6 +508,12 @@ public partial class Pf2eDbContext modelBuilder.Entity(entity => { BindEntity(entity); + + entity + .HasOne(r => r.Parent) + .WithMany(r => r.Children) + .HasForeignKey(r => r.ParentId) + .IsRequired(false); }); }