diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs
new file mode 100644
index 0000000..a8ca024
--- /dev/null
+++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/GameController.cs
@@ -0,0 +1,52 @@
+using CloudGaming.Api.Base;
+using CloudGaming.Code.Cache;
+using CloudGaming.Code.Game;
+using CloudGaming.Code.MiddlewareExtend;
+using CloudGaming.DtoModel.Game;
+using CloudGaming.GameModel.Db.Db_Game;
+
+using Microsoft.AspNetCore.Mvc;
+
+namespace CloudGaming.Api.Controllers
+{
+ ///
+ /// 游戏控制器
+ ///
+ public class GameController : CloudGamingControllerBase
+ {
+ public GameController(IServiceProvider _serviceProvider) : base(_serviceProvider)
+ {
+ }
+
+
+ ///
+ /// 游戏类型列表
+ ///
+ ///
+ [HttpGet]
+ [RedisCache(2, 0, 0)]
+ public async Task> GetGameTypeListAsync()
+ {
+ GameBLL gamebll = new GameBLL(this.ServiceProvider);
+ return await gamebll.GetGameTypeListAsync();
+ }
+
+
+ ///
+ /// 根据游戏类型Id 获取游戏列表
+ ///
+ ///
+ ///
+ [HttpGet]
+ [RedisCache(2, 5, 0)]
+ public async Task> GetGameListAsync([FromQuery] int typeId)
+ {
+ if (typeId == 0)
+ {
+ return new List();
+ }
+ GameBLL gamebll = new GameBLL(this.ServiceProvider);
+ return await gamebll.GetGameListAsync(typeId);
+ }
+ }
+}
diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/HomeController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/HomeController.cs
index c4d9b0a..1f6ce5c 100644
--- a/src/CloudGaming/Api/CloudGaming.Api/Controllers/HomeController.cs
+++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/HomeController.cs
@@ -1,5 +1,6 @@
using CloudGaming.Api.Base;
using CloudGaming.Code.Epg;
+using CloudGaming.Code.MiddlewareExtend;
using CloudGaming.DtoModel.Epg;
using Microsoft.AspNetCore.JsonPatch.Internal;
@@ -18,6 +19,7 @@ public class HomeController : CloudGamingControllerBase
///
///
[HttpGet]
+ [RedisCache(1, 0, 0)]
public async Task> GetHomeInfo()
{
EpgBLL epgBLL = new EpgBLL(ServiceProvider);
diff --git a/src/CloudGaming/Api/CloudGaming.Api/Program.cs b/src/CloudGaming/Api/CloudGaming.Api/Program.cs
index d95e4d1..4265974 100644
--- a/src/CloudGaming/Api/CloudGaming.Api/Program.cs
+++ b/src/CloudGaming/Api/CloudGaming.Api/Program.cs
@@ -17,6 +17,7 @@ using CloudGaming.Code.AppExtend.JsonConverHelper;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Options;
using CloudGaming.GameModel.Db.Db_Ext;
+using CloudGaming.Code.MiddlewareExtend;
var builder = WebApplication.CreateBuilder(args);
#region 日志
// Add services to the container.
@@ -37,6 +38,7 @@ builder.Services.AddSingleton(typeof(ILogger), serviceProvi
return loggerFactory.CreateLogger();
});
#endregion
+builder.Services.AddMemoryCache();
builder.Services.AddHttpClient();
builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问
#region 返回数据解析
@@ -168,6 +170,8 @@ app.MapControllers();
app.UseStaticFiles();//静态文件访问配置
//执行扩展中间件
app.UseMiddlewareAll();
+//缓存中间件
+app.UseCloudGamingMiddlewareAll();
#region 默认请求
app.MapGet("/", () => "请求成功").WithName("默认请求");
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
index 8886451..ae0e434 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
@@ -3,6 +3,9 @@ using AgileConfig.Client;
using CloudGaming.Code.DataAccess.MultiTenantUtil;
using HuanMeng.DotNetCore.CacheHelper;
+using HuanMeng.DotNetCore.Redis;
+
+using StackExchange.Redis;
using System.Collections.Concurrent;
using System.Collections.Frozen;
@@ -136,6 +139,15 @@ namespace CloudGaming.Code.AppExtend
tenantInfo.Name = appConfig.Name;
return tenantInfo;
}
+ ///
+ /// 获取redis缓存
+ ///
+ ///
+ ///
+ public static IDatabase GetRedisDataBase(this AppConfig appConfig)
+ {
+ return RedisConnection.GetRedis(appConfig.RedisConnectionString);
+ }
///
///
@@ -162,7 +174,7 @@ namespace CloudGaming.Code.AppExtend
newAppConfig.GameConnectionString = appConfig.GameConnectionString;
newAppConfig.ExtConnectionString = appConfig.ExtConnectionString;
newAppConfig.PhoneConnectionString = appConfig.PhoneConnectionString;
- newAppConfig.AliyunConfig= appConfig.AliyunConfig;
+ newAppConfig.AliyunConfig = appConfig.AliyunConfig;
newAppConfig.DefaultLanguage = appConfig.DefaultLanguage;
return newAppConfig;
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppRequestConfig.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppRequestConfig.cs
index 1a534da..41df7bf 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppRequestConfig.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppRequestConfig.cs
@@ -110,6 +110,15 @@ namespace CloudGaming.Code.AppExtend
}
}
+ ///
+ /// 获取key
+ ///
+ public string Key
+ {
+
+ get => $"{Language}_{Channel}_{Version}";
+ }
+
///
/// 地区
///
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs
index 1941333..c95a720 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs
@@ -71,7 +71,7 @@ namespace CloudGaming.Code.Cache
#endregion
- public GameEntityCache? gameEntityCache;
+ private GameEntityCache? gameEntityCache;
///
/// 游戏缓存
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs
index 9e04edd..c90abf1 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/Special/GameEntityCache.cs
@@ -27,7 +27,8 @@ namespace CloudGaming.Code.Cache.Special
public override string key => $"{appConfig.Identifier}:game:gameInfo";
- public string locaKey => $"{appConfig.Identifier}:lock:gameInfo";
+ public string locaKey => $"lock:gameInfo";
+ public string RedisKey => $"cache:game:gameInfo";
public override List GetDataList()
{
@@ -71,10 +72,10 @@ namespace CloudGaming.Code.Cache.Special
return _dataList;
}
- long hashLength = database.HashLength(key);
+ long hashLength = database.HashLength(RedisKey);
if (hashLength > 0)
{
- var hashEntries = database.HashGetAll(key);
+ var hashEntries = database.HashGetAll(RedisKey);
var list = hashEntries
.Where(entry => !string.IsNullOrEmpty(entry.Value))
.Select(entry => JsonConvert.DeserializeObject(entry.Value))
@@ -94,7 +95,7 @@ namespace CloudGaming.Code.Cache.Special
var serializedGameInfos = tempDataList
.Select(info => new HashEntry($"gameInfo:{info.GameId}", JsonConvert.SerializeObject(info)))
.ToArray();
- database.HashSet(key, serializedGameInfos);
+ database.HashSet(RedisKey, serializedGameInfos);
MemoryCacheHelper.SetCache(key, tempDataList, 60 * 60);
_dataList = tempDataList;
diff --git a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
index 40c30bd..1174cf9 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
@@ -29,8 +29,7 @@ namespace CloudGaming.Code.DataAccess.MultiTenantUtil
///
public virtual async Task Invoke(HttpContext context,
IServiceProvider _serviceProvider,
- AppConfig appConfig
- )
+ AppConfig appConfig )
{
var host = context.Request.Host.Host;
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs
index 4f7f399..b0f5875 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Epg/EpgExtend.cs
@@ -47,8 +47,14 @@ namespace CloudGaming.Code.Epg
return null;
}
- epgInfo.Title ??= gameInfo.GameName;
- epgInfo.SubTitle ??= gameInfo.Title2;
+ if (string.IsNullOrEmpty(epgInfo.Title))
+ {
+ epgInfo.Title = gameInfo.GameName;
+ }
+ if (string.IsNullOrEmpty(epgInfo.SubTitle))
+ {
+ epgInfo.SubTitle = gameInfo.Title2;
+ }
if (epgInfo.ImageUrl == 0 && !string.IsNullOrEmpty(epgCfg.ImageResStyle))
{
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs b/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs
new file mode 100644
index 0000000..b032836
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Game/GameBLL.cs
@@ -0,0 +1,64 @@
+using CloudGaming.Code.Cache;
+using CloudGaming.DtoModel.Game;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.Game
+{
+ ///
+ /// 游戏逻辑类
+ ///
+ public class GameBLL : CloudGamingBase
+ {
+ public GameBLL(IServiceProvider serviceProvider) : base(serviceProvider)
+ {
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetGameTypeListAsync()
+ {
+ var gameList = Cache.GameEntityCache?.DataList ?? new List();
+ var gameTypes = await Task.Run(() =>
+ {
+ return CloudGamingCacheExtend.GetDataEntityCache(this, it => it.IsOnline)?.DataList
+ .Where(it => gameList.Any(item => item.GameType?.Any(gameType => gameType.Id == it.TypeId) ?? false))
+ .OrderBy(it => it.OrderId)
+ .Select(it => new GameExtendedAttribute
+ {
+ Id = it.TypeId,
+ Name = it.TypeName,
+ OrderId = it.OrderId
+ })
+ .ToList();
+ });
+
+ return gameTypes;
+ }
+
+ ///
+ /// 根据游戏类型Id 获取游戏列表
+ ///
+ ///
+ ///
+ public async Task> GetGameListAsync(int typeId)
+ {
+
+ var gameListDto = await Task.Run(() =>
+ {
+ var gameList = Cache.GameEntityCache?.DataList ?? new List();
+ var x = gameList.Where(it => it.GameType?.Any(item => item.Id == typeId) ?? false).Select(it => new
+ GameListDto(it)).ToList();
+ return x;
+ });
+ return gameListDto;
+
+ }
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MemoryCacheMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MemoryCacheMiddleware.cs
new file mode 100644
index 0000000..0cd044c
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MemoryCacheMiddleware.cs
@@ -0,0 +1,147 @@
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Caching.Memory;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.IdentityModel.Tokens;
+using System.Collections.Concurrent;
+
+namespace CloudGaming.Code.MiddlewareExtend
+{
+ ///
+ /// 内存缓存
+ ///
+ public class MemoryCacheMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly IMemoryCache _cache;
+ private static readonly ConcurrentDictionary _attributeCache = new();
+ ///
+ ///
+ ///
+ ///
+ ///
+ public MemoryCacheMiddleware(RequestDelegate next, IMemoryCache cache)
+ {
+ _next = next;
+ _cache = cache;
+ }
+
+ public async Task InvokeAsync(HttpContext context,
+ IServiceProvider _serviceProvider,
+ AppConfig appConfig
+ )
+ {
+ // 检查当前请求是否需要缓存
+ var cacheAttribute = GetCacheAttribute(context);
+ if (cacheAttribute == null)
+ {
+ // 如果没有找到 MemoryCacheAttribute,直接调用下一个中间件
+ await _next(context);
+ return;
+ }
+
+ // 生成缓存键(基于请求路径和查询字符串)
+ var cacheKey = GenerateCacheKey(context.Request, appConfig);
+
+ // 尝试从缓存中获取数据
+ if (_cache.TryGetValue(cacheKey, out string cachedResponse))
+ {
+ context.Response.StatusCode = StatusCodes.Status200OK;
+ // 如果缓存中有数据,则直接返回缓存的响应
+ context.Response.ContentType = "application/json";
+ await context.Response.WriteAsync(cachedResponse);
+ return;
+ }
+
+ // 捕获原始响应流
+ var originalResponseStream = context.Response.Body;
+
+ try
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ context.Response.Body = memoryStream;
+
+ // 调用下一个中间件
+ await _next(context);
+
+ // 将响应流重新定位到起始位置
+ memoryStream.Position = 0;
+
+ // 读取响应内容
+ var responseBody = await new StreamReader(memoryStream).ReadToEndAsync();
+
+ // 将响应内容缓存
+ _cache.Set(cacheKey, responseBody, cacheAttribute.TimeSpan);
+
+ // 将内容写回原始响应流
+ memoryStream.Position = 0;
+ await memoryStream.CopyToAsync(originalResponseStream);
+ }
+ }
+ finally
+ {
+ // 恢复原始响应流
+ context.Response.Body = originalResponseStream;
+ }
+ }
+
+ private MemoryCacheAttribute GetCacheAttribute(HttpContext context)
+ {
+ var endpoint = context.Features.Get()?.Endpoint;
+ if (endpoint == null) return null;
+
+ // 使用字典缓存以减少重复获取
+ if (_attributeCache.TryGetValue(endpoint, out var cachedAttribute))
+ {
+ return cachedAttribute;
+ }
+
+ // 获取并缓存 MemoryCacheAttribute
+ var attribute = endpoint.Metadata.GetMetadata();
+ if (attribute != null)
+ {
+ _attributeCache.TryAdd(endpoint, attribute);
+ }
+
+ return attribute;
+ }
+
+ private string GenerateCacheKey(HttpRequest request, AppConfig appConfig)
+ {
+ var appRequestInfo = new AppRequestConfig(request);
+ // 基于请求路径和查询参数生成缓存键
+ var cacheKey = $"{appConfig.Identifier}:{request.Path.Value.Replace('/', '.').TrimStart('.')}:{(string.IsNullOrEmpty(request.QueryString.Value) ? "default" : request.QueryString)}:{appRequestInfo.Key}";
+ return cacheKey;
+ }
+ }
+ ///
+ /// 内存缓存特性类
+ ///
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public class MemoryCacheAttribute : Attribute
+ {
+
+ public TimeSpan TimeSpan { get; }
+ public MemoryCacheAttribute(int durationInSeconds)
+ {
+ TimeSpan = TimeSpan.FromSeconds(durationInSeconds);
+ }
+ public MemoryCacheAttribute(int hours, int minutes, int seconds)
+ {
+
+ TimeSpan = new TimeSpan(hours, minutes, seconds);
+ }
+ public MemoryCacheAttribute(int minutes, int seconds)
+ {
+
+ TimeSpan = new TimeSpan(0, minutes, seconds);
+ }
+ }
+
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MiddlewareExtends.cs b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MiddlewareExtends.cs
new file mode 100644
index 0000000..aa3a709
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/MiddlewareExtends.cs
@@ -0,0 +1,45 @@
+using HuanMeng.DotNetCore.MiddlewareExtend;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.MiddlewareExtend
+{
+ ///
+ ///
+ ///
+ public static class MiddlewareExtends
+ {
+ ///
+ /// 加载全部中间件
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseCloudGamingMiddlewareAll(this IApplicationBuilder builder)
+ {
+ return builder
+ .UseCacheMiddleware()
+ .UseRedisCacheMiddleware()
+ ;
+
+ }
+
+ ///
+ /// 缓存中间件
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseCacheMiddleware(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+ public static IApplicationBuilder UseRedisCacheMiddleware(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs
new file mode 100644
index 0000000..fb1080d
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/MiddlewareExtend/RedisCacheMiddleware.cs
@@ -0,0 +1,124 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.Extensions.Caching.Distributed;
+
+using System;
+using System.Collections.Concurrent;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.MiddlewareExtend
+{
+ ///
+ /// Redis 缓存中间件
+ ///
+ public class RedisCacheMiddleware
+ {
+ private readonly RequestDelegate _next;
+
+ private static readonly ConcurrentDictionary _attributeCache = new();
+
+ public RedisCacheMiddleware(RequestDelegate next)
+ {
+ _next = next;
+
+ }
+
+ public async Task InvokeAsync(HttpContext context,
+ IServiceProvider _serviceProvider,
+ AppConfig appConfig
+ )
+ {
+ // 检查当前请求是否需要缓存
+ var cacheAttribute = GetCacheAttribute(context);
+ if (cacheAttribute == null)
+ {
+ await _next(context);
+ return;
+ }
+ var _cache = appConfig.GetRedisDataBase();
+
+ // 生成缓存键(基于请求路径和查询字符串)
+ var cacheKey = GenerateCacheKey(context.Request, appConfig);
+
+ // 尝试从 Redis 缓存中获取数据
+ var cachedResponse = await _cache.StringGetAsync(cacheKey);
+ if (!cachedResponse.IsNullOrEmpty)
+ {
+ context.Response.StatusCode = StatusCodes.Status200OK;
+ context.Response.ContentType = "application/json";
+ await context.Response.WriteAsync(cachedResponse);
+ return;
+ }
+
+ // 捕获原始响应流
+ var originalResponseStream = context.Response.Body;
+
+ try
+ {
+ using (var memoryStream = new MemoryStream())
+ {
+ context.Response.Body = memoryStream;
+
+ // 调用下一个中间件
+ await _next(context);
+
+ // 将响应流重新定位到起始位置
+ memoryStream.Position = 0;
+
+ // 读取响应内容
+ var responseBody = await new StreamReader(memoryStream).ReadToEndAsync();
+
+ await _cache.StringSetAsync(cacheKey, responseBody, cacheAttribute.TimeSpan);
+
+ // 将内容写回原始响应流
+ memoryStream.Position = 0;
+ await memoryStream.CopyToAsync(originalResponseStream);
+ }
+ }
+ finally
+ {
+ context.Response.Body = originalResponseStream;
+ }
+ }
+
+ private RedisCacheAttribute GetCacheAttribute(HttpContext context)
+ {
+ var endpoint = context.Features.Get()?.Endpoint;
+ if (endpoint == null) return null;
+
+ if (_attributeCache.TryGetValue(endpoint, out var cachedAttribute))
+ {
+ return cachedAttribute;
+ }
+
+ var attribute = endpoint.Metadata.GetMetadata();
+ if (attribute != null)
+ {
+ _attributeCache.TryAdd(endpoint, attribute);
+ }
+
+ return attribute;
+ }
+
+ private string GenerateCacheKey(HttpRequest request, AppConfig appConfig)
+ {
+ var appRequestInfo = new AppRequestConfig(request);
+ var cacheKey = $"cache:api:{request.Path.Value.Replace('/', '.').TrimStart('.')}:{appRequestInfo.Key}:{(string.IsNullOrEmpty(request.QueryString.Value) ? "default" : request.QueryString)}";
+ return cacheKey;
+ }
+ }
+
+ ///
+ /// Redis 缓存特性类
+ ///
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public class RedisCacheAttribute : Attribute
+ {
+ public TimeSpan TimeSpan { get; }
+ public RedisCacheAttribute(int durationInSeconds) => TimeSpan = TimeSpan.FromSeconds(durationInSeconds);
+ public RedisCacheAttribute(int hours, int minutes, int seconds) => TimeSpan = new TimeSpan(hours, minutes, seconds);
+ public RedisCacheAttribute(int minutes, int seconds) => TimeSpan = new TimeSpan(0, minutes, seconds);
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameInfoDto.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameInfoDto.cs
new file mode 100644
index 0000000..524b1de
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameInfoDto.cs
@@ -0,0 +1,40 @@
+using HuanMeng.DotNetCore.AttributeExtend;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Game
+{
+ public class GameInfoDto
+ {
+ ///
+ /// 游戏Id
+ ///
+ public virtual string GameId { get; set; } = null!;
+
+
+ ///
+ /// 游戏icon
+ ///
+ [Images("ImageIcon")]
+ public virtual int ImageIcon { get; set; }
+
+ ///
+ ///
+ ///
+ [Images("GameBgImage")]
+ public virtual int GameBgImage { get; set; }
+ ///
+ /// 游戏标签
+ ///
+ public List GameTags { get; set; }
+
+ ///
+ /// 游戏列表
+ ///
+ public List GameType { get; set; }
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameListDto.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameListDto.cs
new file mode 100644
index 0000000..d58e359
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Game/GameListDto.cs
@@ -0,0 +1,48 @@
+using HuanMeng.DotNetCore.AttributeExtend;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Game
+{
+ ///
+ /// 游戏列表数据
+ ///
+ public class GameListDto
+ {
+ public GameListDto() { }
+
+ ///
+ ///
+ ///
+ ///
+ public GameListDto(GameInfo gameInfo)
+ {
+ if (gameInfo != null)
+ {
+ this.GameName = gameInfo.GameName;
+ this.GameId = gameInfo.GameId;
+ this.GameIconImage = gameInfo.GameImageId;
+
+
+ }
+ }
+ ///
+ /// 游戏Id
+ ///
+ public string GameId { get; set; }
+ ///
+ /// 游戏名称
+ ///
+ public string GameName { get; set; }
+
+ ///
+ /// 游戏icon
+ ///
+ [Images]
+ public int GameIconImage { get; set; }
+ }
+}
diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions1.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions1.cs
index acce3cf..636d4cc 100644
--- a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions1.cs
+++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/ObjectExtensions1.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Reflection;
using HuanMeng.DotNetCore.AttributeExtend;
using System.Linq.Expressions;
+using Microsoft.IdentityModel.Tokens;
namespace HuanMeng.DotNetCore.Utility;
@@ -23,7 +24,7 @@ public static class ObjectExtensions
///
/// 缓存每个属性是否具有 ImagesAttribute 特性。
///
- public static readonly ConcurrentDictionary _PropertyCache = new();
+ public static readonly ConcurrentDictionary _PropertyCache = new();
///
/// 判断对象是否为原始类型或字符串类型。
@@ -102,8 +103,8 @@ public static class ObjectExtensions
// 如果属性是字符串,在其值前添加 "test"
if (propertyValue is string stringValue)
{
- keyValuePairs[accessor.PropertyName] = $"test{stringValue}";
- Console.WriteLine(propertyPath);
+ keyValuePairs[accessor.PropertyName] = stringValue;
+ //Console.WriteLine(propertyPath);
continue;
}
@@ -130,8 +131,16 @@ public static class ObjectExtensions
// 创建用于访问属性值的委托
var getter = CreatePropertyGetter(type, property);
// 检查属性是否具有 ImagesAttribute,并将结果存储在缓存中
- bool hasImagesAttribute = _PropertyCache.GetOrAdd(property, p => p.GetCustomAttribute() != null);
- return new PropertyAccessor(property.Name, getter, hasImagesAttribute);
+ var imagesAttribute = _PropertyCache.GetOrAdd(property, p => p.GetCustomAttribute());
+ if (imagesAttribute != null)
+ {
+ if (!string.IsNullOrEmpty(imagesAttribute.FieldName))
+ {
+ return new PropertyAccessor(imagesAttribute.FieldName, getter, true);
+ }
+ return new PropertyAccessor(property.Name, getter, true);
+ }
+ return new PropertyAccessor(property.Name, getter, false);
}).ToArray();
}