diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs
index a24a08c..514ed7d 100644
--- a/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs
+++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs
@@ -1,4 +1,5 @@
using CloudGaming.Api.Base;
+using CloudGaming.DtoModel;
using CloudGaming.GameModel.Db.Db_Ext;
using HuanMeng.DotNetCore.Base;
@@ -22,9 +23,11 @@ namespace CloudGaming.Api.Controllers
///
///
[HttpGet]
- public async Task GetAppConfigAsync()
+ public async Task GetAppConfigAsync()
{
- return new { test = "测试", Data = new { txt = "内部数据" } };
+ AppConfigDto appConfigDto = new AppConfigDto();
+ appConfigDto.AppConfigExtend = new AppConfigExtend();
+ return appConfigDto;
}
///
diff --git a/src/CloudGaming/Api/CloudGaming.Api/appsettings.json b/src/CloudGaming/Api/CloudGaming.Api/appsettings.json
index 6be6211..9d8e2c3 100644
--- a/src/CloudGaming/Api/CloudGaming.Api/appsettings.json
+++ b/src/CloudGaming/Api/CloudGaming.Api/appsettings.json
@@ -69,6 +69,15 @@
"refreshTokenExpiration": 10100
},
+ "AgileConfig": {
+ "appId": "CloudGaming",
+ "secret": "95BB717C61D1ECB0E9FB82C932CC77FF",
+ "nodes": "http://124.220.55.158:94", //多个节点使用逗号分隔
+ "url": "http://124.220.55.158:94",
+ "env": "DEV",
+ "UserName": "admin",
+ "Password": "dbt@com@1234"
+ },
//服务器配置
"Kestrel": {
"Endpoints": {
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
index 8e5d079..b96dbd1 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
@@ -1,5 +1,9 @@
+using AgileConfig.Client;
+
using CloudGaming.Code.DataAccess.MultiTenantUtil;
+using HuanMeng.DotNetCore.CacheHelper;
+
using System.Collections.Concurrent;
using System.Collections.Frozen;
@@ -44,6 +48,31 @@ namespace CloudGaming.Code.AppExtend
return AppConfigs.FirstOrDefault().Value;
}
+ ///
+ ///
+ ///
+ ///
+ public static void ConfigClient_ConfigChanged(ConfigReloadedArgs args)
+ {
+
+ if (args.OldConfigs.TryGetValue("Version", out var vresion) && args.NewConfigs.TryGetValue("Version", out var newVersion))
+ {
+ if (vresion != newVersion)
+ {
+ MemoryCacheHelper.cache.Clear();
+ }
+ }
+ VerifyTenant(args);
+ //if (VerifyTenant(args, "Payment:WeChatConfig"))
+ //{
+ // PaymentExtend.AddWeChat(ConfigurationManager);
+ //}
+ //if (VerifyTenant(args, "Payment:AlipayConfig"))
+ //{
+ // PaymentExtend.AddAlipay(ConfigurationManager);
+
+ //}
+ }
///
@@ -51,12 +80,11 @@ namespace CloudGaming.Code.AppExtend
///
///
///
- public static IHostApplicationBuilder AddAppConfigClient(this IHostApplicationBuilder builder)
+ public static IHostApplicationBuilder AddAppConfigClient(this WebApplicationBuilder builder)
{
- //hostBuilder.
- //builder..UseAgileConfig(configClient, ConfigClient_ConfigChanged);
- //AppConfigClient = configClient;
+ var configClient = new ConfigClient(builder.Configuration);
+ builder.Host.UseAgileConfig(configClient, ConfigClient_ConfigChanged);
ConfigurationManager = builder.Configuration;
AppConfigInit(builder.Configuration);
builder.Services.AddScoped();
@@ -137,6 +165,41 @@ namespace CloudGaming.Code.AppExtend
return newAppConfig;
}
+ ///
+ /// 验证多租户
+ ///
+ ///
+ private static bool VerifyTenant(ConfigReloadedArgs args, string key)
+ {
+ var newTenant = args.NewConfigs.Where(it => it.Key.Contains(key)).ToDictionary();
+ var oldTenant = args.OldConfigs.Where(it => it.Key.Contains(key)).ToDictionary();
+ bool areEqual = newTenant.Count == oldTenant.Count &&
+ !newTenant.Except(oldTenant).Any();
+ if (!areEqual)
+ {
+ //更新缓存
+ //AppConfigInit(ConfigurationManager);
+ return true;
+ }
+ return false;
+ }
+ ///
+ /// 验证多租户
+ ///
+ ///
+ private static void VerifyTenant(ConfigReloadedArgs args)
+ {
+ var newTenant = args.NewConfigs.Where(it => it.Key.Contains("Tenants")).ToDictionary();
+ var oldTenant = args.OldConfigs.Where(it => it.Key.Contains("Tenants")).ToDictionary();
+ bool areEqual = newTenant.Count == oldTenant.Count &&
+ !newTenant.Except(oldTenant).Any();
+ if (!areEqual)
+ {
+ //更新缓存
+ AppConfigInit(ConfigurationManager);
+ }
+
+ }
///
/// 初始化租户数据
@@ -144,7 +207,7 @@ namespace CloudGaming.Code.AppExtend
///
private static void AppConfigInit(IConfigurationManager configurationManager)
{
- var tenants = configurationManager.GetSection("Tenant").Get>();
+ var tenants = configurationManager.GetSection("Tenants").Get>();
if (tenants != null)
{
ConcurrentDictionary _AppConfigs = new ConcurrentDictionary();
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CustomResultFilter.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CustomResultFilter.cs
index fc27fcb..b7070e8 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CustomResultFilter.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CustomResultFilter.cs
@@ -1,3 +1,5 @@
+using HuanMeng.DotNetCore.AttributeExtend;
+
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
@@ -36,11 +38,90 @@ namespace CloudGaming.Code.AppExtend
{
}
+ FindImagesAttributes(objectResult.Value);
+ // var responseObject = objectResult.Value;
+ // var membersWithImagesAttribute = responseObject.GetType()
+ //.GetMembers(BindingFlags.Public | BindingFlags.Instance)
+ //.Where(m => m.GetCustomAttribute() != null);
+ // foreach (var member in membersWithImagesAttribute)
+ // {
+ // var imagesAttribute = member.GetCustomAttribute();
+ // Console.WriteLine($"带有 [Images] 特性的成员:{member.Name}");
+ // Console.WriteLine($"FieldName 属性值:{imagesAttribute?.FieldName}");
+ // }
// 递归处理返回对象的所有属性并打印路径
ProcessObjectProperties(objectResult.Value, user, language, path);
}
}
+ private void FindImagesAttributes(object obj)
+ {
+ if (obj == null) return;
+
+ // 使用反射获取对象的所有公共实例属性和字段
+ var membersWithImagesAttribute = obj.GetType()
+ .GetMembers(BindingFlags.Public | BindingFlags.Instance)
+ .Where(m => m is PropertyInfo || m is FieldInfo);
+
+ foreach (var member in membersWithImagesAttribute)
+ {
+ // 获取并输出带有 [Images] 特性的属性或字段
+ var imagesAttribute = member.GetCustomAttribute();
+ if (imagesAttribute != null)
+ {
+ Console.WriteLine($"带有 [Images] 特性的成员:{member.Name}");
+ Console.WriteLine($"FieldName 属性值:{imagesAttribute.FieldName}");
+
+ object value = GetMemberValue(member, obj);
+ Console.WriteLine($"成员值:{value}");
+ }
+
+ // 获取成员值
+ var memberValue = GetMemberValue(member, obj);
+
+ // 如果成员是 IEnumerable(集合类型),递归处理每个元素
+ if (memberValue is IEnumerable enumerableValue && memberValue.GetType() != typeof(string))
+ {
+ foreach (var item in enumerableValue)
+ {
+ if (item != null && !IsSimpleType(item.GetType()))
+ {
+ FindImagesAttributes(item);
+ }
+ }
+ }
+ // 如果成员是非集合的复杂类型,递归检查其内部成员
+ else if (memberValue != null && !IsSimpleType(memberValue.GetType()))
+ {
+ FindImagesAttributes(memberValue);
+ }
+ }
+ }
+
+ private object GetMemberValue(MemberInfo member, object obj)
+ {
+ try
+ {
+ return member switch
+ {
+ PropertyInfo property when property.GetMethod?.IsStatic == false => property.GetValue(obj),
+ FieldInfo field when !field.IsStatic => field.GetValue(obj),
+ _ => null
+ };
+ }
+ catch (TargetParameterCountException ex)
+ {
+ Console.WriteLine($"Error retrieving value for {member.Name}: {ex.Message}");
+ return null;
+ }
+ }
+
+ private bool IsSimpleType(Type type)
+ {
+ return type.IsPrimitive || type.IsEnum || type == typeof(string) || type == typeof(decimal);
+ }
+
+
public void OnResultExecuted(ResultExecutedContext context)
{
// 可在执行完结果后处理其他逻辑
diff --git a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
index b0db308..24f5cb2 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
+++ b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
@@ -9,6 +9,7 @@
+
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/AppConfigDto.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/AppConfigDto.cs
new file mode 100644
index 0000000..02d3dab
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/AppConfigDto.cs
@@ -0,0 +1,53 @@
+using HuanMeng.DotNetCore.AttributeExtend;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel;
+
+///
+///
+///
+public class AppConfigDto
+{
+ ///
+ /// 是否版本审核中
+ ///
+ public bool IsChecking { get; set; }
+
+ ///
+ /// 版本审核中可玩游戏(在谷歌包的审核模式下可以玩的游戏列表)
+ ///
+ public List CheckingGames = new List();
+
+ ///
+ /// 是否开启实名认证
+ ///
+ public bool IsAuthRealName { get; set; }
+
+ ///
+ /// 是否是高延迟地区
+ ///
+ public bool HighDelay { get; set; }
+
+ ///
+ /// 开屏图
+ ///
+ [Images]
+ public int OpenImage { get; set; }
+
+
+ public AppConfigExtend AppConfigExtend { get; set; }
+}
+
+public class AppConfigExtend
+{
+ ///
+ /// 开屏图
+ ///
+ [Images]
+ public int TestImage { get; set; }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
index 47f9781..c0a28a3 100644
--- a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
+++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
@@ -67,9 +67,12 @@ public partial class CloudGamingCBTContext : DbContext
entity.Property(e => e.BossId)
.HasMaxLength(200)
+ .HasComment("渠道号")
.UseCollation("Chinese_PRC_CI_AS");
- entity.Property(e => e.ConfigStr)
- .HasMaxLength(2000)
+ entity.Property(e => e.ConfigId).HasComment("配置值");
+ entity.Property(e => e.ConfigType).HasComment("配置类型");
+ entity.Property(e => e.ConfigValue)
+ .HasComment("配置值")
.UseCollation("Chinese_PRC_CI_AS");
entity.Property(e => e.Continent)
.HasMaxLength(200)
@@ -79,18 +82,26 @@ public partial class CloudGamingCBTContext : DbContext
.HasMaxLength(200)
.HasComment("国家 例:中国")
.UseCollation("Chinese_PRC_CI_AS");
- entity.Property(e => e.CreatTime).HasColumnType("datetime");
+ entity.Property(e => e.CreatTime)
+ .HasComment("创建时间")
+ .HasColumnType("datetime");
entity.Property(e => e.Desc)
- .HasMaxLength(2000)
+ .HasComment("备注")
+ .UseCollation("Chinese_PRC_CI_AS");
+ entity.Property(e => e.ExtJson).HasComment("扩展信息");
+ entity.Property(e => e.IsShow).HasComment("是否启用");
+ entity.Property(e => e.Name)
+ .HasMaxLength(200)
+ .HasComment("配置名称")
.UseCollation("Chinese_PRC_CI_AS");
entity.Property(e => e.Plat)
.HasMaxLength(100)
.IsUnicode(false)
+ .HasComment("平台。安卓还是苹果")
.UseCollation("Chinese_PRC_CI_AS");
- entity.Property(e => e.ShowName)
- .HasMaxLength(200)
- .UseCollation("Chinese_PRC_CI_AS");
- entity.Property(e => e.UpdateTime).HasColumnType("datetime");
+ entity.Property(e => e.UpdateTime)
+ .HasComment("修改时间")
+ .HasColumnType("datetime");
});
diff --git a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs
index 22bb558..e30fcd0 100644
--- a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs
+++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs
@@ -11,28 +11,44 @@ public partial class T_App_Config
public virtual int Id { get; set; }
- public virtual int? ConfigType { get; set; }
+ ///
+ /// 配置类型
+ ///
+ public virtual int ConfigType { get; set; }
- public virtual int? ConfigId { get; set; }
+ ///
+ /// 配置值
+ ///
+ public virtual int ConfigId { get; set; }
- public virtual bool? IsShow { get; set; }
-
- public virtual string? ShowName { get; set; }
+ ///
+ /// 是否启用
+ ///
+ public virtual bool IsShow { get; set; }
+ ///
+ /// 备注
+ ///
public virtual string? Desc { get; set; }
+ ///
+ /// 修改时间
+ ///
public virtual DateTime? UpdateTime { get; set; }
+ ///
+ /// 创建时间
+ ///
public virtual DateTime? CreatTime { get; set; }
- public virtual int? ConfigNum { get; set; }
-
- public virtual int? ConfigNum2 { get; set; }
-
- public virtual string? ConfigStr { get; set; }
-
+ ///
+ /// 渠道号
+ ///
public virtual string? BossId { get; set; }
+ ///
+ /// 平台。安卓还是苹果
+ ///
public virtual string? Plat { get; set; }
///
@@ -44,4 +60,19 @@ public partial class T_App_Config
/// 国家 例:中国
///
public virtual string? CountryName { get; set; }
+
+ ///
+ /// 配置值
+ ///
+ public virtual string? ConfigValue { get; set; }
+
+ ///
+ /// 配置名称
+ ///
+ public virtual string? Name { get; set; }
+
+ ///
+ /// 扩展信息
+ ///
+ public virtual string? ExtJson { get; set; }
}
diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs
new file mode 100644
index 0000000..1374f47
--- /dev/null
+++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/AttributeExtend/ImagesAttribute.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HuanMeng.DotNetCore.AttributeExtend;
+
+///
+///
+///
+[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
+public class ImagesAttribute : Attribute
+{
+
+ public string FieldName { get; set; }
+ ///
+ ///
+ ///
+ /// 生成字段名称
+ // 构造函数,用于传递参数
+ public ImagesAttribute(string fieldName = "")
+ {
+ this.FieldName = fieldName;
+ }
+}