获取鲸云token

This commit is contained in:
zpc 2024-11-21 04:44:06 +08:00
parent 95fb90dc31
commit 0bd2a07927
15 changed files with 443 additions and 10 deletions

View File

@ -1,5 +1,6 @@
using CloudGaming.Api.Base;
using CloudGaming.Code.Mall;
using CloudGaming.DtoModel.JY;
using CloudGaming.DtoModel.Mall;
using HuanMeng.DotNetCore.Base;
@ -8,6 +9,8 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace CloudGaming.Api.Controllers;
@ -43,6 +46,7 @@ public class PaymentController : CloudGamingControllerBase
[Authorize]
public async Task<BaseResponse<bool>> GetOrderRewardsInfo(string orderId)
{
OrderBLL orderBLL = new OrderBLL(ServiceProvider);
return await orderBLL.GetOrderRewardsInfo(orderId);
}

View File

@ -0,0 +1,38 @@
using CloudGaming.Api.Base;
using CloudGaming.Code.Contract;
using CloudGaming.Code.Game;
using CloudGaming.DtoModel.JY;
using CloudGaming.DtoModel.PlayGame;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Refit;
namespace CloudGaming.Api.Controllers
{
public class PlayGameController : CloudGamingControllerBase
{
private IJYApi JYApi;
public PlayGameController(IServiceProvider _serviceProvider, IJYApi jYApi) : base(_serviceProvider)
{
JYApi = jYApi;
}
/// <summary>
/// 获取token接口
/// </summary>
/// <param name="requestBaseModel"></param>
/// <returns></returns>
[HttpPost]
public async Task<string> GetToken([FromBody] RequestBaseModel requestBaseModel)
{
PlayGameBLL playGameBLL = new PlayGameBLL(ServiceProvider, JYApi);
return await playGameBLL.GetTokenAsync(requestBaseModel);
}
}
}

View File

