添加首页接口

This commit is contained in:
zpc 2024-11-07 16:21:04 +08:00
parent 54ea3036f5
commit d762ed726d
15 changed files with 548 additions and 122 deletions

View File

@ -54,39 +54,7 @@ namespace CloudGaming.Code.AppExtend
var dic = value.ToDictionaryOrList();
objectResult.Value = dic;
//if (objectResult.Value is IEnumerable enumerable)
//{
// var list = objectResult.Value.ToListDictionary(5);
// BaseResponse<List<Dictionary<string, object>>> baseResponse = new BaseResponse<List<Dictionary<string, object>>>(ResonseCode.Success, "", list);
// objectResult.Value = baseResponse;
// return;
//}
//var dic = objectResult.Value.ToDictionary(5);
//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);
}
}

View File

@ -1,3 +1,8 @@
using AutoMapper;
using CloudGaming.Code.Cache.Special;
using CloudGaming.DtoModel.Game;
using HuanMeng.DotNetCore.CacheHelper;
using System.Collections.Concurrent;
@ -65,8 +70,39 @@ namespace CloudGaming.Code.Cache
public List<T_Epg_CategoryCfg> EpgCategoryCfg => GetCacheList(ref _epgCategoryCfg, it => it.IsOnline);
#endregion
public GameEntityCache? gameEntityCache;
/// <summary>
/// 游戏缓存
/// </summary>
public GameEntityCache GameEntityCache
{
get
{
if (gameEntityCache == null)
{
gameEntityCache = new GameEntityCache(_gamingBase.Dao, _gamingBase.RedisCache, _gamingBase.Mapper, _gamingBase.AppConfig);
}
return gameEntityCache;
}
}
/// <summary>
/// 游戏列表
/// </summary>
public List<GameInfo> GameInfos
{
get
{
return GameEntityCache?.DataList ?? new List<GameInfo>();
}
}
#region
//private CommonDataEntityCache<T_Game_List>? _gameList;
///// <summary>

View File

