WeddingPlatform.Web 1.0.0.0
지도, 갤러리, 방명록, 계좌 안내와 배경음악을 링크 하나에 담는 무료 모바일 청첩장 서비스입니다.
로딩중...
검색중...
일치하는것 없음
WeddingPlatform.ViewModels.WeddingAdminViewModel 클래스 참조sealed

더 자세히 ...

WeddingPlatform.ViewModels.WeddingAdminViewModel에 대한 협력 다이어그램:

Public 멤버 함수

 WeddingAdminViewModel (ITenantStore tenants, IPhotoService photos, WeddingOptions opts, WeddingUserContext userContext, IMediaQuotaPolicyResolver mediaPolicyResolver, ISuperAdminSessionTokenService superAdminTokens)
async Task InitializeAsync (string slug, CancellationToken ct=default)
async Task< bool > LoginAsync (string slug, CancellationToken ct=default)
async Task< bool > LoginAsSuperAdminAsync (string slug, string? sessionToken, CancellationToken ct=default)
async Task LoadAsync (string slug, CancellationToken ct=default)
async Task SaveConfigAsync (CancellationToken ct=default)
void SetStatusMessage (string message)
async Task SaveStoryChapterAsync (StoryChapter chapter, CancellationToken ct=default)
async Task AddStoryChapterAsync (CancellationToken ct=default)
async Task DeleteStoryChapterAsync (int chapterNumber, CancellationToken ct=default)
async Task RemoveAdminAsync (string userId, CancellationToken ct=default)
async Task UploadGalleryAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task UploadHeroAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task DeletePhotoAsync (string slug, string fileName, CancellationToken ct=default)
async Task MoveGalleryPhotoAsync (string fileName, int offset, CancellationToken ct=default)
async Task MoveGalleryPhotoToAsync (string fileName, bool first, CancellationToken ct=default)
async Task UploadRoadMapAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task GeocodeAsync (CancellationToken ct=default)
void GenerateMapLinks ()
string GetThumbUrl (string slug, string fileName)
string GetPhotoUrl (string slug, string fileName)
string GetHeroUrl (string slug, string fileName)
string GetRoadMapUrl (string slug, string fileName)
string GetMusicUrl (string slug, string fileName)
string GetOgImageUrl (string slug, string fileName)
string GetVideoUrl (string slug, string fileName)
async Task UploadOgImageAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task UploadThankYouOgImageAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task UploadVideoAsync (string slug, IBrowserFile file, CancellationToken ct=default)
async Task DeleteVideoAsync (string slug, string fileName, CancellationToken ct=default)
async Task UploadMusicAsync (string slug, IBrowserFile file, CancellationToken ct=default)

속성

string MaxVideoSizeLabel = "최대 200MB" [get, private set]
int MaxVideoCount = 6 [get, private set]
EffectiveMediaPolicy? EffectiveMediaPolicy [get, private set]
TenantConfigConfig [get, private set]
IReadOnlyList< PhotoInfoGallery = [] [get, private set]
bool IsLoaded [get, private set]
bool IsAuthenticated [get, private set]
bool IsSignedIn [get, private set]
bool IsLinkedToCurrentUser [get, private set]
bool IsOwner [get, private set]
IReadOnlyList< WeddingAdminUserEffectiveAdminUsers = [] [get, private set]
string StatusMessage = "" [get, private set]
string CurrentUserLabel = "" [get, private set]
bool IsUploading [get, private set]
bool IsGeocoding [get, private set]
string GeocodeStatus = "" [get, private set]
string LoginPassword = "" [get, set]

Private 멤버 함수

async Task RefreshCurrentUserAsync ()
bool ValidateLayoutForSave (TenantConfig config)
bool ValidateThemeForSave (TenantConfig config)
void NormalizeGalleryFileOrder ()

정적 Private 멤버 함수

static List< WeddingAdminUserGetAdminUsers (TenantConfig config)
static bool IsOwnerUser (TenantConfig config, WeddingCurrentUser user)
static bool IsAdminUser (TenantConfig config, WeddingCurrentUser user)
static void EnsureAdminUser (TenantConfig config, WeddingCurrentUser user, string role)
static IReadOnlyList< WeddingAdminUserBuildEffectiveAdminUsers (TenantConfig config)
static void NormalizeHeroPanelPosition (TenantConfig config)
static string NormalizeOption (string? value, string[] allowed, string fallback)

Private 속성

readonly ITenantStore _tenants
readonly IPhotoService _photos
readonly WeddingOptions _opts
readonly WeddingUserContext _userContext
readonly IMediaQuotaPolicyResolver _mediaPolicyResolver
readonly ISuperAdminSessionTokenService _superAdminTokens

정적 Private 속성

static readonly HttpClient _geocodeHttp

상세한 설명

Wedding Admin View Model 기능과 관련 상태를 캡슐화합니다.

WeddingAdminViewModel.cs 파일의 20 번째 라인에서 정의되었습니다.

생성자 & 소멸자 문서화

◆ WeddingAdminViewModel()

WeddingPlatform.ViewModels.WeddingAdminViewModel.WeddingAdminViewModel ( ITenantStore tenants,
IPhotoService photos,
WeddingOptions opts,
WeddingUserContext userContext,
IMediaQuotaPolicyResolver mediaPolicyResolver,
ISuperAdminSessionTokenService superAdminTokens )
inline

지정한 설정으로 WeddingAdminViewModel 클래스의 새 인스턴스를 초기화합니다.

매개변수
tenantstenants에 사용할 ITenantStore 값입니다.
photosphotos에 사용할 IPhotoService 값입니다.
optsopts에 사용할 WeddingOptions 값입니다.
userContextuser Context에 사용할 WeddingUserContext 값입니다.
mediaPolicyResolvermedia Policy Resolver에 사용할 IMediaQuotaPolicyResolver 값입니다.
superAdminTokenssuper Admin Tokens에 사용할 ISuperAdminSessionTokenService 값입니다.

WeddingAdminViewModel.cs 파일의 146 번째 라인에서 정의되었습니다.

153 {
154 _tenants = tenants;
155 _photos = photos;
156 _opts = opts;
157 _userContext = userContext;
158 _mediaPolicyResolver = mediaPolicyResolver;
159 _superAdminTokens = superAdminTokens;
160 }

다음을 참조함 : _mediaPolicyResolver, _opts, _photos, _superAdminTokens, _tenants, _userContext.

멤버 함수 문서화

◆ AddStoryChapterAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.AddStoryChapterAsync ( CancellationToken ct = default)
inline

Story Chapter Async 항목을 추가합니다.

매개변수
ct취소 요청을 감시하는 토큰입니다.
반환값
Add Story Chapter Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 769 번째 라인에서 정의되었습니다.

770 {
771 if (Config is null) return;
772 try
773 {
774 InvitationDesignCatalog.Normalize(Config);
775 var chapters = Config.DesignSettings.StoryChapters;
776 var nextNumber = chapters.Count == 0 ? 1 : chapters.Max(x => x.ChapterNumber) + 1;
777 chapters.Add(new StoryChapter
778 {
779 ChapterNumber = nextNumber,
780 Label = $"CHAPTER {nextNumber:00}",
781 Title = "새로운 이야기",
782 });
783
784 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
785 StatusMessage = $"CHAPTER {nextNumber:00} 챕터가 추가되었습니다.";
786 }
787 catch (Exception ex)
788 {
789 StatusMessage = $"챕터 추가 오류: {ex.Message}";
790 }
791 }

