forked from AcaMate/AcaMate_API
482 lines
21 KiB
C#
482 lines
21 KiB
C#
|
|
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Update.Internal;
|
|
using Microsoft.AspNetCore.Http.HttpResults;
|
|
|
|
|
|
using AcaMate.Common.Data;
|
|
using AcaMate.V1.Services;
|
|
using AcaMate.Common.Models;
|
|
using AcaMate.Common.Token;
|
|
using AcaMate.V1.Models;
|
|
|
|
|
|
namespace AcaMate.V1.Controllers;
|
|
|
|
|
|
[ApiController]
|
|
[Route("/api/v1/in/push")]
|
|
[ApiExplorerSettings(GroupName = "공통")]
|
|
public class PushController : ControllerBase
|
|
{
|
|
private readonly ILogger<PushController> _logger;
|
|
private readonly IPushQueue _pushQueue;
|
|
private readonly AppDbContext _dbContext;
|
|
private readonly IRepositoryService _repositoryService;
|
|
private readonly JwtTokenService _jwtTokenService;
|
|
public PushController(ILogger<PushController> logger, IPushQueue pushQueue, AppDbContext dbContext, IRepositoryService repositoryService, JwtTokenService jwtTokenService)
|
|
{
|
|
_logger = logger;
|
|
_pushQueue = pushQueue;
|
|
_dbContext = dbContext;
|
|
_repositoryService = repositoryService;
|
|
_jwtTokenService = jwtTokenService;
|
|
}
|
|
|
|
// 추가 사항
|
|
// 카테고리 별 조회 하는 부분도 추가를 할 지 고민을 해야 할 것 같음
|
|
|
|
[HttpGet()]
|
|
[CustomOperation("푸시 확인", "저장된 양식을 확인 할 수 있다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> GetPush(string bid, string? pid, string? category)
|
|
{
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "GetPush");
|
|
|
|
if (!(await _dbContext.Academy.AnyAsync(a=>a.bid == bid)))
|
|
return Ok(APIResponse.Send("100", $"[{summary}], 존재하지 않는 BID", Empty));
|
|
|
|
List<DBPayload> pushData = new List<DBPayload>();
|
|
var pushQuery = _dbContext.DBPayload.Where(p => p.bid == bid);
|
|
if (pid != null)
|
|
pushQuery = pushQuery.Where(p=>p.pid == pid);
|
|
if (category != null)
|
|
pushQuery = pushQuery.Where(p=>p.category == category);
|
|
pushData = await pushQuery.ToListAsync();
|
|
|
|
if (pushData.Count > 0)
|
|
{
|
|
return Ok(APIResponse.Send("000", $"[{summary}, 정상", pushData));
|
|
}
|
|
|
|
return Ok(APIResponse.Send("001", $"[{summary}], PUSH 데이터 없음", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return StatusCode(500, APIResponse.UnknownError());
|
|
}
|
|
}
|
|
|
|
|
|
[HttpPost("send")]
|
|
[CustomOperation("푸시 발송", "저장된 양식으로, 사용자에게 푸시를 송신한다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> SendPush([FromBody] PushRequest pushRequest)
|
|
{
|
|
string summary = String.Empty;
|
|
try {
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "SendPush");
|
|
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
|
|
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 = pushRequest.content ?? (p.content ?? ""),
|
|
})
|
|
.FirstOrDefaultAsync();
|
|
|
|
await Task.Run(async () =>
|
|
{
|
|
if (payload == null)
|
|
throw new PushInvalidException("payload is NULL");
|
|
|
|
foreach (var uid in pushRequest.uids)
|
|
{
|
|
// 학원 내부에 해당 uid의 일원이 존재하는지 확인
|
|
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.check_yn == false)
|
|
.CountAsync();
|
|
payload.aps.badge = badge + 1;
|
|
|
|
// 푸시를 보내야 하니 푸시 토큰 확인
|
|
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,
|
|
content = payload.content != "" ? payload.content : null,
|
|
};
|
|
|
|
var pushData = new PushData
|
|
{
|
|
pushToken = pushToken,
|
|
payload = payload
|
|
};
|
|
|
|
if (await _repositoryService.SaveData<PushCabinet>(pushCabinet))
|
|
{
|
|
var logPush = new LogPush
|
|
{
|
|
bid = pushRequest.bid,
|
|
pid = pushRequest.pid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = $"[{summary}] : 푸시 캐비닛 저장 성공"
|
|
};
|
|
if (await _repositoryService.SaveData<LogPush>(logPush))
|
|
_logger.LogInformation($"[{summary}] : 로그 추가");
|
|
}
|
|
|
|
_pushQueue.Enqueue(pushData);
|
|
}
|
|
else
|
|
{
|
|
// 존재하지 않는 경우에는 지나가서 다른 uid 로 확인 하겠지
|
|
var logPush = new LogPush
|
|
{
|
|
bid = pushRequest.bid,
|
|
pid = pushRequest.pid,
|
|
create_date = DateTime.Now,
|
|
create_uid = "System",
|
|
log = $"[{summary}] : 푸시 전송 실패"
|
|
};
|
|
if (await _repositoryService.SaveData<LogPush>(logPush))
|
|
_logger.LogInformation($"[{summary}] : 로그 추가");
|
|
}
|
|
|
|
}
|
|
});
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", Empty));
|
|
}
|
|
catch (PushInvalidException ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 푸시 송신 중 문제 발생",Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return StatusCode(500, APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
[HttpPost("set")]
|
|
[CustomOperation("푸시 변경", "저장된 양식을 변경한다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> SetPush(string token, [FromBody] DBPayload request)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
string uid = String.Empty;
|
|
|
|
try
|
|
{
|
|
if (token == "System") uid = "System";
|
|
else
|
|
{
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
}
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "SetPush");
|
|
var dbPayload = await _dbContext.DBPayload
|
|
.FirstOrDefaultAsync(p => p.pid == request.pid && p.bid == request.bid);
|
|
|
|
|
|
if (dbPayload != null)
|
|
{
|
|
var logPush = new LogPush
|
|
{
|
|
bid = dbPayload.bid,
|
|
pid = dbPayload.pid,
|
|
create_uid = uid,
|
|
create_date = DateTime.Now,
|
|
};
|
|
|
|
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>(dbPayload))
|
|
{
|
|
logPush.log = $"[{summary} : 정상 변경";
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", Empty));
|
|
}
|
|
|
|
// 로그를 이제 만들어서 추가를 해야 합니다.
|
|
if (await _repositoryService.SaveData<LogPush>(logPush))
|
|
_logger.LogInformation($"[{summary}] : 로그 추가");
|
|
}
|
|
|
|
return Ok(APIResponse.Send("100", $"[{summary}], PID, BID 또는 Cabinet 오류", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return StatusCode(500, APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
[HttpPost("create")]
|
|
[CustomOperation("푸시 생성", "새로운 푸시 양식을 생성한다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> CreatePush(string token, [FromBody] CreatePush request)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string summary = String.Empty;
|
|
string uid = "";
|
|
|
|
Func<string, int, string> randomLetter = (letters, count) => new string(Enumerable.Range(0, count).Select(_ => letters[new Random().Next(letters.Length)]).ToArray());
|
|
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
var digits = "0123456789";
|
|
var frontLetters = $"{randomLetter(letters, 1)}{randomLetter(digits, 1)}{randomLetter(letters, 1)}";
|
|
var afterLetters = $"{randomLetter(letters, 1)}{randomLetter(digits, 1)}{randomLetter(letters, 1)}";
|
|
|
|
try
|
|
{
|
|
if (token == "System") uid = "System";
|
|
else {
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
}
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "CreatePush");
|
|
|
|
if (await _dbContext.Academy.AnyAsync(a => a.bid == request.bid))
|
|
{
|
|
DBPayload payload = new DBPayload
|
|
{
|
|
bid = request.bid,
|
|
pid = $"AP{DateTime.Now:yyyyMMdd}{frontLetters}{DateTime.Now:HHmmss}{afterLetters}",
|
|
title = request.title,
|
|
subtitle = request.subtitle,
|
|
body = request.body,
|
|
alert_yn = request.alert_yn,
|
|
category = request.category,
|
|
content = request.content,
|
|
};
|
|
|
|
if (await _repositoryService.SaveData<DBPayload>(payload))
|
|
{
|
|
var logPush = new LogPush
|
|
{
|
|
bid = payload.bid,
|
|
pid = payload.pid,
|
|
create_uid = uid,
|
|
create_date = DateTime.Now,
|
|
log = $"[{summary}] : 정상 생성"
|
|
};
|
|
|
|
// 로그를 이제 만들어서 추가를 해야 합니다.
|
|
if (await _repositoryService.SaveData<LogPush>(logPush))
|
|
_logger.LogInformation($"[{summary}] : 로그 추가");
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", Empty));
|
|
}
|
|
|
|
}
|
|
return Ok(APIResponse.Send("100", $"[{summary}], 학원 정보(BID) 확인 불가", Empty));
|
|
}
|
|
catch (TokenException tokenEx)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {tokenEx}");
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 토큰에 문제가 있음",Empty));
|
|
}
|
|
catch (RefreshRevokeException refreshEx)
|
|
{
|
|
_logger.LogInformation($"[{summary}] : {refreshEx}");
|
|
return Ok(APIResponse.Send("001", $"[{summary}], 폐기된 리프레시 토큰",Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return StatusCode(500, APIResponse.UnknownError());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[HttpDelete("delete")]
|
|
[CustomOperation("푸시 삭제", "저장된 푸시 양식을 삭제 한다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> DeletePush(string token, string bid, string pid)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string uid = "";
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
if (token == "System") uid = "System";
|
|
else {
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
}
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "DeletePush");
|
|
|
|
var payload = await _dbContext.DBPayload.FirstOrDefaultAsync(p => p.bid == bid && p.pid == pid);
|
|
if (payload == null) return Ok(APIResponse.Send("001", $"[{summary}], 삭제 할 PUSH 없음", Empty));
|
|
if (!await _repositoryService.DeleteData<DBPayload>(payload)) return Ok(APIResponse.Send("002", $"[{summary}], PUSH 삭제 실패", Empty));
|
|
|
|
// 로그를 이제 만들어서 추가를 해야 합니다.
|
|
var logPush = new LogPush
|
|
{
|
|
bid = bid,
|
|
pid = pid,
|
|
create_uid = uid,
|
|
create_date = DateTime.Now,
|
|
log = $"[{summary}] : {pid} 삭제 - {uid}"
|
|
};
|
|
|
|
// 로그를 이제 만들어서 추가를 해야 합니다.
|
|
if (await _repositoryService.SaveData<LogPush>(logPush)) _logger.LogInformation($"[{summary}] : 로그 추가");
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return BadRequest(APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
|
|
[HttpDelete("delete/list")]
|
|
[CustomOperation("사용자 푸시 목록 삭제", "사용자가 받은 푸시목록에서 푸시를 삭제한다..", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> DeleteListPush(string token, int id)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string uid = "";
|
|
string summary = String.Empty;
|
|
try
|
|
{
|
|
if (token == "System") uid = "System";
|
|
else {
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
}
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "DeleteListPush");
|
|
var cabinetPush = await _dbContext.PushCabinet.FirstOrDefaultAsync(c => c.id == id);
|
|
if (cabinetPush == null) return Ok(APIResponse.Send("001", $"[{summary}], 삭제 할 PUSH 없음", Empty));
|
|
if (!await _repositoryService.DeleteData<PushCabinet>(cabinetPush))
|
|
return Ok(APIResponse.Send("002", $"[{summary}], PUSH 삭제 실패", Empty));
|
|
|
|
// // 로그를 이제 만들어서 추가를 해야 합니다.
|
|
var logPush = new LogPush
|
|
{
|
|
bid = cabinetPush.bid,
|
|
pid = cabinetPush.pid,
|
|
create_uid = uid,
|
|
create_date = DateTime.Now,
|
|
log = $"[{summary}] : {cabinetPush.pid} 삭제 - {uid}"
|
|
};
|
|
if (await _repositoryService.SaveData<LogPush>(logPush)) _logger.LogInformation($"[{summary}] : 로그 추가");
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", Empty));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return BadRequest(APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[HttpPost("list")]
|
|
[CustomOperation("사용자 푸시 목록 조회", "해당 사용자가 받은 푸시의 정보를 조회한다.", "푸시")]
|
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus<object>))]
|
|
public async Task<IActionResult> SearchToUserPush(string token, int size, [FromBody] PushCabinet? request)
|
|
{
|
|
if (string.IsNullOrEmpty(token)) return BadRequest(APIResponse.InvalidInputError());
|
|
if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError());
|
|
string uid = "";
|
|
string summary = String.Empty;
|
|
|
|
try
|
|
{
|
|
if (token == "System") uid = "System";
|
|
else {
|
|
var validateToken = await _jwtTokenService.ValidateToken(token);
|
|
if (validateToken == null) return Ok(APIResponse.AccessExpireError());
|
|
uid = validateToken.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
|
|
}
|
|
|
|
summary = _repositoryService.ReadSummary(typeof(PushController), "SearchToUserPush");
|
|
if (request == null)
|
|
{
|
|
var pagedData = await _dbContext.PushCabinet.Where(c => c.uid == uid)
|
|
.OrderBy(c=> c.send_date)
|
|
.Take(size)
|
|
.ToListAsync();
|
|
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", pagedData));
|
|
}
|
|
else
|
|
{
|
|
var sort = await _dbContext.PushCabinet.Where(p=> p.id == request.id)
|
|
.Select(p => p.send_date).FirstOrDefaultAsync();
|
|
var query = _dbContext.PushCabinet.OrderBy(c => c.send_date).AsQueryable();
|
|
query = query.Where(c => c.send_date > sort);
|
|
var pagedData = await query.Take(size).ToListAsync();
|
|
return Ok(APIResponse.Send("000", $"[{summary}], 정상", pagedData));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"[{summary}] : {ex.Message}");
|
|
return BadRequest(APIResponse.UnknownError(ex.Message));
|
|
}
|
|
}
|
|
|
|
|
|
}// END PUSH CONTROLLER
|
|
|
|
|
|
|
|
|
|
|