@ -0,0 +1,195 @@
using AutoMapper;
using CloudGaming.Code.DataAccess;
using CloudGaming.DtoModel.Game;
using CloudGaming.GameModel.Db.Db_Game;
using HuanMeng.DotNetCore.CacheHelper;
using HuanMeng.DotNetCore.Redis;
using Newtonsoft.Json;
using Org.BouncyCastle.Utilities.Collections;
using StackExchange.Redis;
using System.Collections.Generic;
using System.Linq;
namespace CloudGaming.Code.Cache.Special
{
/// <summary>
/// 游戏缓存表
/// </summary>
public class GameEntityCache(DAO dao, IDatabase database, IMapper mapper, AppConfig appConfig) : CommonDataEntityCache<GameInfo>(GameEntityCache.GameEntityCacheLock, 60 * 60 * 24 * 7)
{
public static object GameEntityCacheLock;
public override string key => $"{appConfig.Identifier}:game:gameInfo";
public string locaKey => $"{appConfig.Identifier}:lock:gameInfo";
public override List<GameInfo> GetDataList()
{
var gameCbtList = dao.DaoPhone.Context.T_GameCBT.AsNoTracking().Where(it => it.IsOnline).ToList() ?? new List<T_GameCBT>();
var gameListDict = dao.DaoGame.Context.T_Game_List.AsNoTracking().ToDictionary(g => g.GameId);
var gameChildList = dao.DaoGame.Context.T_Game_ChildList.AsNoTracking().ToList();
var gameTypesDict = dao.DaoGame.Context.T_Game_Types.AsNoTracking().ToDictionary(type => type.TypeId);
var gameTagsDict = dao.DaoGame.Context.T_Game_Tags.AsNoTracking().ToDictionary(tag => tag.TagId);
var gameInfos = gameCbtList
.Where(gameCbt => gameListDict.ContainsKey(gameCbt.GameId))
.Select(gameCbt =>
{
var game = gameListDict[gameCbt.GameId];
var gameInfo = mapper.Map<GameInfo>(gameCbt);
game.ToGameInfo(gameInfo);
gameInfo.GameType = GetGameExtendedAttributes(gameChildList, gameCbt.GameId, 1, gameTypesDict);
gameInfo.GameTags = GetGameExtendedAttributes(gameChildList, gameCbt.GameId, 2, gameTagsDict);
return gameInfo;
})
.ToList();
return gameInfos;
}
/// <summary>
///
/// </summary>
public override List<GameInfo> DataList
{
get
{
start:
if (_dataList != null) return _dataList;
var tempDataList = MemoryCacheHelper.GetCache<List<GameInfo>>(key);
if (tempDataList != null)
{
_dataList = tempDataList;
return _dataList;
}
long hashLength = database.HashLength(key);
if (hashLength > 0)
{
var hashEntries = database.HashGetAll(key);
var list = hashEntries
.Where(entry => !string.IsNullOrEmpty(entry.Value))
.Select(entry => JsonConvert.DeserializeObject<GameInfo>(entry.Value))
.ToList();
MemoryCacheHelper.SetCache(key, list, 10);
_dataList = list;
return _dataList;
}
if (!database.StringSetLock(locaKey, "1", 5))
{
goto start;
}
tempDataList ??= GetDataList();
var serializedGameInfos = tempDataList
.Select(info => new HashEntry($"gameInfo:{info.GameId}", JsonConvert.SerializeObject(info)))
.ToArray();
database.HashSet(key, serializedGameInfos);
MemoryCacheHelper.SetCache(key, tempDataList, 60 * 60);
_dataList = tempDataList;
database.KeyDelete(locaKey);
return _dataList;
}
}
private Dictionary<string, GameInfo> gameInfoDic;
/// <summary>
/// 游戏详情
/// </summary>
public Dictionary<string, GameInfo> GameInfoDic
{
get
{
if (gameInfoDic == null)
{
gameInfoDic = DataList.ToDictionary(it => it.GameId);
}
return gameInfoDic;
}
}
/// <summary>
/// 获取游戏详情
/// </summary>
/// <param name="gameId"></param>
/// <returns></returns>
public GameInfo? this[string? gameId]
{
get
{
if (string.IsNullOrEmpty(gameId))
{
return null;
}
return GameInfoDic[gameId] ?? null;
}
}
private List<GameExtendedAttribute> GetGameExtendedAttributes<T>(
List<T_Game_ChildList> gameChildList,
string gameId,
int childType,
Dictionary<int, T> dictionary) where T : class
{
return gameChildList
.Where(it => it.GameId == gameId && it.ChildType == childType && (it.ChildId ?? 0) > 0)
.OrderBy(it => it.OrderId)
.Select(it =>
{
dictionary.TryGetValue(it.ChildId.Value, out var item);
return item switch
{
T_Game_Types type => new GameExtendedAttribute
{
Id = type.TypeId,
Name = type.TypeName,
OrderId = it.OrderId
},
T_Game_Tags tag => new GameExtendedAttribute
{
Id = tag.TagId,
Name = tag.TagName,
OrderId = it.OrderId
},
_ => new GameExtendedAttribute()
};
})
.Where(attr => attr.Id > 0)
.ToList();
}
public override bool ClearData()
{
lock (GameEntityCacheLock)
{
database.KeyDelete(key);
MemoryCacheHelper.DelCache(key);
_dataList = null;
gameInfoDic = null;
}
return true;
}
public override void ReloadData()
{
lock (lockObj)
{
database.KeyDelete(key);
MemoryCacheHelper.DelCache(key);
_dataList = null;
var x = DataList;
}
}
}
}

View File

