| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.EntityFrameworkCore;
- using bitforum.DTOs.Response;
- using bitforum.Repository;
- using bitforum.Constants;
- namespace bitforum.Controllers.API
- {
- [ApiController]
- [Route("api/[controller]")]
- public class SystemController : ControllerBase
- {
- private readonly ILogger<SystemController> _logger;
- private readonly IRedisRepository _redisRepository;
- private readonly IConfigRepository _configRepository;
- private readonly DefaultDbContext _db;
- private ResultDto _result = new ResultDto();
- public SystemController(ILogger<SystemController> logger, IRedisRepository redisRepository, IConfigRepository configRepository, DefaultDbContext db)
- {
- _logger = logger;
- _redisRepository = redisRepository;
- _configRepository = configRepository;
- _db = db;
- }
- // Config 값 JSON으로 반환
- [HttpGet("configs")]
- public async Task<ResultDto> Configs()
- {
- try
- {
- var config = await _redisRepository.GetObjectAsync<Dictionary<string, string>>(RedisConst.ConfigKey);
- if (config is null)
- {
- config = _configRepository.GetAll();
- await _redisRepository.SetObjectAsync(RedisConst.ConfigKey, config, RedisConst.CacheExpiration);
- }
- _result.Data = config;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- // 문서 조회
- [HttpGet("docs/{code}")]
- public async Task<ResultDto> Docs([FromRoute] string code)
- {
- try
- {
- string cacheKey = $"{RedisConst.DocumentKey}-{code}";
- var document = await _redisRepository.GetObjectAsync<object>(cacheKey);
- if (document is null)
- {
- document = await _db.Document.Where(c => c.Code == code && c.IsActive)
- .Select(c => new
- {
- c.ID,
- c.Code,
- c.Subject,
- c.Content
- })
- .FirstOrDefaultAsync();
- await _redisRepository.SetObjectAsync(cacheKey, document, RedisConst.CacheExpiration);
- }
- if (document is null)
- {
- throw new Exception("문서 정보가 존재하지 않습니다.");
- }
- _result.Data = document;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- // FAQ 분류 목록
- [HttpGet("faq/categories")]
- public async Task<ResultDto> FaqCategories()
- {
- try
- {
- string cacheKey = "FaqCategories";
- var faqCategories = await _redisRepository.GetObjectAsync<object>(cacheKey);
- if (faqCategories is null)
- {
- faqCategories = await _db.FaqCategory.Where(c => c.IsActive)
- .OrderBy(c => c.Order)
- .Select(c => new
- {
- c.ID,
- c.Code,
- c.Subject
- }).ToListAsync();
- await _redisRepository.SetObjectAsync(cacheKey, faqCategories, RedisConst.CacheExpiration);
- }
- if (faqCategories is null)
- {
- throw new Exception("FAQ 분류 목록이 존재하지 않습니다.");
- }
- _result.Data = faqCategories;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- // FAQ 분류별 자주 묻는 질문 목록
- [HttpGet("faq/{code}")]
- public async Task<ResultDto> Faq([FromRoute] string code, string? search = null)
- {
- try
- {
- string cacheKey = $"{RedisConst.FaqKey}-{code}";
- await _redisRepository.DeleteAsync(cacheKey);
- var faqItems = await _redisRepository.GetObjectAsync<List<object>>(cacheKey);
- if (faqItems == null)
- {
- var query = _db.FaqItem
- .Include(f => f.FaqCategory)
- .Where(f => f.FaqCategory.Code == code && f.FaqCategory.IsActive && f.IsActive);
- if (!string.IsNullOrEmpty(search))
- {
- query = query.Where(f => f.Question.Contains(search) || f.Answer.Contains(search));
- }
- faqItems = await query
- .OrderBy(f => f.Order)
- .Select(f => (object)new
- {
- f.ID,
- f.Question,
- f.Answer,
- f.Order,
- f.IsActive,
- CategoryCode = f.FaqCategory.Code,
- CategorySubject = f.FaqCategory.Subject
- })
- .ToListAsync();
- await _redisRepository.SetObjectAsync(cacheKey, faqItems, RedisConst.CacheExpiration);
- }
- if (faqItems == null || !faqItems.Any())
- {
- throw new Exception("해당하는 FAQ 목록이 존재하지 않습니다.");
- }
- _result.Data = faqItems;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- // 팝업 조회
- [HttpGet("popup")]
- public async Task<ResultDto> Popup()
- {
- try
- {
- string cacheKey = RedisConst.PopupKey;
- var popups = await _redisRepository.GetObjectAsync<List<object>>(cacheKey);
- if (popups is null)
- {
- var now = DateTime.UtcNow;
- popups = await _db.Popup.Where(c => c.IsActive && (c.StartAt == null || c.StartAt <= now) && (c.EndAt == null || c.EndAt.Value.Date >= now.Date))
- .OrderBy(c => c.Order)
- .Select(c => (object)new
- {
- c.ID,
- c.Subject,
- c.Content,
- c.Link
- })
- .ToListAsync();
- await _redisRepository.SetObjectAsync(cacheKey, popups, RedisConst.CacheExpiration);
- }
- if (popups is null)
- {
- throw new Exception("팝업이 존재하지 않습니다.");
- }
- _result.Data = popups;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- [HttpGet("banner/{code}")]
- public async Task<ResultDto> Banner([FromRoute] string code)
- {
- try
- {
- string cacheKey = RedisConst.BannerKey;
- var banners = await _redisRepository.GetObjectAsync<List<object>>(cacheKey);
- if (banners == null)
- {
- var now = DateTime.UtcNow;
- banners = await _db.BannerItem
- .Include(c => c.BannerPosition)
- .Where(c => c.BannerPosition.Code == code && c.BannerPosition.IsActive && (c.StartAt == null || c.StartAt <= now) && (c.EndAt == null || c.EndAt.Value.Date >= now.Date))
- .Where(c => c.IsActive)
- .OrderBy(c => c.Order)
- .Select(c => (object)new
- {
- c.ID,
- c.Subject,
- c.Image,
- c.Width,
- c.Height,
- c.Link,
- PositionID = c.BannerPosition.Code,
- PositionName = c.BannerPosition.Subject
- })
- .ToListAsync();
- await _redisRepository.SetObjectAsync(cacheKey, banners, RedisConst.CacheExpiration);
- }
- if (banners == null || !banners.Any())
- {
- throw new Exception("해당하는 배너가 존재하지 않습니다.");
- }
- _result.Data = banners;
- }
- catch (Exception e)
- {
- _logger.LogError(e, e.Message);
- _result.Ok = false;
- _result.Status = StatusCodes.Status400BadRequest;
- _result.Message = e.Message;
- }
- return _result;
- }
- }
- }
|