초기커밋
This commit is contained in:
285
UGQDataAccess/Repository/AccountRepository.cs
Normal file
285
UGQDataAccess/Repository/AccountRepository.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
using System.Drawing;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDataAccess.Repository.Query;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public enum AccountSortType
|
||||
{
|
||||
CreatedAtAsc,
|
||||
CreatedAtDesc,
|
||||
}
|
||||
|
||||
public class AccountRepository : BaseRepository<AccountEntity>
|
||||
{
|
||||
private const string CollectionName = "Account";
|
||||
|
||||
public AccountRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> getByAccountId(string accountId)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.AccountId, accountId);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> get(string userGuid)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<long> getAllCount()
|
||||
{
|
||||
var builder = Builders<AccountEntity>.Filter;
|
||||
var filter = builder.Empty;
|
||||
|
||||
var result = await Collection.Find(filter).CountDocumentsAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<AccountEntity> getOrInsertForGameUser(string userGuid)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.SetOnInsert(x => x.UserGuid, userGuid)
|
||||
.SetOnInsert(x => x.Nickname, "")
|
||||
.SetOnInsert(x => x.GradeType, UgqGradeType.Amature)
|
||||
.SetOnInsert(x => x.AdditionalSlotCount, 0)
|
||||
.SetOnInsert(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
IsUpsert = true,
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, option);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity> getOrInsert(string userGuid, string nickname, string accountId)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.SetOnInsert(x => x.UserGuid, userGuid)
|
||||
.Set(x => x.Nickname, nickname)
|
||||
.Set(x => x.AccountId, accountId)
|
||||
.SetOnInsert(x => x.AdditionalSlotCount, 0)
|
||||
.SetOnInsert(x => x.GradeType, UgqGradeType.Amature)
|
||||
.SetOnInsert(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
IsUpsert = true,
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, option);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> modifyAccountGrade(string userGuid, UgqGradeType grade)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.GradeType, grade);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> promoteAccountGrade(string userGuid, UgqGradeType before, UgqGradeType after)
|
||||
{
|
||||
var filterBuilder = Builders<AccountEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid) &
|
||||
(filterBuilder.Exists(x => x.GradeType, false) | filterBuilder.Eq(x => x.GradeType, before));
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.GradeType, after);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> addSlotCount(string userGuid, int? slotCountVersion, int addCount)
|
||||
{
|
||||
var filterBuilder = Builders<AccountEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid) &
|
||||
filterBuilder.Eq(x => x.SlotCountVersion, slotCountVersion);
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Inc(x => x.AdditionalSlotCount, addCount)
|
||||
.Inc(x => x.SlotCountVersion, 1);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> incCreatorPoint(string userGuid, int? creatorPointVersion, double amount)
|
||||
{
|
||||
var filterBuilder = Builders<AccountEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid) &
|
||||
filterBuilder.Eq(x => x.CreatorPointVersion, creatorPointVersion);
|
||||
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Inc(x => x.CreatorPoint, amount)
|
||||
.Inc(x => x.CreatorPointVersion, 1);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> saveRefreshToken(string userGuid, string refreshToken, DateTime? refreshTokenExpryTime)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var updateBuilder = Builders<AccountEntity>.Update;
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.RefreshToken, refreshToken);
|
||||
|
||||
if(refreshTokenExpryTime != null)
|
||||
update = updateBuilder.Combine(update, updateBuilder.Set(x => x.RefreshTokenExpiryTime, refreshTokenExpryTime));
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public async Task<AccountEntity?> deleteRefreshToken(string userGuid)
|
||||
{
|
||||
var filter = Builders<AccountEntity>.Filter
|
||||
.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var updateBuilder = Builders<AccountEntity>.Update;
|
||||
var update = Builders<AccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.RefreshToken, "")
|
||||
.Set(x => x.RefreshTokenExpiryTime, DateTime.Now);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public async Task<AllAccountQueryResult> getAccounts(int pageNumber, int pageSize, string? serachText, AccountSortType sortType)
|
||||
{
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var filter = Builders<AccountEntity>.Filter.Empty;
|
||||
|
||||
var sortBuilder = Builders<AccountItemResult>.Sort;
|
||||
SortDefinition<AccountItemResult> sort;
|
||||
switch (sortType)
|
||||
{
|
||||
case AccountSortType.CreatedAtDesc:
|
||||
sort = Builders<AccountItemResult>.Sort.Descending("CreatedAt");
|
||||
break;
|
||||
case AccountSortType.CreatedAtAsc:
|
||||
sort = Builders<AccountItemResult>.Sort.Ascending("CreatedAt");
|
||||
break;
|
||||
default:
|
||||
sort = Builders<AccountItemResult>.Sort.Descending("CreatedAt");
|
||||
break;
|
||||
}
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<AccountItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<AccountItemResult>()
|
||||
.Sort(sort)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = AccountQuery.allAccountPipeline<AccountItemResult>(
|
||||
filter,
|
||||
AccountQuery.AccountItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<AccountItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
var result = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
return new AllAccountQueryResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
119
UGQDataAccess/Repository/AdminAccountRepository.cs
Normal file
119
UGQDataAccess/Repository/AdminAccountRepository.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
using System.Drawing;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDataAccess.Repository.Query;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
|
||||
public class AdminAccountRepository : BaseRepository<AdminAccountEntity>
|
||||
{
|
||||
private const string CollectionName = "AdminAccount";
|
||||
|
||||
public AdminAccountRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<AdminAccountEntity?> get(string username)
|
||||
{
|
||||
var filter = Builders<AdminAccountEntity>.Filter
|
||||
.Eq(x => x.Username, username);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<AdminAccountEntity> signup(string username, string password, UGQAccountRole role)
|
||||
{
|
||||
var filter = Builders<AdminAccountEntity>.Filter
|
||||
.Eq(x => x.Username, username);
|
||||
|
||||
var update = Builders<AdminAccountEntity>.Update
|
||||
.SetOnInsert(x => x.Username, username)
|
||||
.SetOnInsert(x => x.Password, password)
|
||||
.SetOnInsert(x => x.Role, role)
|
||||
.SetOnInsert(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new FindOneAndUpdateOptions<AdminAccountEntity>
|
||||
{
|
||||
IsUpsert = true,
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, option);
|
||||
}
|
||||
|
||||
public async Task<AdminAccountEntity> changePassword(string username, string newPassword)
|
||||
{
|
||||
var filter = Builders<AdminAccountEntity>.Filter
|
||||
.Eq(x => x.Username, username);
|
||||
|
||||
var update = Builders<AdminAccountEntity>.Update
|
||||
.Set(x => x.Password, newPassword)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new FindOneAndUpdateOptions<AdminAccountEntity>
|
||||
{
|
||||
IsUpsert = true,
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, option);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<AdminAccountEntity?> saveRefreshToken(string id, string refreshToken, DateTime? refreshTokenExpryTime)
|
||||
{
|
||||
var filter = Builders<AdminAccountEntity>.Filter
|
||||
.Eq(x => x.Id, id);
|
||||
|
||||
var updateBuilder = Builders<AdminAccountEntity>.Update;
|
||||
var update = Builders<AdminAccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.RefreshToken, refreshToken);
|
||||
|
||||
if (refreshTokenExpryTime != null)
|
||||
update = updateBuilder.Combine(update, updateBuilder.Set(x => x.RefreshTokenExpiryTime, refreshTokenExpryTime));
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AdminAccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public async Task<AdminAccountEntity?> deleteRefreshToken(string username)
|
||||
{
|
||||
var filter = Builders<AdminAccountEntity>.Filter
|
||||
.Eq(x => x.Username, username);
|
||||
|
||||
var updateBuilder = Builders<AdminAccountEntity>.Update;
|
||||
var update = Builders<AdminAccountEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.RefreshToken, "")
|
||||
.Set(x => x.RefreshTokenExpiryTime, DateTime.Now);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<AdminAccountEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
|
||||
67
UGQDataAccess/Repository/BookmarkRepository.cs
Normal file
67
UGQDataAccess/Repository/BookmarkRepository.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class BookmarkRepository : BaseRepository<BookmarkEntity>
|
||||
{
|
||||
private const string CollectionName = "Bookmark";
|
||||
|
||||
public BookmarkRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<BookmarkEntity?> get(long questId, string userGuid)
|
||||
{
|
||||
var builder = Builders<BookmarkEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
BookmarkEntity? entity = await (await Collection.FindAsync(filter)).FirstOrDefaultAsync();
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, string userGuid)
|
||||
{
|
||||
var builder = Builders<BookmarkEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var update = Builders<BookmarkEntity>.Update
|
||||
.SetOnInsert(x => x.QuestId, questId)
|
||||
.SetOnInsert(x => x.UserGuid, userGuid)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new UpdateOptions
|
||||
{
|
||||
IsUpsert = true,
|
||||
};
|
||||
|
||||
var result = await Collection.UpdateOneAsync(filter, update, option);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> delete(long questId, string userGuid)
|
||||
{
|
||||
var builder = Builders<BookmarkEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var result = await Collection.DeleteOneAsync(filter);
|
||||
if (result.DeletedCount == 0)
|
||||
return ServerErrorCode.UgqNullEntity;
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
UGQDataAccess/Repository/CreatorPointHistoryRepository.cs
Normal file
95
UGQDataAccess/Repository/CreatorPointHistoryRepository.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using Amazon.SecurityToken.Model;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using UGQDataAccess.Repository.Query;
|
||||
using System.Linq.Expressions;
|
||||
using MetaAssets;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class CreatorPointHistoryRepository : BaseRepository<CreatorPointHistoryEntity>
|
||||
{
|
||||
private const string CollectionName = "CreatorPointHistory";
|
||||
|
||||
public CreatorPointHistoryRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public async Task<ServerErrorCode> insert(CreatorPointHistoryEntity entity)
|
||||
{
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<CreatorPointHistoryQueryResult> getList(string userGuid, int pageNumber, int pageSize, CreatorPointHistoryKind kind, DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
{
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var filterBuilder = Builders<CreatorPointHistoryEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
if (kind != CreatorPointHistoryKind.None)
|
||||
filter &= filterBuilder.Eq(x => x.Kind, kind);
|
||||
|
||||
if (startDate > endDate)
|
||||
(startDate, endDate) = (endDate, startDate);
|
||||
|
||||
if (startDate != DateTimeOffset.MinValue)
|
||||
filter &= filterBuilder.Gte(x => x.CreatedAt, startDate.UtcDateTime);
|
||||
|
||||
if (endDate != DateTimeOffset.MinValue)
|
||||
filter &= filterBuilder.Lt(x => x.CreatedAt, endDate.UtcDateTime);
|
||||
|
||||
var sort = Builders<CreatorPointHistoryEntity>.Sort.Descending(x => x.CreatedAt);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<CreatorPointHistoryEntity>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<CreatorPointHistoryEntity>()
|
||||
.Sort(sort)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<CreatorPointHistoryEntity>()
|
||||
.Match(filter)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<CreatorPointHistoryEntity>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
return new CreatorPointHistoryQueryResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
128
UGQDataAccess/Repository/GameQuestDataRepository.cs
Normal file
128
UGQDataAccess/Repository/GameQuestDataRepository.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
using StackExchange.Redis;
|
||||
using System.Drawing;
|
||||
using ServerCommon;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class GameQuestDataRepository : BaseRepository<GameQuestDataEntity>
|
||||
{
|
||||
private const string CollectionName = "GameQuestData";
|
||||
|
||||
public GameQuestDataRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public async Task<GameQuestDataEntity?> insert(QuestContentEntity content,
|
||||
QuestContentState state,
|
||||
List<GameQuestDialogDataEntity> dialogues,
|
||||
List<QuestMetaInfo> metas,
|
||||
string ugqGameQuestDataForClientString,
|
||||
UgqGradeType? gradeType = null)
|
||||
{
|
||||
var filterBuilder = Builders<GameQuestDataEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.QuestId, content.QuestId) &
|
||||
filterBuilder.Eq(x => x.Revision, content.Revision) &
|
||||
filterBuilder.Eq(x => x.State, state);
|
||||
|
||||
var updateGradeType = gradeType;
|
||||
if (updateGradeType == null)
|
||||
updateGradeType = content.GradeType;
|
||||
|
||||
var update = Builders<GameQuestDataEntity>.Update
|
||||
.Set(x => x.QuestId, content.QuestId)
|
||||
.Set(x => x.Revision, content.Revision)
|
||||
.Set(x => x.UserGuid, content.UserGuid)
|
||||
.Set(x => x.Author, content.Author)
|
||||
.Set(x => x.BeaconId, content.BeaconId)
|
||||
.Set(x => x.UgcBeaconGuid, content.UgcBeaconGuid)
|
||||
.Set(x => x.UgcBeaconNickname, content.UgcBeaconNickname)
|
||||
.Set(x => x.Title, content.Title)
|
||||
.Set(x => x.Langs, content.Langs)
|
||||
.Set(x => x.TitleImagePath, content.TitleImagePath)
|
||||
.Set(x => x.BannerImagePath, content.BannerImagePath)
|
||||
.Set(x => x.Description, content.Description)
|
||||
.Set(x => x.GradeType, updateGradeType)
|
||||
.Set(x => x.State, state)
|
||||
.Set(x => x.Cost, content.Cost)
|
||||
.Set(x => x.Shutdown, false)
|
||||
.Set(x => x.Tasks, content.Tasks)
|
||||
.Set(x => x.Dialogs, dialogues)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.QuestScriptMetas, metas)
|
||||
.Set(x => x.UgqGameQuestDataForClientString, ugqGameQuestDataForClientString)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new FindOneAndUpdateOptions<GameQuestDataEntity>
|
||||
{
|
||||
IsUpsert = true,
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, option);
|
||||
}
|
||||
|
||||
public async Task delete(long questId, long revision, QuestContentState state)
|
||||
{
|
||||
var filterBuilder = Builders<GameQuestDataEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.QuestId, questId) &
|
||||
filterBuilder.Eq(x => x.Revision, revision) &
|
||||
filterBuilder.Eq(x => x.State, state);
|
||||
|
||||
await Collection.DeleteOneAsync(filter);
|
||||
}
|
||||
|
||||
public async Task<GameQuestDataEntity?> get(long questId, long revision, QuestContentState state)
|
||||
{
|
||||
var builder = Builders<GameQuestDataEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.Revision, revision) &
|
||||
builder.Eq(x => x.State, state);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<GameQuestDataEntity?> getLatestRevision(long questId)
|
||||
{
|
||||
var builder = Builders<GameQuestDataEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId);
|
||||
|
||||
GameQuestDataEntity? entity = await Collection.Find(filter)
|
||||
.SortByDescending(x => x.Revision)
|
||||
.Limit(1)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<GameQuestDataEntity?> setShutdown(long questId, long revision)
|
||||
{
|
||||
var builder = Builders<GameQuestDataEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) & builder.Eq(x => x.Revision, revision) &
|
||||
builder.Eq(x => x.State, QuestContentState.Live);
|
||||
|
||||
var update = Builders<GameQuestDataEntity>.Update
|
||||
.Set(x => x.Shutdown, true);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<GameQuestDataEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
}
|
||||
|
||||
67
UGQDataAccess/Repository/LikeRepository.cs
Normal file
67
UGQDataAccess/Repository/LikeRepository.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class LikeRepository : BaseRepository<LikeEntity>
|
||||
{
|
||||
private const string CollectionName = "Like";
|
||||
|
||||
public LikeRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<LikeEntity?> get(long questId, string userGuid)
|
||||
{
|
||||
var builder = Builders<LikeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
LikeEntity? entity = await (await Collection.FindAsync(filter)).FirstOrDefaultAsync();
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, long revision, string userGuid)
|
||||
{
|
||||
var builder = Builders<LikeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var update = Builders<LikeEntity>.Update
|
||||
.SetOnInsert(x => x.QuestId, questId)
|
||||
.SetOnInsert(x => x.UserGuid, userGuid)
|
||||
.SetOnInsert(x => x.CreatedAt, DateTime.UtcNow);
|
||||
|
||||
var option = new UpdateOptions
|
||||
{
|
||||
IsUpsert = true,
|
||||
};
|
||||
|
||||
var result = await Collection.UpdateOneAsync(filter, update, option);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> delete(long questId, long revision, string userGuid)
|
||||
{
|
||||
var builder = Builders<LikeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var result = await Collection.DeleteOneAsync(filter);
|
||||
if (result.DeletedCount == 0)
|
||||
return ServerErrorCode.UgqNullEntity;
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
266
UGQDataAccess/Repository/Models/Model.cs
Normal file
266
UGQDataAccess/Repository/Models/Model.cs
Normal file
@@ -0,0 +1,266 @@
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using System.Text.Json.Serialization;
|
||||
using UGQDatabase.Models;
|
||||
|
||||
namespace UGQDataAccess.Repository.Models;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
public class UGQSaveQuestModel
|
||||
{
|
||||
public int BeaconId { get; set; }
|
||||
public string? UgcBeaconGuid { get; set; }
|
||||
public string? UgcBeaconNickname { get; set; }
|
||||
|
||||
public TextEntity Title { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
|
||||
public TextEntity Description { get; set; }
|
||||
public int Cost { get; set; }
|
||||
|
||||
public List<TaskEntity> Tasks { get; set; }
|
||||
|
||||
public string Savelanguage { get; set; }
|
||||
}
|
||||
|
||||
public class UGQSaveDialogSequenceAction
|
||||
{
|
||||
public DialogTalker Talker { get; set; }
|
||||
public int Type { get; set; }
|
||||
public TextEntity Talk { get; set; }
|
||||
public int Condition { get; set; }
|
||||
public int ConditionValue { get; set; }
|
||||
public int NextSequence { get; set; }
|
||||
public int NpcAction { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class UGQSaveDialogSequence
|
||||
{
|
||||
public int SequenceId { get; set; }
|
||||
public List<UGQSaveDialogSequenceAction> Actions { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class UGQSaveDialogModel
|
||||
{
|
||||
public List<UGQSaveDialogSequence> Sequences { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class UGQStats
|
||||
{
|
||||
public int Accepted { get; set; } = 0;
|
||||
public int Completed { get; set; } = 0;
|
||||
public int Like { get; set; } = 0;
|
||||
public int Bookmark { get; set; } = 0;
|
||||
public int Report { get; set; } = 0;
|
||||
public double TotalProfit { get; set; } = 0;
|
||||
}
|
||||
|
||||
|
||||
public class SummaryItemResult
|
||||
{
|
||||
public string QuestContentId { get; set; }
|
||||
public long QuestId { get; set; }
|
||||
public long Revision { get; set; }
|
||||
|
||||
public string UserGuid { get; set; }
|
||||
public string Author { get; set; }
|
||||
|
||||
public int BeaconId { get; set; }
|
||||
public string? UgcBeaconGuid { get; set; }
|
||||
public string? UgcBeaconNickname { get; set; }
|
||||
|
||||
public UgqGradeType GradeType { get; set; }
|
||||
|
||||
public TextEntity Title { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
public TextEntity Description { get; set; }
|
||||
public int Cost { get; set; }
|
||||
public string TitleImagePath { get; set; }
|
||||
public string BannerImagePath { get; set; }
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public QuestContentState State { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
public int AcceptedCount { get; set; }
|
||||
public int CompletedCount { get; set; }
|
||||
public int LikeCount { get; set; }
|
||||
public int BookmarkCount { get; set; }
|
||||
public int ReportCount { get; set; }
|
||||
public double TotalProfit { get; set; }
|
||||
public string Savelanguage { get; set; }
|
||||
}
|
||||
|
||||
public class SummaryQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<SummaryItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
public class AllSummaryQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<SummaryItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
public class QuestProfitStatsItemResult
|
||||
{
|
||||
public string QuestContentId { get; set; }
|
||||
public long QuestId { get; set; }
|
||||
public long Revision { get; set; }
|
||||
|
||||
public TextEntity Title { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
public string TitleImagePath { get; set; }
|
||||
public string BannerImagePath { get; set; }
|
||||
|
||||
public int CompletedCount { get; set; }
|
||||
public double TotalProfit { get; set; }
|
||||
}
|
||||
|
||||
public class QuestProfitStatsQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<QuestProfitStatsItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class QuestBoardItemResult
|
||||
{
|
||||
public long QuestId { get; set; }
|
||||
public long Revision { get; set; }
|
||||
public string Author { get; set; }
|
||||
public TextEntity Title { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
public TextEntity Description { get; set; }
|
||||
public int Cost { get; set; }
|
||||
public UgqGradeType GradeType { get; set; }
|
||||
public string TitleImagePath { get; set; }
|
||||
public string BannerImagePath { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public int LikeCount { get; set; }
|
||||
public int BookmarkCount { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class QuestBoardQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<QuestBoardItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
public class QuestBoardSportlightQueryResult
|
||||
{
|
||||
public class DateRangeResult
|
||||
{
|
||||
public QuestBoardItemResult? Today { get; set; }
|
||||
public QuestBoardItemResult? ThisWeek { get; set; }
|
||||
public QuestBoardItemResult? ThisMonth { get; set; }
|
||||
}
|
||||
|
||||
public DateRangeResult MostLiked { get; set; }
|
||||
public DateRangeResult MostBookmarked { get; set; }
|
||||
}
|
||||
|
||||
public class QuestBoardDetailItemResult
|
||||
{
|
||||
public long QuestId { get; set; }
|
||||
public long Revision { get; set; }
|
||||
public string Author { get; set; }
|
||||
public TextEntity Title { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
public TextEntity Description { get; set; }
|
||||
public int Cost { get; set; }
|
||||
public UgqGradeType GradeType { get; set; }
|
||||
public string TitleImagePath { get; set; }
|
||||
public string BannerImagePath { get; set; }
|
||||
|
||||
public int BeaconId { get; set; }
|
||||
public string? UgcBeaconGuid { get; set; }
|
||||
public string? UgcBeaconNickname { get; set; }
|
||||
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public int LikeCount { get; set; }
|
||||
public int BookmarkCount { get; set; }
|
||||
public int QuestAcceptedCount { get; set; }
|
||||
public int QuestCompletedCount { get; set; }
|
||||
|
||||
public bool Liked { get; set; }
|
||||
public bool Bookmarked { get; set; }
|
||||
}
|
||||
|
||||
public class CreatorPointHistoryQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<CreatorPointHistoryEntity> Items { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AccountItemResult
|
||||
{
|
||||
public string UserGuid { get; set; }
|
||||
public string Nickname { get; set; }
|
||||
public string AccountId { get; set; }
|
||||
public int AdditionalSlotCount { get; set; }
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public UgqGradeType GradeType { get; set; }
|
||||
public double CreatorPoint { get; set; }
|
||||
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
public int QuestCount { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AllAccountQueryResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<AccountItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
public class ReserveAccountGradeItemResult
|
||||
{
|
||||
public string ReserveId { get; set; }
|
||||
public string UserGuid { get; set; }
|
||||
public string AccountId { get; set; }
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public UgqGradeType CurrentGradeType { get; set; }
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public UgqGradeType ReserveGradeType { get; set; }
|
||||
public DateTime ReserveTime { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
public bool IsCompleted { get; set; }
|
||||
}
|
||||
|
||||
public class AllReserveAccountGradeResult
|
||||
{
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages { get; set; }
|
||||
public List<ReserveAccountGradeItemResult> Items { get; set; }
|
||||
}
|
||||
|
||||
39
UGQDataAccess/Repository/NpcNameRepository.cs
Normal file
39
UGQDataAccess/Repository/NpcNameRepository.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class NpcNameRepository : BaseRepository<NpcNameEntity>
|
||||
{
|
||||
private const string CollectionName = "NpcName";
|
||||
|
||||
public NpcNameRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task upsertNpcName(int npcId, TextEntity npcName)
|
||||
{
|
||||
var filter = Builders<NpcNameEntity>.Filter.Eq(x => x.NpcId, npcId);
|
||||
|
||||
var update = Builders<NpcNameEntity>.Update
|
||||
.Set(x => x.NpcName, npcName);
|
||||
|
||||
var option = new UpdateOptions
|
||||
{
|
||||
IsUpsert = true,
|
||||
};
|
||||
|
||||
await Collection.UpdateOneAsync(filter, update, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
72
UGQDataAccess/Repository/Query/AccountQuery.cs
Normal file
72
UGQDataAccess/Repository/Query/AccountQuery.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDatabase.Models;
|
||||
using static UGQDataAccess.Repository.Query.QuestContentQuery;
|
||||
|
||||
namespace UGQDataAccess.Repository.Query;
|
||||
|
||||
public static class AccountQuery
|
||||
{
|
||||
|
||||
public class AllAccountQueryJoin : AccountEntity
|
||||
{
|
||||
public IEnumerable<QuestContentEntity> QuestContents { get; set; } = null!;
|
||||
public int QuestCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
|
||||
public static Expression<Func<AllAccountQueryJoin, AccountItemResult>> AccountItemResultProjection =
|
||||
x => new AccountItemResult
|
||||
{
|
||||
UserGuid = x.UserGuid,
|
||||
Nickname = x.Nickname,
|
||||
AccountId = x.AccountId ?? "",
|
||||
AdditionalSlotCount = x.AdditionalSlotCount,
|
||||
GradeType = x.GradeType,
|
||||
CreatorPoint = x.CreatorPoint,
|
||||
CreatedAt = x.CreatedAt,
|
||||
QuestCount = x.QuestCount,
|
||||
};
|
||||
|
||||
public static PipelineDefinition<AccountEntity, T> allAccountPipeline<T>(
|
||||
FilterDefinition<AccountEntity> filter,
|
||||
Expression<Func<AllAccountQueryJoin, T>> projection)
|
||||
{
|
||||
var lookupStage1 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestContent" },
|
||||
{ "localField", "UserGuid" },
|
||||
{ "foreignField", "UserGuid" },
|
||||
{ "pipeline",
|
||||
new BsonArray
|
||||
{
|
||||
new BsonDocument("$match",
|
||||
new BsonDocument("IsDeleted", false))
|
||||
} },
|
||||
{ "as", "QuestContents" }
|
||||
});
|
||||
|
||||
var addFields1 = new BsonDocument("$addFields",
|
||||
new BsonDocument("QuestCount",
|
||||
new BsonDocument("$size", "$QuestContents")));
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<AccountEntity>()
|
||||
.Match(filter)
|
||||
.AppendStage<AccountEntity, AccountEntity, AllAccountQueryJoin>(lookupStage1)
|
||||
.AppendStage<AccountEntity, AllAccountQueryJoin, AllAccountQueryJoin>(addFields1)
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
563
UGQDataAccess/Repository/Query/QuestContentQuery.cs
Normal file
563
UGQDataAccess/Repository/Query/QuestContentQuery.cs
Normal file
@@ -0,0 +1,563 @@
|
||||
using System.Linq.Expressions;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDatabase.Models;
|
||||
|
||||
namespace UGQDataAccess.Repository.Query;
|
||||
|
||||
public static class QuestContentQuery
|
||||
{
|
||||
public class QuestBoardQueryJoin : QuestContentEntity
|
||||
{
|
||||
public IEnumerable<LikeEntity> Likes { get; set; } = null!;
|
||||
public int LikeCount { get; set; } = 0;
|
||||
public IEnumerable<BookmarkEntity> Bookmarks { get; set; } = null!;
|
||||
public int BookmarkCount { get; set; } = 0;
|
||||
|
||||
public List<QuestAcceptedEntity> QuestAccepteds { get; set; } = null!;
|
||||
public int QuestAcceptedCount { get; set; } = 0;
|
||||
|
||||
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
||||
public int QuestCompletedCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class QuestSummariesQueryJoin : QuestContentEntity
|
||||
{
|
||||
public IEnumerable<LikeEntity> Likes { get; set; } = null!;
|
||||
public int LikeCount { get; set; } = 0;
|
||||
public IEnumerable<BookmarkEntity> Bookmarks { get; set; } = null!;
|
||||
public int BookmarkCount { get; set; } = 0;
|
||||
|
||||
public List<QuestAcceptedEntity> QuestAccepteds { get; set; } = null!;
|
||||
public int QuestAcceptedCount { get; set; } = 0;
|
||||
|
||||
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
||||
public int QuestCompletedCount { get; set; } = 0;
|
||||
|
||||
public List<QuestAcceptedEntity> QuestAborteds { get; set; } = null!;
|
||||
public int QuestAbortedCount { get; set; } = 0;
|
||||
|
||||
public List<ReportEntity> Reports { get; set; } = null!;
|
||||
public int ReporCount { get; set; } = 0;
|
||||
|
||||
public List<CreatorPointHistoryEntity> ProfitHistories { get; set; } = null!;
|
||||
public double TotalProfit { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class QuestProfitStatsQueryJoin : QuestContentEntity
|
||||
{
|
||||
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
||||
public int QuestCompletedCount { get; set; } = 0;
|
||||
|
||||
public List<CreatorPointHistoryEntity> ProfitHistories { get; set; } = null!;
|
||||
public double TotalProfit { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class QuestAcceptedLookup : QuestAcceptedEntity
|
||||
{
|
||||
}
|
||||
|
||||
public static Expression<Func<QuestBoardQueryJoin, QuestBoardItemResult>> QuestBoardItemResultProjection =
|
||||
x => new QuestBoardItemResult
|
||||
{
|
||||
QuestId = x.QuestId,
|
||||
Revision = x.Revision,
|
||||
Author = x.Author,
|
||||
Title = x.Title,
|
||||
Languages = x.Langs,
|
||||
Cost = x.Cost,
|
||||
GradeType = x.GradeType,
|
||||
TitleImagePath = x.TitleImagePath,
|
||||
BannerImagePath = x.BannerImagePath,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
LikeCount = x.LikeCount,
|
||||
BookmarkCount = x.BookmarkCount,
|
||||
};
|
||||
|
||||
|
||||
public static Expression<Func<QuestSummariesQueryJoin, SummaryItemResult>> SummaryItemResultProjection =
|
||||
x => new SummaryItemResult
|
||||
{
|
||||
QuestContentId = x.Id.ToString(),
|
||||
QuestId = x.QuestId,
|
||||
Revision = x.Revision,
|
||||
BeaconId = x.BeaconId,
|
||||
|
||||
UserGuid = x.UserGuid,
|
||||
Author = x.Author,
|
||||
|
||||
UgcBeaconGuid = x.UgcBeaconGuid,
|
||||
UgcBeaconNickname = x.UgcBeaconNickname,
|
||||
|
||||
GradeType = x.GradeType,
|
||||
|
||||
Title = x.Title,
|
||||
Languages = x.Langs,
|
||||
Description = x.Description,
|
||||
Cost = x.Cost,
|
||||
TitleImagePath = x.TitleImagePath,
|
||||
BannerImagePath = x.BannerImagePath,
|
||||
State = x.State,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
CreatedAt = x.CreatedAt,
|
||||
|
||||
AcceptedCount = x.QuestAcceptedCount,
|
||||
CompletedCount = x.QuestCompletedCount,
|
||||
LikeCount = x.LikeCount,
|
||||
BookmarkCount = x.BookmarkCount,
|
||||
ReportCount = x.ReporCount,
|
||||
|
||||
TotalProfit = x.TotalProfit,
|
||||
Savelanguage = x.Savelanguage,
|
||||
};
|
||||
|
||||
public static Expression<Func<QuestProfitStatsQueryJoin, QuestProfitStatsItemResult>> QuestProfitStatsResultProjection =
|
||||
x => new QuestProfitStatsItemResult
|
||||
{
|
||||
QuestContentId = x.Id.ToString(),
|
||||
QuestId = x.QuestId,
|
||||
Revision = x.Revision,
|
||||
|
||||
Title = x.Title,
|
||||
Languages = x.Langs,
|
||||
TitleImagePath = x.TitleImagePath,
|
||||
BannerImagePath = x.BannerImagePath,
|
||||
|
||||
CompletedCount = x.QuestCompletedCount,
|
||||
TotalProfit = x.TotalProfit,
|
||||
};
|
||||
|
||||
|
||||
static List<UgqGradeType> getGradeTypes(UgqUICategoryGradeType gradeType)
|
||||
{
|
||||
switch (gradeType)
|
||||
{
|
||||
case UgqUICategoryGradeType.Amateur:
|
||||
return [UgqGradeType.Amature];
|
||||
case UgqUICategoryGradeType.RisingStar:
|
||||
return [UgqGradeType.RisingStar];
|
||||
case UgqUICategoryGradeType.Master:
|
||||
return [UgqGradeType.Master1, UgqGradeType.Master2, UgqGradeType.Master3];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
static async Task<List<long>> getBookmarks(IMongoCollection<BookmarkEntity> bookmarkCollection, string userGuid)
|
||||
{
|
||||
var filterBuilder = Builders<BookmarkEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var list = await bookmarkCollection.Find(filter).ToListAsync();
|
||||
|
||||
return list.Select(x => x.QuestId).ToList();
|
||||
}
|
||||
|
||||
static async Task<List<int>> searchNpcs(IMongoCollection<NpcNameEntity> npcNameCollection, string searchText)
|
||||
{
|
||||
var filterBuilder = Builders<NpcNameEntity>.Filter;
|
||||
var filter = filterBuilder.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) == false)
|
||||
{
|
||||
filter &= (filterBuilder.Regex(x => x.NpcName.Kr, searchText) |
|
||||
filterBuilder.Regex(x => x.NpcName.En, searchText) |
|
||||
filterBuilder.Regex(x => x.NpcName.Jp, searchText));
|
||||
}
|
||||
|
||||
var list = await npcNameCollection.Find(filter).ToListAsync();
|
||||
|
||||
return list.Select(x => x.NpcId).ToList();
|
||||
}
|
||||
|
||||
static FilterDefinition<QuestContentEntity> searchTitle(FilterDefinitionBuilder<QuestContentEntity> filterBuilder, string searchText)
|
||||
{
|
||||
return filterBuilder.Regex(x => x.Title.Kr, searchText) |
|
||||
filterBuilder.Regex(x => x.Title.En, searchText) |
|
||||
filterBuilder.Regex(x => x.Title.Jp, searchText);
|
||||
}
|
||||
|
||||
public static async Task<FilterDefinition<QuestContentEntity>> summariesFilter(string? userGuid,
|
||||
UgqSearchType searchType, string? searchText, QuestContentState state,
|
||||
IMongoCollection<AccountEntity> accountCollection,
|
||||
IMongoCollection<NpcNameEntity> npcNameCollection)
|
||||
{
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
if (state != QuestContentState.None)
|
||||
{
|
||||
if(state == QuestContentState.Uncomplate ||
|
||||
state == QuestContentState.Editable)
|
||||
{
|
||||
var UncomplateOrFilter = filterBuilder.Eq(x => x.State, QuestContentState.Uncomplate);
|
||||
var EditableOrFilter = filterBuilder.Eq(x => x.State, QuestContentState.Editable);
|
||||
filter &= filterBuilder.Or(UncomplateOrFilter, EditableOrFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter &= filterBuilder.Eq(x => x.State, state);
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(userGuid) == false)
|
||||
filter &= filterBuilder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) == false)
|
||||
{
|
||||
switch (searchType)
|
||||
{
|
||||
case UgqSearchType.Title:
|
||||
filter &= searchTitle(filterBuilder, searchText);
|
||||
break;
|
||||
case UgqSearchType.Beacon:
|
||||
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
||||
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
||||
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static async Task<FilterDefinition<QuestContentEntity>> questBoardFilter(string? userGuid,
|
||||
UgqUICategoryGradeType gradeType, UgqSearchType searchType, string? searchText,
|
||||
IMongoCollection<AccountEntity> accountCollection,
|
||||
IMongoCollection<NpcNameEntity> npcNameCollection)
|
||||
{
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= filterBuilder.Eq(x => x.State, QuestContentState.Live);
|
||||
|
||||
if (string.IsNullOrEmpty(userGuid) == false)
|
||||
filter &= filterBuilder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
if(gradeType != UgqUICategoryGradeType.None)
|
||||
{
|
||||
var gradeTypes = getGradeTypes(gradeType);
|
||||
filter &= filterBuilder.In(x => x.GradeType, gradeTypes);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) == false)
|
||||
{
|
||||
switch (searchType)
|
||||
{
|
||||
case UgqSearchType.Title:
|
||||
filter &= searchTitle(filterBuilder, searchText);
|
||||
break;
|
||||
case UgqSearchType.Beacon:
|
||||
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
||||
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
||||
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static async Task<FilterDefinition<QuestContentEntity>> questBoardBookmarkFilter(string userGuid,
|
||||
UgqUICategoryGradeType gradeType, UgqSearchType searchType, string? searchText,
|
||||
IMongoCollection<NpcNameEntity> npcNameCollection,
|
||||
IMongoCollection<BookmarkEntity> bookmarkCollection)
|
||||
{
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= filterBuilder.Eq(x => x.State, QuestContentState.Live);
|
||||
|
||||
if (gradeType != UgqUICategoryGradeType.None)
|
||||
{
|
||||
var gradeTypes = getGradeTypes(gradeType);
|
||||
filter &= filterBuilder.In(x => x.GradeType, gradeTypes);
|
||||
}
|
||||
|
||||
var bookmarkQuestIds = await getBookmarks(bookmarkCollection, userGuid);
|
||||
filter &= filterBuilder.In(x => x.QuestId, bookmarkQuestIds);
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) == false)
|
||||
{
|
||||
switch (searchType)
|
||||
{
|
||||
case UgqSearchType.Title:
|
||||
filter &= searchTitle(filterBuilder, searchText);
|
||||
break;
|
||||
case UgqSearchType.Beacon:
|
||||
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
||||
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
||||
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static SortDefinition<T> questBoardSort<T>(UgqSortType sortType)
|
||||
{
|
||||
var sortBuilder = Builders<T>.Sort;
|
||||
SortDefinition<T> sort;
|
||||
switch (sortType)
|
||||
{
|
||||
case UgqSortType.New:
|
||||
sort = Builders<T>.Sort.Descending("UpdatedAt");
|
||||
break;
|
||||
case UgqSortType.Like:
|
||||
sort = Builders<T>.Sort.Descending("LikeCount");
|
||||
break;
|
||||
case UgqSortType.Bookmark:
|
||||
sort = Builders<T>.Sort.Descending("BookmarkCount");
|
||||
break;
|
||||
default:
|
||||
sort = Builders<T>.Sort.Descending("UpdatedAt");
|
||||
break;
|
||||
}
|
||||
|
||||
return sort;
|
||||
}
|
||||
|
||||
public static PipelineDefinition<QuestContentEntity, T> summariesPipeline<T>(
|
||||
IMongoCollection<LikeEntity> likeCollection,
|
||||
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
||||
FilterDefinition<QuestContentEntity> filter,
|
||||
Expression<Func<QuestSummariesQueryJoin, T>> projection)
|
||||
{
|
||||
var lookupStage1 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestAccepted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "pipeline",
|
||||
new BsonArray
|
||||
{
|
||||
new BsonDocument("$match",
|
||||
new BsonDocument("Reason", "Player"))
|
||||
} },
|
||||
{ "as", "QuestAccepteds" }
|
||||
});
|
||||
|
||||
var addFields1 = new BsonDocument("$addFields",
|
||||
new BsonDocument("QuestAcceptedCount",
|
||||
new BsonDocument("$size", "$QuestAccepteds")));
|
||||
|
||||
var lookupStage2 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestCompleted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "as", "QuestCompleteds" }
|
||||
});
|
||||
|
||||
var addFields2 = new BsonDocument("$addFields",
|
||||
new BsonDocument("QuestCompletedCount",
|
||||
new BsonDocument("$size", "$QuestCompleteds")));
|
||||
|
||||
var lookupStage3 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestAborted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "as", "QuestAborteds" }
|
||||
});
|
||||
|
||||
var addFields3 = new BsonDocument("$addFields",
|
||||
new BsonDocument("QuestAbortedCount",
|
||||
new BsonDocument("$size", "$QuestAborteds")));
|
||||
|
||||
var lookupStage4 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "CreatorPointHistory" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "pipeline",
|
||||
new BsonArray
|
||||
{
|
||||
new BsonDocument("$match",
|
||||
new BsonDocument("Kind", "QuestProfit"))
|
||||
} },
|
||||
{ "as", "ProfitHistories" }
|
||||
});
|
||||
|
||||
var addFields4 = new BsonDocument("$addFields",
|
||||
new BsonDocument("TotalProfit",
|
||||
new BsonDocument("$sum", "$ProfitHistories.Amount")));
|
||||
|
||||
|
||||
var lookupStage5 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "Report" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "as", "Reports" }
|
||||
});
|
||||
|
||||
var addFields5 = new BsonDocument("$addFields",
|
||||
new BsonDocument("ReporCount",
|
||||
new BsonDocument("$size", "$Reports")));
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
||||
.Match(filter)
|
||||
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestSummariesQueryJoin>(
|
||||
likeCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Likes)
|
||||
.Lookup<QuestContentEntity, QuestSummariesQueryJoin, BookmarkEntity, QuestSummariesQueryJoin>(
|
||||
bookmarkCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Bookmarks)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage1)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields1)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage2)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields2)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage3)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields3)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage4)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields4)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage5)
|
||||
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields5)
|
||||
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public static PipelineDefinition<QuestContentEntity, T> questProfitStatsPipeline<T>(
|
||||
FilterDefinition<QuestContentEntity> filter,
|
||||
Expression<Func<QuestProfitStatsQueryJoin, T>> projection)
|
||||
{
|
||||
var lookupStage1 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestCompleted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "as", "QuestCompleteds" }
|
||||
});
|
||||
|
||||
var addFields1 = new BsonDocument("$addFields",
|
||||
new BsonDocument("QuestCompletedCount",
|
||||
new BsonDocument("$size", "$QuestCompleteds")));
|
||||
|
||||
var lookupStage2 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "CreatorPointHistory" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "pipeline",
|
||||
new BsonArray
|
||||
{
|
||||
new BsonDocument("$match",
|
||||
new BsonDocument("Kind", "QuestProfit"))
|
||||
} },
|
||||
{ "as", "ProfitHistories" }
|
||||
});
|
||||
|
||||
var addFields2 = new BsonDocument("$addFields",
|
||||
new BsonDocument("TotalProfit",
|
||||
new BsonDocument("$sum", "$ProfitHistories.Amount")));
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
||||
.Match(filter)
|
||||
.AppendStage<QuestContentEntity, QuestContentEntity, QuestProfitStatsQueryJoin>(lookupStage1)
|
||||
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(addFields1)
|
||||
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(lookupStage2)
|
||||
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(addFields2)
|
||||
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public static PipelineDefinition<QuestContentEntity, T> questBoardPipeline<T>(
|
||||
IMongoCollection<LikeEntity> likeCollection,
|
||||
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
||||
FilterDefinition<QuestContentEntity> filter,
|
||||
Expression<Func<QuestBoardQueryJoin, T>> projection)
|
||||
{
|
||||
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
||||
.Match(filter)
|
||||
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestBoardQueryJoin>(
|
||||
likeCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Likes)
|
||||
.Lookup<QuestContentEntity, QuestBoardQueryJoin, BookmarkEntity, QuestBoardQueryJoin>(
|
||||
bookmarkCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Bookmarks)
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public static PipelineDefinition<QuestContentEntity, T> questBoardDetailPipeline<T>(
|
||||
IMongoCollection<LikeEntity> likeCollection,
|
||||
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
||||
FilterDefinition<QuestContentEntity> filter,
|
||||
Expression<Func<QuestBoardQueryJoin, T>> projection)
|
||||
{
|
||||
var lookupStage1 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestAccepted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "pipeline",
|
||||
new BsonArray
|
||||
{
|
||||
new BsonDocument("$match",
|
||||
new BsonDocument("Reason", "Player"))
|
||||
} },
|
||||
{ "as", "QuestAccepteds" }
|
||||
});
|
||||
|
||||
var lookupStage2 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "QuestCompleted" },
|
||||
{ "localField", "QuestId" },
|
||||
{ "foreignField", "QuestId" },
|
||||
{ "as", "QuestCompleteds" }
|
||||
});
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
||||
.Match(filter)
|
||||
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestBoardQueryJoin>(
|
||||
likeCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Likes)
|
||||
.Lookup<QuestContentEntity, QuestBoardQueryJoin, BookmarkEntity, QuestBoardQueryJoin>(
|
||||
bookmarkCollection,
|
||||
x => x.QuestId,
|
||||
x => x.QuestId,
|
||||
x => x.Bookmarks)
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>(lookupStage1)
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>(lookupStage2)
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {QuestAcceptedCount: {$size:'$QuestAccepteds'}}}")
|
||||
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {QuestCompletedCount: {$size:'$QuestCompleteds'}}}")
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
|
||||
51
UGQDataAccess/Repository/Query/ReserveAccountGradeQuery.cs
Normal file
51
UGQDataAccess/Repository/Query/ReserveAccountGradeQuery.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using System.Linq.Expressions;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDatabase.Models;
|
||||
|
||||
|
||||
public static class ReserveAccountGradeQuery
|
||||
{
|
||||
|
||||
public class AllReserveAccountGradeQueryJoin : ReserveAccountGradeEntity
|
||||
{
|
||||
public IEnumerable<AccountEntity> Accounts { get; set; } = null!;
|
||||
}
|
||||
|
||||
|
||||
public static Expression<Func<AllReserveAccountGradeQueryJoin, ReserveAccountGradeItemResult>> ReserveAccountGradeItemResultProjection =
|
||||
x => new ReserveAccountGradeItemResult
|
||||
{
|
||||
ReserveId = x.Id.ToString(),
|
||||
UserGuid = x.UserGuid,
|
||||
CurrentGradeType = x.BeforeGradeType,
|
||||
AccountId = x.Accounts.First().AccountId ?? string.Empty,
|
||||
ReserveGradeType = x.ReserveGradeType,
|
||||
ReserveTime = x.ReserveTime,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
IsCompleted = x.IsCompleted,
|
||||
};
|
||||
|
||||
public static PipelineDefinition<ReserveAccountGradeEntity, T> allReserveAccountGradePipeline<T>(
|
||||
FilterDefinition<ReserveAccountGradeEntity> filter,
|
||||
Expression<Func<AllReserveAccountGradeQueryJoin, T>> projection)
|
||||
{
|
||||
var lookupStage1 = new BsonDocument("$lookup",
|
||||
new BsonDocument
|
||||
{
|
||||
{ "from", "Account" },
|
||||
{ "localField", "UserGuid" },
|
||||
{ "foreignField", "UserGuid" },
|
||||
{ "as", "Accounts" }
|
||||
});
|
||||
|
||||
var pipeline = new EmptyPipelineDefinition<ReserveAccountGradeEntity>()
|
||||
.Match(filter)
|
||||
.AppendStage<ReserveAccountGradeEntity, ReserveAccountGradeEntity, AllReserveAccountGradeQueryJoin>(lookupStage1)
|
||||
.Project(projection);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
}
|
||||
61
UGQDataAccess/Repository/QuestAbortedRepository.cs
Normal file
61
UGQDataAccess/Repository/QuestAbortedRepository.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class QuestAbortedRepository : BaseRepository<QuestAbortedEntity>
|
||||
{
|
||||
private const string CollectionName = "QuestAborted";
|
||||
|
||||
public QuestAbortedRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<List<QuestAbortedEntity>> getAll()
|
||||
{
|
||||
return await Collection.Find(Builders<QuestAbortedEntity>.Filter.Empty).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, long revision, string author, UGQAbortReason reason, string userGuid)
|
||||
{
|
||||
var entity = new QuestAbortedEntity
|
||||
{
|
||||
QuestId = questId,
|
||||
Revision = revision,
|
||||
Author = author,
|
||||
UserGuid = userGuid,
|
||||
Reason = reason,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<QuestAbortedEntity?> setAuthor(string id, string author)
|
||||
{
|
||||
var filterBuilder = Builders<QuestAbortedEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.Id, id);
|
||||
|
||||
var update = Builders<QuestAbortedEntity>.Update
|
||||
.Set(x => x.Author, author);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestAbortedEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
}
|
||||
61
UGQDataAccess/Repository/QuestAcceptedRepository.cs
Normal file
61
UGQDataAccess/Repository/QuestAcceptedRepository.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class QuestAcceptedRepository : BaseRepository<QuestAcceptedEntity>
|
||||
{
|
||||
private const string CollectionName = "QuestAccepted";
|
||||
|
||||
public QuestAcceptedRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<List<QuestAcceptedEntity>> getAll()
|
||||
{
|
||||
return await Collection.Find(Builders<QuestAcceptedEntity>.Filter.Empty).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, long revision, string author, UGQAcceptReason reason, string userGuid)
|
||||
{
|
||||
var entity = new QuestAcceptedEntity
|
||||
{
|
||||
QuestId = questId,
|
||||
Revision = revision,
|
||||
Author = author,
|
||||
UserGuid = userGuid,
|
||||
Reason = reason,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<QuestAcceptedEntity?> setAuthor(string id, string author)
|
||||
{
|
||||
var filterBuilder = Builders<QuestAcceptedEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.Id, id);
|
||||
|
||||
var update = Builders<QuestAcceptedEntity>.Update
|
||||
.Set(x => x.Author, author);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestAcceptedEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
}
|
||||
70
UGQDataAccess/Repository/QuestCompletedRepository.cs
Normal file
70
UGQDataAccess/Repository/QuestCompletedRepository.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
using ServerCommon;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class QuestCompletedRepository : BaseRepository<QuestCompletedEntity>
|
||||
{
|
||||
private const string CollectionName = "QuestCompleted";
|
||||
|
||||
public QuestCompletedRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<List<QuestCompletedEntity>> getAll()
|
||||
{
|
||||
return await Collection.Find(Builders<QuestCompletedEntity>.Filter.Empty).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, long revision, string author, string userGuid)
|
||||
{
|
||||
var entity = new QuestCompletedEntity
|
||||
{
|
||||
QuestId = questId,
|
||||
Revision = revision,
|
||||
Author = author,
|
||||
UserGuid = userGuid,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<QuestCompletedEntity?> setAuthor(string id, string author)
|
||||
{
|
||||
var filterBuilder = Builders<QuestCompletedEntity>.Filter;
|
||||
|
||||
var filter = filterBuilder.Eq(x => x.Id, id);
|
||||
|
||||
var update = Builders<QuestCompletedEntity>.Update
|
||||
.Set(x => x.Author, author);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestCompletedEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<long> getCount(string author)
|
||||
{
|
||||
var builder = Builders<QuestCompletedEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.Author, author);
|
||||
|
||||
var result = await Collection.Find(filter).CountDocumentsAsync();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
686
UGQDataAccess/Repository/QuestContentRepository.cs
Normal file
686
UGQDataAccess/Repository/QuestContentRepository.cs
Normal file
@@ -0,0 +1,686 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using Amazon.SecurityToken.Model;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using UGQDataAccess.Repository.Query;
|
||||
using System.Linq.Expressions;
|
||||
using ServerCommon.UGQ;
|
||||
using ServerCommon.UGQ.Models;
|
||||
using UGQDataAccess;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
public class QuestContentRepository : BaseRepository<QuestContentEntity>
|
||||
{
|
||||
internal enum SpotlightSort
|
||||
{
|
||||
MostLiked,
|
||||
MostBookmarked,
|
||||
}
|
||||
|
||||
internal class SportlightQuery
|
||||
{
|
||||
internal SpotlightSort Sort { get; set; }
|
||||
internal DateRange DateRange { get; set; }
|
||||
internal List<QuestBoardItemResult> Items { get; set; } = new();
|
||||
|
||||
internal SportlightQuery(SpotlightSort sort, DateRange dateRange)
|
||||
{
|
||||
Sort = sort;
|
||||
DateRange = dateRange;
|
||||
}
|
||||
}
|
||||
|
||||
private const string CollectionName = "QuestContent";
|
||||
|
||||
public QuestContentRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity> insert(QuestContentEntity entity)
|
||||
{
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<List<QuestContentEntity>> getAll(string userGuid)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var result = await Collection.Find(filter).ToListAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<long> getAllCount()
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
var result = await Collection.Find(filter).CountDocumentsAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<List<QuestContentEntity>> getUserQuests(string userGuid, IEnumerable<QuestContentState> states)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter = builder.Eq(x => x.UserGuid, userGuid) &
|
||||
builder.In(x => x.State, states);
|
||||
|
||||
return await Collection.Find(filter).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<SummaryQueryResult> getSummaries(int pageNumber, int pageSize, string userGuid, QuestContentState state, string? searchText)
|
||||
{
|
||||
var accountCollection = _mongoDatabase.GetCollection<AccountEntity>("Account");
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
var npcNameCollection = _mongoDatabase.GetCollection<NpcNameEntity>("NpcName");
|
||||
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var filter = await QuestContentQuery.summariesFilter(userGuid,
|
||||
UgqSearchType.Title, searchText, state,
|
||||
accountCollection, npcNameCollection);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<SummaryItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<SummaryItemResult>()
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = QuestContentQuery.summariesPipeline<SummaryItemResult>(
|
||||
likeCollection, bookmarkCollection,
|
||||
filter,
|
||||
QuestContentQuery.SummaryItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<SummaryItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
var result = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
return new SummaryQueryResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<AllSummaryQueryResult> getAllSummaries(int pageNumber, int pageSize, QuestContentState state, string? searchText)
|
||||
{
|
||||
var accountCollection = _mongoDatabase.GetCollection<AccountEntity>("Account");
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
var npcNameCollection = _mongoDatabase.GetCollection<NpcNameEntity>("NpcName");
|
||||
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var filter = await QuestContentQuery.summariesFilter(null,
|
||||
UgqSearchType.Title, searchText, state,
|
||||
accountCollection, npcNameCollection);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<SummaryItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<SummaryItemResult>()
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = QuestContentQuery.summariesPipeline<SummaryItemResult>(
|
||||
likeCollection, bookmarkCollection,
|
||||
filter,
|
||||
QuestContentQuery.SummaryItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<SummaryItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
return new AllSummaryQueryResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> get(string id)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, id);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> getByQuestId(long questId)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.QuestId, questId);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> getByQuestIdRevision(long questId, long revision)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.QuestId, questId) & builder.Eq(x => x.Revision, revision);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> updateContent(string id, UGQSaveQuestModel model, int? contentVersion)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, id) &
|
||||
builder.Eq(x => x.ContentVersion, contentVersion);
|
||||
|
||||
var State = QuestContentState.Editable;
|
||||
foreach (var task in model.Tasks)
|
||||
{
|
||||
if (task.ActionId == 0)
|
||||
{
|
||||
State = QuestContentState.Uncomplate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var update = Builders<QuestContentEntity>.Update
|
||||
.Set(x => x.BeaconId, model.BeaconId)
|
||||
.Set(x => x.UgcBeaconGuid, model.UgcBeaconGuid)
|
||||
.Set(x => x.UgcBeaconNickname, model.UgcBeaconNickname)
|
||||
.Set(x => x.Title, model.Title)
|
||||
.Set(x => x.Langs, model.Languages)
|
||||
.Set(x => x.Savelanguage, model.Savelanguage)
|
||||
.Set(x => x.Description, model.Description)
|
||||
.Set(x => x.Cost, model.Cost)
|
||||
.Set(x => x.Tasks, model.Tasks)
|
||||
.Set(x => x.State, State)
|
||||
.Inc(x => x.ContentVersion, 1)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestContentEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> updateTasks(string id, List<TaskEntity> tasks, int? contentVersion)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, id) &
|
||||
builder.Eq(x => x.ContentVersion, contentVersion);
|
||||
|
||||
var update = Builders<QuestContentEntity>.Update
|
||||
.Set(x => x.Tasks, tasks)
|
||||
.Inc(x => x.ContentVersion, 1)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestContentEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> updateImages(string id, string? titleImage, string? bannerImage)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, id);
|
||||
|
||||
var updateBuilder = Builders<QuestContentEntity>.Update;
|
||||
var update = updateBuilder.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
if (titleImage != null)
|
||||
update = updateBuilder.Combine(update, updateBuilder.Set(x => x.TitleImagePath, titleImage));
|
||||
|
||||
if (bannerImage != null)
|
||||
update = updateBuilder.Combine(update, updateBuilder.Set(x => x.BannerImagePath, bannerImage));
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestContentEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<QuestContentEntity?> updateState(string id, long questId, long revision,
|
||||
IEnumerable<QuestContentState> before, QuestContentState after, UgqGradeType? gradeType = null)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, id) &
|
||||
builder.In(x => x.State, before);
|
||||
|
||||
// Test->Standby <20><> <20><> toNextRevision<6F><6E> true<75><65> <20>ؼ<EFBFBD> Live <20><> <20><> Revision + 1 ó<><C3B3> <20>Ѵ<EFBFBD>.
|
||||
bool toNextRevision = before.Any(x => x == QuestContentState.Test) && (after == QuestContentState.Standby);
|
||||
|
||||
var updateBuilder = Builders<QuestContentEntity>.Update;
|
||||
var update = updateBuilder
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.QuestId, questId)
|
||||
.Set(x => x.Revision, revision)
|
||||
.Set(x => x.State, after)
|
||||
.Set(x => x.ToNextRevision, toNextRevision);
|
||||
|
||||
if (gradeType != null)
|
||||
update = updateBuilder.Combine(update, updateBuilder.Set(x => x.GradeType, gradeType));
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestContentEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<(ServerErrorCode, int)> incUploadCounter(string questContentId)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, questContentId);
|
||||
|
||||
var update = Builders<QuestContentEntity>.Update
|
||||
.Inc(x => x.UploadCounter, 1)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestContentEntity>()
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return (ServerErrorCode.Success, updated.UploadCounter);
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> deleteQuest(string userGuid, string questContentId)
|
||||
{
|
||||
var builder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.UserGuid, userGuid) & builder.Eq(x => x.Id, questContentId);
|
||||
|
||||
var update = Builders<QuestContentEntity>.Update
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow)
|
||||
.Set(x => x.DeletedAt, DateTime.UtcNow)
|
||||
.Set(x => x.IsDeleted, true);
|
||||
|
||||
var result = await Collection.UpdateOneAsync(filter, update);
|
||||
if(result.ModifiedCount == 0)
|
||||
return ServerErrorCode.UgqNullEntity;
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<QuestBoardQueryResult> getQuestBoard(string? userGuid,
|
||||
UgqQuestBoardRequest request, int pageSize)
|
||||
{
|
||||
var accountCollection = _mongoDatabase.GetCollection<AccountEntity>("Account");
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
var npcNameCollection = _mongoDatabase.GetCollection<NpcNameEntity>("NpcName");
|
||||
|
||||
request.PageNumber = request.PageNumber < 1 ? 1 : request.PageNumber;
|
||||
|
||||
var filter = await QuestContentQuery.questBoardFilter(userGuid, request.GradeType,
|
||||
request.SearchType, request.SearchText, accountCollection, npcNameCollection);
|
||||
|
||||
var sort = QuestContentQuery.questBoardSort<QuestBoardItemResult>(request.SortType);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<QuestBoardItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<QuestBoardItemResult>()
|
||||
.Sort(sort)
|
||||
.Skip((request.PageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = QuestContentQuery.questBoardPipeline<QuestBoardItemResult>(
|
||||
likeCollection, bookmarkCollection, filter,
|
||||
QuestContentQuery.QuestBoardItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<QuestBoardItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if(count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
return new QuestBoardQueryResult
|
||||
{
|
||||
PageNumber = request.PageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<QuestBoardDetailItemResult?> getQuestBoardDetail(string userGuid, long questId, long revision)
|
||||
{
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
filter &= filterBuilder.Eq(x => x.QuestId, questId);
|
||||
filter &= filterBuilder.Eq(x => x.Revision, revision);
|
||||
filter &= filterBuilder.Eq(x => x.State, QuestContentState.Live);
|
||||
|
||||
Expression<Func<QuestContentQuery.QuestBoardQueryJoin, QuestBoardDetailItemResult>> questBoardDetailItemProjection =
|
||||
x => new QuestBoardDetailItemResult
|
||||
{
|
||||
QuestId = x.QuestId,
|
||||
Revision = x.Revision,
|
||||
Author = x.Author,
|
||||
Title = x.Title,
|
||||
Languages = x.Langs,
|
||||
Description = x.Description,
|
||||
Cost = x.Cost,
|
||||
GradeType = x.GradeType,
|
||||
TitleImagePath = x.TitleImagePath,
|
||||
BannerImagePath = x.BannerImagePath,
|
||||
UpdatedAt = x.UpdatedAt,
|
||||
LikeCount = x.LikeCount,
|
||||
BookmarkCount = x.BookmarkCount,
|
||||
QuestAcceptedCount = x.QuestAcceptedCount,
|
||||
QuestCompletedCount = x.QuestCompletedCount,
|
||||
|
||||
BeaconId = x.BeaconId,
|
||||
UgcBeaconGuid = x.UgcBeaconGuid,
|
||||
UgcBeaconNickname = x.UgcBeaconNickname,
|
||||
|
||||
Liked = x.Likes.Any(x => x.UserGuid == userGuid),
|
||||
Bookmarked = x.Bookmarks.Any(x => x.UserGuid == userGuid),
|
||||
};
|
||||
|
||||
|
||||
var pipeline = QuestContentQuery.questBoardDetailPipeline<QuestBoardDetailItemResult>(
|
||||
likeCollection, bookmarkCollection,
|
||||
filter,
|
||||
questBoardDetailItemProjection);
|
||||
|
||||
return await (await Collection.AggregateAsync(pipeline)).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<QuestBoardQueryResult> getBookmarkQuests(string userGuid, UgqQuestBoardRequest request, int pageSize)
|
||||
{
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
var npcNameCollection = _mongoDatabase.GetCollection<NpcNameEntity>("NpcName");
|
||||
|
||||
request.PageNumber = request.PageNumber < 1 ? 1 : request.PageNumber;
|
||||
|
||||
var filter = await QuestContentQuery.questBoardBookmarkFilter(userGuid,
|
||||
request.GradeType, request.SearchType, request.SearchText,
|
||||
npcNameCollection, bookmarkCollection);
|
||||
|
||||
var sort = QuestContentQuery.questBoardSort<QuestBoardItemResult>(request.SortType);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<QuestBoardItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<QuestBoardItemResult>()
|
||||
.Sort(sort)
|
||||
.Skip((request.PageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = QuestContentQuery.questBoardPipeline<QuestBoardItemResult>(
|
||||
likeCollection, bookmarkCollection, filter,
|
||||
QuestContentQuery.QuestBoardItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<QuestBoardItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
return new QuestBoardQueryResult
|
||||
{
|
||||
PageNumber = request.PageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<QuestBoardSportlightQueryResult> getQuestBoardSpotlight()
|
||||
{
|
||||
var accountCollection = _mongoDatabase.GetCollection<AccountEntity>("Account");
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
|
||||
SportlightQuery[] queries = [
|
||||
new SportlightQuery(SpotlightSort.MostLiked, DataRangeHelper.Yesterday(DateTime.Now)),
|
||||
new SportlightQuery(SpotlightSort.MostBookmarked, DataRangeHelper.Yesterday(DateTime.Now)),
|
||||
|
||||
new SportlightQuery(SpotlightSort.MostLiked, DataRangeHelper.LastWeek(DateTime.Now)),
|
||||
new SportlightQuery(SpotlightSort.MostBookmarked, DataRangeHelper.LastWeek(DateTime.Now)),
|
||||
|
||||
new SportlightQuery(SpotlightSort.MostLiked, DataRangeHelper.LastMonth(DateTime.Now)),
|
||||
new SportlightQuery(SpotlightSort.MostBookmarked, DataRangeHelper.LastMonth(DateTime.Now)),
|
||||
];
|
||||
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
|
||||
foreach (var (value, i) in queries.Select((value, i) => (value, i)))
|
||||
{
|
||||
int limit = 1;
|
||||
|
||||
switch(value.Sort)
|
||||
{
|
||||
case SpotlightSort.MostLiked:
|
||||
{
|
||||
var sort = Builders<QuestBoardItemResult>.Sort.Descending("LikeCount").Descending("CreatedAt");
|
||||
|
||||
var pipeline = QuestContentQuery.questBoardPipeline<QuestBoardItemResult>(
|
||||
likeCollection, bookmarkCollection, filter,
|
||||
QuestContentQuery.QuestBoardItemResultProjection)
|
||||
.Sort(sort)
|
||||
.Limit(limit);
|
||||
|
||||
value.Items = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
}
|
||||
break;
|
||||
case SpotlightSort.MostBookmarked:
|
||||
{
|
||||
var sort = Builders<QuestBoardItemResult>.Sort.Descending("BookmarkCount").Descending("CreatedAt");
|
||||
|
||||
var pipeline = QuestContentQuery.questBoardPipeline<QuestBoardItemResult>(
|
||||
likeCollection, bookmarkCollection, filter,
|
||||
QuestContentQuery.QuestBoardItemResultProjection)
|
||||
.Sort(sort)
|
||||
.Limit(limit);
|
||||
|
||||
value.Items = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
foreach (var (value, i) in queries.Select((value, i) => (value, i)))
|
||||
{
|
||||
if (value.Items.Count == 0)
|
||||
continue;
|
||||
|
||||
long questId = value.Items[0].QuestId;
|
||||
long revision = value.Items[0].Revision;
|
||||
|
||||
for (int s = i + 1; s < queries.Length; s++)
|
||||
{
|
||||
queries[s].Items.RemoveAll(x => x.QuestId == questId && x.Revision == revision);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return new QuestBoardSportlightQueryResult
|
||||
{
|
||||
MostLiked = new()
|
||||
{
|
||||
Today = queries[0].Items.FirstOrDefault(),
|
||||
ThisWeek = queries[2].Items.FirstOrDefault(),
|
||||
ThisMonth = queries[4].Items.FirstOrDefault(),
|
||||
},
|
||||
MostBookmarked = new()
|
||||
{
|
||||
Today = queries[1].Items.FirstOrDefault(),
|
||||
ThisWeek = queries[3].Items.FirstOrDefault(),
|
||||
ThisMonth = queries[5].Items.FirstOrDefault(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<QuestProfitStatsQueryResult> getQuestProfitStats(string userGuid, int pageNumber, int pageSize)
|
||||
{
|
||||
var accountCollection = _mongoDatabase.GetCollection<AccountEntity>("Account");
|
||||
var likeCollection = _mongoDatabase.GetCollection<LikeEntity>("Like");
|
||||
var bookmarkCollection = _mongoDatabase.GetCollection<BookmarkEntity>("Bookmark");
|
||||
var npcNameCollection = _mongoDatabase.GetCollection<NpcNameEntity>("NpcName");
|
||||
|
||||
var questAcceptedCollection = _mongoDatabase.GetCollection<QuestAcceptedEntity>("QuestAccepted");
|
||||
var questCompletedCollection = _mongoDatabase.GetCollection<QuestCompletedEntity>("QuestCompleted");
|
||||
var questAbortedCollection = _mongoDatabase.GetCollection<QuestAbortedEntity>("QuestAborted");
|
||||
var creatorPointHistoryCollection = _mongoDatabase.GetCollection<CreatorPointHistoryEntity>("CreatorPointHistory");
|
||||
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
||||
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
||||
filter &= filterBuilder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<QuestProfitStatsItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<QuestProfitStatsItemResult>()
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = QuestContentQuery.questProfitStatsPipeline<QuestProfitStatsItemResult>(
|
||||
filter,
|
||||
QuestContentQuery.QuestProfitStatsResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<QuestProfitStatsItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
return new QuestProfitStatsQueryResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
62
UGQDataAccess/Repository/QuestDialogRepository.cs
Normal file
62
UGQDataAccess/Repository/QuestDialogRepository.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository;
|
||||
|
||||
|
||||
public class QuestDialogRepository : BaseRepository<QuestDialogEntity>
|
||||
{
|
||||
private const string CollectionName = "QuestDialog";
|
||||
|
||||
public QuestDialogRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<(ServerErrorCode, QuestDialogEntity)> add(QuestDialogEntity entity)
|
||||
{
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return (ServerErrorCode.Success, entity);
|
||||
}
|
||||
|
||||
public async Task<QuestDialogEntity?> get(string id)
|
||||
{
|
||||
var filter = Builders<QuestDialogEntity>.Filter
|
||||
.Eq(x => x.Id, id);
|
||||
|
||||
var entity = await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<List<QuestDialogEntity>> get(IEnumerable<string> ids)
|
||||
{
|
||||
var filter = Builders<QuestDialogEntity>.Filter
|
||||
.In(x => x.Id, ids);
|
||||
|
||||
return await Collection.Find(filter).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<(ServerErrorCode, QuestDialogEntity?)> updateSequences(string dialogId, List<DialogSequenceEntity> sequences)
|
||||
{
|
||||
var filter = Builders<QuestDialogEntity>.Filter
|
||||
.Eq(x => x.Id, dialogId);
|
||||
|
||||
var update = Builders<QuestDialogEntity>.Update
|
||||
.Set(x => x.Sequences, sequences)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestDialogEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
var updated = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
return (ServerErrorCode.Success, updated);
|
||||
}
|
||||
}
|
||||
|
||||
57
UGQDataAccess/Repository/QuestIdSequenceRepository.cs
Normal file
57
UGQDataAccess/Repository/QuestIdSequenceRepository.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class QuestIdSequenceRepository : BaseRepository<QuestIdSequenceEntity>
|
||||
{
|
||||
private const string CollectionName = "QuestIdSequence";
|
||||
|
||||
public QuestIdSequenceRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task init()
|
||||
{
|
||||
var found = await Collection.FindAsync(x => x.Id == "QuestId");
|
||||
if(found.FirstOrDefault() == null)
|
||||
{
|
||||
QuestIdSequenceEntity entity = new ()
|
||||
{
|
||||
Id = "QuestId",
|
||||
Sequence = 0,
|
||||
UpdatedAt = DateTime.UtcNow,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<long> getNextSequence()
|
||||
{
|
||||
var filter = Builders<QuestIdSequenceEntity>.Filter.Eq(x => x.Id, "QuestId");
|
||||
var update = Builders<QuestIdSequenceEntity>.Update
|
||||
.Inc(x => x.Sequence, 1)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<QuestIdSequenceEntity>()
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After
|
||||
};
|
||||
|
||||
var result = await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
|
||||
return result.Sequence;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
UGQDataAccess/Repository/ReportRepository.cs
Normal file
51
UGQDataAccess/Repository/ReportRepository.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using SharpCompress.Common;
|
||||
using UGQDatabase.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using ServerCommon.UGQ;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class ReportRepository : BaseRepository<ReportEntity>
|
||||
{
|
||||
private const string CollectionName = "Report";
|
||||
|
||||
public ReportRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<ReportEntity?> get(long questId, long revision, string userGuid)
|
||||
{
|
||||
var builder = Builders<ReportEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.QuestId, questId) &
|
||||
builder.Eq(x => x.Revision, revision) &
|
||||
builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
ReportEntity? entity = await (await Collection.FindAsync(filter)).FirstOrDefaultAsync();
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> insert(long questId, long revision, string userGuid, string contents)
|
||||
{
|
||||
var entity = new ReportEntity
|
||||
{
|
||||
QuestId = questId,
|
||||
Revision = revision,
|
||||
UserGuid = userGuid,
|
||||
Contents = contents,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
230
UGQDataAccess/Repository/ReserveAccountGradeRepository.cs
Normal file
230
UGQDataAccess/Repository/ReserveAccountGradeRepository.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using UGQDataAccess.Repository.Models;
|
||||
using UGQDataAccess.Settings;
|
||||
using UGQDatabase.Models;
|
||||
|
||||
public enum AccountGradeSortType
|
||||
{
|
||||
UpdatedAtAsc,
|
||||
UpdatedAtDesc,
|
||||
GradeAsc,
|
||||
GradeDesc,
|
||||
ReservedAtAsc,
|
||||
ReservedDesc,
|
||||
}
|
||||
|
||||
public enum AccountGradeProcessType
|
||||
{
|
||||
All,
|
||||
Processing,
|
||||
Completed,
|
||||
}
|
||||
|
||||
namespace UGQDataAccess.Repository
|
||||
{
|
||||
public class ReserveAccountGradeRepository : BaseRepository<ReserveAccountGradeEntity>
|
||||
{
|
||||
private const string CollectionName = "ReserveAccountGrade";
|
||||
|
||||
public ReserveAccountGradeRepository(IMongoClient mongoClient, IOptions<UGQDatabaseSettings> settings) :
|
||||
base(mongoClient, settings.Value.DatabaseName, CollectionName)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<ReserveAccountGradeEntity?> get(string userGuid)
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsCompleted, false);
|
||||
filter &= builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
return await Collection.Find(filter).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<List<ReserveAccountGradeEntity>> get(string userGuid, AccountGradeProcessType processType)
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
switch (processType)
|
||||
{
|
||||
case AccountGradeProcessType.Processing:
|
||||
filter &= builder.Eq(x => x.IsCompleted, false);
|
||||
break;
|
||||
case AccountGradeProcessType.Completed:
|
||||
filter &= builder.Eq(x => x.IsCompleted, true);
|
||||
break;
|
||||
case AccountGradeProcessType.All:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return await Collection.Find(filter).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<long> getAllCount()
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Empty;
|
||||
|
||||
var result = await Collection.Find(filter).CountDocumentsAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<ReserveAccountGradeEntity> reserveAccountGrade(string userGuid, UgqGradeType beforeGrade, UgqGradeType reserveGrade, DateTime reserveTime)
|
||||
{
|
||||
var entity = new ReserveAccountGradeEntity
|
||||
{
|
||||
UserGuid = userGuid,
|
||||
BeforeGradeType = beforeGrade,
|
||||
ReserveGradeType = reserveGrade,
|
||||
ReserveTime = reserveTime,
|
||||
UpdatedAt = DateTime.UtcNow,
|
||||
IsCompleted = false,
|
||||
};
|
||||
|
||||
await Collection.InsertOneAsync(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<ReserveAccountGradeEntity> modifyReserveAccountGrade(string reserveId, UgqGradeType reserveGrade, DateTime reserveTime)
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsCompleted, false);
|
||||
|
||||
filter &= builder.Eq(x => x.Id, reserveId);
|
||||
|
||||
var update = Builders<ReserveAccountGradeEntity>.Update
|
||||
.Set(x => x.ReserveGradeType, reserveGrade)
|
||||
.Set(x => x.ReserveTime, reserveTime)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var options = new FindOneAndUpdateOptions<ReserveAccountGradeEntity>
|
||||
{
|
||||
ReturnDocument = ReturnDocument.After,
|
||||
};
|
||||
|
||||
return await Collection.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public async Task<List<ReserveAccountGradeEntity>> completeReserveAccountGrade()
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsCompleted, false);
|
||||
filter &= builder.Lte(x => x.ReserveTime, DateTime.UtcNow);
|
||||
|
||||
var update = Builders<ReserveAccountGradeEntity>.Update
|
||||
.Set(x => x.IsCompleted, true)
|
||||
.Set(x => x.UpdatedAt, DateTime.UtcNow);
|
||||
|
||||
var result = await Collection.Find(filter).ToListAsync();
|
||||
await Collection.UpdateManyAsync(filter, update);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> deleteReserveAccountGrade(string reserveId)
|
||||
{
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = builder.Eq(x => x.IsCompleted, false);
|
||||
filter &= builder.Eq(x => x.Id, reserveId);
|
||||
|
||||
var result = await Collection.DeleteOneAsync(filter);
|
||||
if (result.DeletedCount == 0)
|
||||
return ServerErrorCode.UgqNullEntity;
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<AllReserveAccountGradeResult> getAccounts(int pageNumber, int pageSize, AccountGradeSortType sortType, AccountGradeProcessType processType, string userGuid)
|
||||
{
|
||||
pageNumber = pageNumber < 1 ? 1 : pageNumber;
|
||||
|
||||
var builder = Builders<ReserveAccountGradeEntity>.Filter;
|
||||
var filter = Builders<ReserveAccountGradeEntity>.Filter.Empty;
|
||||
|
||||
switch (processType)
|
||||
{
|
||||
case AccountGradeProcessType.Processing:
|
||||
filter = builder.Eq(x => x.IsCompleted, false);
|
||||
break;
|
||||
case AccountGradeProcessType.Completed:
|
||||
filter = builder.Eq(x => x.IsCompleted, true);
|
||||
break;
|
||||
case AccountGradeProcessType.All:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(userGuid != string.Empty)
|
||||
filter &= builder.Eq(x => x.UserGuid, userGuid);
|
||||
|
||||
var sortBuilder = Builders<ReserveAccountGradeItemResult>.Sort;
|
||||
SortDefinition<ReserveAccountGradeItemResult> sort;
|
||||
switch (sortType)
|
||||
{
|
||||
case AccountGradeSortType.UpdatedAtAsc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Ascending("UpdatedAt");
|
||||
break;
|
||||
case AccountGradeSortType.UpdatedAtDesc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Descending("UpdatedAt");
|
||||
break;
|
||||
case AccountGradeSortType.GradeAsc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Ascending("CurrentGradeType");
|
||||
break;
|
||||
case AccountGradeSortType.GradeDesc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Descending("CurrentGradeType");
|
||||
break;
|
||||
case AccountGradeSortType.ReservedAtAsc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Ascending("ReserveTime");
|
||||
break;
|
||||
case AccountGradeSortType.ReservedDesc:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Descending("ReserveTime");
|
||||
break;
|
||||
default:
|
||||
sort = Builders<ReserveAccountGradeItemResult>.Sort.Descending("UpdatedAt");
|
||||
break;
|
||||
}
|
||||
|
||||
var countFacet = AggregateFacet.Create("count",
|
||||
new EmptyPipelineDefinition<ReserveAccountGradeItemResult>()
|
||||
.Count()
|
||||
);
|
||||
|
||||
var pagingFacet = AggregateFacet.Create("paging",
|
||||
new EmptyPipelineDefinition<ReserveAccountGradeItemResult>()
|
||||
.Sort(sort)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Limit(pageSize)
|
||||
);
|
||||
|
||||
var pipeline = ReserveAccountGradeQuery.allReserveAccountGradePipeline<ReserveAccountGradeItemResult>(
|
||||
filter,
|
||||
ReserveAccountGradeQuery.ReserveAccountGradeItemResultProjection)
|
||||
.Facet(countFacet, pagingFacet);
|
||||
|
||||
var aggregation = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
var count = aggregation.First()
|
||||
.Facets.First(x => x.Name == "count")
|
||||
.Output<AggregateCountResult>()
|
||||
?.FirstOrDefault()
|
||||
?.Count;
|
||||
|
||||
var paging = aggregation.First()
|
||||
.Facets.First(x => x.Name == "paging")
|
||||
.Output<ReserveAccountGradeItemResult>();
|
||||
|
||||
int totalPages = 0;
|
||||
if (count != null)
|
||||
totalPages = (int)Math.Ceiling((double)count / pageSize);
|
||||
|
||||
var result = await (await Collection.AggregateAsync(pipeline)).ToListAsync();
|
||||
return new AllReserveAccountGradeResult
|
||||
{
|
||||
PageNumber = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
Items = paging.ToList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user