@ -41,30 +41,22 @@ namespace CloudGaming.Code.Epg
{
var list = new List<EpgInfo>()
{
//STEAMCLOUD
};
if (it.IdName == EpgEnum.EpgCatIdName.banner滚动栏)
var epgList = GetEpgList(it.Id);
epgList?.ForEach(item =>
{
var epgList = GetEpgList(it.Id);
epgList.ForEach(item =>
//如果首页展示数量小于集合数量,则退出
if (it.ShowNumIndex < list.Count)
{
if (item.ResType == (int)EpgEnum.EpgResType.)
{
}
EpgInfo epgInfo = new EpgInfo()
{
CornerIcon = item.CornerIconId,
EpgId = item.EpgId,
Pic = item.ImageId,
//GameIconImage = item.
};
});
}
return;
}
var epgInfo = item.ToEpgInfo(Cache.GameEntityCache);
if (epgInfo != null)
{
list.Add(epgInfo);
}
});
if (list.Count > 0)
{
@ -108,7 +100,9 @@ namespace CloudGaming.Code.Epg
DateTime currentHour = DateTime.Now.Date.AddHours(DateTime.Now.Hour);
if (list?.DataList?.Count > 0)
{
var dataList = list.DataList.Where(it => it.EpgCategory == epgParentCategoryId && it.StartEnableTime < currentHour && it.EndEnableTime > currentHour).ToList();
var dataList = list.DataList.Where(it => it.EpgCategory == epgParentCategoryId &&
(it.StartEnableTime == null || it.StartEnableTime < currentHour)
&& (it.EndEnableTime == null || it.EndEnableTime > currentHour)).ToList();
return dataList;
}
return null;

View File

@ -0,0 +1,72 @@
using CloudGaming.Code.Cache.Special;
using CloudGaming.DtoModel.Epg;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static CloudGaming.DtoModel.Epg.EpgEnum;
namespace CloudGaming.Code.Epg
{
public static class EpgExtend
{
/// <summary>
/// 菜单转化游戏
/// </summary>
/// <param name="epgCfg"></param>
/// <param name="gameEntityCache"></param>
/// <returns></returns>
public static EpgInfo ToEpgInfo(this T_Epg_Cfg epgCfg, GameEntityCache gameEntityCache)
{
if (epgCfg.ResType == (int)EpgEnum.EpgResType. && string.IsNullOrEmpty(epgCfg.ResId))
{
return null;
}
var epgInfo = new EpgInfo
{
CornerIcon = epgCfg.CornerIconId,
EpgId = epgCfg.Id,
ResId = epgCfg.ResId,
ResType = epgCfg.ResType,
IdName = epgCfg.IdName,
ImageUrl = epgCfg.ImageId,
Title = epgCfg.Title,
SubTitle = epgCfg.Title2
};
if (epgCfg.ResType == (int)EpgEnum.EpgResType.)
{
var gameInfo = gameEntityCache[epgCfg.ResId];
if (gameInfo == null)
{
return null;
}
epgInfo.Title ??= gameInfo.GameName;
epgInfo.SubTitle ??= gameInfo.Title2;
if (epgInfo.ImageUrl == 0 && !string.IsNullOrEmpty(epgCfg.ImageResStyle))
{
epgInfo.ImageUrl = epgCfg.ImageResStyle switch
{
var style when style == ((int)ImageResStyle.Game尊享推荐_312_420).ToString() => gameInfo.ImageId_ZXTJ,
var style when style == ((int)ImageResStyle.Game推荐位大图_984_520).ToString() => gameInfo.ImageId_TJ,
var style when style == ((int)ImageResStyle.Game游戏库_180_180).ToString() => gameInfo.GameImageId,
var style when style == ((int)ImageResStyle.Game最近推出_360_548).ToString() => gameInfo.ImageId_ZJTC,
var style when style == ((int)ImageResStyle.Game精选推荐_474_300).ToString() => gameInfo.ImageId_JXTJ,
_ => epgInfo.ImageUrl
};
}
epgInfo.Score = gameInfo.Score ?? string.Empty;
}
return epgInfo;
}
}
}

View File

@ -89,41 +89,6 @@ namespace CloudGaming.DtoModel.Epg
webH5 = 4
}
/// <summary>
/// 客户端的跳转类型
/// 示例holybladeData={"dataType":9"dataId":"https://moguext.moguyouxi.cn/moguext/ui/bbs/autologin"}
/// </summary>
public enum JumpDataType
{
/// <summary>
/// dataId=咨询Id
/// </summary>
= 1,
= 2,
= 3,
= 4,
= 5,
/// <summary>
/// 应该不用了
/// </summary>
= 6,
/// <summary>
/// dataId无
/// </summary>
= 7,
/// <summary>
/// dataId无
/// </summary>
= 8,
/// <summary>
/// dataId=h5页面完整地址
/// </summary>
h5页面 = 9,
}
}
}