@ -19,6 +19,9 @@ using Microsoft.Extensions.Options;
using CloudGaming.GameModel.Db.Db_Ext;
using CloudGaming.Code.MiddlewareExtend;
using CloudGaming.Code.Filter;
using CloudGaming.Code.Contract;
using Refit;
using CloudGaming.Code.JY;
var builder = WebApplication.CreateBuilder(args);
#region
// Add services to the container.
@ -42,6 +45,7 @@ builder.Services.AddSingleton(typeof(ILogger<ExceptionMiddleware>), serviceProvi
builder.Services.AddMemoryCache();
builder.Services.AddHttpClient();
builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问
#region
//services.AddControllers(options =>
//{
@ -104,7 +108,7 @@ builder.Services.AddSwaggerGen(c =>
var filePath = Path.GetFullPath(".versionDescribe");
if (File.Exists(filePath))
{
description= File.ReadAllText(filePath);
description = File.ReadAllText(filePath);
//string[] lines = File.ReadAllLines(filePath);
//foreach (string line in lines)
//{
@ -159,7 +163,12 @@ builder.AddJwtConfig();
var _myAllowSpecificOrigins = "_myAllowSpecificOrigins";
builder.Services.AddCustomCors(_myAllowSpecificOrigins);
#endregion
builder.Services.AddScoped<JYApiHandler>();
// 配置 HttpClientFactory 和 Refit
builder.Services.AddRefitClient<IJYApi>()
.AddHttpMessageHandler<JYApiHandler>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://default-api.example.com"));
//添加jwt验证
//builder.AddJwtConfig();

View File

@ -74,6 +74,11 @@ public class AppConfig
/// </summary>
public UserConfig UserConfig { get; set; }
/// <summary>
/// 游戏配置
/// </summary>
public GameConfig GameConfig { get; set; }
/// <summary>
/// 获取数据库连接字符串
/// </summary>

View File

@ -193,7 +193,7 @@ namespace CloudGaming.Code.AppExtend
}
newAppConfig.UserConfig = appConfig.UserConfig;
newAppConfig.Payment = appConfig.Payment;
newAppConfig.GameConfig = appConfig.GameConfig;
return newAppConfig;
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.AppExtend.ConfigModel
{
/// <summary>
///
/// </summary>
public class GameConfig
{
/// <summary>
/// 客户渠道Id,如edb684859b848362ec56904286947614
/// </summary>
public string ChannelId { get; set; }
/// <summary>
/// 客户渠道key,加密使用
/// </summary>
public string SignKey { get; set; }
/// <summary>
/// 客户渠道地址
/// </summary>
public string BsUrl { get; set; }
}
}

View File

@ -19,6 +19,8 @@
<PackageReference Include="FastMember" Version="1.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
<PackageReference Include="Refit" Version="8.0.0" />
<PackageReference Include="Refit.HttpClientFactory" Version="8.0.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.9.0" />
</ItemGroup>

View File

@ -0,0 +1,24 @@
using CloudGaming.DtoModel.JY;
using HuanMeng.DotNetCore.Base;
using Refit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Contract
{
/// <summary>
///
/// </summary>
public interface IJYApi
{
[Post("/jyapi/getToken")]
Task<JYResponseCode<GetTokenModel>> GetToken([Body(BodySerializationMethod.UrlEncoded)] SortedDictionary<string, object> data);
}
}

View File

@ -1,5 +1,7 @@
using Newtonsoft.Json;
namespace CloudGaming.Code.Filter;
@ -43,16 +45,39 @@ public class CustomResultFilter : IResultFilter
object? value = null;
if (!x.FullName.Contains("HuanMeng.DotNetCore.Base.BaseResponse"))
{
BaseResponse<object> baseResponse = new BaseResponse<object>(ResonseCode.Success, "", objectResult.Value);
value = baseResponse;
// 获取当前执行的Action方法的信息并进行类型检查
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
//特殊处理
if (objectResult.Value is string)
{
var messageAttribute = MessageAttributeExtend.GetMessageAttribute(controllerActionDescriptor);
// 如果存在MessageAttribute则设置响应消息
if (messageAttribute != null)
BaseResponse<string> baseStringResponse = new BaseResponse<string>(ResonseCode.Success, "", objectResult.Value.ToString());
value = baseStringResponse;
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
baseResponse.Message = messageAttribute.Message;
var messageAttribute = MessageAttributeExtend.GetMessageAttribute(controllerActionDescriptor);
// 如果存在MessageAttribute则设置响应消息
if (messageAttribute != null)
{
baseStringResponse.Message = messageAttribute.Message;
}
}
sw.Stop();
context.HttpContext.Response.Headers.TryAdd("X-Request-Duration-Filter", sw.Elapsed.TotalMilliseconds.ToString());
objectResult.Value = baseStringResponse.ToString();
return;
}
else
{
BaseResponse<object> baseResponse = new BaseResponse<object>(ResonseCode.Success, "", objectResult.Value);
value = baseResponse;
// 获取当前执行的Action方法的信息并进行类型检查
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
var messageAttribute = MessageAttributeExtend.GetMessageAttribute(controllerActionDescriptor);
// 如果存在MessageAttribute则设置响应消息
if (messageAttribute != null)
{
baseResponse.Message = messageAttribute.Message;
}
}
}

View File

@ -0,0 +1,42 @@
using CloudGaming.Code.AppExtend.ConfigModel;
using CloudGaming.Code.Contract;
using CloudGaming.DtoModel.PlayGame;
using Refit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Game
{
public class PlayGameBLL : CloudGamingBase
{
private IJYApi JYApi { get; set; }
public PlayGameBLL(IServiceProvider serviceProvider, IJYApi jYApi) : base(serviceProvider)
{
JYApi = jYApi;
}
public async Task<string> GetTokenAsync(RequestBaseModel requestBaseModel)
{
if (_UserId == 0)
{
throw MessageBox.ErrorShow("请先登录");
}
if (string.IsNullOrEmpty(requestBaseModel.Sn))
{
throw MessageBox.ErrorShow("设备号不能为空");
}
var dicParams = new SortedDictionary<string, object>();
dicParams.Add("sn", requestBaseModel.Sn);
dicParams.Add("client_sid", _UserId);
var data = await JYApi.GetToken(dicParams);
return data?.Data?.Token ?? "";
}
}
}

View File

@ -0,0 +1,44 @@
using CloudGaming.DtoModel.PlayGame;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Game
{
public static class PlayGameExtend
{
/// <summary>
///
/// </summary>
/// <param name="requestBaseModel"></param>
/// <param name="cloudGamingBase"></param>
/// <returns></returns>
public static SortedDictionary<string, object> GetDefaultParams(this RequestBaseModel requestBaseModel, CloudGamingBase cloudGamingBase)
{
return GetDefaultParams(requestBaseModel, cloudGamingBase.AppConfig.GameConfig, cloudGamingBase.HttpContextAccessor.HttpContext.GetClientIpAddress(), cloudGamingBase._UserId);
}
/// <summary>
///
/// </summary>
/// <param name="requestBaseModel"></param>
/// <param name="gameConfig"></param>
/// <param name="ip"></param>
/// <param name="UserId"></param>
/// <returns></returns>
public static SortedDictionary<string, object> GetDefaultParams(this RequestBaseModel requestBaseModel, GameConfig gameConfig, string ip, int UserId)
{
var dicParams = new SortedDictionary<string, object>();
dicParams.Add("channel_id", gameConfig.ChannelId);
dicParams.Add("sn", requestBaseModel.Sn);
dicParams.Add("client_sid", UserId);
dicParams.Add("ip", ip);
dicParams.Add("time", DateTimeOffset.UtcNow.ToUnixTimeSeconds());
return dicParams;
}
}
}

View File

@ -0,0 +1,138 @@
using CloudGaming.Code.AppExtend;
using CloudGaming.Code.AppExtend.ConfigModel;
using CloudGaming.DtoModel.PlayGame;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.JY;
/// <summary>
///
/// </summary>
public class JYApiHandler : DelegatingHandler
{
private readonly IHttpContextAccessor _httpContextAccessor;
public JYApiHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// 访问 HttpContext
var httpContext = _httpContextAccessor.HttpContext;
var host = httpContext.Request.Host.Host;
var app = AppConfigurationExtend.GetAppConfig(host);
if (app != null)
{
var newUri = new Uri(new Uri(app.GameConfig.BsUrl), request.RequestUri.PathAndQuery);
// 更新请求的 URI
request.RequestUri = newUri;
// 处理请求体
if (request.Content is FormUrlEncodedContent)
{
var formData = await request.Content.ReadAsStringAsync();
var parameters = ParseFormData(formData);
if (!parameters.ContainsKey("channel_id"))
{
parameters.Add("channel_id", app.GameConfig.ChannelId);
}
if (!parameters.ContainsKey("ip"))
{
parameters.Add("ip", httpContext.GetClientIpAddress());
}
if (!parameters.ContainsKey("time"))
{
parameters.Add("time", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString());
}
if (!parameters.ContainsKey("sign"))
{
var signKey = signEncode(parameters, app.GameConfig.SignKey);
parameters.Add("sign", signKey);
}
// 对参数进行加密(示例,使用简单的 Base64 编码)
var encryptedParameters = dic2PostData(parameters);
// 更新请求体
request.Content = new StringContent(encryptedParameters, Encoding.UTF8, "application/x-www-form-urlencoded");
}
}
var x = await base.SendAsync(request, cancellationToken);
var json = await x.Content.ReadAsStringAsync();
//调用下一个处理器
return x;
}
private SortedDictionary<string, object> ParseFormData(string formData)
{
var parameters = new SortedDictionary<string, object>();
var pairs = formData.Split('&');
foreach (var pair in pairs)
{
var keyValue = pair.Split('=');
if (keyValue.Length == 2)
{
parameters[keyValue[0]] = keyValue[1];
}
}
return parameters;
}
/// <summary>
/// 字典参数 转 成url参数
/// </summary>
/// <param name="dic"></param>
/// <returns></returns>
private static string dic2PostData(SortedDictionary<string, object> dic)
{
StringBuilder postData = new StringBuilder();
foreach (var item in dic)
{
//string s1 = HttpUtility.UrlEncode(item.Value.ToString());
string s1 = item.Value.ToString();
if (s1.Length > 0)
{
if (postData.Length == 0)
postData.AppendFormat("{0}={1}", item.Key, s1);
else
postData.AppendFormat("&{0}={1}", item.Key, s1);
}
}
return postData.ToString();
}
/// <summary>
/// 签名参数
/// </summary>
/// <param name="dicParams"></param>
/// <returns></returns>
public static string signEncode(SortedDictionary<string, object> dicParams, string key)
{
StringBuilder str = new StringBuilder();
foreach (var item in dicParams)
{
string s1 = item.Value.ToString();
if (s1.Length > 0)
{
if (str.Length == 0)
str.AppendFormat("{0}={1}", item.Key, s1);
else
str.AppendFormat("&{0}={1}", item.Key, s1);
}
}
str.AppendFormat("&key={0}", key);
return MD5Encryption.ComputeMD5Hash(str.ToString()).ToUpper();
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.JY
{
/// <summary>
/// getToken返回值
/// </summary>
public class GetTokenModel
{
/// <summary>
///
/// </summary>
public string Token { get; set; }
/// <summary>
///
/// </summary>
public int Expire_time { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.JY
{
/// <summary>
/// 鲸云api
/// </summary>
/// <typeparam name="T"></typeparam>
public class JYResponseCode<T> where T : class, new()
{
/// <summary>
/// 状态
/// </summary>
public int Status { get; set; }
/// <summary>
/// 消息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 数据源
/// </summary>
public T? Data { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.PlayGame
{
/// <summary>
///
/// </summary>
public class RequestBaseModel
{
/// <summary>
/// 设备号
/// </summary>
public string Sn { get; set; }
}
}