From 32d30a2746ebe4888c277eca69c2e7ab4cbd425b Mon Sep 17 00:00:00 2001 From: zpc Date: Fri, 11 Oct 2024 21:36:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Base/CloudGamingControllerBase.cs | 23 +++ .../CloudGaming.Api/CloudGaming.Api.csproj | 8 +- .../Controllers/AppController.cs | 27 +++ .../Api/CloudGaming.Api/Program.cs | 28 ++- .../appsettings.Development.json | 8 + .../Api/CloudGaming.Api/appsettings.json | 74 +++++++- .../AppExtend/AppConfigurationExtend.cs | 2 - .../AppExtend/CloudGamingBase.cs | 174 ++++++++++++++++++ .../CloudGaming.Code/Cache/CacheBaseConfig.cs | 31 ++++ .../Cache/CloudGamingCache.cs | 146 +++++++++++++++ .../Cache/DataBaseEntityCache.cs | 54 ++++++ .../CloudGaming.Code/CloudGaming.Code.csproj | 1 + .../Code/CloudGaming.Code/DataAccess/DAO.cs | 3 +- .../Db/Db_Ext/CloudGamingCBTContext.cs | 8 +- .../Db/Db_Ext/T_App_Config.cs | 47 +++++ .../Db_Ext/{T_Images.cs => T_Image_Config.cs} | 4 +- .../CacheHelper/CommonDataEntityCache.cs | 98 ++++++++++ .../CacheHelper/Contract/ICacheClearData.cs | 20 ++ .../CacheHelper/Contract/ICacheReloadData.cs | 19 ++ .../CacheHelper/MemoryCacheHelper.cs | 2 +- .../Redis/RedisConnection.cs | 56 ++++++ 21 files changed, 819 insertions(+), 14 deletions(-) create mode 100644 src/CloudGaming/Api/CloudGaming.Api/Base/CloudGamingControllerBase.cs create mode 100644 src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs create mode 100644 src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs create mode 100644 src/CloudGaming/Code/CloudGaming.Code/Cache/CacheBaseConfig.cs create mode 100644 src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs create mode 100644 src/CloudGaming/Code/CloudGaming.Code/Cache/DataBaseEntityCache.cs create mode 100644 src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs rename src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/{T_Images.cs => T_Image_Config.cs} (93%) create mode 100644 src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs create mode 100644 src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs create mode 100644 src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs create mode 100644 src/CloudGaming/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs diff --git a/src/CloudGaming/Api/CloudGaming.Api/Base/CloudGamingControllerBase.cs b/src/CloudGaming/Api/CloudGaming.Api/Base/CloudGamingControllerBase.cs new file mode 100644 index 0000000..37897a2 --- /dev/null +++ b/src/CloudGaming/Api/CloudGaming.Api/Base/CloudGamingControllerBase.cs @@ -0,0 +1,23 @@ +using AutoMapper; + +using CloudGaming.Code.DataAccess; + +using Microsoft.AspNetCore.Mvc; + +namespace CloudGaming.Api.Base +{ + /// + /// 基础父类 + /// + /// + [ApiController] + [Route("api/[controller]/[action]")] + public class CloudGamingControllerBase(IServiceProvider _serviceProvider) : ControllerBase + { + /// + /// 数据库使用 + /// + public IServiceProvider ServiceProvider { get; set; } = _serviceProvider; + + } +} diff --git a/src/CloudGaming/Api/CloudGaming.Api/CloudGaming.Api.csproj b/src/CloudGaming/Api/CloudGaming.Api/CloudGaming.Api.csproj index 09cae8e..567d147 100644 --- a/src/CloudGaming/Api/CloudGaming.Api/CloudGaming.Api.csproj +++ b/src/CloudGaming/Api/CloudGaming.Api/CloudGaming.Api.csproj @@ -20,9 +20,15 @@ + + - + + + + + diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs new file mode 100644 index 0000000..db01b70 --- /dev/null +++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AppController.cs @@ -0,0 +1,27 @@ +using CloudGaming.Api.Base; + +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace CloudGaming.Api.Controllers +{ + /// + /// + /// + public class AppController : CloudGamingControllerBase + { + public AppController(IServiceProvider _serviceProvider) : base(_serviceProvider) + { + } + /// + /// + /// + /// + [HttpGet] + public async Task GetConfig() + { + return "a"; + } + } +} diff --git a/src/CloudGaming/Api/CloudGaming.Api/Program.cs b/src/CloudGaming/Api/CloudGaming.Api/Program.cs index 020c515..98134d2 100644 --- a/src/CloudGaming/Api/CloudGaming.Api/Program.cs +++ b/src/CloudGaming/Api/CloudGaming.Api/Program.cs @@ -10,10 +10,29 @@ using HuanMeng.DotNetCore.SwaggerUtile; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Serilog; var builder = WebApplication.CreateBuilder(args); - +#region 日志 // Add services to the container. +builder.Host.UseSerilog((context, services, configuration) => configuration + .ReadFrom.Configuration(context.Configuration) + .ReadFrom.Services(services) + .Enrich.FromLogContext()); +builder.Services.AddSingleton(typeof(ILogger), serviceProvider => +{ + var loggerFactory = serviceProvider.GetRequiredService(); + return loggerFactory.CreateLogger(); +}); +// +builder.Services.AddSingleton(typeof(ILogger), serviceProvider => +{ + var loggerFactory = serviceProvider.GetRequiredService(); + return loggerFactory.CreateLogger(); +}); +#endregion + +#region 返回数据解析 builder.Services.AddControllers() .AddNewtonsoftJson(options => { @@ -27,8 +46,10 @@ builder.Services.AddControllers() //options.SerializerSettings.Converters.Add() // 其他配置... }); +#endregion // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); +#region jwt builder.Services.AddSwaggerGen(c => { @@ -66,6 +87,9 @@ builder.Services.AddSwaggerGen(c => c.ParameterFilter(); c.RequestBodyFilter(); }); + +#endregion + builder.AddAppConfigClient(); //添加jwt验证 builder.AddJwtConfig(); @@ -83,7 +107,7 @@ var app = builder.Build(); //if (app.Environment.IsDevelopment()) //{ // app.UseSwagger(); -// app.UseSwaggerUI(); +// app.UseSwaggerUI(); //} app.UseSwagger(); app.UseSwaggerUI(c => diff --git a/src/CloudGaming/Api/CloudGaming.Api/appsettings.Development.json b/src/CloudGaming/Api/CloudGaming.Api/appsettings.Development.json index 0c208ae..6d2575f 100644 --- a/src/CloudGaming/Api/CloudGaming.Api/appsettings.Development.json +++ b/src/CloudGaming/Api/CloudGaming.Api/appsettings.Development.json @@ -4,5 +4,13 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + //服务器配置 + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:8080" + } + } } } diff --git a/src/CloudGaming/Api/CloudGaming.Api/appsettings.json b/src/CloudGaming/Api/CloudGaming.Api/appsettings.json index 10f68b8..a0f7c6b 100644 --- a/src/CloudGaming/Api/CloudGaming.Api/appsettings.json +++ b/src/CloudGaming/Api/CloudGaming.Api/appsettings.json @@ -1,9 +1,81 @@ { + "ConnectionStrings": { + "UserConnectionString": "Server=192.168.1.17;Database=CloudGamingUser;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;", + "GameConnectionString": "Server=192.168.1.17;Database=CloudGamingGame;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;", + "PhoneConnectionString": "Server=192.168.1.17;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;", + "ExtConnectionString": "Server=192.168.1.17;Database=CloudGamingCBT;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + }, + "WriteTo": [ + { "Name": "Console" }, + { + "Name": "File", + "Args": { + "path": "../output/logs/info/log-.txt", + "rollingInterval": "Day", + "restrictedToMinimumLevel": "Information", //写入日志的级别 + "shared": true + //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "../output/logs/error/log-.txt", + "rollingInterval": "Day", //日志文件按天滚动生成。 + "restrictedToMinimumLevel": "Error", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal + "shared": true //不占用文件 + // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "../output/logs/debug/log-.txt", + "rollingInterval": "Day", //日志文件按天滚动生成。 + "restrictedToMinimumLevel": "Debug", //写入日志的级别 //包括 Verbose、Debug、Information、Warning、Error 和 Fatal + "shared": true //不占用文件 + // "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + }, + "JwtTokenConfig": { + //加密字段 + "secret": "XtrtwJIcxRHWInEMsCyUdwcRKLNHHAcQ1", + //发行人 + "issuer": "steamcloud.co", + //受众 + "audience": "steamcloud.co", + //token时间,分钟 + "accessTokenExpiration": 10080, + //刷新token时间.分钟 + "refreshTokenExpiration": 10100 + + }, + //服务器配置 + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:80" + } + } + } + } diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs index 525647b..8e5d079 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs @@ -3,7 +3,6 @@ using CloudGaming.Code.DataAccess.MultiTenantUtil; using System.Collections.Concurrent; using System.Collections.Frozen; -using XLib.DotNetCore.CacheHelper; namespace CloudGaming.Code.AppExtend { @@ -36,7 +35,6 @@ namespace CloudGaming.Code.AppExtend { if (AppConfigs.TryGetValue(domainName, out var appConfig)) { - return appConfig; } if (AppConfigs.TryGetValue("default", out appConfig)) diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs new file mode 100644 index 0000000..0dd3c77 --- /dev/null +++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs @@ -0,0 +1,174 @@ +using AutoMapper; + +using CloudGaming.Code.DataAccess; + +using HuanMeng.DotNetCore.JwtInfrastructure.Interface; +using HuanMeng.DotNetCore.Redis; + +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +using StackExchange.Redis; + +namespace CloudGaming.Code.AppExtend +{ + /// + /// bll基础类 + /// + public class CloudGamingBase : BLLBase + { + public CloudGamingBase(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + + #region 数据库 + private DAO _dao; + /// + /// dao 数据库 + /// + public override DAO Dao + { + get + { + if (_dao == null) + { + _dao = new DAO(_serviceProvider); + } + return _dao; + } + } + #endregion + + #region 映射 + private IMapper _mapper; + + /// + /// dto映射 + /// + //[FromServices] + public virtual IMapper Mapper + { + get + { + if (_mapper == null) + { + _mapper = _serviceProvider.GetRequiredService(); + } + return _mapper; + } + set { _mapper = value; } + } + #endregion + #region AppConfig + /// + /// + /// + private AppConfig? appConfig; + /// + /// AppConfig 配置 + /// + public AppConfig AppConfig + { + get + { + if (appConfig == null) + { + appConfig = _serviceProvider.GetService(); + } + return appConfig; + } + } + #endregion + + #region 请求信息 + private IHttpContextAccessor _HttpContextAccessor; + /// + /// HttpContextAccessor + /// + public IHttpContextAccessor HttpContextAccessor + { + get + { + if (_HttpContextAccessor == null) + { + _HttpContextAccessor = _serviceProvider.GetRequiredService(); + } + return _HttpContextAccessor; + } + } + #endregion + + #region http请求 + private IHttpClientFactory? _httpClientFactory; + + /// + /// http请求 + /// + public IHttpClientFactory HttpClientFactory + { + get + { + if (_httpClientFactory == null) + { + _httpClientFactory = _serviceProvider.GetRequiredService(); + } + return _httpClientFactory; + } + } + #endregion + + #region JWT管理 + + private IJwtAuthManager _jwtAuthManager; + /// + /// jwt管理 + /// + public IJwtAuthManager JwtAuthManager + { + get + { + if (_jwtAuthManager == null) + { + _jwtAuthManager = _serviceProvider.GetService(); + } + return _jwtAuthManager; + } + } + #endregion + + + #region 日志 + private ILogger? _logger; + public ILogger _Logger + { + + get + { + if (_logger == null) + { + _logger = _serviceProvider.GetRequiredService>(); + } + return _logger; + } + } + #endregion + + #region Redis + private IDatabase? _redis; + /// + /// 妙语实现类 + /// + public IDatabase RedisCache + { + get + { + if (_redis == null) + { + _redis = RedisConnection.GetRedis(AppConfig.RedisConnectionString); + } + return _redis; + } + } + #endregion + } +} diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/CacheBaseConfig.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/CacheBaseConfig.cs new file mode 100644 index 0000000..173b2e7 --- /dev/null +++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/CacheBaseConfig.cs @@ -0,0 +1,31 @@ +using AutoMapper; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CloudGaming.Code.Cache +{ + /// + /// + /// + public class CacheBaseConfig + { + /// + /// + /// + public AppConfig AppConfig { get; set; } + /// + /// + /// + public IMapper Mapper { get; set; } + + /// + /// 数据库 + /// + public DbContext DbContext { get; set; } + + } +} diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs new file mode 100644 index 0000000..3dde28f --- /dev/null +++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/CloudGamingCache.cs @@ -0,0 +1,146 @@ +using HuanMeng.DotNetCore.CacheHelper; + +using System.Collections.Concurrent; +using System.Linq.Expressions; + +namespace CloudGaming.Code.Cache +{ + /// + /// 缓存数据表 + /// + /// + public class CloudGamingCache(CloudGamingBase gamingBase) + { + #region 图片缓存表 + + /// + /// 图片缓存表 + /// + public CommonDataEntityCache? ImageConfigCache { get; set; } + /// + /// 图片 + /// + public List ImageConfigList + { + get + { + if (ImageConfigCache == null) + { + ImageConfigCache = CloudGamingCacheExtend.GetDataEntityCache(gamingBase); + } + return ImageConfigCache.DataList ?? new List(); + } + } + #endregion + + #region 配置缓存表 + + /// + /// 配置缓存表 + /// + public CommonDataEntityCache? AppConfigCache { get; set; } + + /// + /// 配置 + /// + public List AppConfigList + { + get + { + if (AppConfigCache == null) + { + AppConfigCache = CloudGamingCacheExtend.GetDataEntityCache(gamingBase); + } + return AppConfigCache.DataList ?? new List(); + } + } + #endregion + } + + /// + /// 游戏 + /// + public static class CloudGamingCacheExtend + { + /// + /// 缓存锁字典 + /// + private static readonly ConcurrentDictionary ExtCacheLockList = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary GameCacheLockList = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary AppCacheLockList = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary UserCacheLockList = new ConcurrentDictionary(); + + /// + /// 命名空间与缓存映射 + /// + private static readonly Dictionary cacheList, AppDataBaseType dbType)> NamespaceMapping; + + static CloudGamingCacheExtend() + { + NamespaceMapping = new Dictionary cacheList, AppDataBaseType dbType)> + { + { "CloudGaming.GameModel.Db.Db_Ext", (ExtCacheLockList, AppDataBaseType.Ext) }, + { "CloudGaming.GameModel.Db.Db_Game", (GameCacheLockList, AppDataBaseType.Game) }, + { "CloudGaming.Model.DbSqlServer.Db_Phone", (AppCacheLockList, AppDataBaseType.App) }, + { "CloudGaming.Model.DbSqlServer.Db_User", (UserCacheLockList, AppDataBaseType.User) } + }; + } + + /// + /// 获取实体缓存 + /// + public static CommonDataEntityCache GetDataEntityCache(CloudGamingBase cloudGamingBase, Expression>? expWhere = null) where T : class + { + var typeLock = typeof(T); + var namespaceKey = typeLock.Namespace; + + if (namespaceKey == null || !NamespaceMapping.ContainsKey(namespaceKey)) + { + throw new Exception($"缓存数据不存在或命名空间不匹配:{namespaceKey}"); + } + + var (cacheList, dbType) = NamespaceMapping[namespaceKey]; + object cacheLock = GetOrAddCacheLock(typeLock, cacheList); + CacheBaseConfig cacheBaseConfig = cloudGamingBase.ToCacheBaseConfig(dbType); + + return new DataBaseEntityCache(cacheBaseConfig, cacheLock, expWhere: expWhere); + } + + /// + /// 获取或添加缓存锁对象 + /// + private static object GetOrAddCacheLock(Type typeLock, ConcurrentDictionary cacheList) + { + return cacheList.GetOrAdd(typeLock, _ => + { + Log("没有找到锁对象==>" + typeLock.Name); + return new object(); + }); + } + + /// + /// 根据数据库类型生成缓存配置 + /// + public static CacheBaseConfig ToCacheBaseConfig(this CloudGamingBase cloudGamingBase, AppDataBaseType appDataBaseType) + { + return appDataBaseType switch + { + AppDataBaseType.App => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoPhone.Context }, + AppDataBaseType.User => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoUser.Context }, + AppDataBaseType.Ext => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoExt.Context }, + AppDataBaseType.Game => new CacheBaseConfig { AppConfig = cloudGamingBase.AppConfig, Mapper = cloudGamingBase.Mapper, DbContext = cloudGamingBase.Dao.DaoGame.Context }, + _ => throw new Exception("未找到对应的数据连接") + }; + } + + /// + /// 日志方法 + /// + private static void Log(string message) + { + // 这里可以替换为更好的日志记录系统,例如 NLog, Serilog 等 + Console.WriteLine(message); + } + } + +} diff --git a/src/CloudGaming/Code/CloudGaming.Code/Cache/DataBaseEntityCache.cs b/src/CloudGaming/Code/CloudGaming.Code/Cache/DataBaseEntityCache.cs new file mode 100644 index 0000000..47f494e --- /dev/null +++ b/src/CloudGaming/Code/CloudGaming.Code/Cache/DataBaseEntityCache.cs @@ -0,0 +1,54 @@ +using HuanMeng.DotNetCore.CacheHelper; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace CloudGaming.Code.Cache +{ + + /// + /// + /// + /// + /// + /// + /// + /// + public class DataBaseEntityCache(CacheBaseConfig baseConfig, object lockObj, int cacheTime = 36000, Expression> expWhere = null) + : CommonDataEntityCache(lockObj, cacheTime) where T : class + { + + /// + /// 缓存的key + /// + public override string key + { + get + { + return $"Cache:{baseConfig.AppConfig.Identifier}:CloudGaming:{typeof(T).Name}"; + } + } + /// + /// + /// + /// + public override List GetDataList() + { + + var dbSet = baseConfig.DbContext.Set().AsNoTracking(); + if (dbSet == null) + { + return new List(); + } + if (expWhere != null) + { + dbSet = dbSet.Where(expWhere); + } + return dbSet.ToList(); + } + } +} diff --git a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj index ed85ee3..b0db308 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/Code/CloudGaming.Code/DataAccess/DAO.cs b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/DAO.cs index aa17b91..e03d698 100644 --- a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/DAO.cs +++ b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/DAO.cs @@ -40,8 +40,8 @@ namespace CloudGaming.Code.DataAccess public DAO(IServiceProvider serviceProvider, AppConfig appConfig) : base(serviceProvider) { this._tenantInfo = appConfig.ToITenantInfo(); - } + #region 扩展 private EfCoreDaoBase? _daoExt; /// @@ -62,6 +62,7 @@ namespace CloudGaming.Code.DataAccess } } #endregion + #region 游戏 private EfCoreDaoBase? _daoGame; /// 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 04a0bd4..80de259 100644 --- a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs +++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs @@ -47,19 +47,19 @@ public partial class CloudGamingCBTContext : DbContext /// /// App配置 /// - public virtual DbSet T_Config { get; set; } + public virtual DbSet T_App_Config { get; set; } /// /// 图片列表 /// - public virtual DbSet T_Images { get; set; } + public virtual DbSet T_Image_Config { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlServer("Server=192.168.1.17;Database=CloudGamingCBT;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;"); protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("PK_T_APP_CONFIG"); @@ -94,7 +94,7 @@ public partial class CloudGamingCBTContext : DbContext }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("PK_T_VL_UI_IMAGES"); 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 new file mode 100644 index 0000000..22bb558 --- /dev/null +++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_App_Config.cs @@ -0,0 +1,47 @@ +using System; + +namespace CloudGaming.GameModel.Db.Db_Ext; + +/// +/// App配置 +/// +public partial class T_App_Config +{ + public T_App_Config() { } + + public virtual int Id { get; set; } + + public virtual int? ConfigType { get; set; } + + public virtual int? ConfigId { get; set; } + + public virtual bool? IsShow { get; set; } + + public virtual string? ShowName { 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; } + + /// + /// 州 例:亚洲 + /// + public virtual string? Continent { get; set; } + + /// + /// 国家 例:中国 + /// + public virtual string? CountryName { get; set; } +} diff --git a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Images.cs b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Image_Config.cs similarity index 93% rename from src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Images.cs rename to src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Image_Config.cs index 75633b6..1922715 100644 --- a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Images.cs +++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_Image_Config.cs @@ -5,9 +5,9 @@ namespace CloudGaming.GameModel.Db.Db_Ext; /// /// 图片列表 /// -public partial class T_Images +public partial class T_Image_Config { - public T_Images() { } + public T_Image_Config() { } public virtual int Id { get; set; } diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs new file mode 100644 index 0000000..2719b67 --- /dev/null +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/CommonDataEntityCache.cs @@ -0,0 +1,98 @@ +using HuanMeng.DotNetCore.CacheHelper.Contract; + +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper +{ + /// + /// 缓存扩展- + /// + public abstract class CommonDataEntityCache : ICacheClearData, ICacheReloadData where T : class + { + /// + /// + /// + protected object lockObj; + /// + /// 过期时间 + /// + protected int cacheTime; + + protected CommonDataEntityCache(object lockObj, int cacheTime = 36000) + { + this.lockObj = lockObj; + this.cacheTime = cacheTime; + } + + + /// + /// + /// + public abstract string key { get; } + + /// + /// 缓存数据 + /// + protected List? _dataList; + + /// + /// 数据 + /// + public virtual List DataList + { + get + { + if (_dataList == null) + { + var tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList == null) + { + lock (lockObj) + { + tempDataList = MemoryCacheHelper.GetCache>(key); + if (tempDataList == null) + { + tempDataList = GetDataList(); + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + } + } + } + _dataList = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(tempDataList)); + } + return _dataList ?? new List(); + } + } + + + /// + /// 获取缓存数据 + /// + public abstract List GetDataList(); + + public bool ClearData() + { + lock (lockObj) + { + MemoryCacheHelper.DelCache(key); + _dataList = null; + } + return true; + } + + public void ReloadData() + { + lock (lockObj) + { + var tempDataList = GetDataList(); + MemoryCacheHelper.SetCache(key, tempDataList, cacheTime); + _dataList = tempDataList; + } + } + } +} diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs new file mode 100644 index 0000000..9b90538 --- /dev/null +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheClearData.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper.Contract +{ + /// + /// 清除缓存 + /// + public interface ICacheClearData + { + /// + /// 清除数据 + /// + /// + bool ClearData(); + } +} diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs new file mode 100644 index 0000000..4ccb9c5 --- /dev/null +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/Contract/ICacheReloadData.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.CacheHelper.Contract +{ + /// + /// 重新加载数据 + /// + public interface ICacheReloadData + { + /// + /// 重新加载数据 + /// + void ReloadData(); + } +} diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs index 15b52f5..682fdbf 100644 --- a/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/CacheHelper/MemoryCacheHelper.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace XLib.DotNetCore.CacheHelper +namespace HuanMeng.DotNetCore.CacheHelper { /// /// 内存缓存帮助类 diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs new file mode 100644 index 0000000..f3e9f40 --- /dev/null +++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Redis/RedisConnection.cs @@ -0,0 +1,56 @@ +using Microsoft.Identity.Client; + +using StackExchange.Redis; + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using IDatabase = StackExchange.Redis.IDatabase; +namespace HuanMeng.DotNetCore.Redis +{ + /// + /// 数据库连接字符串 + /// + public static class RedisConnection + { + /// + /// 数据库连接 + /// + public static ConcurrentDictionary Redis { get; set; } = new ConcurrentDictionary(); + + + /// + /// + /// + /// + /// + public static IDatabase GetRedis(string redisConnection) + { + if (!Redis.TryGetValue(redisConnection, out var database)) + { + var redis = ConnectionMultiplexer.Connect(redisConnection); + database = redis.GetDatabase(); + Redis.TryAdd(redisConnection, database); + } + return database; + } + + + /// + /// + /// + /// + /// + /// + /// + /// + public static bool StringSetLock(this IDatabase database, string key, string value, int time = 10) + { + return database.StringSet(key, value, TimeSpan.FromSeconds(time), when: When.NotExists); + } + } +}