297 lines
9.5 KiB
C#
297 lines
9.5 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
|
|
|
|
namespace BrokerCore.Repository;
|
|
|
|
using Common;
|
|
|
|
using DbEntity;
|
|
|
|
using Context;
|
|
|
|
public class PlanetItemExchangeOrderRepo
|
|
{
|
|
private readonly MetaverseBrokerDbContext m_db_context;
|
|
|
|
public PlanetItemExchangeOrderRepo(MetaverseBrokerDbContext dbContext)
|
|
{
|
|
m_db_context = dbContext;
|
|
}
|
|
|
|
//================================================================================
|
|
// 교환 주문을 추가한다.
|
|
// 트랜잭션을 사용한다.
|
|
//================================================================================
|
|
public async Task<Result> add(PlanetItemExchangeOrder order, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
m_db_context.PlanetItemExchangeOrders.Add(order);
|
|
await m_db_context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message };
|
|
}
|
|
|
|
return new Result();
|
|
}
|
|
// public async Task<Result> add(PlanetItemExchangeOrder order,
|
|
// CancellationToken cancellationToken = default)
|
|
// {
|
|
// var result = new Result();
|
|
//
|
|
// // 실행 전략 생성
|
|
// var strategy = m_db_context.Database.CreateExecutionStrategy();
|
|
//
|
|
// // 실행 전략을 사용하여 트랜잭션 작업을 실행
|
|
// await strategy.ExecuteAsync(async () =>
|
|
// {
|
|
// // 트랜잭션 시작
|
|
// await using var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken);
|
|
// try
|
|
// {
|
|
// var order_date_utc = order.CreatedAt.ToUniversalTime().Date; // UTC 기준 주문일의 자정(00:00:00)
|
|
//
|
|
// // 단일 쿼리로 total_exchange_count와 user_exchange_count를 함께 조회
|
|
// var exchange_counts = await m_db_context.PlanetItemExchangeOrders
|
|
// .Where(x => x.PlanetId == order.PlanetId &&
|
|
// x.ExchangeMetaId == order.ExchangeMetaId &&
|
|
// x.CreatedAt >= order_date_utc && x.CreatedAt < order_date_utc.AddDays(1))
|
|
// .GroupBy(x => 1)
|
|
// .Select(g => new
|
|
// {
|
|
// TotalCount = g.Sum(x => x.ExchangeMetaAmount),
|
|
// UserCount = g.Where(x => x.UserGuid == order.UserGuid).Sum(x => x.ExchangeMetaAmount)
|
|
// })
|
|
// .FirstOrDefaultAsync(cancellationToken);
|
|
//
|
|
// var total_exchange_count = exchange_counts?.TotalCount ?? 0;
|
|
// var user_exchange_count = exchange_counts?.UserCount ?? 0;
|
|
//
|
|
// if (total_exchange_count + order.ExchangeMetaAmount > dailyLimit)
|
|
// {
|
|
// result.setFail(ServerErrorCode.ExchangeTotalOrderDailyLimitExceeded,
|
|
// $"일일 총 구매 제한 초과 => {order.ExchangeMetaId} Total exchange count {total_exchange_count} + order amount {order.ExchangeMetaAmount} > daily total limit {dailyLimit}");
|
|
// return;
|
|
// }
|
|
//
|
|
// if (user_exchange_count + order.ExchangeMetaAmount > dailyUserLimit)
|
|
// {
|
|
// result.setFail(ServerErrorCode.ExchangeUserOrderDailyLimitExceeded,
|
|
// $"일일 개인 구매 제한 초과 => {order.ExchangeMetaId} User exchange count {user_exchange_count} + order amount {order.ExchangeMetaAmount} > daily user limit {dailyUserLimit}");
|
|
// return;
|
|
// }
|
|
//
|
|
// m_db_context.PlanetItemExchangeOrders.Add(order);
|
|
// m_
|
|
//
|
|
// await m_db_context.SaveChangesAsync(cancellationToken);
|
|
// await transaction.CommitAsync(cancellationToken);
|
|
// }
|
|
// catch (Exception e)
|
|
// {
|
|
// result.setFail(ServerErrorCode.InternalServerError, e.Message);
|
|
// }
|
|
// });
|
|
//
|
|
// return result;
|
|
// }
|
|
|
|
public async Task<Result> delete(PlanetItemExchangeOrder order, CancellationToken cancellationToken = default)
|
|
{
|
|
var result = new Result();
|
|
try
|
|
{
|
|
m_db_context.PlanetItemExchangeOrders.Remove(order);
|
|
await m_db_context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.setFail(ServerErrorCode.InternalServerError, e.Message);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//================================================================================
|
|
// 교환 주문을 비동기로 업데이트한다.
|
|
// OrderId를 키로 사용한다.
|
|
// OrderType과 OrderCompletedAt만 업데이트한다.
|
|
//================================================================================
|
|
public async Task<(Result, PlanetItemExchangeOrder?)> findAndUpdateStatus(string orderId,
|
|
ExchangeOrderStatus orderStatus,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var result = new Result();
|
|
try
|
|
{
|
|
var order = await m_db_context.PlanetItemExchangeOrders.Where(x => x.OrderId == orderId)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
if (order == null)
|
|
{
|
|
result.setFail(ServerErrorCode.ExchangeOrderIdNotFound, $"Order not found: {orderId}");
|
|
return (result, null);
|
|
}
|
|
order.OrderStatus = orderStatus;
|
|
order.CompletedAt = DateTime.UtcNow;
|
|
m_db_context.PlanetItemExchangeOrders.Attach(order);
|
|
m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
|
|
m_db_context.Entry(order).Property(x => x.CompletedAt).IsModified = true;
|
|
await m_db_context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
|
return (new Result(), order);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// await transaction.RollbackAsync(cancellationToken).ConfigureAwait(false);
|
|
return (new Result { ResultString = e.Message }, null);
|
|
}
|
|
}
|
|
|
|
public async Task<(Result, PlanetItemExchangeOrder?)> findOne(string orderId,
|
|
ExchangeOrderStatus orderStatus,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var order = await m_db_context.PlanetItemExchangeOrders
|
|
.Where(x => x.OrderId == orderId && x.OrderStatus == orderStatus)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
return (new Result(), order);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return (new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message }, null);
|
|
}
|
|
}
|
|
|
|
// public async Task<Result> updateForPending(SapphireExchangeOrder order,
|
|
// CancellationToken cancellationToken = default)
|
|
// {
|
|
// // await using var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken);
|
|
// try
|
|
// {
|
|
// m_db_context.SapphireExchangeOrders.Attach(order);
|
|
// m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
|
|
// await m_db_context.SaveChangesAsync(cancellationToken);
|
|
// // await transaction.CommitAsync(cancellationToken);
|
|
// return new Result();
|
|
// }
|
|
// catch (Exception e)
|
|
// {
|
|
// // await transaction.RollbackAsync(cancellationToken);
|
|
// return new Result { ResultString = e.Message };
|
|
// }
|
|
// }
|
|
//==========================================================================
|
|
//SELECT *
|
|
// FROM `sapphire_exchange_order`
|
|
// WHERE `PlanetId` = @planetId
|
|
// AND `UserGuid` = @userGuid
|
|
// AND (@orderStatus IS NULL OR `OrderStatus` = @orderStatus)
|
|
// ORDER BY `CreatedAt` ASC
|
|
// LIMIT @pageSize OFFSET @offset;
|
|
//==========================================================================
|
|
public async Task<(Result, IEnumerable<PlanetItemExchangeOrder>?, int)> findList(
|
|
string planetId,
|
|
string metaId,
|
|
string seasonId,
|
|
string userGuid,
|
|
ExchangeOrderStatus? orderStatus = null,
|
|
int pageIndex = 1,
|
|
int pageSize = 20,
|
|
string sortOrder = "asc",
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var result = new Result();
|
|
try
|
|
{
|
|
var query = m_db_context.PlanetItemExchangeOrders.AsQueryable();
|
|
|
|
if (!string.IsNullOrEmpty(planetId))
|
|
{
|
|
query = query.Where(x => x.PlanetId == planetId);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(metaId))
|
|
{
|
|
query = query.Where(x => x.ExchangeMetaId == metaId);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(seasonId))
|
|
{
|
|
query = query.Where(x => x.SeasonId == seasonId);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(userGuid))
|
|
{
|
|
query = query.Where(x => x.UserGuid == userGuid);
|
|
}
|
|
|
|
if (orderStatus.HasValue)
|
|
{
|
|
query = query.Where(x => x.OrderStatus == orderStatus);
|
|
}
|
|
|
|
query = sortOrder.ToLower() == "desc"
|
|
? query.OrderByDescending(o => o.CreatedAt)
|
|
: query.OrderBy(o => o.CreatedAt);
|
|
|
|
var orders = await query
|
|
.Skip((pageIndex - 1) * pageSize)
|
|
.Take(pageSize)
|
|
.ToArrayAsync(cancellationToken);
|
|
|
|
var total_count = await query.CountAsync(cancellationToken);
|
|
return (result, orders, total_count);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.setFail(ServerErrorCode.RdbError, e.Message);
|
|
return (result, null, 0);
|
|
}
|
|
}
|
|
|
|
//================================================================================
|
|
// 사파이어 교환 주문 목록을 비동기로 조회한다.
|
|
// OrderType과 PlanetId로 검색한다.
|
|
// Result, IEnumerable<>를 반환한다.
|
|
// 조건에 맞는 값이 없다면 빈 배열을 반환한다.
|
|
//================================================================================
|
|
public async Task<PaginatedList<PlanetItemExchangeOrder>> findPlanetItemExchangeOrders(int pageIndex, int pageSize)
|
|
{
|
|
var query = m_db_context.Set<PlanetItemExchangeOrder>().AsNoTracking();
|
|
|
|
var count = await query.CountAsync();
|
|
var items = await query
|
|
.OrderBy(o => o.CreatedAt)
|
|
.Skip((pageIndex - 1) * pageSize)
|
|
.Take(pageSize)
|
|
.ToListAsync();
|
|
|
|
return new PaginatedList<PlanetItemExchangeOrder>(items, count, pageIndex, pageSize);
|
|
}
|
|
|
|
public class PaginatedList<T> : List<T>
|
|
{
|
|
public int PageIndex { get; private set; }
|
|
public int TotalPages { get; private set; }
|
|
public int TotalCount { get; private set; }
|
|
|
|
public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
|
|
{
|
|
PageIndex = pageIndex;
|
|
TotalCount = count;
|
|
|
|
this.AddRange(items);
|
|
}
|
|
|
|
public bool HasPreviousPage => PageIndex > 1;
|
|
public bool HasNextPage => PageIndex < TotalPages;
|
|
}
|
|
}
|