feat: 배너 목록 API 구현 (#80) #81
32
SPMS.API/Controllers/BannerController.cs
Normal file
32
SPMS.API/Controllers/BannerController.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using SPMS.Application.DTOs.Banner;
|
||||
using SPMS.Application.Interfaces;
|
||||
using SPMS.Domain.Common;
|
||||
|
||||
namespace SPMS.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("v1/in/public/banner")]
|
||||
[ApiExplorerSettings(GroupName = "public")]
|
||||
public class BannerController : ControllerBase
|
||||
{
|
||||
private readonly IBannerService _bannerService;
|
||||
|
||||
public BannerController(IBannerService bannerService)
|
||||
{
|
||||
_bannerService = bannerService;
|
||||
}
|
||||
|
||||
[HttpPost("list")]
|
||||
[SwaggerOperation(Summary = "배너 목록", Description = "활성화된 배너 목록을 조회합니다. position으로 필터링 가능.")]
|
||||
public async Task<IActionResult> GetListAsync([FromBody] BannerListRequestDto request)
|
||||
{
|
||||
var serviceCode = Request.Headers["X-Service-Code"].FirstOrDefault();
|
||||
if (string.IsNullOrWhiteSpace(serviceCode))
|
||||
return BadRequest(ApiResponse.Fail(ErrorCodes.BadRequest, "X-Service-Code 헤더가 필요합니다."));
|
||||
|
||||
var result = await _bannerService.GetListAsync(serviceCode, request);
|
||||
return Ok(ApiResponse<BannerListResponseDto>.Success(result));
|
||||
}
|
||||
}
|
||||
6
SPMS.Application/DTOs/Banner/BannerListRequestDto.cs
Normal file
6
SPMS.Application/DTOs/Banner/BannerListRequestDto.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace SPMS.Application.DTOs.Banner;
|
||||
|
||||
public class BannerListRequestDto
|
||||
{
|
||||
public string? Position { get; set; }
|
||||
}
|
||||
36
SPMS.Application/DTOs/Banner/BannerListResponseDto.cs
Normal file
36
SPMS.Application/DTOs/Banner/BannerListResponseDto.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SPMS.Application.DTOs.Banner;
|
||||
|
||||
public class BannerListResponseDto
|
||||
{
|
||||
[JsonPropertyName("items")]
|
||||
public List<BannerItemDto> Items { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("total_count")]
|
||||
public int TotalCount { get; set; }
|
||||
}
|
||||
|
||||
public class BannerItemDto
|
||||
{
|
||||
[JsonPropertyName("banner_id")]
|
||||
public long BannerId { get; set; }
|
||||
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("image_url")]
|
||||
public string ImageUrl { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("link_url")]
|
||||
public string? LinkUrl { get; set; }
|
||||
|
||||
[JsonPropertyName("link_type")]
|
||||
public string? LinkType { get; set; }
|
||||
|
||||
[JsonPropertyName("position")]
|
||||
public string Position { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("sort_order")]
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ public static class DependencyInjection
|
|||
services.AddScoped<IAccountService, AccountService>();
|
||||
services.AddScoped<IServiceManagementService, ServiceManagementService>();
|
||||
services.AddScoped<INoticeService, NoticeService>();
|
||||
services.AddScoped<IBannerService, BannerService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
|
|
|||
8
SPMS.Application/Interfaces/IBannerService.cs
Normal file
8
SPMS.Application/Interfaces/IBannerService.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using SPMS.Application.DTOs.Banner;
|
||||
|
||||
namespace SPMS.Application.Interfaces;
|
||||
|
||||
public interface IBannerService
|
||||
{
|
||||
Task<BannerListResponseDto> GetListAsync(string serviceCode, BannerListRequestDto request);
|
||||
}
|
||||
43
SPMS.Application/Services/BannerService.cs
Normal file
43
SPMS.Application/Services/BannerService.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using SPMS.Application.DTOs.Banner;
|
||||
using SPMS.Application.Interfaces;
|
||||
using SPMS.Domain.Common;
|
||||
using SPMS.Domain.Exceptions;
|
||||
using SPMS.Domain.Interfaces;
|
||||
|
||||
namespace SPMS.Application.Services;
|
||||
|
||||
public class BannerService : IBannerService
|
||||
{
|
||||
private readonly IBannerRepository _bannerRepository;
|
||||
private readonly IServiceRepository _serviceRepository;
|
||||
|
||||
public BannerService(IBannerRepository bannerRepository, IServiceRepository serviceRepository)
|
||||
{
|
||||
_bannerRepository = bannerRepository;
|
||||
_serviceRepository = serviceRepository;
|
||||
}
|
||||
|
||||
public async Task<BannerListResponseDto> GetListAsync(string serviceCode, BannerListRequestDto request)
|
||||
{
|
||||
var service = await _serviceRepository.GetByServiceCodeAsync(serviceCode);
|
||||
if (service == null)
|
||||
throw new SpmsException(ErrorCodes.NotFound, "존재하지 않는 서비스입니다.", 404);
|
||||
|
||||
var items = await _bannerRepository.GetActiveListAsync(service.Id, request.Position);
|
||||
|
||||
return new BannerListResponseDto
|
||||
{
|
||||
Items = items.Select(b => new BannerItemDto
|
||||
{
|
||||
BannerId = b.Id,
|
||||
Title = b.Title,
|
||||
ImageUrl = b.ImageUrl,
|
||||
LinkUrl = b.LinkUrl,
|
||||
LinkType = b.LinkType,
|
||||
Position = b.Position,
|
||||
SortOrder = b.SortOrder
|
||||
}).ToList(),
|
||||
TotalCount = items.Count
|
||||
};
|
||||
}
|
||||
}
|
||||
8
SPMS.Domain/Interfaces/IBannerRepository.cs
Normal file
8
SPMS.Domain/Interfaces/IBannerRepository.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using SPMS.Domain.Entities;
|
||||
|
||||
namespace SPMS.Domain.Interfaces;
|
||||
|
||||
public interface IBannerRepository : IRepository<Banner>
|
||||
{
|
||||
Task<IReadOnlyList<Banner>> GetActiveListAsync(long serviceId, string? position = null);
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ public static class DependencyInjection
|
|||
services.AddScoped<IServiceRepository, ServiceRepository>();
|
||||
services.AddScoped<IAdminRepository, AdminRepository>();
|
||||
services.AddScoped<INoticeRepository, NoticeRepository>();
|
||||
services.AddScoped<IBannerRepository, BannerRepository>();
|
||||
|
||||
// External Services
|
||||
services.AddScoped<IJwtService, JwtService>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using SPMS.Domain.Entities;
|
||||
using SPMS.Domain.Interfaces;
|
||||
|
||||
namespace SPMS.Infrastructure.Persistence.Repositories;
|
||||
|
||||
public class BannerRepository : Repository<Banner>, IBannerRepository
|
||||
{
|
||||
public BannerRepository(AppDbContext context) : base(context) { }
|
||||
|
||||
public async Task<IReadOnlyList<Banner>> GetActiveListAsync(long serviceId, string? position = null)
|
||||
{
|
||||
var query = _dbSet.Where(b => b.ServiceId == serviceId && b.IsActive);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(position))
|
||||
query = query.Where(b => b.Position == position);
|
||||
|
||||
return await query
|
||||
.OrderBy(b => b.SortOrder)
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user