diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/CollectiblesService.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/CollectiblesService.cs
index e68bed84..8e8ce010 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/CollectiblesService.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/CollectiblesService.cs
@@ -1,17 +1,28 @@
-using Microsoft.AspNetCore.Authorization;
+using Mapster;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Collectibles;
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Market;
+using Yi.Framework.DigitalCollectibles.Domain.Entities;
+using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.DigitalCollectibles.Application.Services;
///
/// 藏品应用服务
///
-public class CollectiblesService:ApplicationService
+public class CollectiblesService : ApplicationService
{
+ private readonly ISqlSugarRepository _collectiblesUserStoreRepository;
+
+ public CollectiblesService(ISqlSugarRepository collectiblesUserStoreRepository)
+ {
+ _collectiblesUserStoreRepository = collectiblesUserStoreRepository;
+ }
+
///
/// 获取当前用户的藏品
///
@@ -20,8 +31,16 @@ public class CollectiblesService:ApplicationService
///
[HttpGet("user")]
[Authorize]
- public async Task> GetForAccountUserAsync(CollectiblesUserGetInput input)
+ public async Task> GetForAccountUserAsync(
+ CollectiblesUserGetInput input)
{
- throw new NotImplementedException();
+ RefAsync total = 0;
+ var entities = await _collectiblesUserStoreRepository._DbQueryable.WhereIF(
+ input.StartTime is not null && input.EndTime is not null,
+ x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
+ .OrderByDescending(x => x.CreationTime)
+ .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+ var output = entities.Adapt>();
+ return new PagedResultDto(total, output);
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/MarketService.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/MarketService.cs
index a16c4da6..f5222f45 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/MarketService.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Services/MarketService.cs
@@ -1,6 +1,10 @@
-using Volo.Abp.Application.Dtos;
+using Mapster;
+using SqlSugar;
+using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.DigitalCollectibles.Application.Contracts.Dtos.Market;
+using Yi.Framework.DigitalCollectibles.Domain.Entities;
+using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.DigitalCollectibles.Application.Services;
@@ -9,14 +13,27 @@ namespace Yi.Framework.DigitalCollectibles.Application.Services;
///
public class MarketService:ApplicationService
{
+ private readonly ISqlSugarRepository _marketGoodsRepository;
+
+ public MarketService(ISqlSugarRepository marketGoodsRepository)
+ {
+ _marketGoodsRepository = marketGoodsRepository;
+ }
+
///
/// 交易市场查询
///
///
///
- ///
public async Task> GetListAsync(MarketGetListInput input)
{
- throw new NotImplementedException();
+ RefAsync total = 0;
+ var entities = await _marketGoodsRepository._DbQueryable.WhereIF(
+ input.StartTime is not null && input.EndTime is not null,
+ x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
+ .OrderByDescending(x => x.CreationTime)
+ .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
+ var output = entities.Adapt>();
+ return new PagedResultDto(total, output);
}
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Attributes/ProbabilityAttribute.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Attributes/ProbabilityAttribute.cs
new file mode 100644
index 00000000..6dee35df
--- /dev/null
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Attributes/ProbabilityAttribute.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+using Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
+
+namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Attributes;
+
+public class ProbabilityAttribute : Attribute
+{
+ public double Value { get; set; }
+
+ public ProbabilityAttribute(double value)
+ {
+ this.Value = value;
+ }
+}
+
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/CacheConst.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/CacheConst.cs
new file mode 100644
index 00000000..015111e3
--- /dev/null
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/CacheConst.cs
@@ -0,0 +1,9 @@
+namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
+
+public class CacheConst
+{
+ ///
+ /// 矿池
+ ///
+ public const string MiningPoolContent = "MiningPool";
+}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
index a1cc1156..453aa212 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
@@ -1,4 +1,6 @@
using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+using Yi.Framework.DigitalCollectibles.Domain.Shared.Attributes;
namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
@@ -7,9 +9,50 @@ namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
///
public enum RarityEnum
{
- [Display(Name = "普通")] Ordinary = 0,
- [Display(Name = "高级")] Senior = 1,
- [Display(Name = "稀有")] Rare = 2,
- [Display(Name = "珍品")] Gem = 3,
- [Display(Name = "传说")] Legend = 4
+ [Display(Name = "普通")][Probability(0.8f)] Ordinary = 0,
+ [Display(Name = "高级")][Probability(0.1f)] Senior = 1,
+ [Display(Name = "稀有")][Probability(0.06f)] Rare = 2,
+ [Display(Name = "珍品")][Probability(0.039f)] Gem = 3,
+ [Display(Name = "传说")][Probability(0.001f)] Legend = 4
+}
+
+public static class RarityEnumExtensions
+{
+ private static T GetAttribute(RarityEnum rarity) where T : Attribute
+ {
+ var fieldInfo = typeof(RarityEnum).GetField(rarity.ToString());
+ var attribute = fieldInfo.GetCustomAttribute();
+ return attribute!;
+ }
+
+ public static decimal GetProbabilityValue(this RarityEnum rarity)
+ {
+ var attribute = GetAttribute(rarity);
+ return attribute.Value.To();
+ }
+
+ public static string GetDisplayValue(this RarityEnum rarity)
+ {
+ var display = GetAttribute(rarity);
+ return display.Name!;
+ }
+
+ public static decimal[] GetProbabilityValues()
+ {
+ List probabilityList = new List();
+
+ foreach (var field in typeof(RarityEnum).GetFields())
+ {
+ // 获取特性
+ var attribute = field.GetCustomAttribute();
+ if (attribute != null)
+ {
+ // 将特性值添加到列表
+ probabilityList.Add(attribute.Value.To());
+ }
+ }
+
+ return probabilityList.ToArray();
+ }
+
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs
new file mode 100644
index 00000000..1ff8714b
--- /dev/null
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs
@@ -0,0 +1,50 @@
+namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Dtos;
+
+///
+/// 矿池内容
+///
+public class MiningPoolContent
+{
+ public MiningPoolContent(DateTime startTime, DateTime endTime)
+ {
+ StartTime = startTime;
+ EndTime = endTime;
+ }
+
+ ///
+ /// 普通藏品剩余数量
+ ///
+ public int I0_OrdinaryNumber { get; set; }
+
+ ///
+ /// 高级藏品剩余数量
+ ///
+ public int I1_SeniorNumber { get; set; }
+
+ ///
+ /// 稀有藏品剩余数量
+ ///
+ public int I2_RareNumber { get; set; }
+
+ ///
+ /// 珍品藏品剩余数量
+ ///
+ public int I3_GemNumber { get; set; }
+
+ ///
+ /// 传说藏品剩余数量
+ ///
+ public int I4_LegendNumber { get; set; }
+
+ ///
+ /// 开始时间
+ ///
+ public DateTime StartTime{ get; set; }
+
+ ///
+ /// 结束时间
+ ///
+ public DateTime EndTime{ get; set; }
+
+}
+
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
index 186bab0b..1c8256fb 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
@@ -10,7 +10,6 @@
-
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Entities/CollectiblesUserStoreAggregateRoot.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Entities/CollectiblesUserStoreAggregateRoot.cs
index cd81f4e0..e6345b4a 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Entities/CollectiblesUserStoreAggregateRoot.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Entities/CollectiblesUserStoreAggregateRoot.cs
@@ -19,4 +19,9 @@ public class CollectiblesUserStoreAggregateRoot:FullAuditedAggregateRoot
/// 藏品id
///
public Guid CollectiblesId { get; set; }
+
+ ///
+ /// 用户是否已读
+ ///
+ public bool IsRead { get; set; }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
index d6cfeea5..20105288 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
@@ -1,4 +1,10 @@
-using Volo.Abp.Domain.Services;
+using Microsoft.Extensions.Caching.Distributed;
+using Volo.Abp.Caching;
+using Volo.Abp.Domain.Services;
+using Volo.Abp.Settings;
+using Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
+using Yi.Framework.DigitalCollectibles.Domain.Shared.Dtos;
+using Yi.Framework.SettingManagement.Domain;
namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
@@ -6,6 +12,134 @@ namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
/// 矿池领域服务
/// 处理矿池相关业务,例如挖矿等
///
-public class MiningPoolManager:DomainService
+public class MiningPoolManager : DomainService
{
+ ///
+ /// 每次挖矿概率,每天根据特定算法计算
+ ///
+ private static decimal CurrentMiningProbability { get; set; }
+
+ private readonly ISettingProvider _settingProvider;
+ private readonly IDistributedCache _cache;
+
+ public MiningPoolManager(ISettingProvider settingProvider, IDistributedCache cache)
+ {
+ _settingProvider = settingProvider;
+ this._cache = cache;
+ }
+
+ ///
+ /// 最后一次计算挖矿概率的时间,如果时间跨了早上10点,重新计算
+ ///
+ private static DateTime LastComputeMiningProbabilityTime { get; set; }
+
+ ///
+ /// 用户进行一次挖矿
+ ///
+ ///
+ public Task MiningAsync(Guid userId)
+ {
+ //从矿池中开挖
+ //根据挖矿概率,进行挖掘
+ //挖到了放到用户仓库即可
+
+ //如果概率是挖到了矿,再从矿物中随机选择一个稀有度,再在当前稀有度中的矿物列表,随机选择一个具体的矿物
+
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// 计算当前挖矿概率
+ ///
+ ///
+ public Task ComputeMiningProbabilityAsync()
+ {
+ //当前的挖矿期望:当天的所有藏品能被刚好挖完
+
+ //保底概率:最大不能高过一个值,百分之10
+ //手动挖矿:1天可挖10次,每次至少间隔6秒
+ //自动挖矿:1天可以挖24次 每次间隔60分钟(需要使用自动挖矿卡)
+ //可影响因素:剩余手动挖矿次数+剩余自动挖矿次数
+
+ //所有能够挖掘次数
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// 刷新矿池
+ ///
+ ///
+ public async Task RefreshMiningPoolAsync()
+ {
+ //获取当前最大的限制
+ var maximumPoolLimit = int.Parse(await _settingProvider.GetOrNullAsync("MaximumPoolLimit"));
+
+ DateTime startTime = DateTime.Today.AddHours(10);
+ DateTime endTime = startTime.AddDays(1);
+ var probabilityValues = RarityEnumExtensions.GetProbabilityValues();
+ var result = GenerateDistribution(maximumPoolLimit, probabilityValues);
+
+ //根据配置,将不同比例的矿,塞入矿池,
+ //矿池,交给redis
+ await _cache.SetAsync(CacheConst.MiningPoolContent, new MiningPoolContent(startTime, endTime)
+ {
+ I0_OrdinaryNumber = result[0],
+ I1_SeniorNumber = result[1],
+ I2_RareNumber = result[2],
+ I3_GemNumber = result[3],
+ I4_LegendNumber = result[4]
+ }, new DistributedCacheEntryOptions
+ {
+ AbsoluteExpiration = endTime
+ });
+ }
+
+ ///
+ /// 根据概率生成给对应稀有度藏品
+ ///
+ ///
+ ///
+ ///
+ ///
+ private int[] GenerateDistribution(int totalCount, decimal[] probabilities)
+ {
+ int[] counts = new int[probabilities.Length];
+ decimal totalProbability = 0;
+
+ // 计算概率总和,确保为 1
+ foreach (var prob in probabilities)
+ {
+ totalProbability += prob;
+ }
+
+ // 检查概率之和是否为 1
+ if (totalProbability < 0.99m || totalProbability > 1.01m)
+ {
+ throw new ArgumentException("概率总和必须接近1");
+ }
+
+ // 生成分布
+ for (int i = 0; i < probabilities.Length; i++)
+ {
+ counts[i] = (int)(totalCount * probabilities[i]);
+ }
+
+ // 处理可能因精度问题导致的总数不足
+ int sum = 0;
+ foreach (var count in counts)
+ {
+ sum += count;
+ }
+
+ int difference = totalCount - sum;
+
+ // 将差值分配给概率最大的一项
+ if (difference > 0)
+ {
+ int maxIndex = Array.IndexOf(counts, Math.Max(counts[0], counts[1]));
+ counts[maxIndex] += difference;
+ }
+
+ return counts;
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Yi.Framework.DigitalCollectibles.Domain.csproj b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Yi.Framework.DigitalCollectibles.Domain.csproj
index 8c36f501..b8434d1a 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Yi.Framework.DigitalCollectibles.Domain.csproj
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Yi.Framework.DigitalCollectibles.Domain.csproj
@@ -9,6 +9,7 @@
+
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/YiFrameworkDigitalCollectiblesDomainModule.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/YiFrameworkDigitalCollectiblesDomainModule.cs
index c2837b07..9171ca5b 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/YiFrameworkDigitalCollectiblesDomainModule.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/YiFrameworkDigitalCollectiblesDomainModule.cs
@@ -3,12 +3,14 @@ using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Yi.Framework.DigitalCollectibles.Domain.Shared;
using Yi.Framework.Mapster;
+using Yi.Framework.SettingManagement.Domain;
namespace Yi.Framework.DigitalCollectibles.Domain
{
[DependsOn(
typeof(YiFrameworkDigitalCollectiblesDomainSharedModule),
+ typeof(YiFrameworkSettingManagementDomainModule),
typeof(YiFrameworkMapsterModule),
typeof(AbpDddDomainModule),
typeof(AbpCachingModule)
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/Yi.Framework.DigitalCollectibles.SqlSugarCore.csproj b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/Yi.Framework.DigitalCollectibles.SqlSugarCore.csproj
index 3cfeec1e..52f1ba49 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/Yi.Framework.DigitalCollectibles.SqlSugarCore.csproj
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/Yi.Framework.DigitalCollectibles.SqlSugarCore.csproj
@@ -4,6 +4,7 @@
+
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/YiFrameworkDigitalCollectiblesSqlSugarCoreModule.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/YiFrameworkDigitalCollectiblesSqlSugarCoreModule.cs
index 336d5147..01bf8331 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/YiFrameworkDigitalCollectiblesSqlSugarCoreModule.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.SqlSugarCore/YiFrameworkDigitalCollectiblesSqlSugarCoreModule.cs
@@ -1,16 +1,13 @@
-using Microsoft.Extensions.DependencyInjection;
-using Volo.Abp.Modularity;
using Yi.Framework.DigitalCollectibles.Domain;
using Yi.Framework.Mapster;
+using Yi.Framework.SettingManagement.SqlSugarCore;
using Yi.Framework.SqlSugarCore;
-using Yi.Framework.SqlSugarCore.Abstractions;
-
namespace Yi.Framework.DigitalCollectibles.SqlsugarCore
{
[DependsOn(
typeof(YiFrameworkDigitalCollectiblesDomainModule),
-
+ typeof(YiFrameworkSettingManagementSqlSugarCoreModule),
typeof(YiFrameworkMapsterModule),
typeof(YiFrameworkSqlSugarCoreModule)
)]