AcaMate_API/Program/V1/Controllers/UserController.cs

291 lines
9.4 KiB
C#

using AcaMate.Common.Data;
using AcaMate.Common.Models;
using AcaMate.V1.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using AcaMate.V1.Services;
using AcaMate.Common.Token;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore.Query;
using MySqlConnector;
namespace AcaMate.V1.Controllers;
[ApiController]
[Route("/api/v1/in/user")]
[ApiExplorerSettings(GroupName = "사용자")]
public class UserController : ControllerBase
{
private readonly AppDbContext _dbContext;
private readonly ILogger<UserController> _logger;
private readonly JwtTokenService _jwtTokenService;
public UserController(AppDbContext dbContext, ILogger<UserController> logger, JwtTokenService jwtTokenService)
{
_dbContext = dbContext;
_logger = logger;
_jwtTokenService = jwtTokenService;
}
[HttpGet]
[CustomOperation("회원 정보 조회", "회원 정보 조회", "사용자")]
public IActionResult GetUserData(string uid)
{
if (string.IsNullOrEmpty(uid)) return BadRequest(DefaultResponse.InvalidInputError);
try
{
var user = _dbContext.User
.Where(u => u.uid == uid)
.Select(u => new User
{
uid = u.uid,
name = u.name,
auto_login_yn = u.auto_login_yn,
birth = u.birth,
device_id = u.device_id,
login_date = u.login_date,
type = u.type
})
.FirstOrDefault();
var response = new APIResponseStatus<User>
{
status = new Status
{
code = "000",
message = "정상"
},
data = user
};
return Ok(response.JsonToString());
}
catch (Exception ex)
{
return StatusCode(500, DefaultResponse.UnknownError);
}
}
[HttpGet("login")]
[CustomOperation("SNS 로그인", "로그인 후 회원이 있는지 확인", "사용자")]
public IActionResult Login(string acctype, string sns_id)
{
if (string.IsNullOrEmpty(acctype) && string.IsNullOrEmpty(sns_id))
return BadRequest(DefaultResponse.InvalidInputError);
try
{
var login = _dbContext.Login.FirstOrDefault(l => l.sns_type == acctype && l.sns_id == sns_id);
var uid = "";
List<string> bids = new List<string>();
if (login != null)
{
uid = login.uid;
var user = _dbContext.User.FirstOrDefault(user => user.uid == uid);
if (user != null)
{
user.login_date = DateTime.Now;
_dbContext.SaveChanges();
}
// 토큰 생성은 로그인 부분에서 하는거지
var accessToken = _jwtTokenService.GenerateJwtToken(uid, "Normal");
var refreshToken = _jwtTokenService.GenerateRefreshToken(uid);
_dbContext.RefreshTokens.Add(refreshToken);
_dbContext.SaveChanges();
var userAcademy = _dbContext.UserAcademy.Where(u => u.uid == uid).ToList();
foreach (var userData in userAcademy)
{
_logger.LogInformation($"uid: {userData.uid} || bid: {userData.bid}");
bids.Add(userData.bid);
}
var response = new APIResponseStatus<dynamic>
{
status = new Status
{
code = "000",
message = "정상"
},
data = new
{
uid = $"{uid}",
bid = bids
}
};
return Ok(response.JsonToString());
}
else
{
// 계정이 없다는 거
var response = new APIResponseStatus<dynamic>
{
status = new Status
{
code = "010",
message = "정상"
},
data = new
{
uid = "",
bid = new string[] { }
}
};
return Ok(response.JsonToString());
}
}
catch (Exception ex)
{
return StatusCode(500, DefaultResponse.UnknownError);
}
}
[HttpPost("academy")]
[CustomOperation("학원 리스트 확인", "등록된 학원 리스트 확인", "사용자")]
public IActionResult ReadAcademyInfo([FromBody] RequestAcademy request)
{
if (!request.bids.Any())
{
var error = DefaultResponse.InvalidInputError;
return Ok(error);
}
var academies = _dbContext
.Academy
.Where(a => request.bids.Contains(a.bid))
.Select(a => new AcademyName
{
bid = a.bid,
name = a.business_name
})
.ToList();
var response = new APIResponseStatus<List<AcademyName>>
{
status = new Status
{
code = "000",
message = "정상"
},
data = academies
};
return Ok(response);
}
[HttpPost("register")]
[CustomOperation("회원 가입", "사용자 회원 가입", "사용자")]
public async Task<IActionResult> UserRegister([FromBody] UserAll request)
{
if (!ModelState.IsValid) return BadRequest(DefaultResponse.InvalidInputError);
var atIndext = request.email.IndexOf('@');
var localPart_email = request.email.Substring(0, atIndext);
var uid = $"AM{localPart_email}{DateTime.Now:yyyyMMdd}";
var user = new User
{
uid = uid,
name = request.name,
birth = request.birth,
type = request.type,
device_id = request.device_id,
auto_login_yn = request.auto_login_yn,
login_date = request.login_date
};
var login = new Login
{
uid = uid,
sns_id = request.sns_id,
sns_type = request.sns_type
};
var permission = new Permission
{
uid = uid,
location_yn = request.location_yn,
camera_yn = request.camera_yn,
photo_yn = request.photo_yn,
push_yn = request.push_yn,
market_app_yn = request.market_app_yn,
market_sms_yn = request.market_sms_yn,
market_email_yn = request.market_email_yn
};
var contact = new Contact
{
uid = uid,
email = request.email,
phone = request.phone,
address = request.address
};
if (await SaveData<User, string>(user, u => u.uid))
{
await SaveData<Login, string>(login, l => l.sns_id);
await SaveData<Permission, string>(permission, p => p.uid);
await SaveData<Contact, string>(contact, c => c.uid);
}
// TO-DO: jwt 토큰 만들어서 여기서 보내는 작업을 해야 함
return Ok($"회원가입 : {uid}");
}
private async Task<bool> SaveData<T, K> (T entity, Expression<Func<T, K>> key) where T : class
{
try
{
var value = key.Compile()(entity);
// x 라 함은 Expression 으로 생성되는 트리에서 T 타입으의 매개변수를 지칭함
var parameter = Expression.Parameter(typeof(T), "x");
var invokedExpr = Expression.Invoke(key, parameter);
var constantExpr = Expression.Constant(value, key.Body.Type);
var equalsExpr = Expression.Equal(invokedExpr, constantExpr);
var predicate = Expression.Lambda<Func<T, bool>>(equalsExpr, parameter);
var dbSet = _dbContext.Set<T>();
var entityData = await dbSet.FirstOrDefaultAsync(predicate);
if (entityData != null)
{
_logger.LogInformation($"[{typeof(T)}] 해당 PK 존재 [{value}]: 계속");
var entry = _dbContext.Entry(entityData);
entry.CurrentValues.SetValues(entity);
if (entry.Properties.Any(p => p.IsModified))
{
_logger.LogInformation($"[{typeof(T)}] 변경사항 존재: 계속");
}
else
{
_logger.LogInformation($"[{typeof(T)}] 변경사항 없음: 종료");
return true;
}
}
else
{
dbSet.Add(entity);
}
await _dbContext.SaveChangesAsync();
_logger.LogInformation($"[{typeof(T)}] DB 저장 완료: 종료");
return true;
}
catch (Exception ex)
{
_logger.LogInformation($"[{typeof(T)}] 알 수 없는 오류: 종료\n{ex}");
return false;
}
}
}