Files
Yi.Framework/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/CollectiblesManager.cs
2024-11-24 19:07:42 +08:00

147 lines
5.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Services;
using Volo.Abp.Users;
using Yi.Framework.DigitalCollectibles.Domain.Entities;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Caches;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
/// <summary>
/// 藏品领域服务
/// 用于管理用户的藏品库存、藏品的业务逻辑
/// </summary>
public class CollectiblesManager:DomainService
{
private readonly ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> _collectiblesUserStoreRepository;
private readonly ISqlSugarRepository<CollectiblesAggregateRoot> _collectiblesRepository;
private readonly IDistributedCache<List<CollectiblesValueCacheItem>> _distributedCache;
public CollectiblesManager(ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> collectiblesUserStoreRepository, ISqlSugarRepository<CollectiblesAggregateRoot> collectiblesRepository, IDistributedCache<List<CollectiblesValueCacheItem>> distributedCache)
{
_collectiblesUserStoreRepository = collectiblesUserStoreRepository;
_collectiblesRepository = collectiblesRepository;
_distributedCache = distributedCache;
}
/// <summary>
/// 获取某个用户的价值
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<decimal> GetAccountValueAsync(Guid userId)
{
var collectiblesList = await _collectiblesUserStoreRepository._DbQueryable
.Where(store => store.UserId == userId)
.LeftJoin<CollectiblesAggregateRoot>((store, c) => store.CollectiblesId == c.Id)
.Select((store, c) =>
new
{
c.Id,
c.ValueNumber
}
).ToListAsync();
var totalValue=ComputeValue(collectiblesList.Select(x=> (x.Id,x.ValueNumber)).ToList());
return totalValue;
}
//计算价值,需要每个藏品的唯一值和藏品的价值即可
private decimal ComputeValue(List<(Guid collectiblesId,decimal valueNumber)> data)
{
var groupBy = data.GroupBy(x => x.collectiblesId);
decimal totalValue = 0;
//首个价值百分之百后续每个只有百分之40最大10个
foreach (var groupByItem in groupBy)
{
foreach (var item in groupByItem.Select((value, index) => new { value, index }))
{
if (item.index == 0)
{
totalValue += item.value.valueNumber;
}
else if (item.index == 10)
{
//到第11个直接跳出循环
break;
}
else
{
totalValue += item.value.valueNumber * 0.4m;
}
}
}
return totalValue;
}
/// <summary>
/// 获取全量的排行榜
/// </summary>
/// <returns></returns>
public async Task<List<CollectiblesValueCacheItem>> GetAllAccountValueByCacheAsync()
{
return await _distributedCache.GetOrAddAsync("AllAccountValue", async () => await GetAccountValueAsync(),
() => new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1)
});
}
private async Task<List<CollectiblesValueCacheItem>> GetAccountValueAsync()
{
var output = new List<CollectiblesValueCacheItem>();
//获取全部用户的库存
var allStore= await _collectiblesUserStoreRepository._DbQueryable.ToListAsync();
//获取全部藏品
var allCollectiblesDic= (await _collectiblesRepository._DbQueryable.ToListAsync()).ToDictionary(x=>x.Id,y=>y.ValueNumber);
//根据用户分组
var userGroup= allStore.GroupBy(x => x.UserId);
//每个用户进行计算价值
foreach (var item in userGroup)
{
var value= ComputeValue(item.Select(x => (x.CollectiblesId, allCollectiblesDic[x.CollectiblesId])).ToList());
output.Add(new CollectiblesValueCacheItem
{
UserId = item.Key,
Value = value
});
}
return output;
}
/// <summary>
/// 全量更新藏品价值
/// </summary>
/// <returns></returns>
public async Task UpdateAllValueAsync()
{
//全部藏品
var collectibles = await _collectiblesRepository.GetListAsync();
foreach (var item in collectibles)
{
var defaultValue= item.Rarity.GetDefaultValue();
//计算实际的百分比
var realValueRate= CalculateValue(item.FindTotal);
var realValue = Math.Round(defaultValue * realValueRate);
item.ValueNumber = realValue.To<decimal>();
}
await _collectiblesRepository.UpdateRangeAsync(collectibles);
}
/// <summary>
/// 价值计算公式
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
private double CalculateValue(double x)
{
return 0.1 + 0.9 * Math.Exp(-0.00824 * (x - 1));
}
}