CategoryController.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using System.Diagnostics;
  2. using Microsoft.AspNetCore.Authorization;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.EntityFrameworkCore;
  5. using bitforum.Models;
  6. using bitforum.Models.Page.Faq;
  7. using bitforum.Repository;
  8. using bitforum.Constants;
  9. namespace bitforum.Controllers.Page.Faq
  10. {
  11. [Authorize]
  12. [Route("Page")]
  13. public class CategoryController : Controller
  14. {
  15. private readonly ILogger<CategoryController> _logger;
  16. private readonly IRedisRepository _redisRepository;
  17. private readonly DefaultDbContext _db;
  18. private readonly string _ViewPath = "~/Views/Page/Faq/Category/Index.cshtml";
  19. public CategoryController(ILogger<CategoryController> logger, IRedisRepository redisRepository, DefaultDbContext db)
  20. {
  21. _logger = logger;
  22. _redisRepository = redisRepository;
  23. _db = db;
  24. }
  25. [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
  26. public IActionResult Error()
  27. {
  28. return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
  29. }
  30. [HttpGet("Faq")]
  31. public IActionResult Index()
  32. {
  33. ViewBag.FaqCategories = _db.FaqCategory.Include(c => c.FaqItem).OrderBy(c => c.Order).ToList();
  34. ViewBag.Total = ViewBag.FaqCategories?.Count ?? 0;
  35. return View(_ViewPath);
  36. }
  37. [HttpPost("Faq")]
  38. public async Task<IActionResult> Save([FromForm] List<FaqCategory> request)
  39. {
  40. using var transaction = await _db.Database.BeginTransactionAsync();
  41. try
  42. {
  43. if (request == null || !request.Any())
  44. {
  45. // 전체 삭제
  46. var faqCategories = await _db.FaqCategory.ToListAsync();
  47. if (faqCategories.Any())
  48. {
  49. _db.FaqCategory.RemoveRange(faqCategories);
  50. await _db.SaveChangesAsync();
  51. }
  52. await transaction.CommitAsync();
  53. return RedirectToAction("Index");
  54. }
  55. if (!ModelState.IsValid)
  56. {
  57. throw new Exception("유효성 검사에 실패하였습니다.");
  58. }
  59. var requestIDs = request.Select(x => x.ID).ToList(); // 요청 데이터의 ID 목록
  60. var existingIDs = await _db.FaqCategory.Select(c => c.ID).ToListAsync(); // 데이터베이스에 존재하는 ID 목록
  61. var IDsToDelete = existingIDs.Except(requestIDs).ToList(); // 삭제 대상 ID: 요청 데이터에 없는 항목
  62. // 삭제 대상 항목 제거
  63. if (IDsToDelete.Any())
  64. {
  65. var selectedRows = await _db.FaqCategory.Where(c => IDsToDelete.Contains(c.ID) && !c.FaqItem.Any()).ToListAsync();
  66. _db.FaqCategory.RemoveRange(selectedRows);
  67. }
  68. foreach (var row in request)
  69. {
  70. // 중복 확인
  71. if (await _db.FaqCategory.AnyAsync(c => c.Code == row.Code && c.ID != row.ID))
  72. {
  73. throw new Exception($"{row.Code} `Code`는 이미 존재합니다.");
  74. }
  75. if (row.ID == 0)
  76. {
  77. row.CreatedAt = DateTime.UtcNow;
  78. await _db.FaqCategory.AddAsync(row);
  79. }
  80. else
  81. {
  82. var faqCategory = await _db.FaqCategory.FirstOrDefaultAsync(c => c.ID == row.ID);
  83. if (faqCategory == null)
  84. {
  85. throw new Exception($"ID {row.ID}에 해당하는 정보가 없습니다.");
  86. }
  87. // 기존 엔터티 업데이트
  88. faqCategory.Code = row.Code;
  89. faqCategory.Subject = row.Subject;
  90. faqCategory.Order = row.Order;
  91. faqCategory.IsActive = row.IsActive;
  92. faqCategory.UpdatedAt = DateTime.UtcNow;
  93. _db.FaqCategory.Update(faqCategory);
  94. }
  95. }
  96. await transaction.CommitAsync();
  97. int affectedRows = await _db.SaveChangesAsync();
  98. if (affectedRows <= 0)
  99. {
  100. throw new Exception("저장 중 오류가 발생했습니다.");
  101. }
  102. await _redisRepository.DeleteAsync(RedisConst.BannerKey);
  103. string message = "FAQ 분류가 저장되었습니다.";
  104. TempData["SuccessMessage"] = message;
  105. _logger.LogInformation(message);
  106. return RedirectToAction("Index");
  107. }
  108. catch (Exception e)
  109. {
  110. await transaction.RollbackAsync();
  111. TempData["ErrorMessages"] = e.Message;
  112. _logger.LogError(e, e.Message);
  113. return Index();
  114. }
  115. }
  116. }
  117. }