ccba017e3e
DB: - V007__CreateFaqs.sql: faqs 테이블 (question, answer, category, sort_order, is_active) + 기본 FAQ 4개 시드 Domain: - Faq 엔티티 - IFaqRepository (GetActiveAsync, GetAllAsync, CRUD) Infrastructure: - FaqRepository: sort_order 정렬, CRUD Application: - FaqService: Categories 상수, Validate (질문·답변 필수) Admin UI (Blazor): - FaqList.razor: 전체 목록, 활성/비활성 상태 칩, 삭제 확인 - FaqEdit.razor: 질문/답변/카테고리/순서/활성 토글 폼 - MainLayout: 홈페이지 그룹 하위에 FAQ 관리 메뉴 추가 홈페이지: - Index.cshtml 하드코딩 FAQ → ActiveFaqs DB 루프로 교체 - FAQ 없으면 섹션 전체 숨김 (빈 DB에 안전) - IndexModel: FaqService 주입, Task.WhenAll 병렬 로드 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
77 lines
2.5 KiB
C#
77 lines
2.5 KiB
C#
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using TaxBaik.Application.Seasonal;
|
|
using TaxBaik.Application.Services;
|
|
using TaxBaik.Domain.Entities;
|
|
|
|
namespace TaxBaik.Web.Pages;
|
|
|
|
public class IndexModel : PageModel
|
|
{
|
|
private readonly BlogService _blogService;
|
|
private readonly SeasonalMarketingService _seasonalMarketingService;
|
|
private readonly AnnouncementService _announcementService;
|
|
private readonly FaqService _faqService;
|
|
|
|
public List<BlogPost> RecentPosts { get; set; } = [];
|
|
public List<BlogPost> SeasonalPosts { get; set; } = [];
|
|
public CurrentSeasonDto? CurrentSeason { get; set; }
|
|
public List<Announcement> ActiveAnnouncements { get; set; } = [];
|
|
public List<Faq> ActiveFaqs { get; set; } = [];
|
|
|
|
public IndexModel(
|
|
BlogService blogService,
|
|
SeasonalMarketingService seasonalMarketingService,
|
|
AnnouncementService announcementService,
|
|
FaqService faqService)
|
|
{
|
|
_blogService = blogService;
|
|
_seasonalMarketingService = seasonalMarketingService;
|
|
_announcementService = announcementService;
|
|
_faqService = faqService;
|
|
}
|
|
|
|
public async Task OnGetAsync()
|
|
{
|
|
CurrentSeason = _seasonalMarketingService.GetCurrentSeason();
|
|
|
|
var announcementsTask = LoadSafeAsync(() => _announcementService.GetActiveAsync());
|
|
var faqsTask = LoadSafeAsync(() => _faqService.GetActiveAsync());
|
|
var blogTask = LoadBlogAsync();
|
|
|
|
await Task.WhenAll(announcementsTask, faqsTask, blogTask);
|
|
|
|
ActiveAnnouncements = (await announcementsTask)?.ToList() ?? [];
|
|
ActiveFaqs = (await faqsTask)?.ToList() ?? [];
|
|
}
|
|
|
|
private async Task LoadBlogAsync()
|
|
{
|
|
try
|
|
{
|
|
if (CurrentSeason is not null && !string.IsNullOrEmpty(CurrentSeason.RelatedCategorySlug))
|
|
{
|
|
var (seasonal, latest) = await _blogService.GetSeasonalPostsAsync(
|
|
CurrentSeason.RelatedCategorySlug, seasonalCount: 2, totalCount: 3);
|
|
SeasonalPosts = seasonal.ToList();
|
|
RecentPosts = latest.ToList();
|
|
}
|
|
else
|
|
{
|
|
var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 3);
|
|
RecentPosts = posts.ToList();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
RecentPosts = [];
|
|
SeasonalPosts = [];
|
|
}
|
|
}
|
|
|
|
private static async Task<IEnumerable<T>?> LoadSafeAsync<T>(Func<Task<IEnumerable<T>>> loader)
|
|
{
|
|
try { return await loader(); }
|
|
catch { return null; }
|
|
}
|
|
}
|