people tags #387

This commit is contained in:
Hamid Reza Mohammadi 2026-10-01 22:05:18 +03:30
parent b20281df7b
commit d7ac35a9fc
9 changed files with 6722 additions and 2 deletions

View File

@ -125,7 +125,17 @@ else
{
if (tag.Poem != null)
{
<li><a href="@tag.Poem.FullUrl">@tag.Poem.FullTitle</a></li>
<li>
<a href="@tag.Poem.FullUrl">@tag.Poem.FullTitle</a>
@if (!string.IsNullOrEmpty(tag.CoupletText))
{
<p>@tag.CoupletText</p>
}
@if (!string.IsNullOrEmpty(tag.Note))
{
<p class="up-hint"><small>یادداشت: @tag.Note</small></p>
}
</li>
}
}
</ul>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace RMuseum.Migrations
{
/// <inheritdoc />
public partial class AddPoemGeoDateTagNote : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Note",
table: "PoemGeoDateTags",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Note",
table: "PoemGeoDateTags");
}
}
}

View File

@ -2845,6 +2845,9 @@ namespace RMuseum.Migrations
b.Property<bool>("MachineGenerated")
.HasColumnType("bit");
b.Property<string>("Note")
.HasColumnType("nvarchar(max)");
b.Property<int?>("PersonId")
.HasColumnType("int");

View File

@ -1,4 +1,6 @@
namespace RMuseum.Models.Ganjoor
using System.ComponentModel.DataAnnotations.Schema;
namespace RMuseum.Models.Ganjoor
{
/// <summary>
/// Geo + date tags for poems
@ -79,5 +81,20 @@
/// AI generated
/// </summary>
public bool MachineGenerated { get; set; }
/// <summary>
/// optional explanatory note for this tag (e.g. why this couplet is relevant to the
/// tagged person - carried over from the suggestion's SuggestionNote when a moderator
/// approves it, and editable afterwards like the tag's other fields)
/// </summary>
public string Note { get; set; }
/// <summary>
/// the tagged couplet's own text (both مصرع of the verse at PoemId/CoupletIndex),
/// filled in on read by whichever service method needs to show it (e.g.
/// GanjoorRelatedPersonService.GetPoemsByPersonAsync) - not a mapped database column
/// </summary>
[NotMapped]
public string CoupletText { get; set; }
}
}

View File

@ -4975,6 +4975,18 @@
<member name="M:RMuseum.Migrations.AddPersonRelationSuggestionAffiliationSupport.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:RMuseum.Migrations.AddPoemGeoDateTagNote">
<inheritdoc />
</member>
<member name="M:RMuseum.Migrations.AddPoemGeoDateTagNote.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:RMuseum.Migrations.AddPoemGeoDateTagNote.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:RMuseum.Migrations.AddPoemGeoDateTagNote.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:RMuseum.Models.Accounting.DonationExpenditure">
<summary>
donation expenditures
@ -11990,6 +12002,20 @@
AI generated
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.PoemGeoDateTag.Note">
<summary>
optional explanatory note for this tag (e.g. why this couplet is relevant to the
tagged person - carried over from the suggestion's SuggestionNote when a moderator
approves it, and editable afterwards like the tag's other fields)
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.PoemGeoDateTag.CoupletText">
<summary>
the tagged couplet's own text (both مصرع of the verse at PoemId/CoupletIndex),
filled in on read by whichever service method needs to show it (e.g.
GanjoorRelatedPersonService.GetPoemsByPersonAsync) - not a mapped database column
</summary>
</member>
<member name="T:RMuseum.Models.Ganjoor.PoemMusicTrack">
<summary>
poem related track

View File

@ -168,6 +168,21 @@ namespace RMuseum.Services.Implementation
tag.Poem.HtmlText = null;
tag.Poem.PlainText = null;
}
// fill in the tagged couplet's own text (CoupletIndex 0 means "whole poem" - no
// single couplet to show), so the person page can show the actual verse instead
// of just a link to the poem it came from
if (tag.CoupletIndex > 0)
{
var coupletVerses = await _context.GanjoorVerses.AsNoTracking()
.Where(v => v.PoemId == tag.PoemId && v.CoupletIndex == tag.CoupletIndex)
.OrderBy(v => v.VOrder)
.ToListAsync();
if (coupletVerses.Count > 0)
{
tag.CoupletText = string.Join(" ", coupletVerses.Select(v => v.Text)).Trim();
}
}
}
return new RServiceResult<PoemGeoDateTag[]>(tags);

View File

@ -746,6 +746,10 @@ namespace RMuseum.Services.Implementation
IgnoreInCategory = dbGeoDateTag.IgnoreInCategory,
VerifiedDate = false,
MachineGenerated = false,
// carry the contributor's reasoning (e.g. "this couplet indicates she is
// daughter of Jamshid") onto the live tag so it can be shown wherever the
// tag itself is displayed, not just during moderation
Note = string.IsNullOrWhiteSpace(dbGeoDateTag.SuggestionNote) ? null : dbGeoDateTag.SuggestionNote.Trim(),
};
newTag.LunarDateTotalNumber = _PrepareLunarDateTotalNumber(newTag);
_context.PoemGeoDateTags.Add(newTag);

View File

@ -89,6 +89,7 @@ namespace RMuseum.Services.Implementation
dbTag.PoemId = tag.PoemId;
dbTag.VerifiedDate = tag.VerifiedDate;
dbTag.IgnoreInCategory = tag.IgnoreInCategory;
dbTag.Note = string.IsNullOrWhiteSpace(tag.Note) ? null : tag.Note.Trim();
dbTag.LunarDateTotalNumber = _PrepareLunarDateTotalNumber(tag);
_context.Update(dbTag);
await _context.SaveChangesAsync();