feat: 完成积分、价值排行榜
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.BbsUser;
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
public class MoneyTopUserDto
|
/// <summary>
|
||||||
|
/// 用户排行榜
|
||||||
|
/// </summary>
|
||||||
|
public class BaseAnalyseTopUserDto
|
||||||
{
|
{
|
||||||
|
public Guid UserId { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public string? Nick { get; set; }
|
public string? Nick { get; set; }
|
||||||
public decimal Money { get; set; }
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public string? Icon { get; set; }
|
public string? Icon { get; set; }
|
||||||
public int Level { get; set; }
|
public int Level { get; set; }
|
||||||
@@ -18,5 +21,4 @@ public class MoneyTopUserDto
|
|||||||
/// 用户限制
|
/// 用户限制
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UserLimitEnum UserLimit { get; set; }
|
public UserLimitEnum UserLimit { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
public class MoneyTopUserDto:BaseAnalyseTopUserDto
|
||||||
|
{
|
||||||
|
public decimal Money { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
public class PointsTopUserDto:BaseAnalyseTopUserDto
|
||||||
|
{
|
||||||
|
public int Points { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
public class ValueTopUserDto:BaseAnalyseTopUserDto
|
||||||
|
{
|
||||||
|
public decimal Value { get; set; }
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\digital-collectibles\Yi.Framework.DigitalCollectibles.Application.Contracts\Yi.Framework.DigitalCollectibles.Application.Contracts.csproj" />
|
||||||
<ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
<ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
||||||
<ProjectReference Include="..\Yi.Framework.Bbs.Domain.Shared\Yi.Framework.Bbs.Domain.Shared.csproj" />
|
<ProjectReference Include="..\Yi.Framework.Bbs.Domain.Shared\Yi.Framework.Bbs.Domain.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Yi.Framework.Bbs.Domain.Entities;
|
|||||||
using Yi.Framework.Bbs.Domain.Entities.Integral;
|
using Yi.Framework.Bbs.Domain.Entities.Integral;
|
||||||
using Yi.Framework.Bbs.Domain.Managers;
|
using Yi.Framework.Bbs.Domain.Managers;
|
||||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.IServices;
|
||||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||||
using Yi.Framework.Rbac.Domain.Authorization;
|
using Yi.Framework.Rbac.Domain.Authorization;
|
||||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||||
@@ -20,11 +21,16 @@ namespace Yi.Framework.Bbs.Application.Services.Analyses
|
|||||||
{
|
{
|
||||||
private BbsUserManager _bbsUserManager;
|
private BbsUserManager _bbsUserManager;
|
||||||
private IOnlineService _onlineService;
|
private IOnlineService _onlineService;
|
||||||
|
private readonly IPointAnalyseService _pointAnalyseService;
|
||||||
|
private readonly IValueAnalyseService _valueAnalyseService;
|
||||||
|
|
||||||
public BbsUserAnalyseService(BbsUserManager bbsUserManager, IOnlineService onlineService)
|
public BbsUserAnalyseService(BbsUserManager bbsUserManager, IOnlineService onlineService,
|
||||||
|
IPointAnalyseService pointAnalyseService, IValueAnalyseService valueAnalyseService)
|
||||||
{
|
{
|
||||||
_bbsUserManager = bbsUserManager;
|
_bbsUserManager = bbsUserManager;
|
||||||
_onlineService = onlineService;
|
_onlineService = onlineService;
|
||||||
|
_pointAnalyseService = pointAnalyseService;
|
||||||
|
_valueAnalyseService = valueAnalyseService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,5 +175,116 @@ namespace Yi.Framework.Bbs.Application.Services.Analyses
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 积分排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("analyse/dc-user/points-top/{userId?}")]
|
||||||
|
public async Task<PagedResultDto<PointsTopUserDto>> GetPointsTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId)
|
||||||
|
{
|
||||||
|
var result = await _pointAnalyseService.GetValueTopAsync(input, null);
|
||||||
|
|
||||||
|
var userIds = result.Items.Select(x => x.UserId).ToList();
|
||||||
|
|
||||||
|
var baseOutput = await _bbsUserManager._userRepository._DbQueryable
|
||||||
|
.Where(u => userIds.Contains(u.Id))
|
||||||
|
.LeftJoin<BbsUserExtraInfoEntity>((u, info) => u.Id == info.UserId)
|
||||||
|
.Select((u, info) =>
|
||||||
|
new BaseAnalyseTopUserDto
|
||||||
|
{
|
||||||
|
UserName = u.UserName,
|
||||||
|
Nick = u.Nick,
|
||||||
|
Icon = u.Icon,
|
||||||
|
Level = info.Level,
|
||||||
|
UserLimit = info.UserLimit,
|
||||||
|
UserId = info.UserId
|
||||||
|
}
|
||||||
|
).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
var output = new List<PointsTopUserDto>();
|
||||||
|
result.Items.ToList().ForEach(x =>
|
||||||
|
{
|
||||||
|
var currentUserInfo = baseOutput.Where(u => u.UserId == x.UserId).FirstOrDefault();
|
||||||
|
|
||||||
|
if (currentUserInfo is not null)
|
||||||
|
{
|
||||||
|
output.Add(new PointsTopUserDto
|
||||||
|
{
|
||||||
|
UserName = currentUserInfo.UserName,
|
||||||
|
Nick = currentUserInfo.Nick,
|
||||||
|
Order = x.Order,
|
||||||
|
Icon = currentUserInfo.Icon,
|
||||||
|
Level = currentUserInfo.Level,
|
||||||
|
LevelName = _bbsUserManager._levelCacheDic[currentUserInfo.Level].Name,
|
||||||
|
UserLimit = UserLimitEnum.Normal,
|
||||||
|
Points = x.Points
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new PagedResultDto<PointsTopUserDto>
|
||||||
|
{
|
||||||
|
Items = output,
|
||||||
|
TotalCount = result.TotalCount
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 价值排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("analyse/dc-user/value-top/{userId?}")]
|
||||||
|
public async Task<PagedResultDto<ValueTopUserDto>> GetValueTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId)
|
||||||
|
{
|
||||||
|
var result = await _valueAnalyseService.GetValueTopAsync(input, null);
|
||||||
|
|
||||||
|
var userIds = result.Items.Select(x => x.UserId).ToList();
|
||||||
|
|
||||||
|
var baseOutput = await _bbsUserManager._userRepository._DbQueryable
|
||||||
|
.Where(u => userIds.Contains(u.Id))
|
||||||
|
.LeftJoin<BbsUserExtraInfoEntity>((u, info) => u.Id == info.UserId)
|
||||||
|
.Select((u, info) =>
|
||||||
|
new BaseAnalyseTopUserDto
|
||||||
|
{
|
||||||
|
UserName = u.UserName,
|
||||||
|
Nick = u.Nick,
|
||||||
|
Icon = u.Icon,
|
||||||
|
Level = info.Level,
|
||||||
|
UserLimit = info.UserLimit,
|
||||||
|
UserId = info.UserId
|
||||||
|
}
|
||||||
|
).ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
var output = new List<ValueTopUserDto>();
|
||||||
|
result.Items.ToList().ForEach(x =>
|
||||||
|
{
|
||||||
|
var currentUserInfo = baseOutput.Where(u => u.UserId == x.UserId).FirstOrDefault();
|
||||||
|
|
||||||
|
if (currentUserInfo is not null)
|
||||||
|
{
|
||||||
|
output.Add(new ValueTopUserDto
|
||||||
|
{
|
||||||
|
UserName = currentUserInfo.UserName,
|
||||||
|
Nick = currentUserInfo.Nick,
|
||||||
|
Order = x.Order,
|
||||||
|
Icon = currentUserInfo.Icon,
|
||||||
|
Level = currentUserInfo.Level,
|
||||||
|
LevelName = _bbsUserManager._levelCacheDic[currentUserInfo.Level].Name,
|
||||||
|
UserLimit = UserLimitEnum.Normal,
|
||||||
|
Value = x.Value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new PagedResultDto<ValueTopUserDto>
|
||||||
|
{
|
||||||
|
Items = output,
|
||||||
|
TotalCount = result.TotalCount
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
public class DcPointsTopUserDto
|
||||||
|
{
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
public int Points { get; set; }
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
public class DcValueTopUserDto
|
||||||
|
{
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
public decimal Value { get; set; }
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.IServices;
|
||||||
|
|
||||||
|
public interface IPointAnalyseService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 积分排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
// [HttpGet("analyse/dc-user/points-top/{userId?}")]
|
||||||
|
Task<PagedResultDto<DcPointsTopUserDto>> GetValueTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
|
||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Contracts.IServices;
|
||||||
|
|
||||||
|
public interface IValueAnalyseService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 价值排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
// [HttpGet("analyse/dc-user/value-top/{userId?}")]
|
||||||
|
Task<PagedResultDto<DcValueTopUserDto>> GetValueTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId);
|
||||||
|
}
|
||||||
@@ -7,8 +7,4 @@
|
|||||||
<ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
<ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="IServices\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SqlSugar;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.IServices;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Domain.Entities;
|
||||||
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Services.Analyses;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户积分分析
|
||||||
|
/// </summary>
|
||||||
|
public class PointAnalyseService: ApplicationService,IPointAnalyseService
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ISqlSugarRepository<InvitationCodeAggregateRoot> _repository;
|
||||||
|
|
||||||
|
public PointAnalyseService(ISqlSugarRepository<InvitationCodeAggregateRoot> repository)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 积分排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
// [HttpGet("analyse/dc-user/points-top/{userId?}")]
|
||||||
|
[RemoteService(isEnabled:false)]
|
||||||
|
public async Task<PagedResultDto<DcPointsTopUserDto>> GetValueTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId)
|
||||||
|
{
|
||||||
|
|
||||||
|
var pageIndex = input.SkipCount;
|
||||||
|
RefAsync<int> total = 0;
|
||||||
|
var output = await _repository._DbQueryable
|
||||||
|
.OrderByDescending(x=>x.PointsNumber)
|
||||||
|
.Select(x =>
|
||||||
|
new DcPointsTopUserDto{
|
||||||
|
UserId = x.UserId,
|
||||||
|
Points = x.PointsNumber,
|
||||||
|
Order=SqlFunc.RowNumber(SqlFunc.Desc(x.PointsNumber))
|
||||||
|
})
|
||||||
|
.ToPageListAsync(pageIndex, input.MaxResultCount, total);
|
||||||
|
return new PagedResultDto<DcPointsTopUserDto>
|
||||||
|
{
|
||||||
|
Items = output,
|
||||||
|
TotalCount = total
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SqlSugar;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Analyse;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Application.Contracts.IServices;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Domain.Entities;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Domain.Managers;
|
||||||
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
|
namespace Yi.Framework.DigitalCollectibles.Application.Services.Analyses;
|
||||||
|
|
||||||
|
public class ValueAnalyseService: ApplicationService,IValueAnalyseService
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly CollectiblesManager _manager;
|
||||||
|
|
||||||
|
public ValueAnalyseService( CollectiblesManager manager)
|
||||||
|
{
|
||||||
|
_manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 价值排行榜
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
// [HttpGet("analyse/dc-user/value-top/{userId?}")]
|
||||||
|
[RemoteService(isEnabled:false)]
|
||||||
|
public async Task<PagedResultDto<DcValueTopUserDto>> GetValueTopAsync([FromQuery] PagedResultRequestDto input,
|
||||||
|
[FromRoute] Guid? userId)
|
||||||
|
{
|
||||||
|
//每个人的价值需要进行计算才能获取,这里计算时间较长,放入缓存,绝对过期
|
||||||
|
var allValue= await _manager.GetAllAccountValueByCacheAsync();
|
||||||
|
var output = allValue.OrderByDescending(x => x.Value).Select((x, index) => new DcValueTopUserDto
|
||||||
|
{
|
||||||
|
UserId = x.UserId,
|
||||||
|
Value = x.Value,
|
||||||
|
Order = index + 1
|
||||||
|
}).Skip((input.SkipCount - 1) * input.MaxResultCount) // 跳过前面(当前页码 - 1)* 每页数量条记录
|
||||||
|
.Take(input.MaxResultCount).ToList();
|
||||||
|
return new PagedResultDto<DcValueTopUserDto>
|
||||||
|
{
|
||||||
|
Items = output,
|
||||||
|
TotalCount = allValue.Count
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Caches;
|
||||||
|
|
||||||
|
public class CollectiblesValueCacheItem
|
||||||
|
{
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
public decimal Value { get; set; }
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
using Volo.Abp.Domain.Services;
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
|
using Volo.Abp.Caching;
|
||||||
|
using Volo.Abp.Domain.Services;
|
||||||
using Volo.Abp.Users;
|
using Volo.Abp.Users;
|
||||||
using Yi.Framework.DigitalCollectibles.Domain.Entities;
|
using Yi.Framework.DigitalCollectibles.Domain.Entities;
|
||||||
|
using Yi.Framework.DigitalCollectibles.Domain.Shared.Caches;
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
|
namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
|
||||||
@@ -11,13 +14,20 @@ namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
|
|||||||
public class CollectiblesManager:DomainService
|
public class CollectiblesManager:DomainService
|
||||||
{
|
{
|
||||||
private readonly ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> _collectiblesUserStoreRepository;
|
private readonly ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> _collectiblesUserStoreRepository;
|
||||||
|
private readonly ISqlSugarRepository<CollectiblesAggregateRoot> _collectiblesRepository;
|
||||||
public CollectiblesManager(ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> collectiblesUserStoreRepository)
|
private readonly IDistributedCache<List<CollectiblesValueCacheItem>> _distributedCache;
|
||||||
|
public CollectiblesManager(ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> collectiblesUserStoreRepository, ISqlSugarRepository<CollectiblesAggregateRoot> collectiblesRepository, IDistributedCache<List<CollectiblesValueCacheItem>> distributedCache)
|
||||||
{
|
{
|
||||||
_collectiblesUserStoreRepository = collectiblesUserStoreRepository;
|
_collectiblesUserStoreRepository = collectiblesUserStoreRepository;
|
||||||
|
_collectiblesRepository = collectiblesRepository;
|
||||||
|
_distributedCache = distributedCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个用户的价值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task<decimal> GetAccountValueAsync(Guid userId)
|
public async Task<decimal> GetAccountValueAsync(Guid userId)
|
||||||
{
|
{
|
||||||
var collectiblesList = await _collectiblesUserStoreRepository._DbQueryable
|
var collectiblesList = await _collectiblesUserStoreRepository._DbQueryable
|
||||||
@@ -30,7 +40,14 @@ public class CollectiblesManager:DomainService
|
|||||||
c.ValueNumber
|
c.ValueNumber
|
||||||
}
|
}
|
||||||
).ToListAsync();
|
).ToListAsync();
|
||||||
var groupBy = collectiblesList.GroupBy(x => x.Id);
|
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;
|
decimal totalValue = 0;
|
||||||
|
|
||||||
//首个价值百分之百,后续每个只有百分之40,最大10个
|
//首个价值百分之百,后续每个只有百分之40,最大10个
|
||||||
@@ -41,7 +58,7 @@ public class CollectiblesManager:DomainService
|
|||||||
|
|
||||||
if (item.index == 0)
|
if (item.index == 0)
|
||||||
{
|
{
|
||||||
totalValue += item.value.ValueNumber;
|
totalValue += item.value.valueNumber;
|
||||||
}
|
}
|
||||||
else if (item.index == 10)
|
else if (item.index == 10)
|
||||||
{
|
{
|
||||||
@@ -50,11 +67,48 @@ public class CollectiblesManager:DomainService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
totalValue += item.value.ValueNumber * 0.4m;
|
totalValue += item.value.valueNumber * 0.4m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalValue;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,11 @@ export function getRecommendedFriend(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取积分排行
|
* 获取钱钱排行
|
||||||
* @param {*} data
|
* @param {*} data
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getRankingPoints(data) {
|
export function getMoneyTop(data) {
|
||||||
return request({
|
return request({
|
||||||
url: "/analyse/bbs-user/money-top",
|
url: "/analyse/bbs-user/money-top",
|
||||||
method: "get",
|
method: "get",
|
||||||
@@ -39,6 +39,35 @@ export function getRankingPoints(data) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取价值排行
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getValueTop(data) {
|
||||||
|
return request({
|
||||||
|
url: "/analyse/dc-user/value-top",
|
||||||
|
method: "get",
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取积分排行
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getPointsTop(data) {
|
||||||
|
return request({
|
||||||
|
url: "/analyse/dc-user/points-top",
|
||||||
|
method: "get",
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户分析
|
* 获取用户分析
|
||||||
* @param {*} data
|
* @param {*} data
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ import {getWeek} from "@/apis/accessApi.js";
|
|||||||
import {
|
import {
|
||||||
getRecommendedTopic,
|
getRecommendedTopic,
|
||||||
getRecommendedFriend,
|
getRecommendedFriend,
|
||||||
getRankingPoints,
|
getMoneyTop,
|
||||||
getUserAnalyse,
|
getUserAnalyse,
|
||||||
getRegisterAnalyse
|
getRegisterAnalyse
|
||||||
} from "@/apis/analyseApi.js";
|
} from "@/apis/analyseApi.js";
|
||||||
@@ -345,7 +345,7 @@ const init = async () => {
|
|||||||
weekList.value = weekData;
|
weekList.value = weekData;
|
||||||
})(),
|
})(),
|
||||||
(async () => {
|
(async () => {
|
||||||
const {data: pointData, config: pointConfig} = await getRankingPoints();
|
const {data: pointData, config: pointConfig} = await getMoneyTop();
|
||||||
pointList.value = pointData.items;
|
pointList.value = pointData.items;
|
||||||
isPointFinished.value = pointConfig.isFinish;
|
isPointFinished.value = pointConfig.isFinish;
|
||||||
})(),
|
})(),
|
||||||
|
|||||||
@@ -3,19 +3,21 @@ import AwardPedestal from "./components/AwardPedestal.vue";
|
|||||||
import AvatarInfo from "@/components/AvatarInfo.vue";
|
import AvatarInfo from "@/components/AvatarInfo.vue";
|
||||||
import { onMounted, reactive, ref, computed } from "vue";
|
import { onMounted, reactive, ref, computed } from "vue";
|
||||||
import {
|
import {
|
||||||
getRankingPoints,
|
getMoneyTop,
|
||||||
|
getValueTop,
|
||||||
|
getPointsTop
|
||||||
} from "@/apis/analyseApi.js";
|
} from "@/apis/analyseApi.js";
|
||||||
const pointList = ref([]);
|
const pointList = ref([]);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const moneyQuery = reactive({ skipCount: 1, maxResultCount: 30 });
|
const moneyQuery = reactive({ skipCount: 1, maxResultCount: 30 });
|
||||||
|
const tabSelect=ref("money");
|
||||||
const isFirstPage = computed(() => {
|
const isFirstPage = computed(() => {
|
||||||
return moneyQuery.skipCount == 1;
|
return moneyQuery.skipCount === 1;
|
||||||
})
|
})
|
||||||
|
|
||||||
const pointListFilter=computed(() => {
|
const pointListFilter=computed(() => {
|
||||||
//如果是第一页,去掉前3个
|
//如果是第一页,去掉前3个
|
||||||
if(moneyQuery.skipCount == 1)
|
if(moneyQuery.skipCount === 1)
|
||||||
{
|
{
|
||||||
return pointList.value.slice(3);
|
return pointList.value.slice(3);
|
||||||
}
|
}
|
||||||
@@ -29,18 +31,49 @@ onMounted(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const initData = async () => {
|
const initData = async () => {
|
||||||
const { data: pointData } = await getRankingPoints(moneyQuery);
|
switch (tabSelect.value)
|
||||||
pointList.value = pointData.items;;
|
{
|
||||||
|
case "money":
|
||||||
|
const { data: pointData } = await getMoneyTop(moneyQuery);
|
||||||
|
pointList.value = pointData.items;
|
||||||
total.value = pointData.totalCount
|
total.value = pointData.totalCount
|
||||||
|
break;
|
||||||
|
case "value":
|
||||||
|
const { data: pointData2 } = await getValueTop(moneyQuery);
|
||||||
|
pointData2.items.forEach(item => {item.money=item.value})
|
||||||
|
pointList.value = pointData2.items;
|
||||||
|
total.value = pointData2.totalCount
|
||||||
|
break;
|
||||||
|
case "points":
|
||||||
|
const { data: pointData3 } = await getPointsTop(moneyQuery);
|
||||||
|
pointData3.items.forEach(item => {item.money=item.points})
|
||||||
|
pointList.value = pointData3.items;
|
||||||
|
total.value = pointData3.totalCount
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//分页事件
|
//分页事件
|
||||||
const changePage = async (currentPage) => {
|
const changePage = async (currentPage) => {
|
||||||
await initData();
|
await initData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//切换tab
|
||||||
|
const handleClickTabs=async (pane) => {
|
||||||
|
|
||||||
|
tabSelect.value=pane.paneName;
|
||||||
|
moneyQuery.skipCount = 1;
|
||||||
|
await initData();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-body">
|
<div class="content-body">
|
||||||
|
<el-tabs v-model="tabSelect" @tab-click="handleClickTabs" class="tabs">
|
||||||
|
<el-tab-pane label="钱钱" name="money"><p class="tab-title">钱钱排行榜</p></el-tab-pane>
|
||||||
|
<el-tab-pane label="价值" name="value"><p class="tab-title">价值排行榜</p></el-tab-pane>
|
||||||
|
<el-tab-pane label="积分" name="points"><p class="tab-title">积分排行榜</p></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
<AwardPedestal v-show="isFirstPage" :goldUserInfo="pointList[0]" :silverUserInfo="pointList[1]"
|
<AwardPedestal v-show="isFirstPage" :goldUserInfo="pointList[0]" :silverUserInfo="pointList[1]"
|
||||||
:bronzeUserInfo="pointList[2]" />
|
:bronzeUserInfo="pointList[2]" />
|
||||||
<div v-for="item in pointListFilter" :key="item.id" class="list-div">
|
<div v-for="item in pointListFilter" :key="item.id" class="list-div">
|
||||||
@@ -110,4 +143,15 @@ const changePage = async (currentPage) => {
|
|||||||
.list-div:hover {
|
.list-div:hover {
|
||||||
background-color: #f7f8fa;
|
background-color: #f7f8fa;
|
||||||
}
|
}
|
||||||
|
.tabs :deep(.el-tabs__nav-wrap)
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center !important;
|
||||||
|
}
|
||||||
|
.tab-title
|
||||||
|
{
|
||||||
|
text-align: center;
|
||||||
|
font-size: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ h3{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gold:hover {
|
.gold:hover {
|
||||||
box-shadow: 0 0 20px 10px rgba(255, 215, 0, 0.7); /* 金色光辉效果 */
|
box-shadow: 0 0 40px 20px rgba(255, 215, 0, 0.7); /* 金色光辉效果 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.gold {
|
.gold {
|
||||||
@@ -76,13 +76,18 @@ h3{
|
|||||||
height: 250px;
|
height: 250px;
|
||||||
box-shadow: 0 8px 20px rgba(255, 215, 0, 0.5);
|
box-shadow: 0 8px 20px rgba(255, 215, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
.silver:hover {
|
||||||
|
box-shadow: 0 0 20px 10px rgba(192, 192, 192, 0.7); /* 金色光辉效果 */
|
||||||
|
}
|
||||||
|
|
||||||
.silver {
|
.silver {
|
||||||
background: linear-gradient(to bottom, #c0c0c0 0%, #d3d3d3 100%);
|
background: linear-gradient(to bottom, #c0c0c0 0%, #d3d3d3 100%);
|
||||||
height: 200px;
|
height: 200px;
|
||||||
box-shadow: 0 6px 18px rgba(192, 192, 192, 0.5);
|
box-shadow: 0 6px 18px rgba(192, 192, 192, 0.5);
|
||||||
}
|
}
|
||||||
|
.bronze:hover {
|
||||||
|
box-shadow: 0 0 20px 10px rgba(205, 127, 50, 0.7); /* 金色光辉效果 */
|
||||||
|
}
|
||||||
.bronze {
|
.bronze {
|
||||||
background: linear-gradient(to bottom, #cd7f32 0%, #a0522d 100%);
|
background: linear-gradient(to bottom, #cd7f32 0%, #a0522d 100%);
|
||||||
height: 170px;
|
height: 170px;
|
||||||
|
|||||||
Reference in New Issue
Block a user