using AcaMate.Common.Models; using AcaMate.V1.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Update.Internal; using AcaMate.Common.Data; using AcaMate.V1.Services; using Microsoft.AspNetCore.Http.HttpResults; namespace AcaMate.V1.Controllers; [ApiController] [Route("/api/v1/in/push")] [ApiExplorerSettings(GroupName = "공통")] public class PushController : ControllerBase { private readonly ILogger _logger; private readonly IPushQueue _pushQueue; private readonly AppDbContext _dbContext; private readonly IRepositoryService _repositoryService; public PushController(ILogger logger, IPushQueue pushQueue, AppDbContext dbContext, IRepositoryService repositoryService) { _logger = logger; _pushQueue = pushQueue; _dbContext = dbContext; _repositoryService = repositoryService; } [HttpGet()] [CustomOperation("푸시 확인", "저장된 양식을 확인 할 수 있다..", "푸시")] public async Task GetPush(string? pid) { if (pid != null) { var pushData = await _dbContext.DBPayload .Where(p => p.pid == pid) .FirstOrDefaultAsync(); } else { } try { } catch (Exception ex) { _logger.LogError($"[푸시] {ex.Message}"); return StatusCode(500, APIResponse.UnknownError()); } return Ok("SEND"); } /// /// Sends a push notification to the specified device token with the provided payload. /// /// /// An IActionResult indicating the result of the operation. /// Push notification sent successfully. /// Invalid input parameters. /// Internal server error occurred. /// Service unavailable. [HttpPost("send")] [CustomOperation("푸시전송", "저장된 양식으로, 사용자에게 푸시를 전송한다.", "푸시")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus))] public async Task SendPush([FromBody] PushRequest pushRequest) { if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError()); try { var payload = await _dbContext.DBPayload .Where(p => p.pid == pushRequest.pid && p.bid == pushRequest.bid ) .Select(p => new Payload { aps = new Aps { alert = new Alert { title = p.title, body = p.body, subtitle = p.subtitle ?? "" }, category = p.category }, pid = pushRequest.pid, bid = pushRequest.bid, content = p.content ?? "", }) .FirstOrDefaultAsync(); await Task.Run(async () => { foreach (var uid in pushRequest.uids) { if ( await _dbContext.UserAcademy .Where(ua => ua.uid == uid && ua.bid == pushRequest.bid) .AnyAsync() ) { var badge = await _dbContext.PushCabinet .Where(c => c.uid == uid && c.bid == pushRequest.bid && c.pid != pushRequest.pid && c.check_yn == false ) .CountAsync(); var pushToken = await _dbContext.User .Where(u => u.uid == uid) .Select(u => u.push_token) .FirstOrDefaultAsync() ?? ""; var pushCabinet = new PushCabinet { uid = uid, bid = pushRequest.bid, pid = pushRequest.pid, send_date = DateTime.Now, }; if (payload != null) payload.aps.badge = badge + 1; var pushData = new PushData { pushToken = pushToken, payload = payload ?? throw new PushInvalidException("payload is NULL") }; await _repositoryService.SaveDataFK(pushCabinet); _pushQueue.Enqueue(pushData); } } }); return Ok(APIResponse.Send("000", "정상", Empty)); } catch (PushInvalidException ex) { _logger.LogError(ex.Message); return Ok(APIResponse.Send("001", "푸시 송신: 푸시 전송 중 문제 발생",Empty)); } catch (Exception ex) { _logger.LogError($"[푸시] {ex.Message}"); return StatusCode(500, APIResponse.UnknownError()); } } [HttpPost("set")] [CustomOperation("푸시내용 변경", "저장된 양식을 변경한다.", "푸시")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus))] public async Task SetPush([FromBody] DBPayload request) { if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError()); try { var dbPayload = await _dbContext.DBPayload .FirstOrDefaultAsync(p => p.pid == request.pid && p.bid == request.bid); if (dbPayload != null) { if (dbPayload.title != request.title && request.title != "") dbPayload.title = request.title; if (dbPayload.body != request.body && request.body != "") dbPayload.body = request.body; if (dbPayload.subtitle != request.subtitle) dbPayload.subtitle = request.subtitle; if (dbPayload.alert_yn != request.alert_yn) dbPayload.alert_yn = request.alert_yn; if (dbPayload.category != request.category && request.category != "") dbPayload.category = request.category; if (dbPayload.content != request.content) dbPayload.content = request.content; if (await _repositoryService.SaveData(dbPayload, p => p.pid)) return Ok(APIResponse.Send("000", "PUSH 정보 변경 완료", Empty)); } return Ok(APIResponse.Send("100", "PID, BID 또는 Cabinet 오류", Empty)); } catch (Exception ex) { _logger.LogError($"[푸시] {ex.Message}"); return StatusCode(500, APIResponse.UnknownError()); } } }// END PUSH CONTROLLER