提交代码
This commit is contained in:
parent
79a69db7d8
commit
bfed45c3e4
|
|
@ -1,4 +1,5 @@
|
|||
using CloudGaming.Api.Base;
|
||||
using CloudGaming.Code.Config;
|
||||
using CloudGaming.DtoModel;
|
||||
using CloudGaming.GameModel.Db.Db_Ext;
|
||||
|
||||
|
|
@ -25,19 +26,11 @@ namespace CloudGaming.Api.Controllers
|
|||
[HttpGet]
|
||||
public async Task<AppConfigDto> GetAppConfigAsync()
|
||||
{
|
||||
AppConfigDto appConfigDto = new AppConfigDto();
|
||||
appConfigDto.AppConfigExtend = new AppConfigExtend();
|
||||
return appConfigDto;
|
||||
AppConfigBLL appConfigBLL = new AppConfigBLL(ServiceProvider);
|
||||
var appConfig = await appConfigBLL.GetAppConfig();
|
||||
return appConfig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<BaseResponse<T_App_Config>> GetConfig1()
|
||||
{
|
||||
return new HuanMeng.DotNetCore.Base.BaseResponse<T_App_Config>(ResonseCode.Success, "成功", new T_App_Config() { BossId = "aa" });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using CloudGaming.Code.AppExtend.JsonConverHelper.JsonConverterUtil;
|
|||
using CloudGaming.Code.AppExtend.JsonConverHelper;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.Options;
|
||||
using CloudGaming.GameModel.Db.Db_Ext;
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
#region 日志
|
||||
// Add services to the container.
|
||||
|
|
@ -110,6 +111,21 @@ builder.Services.AddSwaggerGen(c =>
|
|||
|
||||
#endregion
|
||||
|
||||
#region automap
|
||||
var mapperDomain = AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("HuanMeng") || it.FullName.Contains("CloudGaming.")).ToList();
|
||||
Type type = typeof(T_App_Config);
|
||||
if (type != null)
|
||||
{
|
||||
Assembly assembly = Assembly.GetAssembly(type);
|
||||
if (!mapperDomain.Any(it => it.FullName == assembly.FullName))
|
||||
{
|
||||
mapperDomain.Add(assembly);
|
||||
}
|
||||
}
|
||||
|
||||
builder.Services.AddAutoMapper(mapperDomain);
|
||||
#endregion
|
||||
|
||||
builder.AddAppConfigClient();
|
||||
//添加jwt验证
|
||||
builder.AddJwtConfig();
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudGaming.Model", "Model\
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudGaming.Code", "Code\CloudGaming.Code\CloudGaming.Code.csproj", "{5F851D79-E435-4D16-974A-6D5E3A3269A7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CloudGaming.CreateDataBase", "Console\CloudGaming.CreateDataBase\CloudGaming.CreateDataBase.csproj", "{393ED915-3F88-4F84-AE2A-5C95F8867F16}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudGaming.CreateDataBase", "Console\CloudGaming.CreateDataBase\CloudGaming.CreateDataBase.csproj", "{393ED915-3F88-4F84-AE2A-5C95F8867F16}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CloudGaming.GameModel", "Model\CloudGaming.GameModel\CloudGaming.GameModel.csproj", "{1120C146-6B83-4E4E-8A39-BD09466C7E1B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudGaming.GameModel", "Model\CloudGaming.GameModel\CloudGaming.GameModel.csproj", "{1120C146-6B83-4E4E-8A39-BD09466C7E1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CloudGaming.DtoModel", "Model\CloudGaming.DtoModel\CloudGaming.DtoModel.csproj", "{96CD0865-0AD5-41B3-89A2-374FF17CDD16}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloudGaming.DtoModel", "Model\CloudGaming.DtoModel\CloudGaming.DtoModel.csproj", "{96CD0865-0AD5-41B3-89A2-374FF17CDD16}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CloudGaming.Test", "Console\CloudGaming.Test\CloudGaming.Test.csproj", "{830841B9-E013-4FD5-8D31-D85545870C1C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
|
@ -68,6 +70,10 @@ Global
|
|||
{96CD0865-0AD5-41B3-89A2-374FF17CDD16}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96CD0865-0AD5-41B3-89A2-374FF17CDD16}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96CD0865-0AD5-41B3-89A2-374FF17CDD16}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{830841B9-E013-4FD5-8D31-D85545870C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{830841B9-E013-4FD5-8D31-D85545870C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{830841B9-E013-4FD5-8D31-D85545870C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{830841B9-E013-4FD5-8D31-D85545870C1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -80,6 +86,7 @@ Global
|
|||
{393ED915-3F88-4F84-AE2A-5C95F8867F16} = {9F7EF36C-17BB-4F93-927E-F462FE3C9337}
|
||||
{1120C146-6B83-4E4E-8A39-BD09466C7E1B} = {A3F00FB0-49D6-48B1-99D9-4619634DF8D9}
|
||||
{96CD0865-0AD5-41B3-89A2-374FF17CDD16} = {A3F00FB0-49D6-48B1-99D9-4619634DF8D9}
|
||||
{830841B9-E013-4FD5-8D31-D85545870C1C} = {9F7EF36C-17BB-4F93-927E-F462FE3C9337}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {1D299D92-FA27-47A0-8D78-43D1FAFE7628}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// app 请求信息
|
||||
/// </summary>
|
||||
public class AppRequestConfig(HttpRequest httpRequest)
|
||||
{
|
||||
private string channel { get; set; }
|
||||
/// <summary>
|
||||
/// 渠道
|
||||
/// </summary>
|
||||
public string Channel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel))
|
||||
{
|
||||
if (!httpRequest.Headers.TryGetValue("Channel", out var _channel))
|
||||
{
|
||||
_channel = "27001";
|
||||
}
|
||||
channel = _channel;
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
private string platform;
|
||||
|
||||
/// <summary>
|
||||
/// 平台
|
||||
/// </summary>
|
||||
public string Platform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(platform))
|
||||
{
|
||||
if (!httpRequest.Headers.TryGetValue("Platform", out var _platform))
|
||||
{
|
||||
_platform = "android";
|
||||
}
|
||||
platform = _platform;
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
}
|
||||
|
||||
private string version;
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public string Version
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(version))
|
||||
{
|
||||
if (!httpRequest.Headers.TryGetValue("Version", out var _version))
|
||||
{
|
||||
_version = "1.0.0";
|
||||
}
|
||||
version = _version;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
public int versionNum;
|
||||
public int VersionNum
|
||||
{
|
||||
get
|
||||
{
|
||||
if (versionNum == 0)
|
||||
{
|
||||
var str = Version.Replace(".", "");
|
||||
if (!int.TryParse(str, out versionNum))
|
||||
{
|
||||
versionNum = 100;
|
||||
}
|
||||
}
|
||||
return versionNum;
|
||||
}
|
||||
}
|
||||
private string language;
|
||||
/// <summary>
|
||||
/// 语言
|
||||
/// </summary>
|
||||
public string Language
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(language))
|
||||
{
|
||||
if (!httpRequest.Headers.TryGetValue("Version", out var _language))
|
||||
{
|
||||
_language = "1.0.0";
|
||||
}
|
||||
language = _language;
|
||||
}
|
||||
return language;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地区
|
||||
/// </summary>
|
||||
public string Continent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 国家
|
||||
/// </summary>
|
||||
public string CountryName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ namespace CloudGaming.Code.AppExtend
|
|||
{
|
||||
if (_appConfig == null)
|
||||
{
|
||||
_appConfig = _serviceProvider.GetService<AppConfig>();
|
||||
_appConfig = _serviceProvider.GetRequiredService<AppConfig>();
|
||||
}
|
||||
return _appConfig;
|
||||
}
|
||||
|
|
@ -187,5 +187,22 @@ namespace CloudGaming.Code.AppExtend
|
|||
}
|
||||
}
|
||||
#endregion
|
||||
#region app配置
|
||||
private AppRequestConfig appRequestInfo;
|
||||
/// <summary>
|
||||
/// app请求配置
|
||||
/// </summary>
|
||||
public AppRequestConfig AppRequestInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (appRequestInfo == null)
|
||||
{
|
||||
appRequestInfo = new AppRequestConfig(HttpContextAccessor?.HttpContext?.Request);
|
||||
}
|
||||
return appRequestInfo;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using HuanMeng.DotNetCore.AttributeExtend;
|
||||
using HuanMeng.DotNetCore.Base;
|
||||
using HuanMeng.DotNetCore.Utility;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
|
@ -28,29 +30,41 @@ namespace CloudGaming.Code.AppExtend
|
|||
var path = httpContext.Request.Path.Value ?? "";
|
||||
// 获取当前用户的信息
|
||||
var user = httpContext.User.Identity.IsAuthenticated ? httpContext.User.Identity.Name : "Anonymous";
|
||||
|
||||
// 获取请求头中的某个信息(例如语言信息)
|
||||
var language = httpContext.Request.Headers["Accept-Language"].ToString();
|
||||
|
||||
//Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
|
||||
if (context.Result is ObjectResult objectResult && objectResult.Value != null)
|
||||
{
|
||||
if (IsPrimitiveOrString(objectResult.Value.GetType()))
|
||||
{
|
||||
|
||||
}
|
||||
FindImagesAttributes(objectResult.Value);
|
||||
// var responseObject = objectResult.Value;
|
||||
// var membersWithImagesAttribute = responseObject.GetType()
|
||||
//.GetMembers(BindingFlags.Public | BindingFlags.Instance)
|
||||
//.Where(m => m.GetCustomAttribute<ImagesAttribute>() != null);
|
||||
// foreach (var member in membersWithImagesAttribute)
|
||||
// {
|
||||
// var imagesAttribute = member.GetCustomAttribute<ImagesAttribute>();
|
||||
// Console.WriteLine($"带有 [Images] 特性的成员:{member.Name}");
|
||||
// Console.WriteLine($"FieldName 属性值:{imagesAttribute?.FieldName}");
|
||||
// }
|
||||
// 递归处理返回对象的所有属性并打印路径
|
||||
ProcessObjectProperties(objectResult.Value, user, language, path);
|
||||
|
||||
var dic = objectResult.Value.ToDictionary();
|
||||
//objectResult.Value = dic;
|
||||
var t = objectResult.Value.GetType();
|
||||
if (!t.FullName.Contains("HuanMeng.DotNetCore.Base.BaseResponse"))
|
||||
{
|
||||
BaseResponse<Dictionary<string, object>> baseResponse = new BaseResponse<Dictionary<string, object>>(ResonseCode.Success, "", dic);
|
||||
objectResult.Value = baseResponse;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectResult.Value = dic;
|
||||
}
|
||||
//objectResult.Value.to
|
||||
|
||||
//FindImagesAttributes(objectResult.Value);
|
||||
//// var responseObject = objectResult.Value;
|
||||
//// var membersWithImagesAttribute = responseObject.GetType()
|
||||
////.GetMembers(BindingFlags.Public | BindingFlags.Instance)
|
||||
////.Where(m => m.GetCustomAttribute<ImagesAttribute>() != null);
|
||||
//// foreach (var member in membersWithImagesAttribute)
|
||||
//// {
|
||||
//// var imagesAttribute = member.GetCustomAttribute<ImagesAttribute>();
|
||||
//// Console.WriteLine($"带有 [Images] 特性的成员:{member.Name}");
|
||||
//// Console.WriteLine($"FieldName 属性值:{imagesAttribute?.FieldName}");
|
||||
//// }
|
||||
//// 递归处理返回对象的所有属性并打印路径
|
||||
//ProcessObjectProperties(objectResult.Value, user, language, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
36
src/CloudGaming/Code/CloudGaming.Code/Config/AppConfigBLL.cs
Normal file
36
src/CloudGaming/Code/CloudGaming.Code/Config/AppConfigBLL.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using CloudGaming.DtoModel;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AppConfigBLL : CloudGamingBase
|
||||
{
|
||||
public AppConfigBLL(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取app启动配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<AppConfigDto> GetAppConfig()
|
||||
{
|
||||
var list = Cache.AppConfigList.Where(it => it.IsShow).ToList();
|
||||
var x = AppRequestInfo.versionNum;
|
||||
AppConfigDto appConfigDto = new AppConfigDto()
|
||||
{
|
||||
IsAuthRealName = true
|
||||
};
|
||||
appConfigDto.IsChecking = list.GetAppIsChecking(AppRequestInfo);
|
||||
return appConfigDto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.Config;
|
||||
|
||||
/// <summary>
|
||||
/// AppConfig扩展
|
||||
/// </summary>
|
||||
public static class AppConfigBLLExtend
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取app是否在审核中
|
||||
/// </summary>
|
||||
/// <param name="app_Configs"></param>
|
||||
/// <param name="appRequestInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static bool GetAppIsChecking(this List<T_App_Config> app_Configs, AppRequestConfig appRequestInfo)
|
||||
{
|
||||
var config = GetAppConfig(app_Configs, 7, 1, appRequestInfo);
|
||||
if (config == null || string.IsNullOrEmpty(config.ConfigValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var version = config.ConfigValue.Replace(".", "");
|
||||
if (!int.TryParse(version, out int versionNum))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (appRequestInfo.VersionNum >= versionNum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="app_Configs"></param>
|
||||
/// <param name="cfgType"></param>
|
||||
/// <param name="cfgId"></param>
|
||||
/// <param name="appRequestInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static T_App_Config GetAppConfig(this List<T_App_Config> app_Configs, int cfgType, int cfgId, AppRequestConfig appRequestInfo)
|
||||
{
|
||||
var list = GetAppCfgList(app_Configs, cfgType, cfgId, appRequestInfo.Channel, appRequestInfo.Platform, appRequestInfo.Continent, appRequestInfo.CountryName);
|
||||
return list.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="app_Configs"></param>
|
||||
/// <param name="cfgType"></param>
|
||||
/// <param name="cfgId"></param>
|
||||
/// <param name="appRequestInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T_App_Config> GetAppCfgList(this List<T_App_Config> app_Configs, int cfgType, int cfgId, AppRequestConfig appRequestInfo)
|
||||
{
|
||||
return GetAppCfgList(app_Configs, cfgType, cfgId, appRequestInfo.Channel, appRequestInfo.Platform, appRequestInfo.Continent, appRequestInfo.CountryName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="app_Configs"></param>
|
||||
/// <param name="cfgType"></param>
|
||||
/// <param name="cfgId"></param>
|
||||
/// <param name="bossId"></param>
|
||||
/// <param name="plat"></param>
|
||||
/// <param name="continent"></param>
|
||||
/// <param name="countryName"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T_App_Config> GetAppCfgList(this List<T_App_Config> app_Configs, int cfgType, int cfgId, string bossId, string plat = "", string continent = "", string countryName = "")
|
||||
{
|
||||
//有很多老配置,没有appid的参与
|
||||
var lst = app_Configs.Where(it => it.ConfigType == cfgType && it.ConfigId == cfgId).ToList();
|
||||
|
||||
#region 计算地区、国家
|
||||
if (!string.IsNullOrEmpty(continent))
|
||||
{
|
||||
var tempList = lst.Where(it => !string.IsNullOrEmpty(it.Continent) && (it.Continent + ",").Contains(continent + ",")).ToList();
|
||||
if (tempList == null || tempList.Count == 0)
|
||||
{
|
||||
tempList = lst.Where(it => string.IsNullOrEmpty(it.Continent)).ToList();
|
||||
}
|
||||
lst = tempList;
|
||||
}
|
||||
else
|
||||
{
|
||||
lst = lst.Where(it => string.IsNullOrEmpty(it.Continent)).ToList();
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(countryName))
|
||||
{
|
||||
var tempList = lst.Where(it => !string.IsNullOrEmpty(it.CountryName) && (it.CountryName + ",").Contains(countryName + ",")).ToList();
|
||||
if (tempList == null || tempList.Count == 0)
|
||||
{
|
||||
tempList = lst.Where(it => string.IsNullOrEmpty(it.CountryName)).ToList();
|
||||
}
|
||||
lst = tempList;
|
||||
}
|
||||
else
|
||||
{
|
||||
lst = lst.Where(it => string.IsNullOrEmpty(it.CountryName)).ToList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 计算平台
|
||||
|
||||
if (!string.IsNullOrEmpty(plat))
|
||||
{
|
||||
var tempList = lst.Where(a => a.Plat != null && a.Plat == plat).ToList();
|
||||
if (tempList == null || tempList.Count == 0)
|
||||
{
|
||||
tempList = lst.Where(a => a.Plat == null || string.IsNullOrEmpty(a.Plat)).ToList();
|
||||
}
|
||||
lst = tempList;
|
||||
}
|
||||
else
|
||||
{
|
||||
lst = lst.Where(a => a.Plat == null || string.IsNullOrEmpty(a.Plat)).ToList();
|
||||
}
|
||||
#endregion
|
||||
#region 计算渠道号
|
||||
if (!string.IsNullOrEmpty(bossId))
|
||||
{
|
||||
|
||||
|
||||
var lsts = lst.Where(a => a.BossId != null && (a.BossId == bossId || a.BossId.Contains(bossId))).ToList();
|
||||
if (lsts == null || lsts.Count == 0)
|
||||
{
|
||||
lsts = lst.Where(it => it.BossId == null || string.IsNullOrEmpty(it.BossId)).ToList();
|
||||
}
|
||||
lst = lsts;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
lst = lst.Where(it => it.BossId == null || string.IsNullOrEmpty(it.BossId)).ToList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Model\CloudGaming.DtoModel\CloudGaming.DtoModel.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
67
src/CloudGaming/Console/CloudGaming.Test/ObjectExtensions.cs
Normal file
67
src/CloudGaming/Console/CloudGaming.Test/ObjectExtensions.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
namespace CloudGaming.Test;
|
||||
|
||||
|
||||
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropertyCache = new();
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> FieldCache = new();
|
||||
|
||||
public static Dictionary<string, object> ToDictionary(this object obj, int maxDepth = 3)
|
||||
{
|
||||
return ToDictionaryRecursive(obj, maxDepth);
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> ToDictionaryRecursive(object obj, int depth)
|
||||
{
|
||||
if (obj == null || depth < 0)
|
||||
return null;
|
||||
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
var type = obj.GetType();
|
||||
|
||||
var properties = PropertyCache.GetOrAdd(type, t => t.GetProperties(BindingFlags.Public | BindingFlags.Instance));
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(obj);
|
||||
dictionary[property.Name] = ConvertValue(value, depth - 1);
|
||||
}
|
||||
|
||||
var fields = FieldCache.GetOrAdd(type, t => t.GetFields(BindingFlags.Public | BindingFlags.Instance));
|
||||
foreach (var field in fields)
|
||||
{
|
||||
var value = field.GetValue(obj);
|
||||
dictionary[field.Name] = ConvertValue(value, depth - 1);
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static object ConvertValue(object value, int depth)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
if (value is IEnumerable enumerable && !(value is string))
|
||||
{
|
||||
var list = new List<object>();
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
list.Add(ConvertValue(item, depth - 1));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
if (value.GetType().IsClass && !(value is string))
|
||||
{
|
||||
return ToDictionaryRecursive(value, depth - 1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
24
src/CloudGaming/Console/CloudGaming.Test/Program.cs
Normal file
24
src/CloudGaming/Console/CloudGaming.Test/Program.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// See https://aka.ms/new-console-template for more information
|
||||
using CloudGaming.DtoModel;
|
||||
using CloudGaming.Test;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
Console.WriteLine("Hello, World!");
|
||||
AppConfigDto appConfigDto = new AppConfigDto()
|
||||
{
|
||||
//AppConfigExtend = new AppConfigExtend()
|
||||
//{
|
||||
// TestImage = 1
|
||||
//},
|
||||
//CheckingGames = new List<string>() { "iu","cg111"},
|
||||
//IsChecking = true,
|
||||
//HighDelay = true,
|
||||
//OpenImage = 1,
|
||||
//MyProperty = "test"
|
||||
};
|
||||
var dic = appConfigDto.ToDictionary(15);
|
||||
Console.WriteLine(JsonConvert.SerializeObject(dic));
|
||||
Console.ReadKey();
|
||||
|
|
@ -18,36 +18,20 @@ public class AppConfigDto
|
|||
/// </summary>
|
||||
public bool IsChecking { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 版本审核中可玩游戏(在谷歌包的审核模式下可以玩的游戏列表)
|
||||
/// </summary>
|
||||
public List<string> CheckingGames = new List<string>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启实名认证
|
||||
/// </summary>
|
||||
public bool IsAuthRealName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否是高延迟地区
|
||||
/// </summary>
|
||||
public bool HighDelay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开屏图
|
||||
/// </summary>
|
||||
[Images]
|
||||
public int OpenImage { get; set; }
|
||||
///// <summary>
|
||||
///// 开屏图
|
||||
///// </summary>
|
||||
//[Images]
|
||||
//public int OpenImage { get; set; }
|
||||
|
||||
|
||||
|
||||
public AppConfigExtend AppConfigExtend { get; set; }
|
||||
}
|
||||
|
||||
public class AppConfigExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 开屏图
|
||||
/// </summary>
|
||||
[Images]
|
||||
public int TestImage { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HuanMeng.DotNetCore.AttributeExtend;
|
||||
|
||||
namespace HuanMeng.DotNetCore.Utility;
|
||||
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存属性信息以提高反射访问的性能,使用 ConcurrentDictionary 确保线程安全
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PropertyCache = new();
|
||||
/// <summary>
|
||||
/// 缓存字段信息以提高反射访问的性能,使用 ConcurrentDictionary 确保线程安全
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> FieldCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// 将对象转换为 Dictionary<string, object> 类型。
|
||||
/// </summary>
|
||||
/// <param name="obj">要转换的对象。</param>
|
||||
/// <param name="maxDepth">最大递归深度,以控制嵌套对象的转换层数。</param>
|
||||
/// <returns>包含对象属性和值的字典。</returns>
|
||||
public static Dictionary<string, object> ToDictionary(this object obj, int maxDepth = 3)
|
||||
{
|
||||
return ToDictionaryRecursive(obj, maxDepth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归地将对象转换为 Dictionary<string, object>。
|
||||
/// </summary>
|
||||
/// <param name="obj">要转换的对象。</param>
|
||||
/// <param name="depth">当前递归深度。</param>
|
||||
/// <returns>包含对象属性和值的字典。</returns>
|
||||
private static Dictionary<string, object> ToDictionaryRecursive(object obj, int depth)
|
||||
{
|
||||
// 检查对象是否为 null 或递归深度是否小于 0,若是则返回 null
|
||||
if (obj == null || depth < 0)
|
||||
return null;
|
||||
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
var type = obj.GetType();
|
||||
|
||||
// 获取对象的属性信息,若类型已缓存则直接使用缓存中的信息
|
||||
var properties = PropertyCache.GetOrAdd(type, t => t.GetProperties(BindingFlags.Public | BindingFlags.Instance));
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(obj);
|
||||
var imagesAttribute = property.GetCustomAttribute<ImagesAttribute>();
|
||||
if (imagesAttribute != null)
|
||||
{
|
||||
string keyName = property.Name;
|
||||
if (!string.IsNullOrEmpty(imagesAttribute.FieldName))
|
||||
{
|
||||
keyName = imagesAttribute.FieldName;
|
||||
}
|
||||
dictionary[keyName] = $"[Images]{value.ToString()}";
|
||||
continue;
|
||||
}
|
||||
// 获取属性值并递归转换
|
||||
|
||||
dictionary[property.Name] = ConvertValue(value, depth - 1);
|
||||
}
|
||||
|
||||
// 获取对象的字段信息,若类型已缓存则直接使用缓存中的信息
|
||||
//var fields = FieldCache.GetOrAdd(type, t => t.GetFields(BindingFlags.Public | BindingFlags.Instance));
|
||||
//foreach (var field in fields)
|
||||
//{
|
||||
// //var imagesAttribute = field.GetCustomAttribute<ImagesAttribute>();
|
||||
// //if (imagesAttribute != null)
|
||||
// //{
|
||||
// // Console.WriteLine($"带有 [Images] 特性的成员:{field.Name}");
|
||||
// // Console.WriteLine($"FieldName 属性值:{imagesAttribute?.FieldName}");
|
||||
// //}
|
||||
// // 获取字段值并递归转换
|
||||
// var value = field.GetValue(obj);
|
||||
// dictionary[field.Name] = ConvertValue(value, depth - 1);
|
||||
//}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将属性或字段值转换为适当的类型。
|
||||
/// </summary>
|
||||
/// <param name="value">要转换的值。</param>
|
||||
/// <param name="depth">当前递归深度。</param>
|
||||
/// <returns>转换后的值,可能是基本类型、字典或列表。</returns>
|
||||
private static object ConvertValue(object value, int depth)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
// 检查是否为集合类型(非字符串),如果是则递归转换集合中的每个元素
|
||||
if (value is IEnumerable enumerable && !(value is string))
|
||||
{
|
||||
var list = new List<object>();
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
list.Add(ConvertValue(item, depth - 1));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// 如果是类且非字符串,则递归转换为字典类型
|
||||
if (value.GetType().IsClass && !(value is string))
|
||||
{
|
||||
return ToDictionaryRecursive(value, depth - 1);
|
||||
}
|
||||
|
||||
// 对于基本类型或字符串,直接返回值
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user