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; /// /// 藏品领域服务 /// 用于管理用户的藏品库存、藏品的业务逻辑 /// public class CollectiblesManager:DomainService { private readonly ISqlSugarRepository _collectiblesUserStoreRepository; private readonly ISqlSugarRepository _collectiblesRepository; private readonly IDistributedCache> _distributedCache; public CollectiblesManager(ISqlSugarRepository collectiblesUserStoreRepository, ISqlSugarRepository collectiblesRepository, IDistributedCache> distributedCache) { _collectiblesUserStoreRepository = collectiblesUserStoreRepository; _collectiblesRepository = collectiblesRepository; _distributedCache = distributedCache; } /// /// 获取某个用户的价值 /// /// /// public async Task GetAccountValueAsync(Guid userId) { var collectiblesList = await _collectiblesUserStoreRepository._DbQueryable .Where(store => store.UserId == userId) .LeftJoin((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; } /// /// 获取全量的排行榜 /// /// public async Task> GetAllAccountValueByCacheAsync() { return await _distributedCache.GetOrAddAsync("AllAccountValue", async () => await GetAccountValueAsync(), () => new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1) }); } private async Task> GetAccountValueAsync() { var output = new List(); //获取全部用户的库存 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; } /// /// 全量更新藏品价值 /// /// 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(); } await _collectiblesRepository.UpdateRangeAsync(collectibles); } /// /// 价值计算公式 /// /// /// private double CalculateValue(double x) { return 0.1 + 0.9 * Math.Exp(-0.00824 * (x - 1)); } }