다음을 참조함 : _tenants, Config, WeddingPlatform.Models.InvitationDesignCatalog.Normalize(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ BuildEffectiveAdminUsers()

IReadOnlyList< WeddingAdminUser > WeddingPlatform.ViewModels.WeddingAdminViewModel.BuildEffectiveAdminUsers ( TenantConfig config)
inlinestaticprivate

Effective Admin Users 값을 구성합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
반환값
Build Effective Admin Users 작업에서 생성한 IReadOnlyList<WeddingAdminUser> 결과입니다.

WeddingAdminViewModel.cs 파일의 2182 번째 라인에서 정의되었습니다.

2183 {
2184 var users = GetAdminUsers(config);
2185 if (!string.IsNullOrWhiteSpace(config.OwnerUserId) &&
2186 users.All(x => !string.Equals(x.UserId, config.OwnerUserId, StringComparison.Ordinal)))
2187 {
2188 users.Insert(0, new WeddingAdminUser
2189 {
2190 UserId = config.OwnerUserId,
2191 Provider = config.OwnerProvider,
2192 Email = config.OwnerEmail,
2193 DisplayName = config.OwnerDisplayName,
2194 Role = "Owner",
2195 AddedAt = config.OwnerLinkedAt ?? config.CreatedAt
2196 });
2197 }
2198
2199 foreach (var user in users.Where(x => string.Equals(x.UserId, config.OwnerUserId, StringComparison.Ordinal)))
2200 {
2201 user.Role = "Owner";
2202 }
2203
2204 return users
2205 .OrderByDescending(x => string.Equals(x.Role, "Owner", StringComparison.OrdinalIgnoreCase))
2206 .ThenBy(x => x.AddedAt)
2207 .ToList();
2208 }

다음을 참조함 : GetAdminUsers(), WeddingPlatform.Models.TenantConfig.OwnerDisplayName, WeddingPlatform.Models.TenantConfig.OwnerEmail, WeddingPlatform.Models.TenantConfig.OwnerProvider, WeddingPlatform.Models.TenantConfig.OwnerUserId.

다음에 의해서 참조됨 : InitializeAsync(), LoadAsync(), LoginAsSuperAdminAsync(), LoginAsync(), RemoveAdminAsync(), SaveConfigAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ DeletePhotoAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.DeletePhotoAsync ( string slug,
string fileName,
CancellationToken ct = default )
inline

Delete Photo Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Delete Photo Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1200 번째 라인에서 정의되었습니다.

1201 {
1202 try
1203 {
1204 await _photos.DeleteAsync(slug, fileName, ct).ConfigureAwait(false);
1205 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1206 Gallery = await _photos.GetGalleryAsync(slug, ct).ConfigureAwait(false);
1207 StatusMessage = "삭제 완료";
1208 }
1209 catch (Exception ex) { StatusMessage = $"삭제 오류: {ex.Message}"; }
1210 }

다음을 참조함 : _photos, _tenants, Config, Gallery, StatusMessage.

◆ DeleteStoryChapterAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.DeleteStoryChapterAsync ( int chapterNumber,
CancellationToken ct = default )
inline

Delete Story Chapter Async 작업을 수행합니다.

매개변수
chapterNumberchapter Number에 사용할 int 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Delete Story Chapter Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 825 번째 라인에서 정의되었습니다.

826 {
827 if (Config is null) return;
828 try
829 {
830 InvitationDesignCatalog.Normalize(Config);
831 if (chapterNumber <= 4)
832 {
833 StatusMessage = "기본 4개 챕터는 유지됩니다.";
834 return;
835 }
836
837 var removed = Config.DesignSettings.StoryChapters.RemoveAll(x => x.ChapterNumber == chapterNumber);
838 if (removed == 0)
839 {
840 StatusMessage = "삭제할 챕터를 찾을 수 없습니다.";
841 return;
842 }
843
844 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
845 StatusMessage = $"CHAPTER {chapterNumber:00} 챕터가 삭제되었습니다.";
846 }
847 catch (Exception ex)
848 {
849 StatusMessage = $"챕터 삭제 오류: {ex.Message}";
850 }
851 }

다음을 참조함 : _tenants, Config, WeddingPlatform.Models.InvitationDesignCatalog.Normalize(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ DeleteVideoAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.DeleteVideoAsync ( string slug,
string fileName,
CancellationToken ct = default )
inline

Delete Video Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Delete Video Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1931 번째 라인에서 정의되었습니다.

1932 {
1933 try
1934 {
1935 await _photos.DeleteVideoAsync(slug, fileName, ct).ConfigureAwait(false);
1936 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1937 StatusMessage = "동영상 삭제 완료";
1938 }
1939 catch (Exception ex) { StatusMessage = $"동영상 삭제 오류: {ex.Message}"; }
1940 }

다음을 참조함 : _photos, _tenants, Config, StatusMessage.

◆ EnsureAdminUser()

void WeddingPlatform.ViewModels.WeddingAdminViewModel.EnsureAdminUser ( TenantConfig config,
WeddingCurrentUser user,
string role )
inlinestaticprivate

Ensure Admin User 작업을 수행합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
useruser에 사용할 WeddingCurrentUser 값입니다.
rolerole에 사용할 string 값입니다.

WeddingAdminViewModel.cs 파일의 2129 번째 라인에서 정의되었습니다.

2130 {
2131 if (!user.IsAuthenticated) return;
2132
2133 var users = GetAdminUsers(config);
2134 var existing = users.FirstOrDefault(x => string.Equals(x.UserId, user.Id, StringComparison.Ordinal));
2135 if (existing is null)
2136 {
2137 users.Add(new WeddingAdminUser
2138 {
2139 UserId = user.Id,
2140 Provider = user.Provider,
2141 Email = user.Email,
2142 DisplayName = user.DisplayName,
2143 Role = role,
2144 AddedAt = DateTime.Now
2145 });
2146 return;
2147 }
2148
2149 existing.Provider = user.Provider;
2150 existing.Email = user.Email;
2151 existing.DisplayName = user.DisplayName;
2152 if (role == "Owner")
2153 {
2154 existing.Role = "Owner";
2155 }
2156 }

다음을 참조함 : GetAdminUsers(), WeddingPlatform.Services.WeddingCurrentUser().

다음에 의해서 참조됨 : LoginAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GenerateMapLinks()

void WeddingPlatform.ViewModels.WeddingAdminViewModel.GenerateMapLinks ( )
inline

Generate Map Links 작업을 수행합니다.

WeddingAdminViewModel.cs 파일의 1468 번째 라인에서 정의되었습니다.

1469 {
1470 if (Config is null) return;
1471
1472 var name = Uri.EscapeDataString(Config.VenueName);
1473 var addr = Uri.EscapeDataString(
1474 string.IsNullOrWhiteSpace(Config.VenueAddress) ? Config.VenueName : Config.VenueAddress);
1475 var lat = Config.VenueLat;
1476 var lng = Config.VenueLng;
1477 bool hasCoords = lat != 0 && lng != 0;
1478 var latS = lat.ToString(System.Globalization.CultureInfo.InvariantCulture);
1479 var lngS = lng.ToString(System.Globalization.CultureInfo.InvariantCulture);
1480
1481 // 카카오맵 — 좌표 있으면 핀, 없으면 검색
1482 Config.MapLinkKakao = hasCoords
1483 ? $"https://map.kakao.com/link/map/{name},{latS},{lngS}"
1484 : $"https://map.kakao.com/link/search/{addr}";
1485
1486 // 네이버지도 — 좌표 있으면 좌표 검색, 없으면 주소 검색
1487 Config.MapLinkNaver = hasCoords
1488 ? $"https://map.naver.com/v5/search/{addr}?c={lngS},{latS},15,0,0,0,dh"
1489 : $"https://map.naver.com/v5/search/{addr}";
1490
1491 // 아틀란
1492 if (!string.IsNullOrWhiteSpace(_opts.AtlanAuthKey) && hasCoords)
1493 Config.MapLinkAtlan = $"http://m.atlan.co.kr/searchPlus/linkAtlan.do?shareType=kakao&coordX={lng.ToString(System.Globalization.CultureInfo.InvariantCulture)}&coordY={lat.ToString(System.Globalization.CultureInfo.InvariantCulture)}&title={name}&AuthKey={_opts.AtlanAuthKey}";
1494
1495 // T맵
1496 if (!string.IsNullOrWhiteSpace(_opts.TmapAppKey) && hasCoords)
1497 Config.MapLinkTmap = $"https://apis.openapi.sk.com/tmap/app/routes?appKey={_opts.TmapAppKey}&name={name}&lon={lng.ToString(System.Globalization.CultureInfo.InvariantCulture)}&lat={lat.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
1498 }

다음을 참조함 : _opts, Config.

◆ GeocodeAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.GeocodeAsync ( CancellationToken ct = default)
inline

Geocode Async 작업을 수행합니다.

매개변수
ct취소 요청을 감시하는 토큰입니다.
반환값
Geocode Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1434 번째 라인에서 정의되었습니다.

1435 {
1436 if (Config is null) return;
1437 var query = string.IsNullOrWhiteSpace(Config.VenueAddress) ? Config.VenueName : Config.VenueAddress;
1438 if (string.IsNullOrWhiteSpace(query)) { GeocodeStatus = "❗ 예식장 이름 또는 주소를 먼저 입력해주세요."; return; }
1439
1440 IsGeocoding = true;
1441 GeocodeStatus = "";
1442 try
1443 {
1444 var url = $"https://nominatim.openstreetmap.org/search?q={Uri.EscapeDataString(query)}&format=json&limit=1&accept-language=ko";
1445 var results = await _geocodeHttp.GetFromJsonAsync<JsonElement[]>(url, ct).ConfigureAwait(false);
1446 if (results is null || results.Length == 0)
1447 {
1448 GeocodeStatus = "❌ 좌표를 찾을 수 없습니다. 주소를 더 자세히 입력해 보세요.";
1449 return;
1450 }
1451 var item = results[0];
1452 Config.VenueLat = double.Parse(item.GetProperty("lat").GetString()!, System.Globalization.CultureInfo.InvariantCulture);
1453 Config.VenueLng = double.Parse(item.GetProperty("lon").GetString()!, System.Globalization.CultureInfo.InvariantCulture);
1454 GeocodeStatus = $"✅ 좌표 검색 완료 — {item.GetProperty("display_name").GetString()}";
1455 }
1456 catch { GeocodeStatus = "❌ 좌표 검색 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요."; }
1457 finally { IsGeocoding = false; }
1458 }

다음을 참조함 : _geocodeHttp, Config, GeocodeStatus, IsGeocoding.

◆ GetAdminUsers()

List< WeddingAdminUser > WeddingPlatform.ViewModels.WeddingAdminViewModel.GetAdminUsers ( TenantConfig config)
inlinestaticprivate

Admin Users 값을 가져옵니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
반환값
Get Admin Users 작업에서 생성한 List<WeddingAdminUser> 결과입니다.

WeddingAdminViewModel.cs 파일의 2019 번째 라인에서 정의되었습니다.

2019=> config.AdminUsers ??= [];

다음에 의해서 참조됨 : BuildEffectiveAdminUsers(), EnsureAdminUser(), IsAdminUser(), RemoveAdminAsync().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetHeroUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetHeroUrl ( string slug,
string fileName )
inline

Hero Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Hero Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1598 번째 라인에서 정의되었습니다.

1598=> _photos.GetHeroUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetMusicUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetMusicUrl ( string slug,
string fileName )
inline

Music Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Music Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1664 번째 라인에서 정의되었습니다.

1664=> _photos.GetMusicUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetOgImageUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetOgImageUrl ( string slug,
string fileName )
inline

Og Image Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Og Image Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1697 번째 라인에서 정의되었습니다.

1697=> _photos.GetHeroUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetPhotoUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetPhotoUrl ( string slug,
string fileName )
inline

Photo Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Photo Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1565 번째 라인에서 정의되었습니다.

1565=> _photos.GetPhotoUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetRoadMapUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetRoadMapUrl ( string slug,
string fileName )
inline

Road Map Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Road Map Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1631 번째 라인에서 정의되었습니다.

1631=> _photos.GetRoadMapUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetThumbUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetThumbUrl ( string slug,
string fileName )
inline

Thumb Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Thumb Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1532 번째 라인에서 정의되었습니다.

1532=> _photos.GetThumbUrl(slug, fileName);

다음을 참조함 : _photos.

◆ GetVideoUrl()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GetVideoUrl ( string slug,
string fileName )
inline

Video Url 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
fileNamefile Name에 사용할 string 값입니다.
반환값
Get Video Url 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 1730 번째 라인에서 정의되었습니다.

1730=> _photos.GetVideoUrl(slug, fileName);

다음을 참조함 : _photos.

◆ InitializeAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.InitializeAsync ( string slug,
CancellationToken ct = default )
inline

Initialize Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Initialize Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 350 번째 라인에서 정의되었습니다.

351 {
352 StatusMessage = "";
353 await RefreshCurrentUserAsync().ConfigureAwait(false);
354
355 var config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
356 if (config is null)
357 {
358 return;
359 }
360
361 var user = await _userContext.GetCurrentAsync().ConfigureAwait(false);
362 IsOwner = IsOwnerUser(config, user);
363 IsLinkedToCurrentUser = IsAdminUser(config, user);
364 EffectiveAdminUsers = BuildEffectiveAdminUsers(config);
365
366 if (IsLinkedToCurrentUser)
367 {
368 IsAuthenticated = true;
369 await LoadAsync(slug, ct).ConfigureAwait(false);
370 }
371 }

다음을 참조함 : _tenants, _userContext, BuildEffectiveAdminUsers(), EffectiveAdminUsers, IsAdminUser(), IsAuthenticated, IsLinkedToCurrentUser, IsOwner, IsOwnerUser(), LoadAsync(), RefreshCurrentUserAsync(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ IsAdminUser()

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsAdminUser ( TenantConfig config,
WeddingCurrentUser user )
inlinestaticprivate

Is Admin User 조건을 확인합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
useruser에 사용할 WeddingCurrentUser 값입니다.
반환값
Is Admin User 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

WeddingAdminViewModel.cs 파일의 2090 번째 라인에서 정의되었습니다.

2091 {
2092 if (!user.IsAuthenticated) return false;
2093 if (IsOwnerUser(config, user)) return true;
2094 return GetAdminUsers(config).Any(x => string.Equals(x.UserId, user.Id, StringComparison.Ordinal));
2095 }

다음을 참조함 : GetAdminUsers(), IsOwnerUser(), WeddingPlatform.Services.WeddingCurrentUser().

다음에 의해서 참조됨 : InitializeAsync(), LoginAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ IsOwnerUser()

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsOwnerUser ( TenantConfig config,
WeddingCurrentUser user )
inlinestaticprivate

Is Owner User 조건을 확인합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
useruser에 사용할 WeddingCurrentUser 값입니다.
반환값
Is Owner User 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

WeddingAdminViewModel.cs 파일의 2053 번째 라인에서 정의되었습니다.

2053 =>
2054 user.IsAuthenticated &&
2055 !string.IsNullOrWhiteSpace(config.OwnerUserId) &&
2056 string.Equals(config.OwnerUserId, user.Id, StringComparison.Ordinal);

다음을 참조함 : WeddingPlatform.Services.WeddingCurrentUser().

다음에 의해서 참조됨 : InitializeAsync(), IsAdminUser(), LoginAsync(), RemoveAdminAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ LoadAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.LoadAsync ( string slug,
CancellationToken ct = default )
inline

Async 데이터를 불러옵니다.

매개변수
slugslug에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Load Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 567 번째 라인에서 정의되었습니다.

568 {
569 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false)
570 ?? new TenantConfig { Slug = slug };
571 InvitationDesignCatalog.Normalize(Config);
572 Gallery = await _photos.GetGalleryAsync(slug, ct).ConfigureAwait(false);
573 EffectiveAdminUsers = BuildEffectiveAdminUsers(Config);
574
575 EffectiveMediaPolicy = await _mediaPolicyResolver.ResolveAsync(Config, ct).ConfigureAwait(false);
576
577 var effectiveMb = EffectiveMediaPolicy.VideoMaxFileSizeMb;
578 MaxVideoSizeLabel = effectiveMb <= 0 ? "무제한" : $"최대 {effectiveMb}MB";
579
580 MaxVideoCount = EffectiveMediaPolicy.VideoMaxCount;
581
582 IsLoaded = true;
583 }

다음을 참조함 : _mediaPolicyResolver, _photos, _tenants, BuildEffectiveAdminUsers(), Config, EffectiveAdminUsers, EffectiveMediaPolicy, Gallery, IsLoaded, MaxVideoCount, MaxVideoSizeLabel, WeddingPlatform.Models.InvitationDesignCatalog.Normalize().

다음에 의해서 참조됨 : InitializeAsync(), LoginAsSuperAdminAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ LoginAsSuperAdminAsync()

async Task< bool > WeddingPlatform.ViewModels.WeddingAdminViewModel.LoginAsSuperAdminAsync ( string slug,
string? sessionToken,
CancellationToken ct = default )
inline

Login As Super Admin Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
sessionTokensession Token에 사용할 string? 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Login As Super Admin Async 작업에서 생성한 Task<bool> 결과입니다.

WeddingAdminViewModel.cs 파일의 512 번째 라인에서 정의되었습니다.

513 {
514 if (!_superAdminTokens.ValidateToken(sessionToken))
515 {
516 return false;
517 }
518
519 var config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
520 if (config is null)
521 {
522 StatusMessage = "존재하지 않는 슬러그입니다.";
523 return false;
524 }
525
526 IsAuthenticated = true;
527 IsLinkedToCurrentUser = false;
528 IsOwner = false;
529 EffectiveAdminUsers = BuildEffectiveAdminUsers(config);
530 StatusMessage = "슈퍼관리자 권한으로 접속했습니다.";
531 await LoadAsync(slug, ct).ConfigureAwait(false);
532 return true;
533 }

다음을 참조함 : _superAdminTokens, _tenants, BuildEffectiveAdminUsers(), EffectiveAdminUsers, IsAuthenticated, IsLinkedToCurrentUser, IsOwner, LoadAsync(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ LoginAsync()

async Task< bool > WeddingPlatform.ViewModels.WeddingAdminViewModel.LoginAsync ( string slug,
CancellationToken ct = default )
inline

Login Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Login Async 작업에서 생성한 Task<bool> 결과입니다.

WeddingAdminViewModel.cs 파일의 405 번째 라인에서 정의되었습니다.

406 {
407 var config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
408 if (config is null) { StatusMessage = "존재하지 않는 슬러그입니다."; return false; }
409
410 var user = await _userContext.GetCurrentAsync().ConfigureAwait(false);
411 await RefreshCurrentUserAsync().ConfigureAwait(false);
412
413 if (IsAdminUser(config, user))
414 {
415 IsAuthenticated = true;
416 IsLinkedToCurrentUser = true;
417 IsOwner = IsOwnerUser(config, user);
418 EffectiveAdminUsers = BuildEffectiveAdminUsers(config);
419 StatusMessage = "";
420 return true;
421 }
422
423 var verification = DreaminePasswordHasher.VerifyPassword(LoginPassword, config.PasswordHash, out var upgradedHash);
424 IsAuthenticated = verification is not PasswordHashVerificationResult.Failed;
425 if (!IsAuthenticated)
426 {
427 StatusMessage = "비밀번호가 틀렸습니다.";
428 return false;
429 }
430
431 if (verification is PasswordHashVerificationResult.SuccessRehashNeeded && upgradedHash is not null)
432 {
433 config.PasswordHash = upgradedHash;
434 await _tenants.SaveAsync(config, ct).ConfigureAwait(false);
435 }
436
437 if (user.IsAuthenticated && string.IsNullOrWhiteSpace(config.OwnerUserId))
438 {
439 config.OwnerUserId = user.Id;
440 config.OwnerProvider = user.Provider;
441 config.OwnerEmail = user.Email;
442 config.OwnerDisplayName = user.DisplayName;
443 config.OwnerLinkedAt = DateTime.Now;
444 EnsureAdminUser(config, user, "Owner");
445 await _tenants.SaveAsync(config, ct).ConfigureAwait(false);
446 IsLinkedToCurrentUser = true;
447 IsOwner = true;
448 EffectiveAdminUsers = BuildEffectiveAdminUsers(config);
449 StatusMessage = "CodeMaru/Dreamine 계정에 대표 관리자로 연결되었습니다. 다음부터는 공용 로그인으로 관리할 수 있습니다.";
450 }
451 else if (user.IsAuthenticated)
452 {
453 EnsureAdminUser(config, user, "Admin");
454 await _tenants.SaveAsync(config, ct).ConfigureAwait(false);
455 IsLinkedToCurrentUser = true;
456 IsOwner = IsOwnerUser(config, user);
457 EffectiveAdminUsers = BuildEffectiveAdminUsers(config);
458 StatusMessage = "현재 CodeMaru/Dreamine 계정이 이 청첩장의 관리자로 추가되었습니다.";
459 }
460 else if (!user.IsAuthenticated && string.IsNullOrWhiteSpace(config.OwnerUserId))
461 {
462 StatusMessage = "로그인은 성공했습니다. 공용 계정에 연결하려면 먼저 CodeMaru/Dreamine 로그인을 해주세요.";
463 }
464 else
465 {
466 StatusMessage = "";
467 }
468
469 return IsAuthenticated;
470 }

다음을 참조함 : _tenants, _userContext, BuildEffectiveAdminUsers(), EffectiveAdminUsers, EnsureAdminUser(), IsAdminUser(), IsAuthenticated, IsLinkedToCurrentUser, IsOwner, IsOwnerUser(), LoginPassword, RefreshCurrentUserAsync(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ MoveGalleryPhotoAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.MoveGalleryPhotoAsync ( string fileName,
int offset,
CancellationToken ct = default )
inline

Move Gallery Photo Async 작업을 수행합니다.

매개변수
fileNamefile Name에 사용할 string 값입니다.
offsetoffset에 사용할 int 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Move Gallery Photo Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1252 번째 라인에서 정의되었습니다.

1253 {
1254 if (Config is null) return;
1255 try
1256 {
1257 NormalizeGalleryFileOrder();
1258 var index = Config.GalleryFileNames.FindIndex(x => string.Equals(x, fileName, StringComparison.OrdinalIgnoreCase));
1259 if (index < 0) return;
1260
1261 var target = Math.Clamp(index + offset, 0, Config.GalleryFileNames.Count - 1);
1262 if (index == target) return;
1263
1264 Config.GalleryFileNames.RemoveAt(index);
1265 Config.GalleryFileNames.Insert(target, fileName);
1266 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
1267 Gallery = await _photos.GetGalleryAsync(Config.Slug, ct).ConfigureAwait(false);
1268 StatusMessage = "사진 노출 순서가 저장되었습니다.";
1269 }
1270 catch (Exception ex) { StatusMessage = $"순서 변경 오류: {ex.Message}"; }
1271 }

다음을 참조함 : _photos, _tenants, Config, Gallery, NormalizeGalleryFileOrder(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ MoveGalleryPhotoToAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.MoveGalleryPhotoToAsync ( string fileName,
bool first,
CancellationToken ct = default )
inline

Move Gallery Photo To Async 작업을 수행합니다.

매개변수
fileNamefile Name에 사용할 string 값입니다.
firstfirst에 사용할 bool 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Move Gallery Photo To Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1313 번째 라인에서 정의되었습니다.

1314 {
1315 if (Config is null) return;
1316 try
1317 {
1318 NormalizeGalleryFileOrder();
1319 var index = Config.GalleryFileNames.FindIndex(x => string.Equals(x, fileName, StringComparison.OrdinalIgnoreCase));
1320 if (index < 0) return;
1321
1322 Config.GalleryFileNames.RemoveAt(index);
1323 Config.GalleryFileNames.Insert(first ? 0 : Config.GalleryFileNames.Count, fileName);
1324 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
1325 Gallery = await _photos.GetGalleryAsync(Config.Slug, ct).ConfigureAwait(false);
1326 StatusMessage = "사진 노출 순서가 저장되었습니다.";
1327 }
1328 catch (Exception ex) { StatusMessage = $"순서 변경 오류: {ex.Message}"; }
1329 }

다음을 참조함 : _photos, _tenants, Config, Gallery, NormalizeGalleryFileOrder(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ NormalizeGalleryFileOrder()

void WeddingPlatform.ViewModels.WeddingAdminViewModel.NormalizeGalleryFileOrder ( )
inlineprivate

Normalize Gallery File Order 작업을 수행합니다.

WeddingAdminViewModel.cs 파일의 1339 번째 라인에서 정의되었습니다.

1340 {
1341 if (Config is null) return;
1342 var existing = Gallery.Select(x => x.FileName).ToHashSet(StringComparer.OrdinalIgnoreCase);
1343 Config.GalleryFileNames = Config.GalleryFileNames
1344 .Where(existing.Contains)
1345 .Distinct(StringComparer.OrdinalIgnoreCase)
1346 .ToList();
1347
1348 foreach (var photo in Gallery)
1349 {
1350 if (!Config.GalleryFileNames.Contains(photo.FileName, StringComparer.OrdinalIgnoreCase))
1351 {
1352 Config.GalleryFileNames.Add(photo.FileName);
1353 }
1354 }
1355 }

다음을 참조함 : Config, Gallery.

다음에 의해서 참조됨 : MoveGalleryPhotoAsync(), MoveGalleryPhotoToAsync().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ NormalizeHeroPanelPosition()

void WeddingPlatform.ViewModels.WeddingAdminViewModel.NormalizeHeroPanelPosition ( TenantConfig config)
inlinestaticprivate

Normalize Hero Panel Position 작업을 수행합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.

WeddingAdminViewModel.cs 파일의 2226 번째 라인에서 정의되었습니다.

2227 {
2228 InvitationDesignCatalog.Normalize(config);
2229 config.InviteHeroTopVerticalDesktop = NormalizeOption(config.InviteHeroTopVerticalDesktop, ["top", "middle", "bottom"], "top");
2230 config.InviteHeroTopHorizontalDesktop = NormalizeOption(config.InviteHeroTopHorizontalDesktop, ["left", "center", "right"], "center");
2231 config.InviteHeroTopVerticalMobile = NormalizeOption(config.InviteHeroTopVerticalMobile, ["top", "middle", "bottom"], "top");
2232 config.InviteHeroTopHorizontalMobile = NormalizeOption(config.InviteHeroTopHorizontalMobile, ["left", "center", "right"], "center");
2233 config.InviteHeroBottomVerticalDesktop = NormalizeOption(config.InviteHeroBottomVerticalDesktop, ["top", "middle", "bottom"], "bottom");
2234 config.InviteHeroBottomHorizontalDesktop = NormalizeOption(config.InviteHeroBottomHorizontalDesktop, ["left", "center", "right"], "center");
2235 config.InviteHeroBottomVerticalMobile = NormalizeOption(config.InviteHeroBottomVerticalMobile, ["top", "middle", "bottom"], "bottom");
2236 config.InviteHeroBottomHorizontalMobile = NormalizeOption(config.InviteHeroBottomHorizontalMobile, ["left", "center", "right"], "center");
2237 config.HeroPanelVerticalDesktop = NormalizeOption(config.HeroPanelVerticalDesktop, ["top", "middle", "bottom"], "top");
2238 config.HeroPanelHorizontalDesktop = NormalizeOption(config.HeroPanelHorizontalDesktop, ["left", "center", "right"], "center");
2239 config.HeroPanelVerticalMobile = NormalizeOption(config.HeroPanelVerticalMobile, ["top", "middle", "bottom"], "top");
2240 config.HeroPanelHorizontalMobile = NormalizeOption(config.HeroPanelHorizontalMobile, ["left", "center", "right"], "center");
2241 }

다음을 참조함 : WeddingPlatform.Models.TenantConfig.HeroPanelHorizontalDesktop, WeddingPlatform.Models.TenantConfig.HeroPanelHorizontalMobile, WeddingPlatform.Models.TenantConfig.HeroPanelVerticalDesktop, WeddingPlatform.Models.TenantConfig.HeroPanelVerticalMobile, WeddingPlatform.Models.TenantConfig.InviteHeroBottomHorizontalDesktop, WeddingPlatform.Models.TenantConfig.InviteHeroBottomHorizontalMobile, WeddingPlatform.Models.TenantConfig.InviteHeroBottomVerticalDesktop, WeddingPlatform.Models.TenantConfig.InviteHeroBottomVerticalMobile, WeddingPlatform.Models.TenantConfig.InviteHeroTopHorizontalDesktop, WeddingPlatform.Models.TenantConfig.InviteHeroTopHorizontalMobile, WeddingPlatform.Models.TenantConfig.InviteHeroTopVerticalDesktop, WeddingPlatform.Models.TenantConfig.InviteHeroTopVerticalMobile, WeddingPlatform.Models.InvitationDesignCatalog.Normalize(), NormalizeOption().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ NormalizeOption()

string WeddingPlatform.ViewModels.WeddingAdminViewModel.NormalizeOption ( string? value,
string[] allowed,
string fallback )
inlinestaticprivate

Normalize Option 작업을 수행합니다.

매개변수
value적용할 값입니다.
allowedallowed에 사용할 string[] 값입니다.
fallbackfallback에 사용할 string 값입니다.
반환값
Normalize Option 작업에서 생성한 string 결과입니다.

WeddingAdminViewModel.cs 파일의 2283 번째 라인에서 정의되었습니다.

2284 {
2285 var normalized = value?.Trim().ToLowerInvariant();
2286 return !string.IsNullOrWhiteSpace(normalized) && allowed.Contains(normalized) ? normalized : fallback;
2287 }

다음에 의해서 참조됨 : NormalizeHeroPanelPosition().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ RefreshCurrentUserAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.RefreshCurrentUserAsync ( )
inlineprivate

Refresh Current User Async 작업을 수행합니다.

반환값
Refresh Current User Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 601 번째 라인에서 정의되었습니다.

602 {
603 var user = await _userContext.GetCurrentAsync().ConfigureAwait(false);
604 IsSignedIn = user.IsAuthenticated;
605 CurrentUserLabel = user.IsAuthenticated
606 ? string.IsNullOrWhiteSpace(user.DisplayName)
607 ? user.Provider
608 : $"{user.DisplayName} ({user.Provider})"
609 : "";
610 }

다음을 참조함 : _userContext, CurrentUserLabel, IsSignedIn.

다음에 의해서 참조됨 : InitializeAsync(), LoginAsync().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ RemoveAdminAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.RemoveAdminAsync ( string userId,
CancellationToken ct = default )
inline

Admin Async 항목을 제거합니다.

매개변수
userIduser Id에 사용할 string 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Remove Admin Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1023 번째 라인에서 정의되었습니다.

1024 {
1025 if (Config is null) return;
1026 var user = await _userContext.GetCurrentAsync().ConfigureAwait(false);
1027 if (!IsOwnerUser(Config, user))
1028 {
1029 StatusMessage = "대표 관리자만 관리자 계정을 삭제할 수 있습니다.";
1030 return;
1031 }
1032
1033 if (string.Equals(Config.OwnerUserId, userId, StringComparison.Ordinal))
1034 {
1035 StatusMessage = "대표 관리자는 삭제할 수 없습니다.";
1036 return;
1037 }
1038
1039 var removed = GetAdminUsers(Config).RemoveAll(x => string.Equals(x.UserId, userId, StringComparison.Ordinal));
1040 if (removed == 0)
1041 {
1042 StatusMessage = "삭제할 관리자를 찾을 수 없습니다.";
1043 return;
1044 }
1045
1046 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
1047 EffectiveAdminUsers = BuildEffectiveAdminUsers(Config);
1048 StatusMessage = "관리자 계정이 삭제되었습니다.";
1049 }

다음을 참조함 : _tenants, _userContext, BuildEffectiveAdminUsers(), Config, EffectiveAdminUsers, GetAdminUsers(), IsOwnerUser(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ SaveConfigAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.SaveConfigAsync ( CancellationToken ct = default)
inline

Config Async 데이터를 저장합니다.

매개변수
ct취소 요청을 감시하는 토큰입니다.
반환값
Save Config Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 636 번째 라인에서 정의되었습니다.

637 {
638 if (Config is null) return;
639 try
640 {
641 if (!ValidateLayoutForSave(Config))
642 {
643 return;
644 }
645
646 if (!ValidateThemeForSave(Config))
647 {
648 return;
649 }
650
651 InvitationDesignCatalog.Normalize(Config);
652 Config.PasswordHash = DreaminePasswordHasher.HashPlainTextForStorage(Config.PasswordHash);
653 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
654 EffectiveAdminUsers = BuildEffectiveAdminUsers(Config);
655 StatusMessage = "설정이 저장되었습니다.";
656 }
657 catch (Exception ex) { StatusMessage = $"저장 오류: {ex.Message}"; }
658 }

다음을 참조함 : _tenants, BuildEffectiveAdminUsers(), Config, EffectiveAdminUsers, WeddingPlatform.Models.InvitationDesignCatalog.Normalize(), StatusMessage, ValidateLayoutForSave(), ValidateThemeForSave().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ SaveStoryChapterAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.SaveStoryChapterAsync ( StoryChapter chapter,
CancellationToken ct = default )
inline

Story Chapter Async 데이터를 저장합니다.

매개변수
chapterchapter에 사용할 StoryChapter 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Save Story Chapter Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 710 번째 라인에서 정의되었습니다.

711 {
712 if (Config is null) return;
713 try
714 {
715 InvitationDesignCatalog.Normalize(Config);
716 var chapters = Config.DesignSettings.StoryChapters;
717 var index = chapters.FindIndex(x => x.ChapterNumber == chapter.ChapterNumber);
718 var normalized = WeddingStoryChapterDefaults.Clone(chapter);
719 normalized.Label = string.IsNullOrWhiteSpace(normalized.Label)
720 ? $"CHAPTER {Math.Max(1, normalized.ChapterNumber):00}"
721 : normalized.Label.Trim();
722 normalized.Title = string.IsNullOrWhiteSpace(normalized.Title)
723 ? "스토리"
724 : normalized.Title.Trim();
725
726 if (index >= 0)
727 {
728 chapters[index] = normalized;
729 }
730 else
731 {
732 chapters.Add(normalized);
733 Config.DesignSettings.StoryChapters = WeddingStoryChapterDefaults.Normalize(chapters);
734 }
735
736 await _tenants.SaveAsync(Config, ct).ConfigureAwait(false);
737 StatusMessage = $"{normalized.Label} 챕터가 저장되었습니다.";
738 }
739 catch (Exception ex)
740 {
741 StatusMessage = $"챕터 저장 오류: {ex.Message}";
742 }
743 }

다음을 참조함 : _tenants, Config, WeddingPlatform.Models.InvitationDesignCatalog.Normalize(), StatusMessage.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ SetStatusMessage()

void WeddingPlatform.ViewModels.WeddingAdminViewModel.SetStatusMessage ( string message)
inline

Status Message 값을 설정합니다.

매개변수
message처리할 메시지입니다.

WeddingAdminViewModel.cs 파일의 676 번째 라인에서 정의되었습니다.

676=> StatusMessage = message;

다음을 참조함 : StatusMessage.

◆ UploadGalleryAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadGalleryAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Gallery Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Gallery Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1091 번째 라인에서 정의되었습니다.

1092 {
1093 IsUploading = true;
1094 StatusMessage = "";
1095 try
1096 {
1097 await _photos.UploadAsync(slug, file, ct).ConfigureAwait(false);
1098 // Config도 갱신해야 이후 설정 저장 시 GalleryFileNames가 날아가지 않음
1099 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1100 Gallery = await _photos.GetGalleryAsync(slug, ct).ConfigureAwait(false);
1101 StatusMessage = $"{file.Name} 업로드 완료";
1102 }
1103 catch (Exception ex) { StatusMessage = $"업로드 오류: {ex.Message}"; }
1104 finally { IsUploading = false; }
1105 }

다음을 참조함 : _photos, _tenants, Config, Gallery, IsUploading, StatusMessage.

◆ UploadHeroAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadHeroAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Hero Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Hero Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1147 번째 라인에서 정의되었습니다.

1148 {
1149 IsUploading = true;
1150 try
1151 {
1152 await _photos.UploadHeroAsync(slug, file, ct).ConfigureAwait(false);
1153 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1154 StatusMessage = "히어로 이미지 업로드 완료";
1155 }
1156 catch (Exception ex) { StatusMessage = $"히어로 업로드 오류: {ex.Message}"; }
1157 finally { IsUploading = false; }
1158 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ UploadMusicAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadMusicAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Music Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Music Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1982 번째 라인에서 정의되었습니다.

1983 {
1984 IsUploading = true;
1985 try
1986 {
1987 await _photos.UploadMusicAsync(slug, file, ct).ConfigureAwait(false);
1988 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1989 StatusMessage = "배경 음악 업로드 완료";
1990 }
1991 catch (Exception ex) { StatusMessage = $"음악 업로드 오류: {ex.Message}"; }
1992 finally { IsUploading = false; }
1993 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ UploadOgImageAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadOgImageAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Og Image Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Og Image Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1772 번째 라인에서 정의되었습니다.

1773 {
1774 IsUploading = true;
1775 try
1776 {
1777 await _photos.UploadOgImageAsync(slug, file, ct).ConfigureAwait(false);
1778 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1779 StatusMessage = "미리보기 이미지 업로드 완료";
1780 }
1781 catch (Exception ex) { StatusMessage = $"미리보기 이미지 오류: {ex.Message}"; }
1782 finally { IsUploading = false; }
1783 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ UploadRoadMapAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadRoadMapAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Road Map Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Road Map Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1397 번째 라인에서 정의되었습니다.

1398 {
1399 IsUploading = true;
1400 try
1401 {
1402 await _photos.UploadRoadMapAsync(slug, file, ct).ConfigureAwait(false);
1403 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1404 StatusMessage = "약도 이미지 업로드 완료";
1405 }
1406 catch (Exception ex) { StatusMessage = $"약도 업로드 오류: {ex.Message}"; }
1407 finally { IsUploading = false; }
1408 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ UploadThankYouOgImageAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadThankYouOgImageAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Thank You Og Image Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Thank You Og Image Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1825 번째 라인에서 정의되었습니다.

1826 {
1827 IsUploading = true;
1828 try
1829 {
1830 await _photos.UploadThankYouOgImageAsync(slug, file, ct).ConfigureAwait(false);
1831 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1832 StatusMessage = "감사장 미리보기 이미지 업로드 완료";
1833 }
1834 catch (Exception ex) { StatusMessage = $"감사장 미리보기 이미지 오류: {ex.Message}"; }
1835 finally { IsUploading = false; }
1836 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ UploadVideoAsync()

async Task WeddingPlatform.ViewModels.WeddingAdminViewModel.UploadVideoAsync ( string slug,
IBrowserFile file,
CancellationToken ct = default )
inline

Upload Video Async 작업을 수행합니다.

매개변수
slugslug에 사용할 string 값입니다.
filefile에 사용할 IBrowserFile 값입니다.
ct취소 요청을 감시하는 토큰입니다.
반환값
Upload Video Async 작업에서 생성한 Task 결과입니다.

WeddingAdminViewModel.cs 파일의 1878 번째 라인에서 정의되었습니다.

1879 {
1880 IsUploading = true;
1881 try
1882 {
1883 await _photos.UploadVideoAsync(slug, file, ct).ConfigureAwait(false);
1884 Config = await _tenants.GetAsync(slug, ct).ConfigureAwait(false);
1885 StatusMessage = "동영상 업로드 완료";
1886 }
1887 catch (Exception ex) { StatusMessage = $"동영상 업로드 오류: {ex.Message}"; }
1888 finally { IsUploading = false; }
1889 }

다음을 참조함 : _photos, _tenants, Config, IsUploading, StatusMessage.

◆ ValidateLayoutForSave()

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.ValidateLayoutForSave ( TenantConfig config)
inlineprivate

Layout For Save 값의 유효성을 검사합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
반환값
Validate Layout For Save 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

WeddingAdminViewModel.cs 파일의 877 번째 라인에서 정의되었습니다.

878 {
879 config.DesignSettings ??= new DesignSettings();
880 if (!WeddingLayoutCatalog.IsKnownKey(config.InvitationStyle))
881 {
882 StatusMessage = "저장 오류: 존재하지 않는 레이아웃입니다.";
883 return false;
884 }
885
886 var mode = config.DesignSettings.LayoutMode;
887 if (mode == WeddingLayoutMode.Unknown)
888 {
889 mode = InvitationDesignCatalog.FromLegacyLayoutKey(config.InvitationStyle);
890 config.DesignSettings.LayoutMode = mode;
891 }
892
893 var option = WeddingLayoutCatalog.Instance.Find(mode);
894 if (option is null)
895 {
896 StatusMessage = "저장 오류: 존재하지 않는 레이아웃입니다.";
897 return false;
898 }
899
900 if (!option.IsImplemented)
901 {
902 StatusMessage = "저장 오류: 아직 준비 중인 레이아웃입니다.";
903 return false;
904 }
905
906 var access = new WeddingLayoutAccessState
907 {
908 HasPremiumPlan = config.HasPremiumPlan,
909 UnlockedLayouts = config.UnlockedLayoutModes
910 .Select(WeddingLayoutCatalog.FromLegacyKey)
911 .Where(x => x != WeddingLayoutMode.Unknown)
912 .ToArray(),
913 };
914
915 if (!new WeddingLayoutAccessPolicy().CanUse(option, access))
916 {
917 StatusMessage = "저장 오류: 프리미엄 레이아웃은 플랜 또는 잠금 해제 후 저장할 수 있습니다.";
918 return false;
919 }
920
921 return true;
922 }

다음을 참조함 : WeddingPlatform.Models.TenantConfig.DesignSettings, WeddingPlatform.Models.InvitationDesignCatalog.FromLegacyLayoutKey(), WeddingPlatform.Models.TenantConfig.HasPremiumPlan, WeddingPlatform.Models.TenantConfig.InvitationStyle, WeddingPlatform.Models.DesignSettings.LayoutMode, StatusMessage.

다음에 의해서 참조됨 : SaveConfigAsync().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ValidateThemeForSave()

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.ValidateThemeForSave ( TenantConfig config)
inlineprivate

Theme For Save 값의 유효성을 검사합니다.

매개변수
configconfig에 사용할 TenantConfig 값입니다.
반환값
Validate Theme For Save 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

WeddingAdminViewModel.cs 파일의 948 번째 라인에서 정의되었습니다.

949 {
950 config.DesignSettings ??= new DesignSettings();
951 config.UnlockedThemeKeys ??= new();
952 if (!WeddingThemeCatalog.IsKnownKey(config.DesignSettings.ThemeKey))
953 {
954 StatusMessage = "저장 오류: 존재하지 않는 테마입니다.";
955 return false;
956 }
957
958 var option = WeddingThemeCatalog.Instance.Find(config.DesignSettings.ThemeKey);
959 if (option is null)
960 {
961 StatusMessage = "저장 오류: 존재하지 않는 테마입니다.";
962 return false;
963 }
964
965 if (!option.IsImplemented)
966 {
967 StatusMessage = "저장 오류: 아직 준비 중인 테마입니다.";
968 return false;
969 }
970
971 var access = new WeddingThemeAccessState
972 {
973 HasPremiumPlan = config.HasPremiumPlan,
974 UnlockedThemeKeys = config.UnlockedThemeKeys
975 .Select(WeddingThemeCatalog.NormalizeKey)
976 .Where(WeddingThemeCatalog.IsKnownKey)
977 .ToArray(),
978 };
979
980 if (!new WeddingThemeAccessPolicy().CanUse(option, access))
981 {
982 StatusMessage = "저장 오류: 프리미엄 테마는 플랜 또는 잠금 해제 후 저장할 수 있습니다.";
983 return false;
984 }
985
986 config.DesignSettings.ThemeKey = option.Key;
987 config.ThemeName = option.Key;
988 return true;
989 }

다음을 참조함 : WeddingPlatform.Models.TenantConfig.DesignSettings, WeddingPlatform.Models.TenantConfig.HasPremiumPlan, StatusMessage, WeddingPlatform.Models.DesignSettings.ThemeKey.

다음에 의해서 참조됨 : SaveConfigAsync().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

멤버 데이터 문서화

◆ _geocodeHttp

readonly HttpClient WeddingPlatform.ViewModels.WeddingAdminViewModel._geocodeHttp
staticprivate
초기값:
= new()
{
DefaultRequestHeaders = { { "User-Agent", "CodemaruWeddingPlatform/1.0 (contact: admin@codemaru.co.kr)" } }
}

geocode Http 값을 보관합니다.

WeddingAdminViewModel.cs 파일의 85 번째 라인에서 정의되었습니다.

86 {
87 DefaultRequestHeaders = { { "User-Agent", "CodemaruWeddingPlatform/1.0 (contact: admin@codemaru.co.kr)" } }
88 };

다음에 의해서 참조됨 : GeocodeAsync().

◆ _mediaPolicyResolver

readonly IMediaQuotaPolicyResolver WeddingPlatform.ViewModels.WeddingAdminViewModel._mediaPolicyResolver
private

media Policy Resolver 값을 보관합니다.

WeddingAdminViewModel.cs 파일의 66 번째 라인에서 정의되었습니다.

다음에 의해서 참조됨 : LoadAsync(), WeddingAdminViewModel().

◆ _opts

readonly WeddingOptions WeddingPlatform.ViewModels.WeddingAdminViewModel._opts
private

opts 값을 보관합니다.

WeddingAdminViewModel.cs 파일의 48 번째 라인에서 정의되었습니다.

다음에 의해서 참조됨 : GenerateMapLinks(), WeddingAdminViewModel().

◆ _photos

◆ _superAdminTokens

readonly ISuperAdminSessionTokenService WeddingPlatform.ViewModels.WeddingAdminViewModel._superAdminTokens
private

super Admin Tokens 값을 보관합니다.

WeddingAdminViewModel.cs 파일의 75 번째 라인에서 정의되었습니다.

다음에 의해서 참조됨 : LoginAsSuperAdminAsync(), WeddingAdminViewModel().

◆ _tenants

◆ _userContext

readonly WeddingUserContext WeddingPlatform.ViewModels.WeddingAdminViewModel._userContext
private

user Context 값을 보관합니다.

WeddingAdminViewModel.cs 파일의 57 번째 라인에서 정의되었습니다.

다음에 의해서 참조됨 : InitializeAsync(), LoginAsync(), RefreshCurrentUserAsync(), RemoveAdminAsync(), WeddingAdminViewModel().

속성 문서화

◆ Config

◆ CurrentUserLabel

string WeddingPlatform.ViewModels.WeddingAdminViewModel.CurrentUserLabel = ""
getprivate set

Current User Label 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 279 번째 라인에서 정의되었습니다.

279{ get; private set; } = "";

다음에 의해서 참조됨 : RefreshCurrentUserAsync().

◆ EffectiveAdminUsers

IReadOnlyList<WeddingAdminUser> WeddingPlatform.ViewModels.WeddingAdminViewModel.EffectiveAdminUsers = []
getprivate set

Effective Admin Users 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 261 번째 라인에서 정의되었습니다.

261{ get; private set; } = [];

다음에 의해서 참조됨 : InitializeAsync(), LoadAsync(), LoginAsSuperAdminAsync(), LoginAsync(), RemoveAdminAsync(), SaveConfigAsync().

◆ EffectiveMediaPolicy

EffectiveMediaPolicy? WeddingPlatform.ViewModels.WeddingAdminViewModel.EffectiveMediaPolicy
getprivate set

현재 계정에 적용되는 최종 미디어 정책입니다.

WeddingAdminViewModel.cs 파일의 188 번째 라인에서 정의되었습니다.

188{ get; private set; }

다음에 의해서 참조됨 : LoadAsync().

◆ Gallery

IReadOnlyList<PhotoInfo> WeddingPlatform.ViewModels.WeddingAdminViewModel.Gallery = []
getprivate set

Gallery 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 207 번째 라인에서 정의되었습니다.

207{ get; private set; } = [];

다음에 의해서 참조됨 : DeletePhotoAsync(), LoadAsync(), MoveGalleryPhotoAsync(), MoveGalleryPhotoToAsync(), NormalizeGalleryFileOrder(), UploadGalleryAsync().

◆ GeocodeStatus

string WeddingPlatform.ViewModels.WeddingAdminViewModel.GeocodeStatus = ""
getprivate set

Geocode Status 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 306 번째 라인에서 정의되었습니다.

306{ get; private set; } = "";

다음에 의해서 참조됨 : GeocodeAsync().

◆ IsAuthenticated

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsAuthenticated
getprivate set

Is Authenticated 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 225 번째 라인에서 정의되었습니다.

225{ get; private set; }

다음에 의해서 참조됨 : InitializeAsync(), LoginAsSuperAdminAsync(), LoginAsync().

◆ IsGeocoding

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsGeocoding
getprivate set

Is Geocoding 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 297 번째 라인에서 정의되었습니다.

297{ get; private set; }

다음에 의해서 참조됨 : GeocodeAsync().

◆ IsLinkedToCurrentUser

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsLinkedToCurrentUser
getprivate set

Is Linked To Current User 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 243 번째 라인에서 정의되었습니다.

243{ get; private set; }

다음에 의해서 참조됨 : InitializeAsync(), LoginAsSuperAdminAsync(), LoginAsync().

◆ IsLoaded

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsLoaded
getprivate set

Is Loaded 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 216 번째 라인에서 정의되었습니다.

216{ get; private set; }

다음에 의해서 참조됨 : LoadAsync().

◆ IsOwner

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsOwner
getprivate set

Is Owner 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 252 번째 라인에서 정의되었습니다.

252{ get; private set; }

다음에 의해서 참조됨 : InitializeAsync(), LoginAsSuperAdminAsync(), LoginAsync().

◆ IsSignedIn

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsSignedIn
getprivate set

Is Signed In 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 234 번째 라인에서 정의되었습니다.

234{ get; private set; }

다음에 의해서 참조됨 : RefreshCurrentUserAsync().

◆ IsUploading

bool WeddingPlatform.ViewModels.WeddingAdminViewModel.IsUploading
getprivate set

Is Uploading 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 288 번째 라인에서 정의되었습니다.

288{ get; private set; }

다음에 의해서 참조됨 : UploadGalleryAsync(), UploadHeroAsync(), UploadMusicAsync(), UploadOgImageAsync(), UploadRoadMapAsync(), UploadThankYouOgImageAsync(), UploadVideoAsync().

◆ LoginPassword

string WeddingPlatform.ViewModels.WeddingAdminViewModel.LoginPassword = ""
getset

Login Password 값을 가져오거나 설정합니다.

WeddingAdminViewModel.cs 파일의 316 번째 라인에서 정의되었습니다.

316{ get; set; } = "";

다음에 의해서 참조됨 : LoginAsync().

◆ MaxVideoCount

int WeddingPlatform.ViewModels.WeddingAdminViewModel.MaxVideoCount = 6
getprivate set

동영상 업로드 최대 개수 (0이면 무제한).

WeddingAdminViewModel.cs 파일의 179 번째 라인에서 정의되었습니다.

179{ get; private set; } = 6;

다음에 의해서 참조됨 : LoadAsync().

◆ MaxVideoSizeLabel

string WeddingPlatform.ViewModels.WeddingAdminViewModel.MaxVideoSizeLabel = "최대 200MB"
getprivate set

동영상 업로드 최대 용량 안내 문구 (예: "최대 200MB" 또는 "무제한").

WeddingAdminViewModel.cs 파일의 170 번째 라인에서 정의되었습니다.

170{ get; private set; } = "최대 200MB";

다음에 의해서 참조됨 : LoadAsync().

◆ StatusMessage


이 클래스에 대한 문서화 페이지는 다음의 파일로부터 생성되었습니다.: