seed/data Seeder Announcements
This commit is contained in:
parent
4bf6b4c257
commit
8be8fef972
6 changed files with 133 additions and 96 deletions
2
.github/instructions/lowcode.instructions.md
vendored
2
.github/instructions/lowcode.instructions.md
vendored
|
|
@ -3440,6 +3440,8 @@ Kurallar:
|
|||
(tenant kapsamı dahil) eşleşmesine bakılarak belirlenir.
|
||||
- **Dosyadaki değer varsayılanı ezer.** `InsertFieldsDefaultValueJson` yalnızca dosyada bulunmayan
|
||||
alanları doldurur (audit kolonları, kapsam, anahtar); ekrandan kayıtta ise varsayılan girilen değeri ezer.
|
||||
- **`@USER:kullanıcıAdı`** değeri seed sırasında o kullanıcının anahtarına çözülür; kullanıcı anahtarları
|
||||
her kurulumda yeniden üretildiği için dosyaya GUID yazılmaz. Kullanıcı bulunamazsa alan boş kalır.
|
||||
- **Uygulama yalnızca ekler:** anahtarı veritabanında bulunmayan satırlar `INSERT` edilir; var olan
|
||||
kayıt güncellenmez (her migrate'te ekrandaki güncel değerler dosyadaki eskisiyle ezilmesin diye)
|
||||
ve dosyada olmayan satır silinmez.
|
||||
|
|
|
|||
|
|
@ -2926,6 +2926,10 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
|||
Description = $"{listFormName}.Description",
|
||||
SelectCommandType = SelectCommandTypeEnum.Table,
|
||||
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.Announcement)),
|
||||
SeedFilePath = SeedPathResolver.GetDataFilePath(listFormName),
|
||||
SeedSyncInsert = false,
|
||||
SeedSyncUpdate = false,
|
||||
SeedSyncDelete = false,
|
||||
KeyFieldName = "Id",
|
||||
KeyFieldDbSourceType = DbType.Guid,
|
||||
DefaultFilter = DefaultFilterJson,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ using Sozsoft.Platform.ListForms;
|
|||
using Sozsoft.Platform.Queries;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.Identity;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Volo.Abp.MultiTenancy;
|
||||
using Volo.Abp.Uow;
|
||||
|
||||
|
|
@ -48,8 +50,16 @@ public class ListFormSeedDataApplier(
|
|||
IConfiguration configuration,
|
||||
ICurrentTenant currentTenant,
|
||||
IUnitOfWorkManager unitOfWorkManager,
|
||||
IIdentityUserRepository identityUserRepository,
|
||||
ILookupNormalizer lookupNormalizer,
|
||||
ILogger<ListFormSeedDataApplier> logger) : IListFormSeedDataApplier, ITransientDependency
|
||||
{
|
||||
/// <summary>Satir degerinde kullanicinin adiyla yazilan referans; anahtari seed sirasinda cozulur.</summary>
|
||||
private const string UserTokenPrefix = "@USER:";
|
||||
|
||||
/// <summary>Cozulen kullanici anahtarlari; ayni kullanici her satirda yeniden sorgulanmaz.</summary>
|
||||
private readonly Dictionary<string, Guid?> userIdCache = [];
|
||||
|
||||
public async Task ApplyAsync(Guid? tenantId)
|
||||
{
|
||||
var scopeFolderName = SeedPathResolver.GetScopeFolderName(tenantId);
|
||||
|
|
@ -191,7 +201,7 @@ public class ListFormSeedDataApplier(
|
|||
object[] keys = [keyValue];
|
||||
var hasKey = keyValue != null;
|
||||
|
||||
var insertParameters = BuildParameters(fields, row, keyFieldName, includeKey: hasKey);
|
||||
var insertParameters = BuildParameters(fields, await ResolveTokensAsync(row), keyFieldName, includeKey: hasKey);
|
||||
|
||||
// Var olan kayda dokunulmaz: veritabanindaki guncel deger, dosyadaki eski degerle ezilmemeli.
|
||||
var match = hasKey
|
||||
|
|
@ -271,6 +281,54 @@ public class ListFormSeedDataApplier(
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Satirdaki <c>@USER:kullaniciAdi</c> degerlerini kullanicinin anahtariyla degistirir. Kullanici
|
||||
/// anahtarlari her kurulumda yeniden uretildigi icin dosyaya yazilamaz; ad uzerinden cozulur.
|
||||
/// </summary>
|
||||
private async Task<Dictionary<string, object>> ResolveTokensAsync(Dictionary<string, object> row)
|
||||
{
|
||||
var resolved = new Dictionary<string, object>(row);
|
||||
|
||||
foreach (var item in row)
|
||||
{
|
||||
var userName = GetUserToken(item.Value);
|
||||
if (userName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!userIdCache.TryGetValue(userName, out var userId))
|
||||
{
|
||||
var user = await identityUserRepository.FindByNormalizedUserNameAsync(lookupNormalizer.NormalizeName(userName));
|
||||
userId = user?.Id;
|
||||
userIdCache[userName] = userId;
|
||||
|
||||
if (userId == null)
|
||||
{
|
||||
logger.LogWarning("User '{UserName}' not found, '{Field}' is left empty.", userName, item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
resolved[item.Key] = userId;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private static string GetUserToken(object value)
|
||||
{
|
||||
var text = value switch
|
||||
{
|
||||
JsonElement { ValueKind: JsonValueKind.String } element => element.GetString(),
|
||||
string s => s,
|
||||
_ => null
|
||||
};
|
||||
|
||||
return text?.StartsWith(UserTokenPrefix, StringComparison.OrdinalIgnoreCase) == true
|
||||
? text[UserTokenPrefix.Length..]
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>Dosyadaki satiri, ekranin alan tanimlarina gore tiplendirilmis parametrelere cevirir.</summary>
|
||||
private static Dictionary<string, object> BuildParameters(
|
||||
List<ListFormField> fields,
|
||||
|
|
|
|||
|
|
@ -391,60 +391,6 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"Announcements": [
|
||||
{
|
||||
"title": "🎉 Yeni Ofis Açılışı",
|
||||
"content": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor! Tüm çalışanlarımızı açılış törenimize davet ediyoruz.",
|
||||
"excerpt": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor!",
|
||||
"category": "general",
|
||||
"userName": "system@sozsoft.com",
|
||||
"publishDate": "12-10-2024",
|
||||
"isPinned": true,
|
||||
"viewCount": 0,
|
||||
"imageUrl": "https://images.unsplash.com/photo-1497366216548-37526070297c?w=800&q=80"
|
||||
},
|
||||
{
|
||||
"title": "📅 Performans Değerlendirme Dönemi",
|
||||
"content": "Yıl sonu performans değerlendirmelerimiz 20 Ekim - 5 Kasım tarihleri arasında gerçekleştirilecektir. Lütfen formları zamanında doldurunuz.",
|
||||
"excerpt": "Yıl sonu performans değerlendirmeleri başlıyor.",
|
||||
"category": "event",
|
||||
"userName": "system@sozsoft.com",
|
||||
"publishDate": "08-10-2024",
|
||||
"expiryDate": "05-11-2024",
|
||||
"isPinned": true,
|
||||
"viewCount": 0
|
||||
},
|
||||
{
|
||||
"title": "💻 Sistem Bakımı Duyurusu",
|
||||
"content": "Bu Cumartesi saat 02: 00 - 06: 00 arası sistemlerimizde bakım çalışması yapılacaktır. Bu süre içinde sistemlere erişim sağlanamayacaktır.",
|
||||
"excerpt": "Cumartesi gecesi planlı bakım çalışması",
|
||||
"category": "urgent",
|
||||
"userName": "system@sozsoft.com",
|
||||
"publishDate": "08-10-2024",
|
||||
"isPinned": false,
|
||||
"viewCount": 0
|
||||
},
|
||||
{
|
||||
"title": "🎓 React İleri Seviye Eğitimi",
|
||||
"content": "Yazılım Geliştirme ekibimiz için React İleri Seviye eğitimi 25-26 Ekim tarihlerinde düzenlenecektir. Katılım için IK birimine başvurunuz.",
|
||||
"excerpt": "React İleri Seviye eğitimi kayıtları başladı",
|
||||
"category": "event",
|
||||
"userName": "system@sozsoft.com",
|
||||
"publishDate": "09-10-2024",
|
||||
"isPinned": false,
|
||||
"viewCount": 0
|
||||
},
|
||||
{
|
||||
"title": "⚠️ Güvenlik Politikası Güncellemesi",
|
||||
"content": "Bilgi güvenliği politikamız güncellenmiştir. Tüm çalışanlarımızın yeni politikayı okuması ve onaylaması gerekmektedir.",
|
||||
"excerpt": "Güvenlik politikası güncellendi - Onay gerekli",
|
||||
"category": "urgent",
|
||||
"userName": "system@sozsoft.com",
|
||||
"publishDate": "04-10-2024",
|
||||
"isPinned": true,
|
||||
"viewCount": 0
|
||||
}
|
||||
],
|
||||
"Surveys": [
|
||||
{
|
||||
"Title": "Çalışan Memnuniyet Anketi 2024",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ public class TenantSeederDto
|
|||
public List<ForumCategorySeedDto> ForumCategories { get; set; }
|
||||
|
||||
//Intranet
|
||||
public List<AnnouncementSeedDto> Announcements { get; set; }
|
||||
public List<SurveySeedDto> Surveys { get; set; }
|
||||
public List<SurveyQuestionSeedDto> SurveyQuestions { get; set; }
|
||||
public List<SurveyQuestionOptionSeedDto> SurveyQuestionOptions { get; set; }
|
||||
|
|
@ -176,21 +175,6 @@ public class SurveyQuestionOptionSeedDto
|
|||
public int Order { get; set; }
|
||||
}
|
||||
|
||||
public class AnnouncementSeedDto
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Excerpt { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public DateTime PublishDate { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public bool IsPinned { get; set; }
|
||||
public int ViewCount { get; set; }
|
||||
public string DepartmentNames { get; set; }
|
||||
}
|
||||
|
||||
public class ForumCategorySeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
@ -289,7 +273,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
private readonly IRepository<Contact, Guid> _contactRepository;
|
||||
private readonly IRepository<ForumCategory, Guid> _forumCategoryRepository;
|
||||
private readonly IIdentityUserRepository _repositoryUser;
|
||||
private readonly IRepository<Announcement, Guid> _announcementRepository;
|
||||
private readonly IRepository<Survey, Guid> _surveyRepository;
|
||||
private readonly IRepository<SurveyQuestion, Guid> _surveyQuestionRepository;
|
||||
private readonly IRepository<SurveyQuestionOption, Guid> _surveyQuestionOptionRepository;
|
||||
|
|
@ -315,7 +298,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
IRepository<Contact, Guid> contactRepository,
|
||||
IRepository<ForumCategory, Guid> forumCategoryRepository,
|
||||
|
||||
IRepository<Announcement, Guid> announcementRepository,
|
||||
IRepository<Survey, Guid> surveyRepository,
|
||||
IRepository<SurveyQuestion, Guid> surveyQuestionRepository,
|
||||
IRepository<SurveyQuestionOption, Guid> surveyQuestionOptionRepository,
|
||||
|
|
@ -338,7 +320,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
_aboutRepository = aboutRepository;
|
||||
_contactRepository = contactRepository;
|
||||
_forumCategoryRepository = forumCategoryRepository;
|
||||
_announcementRepository = announcementRepository;
|
||||
_surveyRepository = surveyRepository;
|
||||
_surveyQuestionRepository = surveyQuestionRepository;
|
||||
_surveyQuestionOptionRepository = surveyQuestionOptionRepository;
|
||||
|
|
@ -460,28 +441,6 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Announcements)
|
||||
{
|
||||
var exists = await _announcementRepository.AnyAsync(x => x.Title == item.Title);
|
||||
if (exists)
|
||||
continue;
|
||||
|
||||
var user = await _repositoryUser.FindByNormalizedUserNameAsync(_lookupNormalizer.NormalizeName(item.UserName));
|
||||
await _announcementRepository.InsertAsync(new Announcement
|
||||
{
|
||||
Title = item.Title,
|
||||
Excerpt = item.Excerpt,
|
||||
Content = item.Content,
|
||||
ImageUrl = item.ImageUrl,
|
||||
Category = item.Category,
|
||||
UserId = user != null ? user.Id : null,
|
||||
PublishDate = item.PublishDate,
|
||||
ExpiryDate = item.ExpiryDate,
|
||||
IsPinned = item.IsPinned,
|
||||
ViewCount = item.ViewCount
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in items.Surveys)
|
||||
{
|
||||
var exists = await _surveyRepository.AnyAsync(x => x.Title == item.Title);
|
||||
|
|
|
|||
68
configs/seeds/host/data/App.Intranet.Announcement.json
Normal file
68
configs/seeds/host/data/App.Intranet.Announcement.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"ListFormCode": "App.Intranet.Announcement",
|
||||
"KeyFieldName": "Id",
|
||||
"GeneratedAt": "2026-09-04T00:00:00Z",
|
||||
"Order": 0,
|
||||
"Rows": [
|
||||
{
|
||||
"Id": "3da0e444-4085-5cbb-bcf2-5ccfb7566050",
|
||||
"Title": "🎉 Yeni Ofis Açılışı",
|
||||
"Excerpt": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor!",
|
||||
"Content": "Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor! Tüm çalışanlarımızı açılış törenimize davet ediyoruz.",
|
||||
"Category": "general",
|
||||
"UserId": "@USER:system@sozsoft.com",
|
||||
"PublishDate": "2024-10-12T00:00:00",
|
||||
"ExpiryDate": null,
|
||||
"IsPinned": true,
|
||||
"ImageUrl": "https://images.unsplash.com/photo-1497366216548-37526070297c?w=800&q=80"
|
||||
},
|
||||
{
|
||||
"Id": "169a5022-8c46-50bb-8113-aca8f348721d",
|
||||
"Title": "📅 Performans Değerlendirme Dönemi",
|
||||
"Excerpt": "Yıl sonu performans değerlendirmeleri başlıyor.",
|
||||
"Content": "Yıl sonu performans değerlendirmelerimiz 20 Ekim - 5 Kasım tarihleri arasında gerçekleştirilecektir. Lütfen formları zamanında doldurunuz.",
|
||||
"Category": "event",
|
||||
"UserId": "@USER:system@sozsoft.com",
|
||||
"PublishDate": "2024-10-08T00:00:00",
|
||||
"ExpiryDate": "2024-11-05T00:00:00",
|
||||
"IsPinned": true,
|
||||
"ImageUrl": null
|
||||
},
|
||||
{
|
||||
"Id": "2d1377a3-49b5-51ce-80a3-5bbbbf6b3ad8",
|
||||
"Title": "💻 Sistem Bakımı Duyurusu",
|
||||
"Excerpt": "Cumartesi gecesi planlı bakım çalışması",
|
||||
"Content": "Bu Cumartesi saat 02: 00 - 06: 00 arası sistemlerimizde bakım çalışması yapılacaktır. Bu süre içinde sistemlere erişim sağlanamayacaktır.",
|
||||
"Category": "urgent",
|
||||
"UserId": "@USER:system@sozsoft.com",
|
||||
"PublishDate": "2024-10-08T00:00:00",
|
||||
"ExpiryDate": null,
|
||||
"IsPinned": false,
|
||||
"ImageUrl": null
|
||||
},
|
||||
{
|
||||
"Id": "96a8a3dd-0f4a-5e1e-8b5e-bb44dd41a1f0",
|
||||
"Title": "🎓 React İleri Seviye Eğitimi",
|
||||
"Excerpt": "React İleri Seviye eğitimi kayıtları başladı",
|
||||
"Content": "Yazılım Geliştirme ekibimiz için React İleri Seviye eğitimi 25-26 Ekim tarihlerinde düzenlenecektir. Katılım için IK birimine başvurunuz.",
|
||||
"Category": "event",
|
||||
"UserId": "@USER:system@sozsoft.com",
|
||||
"PublishDate": "2024-10-09T00:00:00",
|
||||
"ExpiryDate": null,
|
||||
"IsPinned": false,
|
||||
"ImageUrl": null
|
||||
},
|
||||
{
|
||||
"Id": "a753ef12-be3e-56c9-b597-47538aa69fde",
|
||||
"Title": "⚠️ Güvenlik Politikası Güncellemesi",
|
||||
"Excerpt": "Güvenlik politikası güncellendi - Onay gerekli",
|
||||
"Content": "Bilgi güvenliği politikamız güncellenmiştir. Tüm çalışanlarımızın yeni politikayı okuması ve onaylaması gerekmektedir.",
|
||||
"Category": "urgent",
|
||||
"UserId": "@USER:system@sozsoft.com",
|
||||
"PublishDate": "2024-10-04T00:00:00",
|
||||
"ExpiryDate": null,
|
||||
"IsPinned": true,
|
||||
"ImageUrl": null
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue