using System.Diagnostics; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using bitforum.Models; using bitforum.Models.BBS; namespace bitforum.Controllers.BBS.Board { [Authorize] [Route("BBS/Board")] public class GroupController : Controller { private readonly ILogger _logger; private readonly DefaultDbContext _db; private readonly string _ViewPath = "~/Views/BBS/Board/Group.cshtml"; public GroupController(ILogger logger, DefaultDbContext db) { _logger = logger; _db = db; } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } [HttpGet("Group")] public IActionResult Index() { ViewBag.BoardGroups = _db.BoardGroup.OrderBy(c => c.Order).ToList(); ViewBag.Total = ViewBag.BoardGroups?.Count ?? 0; return View(_ViewPath); } [HttpPost("Group")] public async Task Save([FromForm] List request) { using var transaction = await _db.Database.BeginTransactionAsync(); try { if (request == null || !request.Any()) { // 전체 삭제 var boardGroups = await _db.BoardGroup.ToListAsync(); if (boardGroups.Any()) { _db.BoardGroup.RemoveRange(boardGroups); await _db.SaveChangesAsync(); } await transaction.CommitAsync(); return Index(); } if (!ModelState.IsValid) { throw new Exception("유효성 검사에 실패하였습니다."); } var requestIDs = request.Select(x => x.ID).ToList(); // 요청 데이터의 ID 목록 var existingIDs = await _db.BoardGroup.Select(c => c.ID).ToListAsync(); // 데이터베이스에 존재하는 ID 목록 var IDsToDelete = existingIDs.Except(requestIDs).ToList(); // 삭제 대상 ID: 요청 데이터에 없는 항목 // 삭제 대상 항목 제거 if (IDsToDelete.Any()) { _db.BoardGroup.RemoveRange( await _db.BoardGroup.Where(c => IDsToDelete.Contains(c.ID) && !c.Board.Any()).ToListAsync() ); } foreach (var row in request) { // 중복 확인 if (await _db.BoardGroup.AnyAsync(c => c.Code == row.Code && c.ID != row.ID)) { throw new Exception($"{row.Code} `Code`는 이미 존재합니다."); } if (row.ID == 0) { row.CreatedAt = DateTime.UtcNow; await _db.BoardGroup.AddAsync(row); } else { var boardGroup = await _db.BoardGroup.FindAsync(row.ID); if (boardGroup == null) { throw new Exception($"ID {row.ID}에 해당하는 정보가 없습니다."); } boardGroup.Code = row.Code; boardGroup.Name = row.Name; boardGroup.Order = row.Order; boardGroup.UpdatedAt = DateTime.UtcNow; _db.BoardGroup.Update(boardGroup); } } await transaction.CommitAsync(); int affectedRows = await _db.SaveChangesAsync(); if (affectedRows <= 0) { throw new Exception("저장 중 오류가 발생했습니다."); } string message = "게시판 분류가 저장되었습니다."; TempData["SuccessMessage"] = message; _logger.LogInformation(message); return RedirectToAction("Index"); } catch (Exception e) { await transaction.RollbackAsync(); TempData["ErrorMessages"] = e.Message; _logger.LogError(e, e.Message); return Index(); } } } }