View File

@ -20,7 +20,7 @@ namespace CloudGaming.DtoModel.Epg
public int EpgId { get; set; }
/// <summary>
/// 资源类型4游戏
/// 资源类型
/// </summary>
public int ResType { get; set; }
@ -38,40 +38,26 @@ namespace CloudGaming.DtoModel.Epg
/// 展示图片信息,长宽
/// </summary>
[Images]
public int Pic { get; set; }
/// <summary>
/// 展示图片信息,长宽
/// </summary>
[Images]
public int Pic2 { get; set; }
/// <summary>
/// 展示图片信息,长宽
/// </summary>
[Images]
public int Pic3 { get; set; }
public int ImageUrl { get; set; }
/// <summary>
/// 展示游戏Iocn信息长宽
/// 角标图片信息
/// </summary>
[Images]
public int GameIconImage { get; set; }
public int CornerIcon { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 标题2
/// 标题
/// </summary>
public string Title2 { get; set; }
public string SubTitle { get; set; }
/// <summary>
/// 评分,0.0
/// </summary>
public string Score { get; set; }
/// <summary>
/// 角标图片信息
/// </summary>
[Images]
public int CornerIcon { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.Game
{
/// <summary>
///
/// </summary>
public class GameExtendedAttribute
{
/// <summary>
/// 类型Id
/// </summary>
public virtual int Id { get; set; }
/// <summary>
/// 类型名称
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// 排序
/// </summary>
public int OrderId { get; set; }
}
}

View File

@ -0,0 +1,112 @@
using AutoMapper;
using AutoMapper.Configuration.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.Game
{
/// <summary>
/// 游戏详情
/// </summary>
[AutoMap(typeof(T_GameCBT))]
public class GameInfo : T_GameCBT
{
#region
/// <summary>
/// 修改时间
/// </summary>
[Ignore]
private new DateTime? UpdateTime { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Ignore]
private new DateTime? CreateTime { get; set; }
/// <summary>
///
/// </summary>
[Ignore]
public virtual int Id { get; set; }
/// <summary>
///
/// </summary>
[Ignore]
private new Guid TenantId { get; set; }
#endregion
/// <summary>
/// 游戏标签
/// </summary>
public List<GameExtendedAttribute> GameTags { get; set; }
/// <summary>
/// 游戏列表
/// </summary>
public List<GameExtendedAttribute> GameType { get; set; }
#region
/// <summary>
/// 游戏人数
/// </summary>
public virtual int GamePeopleNum { get; set; }
/// <summary>
/// 是否存档
/// </summary>
public virtual bool GameIsSaveFile { get; set; }
/// <summary>
/// 游戏是否适配
/// </summary>
public virtual bool GameIsAdapter { get; set; }
/// <summary>
/// 云游戏Id
/// </summary>
public virtual string? GameCloudId { get; set; }
/// <summary>
/// 游戏介绍
/// </summary>
public virtual string? GameIntroduce { get; set; }
/// <summary>
/// 屏幕方向0-横屏 1-竖屏
/// </summary>
public virtual int ScreenOrientation { get; set; }
/// <summary>
/// 是否隐藏鼠标
/// </summary>
public virtual bool GameIsEditionMouse { get; set; }
/// <summary>
/// steam
/// </summary>
public virtual string? SteamId { get; set; }
/// <summary>
/// 游戏难度
/// </summary>
public virtual string GameDifficulty { get; set; }
/// <summary>
/// 游戏操作类型
/// </summary>
public virtual string? GameOperationModel { get; set; }
#endregion
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.Game
{
/// <summary>
/// 扩展类
/// </summary>
public static class GameInfoExtend
{
/// <summary>
/// 转化游戏类
/// </summary>
/// <param name="gameList"></param>
/// <param name="gameInfo"></param>
/// <returns></returns>
public static GameInfo ToGameInfo(this T_Game_List gameList, GameInfo? gameInfo = null)
{
if (gameInfo == null)
{
gameInfo = new GameInfo();
}
if (string.IsNullOrEmpty(gameInfo.GameName))
{
gameInfo.GameName = gameList.GameName;
}
if (string.IsNullOrEmpty(gameInfo.GameId))
{
gameInfo.GameId = gameList.GameId;
}
gameInfo.GamePeopleNum = gameList.GamePeopleNum;
gameInfo.GameIsSaveFile = gameList.GameIsSaveFile;
gameInfo.GameIsAdapter = gameList.GameIsAdapter;
gameInfo.GameCloudId = gameList.GameCloudId;
gameInfo.GameIntroduce = gameList.GameIntroduce;
gameInfo.ScreenOrientation = gameList.ScreenOrientation;
gameInfo.GameIsEditionMouse = gameList.GameIsEditionMouse;
gameInfo.SteamId = gameList.SteamId;
gameInfo.GameDifficulty = gameList.GameDifficulty;
gameInfo.GameOperationModel = gameList.GameOperationModel;
return gameInfo;
}
}
}

View File

@ -0,0 +1,21 @@
using AutoMapper;
using CloudGaming.DtoModel.Game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel;
public class MappingProfile : Profile
{
public MappingProfile()
{
// // 创建映射配置
// CreateMap<T_Game_Types, GameTypes>()
//.ForMember(dest => dest.TypeName, opt => opt.Ignore());
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace CloudGaming.GameModel.Db.Db_Game;

View File

@ -1,11 +1,11 @@
using System;
using System;
namespace CloudGaming.Model.DbSqlServer.Db_Phone;
/// <summary>
/// Epg配置表
/// </summary>
public partial class T_Epg_Cfg: MultiTenantEntity
public partial class T_Epg_Cfg : MultiTenantEntity
{
public T_Epg_Cfg() { }
@ -124,8 +124,8 @@ public partial class T_Epg_Cfg: MultiTenantEntity
/// </summary>
public virtual DateTime? CreateTime { get; set; }
/// <summary>
/// <summary>
/// 所属租户
/// </summary>
public override Guid TenantId { get; set; }
}
}

View File

@ -1,11 +1,11 @@
using System;
using System;
namespace CloudGaming.Model.DbSqlServer.Db_Phone;
/// <summary>
/// 游戏配置
/// </summary>
public partial class T_GameCBT: MultiTenantEntity
public partial class T_GameCBT : MultiTenantEntity
{
public T_GameCBT() { }
@ -156,8 +156,8 @@ public partial class T_GameCBT: MultiTenantEntity
/// </summary>
public virtual string? FriendlyTips { get; set; }
/// <summary>
/// <summary>
/// 所属租户
/// </summary>
public override Guid TenantId { get; set; }
}
}

View File

@ -75,7 +75,7 @@ namespace HuanMeng.DotNetCore.CacheHelper
/// </summary>
public abstract List<T> GetDataList();
public bool ClearData()
public virtual bool ClearData()
{
lock (lockObj)
{
@ -85,7 +85,7 @@ namespace HuanMeng.DotNetCore.CacheHelper
return true;
}
public void ReloadData()
public virtual void ReloadData()
{
lock (lockObj)
{